diff options
-rw-r--r-- | apps/files_external/css/settings.scss (renamed from apps/files_external/css/settings.css) | 42 | ||||
-rw-r--r-- | apps/files_external/js/settings.js | 97 | ||||
-rw-r--r-- | apps/files_external/templates/settings.php | 20 | ||||
-rw-r--r-- | apps/files_external/tests/js/settingsSpec.js | 53 | ||||
-rw-r--r-- | core/css/apps.scss | 20 | ||||
-rw-r--r-- | settings/css/settings.scss | 6 |
6 files changed, 126 insertions, 112 deletions
diff --git a/apps/files_external/css/settings.css b/apps/files_external/css/settings.scss index bac89e26b09..0f52ed3b2a1 100644 --- a/apps/files_external/css/settings.css +++ b/apps/files_external/css/settings.scss @@ -18,9 +18,11 @@ #externalStorage td.status > span { display: inline-block; - height: 16px; - width: 16px; + height: 28px; + width: 28px; vertical-align: text-bottom; + border-radius: 50%; + cursor: pointer; } td.mountPoint, td.backend { width:160px; } @@ -30,9 +32,25 @@ td.mountPoint, td.backend { width:160px; } #addMountPoint>td.applicable { visibility:hidden; } #addMountPoint>td.hidden { visibility:hidden; } -#externalStorage .icon-settings { - padding: 11px 20px; - vertical-align: text-bottom; +#externalStorage td { + height: 50px; + &.mountOptionsToggle, + &.remove, + &.save { + position: relative; + padding: 0 !important; + width: 44px; + [class^='icon-'], + [class*=' icon-'] { + opacity: 0.5; + padding: 14px; + vertical-align: text-bottom; + cursor: pointer; + &:hover { + opacity: 1; + } + } + } } #selectBackend { @@ -57,9 +75,9 @@ td.mountPoint, td.backend { width:160px; } } #externalStorage td.configuration label { - min-width: 144px; /* 130px plus 2x7px padding */ - display: inline-block; - margin-right: 6px; + width: 100%; + display: inline-flex; + align-items: center; } #externalStorage td.configuration input.disabled-success { @@ -72,10 +90,6 @@ td.mountPoint, td.backend { width:160px; } top: 3px; } -#externalStorage td.status .success { - border-radius: 50%; -} - #userMountingBackends { padding-left: 25px; } @@ -111,10 +125,6 @@ td.mountPoint, td.backend { width:160px; } width: auto; } -#externalStorage .mountOptionsDropdown { - margin-right: 40px; -} - .nav-icon-external-storage { background-image: url('../img/app-dark.svg?v=1'); } diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 12ad285c52b..014dd7a3c2b 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -12,31 +12,43 @@ // TODO: move to a separate file var MOUNT_OPTIONS_DROPDOWN_TEMPLATE = - '<div class="drop dropdown mountOptionsDropdown">' + + '<div class="popovermenu open">'+ // FIXME: options are hard-coded for now - ' <div class="optionRow">' + - ' <input id="mountOptionsEncrypt" name="encrypt" type="checkbox" value="true" checked="checked"/>' + - ' <label for="mountOptionsEncrypt">{{t "files_external" "Enable encryption"}}</label>' + - ' </div>' + - ' <div class="optionRow">' + - ' <input id="mountOptionsPreviews" name="previews" type="checkbox" value="true" checked="checked"/>' + - ' <label for="mountOptionsPreviews">{{t "files_external" "Enable previews"}}</label>' + - ' </div>' + - ' <div class="optionRow">' + - ' <input id="mountOptionsSharing" name="enable_sharing" type="checkbox" value="true"/>' + - ' <label for="mountOptionsSharing">{{t "files_external" "Enable sharing"}}</label>' + - ' </div>' + - ' <div class="optionRow">' + - ' <label for="mountOptionsFilesystemCheck">{{t "files_external" "Check for changes"}}</label>' + - ' <select id="mountOptionsFilesystemCheck" name="filesystem_check_changes" data-type="int">' + - ' <option value="0">{{t "files_external" "Never"}}</option>' + - ' <option value="1" selected="selected">{{t "files_external" "Once every direct access"}}</option>' + - ' </select>' + - ' </div>' + - ' <div class="optionRow">' + - ' <input id="mountOptionsEncoding" name="encoding_compatibility" type="checkbox" value="true"/>' + - ' <label for="mountOptionsEncoding">{{mountOptionsEncodingLabel}}</label>' + - ' </div>' + + ' <ul>'+ + ' <li class="optionRow">'+ + ' <span class="menuitem">'+ + ' <input id="mountOptionsEncrypt" class="checkbox" name="encrypt" type="checkbox" value="true" checked="checked"/>'+ + ' <label for="mountOptionsEncrypt">{{t "files_external" "Enable encryption"}}</label>'+ + ' </span>'+ + ' </li>'+ + ' <li class="optionRow">'+ + ' <span class="menuitem">'+ + ' <input id="mountOptionsPreviews" class="checkbox" name="previews" type="checkbox" value="true" checked="checked"/>'+ + ' <label for="mountOptionsPreviews">{{t "files_external" "Enable previews"}}</label>'+ + ' </span>'+ + ' </li>'+ + ' <li class="optionRow">'+ + ' <span class="menuitem">'+ + ' <input id="mountOptionsSharing" class="checkbox" name="enable_sharing" type="checkbox" value="true"/>'+ + ' <label for="mountOptionsSharing">{{t "files_external" "Enable sharing"}}</label>'+ + ' </span>'+ + ' </li>'+ + ' <li class="optionRow">'+ + ' <span class="menuitem icon-search">'+ + ' <label for="mountOptionsFilesystemCheck">{{t "files_external" "Check for changes"}}</label>'+ + ' <select id="mountOptionsFilesystemCheck" name="filesystem_check_changes" data-type="int">'+ + ' <option value="0">{{t "files_external" "Never"}}</option>'+ + ' <option value="1" selected="selected">{{t "files_external" "Once every direct access"}}</option>'+ + ' </select>'+ + ' </span>'+ + ' </li>'+ + ' <li class="optionRow">'+ + ' <span class="menuitem">'+ + ' <input id="mountOptionsEncoding" class="checkbox" name="encoding_compatibility" type="checkbox" value="true"/>'+ + ' <label for="mountOptionsEncoding">{{mountOptionsEncodingLabel}}</label>'+ + ' </span>'+ + ' </li>'+ + ' </ul>'+ '</div>'; /** @@ -716,15 +728,15 @@ MountConfigListView.prototype = _.extend({ self.recheckStorageConfig($(this).closest('tr')); }); - this.$el.on('click', 'td.remove>img', function() { + this.$el.on('click', 'td.remove>.icon-delete', function() { self.deleteStorageConfig($(this).closest('tr')); }); - this.$el.on('click', 'td.save>img', function () { + this.$el.on('click', 'td.save>.icon-checkmark', function () { self.saveStorageConfig($(this).closest('tr')); }); - this.$el.on('click', 'td.mountOptionsToggle>img', function() { + this.$el.on('click', 'td.mountOptionsToggle>.icon-settings-dark', function() { self._showMountOptionsDropdown($(this).closest('tr')); }); @@ -1220,24 +1232,28 @@ MountConfigListView.prototype = _.extend({ */ updateStatus: function($tr, status, message) { var $statusSpan = $tr.find('.status span'); - $statusSpan.removeClass('loading-small success indeterminate error'); switch (status) { case null: // remove status break; case StorageConfig.Status.IN_PROGRESS: - $statusSpan.addClass('loading-small'); + $statusSpan.attr('class', 'icon-loading-small'); break; case StorageConfig.Status.SUCCESS: - $statusSpan.addClass('success'); + $statusSpan.attr('class', 'success icon-checkmark-white'); break; case StorageConfig.Status.INDETERMINATE: - $statusSpan.addClass('indeterminate'); + $statusSpan.attr('class', 'indeterminate icon-info-white'); break; default: - $statusSpan.addClass('error'); + $statusSpan.attr('class', 'error icon-error-white'); + } + if (typeof message === 'string') { + $statusSpan.attr('title', message); + $statusSpan.tooltip(); + } else { + $statusSpan.tooltip('destroy'); } - $statusSpan.attr('data-original-title', (typeof message === 'string') ? message : ''); }, /** @@ -1279,11 +1295,6 @@ MountConfigListView.prototype = _.extend({ * @param {Object} $tr configuration row */ _showMountOptionsDropdown: function($tr) { - if (this._preventNextDropdown) { - // prevented because the click was on the toggle - this._preventNextDropdown = false; - return; - } var self = this; var storage = this.getStorageConfig($tr); var $toggle = $tr.find('.mountOptionsToggle'); @@ -1300,15 +1311,7 @@ MountConfigListView.prototype = _.extend({ dropDown.show($toggle, storage.mountOptions || [], visibleOptions); $('body').on('mouseup.mountOptionsDropdown', function(event) { var $target = $(event.target); - if ($toggle.has($target).length) { - // why is it always so hard to make dropdowns behave ? - // this prevents the click on the toggle to cause - // the dropdown to reopen itself - // (preventDefault doesn't work here because the click - // event is already in the queue and cannot be cancelled) - self._preventNextDropdown = true; - } - if ($target.closest('.dropdown').length) { + if ($target.closest('.popovermenu').length) { return; } dropDown.hide(); diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index 11b3451c32e..895be719ab4 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -106,6 +106,7 @@ <?php if ($_['visibilityType'] === BackendService::VISIBILITY_ADMIN) print_unescaped('<th>'.$l->t('Available for').'</th>'); ?> <th> </th> <th> </th> + <th> </th> </tr> </thead> <tbody> @@ -115,7 +116,7 @@ <?php endif; ?> > <td class="status"> - <span></span> + <span data-placement="right" title="<?php p($l->t('Click to recheck the configuration')); ?>"></span> </td> <td class="mountPoint"><input type="text" name="mountPoint" value="" placeholder="<?php p($l->t('Folder name')); ?>"> @@ -148,25 +149,14 @@ </td> <?php endif; ?> <td class="mountOptionsToggle hidden"> - <img class="svg" - title="<?php p($l->t('Advanced settings')); ?>" - alt="<?php p($l->t('Advanced settings')); ?>" - src="<?php print_unescaped(image_path('core', 'actions/settings.svg')); ?>" - /> + <div class="icon-settings-dark" title="<?php p($l->t('Advanced settings')); ?>"></div> <input type="hidden" class="mountOptions" value="" /> </td> <td class="remove hidden"> - <img class="svg" - alt="<?php p($l->t('Delete')); ?>" - title="<?php p($l->t('Delete')); ?>" - src="<?php print_unescaped(image_path('core', 'actions/delete.svg')); ?>" - /> + <div class="icon-delete" title="<?php p($l->t('Delete')); ?>"></div> </td> <td class="save hidden"> - <img alt="<?php p($l->t('Save')); ?>" - title="<?php p($l->t('Save')); ?>" - src="<?php print_unescaped(image_path('core', 'actions/checkmark.svg')); ?>" - /> + <div class="icon-checkmark" title="<?php p($l->t('Save')); ?>"></div> </td> </tr> </tbody> diff --git a/apps/files_external/tests/js/settingsSpec.js b/apps/files_external/tests/js/settingsSpec.js index d6b96a47189..56bdcff8345 100644 --- a/apps/files_external/tests/js/settingsSpec.js +++ b/apps/files_external/tests/js/settingsSpec.js @@ -45,9 +45,16 @@ describe('OCA.External.Settings tests', function() { '<td class="applicable">' + '<input type="hidden" class="applicableUsers">' + '</td>' + - '<td class="mountOptionsToggle"><input type="hidden" class="mountOptions"/><img class="svg action"/></td>' + - '<td class="remove"><img alt="Delete" title="Delete" class="svg action"/></td>' + - '<td class="save"><img alt="Save" title="Save" class="svg action"/></td>' + + '<td class="mountOptionsToggle">'+ + '<div class="icon-settings-dark" title="Advanced settings" deluminate_imagetype="unknown"></div>'+ + '<input type="hidden" class="mountOptions"/>'+ + '</td>'+ + '<td class="remove">'+ + '<div class="icon-delete" title="Delete" deluminate_imagetype="unknown"></div>'+ + '</td>'+ + '<td class="save">'+ + '<div class="icon-checkmark" title="Save" deluminate_imagetype="unknown"></div>'+ + '</td>'+ '</tr>' + '</tbody>' + '</table>' @@ -206,7 +213,7 @@ describe('OCA.External.Settings tests', function() { expect($mountOptionsField.length).toEqual(1); $mountOptionsField.val(JSON.stringify({previews:true})); - var $saveButton = $tr.find('td.save img'); + var $saveButton = $tr.find('td.save .icon-checkmark'); $saveButton.click(); expect(fakeServer.requests.length).toEqual(1); @@ -231,17 +238,17 @@ describe('OCA.External.Settings tests', function() { // TODO: respond and check data-id }); - it('saves storage after closing mount options dropdown', function() { - $tr.find('.mountOptionsToggle img').click(); + it('saves storage after closing mount options popovermenu', function() { + $tr.find('.mountOptionsToggle .icon-settings-dark').click(); $tr.find('[name=previews]').trigger(new $.Event('keyup', {keyCode: 97})); $tr.find('input[data-parameter=field1]').val('test'); - // does not save inside the dropdown + // does not save inside the popovermenu expect(fakeServer.requests.length).toEqual(0); $('body').mouseup(); - // but after closing the dropdown + // but after closing the popovermenu expect(fakeServer.requests.length).toEqual(1); }); // TODO: status indicator @@ -313,7 +320,7 @@ describe('OCA.External.Settings tests', function() { describe('recheck storages', function() { // TODO }); - describe('mount options dropdown', function() { + describe('mount options popovermenu', function() { var $tr; var $td; @@ -323,45 +330,45 @@ describe('OCA.External.Settings tests', function() { selectBackend('\\OC\\TestBackend'); }); - it('shows dropdown when clicking on toggle button, hides when clicking outside', function() { - $td.find('img').click(); + it('shows popovermenu when clicking on toggle button, hides when clicking outside', function() { + $td.find('.icon-settings-dark').click(); - expect($td.find('.dropdown').length).toEqual(1); + expect($td.find('.popovermenu.open').length).toEqual(1); $('body').mouseup(); - expect($td.find('.dropdown').length).toEqual(0); + expect($td.find('.popovermenu.open').length).toEqual(0); }); it('doesnt show the encryption option when encryption is disabled', function () { view._encryptionEnabled = false; - $td.find('img').click(); + $td.find('.icon-settings-dark').click(); - expect($td.find('.dropdown [name=encrypt]:visible').length).toEqual(0); + expect($td.find('.popovermenu [name=encrypt]:visible').length).toEqual(0); $('body').mouseup(); - expect($td.find('.dropdown').length).toEqual(0); + expect($td.find('.popovermenu.open').length).toEqual(0); }); it('reads config from mountOptions field', function() { $tr.find('input.mountOptions').val(JSON.stringify({previews:false})); - $td.find('img').click(); - expect($td.find('.dropdown [name=previews]').prop('checked')).toEqual(false); + $td.find('.icon-settings-dark').click(); + expect($td.find('.popovermenu [name=previews]').prop('checked')).toEqual(false); $('body').mouseup(); $tr.find('input.mountOptions').val(JSON.stringify({previews:true})); - $td.find('img').click(); - expect($td.find('.dropdown [name=previews]').prop('checked')).toEqual(true); + $td.find('.icon-settings-dark').click(); + expect($td.find('.popovermenu [name=previews]').prop('checked')).toEqual(true); }); it('writes config into mountOptions field', function() { - $td.find('img').click(); + $td.find('.icon-settings-dark').click(); // defaults to true - var $field = $td.find('.dropdown [name=previews]'); + var $field = $td.find('.popovermenu [name=previews]'); expect($field.prop('checked')).toEqual(true); - $td.find('.dropdown [name=filesystem_check_changes]').val(0); + $td.find('.popovermenu [name=filesystem_check_changes]').val(0); $('body').mouseup(); expect(JSON.parse($tr.find('input.mountOptions').val())).toEqual({ diff --git a/core/css/apps.scss b/core/css/apps.scss index becbf63cd6d..10adaee929d 100644 --- a/core/css/apps.scss +++ b/core/css/apps.scss @@ -845,6 +845,10 @@ kbd { line-height: 1.6em; padding: 8px 0; } + > select { + margin: 0; + margin-left: 6px; + } /* Add padding if contains icon+text */ &:not(:empty) { padding-right: 10px !important; @@ -853,17 +857,17 @@ kbd { width: 16px; padding: 0 10px; } + /* checkbox/radio fixes */ + > input.radio + label, > input.checkbox + label { padding: 0 !important; - &::before { - margin: -2px 12px 0; - } + width: 100%; } - > input.radio + label { - padding: 0 !important; - &::before { - margin: -2px 11px 0; - } + > input.checkbox + label::before { + margin: -2px 12px 0; + } + > input.radio + label::before { + margin: -2px 11px 0; } } > button { diff --git a/settings/css/settings.scss b/settings/css/settings.scss index 611961b1065..451b9e733f2 100644 --- a/settings/css/settings.scss +++ b/settings/css/settings.scss @@ -1112,14 +1112,14 @@ table.grid td.date { span { &.success { - background: #37ce02; + background-color: $color-success; border-radius: $border-radius; } &.error { - background: #ce3702; + background-color: $color-error; } &.indeterminate { - background: #e6db00; + background-color: $color-warning; border-radius: 40% 0; } } |