From b72aa998d63dff60944c90a5acb49e991f69648e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 8 Jul 2017 15:33:03 +0200 Subject: [PATCH 1/5] Fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- tests/acceptance/features/bootstrap/FilesAppContext.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/features/bootstrap/FilesAppContext.php b/tests/acceptance/features/bootstrap/FilesAppContext.php index 52f69c66796..205c852078b 100644 --- a/tests/acceptance/features/bootstrap/FilesAppContext.php +++ b/tests/acceptance/features/bootstrap/FilesAppContext.php @@ -123,7 +123,7 @@ class FilesAppContext implements Context, ActorAwareInterface { /** * @return Locator */ - public static function inputFieldForTagsInCurrentSectionDetails() { + public static function inputFieldForTagsInCurrentSectionDetailsView() { return Locator::forThe()->css(".systemTagsInfoView")-> descendantOf(self::currentSectionDetailsView())-> describedAs("Input field for tags in current section details view in Files app"); @@ -425,7 +425,7 @@ class FilesAppContext implements Context, ActorAwareInterface { */ public function iSeeThatTheInputFieldForTagsInTheDetailsViewIsShown() { PHPUnit_Framework_Assert::assertTrue( - $this->actor->find(self::inputFieldForTagsInCurrentSectionDetails(), 10)->isVisible()); + $this->actor->find(self::inputFieldForTagsInCurrentSectionDetailsView(), 10)->isVisible()); } /** From 6cf19cc81a296663950deaf82aab4f2478e9c571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 8 Jul 2017 15:36:01 +0200 Subject: [PATCH 2/5] Extract app navigation elements to its own context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The app navigation is not exclusive to the Files app but a generic component used by other apps too, so its locators and steps should be in its own context. Signed-off-by: Daniel Calviño Sánchez --- tests/acceptance/config/behat.yml | 1 + .../bootstrap/AppNavigationContext.php | 69 +++++++++++++++++++ .../features/bootstrap/FilesAppContext.php | 39 ----------- 3 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 tests/acceptance/features/bootstrap/AppNavigationContext.php diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 15310e6883f..86510083761 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -9,6 +9,7 @@ default: - ActorContext - NextcloudTestServerContext + - AppNavigationContext - FeatureContext - FilesAppContext - FilesSharingAppContext diff --git a/tests/acceptance/features/bootstrap/AppNavigationContext.php b/tests/acceptance/features/bootstrap/AppNavigationContext.php new file mode 100644 index 00000000000..9ef71a06065 --- /dev/null +++ b/tests/acceptance/features/bootstrap/AppNavigationContext.php @@ -0,0 +1,69 @@ +. + * + */ + +use Behat\Behat\Context\Context; + +class AppNavigationContext implements Context, ActorAwareInterface { + + use ActorAware; + + /** + * @return Locator + */ + public static function appNavigation() { + return Locator::forThe()->id("app-navigation")-> + describedAs("App navigation"); + } + + /** + * @return Locator + */ + public static function appNavigationSectionItemFor($sectionText) { + return Locator::forThe()->xpath("//li[normalize-space() = '$sectionText']")-> + descendantOf(self::appNavigation())-> + describedAs($sectionText . " section item in App Navigation"); + } + + /** + * @return Locator + */ + public static function appNavigationCurrentSectionItem() { + return Locator::forThe()->css(".active")->descendantOf(self::appNavigation())-> + describedAs("Current section item in App Navigation"); + } + + /** + * @Given I open the :section section + */ + public function iOpenTheSection($section) { + $this->actor->find(self::appNavigationSectionItemFor($section), 10)->click(); + } + + /** + * @Then I see that the current section is :section + */ + public function iSeeThatTheCurrentSectionIs($section) { + PHPUnit_Framework_Assert::assertEquals($this->actor->find(self::appNavigationCurrentSectionItem(), 10)->getText(), $section); + } + +} diff --git a/tests/acceptance/features/bootstrap/FilesAppContext.php b/tests/acceptance/features/bootstrap/FilesAppContext.php index 205c852078b..b9ccb7316ab 100644 --- a/tests/acceptance/features/bootstrap/FilesAppContext.php +++ b/tests/acceptance/features/bootstrap/FilesAppContext.php @@ -41,31 +41,6 @@ class FilesAppContext implements Context, ActorAwareInterface { "Deleted files" => "trashbin" ]; } - /** - * @return Locator - */ - public static function appNavigation() { - return Locator::forThe()->id("app-navigation")-> - describedAs("App navigation"); - } - - /** - * @return Locator - */ - public static function appNavigationSectionItemFor($sectionText) { - return Locator::forThe()->xpath("//li[normalize-space() = '$sectionText']")-> - descendantOf(self::appNavigation())-> - describedAs($sectionText . " section item in App Navigation"); - } - - /** - * @return Locator - */ - public static function appNavigationCurrentSectionItem() { - return Locator::forThe()->css(".active")->descendantOf(self::appNavigation())-> - describedAs("Current section item in App Navigation"); - } - /** * @return Locator */ @@ -293,13 +268,6 @@ class FilesAppContext implements Context, ActorAwareInterface { describedAs($itemText . " item in file actions menu in Files app"); } - /** - * @Given I open the :section section - */ - public function iOpenTheSection($section) { - $this->actor->find(self::appNavigationSectionItemFor($section), 10)->click(); - } - /** * @Given I open the details view for :fileName */ @@ -373,13 +341,6 @@ class FilesAppContext implements Context, ActorAwareInterface { $this->actor->getSession()->getCurrentUrl()); } - /** - * @Then I see that the current section is :section - */ - public function iSeeThatTheCurrentSectionIs($section) { - PHPUnit_Framework_Assert::assertEquals($this->actor->find(self::appNavigationCurrentSectionItem(), 10)->getText(), $section); - } - /** * @Then I see that the details view for :section section is open */ From 00e0535aecf69a1e3ef93afe3d162fd45fb00ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 8 Jul 2017 15:46:16 +0200 Subject: [PATCH 3/5] Add acceptance tests for unselecting items in dropdown for tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- tests/acceptance/config/behat.yml | 1 + tests/acceptance/features/app-files.feature | 72 +++++++++ .../features/bootstrap/FilesAppContext.php | 93 +++++++++++ .../features/bootstrap/SettingsContext.php | 152 ++++++++++++++++++ .../bootstrap/SettingsMenuContext.php | 16 ++ 5 files changed, 334 insertions(+) create mode 100644 tests/acceptance/features/bootstrap/SettingsContext.php diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 86510083761..f9412935e51 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -15,6 +15,7 @@ default: - FilesSharingAppContext - LoginPageContext - NotificationContext + - SettingsContext - SettingsMenuContext - UsersSettingsContext extensions: diff --git a/tests/acceptance/features/app-files.feature b/tests/acceptance/features/app-files.feature index 8d32508513a..5a0a0095512 100644 --- a/tests/acceptance/features/app-files.feature +++ b/tests/acceptance/features/app-files.feature @@ -68,3 +68,75 @@ Feature: app-files And I see that the "Sharing" tab in the details view is eventually loaded When I open the input field for tags in the details view Then I see that the input field for tags in the details view is shown + + Scenario: create tags using the Administration settings + Given I am logged in as the admin + And I open the Admin settings + And I open the "Workflow" section + # The "create" button does nothing before JavaScript was initialized, and + # the only way to detect that is waiting for the button to select tags to be + # shown. + And I see that the button to select tags is shown + When I create the tag "tag1" in the settings + Then I see that the dropdown for tags in the settings eventually contains the tag "tag1" + + Scenario: add tags using the dropdown in the details view + Given I am logged in as the admin + And I open the Admin settings + And I open the "Workflow" section + # The "create" button does nothing before JavaScript was initialized, and + # the only way to detect that is waiting for the button to select tags to be + # shown. + And I see that the button to select tags is shown + And I create the tag "tag1" in the settings + And I create the tag "tag2" in the settings + And I create the tag "tag3" in the settings + And I create the tag "tag4" in the settings + And I see that the dropdown for tags in the settings eventually contains the tag "tag1" + And I see that the dropdown for tags in the settings eventually contains the tag "tag2" + And I see that the dropdown for tags in the settings eventually contains the tag "tag3" + And I see that the dropdown for tags in the settings eventually contains the tag "tag4" + And I log out + And I am logged in + And I open the details view for "welcome.txt" + And I open the input field for tags in the details view + # When the input field is opened the dropdown is also opened automatically. + When I check the tag "tag2" in the dropdown for tags in the details view + And I check the tag "tag4" in the dropdown for tags in the details view + Then I see that the tag "tag2" in the dropdown for tags in the details view is checked + And I see that the tag "tag4" in the dropdown for tags in the details view is checked + And I see that the input field for tags in the details view contains the tag "tag2" + And I see that the input field for tags in the details view contains the tag "tag4" + + Scenario: remove tags using the dropdown in the details view + Given I am logged in as the admin + And I open the Admin settings + And I open the "Workflow" section + # The "create" button does nothing before JavaScript was initialized, and + # the only way to detect that is waiting for the button to select tags to be + # shown. + And I see that the button to select tags is shown + And I create the tag "tag1" in the settings + And I create the tag "tag2" in the settings + And I create the tag "tag3" in the settings + And I create the tag "tag4" in the settings + And I see that the dropdown for tags in the settings eventually contains the tag "tag1" + And I see that the dropdown for tags in the settings eventually contains the tag "tag2" + And I see that the dropdown for tags in the settings eventually contains the tag "tag3" + And I see that the dropdown for tags in the settings eventually contains the tag "tag4" + And I log out + And I am logged in + And I open the details view for "welcome.txt" + And I open the input field for tags in the details view + # When the input field is opened the dropdown is also opened automatically. + And I check the tag "tag2" in the dropdown for tags in the details view + And I check the tag "tag4" in the dropdown for tags in the details view + And I check the tag "tag3" in the dropdown for tags in the details view + When I uncheck the tag "tag2" in the dropdown for tags in the details view + And I uncheck the tag "tag4" in the dropdown for tags in the details view + Then I see that the tag "tag2" in the dropdown for tags in the details view is not checked + And I see that the tag "tag4" in the dropdown for tags in the details view is not checked + And I see that the tag "tag3" in the dropdown for tags in the details view is checked + And I see that the input field for tags in the details view does not contain the tag "tag2" + And I see that the input field for tags in the details view does not contain the tag "tag4" + And I see that the input field for tags in the details view contains the tag "tag3" diff --git a/tests/acceptance/features/bootstrap/FilesAppContext.php b/tests/acceptance/features/bootstrap/FilesAppContext.php index b9ccb7316ab..61f6b115ac6 100644 --- a/tests/acceptance/features/bootstrap/FilesAppContext.php +++ b/tests/acceptance/features/bootstrap/FilesAppContext.php @@ -104,6 +104,41 @@ class FilesAppContext implements Context, ActorAwareInterface { describedAs("Input field for tags in current section details view in Files app"); } + /** + * @return Locator + */ + public static function itemInInputFieldForTagsInCurrentSectionDetailsViewForTag($tag) { + return Locator::forThe()->xpath("//span[normalize-space() = '$tag']")-> + descendantOf(self::inputFieldForTagsInCurrentSectionDetailsView())-> + describedAs("Item in input field for tags in current section details view for tag $tag in Files app"); + } + + /** + * @return Locator + */ + public static function itemInDropdownForTag($tag) { + return Locator::forThe()->xpath("//*[contains(concat(' ', normalize-space(@class), ' '), ' select2-result-label ')]//span[normalize-space() = '$tag']/ancestor::li")-> + descendantOf(self::select2Dropdown())-> + describedAs("Item in dropdown for tag $tag in Files app"); + } + + /** + * @return Locator + */ + public static function checkmarkInItemInDropdownForTag($tag) { + return Locator::forThe()->css(".checkmark")-> + descendantOf(self::itemInDropdownForTag($tag))-> + describedAs("Checkmark in item in dropdown for tag $tag in Files app"); + } + + /** + * @return Locator + */ + private static function select2Dropdown() { + return Locator::forThe()->css("#select2-drop")-> + describedAs("Select2 dropdown in Files app"); + } + /** * @return Locator */ @@ -323,6 +358,24 @@ class FilesAppContext implements Context, ActorAwareInterface { $this->actor->find(self::viewFileInFolderMenuItem(), 2)->click(); } + /** + * @When I check the tag :tag in the dropdown for tags in the details view + */ + public function iCheckTheTagInTheDropdownForTagsInTheDetailsView($tag) { + $this->iSeeThatTheTagInTheDropdownForTagsInTheDetailsViewIsNotChecked($tag); + + $this->actor->find(self::itemInDropdownForTag($tag), 10)->click(); + } + + /** + * @When I uncheck the tag :tag in the dropdown for tags in the details view + */ + public function iUncheckTheTagInTheDropdownForTagsInTheDetailsView($tag) { + $this->iSeeThatTheTagInTheDropdownForTagsInTheDetailsViewIsChecked($tag); + + $this->actor->find(self::itemInDropdownForTag($tag), 10)->click(); + } + /** * @When I protect the shared link with the password :password */ @@ -389,6 +442,46 @@ class FilesAppContext implements Context, ActorAwareInterface { $this->actor->find(self::inputFieldForTagsInCurrentSectionDetailsView(), 10)->isVisible()); } + /** + * @Then I see that the input field for tags in the details view contains the tag :tag + */ + public function iSeeThatTheInputFieldForTagsInTheDetailsViewContainsTheTag($tag) { + PHPUnit_Framework_Assert::assertTrue( + $this->actor->find(self::itemInInputFieldForTagsInCurrentSectionDetailsViewForTag($tag), 10)->isVisible()); + } + + /** + * @Then I see that the input field for tags in the details view does not contain the tag :tag + */ + public function iSeeThatTheInputFieldForTagsInTheDetailsViewDoesNotContainTheTag($tag) { + $this->iSeeThatTheInputFieldForTagsInTheDetailsViewIsShown(); + + try { + PHPUnit_Framework_Assert::assertFalse( + $this->actor->find(self::itemInInputFieldForTagsInCurrentSectionDetailsViewForTag($tag))->isVisible()); + } catch (NoSuchElementException $exception) { + } + } + + /** + * @Then I see that the tag :tag in the dropdown for tags in the details view is checked + */ + public function iSeeThatTheTagInTheDropdownForTagsInTheDetailsViewIsChecked($tag) { + PHPUnit_Framework_Assert::assertTrue( + $this->actor->find(self::checkmarkInItemInDropdownForTag($tag), 10)->isVisible()); + } + + /** + * @Then I see that the tag :tag in the dropdown for tags in the details view is not checked + */ + public function iSeeThatTheTagInTheDropdownForTagsInTheDetailsViewIsNotChecked($tag) { + PHPUnit_Framework_Assert::assertTrue( + $this->actor->find(self::itemInDropdownForTag($tag), 10)->isVisible()); + + PHPUnit_Framework_Assert::assertFalse( + $this->actor->find(self::checkmarkInItemInDropdownForTag($tag))->isVisible()); + } + /** * @When I see that the :tabName tab in the details view is eventually loaded */ diff --git a/tests/acceptance/features/bootstrap/SettingsContext.php b/tests/acceptance/features/bootstrap/SettingsContext.php new file mode 100644 index 00000000000..edbb6a94d15 --- /dev/null +++ b/tests/acceptance/features/bootstrap/SettingsContext.php @@ -0,0 +1,152 @@ +. + * + */ + +use Behat\Behat\Context\Context; + +class SettingsContext implements Context, ActorAwareInterface { + + use ActorAware; + + /** + * @return Locator + */ + public static function systemTagsSelectTagButton() { + return Locator::forThe()->id("s2id_systemtag")-> + describedAs("Select tag button in system tags section in Administration Settings"); + } + + /** + * @return Locator + */ + public static function systemTagsItemInDropdownForTag($tag) { + return Locator::forThe()->xpath("//*[contains(concat(' ', normalize-space(@class), ' '), ' select2-result-label ')]//span[normalize-space() = '$tag']/ancestor::li")-> + descendantOf(self::select2Dropdown())-> + describedAs("Item in dropdown for tag $tag in system tags section in Administration Settings"); + } + + /** + * @return Locator + */ + private static function select2Dropdown() { + return Locator::forThe()->css("#select2-drop")-> + describedAs("Select2 dropdown in Settings"); + } + + /** + * @return Locator + */ + private static function select2DropdownMask() { + return Locator::forThe()->css("#select2-drop-mask")-> + describedAs("Select2 dropdown mask in Settings"); + } + + /** + * @return Locator + */ + public static function systemTagsTagNameInput() { + return Locator::forThe()->id("systemtag_name")-> + describedAs("Tag name input in system tags section in Administration Settings"); + } + + /** + * @return Locator + */ + public static function systemTagsCreateOrUpdateButton() { + return Locator::forThe()->id("systemtag_submit")-> + describedAs("Create/Update button in system tags section in Administration Settings"); + } + + /** + * @return Locator + */ + public static function systemTagsResetButton() { + return Locator::forThe()->id("systemtag_reset")-> + describedAs("Reset button in system tags section in Administration Settings"); + } + + /** + * @When I create the tag :tag in the settings + */ + public function iCreateTheTagInTheSettings($tag) { + $this->actor->find(self::systemTagsResetButton(), 10)->click(); + $this->actor->find(self::systemTagsTagNameInput())->setValue($tag); + $this->actor->find(self::systemTagsCreateOrUpdateButton())->click(); + } + + /** + * @Then I see that the button to select tags is shown + */ + public function iSeeThatTheButtonToSelectTagsIsShown() { + PHPUnit_Framework_Assert::assertTrue($this->actor->find(self::systemTagsSelectTagButton(), 10)->isVisible()); + } + + /** + * @Then I see that the dropdown for tags in the settings eventually contains the tag :tag + */ + public function iSeeThatTheDropdownForTagsInTheSettingsEventuallyContainsTheTag($tag) { + // When the dropdown is opened it is not automatically updated if new + // tags are added to the server, and when a tag is created, no explicit + // feedback is provided to the user about the completion of that + // operation (that is, when the tag is added to the server). Therefore, + // to verify that creating a tag does in fact add it to the server it is + // necessary to repeatedly open the dropdown until the tag is shown in + // the dropdown (or the limit of tries is reached). + + PHPUnit_Framework_Assert::assertTrue($this->actor->find(self::systemTagsSelectTagButton(), 10)->isVisible()); + + $actor = $this->actor; + + $tagFoundInDropdownCallback = function() use($actor, $tag) { + // Open the dropdown to look for the tag. + $actor->find(self::systemTagsSelectTagButton())->click(); + + // When the dropdown is opened it is initially empty, and its + // contents are updated once received from the server. Therefore, a + // timeout must be used when looking for the tags. + try { + $tagFound = $this->actor->find(self::systemTagsItemInDropdownForTag($tag), 10)->isVisible(); + } catch (NoSuchElementException $exception) { + $tagFound = false; + } + + // Close again the dropdown after looking for the tag. When a + // dropdown is opened Select2 creates a special element that masks + // every other element but the dropdown to get all mouse clicks; + // this is used by Select2 to close the dropdown when the user + // clicks outside it. + $actor->find(self::select2DropdownMask())->click(); + + return $tagFound; + }; + + $numberOfTries = 5; + for ($i = 0; $i < $numberOfTries; $i++) { + if ($tagFoundInDropdownCallback()) { + return; + } + } + + PHPUnit_Framework_Assert::fail("The dropdown in system tags section in Administration Settings does not contain the tag $tag after $numberOfTries tries"); + } + +} diff --git a/tests/acceptance/features/bootstrap/SettingsMenuContext.php b/tests/acceptance/features/bootstrap/SettingsMenuContext.php index 1ff5d94e98f..cc0fc81cf78 100644 --- a/tests/acceptance/features/bootstrap/SettingsMenuContext.php +++ b/tests/acceptance/features/bootstrap/SettingsMenuContext.php @@ -43,6 +43,13 @@ class SettingsMenuContext implements Context, ActorAwareInterface { describedAs("Settings menu"); } + /** + * @return Locator + */ + public static function adminMenuItem() { + return self::menuItemFor("Admin"); + } + /** * @return Locator */ @@ -73,6 +80,15 @@ class SettingsMenuContext implements Context, ActorAwareInterface { $this->actor->find(self::settingsMenuButton(), 10)->click(); } + /** + * @When I open the Admin settings + */ + public function iOpenTheAdminSettings() { + $this->iOpenTheSettingsMenu(); + + $this->actor->find(self::adminMenuItem(), 2)->click(); + } + /** * @When I open the User settings */ From bf4913acb965aa3771ae06971c35332fae4dff32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 8 Jul 2017 15:49:12 +0200 Subject: [PATCH 4/5] Add select2-toggleselect to the JavaScript files to load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "select2-toggleselect.js" provides an extension to Select2 that makes possible to unselect items in a multi-select dropdown by clicking on them. It seems that its load slipped through when moving things around in commit 6a470e59356b8c52115fe2790666027f38977604; this commit adds it to the JavaScript files to be loaded in the same position that it should have had in that commit (based on how the other declarations were moved). Signed-off-by: Daniel Calviño Sánchez --- core/js/merged-template-prepend.json | 1 + 1 file changed, 1 insertion(+) diff --git a/core/js/merged-template-prepend.json b/core/js/merged-template-prepend.json index 0dd6bed5329..0de1da0bf62 100644 --- a/core/js/merged-template-prepend.json +++ b/core/js/merged-template-prepend.json @@ -12,6 +12,7 @@ "mimetype.js", "mimetypelist.js", "oc-backbone.js", + "select2-toggleselect.js", "placeholder.js", "jquery.avatar.js", "jquery.contactsmenu.js" From 3a660a1b89f4a95abf30331dddf0e1b6f499752d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 8 Jul 2017 15:56:19 +0200 Subject: [PATCH 5/5] Enable the toggleSelect extension in multi-select dropdowns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The toggleSelect extension for Select2 makes possible to unselect items in a multi-select dropdown by clicking on them; this behaviour should be enabled in all the multi-select dropdowns used in the server. Signed-off-by: Daniel Calviño Sánchez --- apps/files_external/js/settings.js | 1 + apps/systemtags/js/systemtagsfilelist.js | 1 + settings/js/settings.js | 1 + 3 files changed, 3 insertions(+) diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 4e35ea531eb..112676b8c27 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -93,6 +93,7 @@ function addSelect2 ($elements, userListLimit) { placeholder: t('files_external', 'All users. Type to select user or group.'), allowClear: true, multiple: true, + toggleSelect: true, dropdownCssClass: 'files-external-select2', //minimumInputLength: 1, ajax: { diff --git a/apps/systemtags/js/systemtagsfilelist.js b/apps/systemtags/js/systemtagsfilelist.js index c2a6f09fd9e..a40eb548d9f 100644 --- a/apps/systemtags/js/systemtagsfilelist.js +++ b/apps/systemtags/js/systemtagsfilelist.js @@ -88,6 +88,7 @@ placeholder: t('systemtags', 'Select tags to filter by'), allowClear: false, multiple: true, + toggleSelect: true, separator: ',', query: _.bind(this._queryTagsAutocomplete, this), diff --git a/settings/js/settings.js b/settings/js/settings.js index 5a2ba4bcec7..3a1e67f41cd 100644 --- a/settings/js/settings.js +++ b/settings/js/settings.js @@ -30,6 +30,7 @@ OC.Settings = _.extend(OC.Settings, { placeholder: t('core', 'Groups'), allowClear: true, multiple: true, + toggleSelect: true, separator: '|', query: _.debounce(function(query) { var queryData = {};