From 39f3dbd945af19d7e1bdc165d2ecf17f256b7e2f Mon Sep 17 00:00:00 2001
From: Joffrey JAFFEUX
Date: Tue, 21 Nov 2017 11:53:09 +0100
Subject: [PATCH] Introduces select-kit
* renames `select-box-kit` into `select-kit`
* introduces `single-select` and `multi-select` as base components
* introduces {{search-advanced-category-chooser}} as a better component for selecting category in advanced search
* improves events handling in select-kit
* recreates color selection inputs using {{multi-select}} and a custom {{selected-color}} component
* replaces category-selector by a component using select-kit and based on multi-select
* improves positioning of wrapper
* removes the need for offscreen, and instead use `select-kit-header` as a base focus point for all select-kit based components
* introduces a formal plugin api for select-kit based components
* introduces a formal pattern for loading and updating select-kit based components:
```
computeValue()
computeContent()
mutateValue()
```
---
.eslintrc | 12 +-
.../site-settings/category-list.hbs | 2 +-
.../admin/templates/web-hooks-show.hbs | 2 +-
app/assets/javascripts/application.js | 2 +-
.../discourse-common/lib/icon-library.js.es6 | 21 +-
.../components/category-selector.js.es6 | 49 ---
.../components/future-date-input.js.es6 | 2 +-
.../components/search-advanced-options.js.es6 | 16 +-
.../components/topic-timeline.js.es6 | 1 +
.../discourse/lib/plugin-api.js.es6 | 16 +
.../components/category-selector.hbs | 1 -
.../templates/components/d-navigation.hbs | 2 +-
.../components/edit-category-general.hbs | 2 +
.../components/search-advanced-options.hbs | 2 +-
.../components/topic-footer-buttons.hbs | 4 +-
.../javascripts/discourse/templates/topic.hbs | 1 +
.../discourse/templates/topic/unsubscribe.hbs | 2 +-
.../discourse/templates/user/messages.hbs | 2 +-
.../widgets/component_connector.js.es6 | 18 +-
.../discourse/widgets/topic-timeline.js.es6 | 9 +-
.../components/admin-group-selector.js.es6 | 45 ---
.../components/category-chooser.js.es6 | 131 ------
.../category-notifications-button.js.es6 | 13 -
...ategory-notifications-button-header.js.es6 | 13 -
.../combo-box/combo-box-header.js.es6 | 39 --
.../components/dropdown-select-box.js.es6 | 22 --
.../dropdown-select-box-header.js.es6 | 6 -
.../dropdown-select-box-row.js.es6 | 9 -
.../future-date-input-selector-header.js.es6 | 14 -
.../future-date-input-selector-row.js.es6 | 14 -
.../components/list-setting.js.es6 | 55 ---
.../components/multi-combo-box.js.es6 | 240 -----------
.../multi-combo-box/selected-color.js.es6 | 8 -
.../notifications-button-header.js.es6 | 26 --
.../components/pinned-options.js.es6 | 60 ---
.../pinned-options-header.js.es6 | 30 --
.../components/select-box-kit.js.es6 | 328 ---------------
.../select-box-kit-collection.js.es6 | 5 -
.../select-box-kit-create-row.js.es6 | 10 -
.../select-box-kit-header.js.es6 | 28 --
.../select-box-kit-none-row.js.es6 | 10 -
.../select-box-kit/select-box-kit-row.js.es6 | 70 ----
.../tag-notifications-button.js.es6 | 12 -
.../tag-notifications-button-header.js.es6 | 13 -
.../select-box-kit/mixins/keyboard.js.es6 | 222 -----------
.../components/combo-box/combo-box-header.hbs | 15 -
.../dropdown-select-box-header.hbs | 18 -
.../multi-combo-box-header.hbs | 13 -
.../multi-combo-box/selected-name.hbs | 9 -
.../select-box-kit/select-box-kit-header.hbs | 7 -
.../select-box-kit/select-box-kit-row.hbs | 9 -
.../admin-agree-flag-dropdown.js.es6 | 29 +-
.../admin-delete-flag-dropdown.js.es6 | 25 +-
.../components/admin-group-selector.js.es6 | 51 +++
.../categories-admin-dropdown.js.es6 | 23 +-
.../components/category-chooser.js.es6 | 92 +++++
.../category-notifications-button.js.es6 | 20 +
.../select-kit/components/category-row.js.es6 | 63 +++
.../components/category-selector.js.es6 | 40 ++
.../components/combo-box.js.es6 | 11 +-
.../combo-box/combo-box-header.js.es6 | 21 +
.../components/dropdown-select-box.js.es6 | 32 ++
.../dropdown-select-box-header.js.es6 | 15 +
.../dropdown-select-box-row.js.es6 | 9 +
.../future-date-input-selector.js.es6 | 39 +-
.../future-date-input-selector-header.js.es6 | 6 +
.../future-date-input-selector-row.js.es6 | 6 +
.../future-date-input-selector/mixin.js.es6 | 11 +-
.../group-notifications-button.js.es6 | 7 +-
.../select-kit/components/list-setting.js.es6 | 54 +++
.../select-kit/components/multi-select.js.es6 | 255 ++++++++++++
.../multi-select/multi-select-header.js.es6} | 14 +-
.../multi-select/selected-category.js.es6 | 13 +
.../multi-select/selected-color.js.es6 | 11 +
.../multi-select}/selected-name.js.es6 | 17 +-
.../components/none-category-row.js.es6 | 10 +
.../components/notifications-button.js.es6 | 27 +-
.../notifications-button-row.js.es6 | 8 +-
.../components/pinned-button.js.es6 | 7 +-
.../components/pinned-options.js.es6 | 55 +++
.../search-advanced-category-chooser.js.es6 | 20 +
.../select-kit/components/select-kit.js.es6 | 239 +++++++++++
.../select-kit/select-kit-collection.js.es6 | 5 +
.../select-kit/select-kit-create-row.js.es6 | 10 +
.../select-kit/select-kit-filter.js.es6} | 4 +-
.../select-kit/select-kit-header.js.es6 | 35 ++
.../select-kit/select-kit-none-row.js.es6 | 10 +
.../select-kit/select-kit-row.js.es6 | 58 +++
.../components/single-select.js.es6 | 168 ++++++++
.../tag-notifications-button.js.es6 | 23 ++
.../topic-footer-mobile-dropdown.js.es6 | 30 +-
.../topic-notifications-button.js.es6 | 2 +-
.../topic-notifications-options.js.es6 | 9 +-
.../mixins/dom-helpers.js.es6 | 99 ++---
.../select-kit/mixins/events.js.es6 | 233 +++++++++++
.../select-kit/mixins/plugin-api.js.es6 | 71 ++++
.../mixins/utils.js.es6 | 46 +--
.../templates/components/category-row.hbs | 19 +
.../components/combo-box/combo-box-header.hbs | 13 +
.../dropdown-select-box-header.hbs | 7 +
.../dropdown-select-box-row.hbs | 4 +-
.../future-date-input-selector-header.hbs | 14 +-
.../future-date-input-selector-row.hbs | 6 +-
.../multi-select/multi-select-header.hbs | 13 +
.../multi-select/selected-category.hbs | 7 +
.../multi-select/selected-color.hbs | 13 +
.../components/multi-select/selected-name.hbs | 13 +
.../templates/components/pinned-button.hbs | 2 +-
.../templates/components/select-kit.hbs} | 41 +-
.../select-kit/select-kit-collection.hbs} | 30 +-
.../select-kit/select-kit-filter.hbs} | 4 +-
.../select-kit/select-kit-header.hbs | 5 +
.../components/select-kit/select-kit-row.hbs | 6 +
.../components/topic-notifications-button.hbs | 5 +-
app/assets/javascripts/wizard-application.js | 2 +-
.../wizard/test/acceptance/wizard-test.js.es6 | 2 +-
app/assets/stylesheets/common.scss | 2 +-
.../stylesheets/common/admin/admin_base.scss | 8 +-
.../stylesheets/common/admin/flagging.scss | 4 +-
.../stylesheets/common/base/_topic-list.scss | 2 +-
.../base/edit-topic-status-update-modal.scss | 2 +-
app/assets/stylesheets/common/base/modal.scss | 2 +-
.../common/base/notifications-button.scss | 9 -
.../categories-admin-dropdown.scss | 12 -
.../admin-agree-flag-dropdown.scss | 6 +-
.../admin-delete-flag-dropdown.scss | 0
.../select-kit/categories-admin-dropdown.scss | 12 +
.../category-chooser.scss | 4 +-
.../combo-box.scss | 24 +-
.../dropdown-select-box.scss | 76 ++--
.../future-date-input-selector.scss | 2 +-
.../legacy-combo-box.scss | 0
.../list-setting.scss | 6 +-
.../multi-select.scss} | 82 ++--
.../notifications-button.scss | 6 +-
.../pinned-button.scss | 2 +-
.../select-kit.scss} | 51 +--
.../topic-notifications-button.scss | 0
app/assets/stylesheets/mobile/topic-list.scss | 2 +-
app/assets/stylesheets/wizard.scss | 2 +-
config/locales/client.ar.yml | 2 +-
config/locales/client.de.yml | 2 +-
config/locales/client.el.yml | 2 +-
config/locales/client.en.yml | 2 +-
config/locales/client.es.yml | 2 +-
config/locales/client.fa_IR.yml | 2 +-
config/locales/client.fi.yml | 2 +-
config/locales/client.fr.yml | 2 +-
config/locales/client.it.yml | 2 +-
config/locales/client.ja.yml | 2 +-
config/locales/client.ko.yml | 2 +-
config/locales/client.nb_NO.yml | 2 +-
config/locales/client.nl.yml | 2 +-
config/locales/client.pl_PL.yml | 2 +-
config/locales/client.pt.yml | 2 +-
config/locales/client.ru.yml | 2 +-
config/locales/client.vi.yml | 2 +-
config/locales/client.zh_CN.yml | 2 +-
.../acceptance/details-button-test.js.es6 | 10 +-
.../widgets/discourse-poll-option-test.js.es6 | 8 +-
.../acceptance/admin-flags-test.js.es6 | 24 +-
.../acceptance/admin-suspend-user-test.js.es6 | 4 +-
.../acceptance/category-chooser-test.js.es6 | 6 +-
.../acceptance/category-edit-test.js.es6 | 4 +-
.../acceptance/composer-test.js.es6 | 4 +-
.../acceptance/search-full-test.js.es6 | 32 +-
.../javascripts/acceptance/search-test.js.es6 | 44 +--
.../topic-notifications-button-test.js.es6 | 6 +-
test/javascripts/acceptance/topic-test.js.es6 | 12 +-
.../categories-admin-dropdown-test.js.es6 | 10 +-
.../components/category-chooser-test.js.es6 | 40 +-
.../components/categpry-selector-test.js.es6 | 67 ++++
.../components/combo-box-test.js.es6 | 86 ++--
.../components/d-button-test.js.es6 | 4 +-
.../components/list-setting-test.js.es6 | 42 +-
.../components/multi-combo-box-test.js.es6 | 109 -----
.../components/multi-select-test.js.es6 | 109 +++++
.../components/pinned-button-test.js.es6 | 40 --
.../components/pinned-options-test.js.es6 | 35 ++
.../components/select-box-kit-test.js.es6 | 288 --------------
.../components/single-select-test.js.es6 | 372 ++++++++++++++++++
.../topic-footer-mobile-dropdown-test.js.es6 | 12 +-
.../topic-notifications-button-test.js.es6 | 16 +-
.../helpers/select-box-kit-helper.js | 146 -------
test/javascripts/helpers/select-kit-helper.js | 149 +++++++
test/javascripts/test_helper.js | 2 +-
.../widgets/actions-summary-test.js.es6 | 2 +-
test/javascripts/widgets/button-test.js.es6 | 4 +-
.../javascripts/widgets/home-logo-test.js.es6 | 2 +-
test/javascripts/widgets/post-test.js.es6 | 6 +-
.../widgets/poster-name-test.js.es6 | 2 +-
191 files changed, 3160 insertions(+), 2788 deletions(-)
delete mode 100644 app/assets/javascripts/discourse/components/category-selector.js.es6
delete mode 100644 app/assets/javascripts/discourse/templates/components/category-selector.hbs
delete mode 100644 app/assets/javascripts/select-box-kit/components/admin-group-selector.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/category-chooser.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/category-notifications-button.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/category-notifications-button/category-notifications-button-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/combo-box/combo-box-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/dropdown-select-box.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/list-setting.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/multi-combo-box.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/multi-combo-box/selected-color.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/notifications-button/notifications-button-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/pinned-options.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/pinned-options/pinned-options-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/select-box-kit.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-collection.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-create-row.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-none-row.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-row.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/tag-notifications-button.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/components/tag-notifications-button/tag-notifications-button-header.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/mixins/keyboard.js.es6
delete mode 100644 app/assets/javascripts/select-box-kit/templates/components/combo-box/combo-box-header.hbs
delete mode 100644 app/assets/javascripts/select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs
delete mode 100644 app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/multi-combo-box-header.hbs
delete mode 100644 app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/selected-name.hbs
delete mode 100644 app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-header.hbs
delete mode 100644 app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-row.hbs
rename app/assets/javascripts/{select-box-kit => select-kit}/components/admin-agree-flag-dropdown.js.es6 (76%)
rename app/assets/javascripts/{select-box-kit => select-kit}/components/admin-delete-flag-dropdown.js.es6 (74%)
create mode 100644 app/assets/javascripts/select-kit/components/admin-group-selector.js.es6
rename app/assets/javascripts/{select-box-kit => select-kit}/components/categories-admin-dropdown.js.es6 (51%)
create mode 100644 app/assets/javascripts/select-kit/components/category-chooser.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/category-notifications-button.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/category-row.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/category-selector.js.es6
rename app/assets/javascripts/{select-box-kit => select-kit}/components/combo-box.js.es6 (61%)
create mode 100644 app/assets/javascripts/select-kit/components/combo-box/combo-box-header.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/dropdown-select-box.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6
rename app/assets/javascripts/{select-box-kit => select-kit}/components/future-date-input-selector.js.es6 (79%)
create mode 100644 app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6
rename app/assets/javascripts/{select-box-kit => select-kit}/components/future-date-input-selector/mixin.js.es6 (76%)
rename app/assets/javascripts/{select-box-kit => select-kit}/components/group-notifications-button.js.es6 (51%)
create mode 100644 app/assets/javascripts/select-kit/components/list-setting.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/multi-select.js.es6
rename app/assets/javascripts/{select-box-kit/components/multi-combo-box/multi-combo-box-header.js.es6 => select-kit/components/multi-select/multi-select-header.js.es6} (66%)
create mode 100644 app/assets/javascripts/select-kit/components/multi-select/selected-category.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/multi-select/selected-color.js.es6
rename app/assets/javascripts/{select-box-kit/components/multi-combo-box => select-kit/components/multi-select}/selected-name.js.es6 (50%)
create mode 100644 app/assets/javascripts/select-kit/components/none-category-row.js.es6
rename app/assets/javascripts/{select-box-kit => select-kit}/components/notifications-button.js.es6 (56%)
rename app/assets/javascripts/{select-box-kit => select-kit}/components/notifications-button/notifications-button-row.js.es6 (76%)
rename app/assets/javascripts/{select-box-kit => select-kit}/components/pinned-button.js.es6 (71%)
create mode 100644 app/assets/javascripts/select-kit/components/pinned-options.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/search-advanced-category-chooser.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/select-kit.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/select-kit/select-kit-collection.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/select-kit/select-kit-create-row.js.es6
rename app/assets/javascripts/{select-box-kit/components/select-box-kit/select-box-kit-filter.js.es6 => select-kit/components/select-kit/select-kit-filter.js.es6} (51%)
create mode 100644 app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/select-kit/select-kit-none-row.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/select-kit/select-kit-row.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/single-select.js.es6
create mode 100644 app/assets/javascripts/select-kit/components/tag-notifications-button.js.es6
rename app/assets/javascripts/{select-box-kit => select-kit}/components/topic-footer-mobile-dropdown.js.es6 (68%)
rename app/assets/javascripts/{select-box-kit => select-kit}/components/topic-notifications-button.js.es6 (62%)
rename app/assets/javascripts/{select-box-kit => select-kit}/components/topic-notifications-options.js.es6 (79%)
rename app/assets/javascripts/{select-box-kit => select-kit}/mixins/dom-helpers.js.es6 (71%)
create mode 100644 app/assets/javascripts/select-kit/mixins/events.js.es6
create mode 100644 app/assets/javascripts/select-kit/mixins/plugin-api.js.es6
rename app/assets/javascripts/{select-box-kit => select-kit}/mixins/utils.js.es6 (52%)
create mode 100644 app/assets/javascripts/select-kit/templates/components/category-row.hbs
create mode 100644 app/assets/javascripts/select-kit/templates/components/combo-box/combo-box-header.hbs
create mode 100644 app/assets/javascripts/select-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs
rename app/assets/javascripts/{select-box-kit => select-kit}/templates/components/dropdown-select-box/dropdown-select-box-row.hbs (78%)
rename app/assets/javascripts/{select-box-kit => select-kit}/templates/components/future-date-input-selector/future-date-input-selector-header.hbs (51%)
rename app/assets/javascripts/{select-box-kit => select-kit}/templates/components/future-date-input-selector/future-date-input-selector-row.hbs (58%)
create mode 100644 app/assets/javascripts/select-kit/templates/components/multi-select/multi-select-header.hbs
create mode 100644 app/assets/javascripts/select-kit/templates/components/multi-select/selected-category.hbs
create mode 100644 app/assets/javascripts/select-kit/templates/components/multi-select/selected-color.hbs
create mode 100644 app/assets/javascripts/select-kit/templates/components/multi-select/selected-name.hbs
rename app/assets/javascripts/{select-box-kit => select-kit}/templates/components/pinned-button.hbs (50%)
rename app/assets/javascripts/{select-box-kit/templates/components/select-box-kit.hbs => select-kit/templates/components/select-kit.hbs} (56%)
rename app/assets/javascripts/{select-box-kit/templates/components/select-box-kit/select-box-kit-collection.hbs => select-kit/templates/components/select-kit/select-kit-collection.hbs} (62%)
rename app/assets/javascripts/{select-box-kit/templates/components/select-box-kit/select-box-kit-filter.hbs => select-kit/templates/components/select-kit/select-kit-filter.hbs} (77%)
create mode 100644 app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs
create mode 100644 app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs
rename app/assets/javascripts/{select-box-kit => select-kit}/templates/components/topic-notifications-button.hbs (50%)
delete mode 100644 app/assets/stylesheets/common/base/notifications-button.scss
delete mode 100644 app/assets/stylesheets/common/select-box-kit/categories-admin-dropdown.scss
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/admin-agree-flag-dropdown.scss (64%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/admin-delete-flag-dropdown.scss (100%)
create mode 100644 app/assets/stylesheets/common/select-kit/categories-admin-dropdown.scss
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/category-chooser.scss (92%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/combo-box.scss (80%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/dropdown-select-box.scss (67%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/future-date-input-selector.scss (93%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/legacy-combo-box.scss (100%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/list-setting.scss (56%)
rename app/assets/stylesheets/common/{select-box-kit/multi-combo-box.scss => select-kit/multi-select.scss} (61%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/notifications-button.scss (69%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/pinned-button.scss (94%)
rename app/assets/stylesheets/common/{select-box-kit/select-box-kit.scss => select-kit/select-kit.scss} (86%)
rename app/assets/stylesheets/common/{select-box-kit => select-kit}/topic-notifications-button.scss (100%)
create mode 100644 test/javascripts/components/categpry-selector-test.js.es6
delete mode 100644 test/javascripts/components/multi-combo-box-test.js.es6
create mode 100644 test/javascripts/components/multi-select-test.js.es6
delete mode 100644 test/javascripts/components/pinned-button-test.js.es6
create mode 100644 test/javascripts/components/pinned-options-test.js.es6
delete mode 100644 test/javascripts/components/select-box-kit-test.js.es6
create mode 100644 test/javascripts/components/single-select-test.js.es6
delete mode 100644 test/javascripts/helpers/select-box-kit-helper.js
create mode 100644 test/javascripts/helpers/select-kit-helper.js
diff --git a/.eslintrc b/.eslintrc
index 6f7c9f0ecdd..bfbe34ea65e 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -42,12 +42,12 @@
"invisible":true,
"asyncRender":true,
"selectDropdown":true,
- "selectBox":true,
- "expandSelectBoxKit":true,
- "collapseSelectBoxKit":true,
- "selectBoxKitSelectRow":true,
- "selectBoxKitSelectNoneRow":true,
- "selectBoxKitFillInFilter":true,
+ "selectKit":true,
+ "expandSelectKit":true,
+ "collapseSelectKit":true,
+ "selectKitSelectRow":true,
+ "selectKitSelectNoneRow":true,
+ "selectKitFillInFilter":true,
"asyncTestDiscourse":true,
"fixture":true,
"find":true,
diff --git a/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs
index 8c0b4eda1e9..0aadec18d81 100644
--- a/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs
+++ b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs
@@ -1,3 +1,3 @@
-{{category-selector categories=selectedCategories blacklist=selectedCategories}}
+{{category-selector categories=selectedCategories}}
{{{unbound setting.description}}}
{{setting-validation-message message=validationMessage}}
diff --git a/app/assets/javascripts/admin/templates/web-hooks-show.hbs b/app/assets/javascripts/admin/templates/web-hooks-show.hbs
index 53c0cba1467..ef9c478774a 100644
--- a/app/assets/javascripts/admin/templates/web-hooks-show.hbs
+++ b/app/assets/javascripts/admin/templates/web-hooks-show.hbs
@@ -48,7 +48,7 @@
{{d-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.categories_filter'}}
- {{category-selector categories=model.categories blacklist=model.categories}}
+ {{category-selector categories=model.categories}}
{{i18n 'admin.web_hooks.categories_filter_instructions'}}
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 280e12954ee..6b0d64be848 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -4,7 +4,7 @@
//= require ./ember-addons/ember-computed-decorators
//= require ./ember-addons/fmt
//= require_tree ./discourse-common
-//= require_tree ./select-box-kit
+//= require_tree ./select-kit
//= require ./discourse
//= require ./deprecated
diff --git a/app/assets/javascripts/discourse-common/lib/icon-library.js.es6 b/app/assets/javascripts/discourse-common/lib/icon-library.js.es6
index 0dcf4051cd8..15001e4ca59 100644
--- a/app/assets/javascripts/discourse-common/lib/icon-library.js.es6
+++ b/app/assets/javascripts/discourse-common/lib/icon-library.js.es6
@@ -42,7 +42,8 @@ export function renderIcon(renderType, id, params) {
let rendererForType = renderer[renderType];
if (rendererForType) {
- let result = rendererForType(REPLACEMENTS[id] || id, params || {});
+ const icon = { id, replacementId: REPLACEMENTS[id] };
+ let result = rendererForType(icon, params || {});
if (result) {
return result;
}
@@ -68,8 +69,14 @@ export function registerIconRenderer(renderer) {
}
// Support for font awesome icons
-function faClasses(id, params) {
- let classNames = `fa fa-${id} d-icon d-icon-${id}`;
+function faClasses(icon, params) {
+ let classNames;
+ if (typeof icon.replacementId !== "undefined") {
+ classNames = `fa fa-${icon.replacementId} d-icon ${icon.id}`;
+ } else {
+ classNames = `fa fa-${icon.id} d-icon d-${icon.id}`;
+ }
+
if (params) {
if (params.modifier) { classNames += " fa-" + params.modifier; }
if (params['class']) { classNames += ' ' + params['class']; }
@@ -81,9 +88,9 @@ function faClasses(id, params) {
registerIconRenderer({
name: 'font-awesome',
- string(id, params) {
+ string(icon, params) {
let tagName = params.tagName || 'i';
- let html = `<${tagName} class='${faClasses(id, params)}'`;
+ let html = `<${tagName} class='${faClasses(icon, params)}'`;
if (params.title) { html += ` title='${I18n.t(params.title)}'`; }
if (params.label) { html += " aria-hidden='true'"; }
html += `>${tagName}>`;
@@ -93,11 +100,11 @@ registerIconRenderer({
return html;
},
- node(id, params) {
+ node(icon, params) {
let tagName = params.tagName || 'i';
const properties = {
- className: faClasses(id, params),
+ className: faClasses(icon, params),
attributes: { "aria-hidden": true }
};
diff --git a/app/assets/javascripts/discourse/components/category-selector.js.es6 b/app/assets/javascripts/discourse/components/category-selector.js.es6
deleted file mode 100644
index 9cb3eec14ae..00000000000
--- a/app/assets/javascripts/discourse/components/category-selector.js.es6
+++ /dev/null
@@ -1,49 +0,0 @@
-import { categoryBadgeHTML } from 'discourse/helpers/category-link';
-import Category from 'discourse/models/category';
-import { on, observes } from 'ember-addons/ember-computed-decorators';
-import { findRawTemplate } from 'discourse/lib/raw-templates';
-
-export default Ember.Component.extend({
- @observes('categories')
- _update() {
- if (this.get('canReceiveUpdates') === 'true')
- this._initializeAutocomplete({updateData: true});
- },
-
- @on('didInsertElement')
- _initializeAutocomplete(opts) {
- const self = this,
- regexp = new RegExp(`href=['\"]${Discourse.getURL('/c/')}([^'\"]+)`);
-
- this.$('input').autocomplete({
- items: this.get('categories'),
- single: this.get('single'),
- allowAny: false,
- updateData: (opts && opts.updateData) ? opts.updateData : false,
- dataSource(term) {
- return Category.list().filter(category => {
- const regex = new RegExp(term, 'i');
- return category.get('name').match(regex) &&
- !_.contains(self.get('blacklist') || [], category) &&
- !_.contains(self.get('categories'), category) ;
- });
- },
- onChangeItems(items) {
- const categories = _.map(items, link => {
- const slug = link.match(regexp)[1];
- return Category.findSingleBySlug(slug);
- });
- Em.run.next(() => {
- let existingCategory = _.isArray(self.get('categories')) ? self.get('categories') : [self.get('categories')];
- const result = _.intersection(existingCategory.map(itm => itm.id), categories.map(itm => itm.id));
- if (result.length !== categories.length || existingCategory.length !== categories.length)
- self.set('categories', categories);
- });
- },
- template: findRawTemplate('category-selector-autocomplete'),
- transformComplete(category) {
- return categoryBadgeHTML(category, {allowUncategorized: true});
- }
- });
- }
-});
diff --git a/app/assets/javascripts/discourse/components/future-date-input.js.es6 b/app/assets/javascripts/discourse/components/future-date-input.js.es6
index 97b87387872..5c9d37527e0 100644
--- a/app/assets/javascripts/discourse/components/future-date-input.js.es6
+++ b/app/assets/javascripts/discourse/components/future-date-input.js.es6
@@ -1,7 +1,7 @@
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
import {
FORMAT,
-} from "select-box-kit/components/future-date-input-selector";
+} from "select-kit/components/future-date-input-selector";
import { PUBLISH_TO_CATEGORY_STATUS_TYPE } from 'discourse/controllers/edit-topic-timer';
diff --git a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6
index f29c6f95a39..a171083523d 100644
--- a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6
+++ b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6
@@ -185,18 +185,18 @@ export default Em.Component.extend({
const userInput = Discourse.Category.findBySlug(subcategories[1], subcategories[0]);
if ((!existingInput && userInput)
|| (existingInput && userInput && existingInput.id !== userInput.id))
- this.set('searchedTerms.category', [userInput]);
+ this.set('searchedTerms.category', userInput);
} else
if (isNaN(subcategories)) {
const userInput = Discourse.Category.findSingleBySlug(subcategories[0]);
if ((!existingInput && userInput)
|| (existingInput && userInput && existingInput.id !== userInput.id))
- this.set('searchedTerms.category', [userInput]);
+ this.set('searchedTerms.category', userInput);
} else {
const userInput = Discourse.Category.findById(subcategories[0]);
if ((!existingInput && userInput)
|| (existingInput && userInput && existingInput.id !== userInput.id))
- this.set('searchedTerms.category', [userInput]);
+ this.set('searchedTerms.category', userInput);
}
} else
this.set('searchedTerms.category', '');
@@ -303,11 +303,11 @@ export default Em.Component.extend({
const slugCategoryMatches = (match.length !== 0) ? match[0].match(REGEXP_CATEGORY_SLUG) : null;
const idCategoryMatches = (match.length !== 0) ? match[0].match(REGEXP_CATEGORY_ID) : null;
- if (categoryFilter && categoryFilter[0]) {
- const id = categoryFilter[0].id;
- const slug = categoryFilter[0].slug;
- if (categoryFilter[0].parentCategory) {
- const parentSlug = categoryFilter[0].parentCategory.slug;
+ if (categoryFilter) {
+ const id = categoryFilter.id;
+ const slug = categoryFilter.slug;
+ if (categoryFilter.parentCategory) {
+ const parentSlug = categoryFilter.parentCategory.slug;
if (slugCategoryMatches)
searchTerm = searchTerm.replace(slugCategoryMatches[0], `#${parentSlug}:${slug}`);
else if (idCategoryMatches)
diff --git a/app/assets/javascripts/discourse/components/topic-timeline.js.es6 b/app/assets/javascripts/discourse/components/topic-timeline.js.es6
index cfa9340e940..8512ca6794a 100644
--- a/app/assets/javascripts/discourse/components/topic-timeline.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-timeline.js.es6
@@ -12,6 +12,7 @@ export default MountWidget.extend(Docking, {
buildArgs() {
let attrs = {
topic: this.get('topic'),
+ notificationLevel: this.get('notificationLevel'),
topicTrackingState: this.topicTrackingState,
enteredIndex: this.get('enteredIndex'),
dockAt: this.dockAt,
diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6
index 03467421cb9..a674d497f31 100644
--- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6
+++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6
@@ -21,6 +21,7 @@ import { attachAdditionalPanel } from 'discourse/widgets/header';
import { registerIconRenderer, replaceIcon } from 'discourse-common/lib/icon-library';
import { addNavItem } from 'discourse/models/nav-item';
import { replaceFormatter } from 'discourse/lib/utilities';
+import { modifySelectKit } from "select-kit/mixins/plugin-api";
// If you add any methods to the API ensure you bump up this number
const PLUGIN_API_VERSION = '0.8.12';
@@ -589,6 +590,21 @@ class PluginApi {
formatUsername(fn) {
replaceFormatter(fn);
}
+
+ /**
+ *
+ * Access SelectKit plugin api
+ *
+ * Example:
+ *
+ * modifySelectKit("topic-footer-mobile-dropdown").appendContent(() => [{
+ * name: "discourse",
+ * id: 1
+ * }])
+ */
+ modifySelectKit(pluginApiKey) {
+ return modifySelectKit(pluginApiKey);
+ }
}
let _pluginv01;
diff --git a/app/assets/javascripts/discourse/templates/components/category-selector.hbs b/app/assets/javascripts/discourse/templates/components/category-selector.hbs
deleted file mode 100644
index a265ef5f12b..00000000000
--- a/app/assets/javascripts/discourse/templates/components/category-selector.hbs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/app/assets/javascripts/discourse/templates/components/d-navigation.hbs b/app/assets/javascripts/discourse/templates/components/d-navigation.hbs
index dd0fe03f3e6..6f8c71f5249 100644
--- a/app/assets/javascripts/discourse/templates/components/d-navigation.hbs
+++ b/app/assets/javascripts/discourse/templates/components/d-navigation.hbs
@@ -9,7 +9,7 @@
{{navigation-bar navItems=navItems filterMode=filterMode category=category}}
{{#if showCategoryNotifications}}
- {{category-notifications-button category=category}}
+ {{category-notifications-button value=category.notification_level category=category}}
{{/if}}
{{create-topic-button
diff --git a/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs b/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs
index 4f89ede6048..c31406819a7 100644
--- a/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs
+++ b/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs
@@ -22,7 +22,9 @@
{{category-chooser
none="category.none"
value=category.parent_category_id
+ excludeCategoryId=category.id
categories=parentCategories
+ allowSubCategories=false
allowUncategorized=false}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs b/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs
index c1c1914b64a..eb8342b8ded 100644
--- a/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs
+++ b/app/assets/javascripts/discourse/templates/components/search-advanced-options.hbs
@@ -13,7 +13,7 @@
{{i18n "search.advanced.in_category.label"}}
- {{category-selector categories=searchedTerms.category single="true" canReceiveUpdates="true"}}
+ {{search-advanced-category-chooser value=searchedTerms.category}}
diff --git a/app/assets/javascripts/discourse/templates/components/topic-footer-buttons.hbs b/app/assets/javascripts/discourse/templates/components/topic-footer-buttons.hbs
index a4dcf9987ab..048cff64c98 100644
--- a/app/assets/javascripts/discourse/templates/components/topic-footer-buttons.hbs
+++ b/app/assets/javascripts/discourse/templates/components/topic-footer-buttons.hbs
@@ -74,10 +74,10 @@
args=(hash topic=topic)
connectorTagName="span"}}
- {{pinned-button topic=topic}}
+ {{pinned-button pinned=topic.pinned topic=topic}}
-{{topic-notifications-button topic=topic}}
+{{topic-notifications-button notificationLevel=topic.details.notification_level topic=topic}}
{{plugin-outlet name="after-topic-footer-buttons"
args=(hash topic=topic)
diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs
index f26c41d6414..281ffd8f135 100644
--- a/app/assets/javascripts/discourse/templates/topic.hbs
+++ b/app/assets/javascripts/discourse/templates/topic.hbs
@@ -85,6 +85,7 @@
{{topic-timeline
topic=model
+ notificationLevel=model.details.notification_level
prevEvent=info.prevEvent
fullscreen=info.topicProgressExpanded
enteredIndex=enteredIndex
diff --git a/app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs b/app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs
index 54947fbdaaa..17a4df882eb 100644
--- a/app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs
+++ b/app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs
@@ -8,6 +8,6 @@
{{i18n "topic.unsubscribe.change_notification_state"}}
- {{topic-notifications-button topic=model}}
+ {{topic-notifications-button notificationLevel=model.details.notification_level topic=model}}
diff --git a/app/assets/javascripts/discourse/templates/user/messages.hbs b/app/assets/javascripts/discourse/templates/user/messages.hbs
index 3e19ee722a1..5a788282337 100644
--- a/app/assets/javascripts/discourse/templates/user/messages.hbs
+++ b/app/assets/javascripts/discourse/templates/user/messages.hbs
@@ -73,7 +73,7 @@
{{/if}}
{{#if isGroup}}
- {{group-notifications-button group=group user=model}}
+ {{group-notifications-button value=group.group_user.notification_level group=group user=model}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/widgets/component_connector.js.es6 b/app/assets/javascripts/discourse/widgets/component_connector.js.es6
index 7484fad179d..e603896883c 100644
--- a/app/assets/javascripts/discourse/widgets/component_connector.js.es6
+++ b/app/assets/javascripts/discourse/widgets/component_connector.js.es6
@@ -1,12 +1,13 @@
export default class ComponentConnector {
- constructor(widget, componentName, opts) {
+ constructor(widget, componentName, opts, trackedProperties) {
this.widget = widget;
this.opts = opts;
this.componentName = componentName;
+ this.trackedProperties = trackedProperties || [];
}
init() {
- const $elem = $('${categoryBadgeHTML(Category.findById(parentCategoryId), {link: false})} ${result}`;
- } else {
- result = `
${result}`;
- }
-
- result += ` × ${category.get("topic_count")}
`;
-
- const description = category.get("description");
- // TODO wtf how can this be null?;
- if (description && description !== "null") {
- result += `
${description.substr(0, 200)}${description.length > 200 ? '…' : ''}
`;
- }
-
- return result;
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/category-notifications-button.js.es6 b/app/assets/javascripts/select-box-kit/components/category-notifications-button.js.es6
deleted file mode 100644
index 05908840069..00000000000
--- a/app/assets/javascripts/select-box-kit/components/category-notifications-button.js.es6
+++ /dev/null
@@ -1,13 +0,0 @@
-import NotificationOptionsComponent from "select-box-kit/components/notifications-button";
-
-export default NotificationOptionsComponent.extend({
- classNames: "category-notifications-button",
- isHidden: Ember.computed.or("category.deleted", "site.isMobileDevice"),
- i18nPrefix: "category.notifications",
- value: Ember.computed.alias("category.notification_level"),
- headerComponent: "category-notifications-button/category-notifications-button-header",
-
- selectValueFunction(value) {
- this.get("category").setNotification(value);
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/category-notifications-button/category-notifications-button-header.js.es6 b/app/assets/javascripts/select-box-kit/components/category-notifications-button/category-notifications-button-header.js.es6
deleted file mode 100644
index 8c5ef82fe39..00000000000
--- a/app/assets/javascripts/select-box-kit/components/category-notifications-button/category-notifications-button-header.js.es6
+++ /dev/null
@@ -1,13 +0,0 @@
-import NotificationButtonHeader from "select-box-kit/components/notifications-button/notifications-button-header";
-import computed from "ember-addons/ember-computed-decorators";
-import { iconHTML } from 'discourse-common/lib/icon-library';
-
-export default NotificationButtonHeader.extend({
- classNames: "category-notifications-button-header",
- shouldDisplaySelectedName: false,
-
- @computed("_selectedDetails.icon", "_selectedDetails.key")
- icon() {
- return `${this._super()}${iconHTML("caret-down")}`.htmlSafe();
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/combo-box/combo-box-header.js.es6 b/app/assets/javascripts/select-box-kit/components/combo-box/combo-box-header.js.es6
deleted file mode 100644
index 996ca1f4729..00000000000
--- a/app/assets/javascripts/select-box-kit/components/combo-box/combo-box-header.js.es6
+++ /dev/null
@@ -1,39 +0,0 @@
-import SelectBoxKitHeaderComponent from "select-box-kit/components/select-box-kit/select-box-kit-header";
-import { default as computed } from "ember-addons/ember-computed-decorators";
-
-export default SelectBoxKitHeaderComponent.extend({
- layoutName: "select-box-kit/templates/components/combo-box/combo-box-header",
- classNames: "combo-box-header",
-
- clearable: Ember.computed.alias("options.clearable"),
- caretUpIcon: Ember.computed.alias("options.caretUpIcon"),
- caretDownIcon: Ember.computed.alias("options.caretDownIcon"),
- selectedName: Ember.computed.alias("options.selectedName"),
-
- @computed("isExpanded", "caretUpIcon", "caretDownIcon")
- caretIcon(isExpanded, caretUpIcon, caretDownIcon) {
- return isExpanded === true ? caretUpIcon : caretDownIcon;
- },
-
- @computed("clearable", "selectedContent")
- shouldDisplayClearableButton(clearable, selectedContent) {
- return clearable === true && !Ember.isEmpty(selectedContent);
- },
-
- @computed("options.selectedName", "selectedContent.firstObject.name", "none.name")
- selectedName(selectedName, name, noneName) {
- if (Ember.isPresent(selectedName)) {
- return selectedName;
- }
-
- if (Ember.isNone(name)) {
- if (Ember.isNone(noneName)) {
- return this._super();
- } else {
- return noneName;
- }
- } else {
- return name;
- }
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/dropdown-select-box.js.es6 b/app/assets/javascripts/select-box-kit/components/dropdown-select-box.js.es6
deleted file mode 100644
index 10447655825..00000000000
--- a/app/assets/javascripts/select-box-kit/components/dropdown-select-box.js.es6
+++ /dev/null
@@ -1,22 +0,0 @@
-import SelectBoxKitComponent from "select-box-kit/components/select-box-kit";
-
-export default SelectBoxKitComponent.extend({
- classNames: "dropdown-select-box",
- verticalOffset: 3,
- fullWidthOnMobile: true,
- filterable: false,
- autoFilterable: false,
- headerComponent: "dropdown-select-box/dropdown-select-box-header",
- rowComponent: "dropdown-select-box/dropdown-select-box-row",
-
- clickOutside() {
- if (this.get("isExpanded") === false) { return; }
- this.close();
- },
-
- didSelectValue() {
- this._super();
-
- this.blur();
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6 b/app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6
deleted file mode 100644
index 53dc082bdcc..00000000000
--- a/app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6
+++ /dev/null
@@ -1,6 +0,0 @@
-import SelectBoxKitHeaderComponent from "select-box-kit/components/select-box-kit/select-box-kit-header";
-
-export default SelectBoxKitHeaderComponent.extend({
- layoutName: "select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-header",
- classNames: "dropdown-select-box-header",
-});
diff --git a/app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6 b/app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6
deleted file mode 100644
index 38ce2a7aa03..00000000000
--- a/app/assets/javascripts/select-box-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6
+++ /dev/null
@@ -1,9 +0,0 @@
-import SelectBoxKitRowComponent from "select-box-kit/components/select-box-kit/select-box-kit-row";
-
-export default SelectBoxKitRowComponent.extend({
- layoutName: "select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-row",
- classNames: "dropdown-select-box-row",
-
- name: Ember.computed.alias("content.name"),
- description: Ember.computed.alias("content.originalContent.description")
-});
diff --git a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6 b/app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6
deleted file mode 100644
index e62e1276251..00000000000
--- a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6
+++ /dev/null
@@ -1,14 +0,0 @@
-import ComboBoxHeaderComponent from "select-box-kit/components/combo-box/combo-box-header";
-import DatetimeMixin from "select-box-kit/components/future-date-input-selector/mixin";
-import computed from "ember-addons/ember-computed-decorators";
-
-export default ComboBoxHeaderComponent.extend(DatetimeMixin, {
- layoutName: "select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-header",
- classNames: "future-date-input-selector-header",
-
- @computed("selectedContent.firstObject.value")
- datetime(value) { return this._computeDatetimeForValue(value); },
-
- @computed("selectedContent.firstObject.value")
- icon(value) { return this._computeIconForValue(value); }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6 b/app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6
deleted file mode 100644
index be35212a761..00000000000
--- a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6
+++ /dev/null
@@ -1,14 +0,0 @@
-import SelectBoxKitRowComponent from "select-box-kit/components/select-box-kit/select-box-kit-row";
-import DatetimeMixin from "select-box-kit/components/future-date-input-selector/mixin";
-import computed from "ember-addons/ember-computed-decorators";
-
-export default SelectBoxKitRowComponent.extend(DatetimeMixin, {
- layoutName: "select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-row",
- classNames: "future-date-input-selector-row",
-
- @computed("content.value")
- datetime(value) { return this._computeDatetimeForValue(value); },
-
- @computed("content.value")
- icon(value) { return this._computeIconForValue(value); }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/list-setting.js.es6 b/app/assets/javascripts/select-box-kit/components/list-setting.js.es6
deleted file mode 100644
index 94fa2fa66f2..00000000000
--- a/app/assets/javascripts/select-box-kit/components/list-setting.js.es6
+++ /dev/null
@@ -1,55 +0,0 @@
-import MultiComboBoxComponent from "select-box-kit/components/multi-combo-box";
-import { observes } from 'ember-addons/ember-computed-decorators';
-
-export default MultiComboBoxComponent.extend({
- classNames: "list-setting",
- tokenSeparator: "|",
- settingValue: "",
- choices: null,
- filterable: true,
-
- init() {
- const valuesFromString = this.get("settingValue").split(this.get("tokenSeparator"));
- this.set("value", valuesFromString.reject(v => Ember.isEmpty(v)));
-
- if (Ember.isNone(this.get("choices"))) {
- this.set("content", valuesFromString);
- } else {
- this.set("content", this.get("choices"));
- }
-
- if (!Ember.isNone(this.get("settingName"))) {
- this.set("nameProperty", this.get("settingName"));
- }
-
- if (Ember.isEmpty(this.get("content"))) {
- this.set("rowComponent", null);
- this.set("noContentLabel", null);
- }
-
- this._super();
-
- if (this.get("nameProperty").indexOf("color") > -1) {
- this.set("headerComponentOptions", Ember.Object.create({
- selectedNameComponent: "multi-combo-box/selected-color"
- }));
- }
- },
-
- @observes("value.[]")
- setSettingValue() {
- this.set("settingValue", this.get("value").join(this.get("tokenSeparator")));
- },
-
- @observes("content.[]")
- setChoices() { this.set("choices", this.get("content")); },
-
- _handleTabOnKeyDown(event) {
- if (this.$highlightedRow().length === 1) {
- this._super(event);
- } else {
- this.close();
- return false;
- }
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/multi-combo-box.js.es6 b/app/assets/javascripts/select-box-kit/components/multi-combo-box.js.es6
deleted file mode 100644
index bf08d7da1f1..00000000000
--- a/app/assets/javascripts/select-box-kit/components/multi-combo-box.js.es6
+++ /dev/null
@@ -1,240 +0,0 @@
-import SelectBoxKitComponent from "select-box-kit/components/select-box-kit";
-import computed from "ember-addons/ember-computed-decorators";
-const { get, isNone, isEmpty } = Ember;
-
-export default SelectBoxKitComponent.extend({
- classNames: "multi-combo-box",
- headerComponent: "multi-combo-box/multi-combo-box-header",
- filterComponent: null,
- headerText: "select_box.default_header_text",
- allowAny: true,
- allowValueMutation: false,
- autoSelectFirst: false,
- autoFilterable: true,
- selectedNameComponent: "multi-combo-box/selected-name",
-
- init() {
- this._super();
-
- if (isNone(this.get("value"))) { this.set("value", []); }
-
- this.set("headerComponentOptions", Ember.Object.create({
- selectedNameComponent: this.get("selectedNameComponent")
- }));
- },
-
- @computed("filter")
- templateForCreateRow() {
- return (rowComponent) => {
- return I18n.t("select_box.create", { content: rowComponent.get("content.name")});
- };
- },
-
- keyDown(event) {
- const keyCode = event.keyCode || event.which;
- const $filterInput = this.$filterInput();
-
- if (this.get("isFocused") === true && this.get("isExpanded") === false && keyCode === this.keys.BACKSPACE) {
- this.expand();
- return;
- }
-
- // select all choices
- if (event.metaKey === true && keyCode === 65 && isEmpty(this.get("filter"))) {
- this.$(".choices .selected-name:not(.is-locked)").addClass("is-highlighted");
- return;
- }
-
- // clear selection when multiple
- if (Ember.isEmpty(this.get("filter")) && this.$(".selected-name.is-highlighted").length >= 1 && keyCode === this.keys.BACKSPACE) {
- const highlightedValues = [];
- $.each(this.$(".selected-name.is-highlighted"), (i, el) => {
- highlightedValues.push($(el).attr("data-value"));
- });
-
- this.send("onDeselect", highlightedValues);
- return;
- }
-
- // try to remove last item from the list
- if (Ember.isEmpty(this.get("filter")) && keyCode === this.keys.BACKSPACE) {
- let $lastSelectedValue = $(this.$(".choices .selected-name:not(.is-locked)").last());
-
- if ($lastSelectedValue.length === 0) { return; }
-
- if ($lastSelectedValue.hasClass("is-highlighted") || $(document.activeElement).is($lastSelectedValue)) {
- this.send("onDeselect", this.get("selectedContent.lastObject.value"));
- $filterInput.focus();
- return;
- }
-
- if ($filterInput.not(":visible") && $lastSelectedValue.length > 0) {
- $lastSelectedValue.click();
- return false;
- }
-
- if ($filterInput.val() === "") {
- if ($filterInput.is(":focus")) {
- if ($lastSelectedValue.length > 0) { $lastSelectedValue.click(); }
- } else {
- if ($lastSelectedValue.length > 0) {
- $lastSelectedValue.click();
- } else {
- $filterInput.focus();
- }
- }
- }
- }
- },
-
- @computed("value.[]")
- computedValue(value) { return value.map(v => this._castInteger(v)); },
-
- @computed("value.[]", "computedContent.[]")
- selectedContent(value, computedContent) {
- const contents = [];
- value.forEach(v => {
- const content = computedContent.findBy("value", v);
- if (!isNone(content)) { contents.push(content); }
- });
- return contents;
- },
-
- filteredContentFunction(computedContent, computedValue, filter) {
- computedContent = computedContent.filter(c => {
- return !computedValue.includes(get(c, "value"));
- });
-
- if (isEmpty(filter)) { return computedContent; }
-
- const lowerFilter = filter.toLowerCase();
- return computedContent.filter(c => {
- return get(c, "name").toLowerCase().indexOf(lowerFilter) > -1;
- });
- },
-
- willCreateContent() {
- this.set("highlightedValue", null);
- },
-
- didCreateContent() {
- this.clearFilter();
- this.autoHighlightFunction();
- },
-
- createContentFunction(input) {
- if (!this.get("content").includes(input)) {
- this.get("content").pushObject(input);
- this.get("value").pushObject(input);
- }
- },
-
- deselectValuesFunction(values) {
- const contents = this._computeRemovableContentsForValues(values);
- this.get("value").removeObjects(values);
- this.get("content").removeObjects(contents);
- },
-
- highlightValueFunction(value) {
- this.set("highlightedValue", value);
- },
-
- selectValuesFunction(values) {
- this.get("value").pushObjects(values);
- },
-
- willSelectValues() {
- this.expand();
- this.set("highlightedValue", null);
- },
-
- didSelectValues() {
- this.focus();
- this.clearFilter();
- this.autoHighlightFunction();
- },
-
- willDeselectValues() {
- this.set("highlightedValue", null);
- },
-
- didDeselectValues() {
- this.autoHighlightFunction();
- },
-
- willHighlightValue() {},
-
- didHighlightValue() {},
-
- autoHighlightFunction() {
- Ember.run.schedule("afterRender", () => {
- if (this.get("isExpanded") === false) { return; }
- if (this.get("renderedBodyOnce") === false) { return; }
- if (!isNone(this.get("highlightedValue"))) { return; }
-
- if (isEmpty(this.get("filteredContent"))) {
- if (!isEmpty(this.get("filter"))) {
- this.send("onHighlight", this.get("filter"));
- } else if (this.get("none") && !isEmpty(this.get("selectedContent"))) {
- this.send("onHighlight", this.noneValue);
- }
- } else {
- this.send("onHighlight", this.get("filteredContent.firstObject.value"));
- }
- });
- },
-
- actions: {
- onClearSelection() {
- const values = this.get("selectedContent").map(c => get(c, "value"));
- this.send("onDeselect", values);
- },
-
- onHighlight(value) {
- value = this._originalValueForValue(value);
- this.willHighlightValue(value);
- this.set("highlightedValue", value);
- this.highlightValueFunction(value);
- this.didHighlightValue(value);
- },
-
- onCreateContent(input) {
- this.willCreateContent(input);
- this.createContentFunction(input);
- this.didCreateContent(input);
- },
-
- onSelect(values) {
- values = Ember.makeArray(values).map(v => this._originalValueForValue(v));
- this.willSelectValues(values);
- this.selectValuesFunction(values);
- this.didSelectValues(values);
- },
-
- onDeselect(values) {
- values = Ember.makeArray(this._computeRemovableValues(values));
- this.willDeselectValues(values);
- this.deselectValuesFunction(values);
- this.didSelectValues(values);
- }
- },
-
- _computeRemovableContentsForValues(values) {
- const removableContents = [];
- values.forEach(v => {
- if (!this.get("_initialValues").includes(v)) {
- const content = this._contentForValue(v);
- if (!isNone(content)) { removableContents.push(content); }
- }
- });
- return removableContents;
- },
-
- _computeRemovableValues(values) {
- return Ember.makeArray(values)
- .map(v => this._originalValueForValue(v))
- .filter(v => {
- return get(this._computedContentForValue(v), "locked") !== true;
- });
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/multi-combo-box/selected-color.js.es6 b/app/assets/javascripts/select-box-kit/components/multi-combo-box/selected-color.js.es6
deleted file mode 100644
index 240c3570d9e..00000000000
--- a/app/assets/javascripts/select-box-kit/components/multi-combo-box/selected-color.js.es6
+++ /dev/null
@@ -1,8 +0,0 @@
-import SelectedNameComponent from "select-box-kit/components/multi-combo-box/selected-name";
-
-export default SelectedNameComponent.extend({
- didRender() {
- const name = this.get("content.name");
- this.$().css("border-bottom", Handlebars.Utils.escapeExpression(`7px solid #${name}`));
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/notifications-button/notifications-button-header.js.es6 b/app/assets/javascripts/select-box-kit/components/notifications-button/notifications-button-header.js.es6
deleted file mode 100644
index 268e8d7b311..00000000000
--- a/app/assets/javascripts/select-box-kit/components/notifications-button/notifications-button-header.js.es6
+++ /dev/null
@@ -1,26 +0,0 @@
-import DropdownSelectBoxHeaderComponent from "select-box-kit/components/dropdown-select-box/dropdown-select-box-header";
-import computed from "ember-addons/ember-computed-decorators";
-import { iconHTML } from 'discourse-common/lib/icon-library';
-import { buttonDetails } from "discourse/lib/notification-levels";
-
-export default DropdownSelectBoxHeaderComponent.extend({
- classNames: "notifications-button-header",
-
- i18nPrefix: Ember.computed.alias("options.i18nPrefix"),
- shouldDisplaySelectedName: Ember.computed.alias("options.showFullTitle"),
-
- @computed("_selectedDetails.icon", "_selectedDetails.key")
- icon(icon, key) {
- return iconHTML(icon, { class: key }).htmlSafe();
- },
-
- @computed("_selectedDetails.key", "i18nPrefix")
- selectedName(key, prefix) {
- return I18n.t(`${prefix}.${key}.title`);
- },
-
- @computed("selectedContent.firstObject.value")
- _selectedDetails(value) {
- return buttonDetails(value);
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/pinned-options.js.es6 b/app/assets/javascripts/select-box-kit/components/pinned-options.js.es6
deleted file mode 100644
index 3c96f2ee228..00000000000
--- a/app/assets/javascripts/select-box-kit/components/pinned-options.js.es6
+++ /dev/null
@@ -1,60 +0,0 @@
-import DropdownSelectBoxComponent from "select-box-kit/components/dropdown-select-box";
-import computed from "ember-addons/ember-computed-decorators";
-import { observes } from "ember-addons/ember-computed-decorators";
-import { on } from "ember-addons/ember-computed-decorators";
-
-export default DropdownSelectBoxComponent.extend({
- classNames: "pinned-options",
-
- headerComponent: "pinned-options/pinned-options-header",
-
- @on("didReceiveAttrs")
- _setComponentOptions() {
- this.set("headerComponentOptions", Ember.Object.create({
- pinned: this.get("topic.pinned"),
- pinnedGlobally: this.get("topic.pinned_globally")
- }));
- },
-
- @computed("topic.pinned")
- value(pinned) {
- return pinned ? "pinned" : "unpinned";
- },
-
- @observes("topic.pinned")
- _pinStateChanged() {
- this.set("value", this.get("topic.pinned") ? "pinned" : "unpinned");
- this._setComponentOptions();
- },
-
- @computed("topic.pinned_globally")
- content(pinnedGlobally) {
- const globally = pinnedGlobally ? "_globally" : "";
-
- return [
- {
- id: "pinned",
- name: I18n.t("topic_statuses.pinned" + globally + ".title"),
- description: I18n.t('topic_statuses.pinned' + globally + '.help'),
- icon: "thumb-tack"
- },
- {
- id: "unpinned",
- name: I18n.t("topic_statuses.unpinned.title"),
- icon: "thumb-tack",
- description: I18n.t('topic_statuses.unpinned.help'),
- iconClass: "unpinned"
- }
- ];
- },
-
- selectValueFunction(value) {
- const topic = this.get("topic");
-
- if (value === "unpinned") {
- topic.clearPin();
- } else {
- topic.rePin();
- }
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/pinned-options/pinned-options-header.js.es6 b/app/assets/javascripts/select-box-kit/components/pinned-options/pinned-options-header.js.es6
deleted file mode 100644
index 3f83e8bffda..00000000000
--- a/app/assets/javascripts/select-box-kit/components/pinned-options/pinned-options-header.js.es6
+++ /dev/null
@@ -1,30 +0,0 @@
-import DropdownSelectBoxHeaderComponent from "select-box-kit/components/dropdown-select-box/dropdown-select-box-header";
-import computed from "ember-addons/ember-computed-decorators";
-import { iconHTML } from 'discourse-common/lib/icon-library';
-
-export default DropdownSelectBoxHeaderComponent.extend({
- classNames: "pinned-options-header",
-
- pinnedGlobally: Ember.computed.alias("options.pinnedGlobally"),
- pinned: Ember.computed.alias("options.pinned"),
-
- @computed("pinned", "pinnedGlobally")
- icon(pinned, pinnedGlobally) {
- const globally = pinnedGlobally ? "_globally" : "";
- const state = pinned ? `pinned${globally}` : "unpinned";
-
- return iconHTML(
- "thumb-tack",
- { class: (state === "unpinned" ? "unpinned" : null) }
- );
- },
-
- @computed("pinned", "pinnedGlobally")
- selectedName(pinned, pinnedGlobally) {
- const globally = pinnedGlobally ? "_globally" : "";
- const state = pinned ? `pinned${globally}` : "unpinned";
- const title = I18n.t(`topic_statuses.${state}.title`);
-
- return `${title}${iconHTML("caret-down")}`.htmlSafe();
- },
-});
diff --git a/app/assets/javascripts/select-box-kit/components/select-box-kit.js.es6 b/app/assets/javascripts/select-box-kit/components/select-box-kit.js.es6
deleted file mode 100644
index a3371d0249c..00000000000
--- a/app/assets/javascripts/select-box-kit/components/select-box-kit.js.es6
+++ /dev/null
@@ -1,328 +0,0 @@
-const { get, isNone, isEmpty, isPresent } = Ember;
-import { on } from "ember-addons/ember-computed-decorators";
-import computed from "ember-addons/ember-computed-decorators";
-import UtilsMixin from "select-box-kit/mixins/utils";
-import DomHelpersMixin from "select-box-kit/mixins/dom-helpers";
-import KeyboardMixin from "select-box-kit/mixins/keyboard";
-
-export default Ember.Component.extend(UtilsMixin, DomHelpersMixin, KeyboardMixin, {
- layoutName: "select-box-kit/templates/components/select-box-kit",
- classNames: "select-box-kit",
- classNameBindings: [
- "isFocused",
- "isExpanded",
- "isDisabled",
- "isHidden",
- "isAbove",
- "isBelow",
- "isLeftAligned",
- "isRightAligned"
- ],
- isDisabled: false,
- isExpanded: false,
- isFocused: false,
- isHidden: false,
- renderedBodyOnce: false,
- renderedFilterOnce: false,
- tabindex: 0,
- scrollableParentSelector: ".modal-body",
- value: null,
- none: null,
- highlightedValue: null,
- noContentLabel: "select_box.no_content",
- valueAttribute: "id",
- nameProperty: "name",
- autoFilterable: false,
- filterable: false,
- filter: "",
- filterPlaceholder: "select_box.filter_placeholder",
- filterIcon: "search",
- rowComponent: "select-box-kit/select-box-kit-row",
- rowComponentOptions: null,
- noneRowComponent: "select-box-kit/select-box-kit-none-row",
- createRowComponent: "select-box-kit/select-box-kit-create-row",
- filterComponent: "select-box-kit/select-box-kit-filter",
- headerComponent: "select-box-kit/select-box-kit-header",
- headerComponentOptions: null,
- collectionComponent: "select-box-kit/select-box-kit-collection",
- collectionHeight: 200,
- verticalOffset: 0,
- horizontalOffset: 0,
- fullWidthOnMobile: false,
- castInteger: false,
- allowAny: false,
- allowValueMutation: true,
- autoSelectFirst: true,
- content: null,
- _initialValues: null,
-
- init() {
- this._super();
-
- this.noneValue = "__none__";
- this._previousScrollParentOverflow = "auto";
- this._previousCSSContext = {};
- this.set("headerComponentOptions", Ember.Object.create());
- this.set("rowComponentOptions", Ember.Object.create());
-
- if ($(window).outerWidth(false) <= 420) {
- this.setProperties({ filterable: false, autoFilterable: false });
- }
-
- if (isNone(this.get("content"))) { this.set("content", []); }
- this.set("value", this._castInteger(this.get("value")));
-
- this.setInitialValues();
- },
-
- setInitialValues() {
- this.set("_initialValues", this.getWithDefault("content", []).map((c) => {
- return this._valueForContent(c);
- }));
- },
-
- @computed("computedContent.[]", "computedValue.[]", "filter")
- filteredContent(computedContent, computedValue, filter) {
- return this.filteredContentFunction(computedContent, computedValue, filter);
- },
-
- filteredContentFunction(computedContent, computedValue, filter) {
- if (isEmpty(filter)) { return computedContent; }
-
- const lowerFilter = filter.toLowerCase();
- return computedContent.filter(c => {
- return get(c, "name").toLowerCase().indexOf(lowerFilter) > -1;
- });
- },
-
- formatRowContent(content) {
- let originalContent;
-
- if (typeof content === "string" || typeof content === "number") {
- originalContent = {};
- originalContent[this.get("valueAttribute")] = content;
- originalContent[this.get("nameProperty")] = content;
- } else {
- originalContent = content;
- }
-
- return {
- value: this._castInteger(this._valueForContent(content)),
- name: this._nameForContent(content),
- locked: false,
- originalContent
- };
- },
-
- formatContents(contents) {
- return contents.map(content => this.formatRowContent(content));
- },
-
- @computed("filter", "filterable", "autoFilterable", "renderedFilterOnce")
- shouldDisplayFilter(filter, filterable, autoFilterable, renderedFilterOnce) {
- if (renderedFilterOnce === true || filterable === true) { return true; }
- if (filter.length > 0 && autoFilterable === true) { return true; }
- return false;
- },
-
- @computed("filter")
- shouldDisplayCreateRow(filter) {
- if (this.get("allowAny") === true && filter.length > 0) { return true; }
- return false;
- },
-
- @computed("filter", "shouldDisplayCreateRow")
- createRowContent(filter, shouldDisplayCreateRow) {
- if (shouldDisplayCreateRow === true && !this.get("value").includes(filter)) {
- return Ember.Object.create({ value: filter, name: filter });
- }
- },
-
- @computed("content.[]", "value.[]")
- computedContent(content) {
- this._mutateValue();
- return this.formatContents(content || []);
- },
-
- @computed("value", "none", "computedContent.firstObject.value")
- computedValue(value, none, firstContentValue) {
- if (isNone(value) && isNone(none) && this.get("autoSelectFirst") === true) {
- return firstContentValue;
- }
-
- return value;
- },
-
- @computed
- templateForRow() { return () => null; },
-
- @computed
- templateForNoneRow() { return () => null; },
-
- @computed
- templateForCreateRow() { return () => null; },
-
- @computed("none")
- computedNone(none) {
- if (isNone(none)) { return null; }
-
- switch (typeof none) {
- case "string":
- return Ember.Object.create({ name: I18n.t(none), value: this.noneValue });
- default:
- return this.formatRowContent(none);
- }
- },
-
- @computed("computedValue", "computedContent.[]")
- selectedContent(computedValue, computedContent) {
- if (isNone(computedValue)) { return []; }
- return [ computedContent.findBy("value", computedValue) ];
- },
-
- @on("didInsertElement")
- _setupResizeListener() {
- $(window).on("resize.select-box-kit", () => this.collapse() );
- },
-
-
- autoHighlightFunction() {
- Ember.run.schedule("afterRender", () => {
- if (!isNone(this.get("highlightedValue"))) { return; }
-
- const filteredContent = this.get("filteredContent");
- const display = this.get("shouldDisplayCreateRow");
- const none = this.get("computedNone");
-
- if (isNone(this.get("highlightedValue")) && !isEmpty(filteredContent)) {
- this.send("onHighlight", get(filteredContent, "firstObject.value"));
- return;
- }
-
- if (display === true && isEmpty(filteredContent)) {
- this.send("onHighlight", this.get("filter"));
- }
- else if (!isEmpty(filteredContent)) {
- this.send("onHighlight", get(filteredContent, "firstObject.value"));
- }
- else if (isEmpty(filteredContent) && isPresent(none) && display === false) {
- this.send("onHighlight", get(none, "value"));
- }
- });
- },
-
- willFilterContent() {
- this.expand();
- this.set("highlightedValue", null);
- },
- didFilterContent() {
- this.set("renderedFilterOnce", true);
- this.autoHighlightFunction();
- },
-
- willCreateContent() { },
- createContentFunction(input) {
- this.get("content").pushObject(input);
- this.send("onSelect", input);
- },
- didCreateContent() {
- this.clearFilter();
- this.autoHighlightFunction();
- },
-
- willHighlightValue() {},
- highlightValueFunction(value) {
- this.set("highlightedValue", value);
- },
- didHighlightValue() {},
-
- willSelectValue() {
- this.clearFilter();
- this.set("highlightedValue", null);
- },
- selectValueFunction(value) {
- this.set("value", value);
- },
- didSelectValue() {
- this.collapse();
- this.focus();
- },
-
- willDeselectValue() {
- this.set("highlightedValue", null);
- },
- unsetValueFunction() {
- this.set("value", null);
- },
- didDeselectValue() {
- this.focus();
- },
-
- actions: {
- onToggle() {
- this.get("isExpanded") === true ? this.collapse() : this.expand();
- },
-
- onClearSelection() {
- this.send("onDeselect", this.get("value"));
- },
-
- onHighlight(value) {
- value = this._originalValueForValue(value);
- this.willHighlightValue(value);
- this.set("highlightedValue", value);
- this.highlightValueFunction(value);
- this.didHighlightValue(value);
- },
-
- onCreateContent(input) {
- this.willCreateContent(input);
- this.createContentFunction(input);
- this.didCreateContent(input);
- },
-
- onSelect(value) {
- if (value === "") { value = null; }
- this.willSelectValue(value);
- this.selectValueFunction(value);
- this.didSelectValue(value);
- },
-
- onDeselect(value) {
- value = this._originalValueForValue(value);
- this.willDeselectValue(value);
- this.unsetValueFunction(value);
- this.didSelectValue(value);
- },
-
- onFilterChange(_filter) {
- this.willFilterContent(_filter);
- this.set("filter", _filter);
- this.didFilterContent(_filter);
- },
- },
-
- clearFilter() {
- this.$filterInput().val("");
- this.setProperties({ filter: "" });
- },
-
- @on("didReceiveAttrs")
- _mutateValue() {
- if (this.get("allowValueMutation") !== true) {
- return;
- }
-
- const none = isNone(this.get("none"));
- const emptyValue = isEmpty(this.get("value"));
-
- if (none && emptyValue) {
- Ember.run.scheduleOnce("sync", () => {
- if (!isEmpty(this.get("computedContent"))) {
- const firstValue = this.get("computedContent.firstObject.value");
- this.set("value", firstValue);
- }
- });
- }
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-collection.js.es6 b/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-collection.js.es6
deleted file mode 100644
index ca378f5ef93..00000000000
--- a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-collection.js.es6
+++ /dev/null
@@ -1,5 +0,0 @@
-export default Ember.Component.extend({
- layoutName: "select-box-kit/templates/components/select-box-kit/select-box-kit-collection",
- classNames: "select-box-kit-collection",
- tagName: "ul"
-});
diff --git a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-create-row.js.es6 b/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-create-row.js.es6
deleted file mode 100644
index fd686080ec9..00000000000
--- a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-create-row.js.es6
+++ /dev/null
@@ -1,10 +0,0 @@
-import SelectBoxKitRowComponent from "select-box-kit/components/select-box-kit/select-box-kit-row";
-
-export default SelectBoxKitRowComponent.extend({
- layoutName: "select-box-kit/templates/components/select-box-kit/select-box-kit-row",
- classNames: "create",
-
- click() {
- this.sendAction("onCreateContent", this.get("content.name"));
- },
-});
diff --git a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-header.js.es6 b/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-header.js.es6
deleted file mode 100644
index b7797571ae3..00000000000
--- a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-header.js.es6
+++ /dev/null
@@ -1,28 +0,0 @@
-import computed from 'ember-addons/ember-computed-decorators';
-
-export default Ember.Component.extend({
- layoutName: "select-box-kit/templates/components/select-box-kit/select-box-kit-header",
- classNames: "select-box-kit-header",
- classNameBindings: ["isFocused"],
- attributeBindings: ["selectedName:data-name"],
- shouldDisplaySelectedName: true,
-
- @computed("options.shouldDisplaySelectedName")
- shouldDisplaySelectedName(should) {
- if (Ember.isNone(should)) { return true; }
- return should;
- },
-
- @computed("options.selectedName", "selectedContent.firstObject.name")
- selectedName(optionsSelectedName, firstSelectedContentName) {
- if (Ember.isNone(optionsSelectedName)) {
- return firstSelectedContentName;
- }
- return optionsSelectedName;
- },
-
- @computed("options.icon")
- icon(optionsIcon) { return optionsIcon; },
-
- click() { this.sendAction("onToggle"); }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-none-row.js.es6 b/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-none-row.js.es6
deleted file mode 100644
index fbc07b312c6..00000000000
--- a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-none-row.js.es6
+++ /dev/null
@@ -1,10 +0,0 @@
-import SelectBoxKitRowComponent from "select-box-kit/components/select-box-kit/select-box-kit-row";
-
-export default SelectBoxKitRowComponent.extend({
- layoutName: "select-box-kit/templates/components/select-box-kit/select-box-kit-row",
- classNames: "none",
-
- click() {
- this.sendAction("onClearSelection");
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-row.js.es6 b/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-row.js.es6
deleted file mode 100644
index c1bf0f2d5ed..00000000000
--- a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-row.js.es6
+++ /dev/null
@@ -1,70 +0,0 @@
-import { iconHTML } from 'discourse-common/lib/icon-library';
-import { on } from 'ember-addons/ember-computed-decorators';
-import computed from 'ember-addons/ember-computed-decorators';
-const { run, isPresent } = Ember;
-import UtilsMixin from "select-box-kit/mixins/utils";
-
-export default Ember.Component.extend(UtilsMixin, {
- layoutName: "select-box-kit/templates/components/select-box-kit/select-box-kit-row",
- classNames: "select-box-kit-row",
- tagName: "li",
- tabIndex: -1,
- attributeBindings: [
- "tabIndex",
- "title",
- "content.value:data-value",
- "content.name:data-name"
- ],
- classNameBindings: ["isHighlighted", "isSelected"],
- clicked: false,
-
- @computed("content.originalContent.title", "content.name")
- title(title, name) {
- return title || name;
- },
-
- @computed("templateForRow")
- template(templateForRow) { return templateForRow(this); },
-
- @on("didReceiveAttrs")
- _setSelectionState() {
- const contentValue = this.get("content.value");
-
- this.set("isSelected", this.get("value") === contentValue);
- this.set("isHighlighted", this.get("highlightedValue") === contentValue);
- },
-
- @on("willDestroyElement")
- _clearDebounce() {
- const hoverDebounce = this.get("hoverDebounce");
- if (isPresent(hoverDebounce)) { run.cancel(hoverDebounce); }
- },
-
- @computed("content.originalContent.icon", "content.originalContent.iconClass")
- icon(icon, cssClass) {
- if (icon) {
- return iconHTML(icon, { class: cssClass });
- }
-
- return null;
- },
-
- mouseEnter() {
- this.set("hoverDebounce", run.debounce(this, this._sendOnHighlightAction, 32));
- },
-
- click() {
- this._sendOnSelectAction();
- },
-
- _sendOnSelectAction() {
- if (this.get("clicked") === false) {
- this.set("clicked", true);
- this.sendAction("onSelect", this.get("content.value"));
- }
- },
-
- _sendOnHighlightAction() {
- this.sendAction("onHighlight", this.get("content.value"));
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/tag-notifications-button.js.es6 b/app/assets/javascripts/select-box-kit/components/tag-notifications-button.js.es6
deleted file mode 100644
index bc2d95ac4d0..00000000000
--- a/app/assets/javascripts/select-box-kit/components/tag-notifications-button.js.es6
+++ /dev/null
@@ -1,12 +0,0 @@
-import NotificationOptionsComponent from "select-box-kit/components/notifications-button";
-
-export default NotificationOptionsComponent.extend({
- classNames: "tag-notifications-button",
- i18nPrefix: "tagging.notifications",
- showFullTitle: false,
- headerComponent: "tag-notifications-button/tag-notifications-button-header",
-
- selectValueFunction(value) {
- this.sendAction("action", value);
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/components/tag-notifications-button/tag-notifications-button-header.js.es6 b/app/assets/javascripts/select-box-kit/components/tag-notifications-button/tag-notifications-button-header.js.es6
deleted file mode 100644
index 524c8b8585d..00000000000
--- a/app/assets/javascripts/select-box-kit/components/tag-notifications-button/tag-notifications-button-header.js.es6
+++ /dev/null
@@ -1,13 +0,0 @@
-import NotificationButtonHeader from "select-box-kit/components/notifications-button/notifications-button-header";
-import computed from "ember-addons/ember-computed-decorators";
-import { iconHTML } from 'discourse-common/lib/icon-library';
-
-export default NotificationButtonHeader.extend({
- classNames: "tag-notifications-button-header",
- shouldDisplaySelectedName: false,
-
- @computed("_selectedDetails.icon", "_selectedDetails.key")
- icon() {
- return `${this._super()}${iconHTML("caret-down")}`.htmlSafe();
- }
-});
diff --git a/app/assets/javascripts/select-box-kit/mixins/keyboard.js.es6 b/app/assets/javascripts/select-box-kit/mixins/keyboard.js.es6
deleted file mode 100644
index e7973f5b0f8..00000000000
--- a/app/assets/javascripts/select-box-kit/mixins/keyboard.js.es6
+++ /dev/null
@@ -1,222 +0,0 @@
-export default Ember.Mixin.create({
- init() {
- this._super();
-
- this.keys = {
- TAB: 9,
- ENTER: 13,
- ESC: 27,
- SPACE: 32,
- LEFT: 37,
- UP: 38,
- RIGHT: 39,
- DOWN: 40,
- SHIFT: 16,
- CTRL: 17,
- ALT: 18,
- PAGE_UP: 33,
- PAGE_DOWN: 34,
- HOME: 36,
- END: 35,
- BACKSPACE: 8
- };
- },
-
- willDestroyElement() {
- this._super();
-
- $(document)
- .off("mousedown.select-box-kit")
- .off("touchstart.select-box-kit");
-
- this.$offscreenInput()
- .off("focus.select-box-kit")
- .off("focusin.select-box-kit")
- .off("blur.select-box-kit")
- .off("keypress.select-box-kit")
- .off("keydown.select-box-kit");
-
- this.$filterInput()
- .off("change.select-box-kit")
- .off("keypress.select-box-kit")
- .off("keydown.select-box-kit");
- },
-
- didInsertElement() {
- this._super();
-
- $(document)
- .on("mousedown.select-box-kit, touchstart.select-box-kit", event => {
- if (Ember.isNone(this.get("element"))) {
- return;
- }
-
- if (this.get("element").contains(event.target)) { return; }
- this.clickOutside(event);
- });
-
- this.$offscreenInput()
- .on("blur.select-box-kit", () => {
- if (this.get("isExpanded") === false && this.get("isFocused") === true) {
- this.close();
- }
- })
- .on("focus.select-box-kit", (event) => {
- this.set("isFocused", true);
- this._killEvent(event);
- })
- .on("focusin.select-box-kit", (event) => {
- this.set("isFocused", true);
- this._killEvent(event);
- })
- .on("keydown.select-box-kit", (event) => {
- const keyCode = event.keyCode || event.which;
-
- if (keyCode === this.keys.TAB) { this._handleTabOnKeyDown(event); }
- if (keyCode === this.keys.ESC) { this._handleEscOnKeyDown(event); }
- if (keyCode === this.keys.UP || keyCode === this.keys.DOWN) {
- this._handleArrowKey(keyCode, event);
- }
- if (keyCode === this.keys.BACKSPACE) {
- this.expand();
-
- if (this.$filterInput().is(":visible")) {
- this.$filterInput().focus().trigger(event).trigger("change");
- }
-
- return event;
- }
-
- return true;
- })
- .on("keypress.select-box-kit", (event) => {
- const keyCode = event.keyCode || event.which;
-
- switch (keyCode) {
- case this.keys.ENTER:
- if (this.get("isExpanded") === false) {
- this.expand();
- } else if (this.$highlightedRow().length === 1) {
- this.$highlightedRow().click();
- }
- return false;
- case this.keys.BACKSPACE:
- return event;
- }
-
- if (this._isSpecialKey(keyCode) === false && event.metaKey === false) {
- this.expand();
-
- if (this.get("filterable") === true || this.get("autoFilterable")) {
- this.set("renderedFilterOnce", true);
- }
-
- Ember.run.schedule("afterRender", () => {
- this.$filterInput()
- .focus()
- .val(this.$filterInput().val() + String.fromCharCode(keyCode));
- });
- }
- });
-
- this.$filterInput()
- .on("change.select-box-kit", (event) => {
- this.send("onFilterChange", $(event.target).val());
- })
- .on("keydown.select-box-kit", (event) => {
- const keyCode = event.keyCode || event.which;
-
- if (keyCode === this.keys.TAB) { this._handleTabOnKeyDown(event); }
- if (keyCode === this.keys.ESC) { this._handleEscOnKeyDown(event); }
- if (keyCode === this.keys.UP || keyCode === this.keys.DOWN) {
- this._handleArrowKey(keyCode, event);
- }
- })
- .on("keypress.select-box-kit", (event) => {
- const keyCode = event.keyCode || event.which;
-
- if ([
- this.keys.RIGHT,
- this.keys.LEFT,
- this.keys.BACKSPACE,
- this.keys.SPACE,
- ].includes(keyCode) || event.metaKey === true) {
- return true;
- }
-
- if (keyCode === this.keys.TAB && this.get("isExpanded") === false) {
- return true;
- }
-
- if (this._isSpecialKey(keyCode) === true) {
- this.$offscreenInput().focus().trigger(event);
- return false;
- }
-
- return true;
- });
- },
-
- _handleEscOnKeyDown(event) {
- this.unfocus();
- this._killEvent(event);
- },
-
- _handleTabOnKeyDown(event) {
- if (this.get("isExpanded") === false) {
- this.unfocus();
- return true;
- } else if (this.$highlightedRow().length === 1) {
- this._killEvent(event);
- this.$highlightedRow().click();
- this.focus();
- } else {
- this.unfocus();
- return true;
- }
- return false;
- },
-
- _handleArrowKey(keyCode, event) {
- if (this.get("isExpanded") === false) { this.expand(); }
- this._killEvent(event);
- const $rows = this.$rows();
-
- if ($rows.length <= 0) { return; }
- if ($rows.length === 1) {
- this._rowSelection($rows, 0);
- return;
- }
-
- const direction = keyCode === 38 ? -1 : 1;
-
- Ember.run.throttle(this, this._moveHighlight, direction, $rows, 32);
- },
-
- _moveHighlight(direction, $rows) {
- const currentIndex = $rows.index(this.$highlightedRow());
- let nextIndex = currentIndex + direction;
-
- if (nextIndex < 0) {
- nextIndex = $rows.length - 1;
- } else if (nextIndex >= $rows.length) {
- nextIndex = 0;
- }
-
- this._rowSelection($rows, nextIndex);
- },
-
- _rowSelection($rows, nextIndex) {
- const highlightableValue = $rows.eq(nextIndex).attr("data-value");
- const $highlightableRow = this.$findRowByValue(highlightableValue);
-
- Ember.run.schedule("afterRender", () => {
- $highlightableRow.trigger("mouseover").focus();
- this.focus();
- });
- },
-
- _isSpecialKey(keyCode) {
- return _.values(this.keys).includes(keyCode);
- },
-});
diff --git a/app/assets/javascripts/select-box-kit/templates/components/combo-box/combo-box-header.hbs b/app/assets/javascripts/select-box-kit/templates/components/combo-box/combo-box-header.hbs
deleted file mode 100644
index 38e070fa345..00000000000
--- a/app/assets/javascripts/select-box-kit/templates/components/combo-box/combo-box-header.hbs
+++ /dev/null
@@ -1,15 +0,0 @@
-{{#if icon}}
- {{{icon}}}
-{{/if}}
-
-
- {{{selectedName}}}
-
-
-{{#if shouldDisplayClearableButton}}
-
- {{d-icon 'times'}}
-
-{{/if}}
-
-{{d-icon caretIcon class="caret-icon"}}
diff --git a/app/assets/javascripts/select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs b/app/assets/javascripts/select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs
deleted file mode 100644
index 0129d1651fd..00000000000
--- a/app/assets/javascripts/select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- {{#if icon}}
- {{{icon}}}
- {{/if}}
-
- {{#if shouldDisplaySelectedName}}
-
- {{selectedName}}
-
- {{/if}}
-
-
diff --git a/app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/multi-combo-box-header.hbs b/app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/multi-combo-box-header.hbs
deleted file mode 100644
index 6245b4e8c7b..00000000000
--- a/app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/multi-combo-box-header.hbs
+++ /dev/null
@@ -1,13 +0,0 @@
-
- {{#each selectedContent as |selectedContent|}}
- {{component selectedNameComponent onDeselect=onDeselect content=selectedContent}}
- {{/each}}
-
- {{component "select-box-kit/select-box-kit-filter"
- onFilterChange=onFilterChange
- shouldDisplayFilter=shouldDisplayFilter
- isFocused=isFocused
- filter=filter
- }}
-
-
diff --git a/app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/selected-name.hbs b/app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/selected-name.hbs
deleted file mode 100644
index 54ef362ed31..00000000000
--- a/app/assets/javascripts/select-box-kit/templates/components/multi-combo-box/selected-name.hbs
+++ /dev/null
@@ -1,9 +0,0 @@
-
- {{#unless isLocked}}
-
- {{d-icon "times"}}
-
- {{/unless}}
-
- {{content.name}}
-
diff --git a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-header.hbs b/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-header.hbs
deleted file mode 100644
index b0cea9f9134..00000000000
--- a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-header.hbs
+++ /dev/null
@@ -1,7 +0,0 @@
-{{#if icon}}
- {{{icon}}}
-{{/if}}
-
-
- {{{selectedName}}}
-
diff --git a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-row.hbs b/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-row.hbs
deleted file mode 100644
index 1786cfb5538..00000000000
--- a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-row.hbs
+++ /dev/null
@@ -1,9 +0,0 @@
-{{#if template}}
- {{{template}}}
-{{else}}
- {{#if icon}}
- {{{icon}}}
- {{/if}}
-
-
{{content.name}}
-{{/if}}
diff --git a/app/assets/javascripts/select-box-kit/components/admin-agree-flag-dropdown.js.es6 b/app/assets/javascripts/select-kit/components/admin-agree-flag-dropdown.js.es6
similarity index 76%
rename from app/assets/javascripts/select-box-kit/components/admin-agree-flag-dropdown.js.es6
rename to app/assets/javascripts/select-kit/components/admin-agree-flag-dropdown.js.es6
index cca1e5c76cc..55708f10eaa 100644
--- a/app/assets/javascripts/select-box-kit/components/admin-agree-flag-dropdown.js.es6
+++ b/app/assets/javascripts/select-kit/components/admin-agree-flag-dropdown.js.es6
@@ -1,21 +1,18 @@
-import { iconHTML } from 'discourse-common/lib/icon-library';
-import DropdownSelectBox from "select-box-kit/components/dropdown-select-box";
+import DropdownSelectBox from "select-kit/components/dropdown-select-box";
import computed from "ember-addons/ember-computed-decorators";
-import { on } from "ember-addons/ember-computed-decorators";
export default DropdownSelectBox.extend({
- headerText: "admin.flags.agree",
- headerIcon: "thumbs-o-up",
+ pluginApiIdentifiers: ["admin-agree-flag-dropdown"],
classNames: ["agree-flag", "admin-agree-flag-dropdown"],
adminTools: Ember.inject.service(),
nameProperty: "label",
+ allowInitialValueMutation: false,
+ headerIcon: "thumbs-o-up",
- @on("didReceiveAttrs")
- _setAdminAgreeDropdownOptions() {
- this.get('headerComponentOptions').setProperties({
- selectedName: `${I18n.t(this.get("headerText"))} ...`,
- icon: iconHTML("thumbs-o-up")
- });
+ computeHeaderContent() {
+ let content = this.baseHeaderComputedContent();
+ content.name = `${I18n.t("admin.flags.agree")}...`;
+ return content;
},
@computed("adminTools", "post.user")
@@ -25,9 +22,10 @@ export default DropdownSelectBox.extend({
canDeleteSpammer: Ember.computed.and("spammerDetails.canDelete", "post.flaggedForSpam"),
- @computed("post", "canDeleteSpammer")
- content(post, canDeleteSpammer) {
+ computeContent() {
const content = [];
+ const post = this.get("post");
+ const canDeleteSpammer = this.get("canDeleteSpammer");
if (post.user_deleted) {
content.push({
@@ -70,8 +68,9 @@ export default DropdownSelectBox.extend({
return content;
},
- selectValueFunction(value) {
- Ember.get(this._contentForValue(value), "action")();
+ mutateValue(value) {
+ const computedContentItem = this.get("computedContent").findBy("value", value);
+ Ember.get(computedContentItem, "originalContent.action")();
},
actions: {
diff --git a/app/assets/javascripts/select-box-kit/components/admin-delete-flag-dropdown.js.es6 b/app/assets/javascripts/select-kit/components/admin-delete-flag-dropdown.js.es6
similarity index 74%
rename from app/assets/javascripts/select-box-kit/components/admin-delete-flag-dropdown.js.es6
rename to app/assets/javascripts/select-kit/components/admin-delete-flag-dropdown.js.es6
index 8b130c2c8b9..2144a1512a6 100644
--- a/app/assets/javascripts/select-box-kit/components/admin-delete-flag-dropdown.js.es6
+++ b/app/assets/javascripts/select-kit/components/admin-delete-flag-dropdown.js.es6
@@ -1,20 +1,16 @@
-import { iconHTML } from 'discourse-common/lib/icon-library';
-import DropdownSelectBox from "select-box-kit/components/dropdown-select-box";
+import DropdownSelectBox from "select-kit/components/dropdown-select-box";
import computed from "ember-addons/ember-computed-decorators";
-import { on } from "ember-addons/ember-computed-decorators";
export default DropdownSelectBox.extend({
- headerText: "admin.flags.delete",
classNames: ["delete-flag", "admin-delete-flag-dropdown"],
adminTools: Ember.inject.service(),
nameProperty: "label",
+ headerIcon: "trash-o",
- @on("didReceiveAttrs")
- _setAdminDeleteDropdownOptions() {
- this.get('headerComponentOptions').setProperties({
- selectedName: `${I18n.t(this.get("headerText"))} ...`,
- icon: iconHTML("trash-o")
- });
+ computeHeaderContent() {
+ let content = this.baseHeaderComputedContent();
+ content.name = I18n.t("admin.flags.delete");
+ return content;
},
@computed("adminTools", "post.user")
@@ -24,9 +20,9 @@ export default DropdownSelectBox.extend({
canDeleteSpammer: Ember.computed.and("spammerDetails.canDelete", "post.flaggedForSpam"),
- @computed("post", "canDeleteSpammer")
- content(post, canDeleteSpammer) {
+ computeContent() {
const content = [];
+ const canDeleteSpammer = this.get("canDeleteSpammer");
content.push({
icon: "external-link",
@@ -57,8 +53,9 @@ export default DropdownSelectBox.extend({
return content;
},
- selectValueFunction(value) {
- Ember.get(this._contentForValue(value), "action")();
+ mutateValue(value) {
+ const computedContentItem = this.get("computedContent").findBy("value", value);
+ Ember.get(computedContentItem, "originalContent.action")();
},
actions: {
diff --git a/app/assets/javascripts/select-kit/components/admin-group-selector.js.es6 b/app/assets/javascripts/select-kit/components/admin-group-selector.js.es6
new file mode 100644
index 00000000000..be3352b376b
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/admin-group-selector.js.es6
@@ -0,0 +1,51 @@
+import MultiSelectComponent from "select-kit/components/multi-select";
+const { makeArray } = Ember;
+
+export default MultiSelectComponent.extend({
+ pluginApiIdentifiers: ["admin-group-selector"],
+ classNames: "admin-group-selector",
+ selected: null,
+ available: null,
+ allowAny: false,
+
+ computeValues() {
+ return makeArray(this.get("selected"))
+ .map(s => this.valueForContentItem(s));
+ },
+
+ computeContent() {
+ return makeArray(this.get("available"));
+ },
+
+ computeContentItem(contentItem, name) {
+ let computedContent = this.baseComputedContentItem(contentItem, name);
+ computedContent.locked = contentItem.automatic;
+ return computedContent;
+ },
+
+ mutateValues(values) {
+ if (values.length > this.get("selected").length) {
+ const newValues = values
+ .filter(v => !this.get("selected")
+ .map(s => this.valueForContentItem(s))
+ .includes(v));
+
+ newValues.forEach(value => {
+ const actionContext = this.get("available")
+ .findBy(this.get("valueAttribute"), parseInt(value, 10));
+
+ this.triggerAction({ action: "groupAdded", actionContext });
+ });
+ } else if (values.length < this.get("selected").length) {
+ const selected = this.get("selected")
+ .filter(s => !values.includes(this.valueForContentItem(s)));
+
+ selected.forEach(s => {
+ this.triggerAction({
+ action: "groupRemoved",
+ actionContext: this.valueForContentItem(s)
+ });
+ });
+ }
+ }
+});
diff --git a/app/assets/javascripts/select-box-kit/components/categories-admin-dropdown.js.es6 b/app/assets/javascripts/select-kit/components/categories-admin-dropdown.js.es6
similarity index 51%
rename from app/assets/javascripts/select-box-kit/components/categories-admin-dropdown.js.es6
rename to app/assets/javascripts/select-kit/components/categories-admin-dropdown.js.es6
index 187a710b880..63f1bac5499 100644
--- a/app/assets/javascripts/select-box-kit/components/categories-admin-dropdown.js.es6
+++ b/app/assets/javascripts/select-kit/components/categories-admin-dropdown.js.es6
@@ -1,21 +1,15 @@
-import DropdownSelectBoxComponent from "select-box-kit/components/dropdown-select-box";
-import { iconHTML } from "discourse-common/lib/icon-library";
-import computed from "ember-addons/ember-computed-decorators";
-import { on } from "ember-addons/ember-computed-decorators";
+import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
export default DropdownSelectBoxComponent.extend({
+ pluginApiIdentifiers: ["categories-admin-dropdown"],
classNames: "categories-admin-dropdown",
+ showFullTitle: false,
+ allowInitialValueMutation: false,
+ headerIcon: ["bars", "caret-down"],
- @on("didReceiveAttrs")
- _setComponentOptions() {
- this.get("headerComponentOptions").setProperties({
- shouldDisplaySelectedName: false,
- icon: `${iconHTML('bars')}${iconHTML('caret-down')}`.htmlSafe(),
- });
- },
+ autoHighlight() {},
- @computed
- content() {
+ computeContent() {
const items = [
{
id: "create",
@@ -38,8 +32,7 @@ export default DropdownSelectBoxComponent.extend({
return items;
},
- selectValueFunction(value) {
+ mutateValue(value) {
this.get(value)();
- this.set("value", null);
}
});
diff --git a/app/assets/javascripts/select-kit/components/category-chooser.js.es6 b/app/assets/javascripts/select-kit/components/category-chooser.js.es6
new file mode 100644
index 00000000000..47a319e066a
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/category-chooser.js.es6
@@ -0,0 +1,92 @@
+import ComboBoxComponent from "select-kit/components/combo-box";
+import { on } from "ember-addons/ember-computed-decorators";
+import computed from "ember-addons/ember-computed-decorators";
+import PermissionType from "discourse/models/permission-type";
+import Category from "discourse/models/category";
+const { get, isNone, isEmpty } = Ember;
+
+export default ComboBoxComponent.extend({
+ pluginApiIdentifiers: ["category-chooser"],
+ classNames: "category-chooser",
+ filterable: true,
+ castInteger: true,
+ allowUncategorized: false,
+ rowComponent: "category-row",
+ noneRowComponent: "none-category-row",
+ allowSubCategories: true,
+
+ filterComputedContent(computedContent, computedValue, filter) {
+ if (isEmpty(filter)) { return computedContent; }
+
+ const _matchFunction = (f, text) => {
+ return text.toLowerCase().indexOf(f) > -1;
+ };
+ const lowerFilter = filter.toLowerCase();
+
+ return computedContent.filter(c => {
+ const category = Category.findById(get(c, "value"));
+ const text = get(c, "name");
+ if (category && category.get("parentCategory")) {
+ const categoryName = category.get("parentCategory.name");
+ return _matchFunction(lowerFilter, text) || _matchFunction(lowerFilter, categoryName);
+ } else {
+ return _matchFunction(lowerFilter, text);
+ }
+ });
+ },
+
+ @computed("rootNone", "rootNoneLabel")
+ none(rootNone, rootNoneLabel) {
+ if (this.siteSettings.allow_uncategorized_topics || this.get("allowUncategorized")) {
+ if (!isNone(rootNone)) {
+ return rootNoneLabel || "category.none";
+ } else {
+ return Category.findUncategorized();
+ }
+ } else {
+ return "category.choose";
+ }
+ },
+
+ @on("didRender")
+ _bindComposerResizing() {
+ this.appEvents.on("composer:resized", this, this.applyDirection);
+ },
+
+ @on("willDestroyElement")
+ _unbindComposerResizing() {
+ this.appEvents.off("composer:resized");
+ },
+
+ computeContent() {
+ const categories = Discourse.SiteSettings.fixed_category_positions_on_create ?
+ Category.list() :
+ Category.listByActivity();
+
+ let scopedCategoryId = this.get("scopedCategoryId");
+ if (scopedCategoryId) {
+ const scopedCat = Category.findById(scopedCategoryId);
+ scopedCategoryId = scopedCat.get("parent_category_id") || scopedCat.get("id");
+ }
+
+ const excludeCategoryId = this.get("excludeCategoryId");
+
+ return categories.filter(c => {
+ const categoryId = this.valueForContentItem(c);
+
+ if (scopedCategoryId && categoryId !== scopedCategoryId && get(c, "parent_category_id") !== scopedCategoryId) {
+ return false;
+ }
+
+ if (this.get("allowSubCategories") === false && c.get("parentCategory") ) {
+ return false;
+ }
+
+ if ((this.get("allowUncategorized") === false && get(c, "isUncategorizedCategory")) || excludeCategoryId === categoryId) {
+ return false;
+ }
+
+ return get(c, "permission") === PermissionType.FULL;
+ });
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/category-notifications-button.js.es6 b/app/assets/javascripts/select-kit/components/category-notifications-button.js.es6
new file mode 100644
index 00000000000..f84c0ba4c2f
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/category-notifications-button.js.es6
@@ -0,0 +1,20 @@
+import NotificationOptionsComponent from "select-kit/components/notifications-button";
+import computed from "ember-addons/ember-computed-decorators";
+
+export default NotificationOptionsComponent.extend({
+ pluginApiIdentifiers: ["category-notifications-button"],
+ classNames: "category-notifications-button",
+ isHidden: Ember.computed.or("category.deleted", "site.isMobileDevice"),
+ i18nPrefix: "category.notifications",
+ showFullTitle: false,
+ allowInitialValueMutation: false,
+
+ mutateValue(value) {
+ this.get("category").setNotification(value);
+ },
+
+ @computed("iconForSelectedDetails")
+ headerIcon(iconForSelectedDetails) {
+ return [iconForSelectedDetails, "caret-down"];
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/category-row.js.es6 b/app/assets/javascripts/select-kit/components/category-row.js.es6
new file mode 100644
index 00000000000..b3470102296
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/category-row.js.es6
@@ -0,0 +1,63 @@
+import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
+import computed from "ember-addons/ember-computed-decorators";
+import Category from "discourse/models/category";
+import { categoryBadgeHTML } from "discourse/helpers/category-link";
+
+export default SelectKitRowComponent.extend({
+ layoutName: "select-kit/templates/components/category-row",
+ classNames: "category-row",
+ displayCategoryDescription: true,
+
+ @computed("computedContent.value", "computedContent.name")
+ category(value, name) {
+ if (Ember.isEmpty(value)) {
+ const uncat = Category.findUncategorized();
+ if (uncat && uncat.get("name") === name) {
+ return uncat;
+ }
+ } else {
+ return Category.findById(parseInt(value, 10));
+ }
+ },
+
+ @computed("category")
+ badgeForCategory(category) {
+ return categoryBadgeHTML(category, {
+ link: false,
+ allowUncategorized: true,
+ hideParent: true
+ }).htmlSafe();
+ },
+
+ @computed("parentCategory")
+ badgeForParentCategory(parentCategory) {
+ return categoryBadgeHTML(parentCategory, {link: false}).htmlSafe();
+ },
+
+ @computed("parentCategoryid")
+ parentCategory(parentCategoryId) {
+ return Category.findById(parentCategoryId);
+ },
+
+ @computed("parentCategoryid")
+ hasParentCategory(parentCategoryid) {
+ return !Ember.isNone(parentCategoryid);
+ },
+
+ @computed("category")
+ parentCategoryid(category) {
+ return category.get("parent_category_id");
+ },
+
+ topicCount: Ember.computed.alias("category.topic_count"),
+
+ @computed("options.displayCategoryDescription", "category.description")
+ hasDescription(displayCategoryDescription, description) {
+ return displayCategoryDescription && description && description !== "null";
+ },
+
+ @computed("category.description")
+ description(description) {
+ return `${description.substr(0, 200)}${description.length > 200 ? '…' : ''}`;
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/category-selector.js.es6 b/app/assets/javascripts/select-kit/components/category-selector.js.es6
new file mode 100644
index 00000000000..9305517bf99
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/category-selector.js.es6
@@ -0,0 +1,40 @@
+import MultiSelectComponent from "select-kit/components/multi-select";
+import Category from "discourse/models/category";
+
+export default MultiSelectComponent.extend({
+ pluginApiIdentifiers: ["category-selector"],
+ classNames: "category-selector",
+ filterable: true,
+ allowAny: false,
+ rowComponent: "category-row",
+
+ init() {
+ this._super();
+
+ this.set("headerComponentOptions", Ember.Object.create({
+ selectedNameComponent: "multi-select/selected-category"
+ }));
+
+ this.set("rowComponentOptions", Ember.Object.create({
+ displayCategoryDescription: false
+ }));
+ },
+
+ computeValues() {
+ return Ember.makeArray(this.get("categories")).map(c => c.id);
+ },
+
+ mutateValues(values) {
+ this.set("categories", values.map(v => Category.findById(v)));
+ },
+
+ filterComputedContent(computedContent, computedValues, filter) {
+ const regex = new RegExp(filter.toLowerCase(), 'i');
+ return computedContent.filter(category => Ember.get(category, "name").match(regex));
+ },
+
+ computeContent() {
+ const blacklist = Ember.makeArray(this.get("blacklist"));
+ return Category.list().filter(category => !blacklist.includes(category));
+ }
+});
diff --git a/app/assets/javascripts/select-box-kit/components/combo-box.js.es6 b/app/assets/javascripts/select-kit/components/combo-box.js.es6
similarity index 61%
rename from app/assets/javascripts/select-box-kit/components/combo-box.js.es6
rename to app/assets/javascripts/select-kit/components/combo-box.js.es6
index 26779a38949..0a576eae9af 100644
--- a/app/assets/javascripts/select-box-kit/components/combo-box.js.es6
+++ b/app/assets/javascripts/select-kit/components/combo-box.js.es6
@@ -1,7 +1,8 @@
-import SelectBoxKitComponent from "select-box-kit/components/select-box-kit";
+import SingleSelectComponent from "select-kit/components/single-select";
import { on } from "ember-addons/ember-computed-decorators";
-export default SelectBoxKitComponent.extend({
+export default SingleSelectComponent.extend({
+ pluginApiIdentifiers: ["combo-box"],
classNames: "combobox combo-box",
autoFilterable: true,
headerComponent: "combo-box/combo-box-header",
@@ -10,6 +11,12 @@ export default SelectBoxKitComponent.extend({
caretDownIcon: "caret-down",
clearable: false,
+ computeHeaderContent() {
+ let content = this.baseHeaderComputedContent();
+ content.hasSelection = this.get("hasSelection");
+ return content;
+ },
+
@on("didReceiveAttrs")
_setComboBoxOptions() {
this.get("headerComponentOptions").setProperties({
diff --git a/app/assets/javascripts/select-kit/components/combo-box/combo-box-header.js.es6 b/app/assets/javascripts/select-kit/components/combo-box/combo-box-header.js.es6
new file mode 100644
index 00000000000..6cc5ecd21f7
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/combo-box/combo-box-header.js.es6
@@ -0,0 +1,21 @@
+import SelectKitHeaderComponent from "select-kit/components/select-kit/select-kit-header";
+import { default as computed } from "ember-addons/ember-computed-decorators";
+
+export default SelectKitHeaderComponent.extend({
+ layoutName: "select-kit/templates/components/combo-box/combo-box-header",
+ classNames: "combo-box-header",
+
+ clearable: Ember.computed.alias("options.clearable"),
+ caretUpIcon: Ember.computed.alias("options.caretUpIcon"),
+ caretDownIcon: Ember.computed.alias("options.caretDownIcon"),
+
+ @computed("isExpanded", "caretUpIcon", "caretDownIcon")
+ caretIcon(isExpanded, caretUpIcon, caretDownIcon) {
+ return isExpanded === true ? caretUpIcon : caretDownIcon;
+ },
+
+ @computed("clearable", "computedContent.hasSelection")
+ shouldDisplayClearableButton(clearable, hasSelection) {
+ return clearable === true && hasSelection === true;
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/dropdown-select-box.js.es6 b/app/assets/javascripts/select-kit/components/dropdown-select-box.js.es6
new file mode 100644
index 00000000000..8e7636445a1
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/dropdown-select-box.js.es6
@@ -0,0 +1,32 @@
+import SingleSelectComponent from "select-kit/components/single-select";
+import { on } from "ember-addons/ember-computed-decorators";
+
+export default SingleSelectComponent.extend({
+ pluginApiIdentifiers: ["dropdown-select-box"],
+ classNames: "dropdown-select-box",
+ verticalOffset: 3,
+ fullWidthOnMobile: true,
+ filterable: false,
+ autoFilterable: false,
+ headerComponent: "dropdown-select-box/dropdown-select-box-header",
+ rowComponent: "dropdown-select-box/dropdown-select-box-row",
+ showFullTitle: true,
+ allowInitialValueMutation: false,
+
+ @on("didReceiveAttrs")
+ _setDropdownSelectBoxComponentOptions() {
+ this.get("headerComponentOptions").setProperties({
+ showFullTitle: this.get("showFullTitle")
+ });
+ },
+
+ didClickOutside() {
+ if (this.get("isExpanded") === false) { return; }
+ this.close();
+ },
+
+ didSelect() {
+ this._super();
+ this.close();
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6 b/app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6
new file mode 100644
index 00000000000..d7e08764309
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-header.js.es6
@@ -0,0 +1,15 @@
+import SelectKitHeaderComponent from "select-kit/components/select-kit/select-kit-header";
+import computed from "ember-addons/ember-computed-decorators";
+
+export default SelectKitHeaderComponent.extend({
+ layoutName: "select-kit/templates/components/dropdown-select-box/dropdown-select-box-header",
+ classNames: "dropdown-select-box-header",
+ tagName: "button",
+
+ classNameBindings: ["btnClassName"],
+
+ @computed("options.showFullTitle")
+ btnClassName(showFullTitle) {
+ return `btn ${showFullTitle ? 'btn-icon-text' : 'no-text btn-icon'}`;
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6 b/app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6
new file mode 100644
index 00000000000..fd865fb6021
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/dropdown-select-box/dropdown-select-box-row.js.es6
@@ -0,0 +1,9 @@
+import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
+
+export default SelectKitRowComponent.extend({
+ layoutName: "select-kit/templates/components/dropdown-select-box/dropdown-select-box-row",
+ classNames: "dropdown-select-box-row",
+
+ name: Ember.computed.alias("computedContent.name"),
+ description: Ember.computed.alias("computedContent.originalContent.description")
+});
diff --git a/app/assets/javascripts/select-box-kit/components/future-date-input-selector.js.es6 b/app/assets/javascripts/select-kit/components/future-date-input-selector.js.es6
similarity index 79%
rename from app/assets/javascripts/select-box-kit/components/future-date-input-selector.js.es6
rename to app/assets/javascripts/select-kit/components/future-date-input-selector.js.es6
index b344f2080e6..961c7c2cf97 100644
--- a/app/assets/javascripts/select-box-kit/components/future-date-input-selector.js.es6
+++ b/app/assets/javascripts/select-kit/components/future-date-input-selector.js.es6
@@ -1,7 +1,6 @@
-import { default as computed, observes } from "ember-addons/ember-computed-decorators";
-import ComboBoxComponent from "select-box-kit/components/combo-box";
+import ComboBoxComponent from "select-kit/components/combo-box";
import { CLOSE_STATUS_TYPE } from "discourse/controllers/edit-topic-timer";
-import DatetimeMixin from "select-box-kit/components/future-date-input-selector/mixin";
+import DatetimeMixin from "select-kit/components/future-date-input-selector/mixin";
const TIMEFRAME_BASE = {
enabled: () => true,
@@ -112,14 +111,30 @@ export function timeframeDetails(id) {
export const FORMAT = "YYYY-MM-DD HH:mm";
export default ComboBoxComponent.extend(DatetimeMixin, {
+ pluginApiIdentifiers: ["future-date-input-selector"],
classNames: ["future-date-input-selector"],
isCustom: Ember.computed.equal("value", "pick_date_and_time"),
clearable: true,
rowComponent: "future-date-input-selector/future-date-input-selector-row",
headerComponent: "future-date-input-selector/future-date-input-selector-header",
- @computed
- content() {
+ computeHeaderContent() {
+ let content = this.baseHeaderComputedContent();
+ content.datetime = this._computeDatetimeForValue(this.get("computedValue"));
+ content.name = this.get("selectedComputedContent.name") || content.name;
+ content.hasSelection = this.get("hasSelection");
+ content.icons = this._computeIconsForValue(this.get("computedValue"));
+ return content;
+ },
+
+ computeContentItem(contentItem, name) {
+ let item = this.baseComputedContentItem(contentItem, name);
+ item.datetime = this._computeDatetimeForValue(contentItem.id);
+ item.icons = this._computeIconsForValue(contentItem.id);
+ return item;
+ },
+
+ computeContent() {
let now = moment();
let opts = {
now,
@@ -138,21 +153,15 @@ export default ComboBoxComponent.extend(DatetimeMixin, {
});
},
- @observes("value")
- _updateInput() {
+ mutateValue(value) {
if (this.get("isCustom")) return;
let input = null;
- const { time } = this.get("updateAt");
+ const { time } = this._updateAt(value);
- if (time && !Ember.isEmpty(this.get("value"))) {
+ if (time && !Ember.isEmpty(value)) {
input = time.format(FORMAT);
}
- this.set("input", input);
+ this.setProperties({ input, value });
},
-
- @computed("value")
- updateAt(value) {
- return this._updateAt(value);
- }
});
diff --git a/app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6 b/app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6
new file mode 100644
index 00000000000..7a5e8075381
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-header.js.es6
@@ -0,0 +1,6 @@
+import ComboBoxHeaderComponent from "select-kit/components/combo-box/combo-box-header";
+
+export default ComboBoxHeaderComponent.extend({
+ layoutName: "select-kit/templates/components/future-date-input-selector/future-date-input-selector-header",
+ classNames: "future-date-input-selector-header"
+});
diff --git a/app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6 b/app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6
new file mode 100644
index 00000000000..a04a59507b1
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/future-date-input-selector/future-date-input-selector-row.js.es6
@@ -0,0 +1,6 @@
+import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
+
+export default SelectKitRowComponent.extend({
+ layoutName: "select-kit/templates/components/future-date-input-selector/future-date-input-selector-row",
+ classNames: "future-date-input-selector-row"
+});
diff --git a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/mixin.js.es6 b/app/assets/javascripts/select-kit/components/future-date-input-selector/mixin.js.es6
similarity index 76%
rename from app/assets/javascripts/select-box-kit/components/future-date-input-selector/mixin.js.es6
rename to app/assets/javascripts/select-kit/components/future-date-input-selector/mixin.js.es6
index d69b38a5666..63689570562 100644
--- a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/mixin.js.es6
+++ b/app/assets/javascripts/select-kit/components/future-date-input-selector/mixin.js.es6
@@ -1,16 +1,15 @@
-import { iconHTML } from 'discourse-common/lib/icon-library';
import { CLOSE_STATUS_TYPE } from 'discourse/controllers/edit-topic-timer';
-import { timeframeDetails } from 'select-box-kit/components/future-date-input-selector';
+import { timeframeDetails } from 'select-kit/components/future-date-input-selector';
export default Ember.Mixin.create({
- _computeIconForValue(value) {
+ _computeIconsForValue(value) {
let {icon} = this._updateAt(value);
if (icon) {
- return icon.split(",").map(i => iconHTML(i)).join(" ");
+ return icon.split(",");
}
- return null;
+ return [];
},
_computeDatetimeForValue(value) {
@@ -20,7 +19,6 @@ export default Ember.Mixin.create({
let {time} = this._updateAt(value);
if (time) {
-
let details = timeframeDetails(value);
if (!details.displayWhen) {
time = null;
@@ -34,6 +32,7 @@ export default Ember.Mixin.create({
_updateAt(selection) {
let details = timeframeDetails(selection);
+
if (details) {
return {
time: details.when(moment(), this.get('statusType') !== CLOSE_STATUS_TYPE ? 8 : 18),
diff --git a/app/assets/javascripts/select-box-kit/components/group-notifications-button.js.es6 b/app/assets/javascripts/select-kit/components/group-notifications-button.js.es6
similarity index 51%
rename from app/assets/javascripts/select-box-kit/components/group-notifications-button.js.es6
rename to app/assets/javascripts/select-kit/components/group-notifications-button.js.es6
index e30b4ec62fc..8236e4bbe14 100644
--- a/app/assets/javascripts/select-box-kit/components/group-notifications-button.js.es6
+++ b/app/assets/javascripts/select-kit/components/group-notifications-button.js.es6
@@ -1,11 +1,12 @@
-import NotificationOptionsComponent from "select-box-kit/components/notifications-button";
+import NotificationOptionsComponent from "select-kit/components/notifications-button";
export default NotificationOptionsComponent.extend({
+ pluginApiIdentifiers: ["grouo-notifications-button"],
classNames: ["group-notifications-button"],
- value: Ember.computed.alias("group.group_user.notification_level"),
i18nPrefix: "groups.notifications",
+ allowInitialValueMutation: false,
- selectValueFunction(value) {
+ mutateValue(value) {
this.get("group").setNotification(value, this.get("user.id"));
}
});
diff --git a/app/assets/javascripts/select-kit/components/list-setting.js.es6 b/app/assets/javascripts/select-kit/components/list-setting.js.es6
new file mode 100644
index 00000000000..0872aab9510
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/list-setting.js.es6
@@ -0,0 +1,54 @@
+import MultiSelectComponent from "select-kit/components/multi-select";
+
+export default MultiSelectComponent.extend({
+ pluginApiIdentifiers: ["list-setting"],
+ classNames: "list-setting",
+ tokenSeparator: "|",
+ settingValue: "",
+ choices: null,
+ filterable: true,
+
+ init() {
+ this._super();
+
+ if (!Ember.isNone(this.get("settingName"))) {
+ this.set("nameProperty", this.get("settingName"));
+ }
+
+ if (this.get("nameProperty").indexOf("color") > -1) {
+ this.set("headerComponentOptions", Ember.Object.create({
+ selectedNameComponent: "multi-select/selected-color"
+ }));
+ }
+ },
+
+ computeContent() {
+ let content;
+ if (Ember.isNone(this.get("choices"))) {
+ content = this.get("settingValue").split(this.get("tokenSeparator"));;
+ } else {
+ content = this.get("choices");
+ }
+
+ return Ember.makeArray(content).filter(c => c);
+ },
+
+ mutateValues(values) {
+ this.set("settingValue", values.join(this.get("tokenSeparator")));
+ },
+
+ computeValues() {
+ return this.get("settingValue")
+ .split(this.get("tokenSeparator"))
+ .filter(c => c);
+ },
+
+ _handleTabOnKeyDown(event) {
+ if (this.$highlightedRow().length === 1) {
+ this._super(event);
+ } else {
+ this.close();
+ return false;
+ }
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/multi-select.js.es6 b/app/assets/javascripts/select-kit/components/multi-select.js.es6
new file mode 100644
index 00000000000..ceb7e373919
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/multi-select.js.es6
@@ -0,0 +1,255 @@
+import SelectKitComponent from "select-kit/components/select-kit";
+import computed from "ember-addons/ember-computed-decorators";
+import { on } from "ember-addons/ember-computed-decorators";
+const { get, isNone, isEmpty, makeArray } = Ember;
+
+export default SelectKitComponent.extend({
+ pluginApiIdentifiers: ["multi-select"],
+ classNames: "multi-select",
+ headerComponent: "multi-select/multi-select-header",
+ filterComponent: null,
+ headerText: "select_kit.default_header_text",
+ allowAny: true,
+ allowInitialValueMutation: false,
+ autoFilterable: true,
+ selectedNameComponent: "multi-select/selected-name",
+
+ init() {
+ this._super();
+
+ this.set("computedValues", []);
+ if (isNone(this.get("values"))) { this.set("values", []); }
+
+ this.set("headerComponentOptions", Ember.Object.create({
+ selectedNameComponent: this.get("selectedNameComponent")
+ }));
+ },
+
+ @on("didRender")
+ _setChoicesMaxWidth() {
+ const width = this.$body().outerWidth(false);
+ this.$(".choices").css({ maxWidth: width, width });
+ },
+
+ @on("didReceiveAttrs")
+ _compute() {
+ Ember.run.scheduleOnce("afterRender", () => {
+ this.willComputeAttributes();
+ let content = this._beforeWillComputeContent(this.get("content"));
+ content = this.willComputeContent(content);
+ let values = this._beforeWillComputeValues(this.get("values"));
+ content = this.computeContent(content);
+ content = this._beforeDidComputeContent(content);
+ values = this.willComputeValues(values);
+ values = this.computeValues(values);
+ values = this._beforeDidComputeValues(values);
+ this.set("headerComputedContent", this.computeHeaderContent());
+ this.didComputeContent(content);
+ this.didComputeValues(values);
+ this.didComputeAttributes();
+ });
+ },
+
+ @computed("filter", "shouldDisplayCreateRow")
+ createRowComputedContent(filter, shouldDisplayCreateRow) {
+ if (shouldDisplayCreateRow === true) {
+ let content = this.createContentFromInput(filter);
+ return this.computeContentItem(content, { created: true });
+ }
+ },
+
+ @computed("filter", "computedValues")
+ shouldDisplayCreateRow(filter, computedValues) {
+ return this._super() && !computedValues.includes(filter);
+ },
+
+ _beforeWillComputeValues(values) {
+ return values.map(v => this._castInteger(v === "" ? null : v));
+ },
+ willComputeValues(values) { return values; },
+ computeValues(values) { return values; },
+ _beforeDidComputeValues(values) {
+ this.setProperties({ computedValues: values });
+ return values;
+ },
+ didComputeValues(values) { return values; },
+
+ mutateAttributes() {
+ Ember.run.next(() => {
+ this.mutateContent(this.get("computedContent"));
+ this.mutateValues(this.get("computedValues"));
+ this.set("headerComputedContent", this.computeHeaderContent());
+ });
+ },
+ mutateValues(computedValues) { this.set("values", computedValues); },
+
+ filterComputedContent(computedContent, computedValues, filter) {
+ const lowerFilter = filter.toLowerCase();
+ return computedContent.filter(c => {
+ return get(c, "name").toLowerCase().indexOf(lowerFilter) > -1;
+ });
+ },
+
+ @computed("computedContent.[]", "computedValues.[]", "filter")
+ filteredComputedContent(computedContent, computedValues, filter) {
+ computedContent = computedContent.filter(c => {
+ return !computedValues.includes(get(c, "value"));
+ });
+
+ if (this.get("shouldFilter") === true) {
+ computedContent = this.filterComputedContent(computedContent, computedValues, filter);
+ }
+
+ return computedContent.slice(0, this.get("limitMatches"));
+ },
+
+ baseHeaderComputedContent() {
+ return {
+ selectedComputedContents: this.get("selectedComputedContents")
+ };
+ },
+
+ @computed("filter")
+ templateForCreateRow() {
+ return (rowComponent) => {
+ return I18n.t("select_kit.create", { content: rowComponent.get("computedContent.name")});
+ };
+ },
+
+ didPressBackspace(event) {
+ this.expand();
+ this.keyDown(event);
+ this._destroyEvent(event);
+ },
+
+ didPressEscape(event) {
+ const $highlighted = this.$(".selected-name.is-highlighted");
+ if ($highlighted.length > 0) {
+ $highlighted.removeClass("is-highlighted");
+ }
+
+ this._super(event);
+ },
+
+ keyDown(event) {
+ if (!isEmpty(this.get("filter"))) return;
+
+ const keyCode = event.keyCode || event.which;
+ const $filterInput = this.$filterInput();
+
+ // select all choices
+ if (this.get("hasSelection") && event.metaKey === true && keyCode === 65) {
+ this.$(".choices .selected-name:not(.is-locked)").addClass("is-highlighted");
+ return false;
+ }
+
+ // clear selection when multiple
+ if (this.$(".selected-name.is-highlighted").length >= 1 && keyCode === this.keys.BACKSPACE) {
+ const highlightedComputedContents = [];
+ $.each(this.$(".selected-name.is-highlighted"), (i, el) => {
+ const computedContent = this._findComputedContentItemByGuid($(el).attr("data-guid"));
+ if (!Ember.isNone(computedContent)) { highlightedComputedContents.push(computedContent); }
+ });
+ this.send("onDeselect", highlightedComputedContents);
+ return;
+ }
+
+ // try to remove last item from the list
+ if (keyCode === this.keys.BACKSPACE) {
+ let $lastSelectedValue = $(this.$(".choices .selected-name:not(.is-locked)").last());
+
+ if ($lastSelectedValue.length === 0) { return; }
+
+ if ($filterInput.not(":visible") && $lastSelectedValue.length > 0) {
+ $lastSelectedValue.click();
+ return false;
+ }
+
+ if ($filterInput.val() === "") {
+ if ($filterInput.is(":focus")) {
+ if ($lastSelectedValue.length > 0) { $lastSelectedValue.click(); }
+ } else {
+ if ($lastSelectedValue.length > 0) {
+ $lastSelectedValue.click();
+ } else {
+ $filterInput.focus();
+ }
+ }
+ }
+ }
+ },
+
+ @computed("computedValues.[]", "computedContent.[]")
+ selectedComputedContents(computedValues, computedContent) {
+ const selected = [];
+ computedValues.forEach(v => selected.push(computedContent.findBy("value", v)) );
+ return selected;
+ },
+
+ @computed("selectedComputedContents.[]")
+ hasSelection(selectedComputedContents) { return !Ember.isEmpty(selectedComputedContents); },
+
+ autoHighlight() {
+ Ember.run.schedule("afterRender", () => {
+ if (this.get("isExpanded") === false) { return; }
+ if (this.get("renderedBodyOnce") === false) { return; }
+ if (!isNone(this.get("highlightedValue"))) { return; }
+
+ if (isEmpty(this.get("filteredComputedContent"))) {
+ if (this.get("createRowComputedContent")) {
+ this.send("onHighlight", this.get("createRowComputedContent"));
+ } else if (this.get("noneRowComputedContent") && this.get("hasSelection") === true) {
+ this.send("onHighlight", this.get("noneRowComputedContent"));
+ }
+ } else {
+ this.send("onHighlight", this.get("filteredComputedContent.firstObject"));
+ }
+ });
+ },
+
+ didSelect() {
+ this.focus();
+ this.autoHighlight();
+ },
+
+ didDeselect() {
+ this.focus();
+ this.autoHighlight();
+ },
+
+ validateComputedContentItem(computedContentItem) {
+ return !this.get("computedValues").includes(computedContentItem.value);
+ },
+
+ actions: {
+ onClear() {
+ this.get("selectedComputedContents").forEach(selectedComputedContent => {
+ this.send("onDeselect", selectedComputedContent);
+ });
+ },
+
+ onCreate(computedContentItem) {
+ if (this.validateComputedContentItem(computedContentItem)) {
+ this.get("computedContent").pushObject(computedContentItem);
+ this.send("onSelect", computedContentItem);
+ }
+ },
+
+ onSelect(computedContentItem) {
+ this.willSelect(computedContentItem);
+ this.get("computedValues").pushObject(computedContentItem.value);
+ Ember.run.next(() => this.mutateAttributes());
+ Ember.run.schedule("afterRender", () => this.didSelect(computedContentItem));
+ },
+
+ onDeselect(rowComputedContentItems) {
+ rowComputedContentItems = Ember.makeArray(rowComputedContentItems);
+ const generatedComputedContents = this._filterRemovableComputedContents(makeArray(rowComputedContentItems));
+ this.willDeselect(rowComputedContentItems);
+ this.get("computedValues").removeObjects(rowComputedContentItems.map(r => r.value));
+ this.get("computedContent").removeObjects(generatedComputedContents);
+ Ember.run.next(() => this.mutateAttributes());
+ Ember.run.schedule("afterRender", () => this.didDeselect(rowComputedContentItems));
+ }
+ }
+});
diff --git a/app/assets/javascripts/select-box-kit/components/multi-combo-box/multi-combo-box-header.js.es6 b/app/assets/javascripts/select-kit/components/multi-select/multi-select-header.js.es6
similarity index 66%
rename from app/assets/javascripts/select-box-kit/components/multi-combo-box/multi-combo-box-header.js.es6
rename to app/assets/javascripts/select-kit/components/multi-select/multi-select-header.js.es6
index 10e2d299ceb..d86af77ed8b 100644
--- a/app/assets/javascripts/select-box-kit/components/multi-combo-box/multi-combo-box-header.js.es6
+++ b/app/assets/javascripts/select-kit/components/multi-select/multi-select-header.js.es6
@@ -1,11 +1,11 @@
import { on } from "ember-addons/ember-computed-decorators";
import computed from "ember-addons/ember-computed-decorators";
-import SelectBoxKitHeaderComponent from "select-box-kit/components/select-box-kit/select-box-kit-header";
+import SelectKitHeaderComponent from "select-kit/components/select-kit/select-kit-header";
-export default SelectBoxKitHeaderComponent.extend({
+export default SelectKitHeaderComponent.extend({
attributeBindings: ["names:data-name"],
- classNames: "multi-combo-box-header",
- layoutName: "select-box-kit/templates/components/multi-combo-box/multi-combo-box-header",
+ classNames: "multi-select-header",
+ layoutName: "select-kit/templates/components/multi-select/multi-select-header",
selectedNameComponent: Ember.computed.alias("options.selectedNameComponent"),
@on("didRender")
@@ -25,6 +25,8 @@ export default SelectBoxKitHeaderComponent.extend({
$filter.width(availableSpace - parentRightPadding * 4);
},
- @computed("selectedContent.[]")
- names(selectedContent) { return selectedContent.map(sc => sc.name).join(","); }
+ @computed("computedContent.selectedComputedContents.[]")
+ names(selectedComputedContents) {
+ return Ember.makeArray(selectedComputedContents).map(sc => sc.name).join(",");
+ }
});
diff --git a/app/assets/javascripts/select-kit/components/multi-select/selected-category.js.es6 b/app/assets/javascripts/select-kit/components/multi-select/selected-category.js.es6
new file mode 100644
index 00000000000..0a09d69fabb
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/multi-select/selected-category.js.es6
@@ -0,0 +1,13 @@
+import SelectedNameComponent from "select-kit/components/multi-select/selected-name";
+import computed from "ember-addons/ember-computed-decorators";
+import { categoryBadgeHTML } from "discourse/helpers/category-link";
+
+export default SelectedNameComponent.extend({
+ classNames: "selected-category",
+ layoutName: "select-kit/templates/components/multi-select/selected-category",
+
+ @computed("content.originalContent")
+ badge(category) {
+ return categoryBadgeHTML(category, {allowUncategorized: true, link: false}).htmlSafe();
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/multi-select/selected-color.js.es6 b/app/assets/javascripts/select-kit/components/multi-select/selected-color.js.es6
new file mode 100644
index 00000000000..3349d95ff8a
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/multi-select/selected-color.js.es6
@@ -0,0 +1,11 @@
+import SelectedNameComponent from "select-kit/components/multi-select/selected-name";
+
+export default SelectedNameComponent.extend({
+ classNames: "selected-color",
+ layoutName: "select-kit/templates/components/multi-select/selected-color",
+
+ didRender() {
+ const name = this.get("content.name");
+ this.$(".color-preview").css("background", `#${name}`.htmlSafe());
+ }
+});
diff --git a/app/assets/javascripts/select-box-kit/components/multi-combo-box/selected-name.js.es6 b/app/assets/javascripts/select-kit/components/multi-select/selected-name.js.es6
similarity index 50%
rename from app/assets/javascripts/select-box-kit/components/multi-combo-box/selected-name.js.es6
rename to app/assets/javascripts/select-kit/components/multi-select/selected-name.js.es6
index 07c3ad0d64c..c3ca9488e53 100644
--- a/app/assets/javascripts/select-box-kit/components/multi-combo-box/selected-name.js.es6
+++ b/app/assets/javascripts/select-kit/components/multi-select/selected-name.js.es6
@@ -1,18 +1,27 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
- attributeBindings: ["tabindex","content.name:data-name", "content.value:data-value"],
- classNames: "selected-name",
+ attributeBindings: [
+ "tabindex",
+ "content.name:data-name",
+ "content.value:data-value",
+ "guid:data-guid"
+ ],
+ classNames: ["selected-name", "choice"],
classNameBindings: ["isHighlighted", "isLocked"],
- layoutName: "select-box-kit/templates/components/multi-combo-box/selected-name",
+ layoutName: "select-kit/templates/components/multi-select/selected-name",
tagName: "li",
tabindex: -1,
+ @computed("content")
+ guid(content) { return Ember.guidFor(content); },
+
isLocked: Ember.computed("content.locked", function() {
return this.getWithDefault("content.locked", false);
}),
click() {
if (this.get("isLocked") === true) { return false; }
-
this.toggleProperty("isHighlighted");
return false;
}
diff --git a/app/assets/javascripts/select-kit/components/none-category-row.js.es6 b/app/assets/javascripts/select-kit/components/none-category-row.js.es6
new file mode 100644
index 00000000000..60b932920ee
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/none-category-row.js.es6
@@ -0,0 +1,10 @@
+import CategoryRowComponent from "select-kit/components/category-row";
+
+export default CategoryRowComponent.extend({
+ layoutName: "select-kit/templates/components/category-row",
+ classNames: "none category-row",
+
+ click() {
+ this.sendAction("onClear");
+ }
+});
diff --git a/app/assets/javascripts/select-box-kit/components/notifications-button.js.es6 b/app/assets/javascripts/select-kit/components/notifications-button.js.es6
similarity index 56%
rename from app/assets/javascripts/select-box-kit/components/notifications-button.js.es6
rename to app/assets/javascripts/select-kit/components/notifications-button.js.es6
index d0515535001..344ca204cee 100644
--- a/app/assets/javascripts/select-box-kit/components/notifications-button.js.es6
+++ b/app/assets/javascripts/select-kit/components/notifications-button.js.es6
@@ -1,4 +1,4 @@
-import DropdownSelectBoxComponent from "select-box-kit/components/dropdown-select-box";
+import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
import { default as computed, on } from "ember-addons/ember-computed-decorators";
import { buttonDetails } from "discourse/lib/notification-levels";
import { allLevels } from "discourse/lib/notification-levels";
@@ -9,24 +9,29 @@ export default DropdownSelectBoxComponent.extend({
fullWidthOnMobile: true,
content: allLevels,
collectionHeight: "auto",
- value: Ember.computed.alias("notificationLevel"),
castInteger: true,
autofilterable: false,
filterable: false,
rowComponent: "notifications-button/notifications-button-row",
- headerComponent: "notifications-button/notifications-button-header",
-
+ allowInitialValueMutation: false,
i18nPrefix: "",
i18nPostfix: "",
- showFullTitle: true,
- @on("didReceiveAttrs", "didUpdateAttrs")
- _setComponentOptions() {
- this.get("headerComponentOptions").setProperties({
- i18nPrefix: this.get("i18nPrefix"),
- showFullTitle: this.get("showFullTitle"),
- });
+ @computed("iconForSelectedDetails")
+ headerIcon(iconForSelectedDetails) { return iconForSelectedDetails; },
+ @computed("selectedDetails.icon")
+ iconForSelectedDetails(icon) { return icon; },
+
+ computeHeaderContent() {
+ let content = this.baseHeaderComputedContent();
+ content.name = I18n.t(`${this.get("i18nPrefix")}.${this.get("selectedDetails.key")}.title`);
+ content.hasSelection = this.get("hasSelection");
+ return content;
+ },
+
+ @on("didReceiveAttrs")
+ _setNotificationsButtonComponentOptions() {
this.get("rowComponentOptions").setProperties({
i18nPrefix: this.get("i18nPrefix"),
i18nPostfix: this.get("i18nPostfix")
diff --git a/app/assets/javascripts/select-box-kit/components/notifications-button/notifications-button-row.js.es6 b/app/assets/javascripts/select-kit/components/notifications-button/notifications-button-row.js.es6
similarity index 76%
rename from app/assets/javascripts/select-box-kit/components/notifications-button/notifications-button-row.js.es6
rename to app/assets/javascripts/select-kit/components/notifications-button/notifications-button-row.js.es6
index 6f3f257b439..e2e89d3a0b1 100644
--- a/app/assets/javascripts/select-box-kit/components/notifications-button/notifications-button-row.js.es6
+++ b/app/assets/javascripts/select-kit/components/notifications-button/notifications-button-row.js.es6
@@ -1,4 +1,4 @@
-import DropdownSelectBoxRoxComponent from "select-box-kit/components/dropdown-select-box/dropdown-select-box-row";
+import DropdownSelectBoxRoxComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-row";
import { buttonDetails } from "discourse/lib/notification-levels";
import computed from "ember-addons/ember-computed-decorators";
import { iconHTML } from 'discourse-common/lib/icon-library';
@@ -9,13 +9,13 @@ export default DropdownSelectBoxRoxComponent.extend({
i18nPrefix: Ember.computed.alias("options.i18nPrefix"),
i18nPostfix: Ember.computed.alias("options.i18nPostfix"),
- @computed("content.value", "i18nPrefix")
+ @computed("computedContent.value", "i18nPrefix")
title(value, prefix) {
const key = buttonDetails(value).key;
return I18n.t(`${prefix}.${key}.title`);
},
- @computed("content.name", "content.originalContent.icon")
+ @computed("computedContent.name", "computedContent.originalContent.icon")
icon(contentName, icon) {
return iconHTML(icon, { class: contentName.dasherize() });
},
@@ -30,7 +30,7 @@ export default DropdownSelectBoxRoxComponent.extend({
return Handlebars.escapeExpression(I18n.t(`${_start}.title`));
},
- @computed("i18nPrefix", "i18nPostfix", "content.name")
+ @computed("i18nPrefix", "i18nPostfix", "computedContent.name")
_start(prefix, postfix, contentName) {
return `${prefix}.${contentName}${postfix}`;
},
diff --git a/app/assets/javascripts/select-box-kit/components/pinned-button.js.es6 b/app/assets/javascripts/select-kit/components/pinned-button.js.es6
similarity index 71%
rename from app/assets/javascripts/select-box-kit/components/pinned-button.js.es6
rename to app/assets/javascripts/select-kit/components/pinned-button.js.es6
index c36d53c2369..079274a2a8a 100644
--- a/app/assets/javascripts/select-box-kit/components/pinned-button.js.es6
+++ b/app/assets/javascripts/select-kit/components/pinned-button.js.es6
@@ -1,12 +1,13 @@
import computed from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({
+ pluginApiIdentifiers: ["pinned-button"],
descriptionKey: "help",
classNames: "pinned-button",
classNameBindings: ["isHidden"],
- layoutName: "select-box-kit/templates/components/pinned-button",
+ layoutName: "select-kit/templates/components/pinned-button",
- @computed("topic.pinned_globally", "topic.pinned")
+ @computed("topic.pinned_globally", "pinned")
reasonText(pinnedGlobally, pinned) {
const globally = pinnedGlobally ? "_globally" : "";
const pinnedKey = pinned ? `pinned${globally}` : "unpinned";
@@ -14,7 +15,7 @@ export default Ember.Component.extend({
return I18n.t(key);
},
- @computed("topic.pinned", "topic.deleted", "topic.unpinned")
+ @computed("pinned", "topic.deleted", "topic.unpinned")
isHidden(pinned, deleted, unpinned) {
return deleted || (!pinned && !unpinned);
}
diff --git a/app/assets/javascripts/select-kit/components/pinned-options.js.es6 b/app/assets/javascripts/select-kit/components/pinned-options.js.es6
new file mode 100644
index 00000000000..ebf51344327
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/pinned-options.js.es6
@@ -0,0 +1,55 @@
+import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
+import { on } from "ember-addons/ember-computed-decorators";
+import { iconHTML } from 'discourse-common/lib/icon-library';
+
+export default DropdownSelectBoxComponent.extend({
+ pluginApiIdentifiers: ["pinned-options"],
+ classNames: "pinned-options",
+ allowInitialValueMutation: false,
+
+ autoHighlight() {},
+
+ computeHeaderContent() {
+ let content = this.baseHeaderComputedContent();
+ const pinnedGlobally = this.get("topic.pinned_globally");
+ const pinned = this.get("computedValue");
+ const globally = pinnedGlobally ? "_globally" : "";
+ const state = pinned ? `pinned${globally}` : "unpinned";
+ const title = I18n.t(`topic_statuses.${state}.title`);
+
+ content.name = `${title}${iconHTML("caret-down")}`.htmlSafe();
+ content.dataName = title;
+ content.icon = `thumb-tack ${state === "unpinned" ? "unpinned" : null}`;
+ return content;
+ },
+
+ @on("init")
+ _setContent() {
+ const globally = this.get("topic.pinned_globally") ? "_globally" : "";
+
+ this.set("content", [
+ {
+ id: "pinned",
+ name: I18n.t("topic_statuses.pinned" + globally + ".title"),
+ description: I18n.t('topic_statuses.pinned' + globally + '.help'),
+ icon: "thumb-tack"
+ },
+ {
+ id: "unpinned",
+ name: I18n.t("topic_statuses.unpinned.title"),
+ icon: "thumb-tack unpinned",
+ description: I18n.t('topic_statuses.unpinned.help'),
+ }
+ ]);
+ },
+
+ mutateValue(value) {
+ const topic = this.get("topic");
+
+ if (value === "unpinned") {
+ topic.clearPin();
+ } else {
+ topic.rePin();
+ }
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/search-advanced-category-chooser.js.es6 b/app/assets/javascripts/select-kit/components/search-advanced-category-chooser.js.es6
new file mode 100644
index 00000000000..6ab1319d416
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/search-advanced-category-chooser.js.es6
@@ -0,0 +1,20 @@
+import CategoryChooserComponent from "select-kit/components/category-chooser";
+import Category from "discourse/models/category";
+
+export default CategoryChooserComponent.extend({
+ pluginApiIdentifiers: ["advanced-search-category-chooser"],
+ rootNone: true,
+ rootNoneLabel: "category.all",
+ allowUncategorized: true,
+ clearable: true,
+
+ mutateValue(value) {
+ if (value) {
+ this.set("value", Category.findById(value));
+ } else {
+ this.set("value", null);
+ }
+ },
+
+ computeValue(category) { if (category) return category.id; }
+});
diff --git a/app/assets/javascripts/select-kit/components/select-kit.js.es6 b/app/assets/javascripts/select-kit/components/select-kit.js.es6
new file mode 100644
index 00000000000..29b418540da
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/select-kit.js.es6
@@ -0,0 +1,239 @@
+const { isNone, run, makeArray } = Ember;
+import computed from "ember-addons/ember-computed-decorators";
+import UtilsMixin from "select-kit/mixins/utils";
+import DomHelpersMixin from "select-kit/mixins/dom-helpers";
+import EventsMixin from "select-kit/mixins/events";
+import PluginApiMixin from "select-kit/mixins/plugin-api";
+import { applyContentPluginApiCallbacks } from "select-kit/mixins/plugin-api";
+
+export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixin, EventsMixin, {
+ pluginApiIdentifiers: ["select-kit"],
+ layoutName: "select-kit/templates/components/select-kit",
+ classNames: ["select-kit", "select-box-kit"],
+ classNameBindings: [
+ "isFocused",
+ "isExpanded",
+ "isDisabled",
+ "isHidden",
+ "isAbove",
+ "isBelow",
+ "isLeftAligned",
+ "isRightAligned"
+ ],
+ isDisabled: false,
+ isExpanded: false,
+ isFocused: false,
+ isHidden: false,
+ renderedBodyOnce: false,
+ renderedFilterOnce: false,
+ tabindex: 0,
+ scrollableParentSelector: ".modal-body",
+ none: null,
+ highlightedValue: null,
+ noContentLabel: "select_kit.no_content",
+ valueAttribute: "id",
+ nameProperty: "name",
+ autoFilterable: false,
+ filterable: false,
+ filter: "",
+ filterPlaceholder: "select_kit.filter_placeholder",
+ filterIcon: "search",
+ headerIcon: null,
+ rowComponent: "select-kit/select-kit-row",
+ rowComponentOptions: null,
+ noneRowComponent: "select-kit/select-kit-none-row",
+ createRowComponent: "select-kit/select-kit-create-row",
+ filterComponent: "select-kit/select-kit-filter",
+ headerComponent: "select-kit/select-kit-header",
+ headerComponentOptions: null,
+ headerComputedContent: null,
+ collectionComponent: "select-kit/select-kit-collection",
+ collectionHeight: 200,
+ verticalOffset: 0,
+ horizontalOffset: 0,
+ fullWidthOnMobile: false,
+ castInteger: false,
+ allowAny: false,
+ allowInitialValueMutation: false,
+ content: null,
+ computedContent: null,
+ limitMatches: 100,
+
+ init() {
+ this._super();
+
+ this.noneValue = "__none__";
+ this._previousScrollParentOverflow = "auto";
+ this._previousCSSContext = {};
+ this.set("headerComponentOptions", Ember.Object.create());
+ this.set("rowComponentOptions", Ember.Object.create());
+ this.set("computedContent", []);
+
+ if ($(window).outerWidth(false) <= 420) {
+ this.setProperties({ filterable: false, autoFilterable: false });
+ }
+ },
+
+ willComputeAttributes() {},
+ didComputeAttributes() {},
+
+ _beforeWillComputeContent(content) { return makeArray(content); },
+ willComputeContent(content) { return content; },
+ computeContent(content) { return content; },
+ _beforeDidComputeContent(content) {
+ content = applyContentPluginApiCallbacks(this.get("pluginApiIdentifiers"), content);
+
+ const existingCreatedComputedContent = this.get("computedContent").filterBy("created", true);
+ this.setProperties({
+ computedContent: content.map(c => this.computeContentItem(c)).concat(existingCreatedComputedContent)
+ });
+ return content;
+ },
+ didComputeContent() {},
+
+ mutateAttributes() {
+ run.next(() => {
+ this.mutateContent(this.get("computedContent"));
+ this.mutateValue(this.get("computedValue"));
+ this.set("headerComputedContent", this.computeHeaderContent());
+ });
+ },
+ mutateContent() {},
+ mutateValue(computedValue) { this.set("value", computedValue); },
+
+ computeHeaderContent() {
+ return this.baseHeaderComputedContent();
+ },
+
+ computeContentItem(contentItem, options) {
+ return this.baseComputedContentItem(contentItem, options);
+ },
+
+ baseComputedContentItem(contentItem, options) {
+ let originalContent;
+ options = options || {};
+ const name = options.name;
+
+ if (typeof contentItem === "string" || typeof contentItem === "number") {
+ originalContent = {};
+ originalContent[this.get("valueAttribute")] = contentItem;
+ originalContent[this.get("nameProperty")] = name || contentItem;
+ } else {
+ originalContent = contentItem;
+ }
+
+ return {
+ value: this._castInteger(this.valueForContentItem(contentItem)),
+ name: name || this._nameForContent(contentItem),
+ locked: false,
+ created: options.created || false,
+ originalContent
+ };
+ },
+
+ @computed("shouldFilter", "allowAny", "filter")
+ shouldDisplayFilter(shouldFilter, allowAny, filter) {
+ if (shouldFilter === true) return true;
+ if (allowAny === true && filter.length > 0) return true;
+ return false;
+ },
+
+ @computed("filter", "filteredComputedContent.[]")
+ shouldDisplayNoContentRow(filter, filteredComputedContent) {
+ return filter.length > 0 && filteredComputedContent.length === 0;
+ },
+
+ @computed("filter", "filterable", "autoFilterable", "renderedFilterOnce")
+ shouldFilter(filter, filterable, autoFilterable, renderedFilterOnce) {
+ if (renderedFilterOnce === true && filterable === true) return true;
+ if (filterable === true) return true;
+ if (autoFilterable === true && filter.length > 0) return true;
+ return false;
+ },
+
+ @computed("filter", "computedContent")
+ shouldDisplayCreateRow(filter, computedContent) {
+ if (computedContent.map(c => c.value).includes(filter)) return false;
+ if (this.get("allowAny") === true && filter.length > 0) return true;
+ return false;
+ },
+
+ @computed("filter", "shouldDisplayCreateRow")
+ createRowComputedContent(filter, shouldDisplayCreateRow) {
+ if (shouldDisplayCreateRow === true) {
+ let content = this.createContentFromInput(filter);
+ return this.computeContentItem(content, { created: true });
+ }
+ },
+
+ @computed
+ templateForRow() { return () => null; },
+
+ @computed
+ templateForNoneRow() { return () => null; },
+
+ @computed("filter")
+ templateForCreateRow() {
+ return (rowComponent) => {
+ return I18n.t("select_box.create", {
+ content: rowComponent.get("computedContent.name")
+ });
+ };
+ },
+
+ @computed("none")
+ noneRowComputedContent(none) {
+ if (isNone(none)) { return null; }
+
+ switch (typeof none) {
+ case "string":
+ return this.computeContentItem(this.noneValue, { name: I18n.t(none) });
+ default:
+ return this.computeContentItem(none);
+ }
+ },
+
+ createContentFromInput(input) { return input; },
+
+ willSelect() {
+ this.clearFilter();
+ this.set("highlightedValue", null);
+ },
+ didSelect() {
+ this.collapse();
+ this.focus();
+ },
+
+ willDeselect() {
+ this.clearFilter();
+ this.set("highlightedValue", null);
+ },
+ didDeselect() {
+ this.collapse();
+ this.focus();
+ },
+
+ clearFilter() {
+ this.$filterInput().val("");
+ this.setProperties({ filter: "" });
+ },
+
+ actions: {
+ onToggle() {
+ this.get("isExpanded") === true ? this.collapse() : this.expand();
+ },
+
+ onHighlight(rowComputedContent) {
+ this.set("highlightedValue", rowComputedContent.value);
+ },
+
+ onFilter(filter) {
+ this.setProperties({
+ highlightedValue: null,
+ renderedFilterOnce: true,
+ filter
+ });
+ this.autoHighlight();
+ }
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/select-kit/select-kit-collection.js.es6 b/app/assets/javascripts/select-kit/components/select-kit/select-kit-collection.js.es6
new file mode 100644
index 00000000000..67508609d2a
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/select-kit/select-kit-collection.js.es6
@@ -0,0 +1,5 @@
+export default Ember.Component.extend({
+ layoutName: "select-kit/templates/components/select-kit/select-kit-collection",
+ classNames: ["select-kit-collection", "select-box-kit-collection"],
+ tagName: "ul"
+});
diff --git a/app/assets/javascripts/select-kit/components/select-kit/select-kit-create-row.js.es6 b/app/assets/javascripts/select-kit/components/select-kit/select-kit-create-row.js.es6
new file mode 100644
index 00000000000..390408349b9
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/select-kit/select-kit-create-row.js.es6
@@ -0,0 +1,10 @@
+import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
+
+export default SelectKitRowComponent.extend({
+ layoutName: "select-kit/templates/components/select-kit/select-kit-row",
+ classNames: "create",
+
+ click() {
+ this.sendAction("onCreate", this.get("computedContent"));
+ },
+});
diff --git a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-filter.js.es6 b/app/assets/javascripts/select-kit/components/select-kit/select-kit-filter.js.es6
similarity index 51%
rename from app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-filter.js.es6
rename to app/assets/javascripts/select-kit/components/select-kit/select-kit-filter.js.es6
index aafaa5e1363..f60a627de85 100644
--- a/app/assets/javascripts/select-box-kit/components/select-box-kit/select-box-kit-filter.js.es6
+++ b/app/assets/javascripts/select-kit/components/select-kit/select-kit-filter.js.es6
@@ -1,6 +1,6 @@
export default Ember.Component.extend({
- layoutName: "select-box-kit/templates/components/select-box-kit/select-box-kit-filter",
- classNames: "select-box-kit-filter",
+ layoutName: "select-kit/templates/components/select-kit/select-kit-filter",
+ classNames: ["select-kit-filter", "select-box-kit-filter"],
classNameBindings: ["isFocused", "isHidden"],
isHidden: Ember.computed.not("shouldDisplayFilter")
});
diff --git a/app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6 b/app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6
new file mode 100644
index 00000000000..30863d179c4
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/select-kit/select-kit-header.js.es6
@@ -0,0 +1,35 @@
+import computed from 'ember-addons/ember-computed-decorators';
+
+export default Ember.Component.extend({
+ layoutName: "select-kit/templates/components/select-kit/select-kit-header",
+ classNames: ["select-kit-header", "select-box-kit-header"],
+ classNameBindings: ["isFocused"],
+ attributeBindings: [
+ "dataName:data-name",
+ "tabindex",
+ "ariaLabel:aria-label",
+ "ariaHasPopup:aria-haspopup",
+ "title"
+ ],
+
+ ariaHasPopup: true,
+
+ ariaLabel: Ember.computed.alias("title"),
+
+ name: Ember.computed.alias("computedContent.name"),
+
+ @computed("computedContent.icon", "computedContent.icons")
+ icons(icon, icons) {
+ return Ember.makeArray(icon).concat(icons).filter(i => !Ember.isEmpty(i));
+ },
+
+ @computed("computedContent.dataName", "name")
+ dataName(dataName, name) { return dataName || name; },
+
+ @computed("computedContent.title", "name")
+ title(title, name) { return title || name; },
+
+ click() {
+ this.sendAction("onToggle");
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/select-kit/select-kit-none-row.js.es6 b/app/assets/javascripts/select-kit/components/select-kit/select-kit-none-row.js.es6
new file mode 100644
index 00000000000..542b9472c41
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/select-kit/select-kit-none-row.js.es6
@@ -0,0 +1,10 @@
+import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
+
+export default SelectKitRowComponent.extend({
+ layoutName: "select-kit/templates/components/select-kit/select-kit-row",
+ classNames: "none",
+
+ click() {
+ this.sendAction("onClear");
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/select-kit/select-kit-row.js.es6 b/app/assets/javascripts/select-kit/components/select-kit/select-kit-row.js.es6
new file mode 100644
index 00000000000..f9c46b0a1e9
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/select-kit/select-kit-row.js.es6
@@ -0,0 +1,58 @@
+import { on } from 'ember-addons/ember-computed-decorators';
+import computed from 'ember-addons/ember-computed-decorators';
+const { run, isPresent, makeArray, isEmpty } = Ember;
+import UtilsMixin from "select-kit/mixins/utils";
+
+export default Ember.Component.extend(UtilsMixin, {
+ layoutName: "select-kit/templates/components/select-kit/select-kit-row",
+ classNames: ["select-kit-row", "select-box-kit-row"],
+ tagName: "li",
+ tabIndex: -1,
+ attributeBindings: [
+ "tabIndex",
+ "title",
+ "computedContent.value:data-value",
+ "computedContent.name:data-name"
+ ],
+ classNameBindings: ["isHighlighted", "isSelected"],
+
+ @computed("computedContent.title", "computedContent.name")
+ title(title, name) { return title || name; },
+
+ @computed("templateForRow")
+ template(templateForRow) { return templateForRow(this); },
+
+ @on("didReceiveAttrs")
+ _setSelectionState() {
+ const contentValue = this.get("computedContent.value");
+
+ this.set("isSelected", this.get("computedValue") === contentValue);
+ this.set("isHighlighted", this.get("highlightedValue") === contentValue);
+ },
+
+ @on("willDestroyElement")
+ _clearDebounce() {
+ const hoverDebounce = this.get("hoverDebounce");
+ if (isPresent(hoverDebounce)) { run.cancel(hoverDebounce); }
+ },
+
+ @computed("computedContent.icon", "computedContent.icons", "computedContent.originalContent.icon")
+ icons(icon, icons, originalIcon) {
+ return makeArray(icon)
+ .concat(icons)
+ .concat(makeArray(originalIcon))
+ .filter(i => !isEmpty(i));
+ },
+
+ mouseEnter() {
+ this.set("hoverDebounce", run.debounce(this, this._sendOnHighlightAction, 32));
+ },
+
+ click() {
+ this.sendAction("onSelect", this.get("computedContent"));
+ },
+
+ _sendOnHighlightAction() {
+ this.sendAction("onHighlight", this.get("computedContent"));
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/single-select.js.es6 b/app/assets/javascripts/select-kit/components/single-select.js.es6
new file mode 100644
index 00000000000..a363b1d67e3
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/single-select.js.es6
@@ -0,0 +1,168 @@
+import SelectKitComponent from "select-kit/components/select-kit";
+import { on } from "ember-addons/ember-computed-decorators";
+import computed from "ember-addons/ember-computed-decorators";
+const { get, isNone, isEmpty, isPresent } = Ember;
+
+export default SelectKitComponent.extend({
+ pluginApiIdentifiers: ["single-select"],
+ classNames: "single-select",
+ computedValue: null,
+ value: null,
+ allowInitialValueMutation: true,
+
+ init() {
+ this._super();
+
+ if (this.get("allowInitialValueMutation") === true) {
+ const none = isNone(this.get("none"));
+ const emptyValue = isEmpty(this.get("value"));
+ if (none && emptyValue) {
+ if (!isEmpty(this.get("content"))) {
+ const value = this.valueForContentItem(this.get("content.firstObject"));
+ Ember.run.next(() => this.mutateValue(value));
+ }
+ }
+ }
+ },
+
+ @on("didReceiveAttrs")
+ _compute() {
+ Ember.run.scheduleOnce("afterRender", () => {
+ this.willComputeAttributes();
+ let content = this._beforeWillComputeContent(this.get("content"));
+ content = this.willComputeContent(content);
+ let value = this._beforeWillComputeValue(this.get("value"));
+ content = this.computeContent(content);
+ content = this._beforeDidComputeContent(content);
+ value = this.willComputeValue(value);
+ value = this.computeValue(value);
+ value = this._beforeDidComputeValue(value);
+ this.didComputeContent(content);
+ this.didComputeValue(value);
+ this.set("headerComputedContent", this.computeHeaderContent());
+ this.didComputeAttributes();
+ });
+ },
+
+ _beforeWillComputeValue(value) {
+ switch (typeof value) {
+ case "string":
+ case "number":
+ return this._castInteger(value === "" ? null : value);
+ default:
+ return value;
+ }
+ },
+ willComputeValue(value) { return value; },
+ computeValue(value) { return value; },
+ _beforeDidComputeValue(value) {
+ if (!isEmpty(this.get("content")) && isNone(value) && isNone(this.get("none"))) {
+ value = this.valueForContentItem(get(this.get("content"), "firstObject"));
+ }
+
+ this.setProperties({ computedValue: value });
+ return value;
+ },
+ didComputeValue(value) { return value; },
+
+ filterComputedContent(computedContent, computedValue, filter) {
+ const lowerFilter = filter.toLowerCase();
+ return computedContent.filter(c => {
+ return get(c, "name").toLowerCase().indexOf(lowerFilter) > -1;
+ });
+ },
+
+ baseHeaderComputedContent() {
+ return {
+ icons: Ember.makeArray(this.getWithDefault("headerIcon", [])),
+ name: this.get("selectedComputedContent.name") || this.get("noneRowComputedContent.name")
+ };
+ },
+
+ @computed("computedContent.[]", "computedValue", "filter", "shouldFilter")
+ filteredComputedContent(computedContent, computedValue, filter, shouldFilter) {
+ if (shouldFilter === true) {
+ computedContent = this.filterComputedContent(computedContent, computedValue, filter);
+ }
+
+ return computedContent.slice(0, this.get("limitMatches"));
+ },
+
+ @computed("computedValue", "computedContent.[]")
+ selectedComputedContent(computedValue, computedContent) {
+ if (isNone(computedValue) || isNone(computedContent)) { return null; }
+ return computedContent.findBy("value", computedValue);
+ },
+
+ @computed("selectedComputedContent")
+ hasSelection(selectedComputedContent) {
+ return selectedComputedContent !== this.get("noneRowComputedContent") &&
+ !Ember.isNone(selectedComputedContent);
+ },
+
+ @computed("filter", "computedValue")
+ shouldDisplayCreateRow(filter, computedValue) {
+ return this._super() && computedValue !== filter;
+ },
+
+ autoHighlight() {
+ Ember.run.schedule("afterRender", () => {
+ if (!isNone(this.get("highlightedValue"))) { return; }
+
+ const filteredComputedContent = this.get("filteredComputedContent");
+ const displayCreateRow = this.get("shouldDisplayCreateRow");
+ const none = this.get("noneRowComputedContent");
+
+ if (this.get("hasSelection") && isEmpty(this.get("filter"))) {
+ this.send("onHighlight", this.get("selectedComputedContent"));
+ return;
+ }
+
+ if (isNone(this.get("highlightedValue")) && !isEmpty(filteredComputedContent)) {
+ this.send("onHighlight", get(filteredComputedContent, "firstObject"));
+ return;
+ }
+
+ if (displayCreateRow === true && isEmpty(filteredComputedContent)) {
+ this.send("onHighlight", this.get("createRowComputedContent"));
+ }
+ else if (!isEmpty(filteredComputedContent)) {
+ this.send("onHighlight", get(filteredComputedContent, "firstObject"));
+ }
+ else if (isEmpty(filteredComputedContent) && isPresent(none) && displayCreateRow === false) {
+ this.send("onHighlight", none);
+ }
+ });
+ },
+
+ validateComputedContentItem(computedContentItem) {
+ return this.get("computedValue") !== computedContentItem.value;
+ },
+
+ actions: {
+ onClear() {
+ this.send("onDeselect", this.get("selectedComputedContent"));
+ },
+
+ onCreate(computedContentItem) {
+ if (this.validateComputedContentItem(computedContentItem)) {
+ this.get("computedContent").pushObject(computedContentItem);
+ this.send("onSelect", computedContentItem);
+ }
+ },
+
+ onSelect(rowComputedContentItem) {
+ this.willSelect(rowComputedContentItem);
+ this.set("computedValue", rowComputedContentItem.value);
+ this.mutateAttributes();
+ Ember.run.schedule("afterRender", () => this.didSelect(rowComputedContentItem));
+ },
+
+ onDeselect(rowComputedContentItem) {
+ this.willDeselect(rowComputedContentItem);
+ this.set("computedValue", null);
+ this.mutateAttributes();
+ Ember.run.schedule("afterRender", () => this.didDeselect(rowComputedContentItem));
+ }
+ }
+});
diff --git a/app/assets/javascripts/select-kit/components/tag-notifications-button.js.es6 b/app/assets/javascripts/select-kit/components/tag-notifications-button.js.es6
new file mode 100644
index 00000000000..7208f8c81ab
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/tag-notifications-button.js.es6
@@ -0,0 +1,23 @@
+import NotificationOptionsComponent from "select-kit/components/notifications-button";
+import computed from "ember-addons/ember-computed-decorators";
+
+export default NotificationOptionsComponent.extend({
+ pluginApiIdentifiers: ["tag-notifications-button"],
+ classNames: "tag-notifications-button",
+ i18nPrefix: "tagging.notifications",
+ showFullTitle: false,
+ allowInitialValueMutation: false,
+
+ mutateValue(value) {
+ this.sendAction("action", value);
+ },
+
+ computeValue() {
+ return this.get("notificationLevel");
+ },
+
+ @computed("iconForSelectedDetails")
+ headerIcon(iconForSelectedDetails) {
+ return [iconForSelectedDetails, "caret-down"];
+ }
+});
diff --git a/app/assets/javascripts/select-box-kit/components/topic-footer-mobile-dropdown.js.es6 b/app/assets/javascripts/select-kit/components/topic-footer-mobile-dropdown.js.es6
similarity index 68%
rename from app/assets/javascripts/select-box-kit/components/topic-footer-mobile-dropdown.js.es6
rename to app/assets/javascripts/select-kit/components/topic-footer-mobile-dropdown.js.es6
index 2222fbc8221..ccdf3af4890 100644
--- a/app/assets/javascripts/select-box-kit/components/topic-footer-mobile-dropdown.js.es6
+++ b/app/assets/javascripts/select-kit/components/topic-footer-mobile-dropdown.js.es6
@@ -1,24 +1,21 @@
-import computed from "ember-addons/ember-computed-decorators";
-import ComboBoxComponent from "select-box-kit/components/combo-box";
-import { on } from "ember-addons/ember-computed-decorators";
+import ComboBoxComponent from "select-kit/components/combo-box";
export default ComboBoxComponent.extend({
- headerText: "topic.controls",
+ pluginApiIdentifiers: ["topic-footer-mobile-dropdown"],
classNames: "topic-footer-mobile-dropdown",
filterable: false,
autoFilterable: false,
- allowValueMutation: false,
- autoSelectFirst: false,
+ allowInitialValueMutation: false,
- @on("didReceiveAttrs")
- _setTopicFooterMobileDropdownOptions() {
- this.get("headerComponentOptions")
- .set("selectedName", I18n.t(this.get("headerText")));
+ computeHeaderContent() {
+ let content = this.baseHeaderComputedContent();
+ content.name = I18n.t("topic.controls");
+ return content;
},
- @computed("topic", "topic.details", "value")
- content(topic, details) {
- const content = [];
+ computeContent(content) {
+ const topic = this.get("topic");
+ const details = topic.get("details");
if (details.get("can_invite_to")) {
content.push({ id: "invite", icon: "users", name: I18n.t("topic.invite_reply.title") });
@@ -39,16 +36,15 @@ export default ComboBoxComponent.extend({
return content;
},
- selectValueFunction(value) {
+ autoHighlight() {},
+
+ mutateValue(value) {
const topic = this.get("topic");
- // In case it"s not a valid topic
if (!topic.get("id")) {
return;
}
- this.set("value", value);
-
const refresh = () => this.send("onDeselect", value);
switch(value) {
diff --git a/app/assets/javascripts/select-box-kit/components/topic-notifications-button.js.es6 b/app/assets/javascripts/select-kit/components/topic-notifications-button.js.es6
similarity index 62%
rename from app/assets/javascripts/select-box-kit/components/topic-notifications-button.js.es6
rename to app/assets/javascripts/select-kit/components/topic-notifications-button.js.es6
index 3aeb9a9d980..741b89106f2 100644
--- a/app/assets/javascripts/select-box-kit/components/topic-notifications-button.js.es6
+++ b/app/assets/javascripts/select-kit/components/topic-notifications-button.js.es6
@@ -1,5 +1,5 @@
export default Ember.Component.extend({
- layoutName: "select-box-kit/templates/components/topic-notifications-button",
+ layoutName: "select-kit/templates/components/topic-notifications-button",
classNames: "topic-notifications-button",
showFullTitle: true,
appendReason: true
diff --git a/app/assets/javascripts/select-box-kit/components/topic-notifications-options.js.es6 b/app/assets/javascripts/select-kit/components/topic-notifications-options.js.es6
similarity index 79%
rename from app/assets/javascripts/select-box-kit/components/topic-notifications-options.js.es6
rename to app/assets/javascripts/select-kit/components/topic-notifications-options.js.es6
index 34f63f4ea5a..4feb3b003f1 100644
--- a/app/assets/javascripts/select-box-kit/components/topic-notifications-options.js.es6
+++ b/app/assets/javascripts/select-kit/components/topic-notifications-options.js.es6
@@ -1,12 +1,13 @@
-import NotificationOptionsComponent from "select-box-kit/components/notifications-button";
+import NotificationOptionsComponent from "select-kit/components/notifications-button";
import { on } from "ember-addons/ember-computed-decorators";
import { topicLevels } from "discourse/lib/notification-levels";
export default NotificationOptionsComponent.extend({
+ pluginApiIdentifiers: ["topic-notifications-options"],
classNames: "topic-notifications-options",
content: topicLevels,
i18nPrefix: "topic.notifications",
- value: Ember.computed.alias("topic.details.notification_level"),
+ allowInitialValueMutation: false,
@on("didInsertElement")
_bindGlobalLevelChanged() {
@@ -24,11 +25,9 @@ export default NotificationOptionsComponent.extend({
this.appEvents.off("topic-notifications-button:changed");
},
- selectValueFunction(value) {
+ mutateValue(value) {
if (value !== this.get("value")) {
this.get("topic.details").updateNotifications(value);
}
-
- this.set("value", value);
}
});
diff --git a/app/assets/javascripts/select-box-kit/mixins/dom-helpers.js.es6 b/app/assets/javascripts/select-kit/mixins/dom-helpers.js.es6
similarity index 71%
rename from app/assets/javascripts/select-box-kit/mixins/dom-helpers.js.es6
rename to app/assets/javascripts/select-kit/mixins/dom-helpers.js.es6
index a363c546e0c..2a5afbd3e33 100644
--- a/app/assets/javascripts/select-box-kit/mixins/dom-helpers.js.es6
+++ b/app/assets/javascripts/select-kit/mixins/dom-helpers.js.es6
@@ -4,13 +4,12 @@ export default Ember.Mixin.create({
init() {
this._super();
- this.offscreenInputSelector = ".select-box-kit-offscreen";
- this.filterInputSelector = ".select-box-kit-filter-input";
- this.rowSelector = ".select-box-kit-row";
- this.collectionSelector = ".select-box-kit-collection";
- this.headerSelector = ".select-box-kit-header";
- this.bodySelector = ".select-box-kit-body";
- this.wrapperSelector = ".select-box-kit-wrapper";
+ this.filterInputSelector = ".filter-input";
+ this.rowSelector = ".select-kit-row";
+ this.collectionSelector = ".select-kit-collection";
+ this.headerSelector = ".select-kit-header";
+ this.bodySelector = ".select-kit-body";
+ this.wrapperSelector = ".select-kit-wrapper";
},
$findRowByValue(value) { return this.$(`${this.rowSelector}[data-value='${value}']`); },
@@ -34,45 +33,50 @@ export default Ember.Mixin.create({
$selectedRow() { return this.$rows().filter(".is-selected"); },
- $offscreenInput() { return this.$(this.offscreenInputSelector); },
-
$filterInput() { return this.$(this.filterInputSelector); },
@on("didRender")
_ajustPosition() {
- $(`.select-box-kit-fixed-placeholder-${this.elementId}`).remove();
+ $(`.select-kit-fixed-placeholder-${this.elementId}`).remove();
this.$collection().css("max-height", this.get("collectionHeight"));
this._applyFixedPosition();
this._applyDirection();
this._positionWrapper();
},
+ @on("didInsertElement")
+ _setupResizeListener() {
+ $(window).on("resize.select-kit", () => this.collapse() );
+ },
+
@on("willDestroyElement")
_clearState() {
- $(window).off("resize.select-box-kit");
- $(`.select-box-kit-fixed-placeholder-${this.elementId}`).remove();
+ $(window).off("resize.select-kit");
+ $(`.select-kit-fixed-placeholder-${this.elementId}`).remove();
},
// make sure we don’t propagate a click outside component
// to avoid closing a modal containing the component for example
- click(event) { this._killEvent(event); },
+ click(event) {
+ this._destroyEvent(event);
+ },
// use to collapse and remove focus
- close() {
- this.collapse();
+ close(event) {
+ this.collapse(event);
this.setProperties({ isFocused: false });
},
// force the component in a known default state
focus() {
- Ember.run.schedule("afterRender", () => this.$offscreenInput().select() );
+ Ember.run.schedule("afterRender", () => this.$header().focus() );
},
- expand() {
- if (this.get("isExpanded") === true) { return; }
+ expand(event) {
+ if (this.get("isExpanded") === true) return;
this.setProperties({ isExpanded: true, renderedBodyOnce: true, isFocused: true });
- this.focus();
- this.autoHighlightFunction();
+ this.focus(event);
+ this.autoHighlight();
},
collapse() {
@@ -80,35 +84,18 @@ export default Ember.Mixin.create({
Ember.run.schedule("afterRender", () => this._removeFixedPosition() );
},
- // make sure we close/unfocus the component when clicked outside
- clickOutside(event) {
- if ($(event.target).parents(".select-box-kit").length === 1) {
- this.close();
- return false;
- }
-
- this.unfocus();
- return;
- },
-
// lose focus of the component in two steps
- // first collapase and keep focus and then remove focus
- unfocus() {
- this.set("highlightedValue", null);
-
+ // first collapse and keep focus and then remove focus
+ unfocus(event) {
if (this.get("isExpanded") === true) {
- this.collapse();
- this.focus();
+ this.collapse(event);
+ this.focus(event);
} else {
- this.close();
+ this.close(event);
}
},
- blur() {
- Ember.run.schedule("afterRender", () => this.$offscreenInput().blur() );
- },
-
- _killEvent(event) {
+ _destroyEvent(event) {
event.preventDefault();
event.stopPropagation();
},
@@ -119,8 +106,8 @@ export default Ember.Mixin.create({
const dHeader = $(".d-header")[0];
const dHeaderBounds = dHeader ? dHeader.getBoundingClientRect() : {top: 0, height: 0};
const dHeaderHeight = dHeaderBounds.top + dHeaderBounds.height;
- const headerHeight = this.$header().outerHeight(false);
- const headerWidth = this.$header().outerWidth(false);
+ const componentHeight = this.$().outerHeight(false);
+ const componentWidth = this.$().outerWidth(false);
const bodyHeight = this.$body().outerHeight(false);
const windowWidth = $(window).width();
const windowHeight = $(window).height();
@@ -145,7 +132,7 @@ export default Ember.Mixin.create({
options.left = bodyWidth + this.get("horizontalOffset");
} else {
this.setProperties({ isLeftAligned: false, isRightAligned: true });
- options.right = - (bodyWidth - headerWidth + this.get("horizontalOffset"));
+ options.right = - (bodyWidth - componentWidth + this.get("horizontalOffset"));
}
} else {
const horizontalSpacing = boundingRect.left;
@@ -160,15 +147,15 @@ export default Ember.Mixin.create({
}
}
- const componentHeight = this.get("verticalOffset") + bodyHeight + headerHeight;
- const hasBelowSpace = windowHeight - offsetBottom - componentHeight > 0;
- const hasAboveSpace = offsetTop - componentHeight - dHeaderHeight > 0;
+ const fullHeight = this.get("verticalOffset") + bodyHeight + componentHeight;
+ const hasBelowSpace = windowHeight - offsetBottom - fullHeight > 0;
+ const hasAboveSpace = offsetTop - fullHeight - dHeaderHeight > 0;
if (hasBelowSpace || (!hasBelowSpace && !hasAboveSpace)) {
this.setProperties({ isBelow: true, isAbove: false });
- options.top = headerHeight + this.get("verticalOffset");
+ options.top = componentHeight + this.get("verticalOffset") - 2;
} else {
this.setProperties({ isBelow: false, isAbove: true });
- options.bottom = headerHeight + this.get("verticalOffset");
+ options.bottom = componentHeight + this.get("verticalOffset") - 1;
}
this.$body().css(options);
@@ -182,7 +169,7 @@ export default Ember.Mixin.create({
const width = this.$().outerWidth(false);
const height = this.$().outerHeight(false);
- const $placeholder = $(`
`);
+ const $placeholder = $(`
`);
this._previousScrollParentOverflow = this._previousScrollParentOverflow || scrollableParent.css("overflow");
scrollableParent.css({ overflow: "hidden" });
@@ -212,7 +199,7 @@ export default Ember.Mixin.create({
},
_removeFixedPosition() {
- $(`.select-box-kit-fixed-placeholder-${this.elementId}`).remove();
+ $(`.select-kit-fixed-placeholder-${this.elementId}`).remove();
if (!this.element || this.isDestroying || this.isDestroyed) { return; }
@@ -236,11 +223,11 @@ export default Ember.Mixin.create({
},
_positionWrapper() {
- const headerHeight = this.$header().outerHeight(false);
+ const componentHeight = this.$().outerHeight(false);
this.$(this.wrapperSelector).css({
- width: this.$().outerWidth(false),
- height: headerHeight + this.$body().outerHeight(false)
+ width: this.$().outerWidth(false) - 2,
+ height: componentHeight + this.$body().outerHeight(false)
});
},
});
diff --git a/app/assets/javascripts/select-kit/mixins/events.js.es6 b/app/assets/javascripts/select-kit/mixins/events.js.es6
new file mode 100644
index 00000000000..a462ed683f9
--- /dev/null
+++ b/app/assets/javascripts/select-kit/mixins/events.js.es6
@@ -0,0 +1,233 @@
+export default Ember.Mixin.create({
+ init() {
+ this._super();
+
+ this.keys = {
+ TAB: 9,
+ ENTER: 13,
+ ESC: 27,
+ UP: 38,
+ DOWN: 40,
+ BACKSPACE: 8,
+ };
+ },
+
+ willDestroyElement() {
+ this._super();
+
+ $(document)
+ .off("mousedown.select-kit")
+ .off("touchstart.select-kit");
+
+ this.$header()
+ .off("focus.select-kit")
+ .off("blur.select-kit")
+ .off("keypress.select-kit")
+ .off("keydown.select-kit");
+
+ this.$filterInput()
+ .off("change.select-kit")
+ .off("keydown.select-kit")
+ .off("focus.select-kit")
+ .off("focusin.select-kit");
+ },
+
+ didInsertElement() {
+ this._super();
+
+ $(document)
+ .on("mousedown.select-kit, touchstart.select-kit", event => {
+ if (Ember.isNone(this.get("element"))) return;
+ if (this.get("element").contains(event.target)) return;
+
+ this.didClickOutside(event);
+ });
+
+ this.$header()
+ .on("blur.select-kit", () => {
+ if (this.get("isExpanded") === false && this.get("isFocused") === true) {
+ this.close();
+ }
+ })
+ .on("focus.select-kit", (event) => {
+ this.set("isFocused", true);
+ this._destroyEvent(event);
+ })
+ .on("keydown.select-kit", (event) => {
+ const keyCode = event.keyCode || event.which;
+
+ if (document.activeElement !== this.$header()[0]) return event;
+
+ if (keyCode === this.keys.TAB) this.tabFromHeader(event);
+ if (keyCode === this.keys.BACKSPACE) this.backspaceFromHeader(event);
+ if (keyCode === this.keys.ESC) this.escapeFromHeader(event);
+ if (keyCode === this.keys.ENTER) this.enterFromHeader(event);
+ if ([this.keys.UP, this.keys.DOWN].includes(keyCode)) this.upAndDownFromHeader(event);
+ return event;
+ })
+ .on("keypress.select-kit", (event) => {
+ const keyCode = event.keyCode || event.which;
+
+ if (keyCode === this.keys.ENTER) { return true; }
+
+ this.expand(event);
+
+ if (this.get("filterable") === true || this.get("autoFilterable")) {
+ this.set("renderedFilterOnce", true);
+ }
+
+ Ember.run.schedule("afterRender", () => {
+ let newVal = this.$filterInput().val();
+
+ const start = this.$filterInput()[0].selectionStart;
+ const end = this.$filterInput()[0].selectionEnd;
+ if (!Ember.isNone(start) && !Ember.isNone(end)) {
+ newVal = newVal.substr(0, start) +
+ String.fromCharCode(keyCode) +
+ newVal.substr(end, newVal.length);
+ } else {
+ newVal = newVal + String.fromCharCode(keyCode);
+ }
+
+ this.$filterInput().focus().val(newVal);
+ });
+
+ return false;
+ });
+
+ this.$filterInput()
+ .on("change.select-kit", (event) => {
+ this.send("onFilter", $(event.target).val());
+ })
+ .on("focus.select-kit focusin.select-kit", (event) => {
+ this.set("isFocused", true);
+ this._destroyEvent(event);
+ })
+ .on("keydown.select-kit", (event) => {
+ const keyCode = event.keyCode || event.which;
+
+ if (keyCode === this.keys.TAB) this.tabFromFilter(event);
+ if (keyCode === this.keys.ESC) this.escapeFromFilter(event);
+ if (keyCode === this.keys.ENTER) this.enterFromFilter(event);
+ if ([this.keys.UP, this.keys.DOWN].includes(keyCode)) this.upAndDownFromFilter(event);
+ });
+ },
+
+ didPressTab(event) {
+ if (this.get("isExpanded") === false) {
+ this.unfocus(event);
+ } else if (this.$highlightedRow().length === 1) {
+ this._destroyEvent(event);
+ Ember.run.throttle(this, this._rowClick, this.$highlightedRow(), 150, 150, true);
+ this.focus(event);
+ } else {
+ this._destroyEvent(event);
+ this.unfocus(event);
+ }
+
+ return true;
+ },
+
+ didPressEscape(event) {
+ this._destroyEvent(event);
+ this.unfocus(event);
+ },
+
+ didPressUpAndDownArrows(event) {
+ this._destroyEvent(event);
+
+ const keyCode = event.keyCode || event.which;
+ const $rows = this.$rows();
+
+ if (this.get("isExpanded") === false) {
+ this.expand(event);
+
+ if (this.$selectedRow().length === 1) {
+ this._highlightRow(this.$selectedRow());
+ return;
+ }
+ }
+
+ if ($rows.length <= 0) { return; }
+ if ($rows.length === 1) {
+ this._rowSelection($rows, 0);
+ return;
+ }
+
+ const direction = keyCode === 38 ? -1 : 1;
+
+ Ember.run.throttle(this, this._moveHighlight, direction, $rows, 32);
+ },
+
+ didPressBackspace(event) {
+ this._destroyEvent(event);
+
+ this.expand(event);
+
+ if (this.$filterInput().is(":visible")) {
+ this.$filterInput().focus().trigger(event).trigger("change");
+ }
+ },
+
+ didPressEnter(event) {
+ this._destroyEvent(event);
+
+ if (this.get("isExpanded") === false) {
+ this.expand(event);
+ } else if (this.$highlightedRow().length === 1) {
+ Ember.run.throttle(this, this._rowClick, this.$highlightedRow(), 150, true);
+ }
+ },
+
+ didClickOutside(event) {
+ if ($(event.target).parents(".select-kit").length === 1) {
+ this.close(event);
+ return false;
+ }
+
+ this.unfocus(event);
+ return;
+ },
+
+ tabFromHeader(event) { this.didPressTab(event); },
+ tabFromFilter(event) { this.didPressTab(event); },
+
+ escapeFromHeader(event) { this.didPressEscape(event); },
+ escapeFromFilter(event) { this.didPressEscape(event); },
+
+ upAndDownFromHeader(event) { this.didPressUpAndDownArrows(event); },
+ upAndDownFromFilter(event) { this.didPressUpAndDownArrows(event); },
+
+ backspaceFromHeader(event) { this.didPressBackspace(event); },
+
+ enterFromHeader(event) { this.didPressEnter(event); },
+ enterFromFilter(event) { this.didPressEnter(event); },
+
+ _moveHighlight(direction, $rows) {
+ const currentIndex = $rows.index(this.$highlightedRow());
+ let nextIndex = currentIndex + direction;
+
+ if (nextIndex < 0) {
+ nextIndex = $rows.length - 1;
+ } else if (nextIndex >= $rows.length) {
+ nextIndex = 0;
+ }
+
+ this._rowSelection($rows, nextIndex);
+ },
+
+ _rowClick($row) { $row.click(); },
+
+ _rowSelection($rows, nextIndex) {
+ const highlightableValue = $rows.eq(nextIndex).attr("data-value");
+ const $highlightableRow = this.$findRowByValue(highlightableValue);
+ this._highlightRow($highlightableRow);
+ },
+
+ _highlightRow($row) {
+ Ember.run.schedule("afterRender", () => {
+ $row.trigger("mouseover").focus();
+ this.focus();
+ });
+ }
+});
diff --git a/app/assets/javascripts/select-kit/mixins/plugin-api.js.es6 b/app/assets/javascripts/select-kit/mixins/plugin-api.js.es6
new file mode 100644
index 00000000000..effe298a02a
--- /dev/null
+++ b/app/assets/javascripts/select-kit/mixins/plugin-api.js.es6
@@ -0,0 +1,71 @@
+let _appendContentCallbacks = {};
+function appendContent(pluginApiIdentifiers, contentFunction) {
+ if (Ember.isNone(_appendContentCallbacks[pluginApiIdentifiers])) {
+ _appendContentCallbacks[pluginApiIdentifiers] = [];
+ }
+
+ _appendContentCallbacks[pluginApiIdentifiers].push(contentFunction);
+}
+
+let _prependContentCallbacks = {};
+function prependContent(pluginApiIdentifiers, contentFunction) {
+ if (Ember.isNone(_prependContentCallbacks[pluginApiIdentifiers])) {
+ _prependContentCallbacks[pluginApiIdentifiers] = [];
+ }
+
+ _prependContentCallbacks[pluginApiIdentifiers].push(contentFunction);
+}
+
+let _modifyContentCallbacks = {};
+function modifyContent(pluginApiIdentifiers, contentFunction) {
+ if (Ember.isNone(_modifyContentCallbacks[pluginApiIdentifiers])) {
+ _modifyContentCallbacks[pluginApiIdentifiers] = [];
+ }
+
+ _modifyContentCallbacks[pluginApiIdentifiers].push(contentFunction);
+}
+
+export function applyContentPluginApiCallbacks(identifiers, content) {
+ identifiers.forEach((key) => {
+ (_prependContentCallbacks[key] || []).forEach((c) => {
+ content = c().concat(content);
+ });
+ (_appendContentCallbacks[key] || []).forEach((c) => {
+ content = content.concat(c());
+ });
+ (_modifyContentCallbacks[key] || []).forEach((c) => {
+ content = c(content);
+ });
+ });
+
+ return content;
+}
+
+export function modifySelectKit(pluginApiIdentifiers) {
+ return {
+ appendContent: (content) => {
+ appendContent(pluginApiIdentifiers, () => {return content;} );
+ return modifySelectKit(pluginApiIdentifiers);
+ },
+ prependContent: (content) => {
+ prependContent(pluginApiIdentifiers, () => {return content;} );
+ return modifySelectKit(pluginApiIdentifiers);
+ },
+ modifyContent: (callback) => {
+ modifyContent(pluginApiIdentifiers, callback);
+ return modifySelectKit(pluginApiIdentifiers);
+ }
+ };
+}
+
+export function clearCallbacks() {
+ _appendContentCallbacks = {};
+ _prependContentCallbacks = {};
+ _modifyContentCallbacks = {};
+}
+
+const EMPTY_ARRAY = Object.freeze([]);
+export default Ember.Mixin.create({
+ concatenatedProperties: ["pluginApiIdentifiers"],
+ pluginApiIdentifiers: EMPTY_ARRAY
+});
diff --git a/app/assets/javascripts/select-box-kit/mixins/utils.js.es6 b/app/assets/javascripts/select-kit/mixins/utils.js.es6
similarity index 52%
rename from app/assets/javascripts/select-box-kit/mixins/utils.js.es6
rename to app/assets/javascripts/select-kit/mixins/utils.js.es6
index 475cf726fcc..b3ca2dbfedf 100644
--- a/app/assets/javascripts/select-box-kit/mixins/utils.js.es6
+++ b/app/assets/javascripts/select-kit/mixins/utils.js.es6
@@ -1,6 +1,16 @@
-const { get, isNone } = Ember;
+const { get, isNone, guidFor } = Ember;
export default Ember.Mixin.create({
+ valueForContentItem(content) {
+ switch (typeof content) {
+ case "string":
+ case "number":
+ return content;
+ default:
+ return get(content, this.get("valueAttribute"));
+ }
+ },
+
_nameForContent(content) {
if (isNone(content)) {
return null;
@@ -25,37 +35,13 @@ export default Ember.Mixin.create({
return value;
},
- _valueForContent(content) {
- switch (typeof content) {
- case "string":
- case "number":
- return content;
- default:
- return get(content, this.get("valueAttribute"));
- }
- },
-
- _contentForValue(value) {
- return this.get("content").find(c => {
- if (this._valueForContent(c) === value) { return true; }
- });
- },
-
- _computedContentForValue(value) {
- const searchedValue = value.toString();
+ _findComputedContentItemByGuid(guid) {
return this.get("computedContent").find(c => {
- if (c.value.toString() === searchedValue) { return true; }
+ return guidFor(c) === guid;
});
},
- _originalValueForValue(value) {
- if (isNone(value)) { return null; }
- if (value === this.noneValue) { return this.noneValue; }
-
- const computedContent = this._computedContentForValue(value);
-
- if (isNone(computedContent)) { return value; }
-
- return get(computedContent.originalContent, this.get("valueAttribute"));
- },
+ _filterRemovableComputedContents(computedContent) {
+ return computedContent.filter(c => c.created === true);
+ }
});
diff --git a/app/assets/javascripts/select-kit/templates/components/category-row.hbs b/app/assets/javascripts/select-kit/templates/components/category-row.hbs
new file mode 100644
index 00000000000..2ba26d02130
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/category-row.hbs
@@ -0,0 +1,19 @@
+{{#if category}}
+ {{#if hasParentCategory}}
+
+ {{badgeForParentCategory}} {{badgeForCategory}}
+ × {{topicCount}}
+
+ {{else}}
+
+ {{badgeForCategory}}
+ × {{topicCount}}
+
+ {{/if}}
+
+ {{#if hasDescription}}
+
{{description}}
+ {{/if}}
+{{else}}
+ {{computedContent.name}}
+{{/if}}
diff --git a/app/assets/javascripts/select-kit/templates/components/combo-box/combo-box-header.hbs b/app/assets/javascripts/select-kit/templates/components/combo-box/combo-box-header.hbs
new file mode 100644
index 00000000000..adc9440ce54
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/combo-box/combo-box-header.hbs
@@ -0,0 +1,13 @@
+{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
+
+
+ {{{name}}}
+
+
+{{#if shouldDisplayClearableButton}}
+
+ {{d-icon 'times'}}
+
+{{/if}}
+
+{{d-icon caretIcon class="caret-icon"}}
diff --git a/app/assets/javascripts/select-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs b/app/assets/javascripts/select-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs
new file mode 100644
index 00000000000..9cc8c31cf60
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/dropdown-select-box/dropdown-select-box-header.hbs
@@ -0,0 +1,7 @@
+{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
+
+{{#if options.showFullTitle}}
+
+ {{name}}
+
+{{/if}}
diff --git a/app/assets/javascripts/select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-row.hbs b/app/assets/javascripts/select-kit/templates/components/dropdown-select-box/dropdown-select-box-row.hbs
similarity index 78%
rename from app/assets/javascripts/select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-row.hbs
rename to app/assets/javascripts/select-kit/templates/components/dropdown-select-box/dropdown-select-box-row.hbs
index 0fe1813c8a6..556551a61f0 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/dropdown-select-box/dropdown-select-box-row.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/dropdown-select-box/dropdown-select-box-row.hbs
@@ -1,10 +1,10 @@
{{#if template}}
{{{template}}}
{{else}}
- {{#if icon}}
+ {{#if icons}}
- {{{icon}}}
+ {{#each icons as |icon|}} {{d-icon icon}} {{/each}}
{{/if}}
diff --git a/app/assets/javascripts/select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-header.hbs b/app/assets/javascripts/select-kit/templates/components/future-date-input-selector/future-date-input-selector-header.hbs
similarity index 51%
rename from app/assets/javascripts/select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-header.hbs
rename to app/assets/javascripts/select-kit/templates/components/future-date-input-selector/future-date-input-selector-header.hbs
index 5e175c5ee7d..4c8904e9a32 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-header.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/future-date-input-selector/future-date-input-selector-header.hbs
@@ -1,21 +1,21 @@
-{{#if icon}}
+{{#if icons}}
- {{{icon}}}
+ {{#each icons as |icon|}} {{d-icon icon}} {{/each}}
{{/if}}
-
- {{{selectedName}}}
+
+ {{{name}}}
-{{#if datetime}}
+{{#if computedContent.datetime}}
- {{datetime}}
+ {{computedContent.datetime}}
{{/if}}
{{#if shouldDisplayClearableButton}}
-
+
{{d-icon 'times'}}
{{/if}}
diff --git a/app/assets/javascripts/select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-row.hbs b/app/assets/javascripts/select-kit/templates/components/future-date-input-selector/future-date-input-selector-row.hbs
similarity index 58%
rename from app/assets/javascripts/select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-row.hbs
rename to app/assets/javascripts/select-kit/templates/components/future-date-input-selector/future-date-input-selector-row.hbs
index dc936cbe690..ce47ece0222 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/future-date-input-selector/future-date-input-selector-row.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/future-date-input-selector/future-date-input-selector-row.hbs
@@ -1,10 +1,10 @@
-{{#if icon}}
+{{#if icons}}
- {{{icon}}}
+ {{#each icons as |icon|}} {{d-icon icon}} {{/each}}
{{/if}}
-{{content.name}}
+{{computedContent.name}}
{{#if datetime}}
diff --git a/app/assets/javascripts/select-kit/templates/components/multi-select/multi-select-header.hbs b/app/assets/javascripts/select-kit/templates/components/multi-select/multi-select-header.hbs
new file mode 100644
index 00000000000..8b141c5b3be
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/multi-select/multi-select-header.hbs
@@ -0,0 +1,13 @@
+
+ {{#each computedContent.selectedComputedContents as |selectedComputedContent|}}
+ {{component selectedNameComponent onDeselect=onDeselect content=selectedComputedContent}}
+ {{/each}}
+
+ {{component "select-kit/select-kit-filter"
+ onFilter=onFilter
+ shouldDisplayFilter=shouldDisplayFilter
+ isFocused=isFocused
+ filter=filter
+ }}
+
+
diff --git a/app/assets/javascripts/select-kit/templates/components/multi-select/selected-category.hbs b/app/assets/javascripts/select-kit/templates/components/multi-select/selected-category.hbs
new file mode 100644
index 00000000000..c220d68cfc3
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/multi-select/selected-category.hbs
@@ -0,0 +1,7 @@
+
+
+ {{d-icon "times"}}
+
+
+ {{badge}}
+
diff --git a/app/assets/javascripts/select-kit/templates/components/multi-select/selected-color.hbs b/app/assets/javascripts/select-kit/templates/components/multi-select/selected-color.hbs
new file mode 100644
index 00000000000..c0d544ab9d5
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/multi-select/selected-color.hbs
@@ -0,0 +1,13 @@
+
+
+ {{#unless isLocked}}
+
+ {{d-icon "times"}}
+
+ {{/unless}}
+
+ #{{content.name}}
+
+
+
+
diff --git a/app/assets/javascripts/select-kit/templates/components/multi-select/selected-name.hbs b/app/assets/javascripts/select-kit/templates/components/multi-select/selected-name.hbs
new file mode 100644
index 00000000000..67c7a1235a9
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/multi-select/selected-name.hbs
@@ -0,0 +1,13 @@
+
+ {{#if isLocked}}
+
+ {{d-icon "lock"}}
+
+ {{else}}
+
+ {{d-icon "times"}}
+
+ {{/if}}
+
+ {{content.name}}
+
diff --git a/app/assets/javascripts/select-box-kit/templates/components/pinned-button.hbs b/app/assets/javascripts/select-kit/templates/components/pinned-button.hbs
similarity index 50%
rename from app/assets/javascripts/select-box-kit/templates/components/pinned-button.hbs
rename to app/assets/javascripts/select-kit/templates/components/pinned-button.hbs
index aaabc2f1bf3..31fc07f1dcb 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/pinned-button.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/pinned-button.hbs
@@ -1,4 +1,4 @@
-{{pinned-options topic=topic}}
+{{pinned-options value=pinned topic=topic}}
{{{reasonText}}}
diff --git a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit.hbs b/app/assets/javascripts/select-kit/templates/components/select-kit.hbs
similarity index 56%
rename from app/assets/javascripts/select-box-kit/templates/components/select-box-kit.hbs
rename to app/assets/javascripts/select-kit/templates/components/select-kit.hbs
index 9c9e7188ad7..d15ba708afa 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/select-kit.hbs
@@ -1,31 +1,19 @@
-
-
{{component headerComponent
- none=computedNone
+ tabindex=tabindex
isFocused=isFocused
isExpanded=isExpanded
- selectedContent=selectedContent
+ computedContent=headerComputedContent
onDeselect=(action "onDeselect")
onToggle=(action "onToggle")
- onFilterChange=(action "onFilterChange")
- onClearSelection=(action "onClearSelection")
- shouldDisplayFilter=shouldDisplayFilter
+ onFilter=(action "onFilter")
+ onClear=(action "onClear")
options=headerComponentOptions
+ shouldDisplayFilter=shouldDisplayFilter
}}
-
+
{{component filterComponent
- onFilterChange=(action "onFilterChange")
+ onFilter=(action "onFilter")
icon=filterIcon
shouldDisplayFilter=shouldDisplayFilter
isFocused=isFocused
@@ -35,26 +23,27 @@
{{#if renderedBodyOnce}}
{{component collectionComponent
- none=computedNone
- createRowContent=createRowContent
- selectedContent=selectedContent
- filteredContent=filteredContent
+ hasSelection=hasSelection
+ noneRowComputedContent=noneRowComputedContent
+ createRowComputedContent=createRowComputedContent
+ filteredComputedContent=filteredComputedContent
rowComponent=rowComponent
noneRowComponent=noneRowComponent
createRowComponent=createRowComponent
templateForRow=templateForRow
templateForNoneRow=templateForNoneRow
templateForCreateRow=templateForCreateRow
- onClearSelection=(action "onClearSelection")
+ onClear=(action "onClear")
onSelect=(action "onSelect")
onHighlight=(action "onHighlight")
- onCreateContent=(action "onCreateContent")
+ onCreate=(action "onCreate")
noContentLabel=noContentLabel
highlightedValue=highlightedValue
computedValue=computedValue
+ shouldDisplayNoContentRow=shouldDisplayNoContentRow
rowComponentOptions=rowComponentOptions
}}
{{/if}}
-
+
diff --git a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-collection.hbs b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-collection.hbs
similarity index 62%
rename from app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-collection.hbs
rename to app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-collection.hbs
index bf7311049cb..824f34f2c1f 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-collection.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-collection.hbs
@@ -1,10 +1,10 @@
-{{#if none}}
- {{#if selectedContent}}
+{{#if hasSelection}}
+ {{#if noneRowComputedContent}}
{{component noneRowComponent
- content=none
+ computedContent=noneRowComputedContent
templateForRow=templateForNoneRow
highlightedValue=highlightedValue
- onClearSelection=onClearSelection
+ onClear=onClear
onHighlight=onHighlight
value=computedValue
options=rowComponentOptions
@@ -12,34 +12,34 @@
{{/if}}
{{/if}}
-{{#if createRowContent}}
+{{#if createRowComputedContent}}
{{component createRowComponent
- content=createRowContent
+ computedContent=createRowComputedContent
templateForRow=templateForCreateRow
- titleForRow=titleForRow
highlightedValue=highlightedValue
onHighlight=onHighlight
- onCreateContent=onCreateContent
+ onCreate=onCreate
value=computedValue
options=rowComponentOptions
}}
{{/if}}
-{{#each filteredContent as |content|}}
+{{#each filteredComputedContent as |computedContent|}}
{{component rowComponent
- content=content
+ computedContent=computedContent
templateForRow=templateForRow
- titleForRow=titleForRow
highlightedValue=highlightedValue
onSelect=onSelect
onHighlight=onHighlight
- value=computedValue
+ computedValue=computedValue
options=rowComponentOptions
}}
-{{else}}
+{{/each}}
+
+{{#if shouldDisplayNoContentRow}}
{{#if noContentLabel}}
-
+
{{i18n noContentLabel}}
{{/if}}
-{{/each}}
+{{/if}}
diff --git a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-filter.hbs b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-filter.hbs
similarity index 77%
rename from app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-filter.hbs
rename to app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-filter.hbs
index dc50d225040..dd62fca94ad 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/select-box-kit/select-box-kit-filter.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-filter.hbs
@@ -1,8 +1,8 @@
{{input
tabindex=-1
- class="select-box-kit-filter-input"
+ class="filter-input"
placeholder=placeholder
- key-up=onFilterChange
+ key-up=onFilter
autocomplete="off"
autocorrect="off"
autocapitalize="off"
diff --git a/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs
new file mode 100644
index 00000000000..abd119afda2
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-header.hbs
@@ -0,0 +1,5 @@
+{{#each icons as |icon|}} {{d-icon icon}} {{/each}}
+
+
+ {{{name}}}
+
diff --git a/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs
new file mode 100644
index 00000000000..80444173f40
--- /dev/null
+++ b/app/assets/javascripts/select-kit/templates/components/select-kit/select-kit-row.hbs
@@ -0,0 +1,6 @@
+{{#if template}}
+ {{{template}}}
+{{else}}
+ {{#each icons as |icon|}} {{d-icon icon}} {{/each}}
+
{{computedContent.name}}
+{{/if}}
diff --git a/app/assets/javascripts/select-box-kit/templates/components/topic-notifications-button.hbs b/app/assets/javascripts/select-kit/templates/components/topic-notifications-button.hbs
similarity index 50%
rename from app/assets/javascripts/select-box-kit/templates/components/topic-notifications-button.hbs
rename to app/assets/javascripts/select-kit/templates/components/topic-notifications-button.hbs
index 17d99530559..2569ea0c865 100644
--- a/app/assets/javascripts/select-box-kit/templates/components/topic-notifications-button.hbs
+++ b/app/assets/javascripts/select-kit/templates/components/topic-notifications-button.hbs
@@ -1,4 +1,7 @@
-{{topic-notifications-options topic=topic showFullTitle=showFullTitle}}
+{{topic-notifications-options
+ value=notificationLevel
+ topic=topic
+ showFullTitle=showFullTitle}}
{{#if appendReason}}
diff --git a/app/assets/javascripts/wizard-application.js b/app/assets/javascripts/wizard-application.js
index 9baf2c224ba..ef619973510 100644
--- a/app/assets/javascripts/wizard-application.js
+++ b/app/assets/javascripts/wizard-application.js
@@ -3,7 +3,7 @@
//= require ./ember-addons/macro-alias
//= require ./ember-addons/ember-computed-decorators
//= require_tree ./discourse-common
-//= require_tree ./select-box-kit
+//= require_tree ./select-kit
//= require wizard/router
//= require wizard/wizard
//= require_tree ./wizard/templates
diff --git a/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6 b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
index 3154e426ab1..97029c5eeb0 100644
--- a/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
+++ b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
@@ -56,7 +56,7 @@ test("Going back and forth in steps", assert => {
assert.ok(!exists('.wizard-step-title'));
assert.ok(!exists('.wizard-step-description'));
- assert.ok(exists('.select-box-kit.field-snack'), "went to the next step");
+ assert.ok(exists('.select-kit.field-snack'), "went to the next step");
assert.ok(exists('.preview-area'), "renders the component field");
assert.ok(!exists('.wizard-btn.next'));
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index b4d00edc0c9..565e4317447 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -6,7 +6,7 @@
@import "vendor/select2";
@import "common/foundation/mixins";
@import "common/foundation/variables";
-@import "common/select-box-kit/*";
+@import "common/select-kit/*";
@import "common/components/*";
@import "common/input_tip";
@import "common/topic-entrance";
diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss
index 8ad76b89218..4b61694769c 100644
--- a/app/assets/stylesheets/common/admin/admin_base.scss
+++ b/app/assets/stylesheets/common/admin/admin_base.scss
@@ -212,10 +212,10 @@ $mobile-breakpoint: 700px;
.admin-container {
margin-top: 20px;
- .select-box-kit {
+ .select-kit {
width: 350px;
}
- .select-box-kit.multi-combo-box {
+ .select-kit.multi-select {
width: 500px;
}
.select-box-kit.dropdown-select-box {
@@ -452,7 +452,7 @@ $mobile-breakpoint: 700px;
width: 100%;
padding-right: 0;
}
- .select-box-kit {
+ .select-kit {
width: 100% !important; // Needs !important to override hard-coded value
@media (max-width: $mobile-breakpoint) {
width: 100% !important; // !important overrides hard-coded mobile width of 68px
@@ -623,7 +623,7 @@ section.details {
margin-left: 0;
}
- .select-box-kit {
+ .select-kit {
width: inherit;
}
}
diff --git a/app/assets/stylesheets/common/admin/flagging.scss b/app/assets/stylesheets/common/admin/flagging.scss
index 0bcdd190b26..debcb8f7864 100644
--- a/app/assets/stylesheets/common/admin/flagging.scss
+++ b/app/assets/stylesheets/common/admin/flagging.scss
@@ -154,9 +154,9 @@
align-items: center;
justify-content: flex-start;
- button, .select-box-kit {
- margin-bottom: 0.5em;
+ button {
margin-right: 0.5em;
+ margin-bottom: 0.5em;
}
}
}
diff --git a/app/assets/stylesheets/common/base/_topic-list.scss b/app/assets/stylesheets/common/base/_topic-list.scss
index bc0164c31bf..9393c7fc822 100644
--- a/app/assets/stylesheets/common/base/_topic-list.scss
+++ b/app/assets/stylesheets/common/base/_topic-list.scss
@@ -8,7 +8,7 @@
}
.list-controls {
- .select-box-kit {
+ .select-kit {
align-self: center;
&.categories-admin-dropdown, &.category-notifications-button, &.tag-notifications-button {
diff --git a/app/assets/stylesheets/common/base/edit-topic-status-update-modal.scss b/app/assets/stylesheets/common/base/edit-topic-status-update-modal.scss
index f535f9a3f77..b16a1f70659 100644
--- a/app/assets/stylesheets/common/base/edit-topic-status-update-modal.scss
+++ b/app/assets/stylesheets/common/base/edit-topic-status-update-modal.scss
@@ -3,7 +3,7 @@
max-height: none;
}
- .select-box-kit {
+ .select-kit {
width: 50%;
}
diff --git a/app/assets/stylesheets/common/base/modal.scss b/app/assets/stylesheets/common/base/modal.scss
index 1183ad70f79..aa00dc21c71 100644
--- a/app/assets/stylesheets/common/base/modal.scss
+++ b/app/assets/stylesheets/common/base/modal.scss
@@ -75,7 +75,7 @@
background-color: $secondary;
background-clip: padding-box;
- .select-box-kit {
+ .select-kit {
width: 220px;
}
}
diff --git a/app/assets/stylesheets/common/base/notifications-button.scss b/app/assets/stylesheets/common/base/notifications-button.scss
deleted file mode 100644
index 12e8252a821..00000000000
--- a/app/assets/stylesheets/common/base/notifications-button.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.notifications-button, .dropdown-select-box .select-box-kit-row .icons {
- .d-icon.regular, .d-icon.muted, .d-icon.watching-first-post {
- color: dark-light-choose($primary-medium, $secondary-medium);
- }
- .d-icon.tracking, .d-icon.watching {
- color: $tertiary;
- font-weight: normal;
- }
-}
diff --git a/app/assets/stylesheets/common/select-box-kit/categories-admin-dropdown.scss b/app/assets/stylesheets/common/select-box-kit/categories-admin-dropdown.scss
deleted file mode 100644
index 9a7a2e522e9..00000000000
--- a/app/assets/stylesheets/common/select-box-kit/categories-admin-dropdown.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-.select-box-kit {
- &.categories-admin-dropdown {
- .select-box-kit-select-box-kit-body {
- min-width: auto;
- width: 250px;
- }
-
- .select-box-kit-header .d-icon {
- justify-content: space-between;
- }
- }
-}
diff --git a/app/assets/stylesheets/common/select-box-kit/admin-agree-flag-dropdown.scss b/app/assets/stylesheets/common/select-kit/admin-agree-flag-dropdown.scss
similarity index 64%
rename from app/assets/stylesheets/common/select-box-kit/admin-agree-flag-dropdown.scss
rename to app/assets/stylesheets/common/select-kit/admin-agree-flag-dropdown.scss
index 46463584cc0..9c1e778499b 100644
--- a/app/assets/stylesheets/common/select-box-kit/admin-agree-flag-dropdown.scss
+++ b/app/assets/stylesheets/common/select-kit/admin-agree-flag-dropdown.scss
@@ -1,4 +1,4 @@
-.select-box-kit {
+.select-box-kit-body, .select-kit {
&.dropdown-select-box {
&.admin-agree-flag-dropdown {
@@ -7,7 +7,9 @@
max-width: 485px;
}
.select-box-kit-row[data-value="delete-spammer"] .texts .name,
- .select-box-kit-row[data-value="delete-spammer"] .icons .d-icon {
+ .select-kit-row[data-value="delete-spammer"] .texts .name,
+ .select-box-kit-row[data-value="delete-spammer"] .icons .d-icon,
+ .select-kit-row[data-value="delete-spammer"] .icons .d-icon {
color: $danger;
}
}
diff --git a/app/assets/stylesheets/common/select-box-kit/admin-delete-flag-dropdown.scss b/app/assets/stylesheets/common/select-kit/admin-delete-flag-dropdown.scss
similarity index 100%
rename from app/assets/stylesheets/common/select-box-kit/admin-delete-flag-dropdown.scss
rename to app/assets/stylesheets/common/select-kit/admin-delete-flag-dropdown.scss
diff --git a/app/assets/stylesheets/common/select-kit/categories-admin-dropdown.scss b/app/assets/stylesheets/common/select-kit/categories-admin-dropdown.scss
new file mode 100644
index 00000000000..9e3326dd0eb
--- /dev/null
+++ b/app/assets/stylesheets/common/select-kit/categories-admin-dropdown.scss
@@ -0,0 +1,12 @@
+.select-box-kit, .select-kit {
+ &.categories-admin-dropdown {
+ .select-box-kit-body, .select-kit-body {
+ min-width: auto;
+ width: 250px;
+ }
+
+ .select-box-kit-header .d-icon, .select-kit-header .d-icon {
+ justify-content: space-between;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/common/select-box-kit/category-chooser.scss b/app/assets/stylesheets/common/select-kit/category-chooser.scss
similarity index 92%
rename from app/assets/stylesheets/common/select-box-kit/category-chooser.scss
rename to app/assets/stylesheets/common/select-kit/category-chooser.scss
index e5f30989c07..ed4417f96ae 100644
--- a/app/assets/stylesheets/common/select-box-kit/category-chooser.scss
+++ b/app/assets/stylesheets/common/select-kit/category-chooser.scss
@@ -1,8 +1,8 @@
-.select-box-kit {
+.select-box-kit, .select-kit {
&.combo-box {
&.category-chooser {
width: 300px;
- .select-box-kit-row {
+ .select-box-kit-row, .select-kit-row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
diff --git a/app/assets/stylesheets/common/select-box-kit/combo-box.scss b/app/assets/stylesheets/common/select-kit/combo-box.scss
similarity index 80%
rename from app/assets/stylesheets/common/select-box-kit/combo-box.scss
rename to app/assets/stylesheets/common/select-kit/combo-box.scss
index 2c93026e4bc..439279c7b78 100644
--- a/app/assets/stylesheets/common/select-box-kit/combo-box.scss
+++ b/app/assets/stylesheets/common/select-kit/combo-box.scss
@@ -1,29 +1,29 @@
-.select-box-kit {
+.select-box-kit, .select-kit {
&.combo-box {
border-radius: 3px;
- .select-box-kit-body {
+ .select-box-kit-body, .select-kit-body {
width: 100%;
}
- .select-box-kit-row {
+ .select-box-kit-row, .select-kit-row {
margin: 5px;
min-height: 1px;
padding: 5px;
}
- .select-box-kit-filter {
+ .select-box-kit-filter, .select-kit-filter {
line-height: 18px;
padding: 5px 10px;
border-top: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
border-bottom: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
- .select-box-kit-filter-input {
+ .filter-input {
margin-right: 5px;
}
}
- .select-box-kit-header {
+ .select-box-kit-header, .select-kit-header {
background: $secondary;
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
border-radius: 3px;
@@ -41,14 +41,14 @@
}
&.is-disabled {
- .select-box-kit-header {
+ .select-kit-header {
background: #e9e9e9;
border-color: #ddd;
}
}
&.is-highlighted {
- .select-box-kit-header {
+ .select-kit-header {
border: 1px solid $tertiary;
-webkit-box-shadow: $tertiary 0px 0px 6px 0px;
box-shadow: $tertiary 0px 0px 6px 0px;
@@ -56,7 +56,7 @@
}
&.is-expanded {
- .select-box-kit-wrapper {
+ .select-kit-wrapper {
display: block;
border: 1px solid $tertiary;
border-radius: 3px;
@@ -64,20 +64,20 @@
box-shadow: $tertiary 0px 0px 6px 0px;
}
- .select-box-kit-header {
+ .select-kit-header {
border-radius: 3px 3px 0 0;
border-color: transparent;
-webkit-box-shadow: none;
box-shadow: none;
}
- .select-box-kit-body {
+ .select-kit-body {
border-radius: 3px 3px 0 0;
}
}
&.is-expanded.is-above {
- .select-box-kit-header {
+ .select-kit-header {
border-radius: 0 0 3px 3px;
}
}
diff --git a/app/assets/stylesheets/common/select-box-kit/dropdown-select-box.scss b/app/assets/stylesheets/common/select-kit/dropdown-select-box.scss
similarity index 67%
rename from app/assets/stylesheets/common/select-box-kit/dropdown-select-box.scss
rename to app/assets/stylesheets/common/select-kit/dropdown-select-box.scss
index 670a31e657c..97c0aae8c18 100644
--- a/app/assets/stylesheets/common/select-box-kit/dropdown-select-box.scss
+++ b/app/assets/stylesheets/common/select-kit/dropdown-select-box.scss
@@ -1,18 +1,35 @@
-.select-box-kit {
+.select-box-kit, .select-kit {
&.dropdown-select-box {
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
min-width: auto;
+ border: none;
+
+
+ .d-icon {
+ color: dark-light-choose(scale-color($primary, $lightness: 40%), scale-color($secondary, $lightness: 60%));
+ }
+
+ .d-regular, .d-muted, .d-watching-first-post {
+ color: dark-light-choose($primary-medium, $secondary-medium);
+ }
+
+ .d-tracking, .d-watching {
+ color: $tertiary;
+ font-weight: normal;
+ }
&.is-expanded {
.select-box-kit-collection,
- .select-box-kit-body {
+ .select-box-kit-body,
+ .select-kit-collection,
+ .select-kit-body {
border-radius: 0;
}
}
- .select-box-kit-body {
+ .select-box-kit-body, .select-kit-body {
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
background-clip: padding-box;
-webkit-box-shadow: 0 1px 5px rgba(0,0,0,0.4);
@@ -21,7 +38,7 @@
width: 300px;
}
- .select-box-kit-row {
+ .select-box-kit-row, .select-kit-row {
margin: 0;
padding: 10px 5px;
@@ -47,7 +64,6 @@
align-self: center;
margin-right: 0;
opacity: 1;
- color: dark-light-choose(scale-color($primary, $lightness: 40%), scale-color($secondary, $lightness: 60%));
}
}
@@ -91,7 +107,7 @@
}
}
- .select-box-kit-collection {
+ .select-box-kit-collection, .select-kit-collection {
padding: 0;
}
@@ -99,46 +115,30 @@
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
- padding: 0;
border: 0;
- outline: 0;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- justify-content: flex-start;
- background: none;
height: 30px;
- &.is-focused {
- .btn {
- border: 1px solid $tertiary;
- -webkit-box-shadow: $tertiary 0px 0px 6px 0px;
- box-shadow: $tertiary 0px 0px 6px 0px;
- }
- }
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
.d-icon + .d-icon {
margin-left: 5px;
- font-size: 1.143em;
- line-height: 18px;
}
- .btn {
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: justify;
- -ms-flex-pack: justify;
- justify-content: space-between;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -ms-flex-direction: row;
- flex-direction: row;
- display: -webkit-inline-box;
- display: -ms-inline-flexbox;
- display: inline-flex;
- height: 100%;
- margin: 0;
- border: 1px solid transparent
+ &.is-focused {
+ outline-style: auto;
+ outline-color: $tertiary;
}
}
}
diff --git a/app/assets/stylesheets/common/select-box-kit/future-date-input-selector.scss b/app/assets/stylesheets/common/select-kit/future-date-input-selector.scss
similarity index 93%
rename from app/assets/stylesheets/common/select-box-kit/future-date-input-selector.scss
rename to app/assets/stylesheets/common/select-kit/future-date-input-selector.scss
index 60683bddc42..05771bb9d37 100644
--- a/app/assets/stylesheets/common/select-box-kit/future-date-input-selector.scss
+++ b/app/assets/stylesheets/common/select-kit/future-date-input-selector.scss
@@ -1,4 +1,4 @@
-.select-box-kit {
+.select-box-kit, .select-kit {
&.combobox {
&.future-date-input-selector {
min-width: 50%;
diff --git a/app/assets/stylesheets/common/select-box-kit/legacy-combo-box.scss b/app/assets/stylesheets/common/select-kit/legacy-combo-box.scss
similarity index 100%
rename from app/assets/stylesheets/common/select-box-kit/legacy-combo-box.scss
rename to app/assets/stylesheets/common/select-kit/legacy-combo-box.scss
diff --git a/app/assets/stylesheets/common/select-box-kit/list-setting.scss b/app/assets/stylesheets/common/select-kit/list-setting.scss
similarity index 56%
rename from app/assets/stylesheets/common/select-box-kit/list-setting.scss
rename to app/assets/stylesheets/common/select-kit/list-setting.scss
index eea89e6cb5a..1f7103ef982 100644
--- a/app/assets/stylesheets/common/select-box-kit/list-setting.scss
+++ b/app/assets/stylesheets/common/select-kit/list-setting.scss
@@ -1,7 +1,7 @@
-.select-box-kit {
- &.multi-combo-box {
+.select-box-kit, .select-kit {
+ &.multi-select {
&.list-setting {
- .select-box-kit-row.create {
+ .select-box-kit-row.create, .select-kit-row.create {
.square {
width: 12px;
height: 12px;
diff --git a/app/assets/stylesheets/common/select-box-kit/multi-combo-box.scss b/app/assets/stylesheets/common/select-kit/multi-select.scss
similarity index 61%
rename from app/assets/stylesheets/common/select-box-kit/multi-combo-box.scss
rename to app/assets/stylesheets/common/select-kit/multi-select.scss
index 501afde4e6e..a705282643d 100644
--- a/app/assets/stylesheets/common/select-box-kit/multi-combo-box.scss
+++ b/app/assets/stylesheets/common/select-kit/multi-select.scss
@@ -1,29 +1,27 @@
-.select-box-kit {
- &.multi-combo-box {
+.select-box-kit, .select-kit {
+ &.multi-select {
width: 300px;
background: $secondary;
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
border-radius: 0;
- .select-box-kit-body {
+ .select-box-kit-body, .select-kit-body {
width: 100%;
}
- .select-box-kit-row {
+ .select-box-kit-row, .select-kit-row {
margin: 5px;
min-height: 1px;
padding: 5px;
border-radius: 0;
}
- .select-box-kit-filter {
+ .select-box-kit-filter, .select-kit-filter {
border: 0;
}
- .multi-combo-box-header {
+ .multi-select-header {
background: $secondary;
- border: 0;
- border-bottom: 1px solid transparent;
&.is-focused {
box-shadow: $tertiary 0px 0px 6px 0px;
@@ -32,14 +30,14 @@
}
&.is-disabled {
- .multi-combo-box-header {
+ .multi-select-header {
background: #e9e9e9;
border-color: #ddd;
}
}
&.is-highlighted {
- .multi-combo-box-header {
+ .multi-select-header {
border-radius: 0;
border-bottom: 1px solid transparent;
box-shadow: $tertiary 0px 0px 6px 0px;
@@ -47,20 +45,19 @@
}
&.is-expanded {
- .select-box-kit-wrapper {
+ .select-box-kit-wrapper, .select-kit-wrapper {
display: block;
border: 1px solid $tertiary;
box-shadow: $tertiary 0px 0px 6px 0px;
border-radius: 0;
}
- .multi-combo-box-header {
- border-bottom: 1px solid $primary-low;
+ .multi-select-header {
border-radius: 0;
box-shadow: none;
}
- .select-box-kit-body {
+ .select-box-kit-body, .select-kit-body {
border-radius: 0;
}
}
@@ -69,16 +66,20 @@
list-style: none;
margin: 0;
padding: 5px;
- flex: 1;
- min-height: 36px;
box-sizing: border-box;
+ display: inline;
+ list-style-type: none;
- li {
+ .choice {
display: inline-flex;
box-sizing: border-box;
padding: 0 5px;
- margin-bottom: 4px;
+ margin: 2px 0;
border: 1px solid transparent;
+ align-items: center;
+ justify-content: space-between;
+ overflow: hidden;
+ align-items: center;
}
.filter {
@@ -87,8 +88,9 @@
white-space: nowrap;
min-width: 50px;
padding: 0;
+ outline: none;
- .select-box-kit-filter-input, .select-box-kit-filter-input:focus {
+ .filter-input, .filter-input:focus {
border: none;
background: none;
display: inline-block;
@@ -102,6 +104,21 @@
-webkit-box-shadow: none;
box-shadow: none;
border-radius: 0;
+ height: 21px;
+ }
+ }
+
+ .selected-color {
+ .selected-color-wrapper {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ }
+
+ .color-preview {
+ height: 5px;
+ margin: 0 2px 2px 2px;
+ border-radius: 5px;
}
}
@@ -119,26 +136,33 @@
background-color: $primary-low;
cursor: pointer;
outline: none;
- padding: 0;
+ padding-left: 0;
+ padding-right: 0;
line-height: normal;
.name {
padding: 0 5px;
- line-height: 22px
+ line-height: 18px;
}
&.is-highlighted {
- border-color: $danger;
+ box-shadow: 0 0 2px $danger, 0 1px 0 rgba(0,0,0,0.05);
}
- .d-icon {
- margin-right: 5px;
- color: $primary-medium;
- cursor: pointer;
- font-size: 12px;
+ .locked-icon, .delete-icon {
+ justify-content: center;
+ align-items: center;
+ width: 21px;
+ height: 21px;
+ display: inline-flex;
+ .d-icon {
+ color: $primary-medium;
+ cursor: pointer;
+ font-size: 14px;
- &:hover {
- color: $primary;
+ &:hover {
+ color: $primary;
+ }
}
}
}
diff --git a/app/assets/stylesheets/common/select-box-kit/notifications-button.scss b/app/assets/stylesheets/common/select-kit/notifications-button.scss
similarity index 69%
rename from app/assets/stylesheets/common/select-box-kit/notifications-button.scss
rename to app/assets/stylesheets/common/select-kit/notifications-button.scss
index 877cf815ab8..78db012b79f 100644
--- a/app/assets/stylesheets/common/select-box-kit/notifications-button.scss
+++ b/app/assets/stylesheets/common/select-kit/notifications-button.scss
@@ -1,12 +1,12 @@
-.select-box-kit {
+.select-kit {
&.dropdown-select-box {
&.notifications-button {
- .select-box-kit-body {
+ .select-box-kit-body, .select-kit-body {
min-width: 550px;
max-width: 550px;
}
- .select-box-kit-row {
+ .select-box-kit-row, .select-kit-row {
.icons {
-ms-flex-item-align: start;
align-self: flex-start;
diff --git a/app/assets/stylesheets/common/select-box-kit/pinned-button.scss b/app/assets/stylesheets/common/select-kit/pinned-button.scss
similarity index 94%
rename from app/assets/stylesheets/common/select-box-kit/pinned-button.scss
rename to app/assets/stylesheets/common/select-kit/pinned-button.scss
index a75a596c6a3..c96365a0e6d 100644
--- a/app/assets/stylesheets/common/select-box-kit/pinned-button.scss
+++ b/app/assets/stylesheets/common/select-kit/pinned-button.scss
@@ -38,7 +38,7 @@
}
.pinned-options {
- .select-box-kit-body {
+ .select-box-kit-body, .select-kit-body {
min-width: unset;
max-width: unset;
width: 550px;
diff --git a/app/assets/stylesheets/common/select-box-kit/select-box-kit.scss b/app/assets/stylesheets/common/select-kit/select-kit.scss
similarity index 86%
rename from app/assets/stylesheets/common/select-box-kit/select-box-kit.scss
rename to app/assets/stylesheets/common/select-kit/select-kit.scss
index fc8fb103f77..b663b17329d 100644
--- a/app/assets/stylesheets/common/select-box-kit/select-box-kit.scss
+++ b/app/assets/stylesheets/common/select-kit/select-kit.scss
@@ -1,8 +1,8 @@
-.mobile-view .select-box-kit.is-expanded {
+.mobile-view .select-kit.is-expanded {
z-index: 1000;
}
-.select-box-kit {
+.select-box-kit, .select-kit {
border: 1px solid transparent;
min-width: 220px;
-webkit-box-sizing: border-box;
@@ -31,7 +31,7 @@
&.is-expanded {
z-index: 999;
- .select-box-kit-body {
+ .select-kit-body {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@@ -44,18 +44,22 @@
top: 0;
}
- .select-box-kit-collection, {
+ .select-kit-collection, {
border-radius: inherit;
}
}
&.is-above {
- .select-box-kit-body {
+ .select-kit-body {
bottom: 0;
top: auto;
}
- .select-box-kit-wrapper {
+ .select-kit-filter {
+ border-top: 0;
+ }
+
+ .select-kit-wrapper {
bottom: 0;
top: auto;
}
@@ -65,7 +69,7 @@
opacity: 0.7;
}
- .select-box-kit-header {
+ .select-box-kit-header, .select-kit-header {
border: 1px solid transparent;
box-sizing: border-box;
overflow: hidden;
@@ -133,14 +137,14 @@
}
}
- .select-box-kit-body {
+ .select-box-kit-body, .select-kit-body {
display: none;
background: $secondary;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
- .select-box-kit-row {
+ .select-box-kit-row, .select-kit-row {
cursor: pointer;
line-height: normal;
outline: none;
@@ -181,7 +185,7 @@
}
}
- .select-box-kit-collection {
+ .select-box-kit-collection, .select-kit-collection {
background: $secondary;
overflow-x: hidden;
overflow-y: auto;
@@ -189,11 +193,11 @@
-webkit-overflow-scrolling: touch;
margin: 0;
- .select-box-kit-collection {
+ .select-kit-collection {
padding: 0;
margin: 0;
- &:hover .select-box-kit-row.is-highlighted:hover {
+ &:hover .select-kit-row.is-highlighted:hover {
background: $tertiary-low;
}
}
@@ -215,7 +219,7 @@
}
}
- .select-box-kit-filter {
+ .select-box-kit-filter, .select-kit-filter {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@@ -226,7 +230,7 @@
-ms-flex-pack: justify;
justify-content: space-between;
- .select-box-kit-filter-input, .select-box-kit-filter-input:focus, .select-box-kit-filter-input:active {
+ .filter-input, .filter-input:focus, .filter-input:active {
background: none;
margin: 0;
padding: 0;
@@ -255,10 +259,10 @@
}
}
- .select-box-kit-wrapper {
+ .select-box-kit-wrapper, .select-kit-wrapper {
position: absolute;
- top: -1px;
- left: -1px;
+ top: 0;
+ left: 0;
background: none;
display: none;
-webkit-box-sizing: border-box;
@@ -266,17 +270,4 @@
pointer-events: none;
border: 1px solid transparent;
}
-
- .select-box-kit-offscreen, .select-box-kit-offscreen:focus {
- margin: -1px;
- width: 1px;
- height: 1px;
- border: 0;
- padding: 0;
- overflow: hidden;
- position: fixed;
- outline: 0;
- left: 0px;
- top: 0px;
- }
}
diff --git a/app/assets/stylesheets/common/select-box-kit/topic-notifications-button.scss b/app/assets/stylesheets/common/select-kit/topic-notifications-button.scss
similarity index 100%
rename from app/assets/stylesheets/common/select-box-kit/topic-notifications-button.scss
rename to app/assets/stylesheets/common/select-kit/topic-notifications-button.scss
diff --git a/app/assets/stylesheets/mobile/topic-list.scss b/app/assets/stylesheets/mobile/topic-list.scss
index 806ab8cb1a7..49c1dd29c0a 100644
--- a/app/assets/stylesheets/mobile/topic-list.scss
+++ b/app/assets/stylesheets/mobile/topic-list.scss
@@ -53,7 +53,7 @@
}
}
- .select-box-kit {
+ .select-kit {
&.categories-admin-dropdown, &.category-notifications-button, &.tag-notifications-button {
margin-top: 5px;
}
diff --git a/app/assets/stylesheets/wizard.scss b/app/assets/stylesheets/wizard.scss
index 7d84bb53aef..ab0b6f3601d 100644
--- a/app/assets/stylesheets/wizard.scss
+++ b/app/assets/stylesheets/wizard.scss
@@ -4,7 +4,7 @@
@import "vendor/sweetalert";
@import "common/foundation/colors";
@import "common/foundation/variables";
-@import "common/select-box-kit/*";
+@import "common/select-kit/*";
body.wizard {
background-color: #fff;
diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml
index 38f66f95508..a8246952beb 100644
--- a/config/locales/client.ar.yml
+++ b/config/locales/client.ar.yml
@@ -1193,7 +1193,7 @@ ar:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: اختر...
no_content: لا يوجد نتائج مطابقة
filter_placeholder: بحث...
diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml
index 2a97f303f9b..29f6944fd05 100644
--- a/config/locales/client.de.yml
+++ b/config/locales/client.de.yml
@@ -1040,7 +1040,7 @@ de:
shift: 'Umschalt'
ctrl: 'Strg'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Auswählen…
no_content: Keine Treffer gefunden
filter_placeholder: Suchen…
diff --git a/config/locales/client.el.yml b/config/locales/client.el.yml
index 6ce5ecf9da4..97eb8ef1fac 100644
--- a/config/locales/client.el.yml
+++ b/config/locales/client.el.yml
@@ -1040,7 +1040,7 @@ el:
shift: ' Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Επίλεξε...
no_content: Δεν βρέθηκαν αποτελέσματα
filter_placeholder: Αναζήτηση...
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 4080de01ee5..dfba2c103d3 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1165,7 +1165,7 @@ en:
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Select...
no_content: No matches found
filter_placeholder: Search...
diff --git a/config/locales/client.es.yml b/config/locales/client.es.yml
index a93159b6048..3f98e7632c3 100644
--- a/config/locales/client.es.yml
+++ b/config/locales/client.es.yml
@@ -1022,7 +1022,7 @@ es:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Seleccionar...
no_content: Ningún resultado
filter_placeholder: Buscar...
diff --git a/config/locales/client.fa_IR.yml b/config/locales/client.fa_IR.yml
index d5c32a495d4..64b3713e55a 100644
--- a/config/locales/client.fa_IR.yml
+++ b/config/locales/client.fa_IR.yml
@@ -981,7 +981,7 @@ fa_IR:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: انتخاب...
no_content: چیزی یافت نشد.
filter_placeholder: جستجو...
diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml
index 8749733268a..1fa33f89a8b 100644
--- a/config/locales/client.fi.yml
+++ b/config/locales/client.fi.yml
@@ -1036,7 +1036,7 @@ fi:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Valitse...
no_content: Ei osumia
filter_placeholder: Hae...
diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml
index dc5879e7e9c..91b5787792b 100644
--- a/config/locales/client.fr.yml
+++ b/config/locales/client.fr.yml
@@ -1036,7 +1036,7 @@ fr:
shift: 'Maj'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Sélectionner…
no_content: Aucune correspondance trouvée
filter_placeholder: Recherche...
diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml
index 1dc4f872800..5444f8fa986 100644
--- a/config/locales/client.it.yml
+++ b/config/locales/client.it.yml
@@ -1040,7 +1040,7 @@ it:
shift: 'Maiusc'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Selezione...
no_content: Nessun risultato trovato
filter_placeholder: Ricerca...
diff --git a/config/locales/client.ja.yml b/config/locales/client.ja.yml
index 20e98796a2b..9375bc1d969 100644
--- a/config/locales/client.ja.yml
+++ b/config/locales/client.ja.yml
@@ -990,7 +990,7 @@ ja:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: 選択...
no_content: 一致する結果が見つかりませんでした。
filter_placeholder: 検索...
diff --git a/config/locales/client.ko.yml b/config/locales/client.ko.yml
index 078091609ef..7496a873804 100644
--- a/config/locales/client.ko.yml
+++ b/config/locales/client.ko.yml
@@ -996,7 +996,7 @@ ko:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: 선택...
no_content: 검색 결과가 없습니다
filter_placeholder: 검색...
diff --git a/config/locales/client.nb_NO.yml b/config/locales/client.nb_NO.yml
index 831a1665d69..206a30e05d6 100644
--- a/config/locales/client.nb_NO.yml
+++ b/config/locales/client.nb_NO.yml
@@ -1039,7 +1039,7 @@ nb_NO:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Velg…
no_content: Ingen treff funnet
filter_placeholder: Søk…
diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml
index 07fbf32c80d..8acb11126cb 100644
--- a/config/locales/client.nl.yml
+++ b/config/locales/client.nl.yml
@@ -1033,7 +1033,7 @@ nl:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Selecteer...
no_content: Geen resultaten gevonden
filter_placeholder: Zoeken...
diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml
index 07c52c7fa07..0442c9cae98 100644
--- a/config/locales/client.pl_PL.yml
+++ b/config/locales/client.pl_PL.yml
@@ -1111,7 +1111,7 @@ pl_PL:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Wybierz...
no_content: Nie znaleziono dopasowań
filter_placeholder: Wyszukiwanie...
diff --git a/config/locales/client.pt.yml b/config/locales/client.pt.yml
index 8684f7b1d66..e2ab135823b 100644
--- a/config/locales/client.pt.yml
+++ b/config/locales/client.pt.yml
@@ -1010,7 +1010,7 @@ pt:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
filter_placeholder: Pesquisar...
emoji_picker:
filter_placeholder: Pesquisar por emoji
diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml
index 56e57730c98..1e5ada6e734 100644
--- a/config/locales/client.ru.yml
+++ b/config/locales/client.ru.yml
@@ -1094,7 +1094,7 @@ ru:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
filter_placeholder: Искать...
emoji_picker:
filter_placeholder: Искать emoji
diff --git a/config/locales/client.vi.yml b/config/locales/client.vi.yml
index cca5bc36ead..6c2ac34a53f 100644
--- a/config/locales/client.vi.yml
+++ b/config/locales/client.vi.yml
@@ -951,7 +951,7 @@ vi:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: Chọn...
no_content: Không tìm thấy
filter_placeholder: Tìm kiến...
diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml
index 13dba3dfcc7..5de44be5809 100644
--- a/config/locales/client.zh_CN.yml
+++ b/config/locales/client.zh_CN.yml
@@ -996,7 +996,7 @@ zh_CN:
shift: 'Shift'
ctrl: 'Ctrl'
alt: 'Alt'
- select_box:
+ select_kit:
default_header_text: 选择...
no_content: 无符合的结果
filter_placeholder: 搜索……
diff --git a/plugins/discourse-details/test/javascripts/acceptance/details-button-test.js.es6 b/plugins/discourse-details/test/javascripts/acceptance/details-button-test.js.es6
index b0f25283ec5..f4639ca26c8 100644
--- a/plugins/discourse-details/test/javascripts/acceptance/details-button-test.js.es6
+++ b/plugins/discourse-details/test/javascripts/acceptance/details-button-test.js.es6
@@ -11,7 +11,7 @@ test('details button', (assert) => {
click('#create-topic');
click('button.options');
- click('.popup-menu .d-icon-caret-right');
+ click('.popup-menu .d-caret-right');
andThen(() => {
assert.equal(
@@ -30,7 +30,7 @@ test('details button', (assert) => {
});
click('button.options');
- click('.popup-menu .d-icon-caret-right');
+ click('.popup-menu .d-caret-right');
andThen(() => {
assert.equal(
@@ -53,7 +53,7 @@ test('details button', (assert) => {
});
click('button.options');
- click('.popup-menu .d-icon-caret-right');
+ click('.popup-menu .d-caret-right');
andThen(() => {
assert.equal(
@@ -76,7 +76,7 @@ test('details button', (assert) => {
});
click('button.options');
- click('.popup-menu .d-icon-caret-right');
+ click('.popup-menu .d-caret-right');
andThen(() => {
assert.equal(
@@ -105,7 +105,7 @@ test('details button surrounds all selected text in a single details block', (as
});
click('button.options');
- click('.popup-menu .d-icon-caret-right');
+ click('.popup-menu .d-caret-right');
andThen(() => {
assert.equal(
diff --git a/plugins/poll/test/javascripts/widgets/discourse-poll-option-test.js.es6 b/plugins/poll/test/javascripts/widgets/discourse-poll-option-test.js.es6
index 75035b6651c..32ab64e6a30 100644
--- a/plugins/poll/test/javascripts/widgets/discourse-poll-option-test.js.es6
+++ b/plugins/poll/test/javascripts/widgets/discourse-poll-option-test.js.es6
@@ -14,7 +14,7 @@ widgetTest('single, not selected', {
},
test(assert) {
- assert.ok(find('li .d-icon-circle-o:eq(0)').length === 1);
+ assert.ok(find('li .d-circle-o:eq(0)').length === 1);
}
});
@@ -27,7 +27,7 @@ widgetTest('single, selected', {
},
test(assert) {
- assert.ok(find('li .d-icon-dot-circle-o:eq(0)').length === 1);
+ assert.ok(find('li .d-dot-circle-o:eq(0)').length === 1);
}
});
@@ -43,7 +43,7 @@ widgetTest('multi, not selected', {
},
test(assert) {
- assert.ok(find('li .d-icon-square-o:eq(0)').length === 1);
+ assert.ok(find('li .d-square-o:eq(0)').length === 1);
}
});
@@ -59,6 +59,6 @@ widgetTest('multi, selected', {
},
test(assert) {
- assert.ok(find('li .d-icon-check-square-o:eq(0)').length === 1);
+ assert.ok(find('li .d-check-square-o:eq(0)').length === 1);
}
});
diff --git a/test/javascripts/acceptance/admin-flags-test.js.es6 b/test/javascripts/acceptance/admin-flags-test.js.es6
index 3d448184334..3b25ee2f087 100644
--- a/test/javascripts/acceptance/admin-flags-test.js.es6
+++ b/test/javascripts/acceptance/admin-flags-test.js.es6
@@ -16,11 +16,11 @@ QUnit.test("flagged posts - agree", assert => {
visit("/admin/flags/active");
andThen(() => {
- expandSelectBoxKit('.agree-flag');
+ expandSelectKit('.agree-flag');
});
andThen(() => {
- selectBoxKitSelectRow('confirm-agree-keep', { selector: '.agree-flag'});
+ selectKitSelectRow('confirm-agree-keep', { selector: '.agree-flag'});
});
andThen(() => {
@@ -32,11 +32,11 @@ QUnit.test("flagged posts - agree + hide", assert => {
visit("/admin/flags/active");
andThen(() => {
- expandSelectBoxKit('.agree-flag');
+ expandSelectKit('.agree-flag');
});
andThen(() => {
- selectBoxKitSelectRow('confirm-agree-hide', { selector: '.agree-flag'});
+ selectKitSelectRow('confirm-agree-hide', { selector: '.agree-flag'});
});
andThen(() => {
@@ -48,11 +48,11 @@ QUnit.test("flagged posts - agree + deleteSpammer", assert => {
visit("/admin/flags/active");
andThen(() => {
- expandSelectBoxKit('.agree-flag');
+ expandSelectKit('.agree-flag');
});
andThen(() => {
- selectBoxKitSelectRow('delete-spammer', { selector: '.agree-flag'});
+ selectKitSelectRow('delete-spammer', { selector: '.agree-flag'});
});
click('.confirm-delete');
@@ -82,11 +82,11 @@ QUnit.test("flagged posts - delete + defer", assert => {
visit("/admin/flags/active");
andThen(() => {
- expandSelectBoxKit('.delete-flag');
+ expandSelectKit('.delete-flag');
});
andThen(() => {
- selectBoxKitSelectRow('delete-defer', { selector: '.delete-flag'});
+ selectKitSelectRow('delete-defer', { selector: '.delete-flag'});
});
andThen(() => {
@@ -98,11 +98,11 @@ QUnit.test("flagged posts - delete + agree", assert => {
visit("/admin/flags/active");
andThen(() => {
- expandSelectBoxKit('.delete-flag');
+ expandSelectKit('.delete-flag');
});
andThen(() => {
- selectBoxKitSelectRow('delete-agree', { selector: '.delete-flag'});
+ selectKitSelectRow('delete-agree', { selector: '.delete-flag'});
});
andThen(() => {
@@ -114,11 +114,11 @@ QUnit.test("flagged posts - delete + deleteSpammer", assert => {
visit("/admin/flags/active");
andThen(() => {
- expandSelectBoxKit('.delete-flag');
+ expandSelectKit('.delete-flag');
});
andThen(() => {
- selectBoxKitSelectRow('delete-spammer', { selector: '.delete-flag'});
+ selectKitSelectRow('delete-spammer', { selector: '.delete-flag'});
});
click('.confirm-delete');
diff --git a/test/javascripts/acceptance/admin-suspend-user-test.js.es6 b/test/javascripts/acceptance/admin-suspend-user-test.js.es6
index bd1fb803563..cfe73206013 100644
--- a/test/javascripts/acceptance/admin-suspend-user-test.js.es6
+++ b/test/javascripts/acceptance/admin-suspend-user-test.js.es6
@@ -44,8 +44,8 @@ QUnit.test("suspend, then unsuspend a user", assert => {
andThen(() => {
assert.equal(find('.perform-suspend[disabled]').length, 1, 'disabled by default');
- expandSelectBoxKit('.suspend-until .combobox');
- selectBoxKitSelectRow('tomorrow', { selector: '.suspend-until .combobox'});
+ expandSelectKit('.suspend-until .combobox');
+ selectKitSelectRow('tomorrow', { selector: '.suspend-until .combobox'});
});
fillIn('.suspend-reason', "for breaking the rules");
diff --git a/test/javascripts/acceptance/category-chooser-test.js.es6 b/test/javascripts/acceptance/category-chooser-test.js.es6
index 9f645bc6b00..793674295f8 100644
--- a/test/javascripts/acceptance/category-chooser-test.js.es6
+++ b/test/javascripts/acceptance/category-chooser-test.js.es6
@@ -11,10 +11,10 @@ QUnit.test("does not display uncategorized if not allowed", assert => {
visit("/");
click('#create-topic');
- ('.category-chooser');
+ expandSelectKit('.category-chooser');
andThen(() => {
- assert.ok(selectBox('.category-chooser').rowByIndex(0).name() !== 'uncategorized');
+ assert.ok(selectKit('.category-chooser').rowByIndex(0).name() !== 'uncategorized');
});
});
@@ -22,6 +22,6 @@ QUnit.test("prefill category when category_id is set", assert => {
visit("/new-topic?category_id=1");
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), 'bug');
+ assert.equal(selectKit('.category-chooser').header.name(), 'bug');
});
});
diff --git a/test/javascripts/acceptance/category-edit-test.js.es6 b/test/javascripts/acceptance/category-edit-test.js.es6
index 24d1eceef41..5f0415a43cb 100644
--- a/test/javascripts/acceptance/category-edit-test.js.es6
+++ b/test/javascripts/acceptance/category-edit-test.js.es6
@@ -75,9 +75,9 @@ QUnit.test("Subcategory list settings", assert => {
click('.edit-category-general');
- expandSelectBoxKit('.edit-category-tab-general .category-chooser');
+ expandSelectKit('.edit-category-tab-general .category-chooser');
- selectBoxKitSelectRow(3, {selector: '.edit-category-tab-general .category-chooser'});
+ selectKitSelectRow(3, {selector: '.edit-category-tab-general .category-chooser'});
click('.edit-category-settings');
andThen(() => {
diff --git a/test/javascripts/acceptance/composer-test.js.es6 b/test/javascripts/acceptance/composer-test.js.es6
index 48afc43867d..97df4f971ce 100644
--- a/test/javascripts/acceptance/composer-test.js.es6
+++ b/test/javascripts/acceptance/composer-test.js.es6
@@ -264,7 +264,7 @@ QUnit.test("Composer can toggle between reply and createTopic", assert => {
click('.topic-post:eq(0) button.reply');
click('button.options');
- click('.popup-menu .d-icon-eye-slash');
+ click('.popup-menu .d-eye-slash');
andThen(() => {
assert.ok(
find('.composer-fields .whisper').text().indexOf(I18n.t("composer.whisper")) > 0,
@@ -286,7 +286,7 @@ QUnit.test("Composer can toggle between reply and createTopic", assert => {
});
click('button.options');
- click('.popup-menu .d-icon-eye-slash');
+ click('.popup-menu .d-eye-slash');
andThen(() => {
assert.ok(
find('.composer-fields .whisper').text().indexOf(I18n.t("composer.unlist")) > 0,
diff --git a/test/javascripts/acceptance/search-full-test.js.es6 b/test/javascripts/acceptance/search-full-test.js.es6
index 24ad402b30b..db5dc8cee85 100644
--- a/test/javascripts/acceptance/search-full-test.js.es6
+++ b/test/javascripts/acceptance/search-full-test.js.es6
@@ -136,10 +136,10 @@ QUnit.test("update category through advanced search ui", assert => {
visit("/search");
fillIn('.search input.full-page-search', 'none');
click('.search-advanced-btn');
- fillIn('.search-advanced-options .category-selector', 'faq');
- click('.search-advanced-options .category-selector');
- keyEvent('.search-advanced-options .category-selector', 'keydown', 8);
- keyEvent('.search-advanced-options .category-selector', 'keydown', 9);
+
+ expandSelectKit('.search-advanced-options .category-chooser');
+ selectKitFillInFilter('faq', { selector: '.search-advanced-options .category-chooser' });
+ selectKitSelectRow(4, { selector: '.search-advanced-options .category-chooser' });
andThen(() => {
assert.ok(exists('.search-advanced-options .badge-category:contains("faq")'), 'has "faq" populated');
@@ -257,12 +257,12 @@ QUnit.test("update in filter through advanced search ui", assert => {
fillIn('.search input.full-page-search', 'none');
click('.search-advanced-btn');
- expandSelectBoxKit('.search-advanced-options .select-box-kit#in');
- selectBoxKitSelectRow('bookmarks', { selector: '.search-advanced-options .select-box-kit#in' });
- fillIn('.search-advanced-options .select-box-kit#in', 'bookmarks');
+ expandSelectKit('.search-advanced-options .select-kit#in');
+ selectKitSelectRow('bookmarks', { selector: '.search-advanced-options .select-kit#in' });
+ fillIn('.search-advanced-options .select-kit#in', 'bookmarks');
andThen(() => {
- assert.ok(exists(selectBox('.search-advanced-options .select-box-kit#in').rowByName("I\'ve bookmarked").el), 'has "I\'ve bookmarked" populated');
+ assert.ok(exists(selectKit('.search-advanced-options .select-kit#in').rowByName("I\'ve bookmarked").el), 'has "I\'ve bookmarked" populated');
assert.equal(find('.search input.full-page-search').val(), "none in:bookmarks", 'has updated search term to "none in:bookmarks"');
});
});
@@ -271,12 +271,12 @@ QUnit.test("update status through advanced search ui", assert => {
visit("/search");
fillIn('.search input.full-page-search', 'none');
click('.search-advanced-btn');
- expandSelectBoxKit('.search-advanced-options .select-box-kit#status');
- selectBoxKitSelectRow('closed', { selector: '.search-advanced-options .select-box-kit#status' });
- fillIn('.search-advanced-options .select-box-kit#status', 'closed');
+ expandSelectKit('.search-advanced-options .select-kit#status');
+ selectKitSelectRow('closed', { selector: '.search-advanced-options .select-kit#status' });
+ fillIn('.search-advanced-options .select-kit#status', 'closed');
andThen(() => {
- assert.ok(exists(selectBox('.search-advanced-options .select-box-kit#status').rowByName("are closed").el), 'has "are closed" populated');
+ assert.ok(exists(selectKit('.search-advanced-options .select-kit#status').rowByName("are closed").el), 'has "are closed" populated');
assert.equal(find('.search input.full-page-search').val(), "none status:closed", 'has updated search term to "none status:closed"');
});
});
@@ -286,12 +286,12 @@ QUnit.test("update post time through advanced search ui", assert => {
fillIn('.search input.full-page-search', 'none');
click('.search-advanced-btn');
fillIn('#search-post-date', '2016-10-05');
- expandSelectBoxKit('.search-advanced-options .select-box-kit#postTime');
- selectBoxKitSelectRow('after', { selector: '.search-advanced-options .select-box-kit#postTime' });
- fillIn('.search-advanced-options .select-box-kit#postTime', 'after');
+ expandSelectKit('.search-advanced-options .select-kit#postTime');
+ selectKitSelectRow('after', { selector: '.search-advanced-options .select-kit#postTime' });
+ fillIn('.search-advanced-options .select-kit#postTime', 'after');
andThen(() => {
- assert.ok(exists(selectBox('.search-advanced-options .select-box-kit#postTime').rowByName("after").el), 'has "after" populated');
+ assert.ok(exists(selectKit('.search-advanced-options .select-kit#postTime').rowByName("after").el), 'has "after" populated');
assert.equal(find('.search-advanced-options #search-post-date').val(), "2016-10-05", 'has "2016-10-05" populated');
assert.equal(find('.search input.full-page-search').val(), "none after:2016-10-05", 'has updated search term to "none after:2016-10-05"');
});
diff --git a/test/javascripts/acceptance/search-test.js.es6 b/test/javascripts/acceptance/search-test.js.es6
index a5ce94669b3..d9fb690638e 100644
--- a/test/javascripts/acceptance/search-test.js.es6
+++ b/test/javascripts/acceptance/search-test.js.es6
@@ -89,20 +89,20 @@ QUnit.test("Search with context", assert => {
QUnit.test("Right filters are shown to anonymous users", assert => {
visit("/search?expanded=true");
- expandSelectBoxKit(".select-box-kit#in");
+ expandSelectKit(".select-kit#in");
andThen(() => {
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=first]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=pinned]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=unpinned]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=wiki]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=images]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=first]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=pinned]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=unpinned]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=wiki]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=images]'));
- assert.notOk(exists('.select-box-kit#in .select-box-kit-row[data-value=unseen]'));
- assert.notOk(exists('.select-box-kit#in .select-box-kit-row[data-value=posted]'));
- assert.notOk(exists('.select-box-kit#in .select-box-kit-row[data-value=watching]'));
- assert.notOk(exists('.select-box-kit#in .select-box-kit-row[data-value=tracking]'));
- assert.notOk(exists('.select-box-kit#in .select-box-kit-row[data-value=bookmarks]'));
+ assert.notOk(exists('.select-kit#in .select-kit-row[data-value=unseen]'));
+ assert.notOk(exists('.select-kit#in .select-kit-row[data-value=posted]'));
+ assert.notOk(exists('.select-kit#in .select-kit-row[data-value=watching]'));
+ assert.notOk(exists('.select-kit#in .select-kit-row[data-value=tracking]'));
+ assert.notOk(exists('.select-kit#in .select-kit-row[data-value=bookmarks]'));
assert.notOk(exists('.search-advanced-options .in-likes'));
assert.notOk(exists('.search-advanced-options .in-private'));
@@ -115,20 +115,20 @@ QUnit.test("Right filters are shown to logged-in users", assert => {
Discourse.reset();
visit("/search?expanded=true");
- expandSelectBoxKit(".select-box-kit#in");
+ expandSelectKit(".select-kit#in");
andThen(() => {
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=first]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=pinned]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=unpinned]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=wiki]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=images]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=first]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=pinned]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=unpinned]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=wiki]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=images]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=unseen]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=posted]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=watching]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=tracking]'));
- assert.ok(exists('.select-box-kit#in .select-box-kit-row[data-value=bookmarks]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=unseen]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=posted]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=watching]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=tracking]'));
+ assert.ok(exists('.select-kit#in .select-kit-row[data-value=bookmarks]'));
assert.ok(exists('.search-advanced-options .in-likes'));
assert.ok(exists('.search-advanced-options .in-private'));
diff --git a/test/javascripts/acceptance/topic-notifications-button-test.js.es6 b/test/javascripts/acceptance/topic-notifications-button-test.js.es6
index fa21ef4e96a..7a0934ffc57 100644
--- a/test/javascripts/acceptance/topic-notifications-button-test.js.es6
+++ b/test/javascripts/acceptance/topic-notifications-button-test.js.es6
@@ -28,12 +28,12 @@ QUnit.test("Updating topic notification level", assert => {
);
});
- expandSelectBoxKit(notificationOptions);
- selectBoxKitSelectRow("3", { selector: notificationOptions});
+ expandSelectKit(notificationOptions);
+ selectKitSelectRow("3", { selector: notificationOptions});
andThen(() => {
assert.equal(
- selectBox(notificationOptions).selectedRow.name(),
+ selectKit(notificationOptions).selectedRow.name(),
"watching",
"it should display the right notification level"
);
diff --git a/test/javascripts/acceptance/topic-test.js.es6 b/test/javascripts/acceptance/topic-test.js.es6
index 72f8518070c..6ffaa1a6f09 100644
--- a/test/javascripts/acceptance/topic-test.js.es6
+++ b/test/javascripts/acceptance/topic-test.js.es6
@@ -33,7 +33,7 @@ QUnit.test("Share Popup", assert => {
QUnit.test("Showing and hiding the edit controls", assert => {
visit("/t/internationalization-localization/280");
- click('#topic-title .d-icon-pencil');
+ click('#topic-title .d-pencil');
andThen(() => {
assert.ok(exists('#edit-title'), 'it shows the editing controls');
@@ -49,13 +49,13 @@ QUnit.test("Showing and hiding the edit controls", assert => {
QUnit.test("Updating the topic title and category", assert => {
visit("/t/internationalization-localization/280");
- click('#topic-title .d-icon-pencil');
+ click('#topic-title .d-pencil');
fillIn('#edit-title', 'this is the new title');
- expandSelectBoxKit('.title-wrapper .category-chooser');
+ expandSelectKit('.title-wrapper .category-chooser');
- selectBoxKitSelectRow(4, {selector: '.title-wrapper .category-chooser'});
+ selectKitSelectRow(4, {selector: '.title-wrapper .category-chooser'});
click('#topic-title .submit-edit');
@@ -103,7 +103,7 @@ QUnit.test("Reply as new topic", assert => {
"it fills composer with the ring string"
);
assert.equal(
- selectBox('.category-chooser').header.name(), "feature",
+ selectKit('.category-chooser').header.name(), "feature",
"it fills category selector with the right category"
);
});
@@ -164,7 +164,7 @@ QUnit.test("Visit topic routes", assert => {
QUnit.test("Updating the topic title with emojis", assert => {
visit("/t/internationalization-localization/280");
- click('#topic-title .d-icon-pencil');
+ click('#topic-title .d-pencil');
fillIn('#edit-title', 'emojis title :bike: :blonde_woman:t6:');
diff --git a/test/javascripts/components/categories-admin-dropdown-test.js.es6 b/test/javascripts/components/categories-admin-dropdown-test.js.es6
index 07593db3e62..3c999f03e9d 100644
--- a/test/javascripts/components/categories-admin-dropdown-test.js.es6
+++ b/test/javascripts/components/categories-admin-dropdown-test.js.es6
@@ -5,15 +5,15 @@ componentTest('default', {
template: '{{categories-admin-dropdown}}',
test(assert) {
- const $selectBox = selectBox('.categories-admin-dropdown');
+ const $selectKit = selectKit('.categories-admin-dropdown');
- assert.equal($selectBox.el.find(".d-icon-bars").length, 1);
- assert.equal($selectBox.el.find(".d-icon-caret-down").length, 1);
+ assert.equal($selectKit.el.find(".d-bars").length, 1);
+ assert.equal($selectKit.el.find(".d-caret-down").length, 1);
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal($selectBox.rowByValue("create").name(), "New Category");
+ assert.equal($selectKit.rowByValue("create").name(), "New Category");
});
}
});
diff --git a/test/javascripts/components/category-chooser-test.js.es6 b/test/javascripts/components/category-chooser-test.js.es6
index d6fca21fd09..ec29639148e 100644
--- a/test/javascripts/components/category-chooser-test.js.es6
+++ b/test/javascripts/components/category-chooser-test.js.es6
@@ -6,10 +6,10 @@ componentTest('with value', {
template: '{{category-chooser value=2}}',
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), "feature");
+ assert.equal(selectKit('.category-chooser').header.name(), "feature");
});
}
});
@@ -18,10 +18,10 @@ componentTest('with excludeCategoryId', {
template: '{{category-chooser excludeCategoryId=2}}',
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').rowByValue(2).el.length, 0);
+ assert.equal(selectKit('.category-chooser').rowByValue(2).el.length, 0);
});
}
});
@@ -30,12 +30,12 @@ componentTest('with scopedCategoryId', {
template: '{{category-chooser scopedCategoryId=2}}',
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').rowByIndex(0).name(), "feature");
- assert.equal(selectBox('.category-chooser').rowByIndex(1).name(), "spec");
- assert.equal(selectBox('.category-chooser').el.find(".select-box-kit-row").length, 2);
+ assert.equal(selectKit('.category-chooser').rowByIndex(0).name(), "feature");
+ assert.equal(selectKit('.category-chooser').rowByIndex(1).name(), "spec");
+ assert.equal(selectKit('.category-chooser').el.find(".select-kit-row").length, 2);
});
}
});
@@ -48,10 +48,10 @@ componentTest('with allowUncategorized=null', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), "Select a category…");
+ assert.equal(selectKit('.category-chooser').header.name(), "Select a category…");
});
}
});
@@ -64,10 +64,10 @@ componentTest('with allowUncategorized=null rootNone=true', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), "Select a category…");
+ assert.equal(selectKit('.category-chooser').header.name(), "Select a category…");
});
}
});
@@ -81,10 +81,10 @@ componentTest('with disallowed uncategorized, rootNone and rootNoneLabel', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), "Select a category…");
+ assert.equal(selectKit('.category-chooser').header.name(), "Select a category…");
});
}
});
@@ -97,10 +97,10 @@ componentTest('with allowed uncategorized', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), "uncategorized");
+ assert.equal(selectKit('.category-chooser').header.name(), "uncategorized");
});
}
});
@@ -113,10 +113,10 @@ componentTest('with allowed uncategorized and rootNone', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), "(no category)");
+ assert.equal(selectKit('.category-chooser').header.name(), "(no category)");
});
}
});
@@ -130,10 +130,10 @@ componentTest('with allowed uncategorized rootNone and rootNoneLabel', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.category-chooser').header.name(), "root none label");
+ assert.equal(selectKit('.category-chooser').header.name(), "root none label");
});
}
});
diff --git a/test/javascripts/components/categpry-selector-test.js.es6 b/test/javascripts/components/categpry-selector-test.js.es6
new file mode 100644
index 00000000000..8c0925587eb
--- /dev/null
+++ b/test/javascripts/components/categpry-selector-test.js.es6
@@ -0,0 +1,67 @@
+import componentTest from 'helpers/component-test';
+import Category from "discourse/models/category";
+
+moduleForComponent('category-selector', {integration: true});
+
+componentTest('default', {
+ template: '{{category-selector categories=categories}}',
+
+ beforeEach() {
+ this.set('categories', [ Category.findById(2) ]);
+ },
+
+ test(assert) {
+ andThen(() => {
+ assert.propEqual(selectKit().header.name(), 'feature');
+ assert.ok(!exists(".select-kit .select-kit-row[data-value='2']"), "selected categories are not in the list");
+ });
+ }
+});
+
+componentTest('with blacklist', {
+ template: '{{category-selector categories=categories blacklist=blacklist}}',
+
+ beforeEach() {
+ this.set('categories', [ Category.findById(2) ]);
+ this.set('blacklist', [ Category.findById(8) ]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.ok(exists(".select-kit .select-kit-row[data-value='6']"), "not blacklisted categories are in the list");
+ assert.ok(!exists(".select-kit .select-kit-row[data-value='8']"), "blacklisted categories are not in the list");
+ });
+ }
+});
+
+componentTest('interactions', {
+ template: '{{category-selector categories=categories}}',
+
+ beforeEach() {
+ this.set('categories', [
+ Category.findById(2),
+ Category.findById(6)
+ ]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ selectKitSelectRow(8);
+
+ andThen(() => {
+ assert.propEqual(selectKit().header.name(), 'feature,support,hosting', 'it adds the selected category');
+ assert.equal(this.get('categories').length, 3);
+ });
+
+ selectKit().keyboard.backspace();
+ selectKit().keyboard.backspace();
+
+ andThen(() => {
+ assert.propEqual(selectKit().header.name(), 'feature,support', 'it removes the last selected category');
+ assert.equal(this.get('categories').length, 2);
+ });
+ }
+});
diff --git a/test/javascripts/components/combo-box-test.js.es6 b/test/javascripts/components/combo-box-test.js.es6
index c7f50b5da13..bf1534cf7ce 100644
--- a/test/javascripts/components/combo-box-test.js.es6
+++ b/test/javascripts/components/combo-box-test.js.es6
@@ -8,12 +8,12 @@ componentTest('default', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').header.name(), "hello");
- assert.equal(selectBox('.combobox').rowByValue(1).name(), "hello");
- assert.equal(selectBox('.combobox').rowByValue(2).name(), "world");
+ assert.equal(selectKit('.combobox').header.name(), "hello");
+ assert.equal(selectKit('.combobox').rowByValue(1).name(), "hello");
+ assert.equal(selectKit('.combobox').rowByValue(2).name(), "world");
});
}
});
@@ -25,11 +25,11 @@ componentTest('with valueAttribute', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').rowByValue(0).name(), "hello");
- assert.equal(selectBox('.combobox').rowByValue(1).name(), "world");
+ assert.equal(selectKit('.combobox').rowByValue(0).name(), "hello");
+ assert.equal(selectKit('.combobox').rowByValue(1).name(), "world");
});
}
});
@@ -41,11 +41,11 @@ componentTest('with nameProperty', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').rowByValue(0).name(), "hello");
- assert.equal(selectBox('.combobox').rowByValue(1).name(), "world");
+ assert.equal(selectKit('.combobox').rowByValue(0).name(), "hello");
+ assert.equal(selectKit('.combobox').rowByValue(1).name(), "world");
});
}
});
@@ -57,11 +57,11 @@ componentTest('with an array as content', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').rowByValue('evil').name(), "evil");
- assert.equal(selectBox('.combobox').rowByValue('trout').name(), "trout");
+ assert.equal(selectKit('.combobox').rowByValue('evil').name(), "evil");
+ assert.equal(selectKit('.combobox').rowByValue('trout').name(), "trout");
});
}
});
@@ -75,17 +75,17 @@ componentTest('with value and none as a string', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').noneRow.name(), 'none');
- assert.equal(selectBox('.combobox').rowByValue("evil").name(), "evil");
- assert.equal(selectBox('.combobox').rowByValue("trout").name(), "trout");
- assert.equal(selectBox('.combobox').header.name(), 'trout');
+ assert.equal(selectKit('.combobox').noneRow.name(), 'none');
+ assert.equal(selectKit('.combobox').rowByValue("evil").name(), "evil");
+ assert.equal(selectKit('.combobox').rowByValue("trout").name(), "trout");
+ assert.equal(selectKit('.combobox').header.name(), 'trout');
assert.equal(this.get('value'), 'trout');
});
- selectBoxKitSelectRow('__none__', {selector: '.combobox' });
+ selectKitSelectRow('__none__', {selector: '.combobox' });
andThen(() => {
assert.equal(this.get('value'), null);
@@ -102,17 +102,17 @@ componentTest('with value and none as an object', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').noneRow.name(), 'none');
- assert.equal(selectBox('.combobox').rowByValue("evil").name(), "evil");
- assert.equal(selectBox('.combobox').rowByValue("trout").name(), "trout");
- assert.equal(selectBox('.combobox').header.name(), 'evil');
+ assert.equal(selectKit('.combobox').noneRow.name(), 'none');
+ assert.equal(selectKit('.combobox').rowByValue("evil").name(), "evil");
+ assert.equal(selectKit('.combobox').rowByValue("trout").name(), "trout");
+ assert.equal(selectKit('.combobox').header.name(), 'evil');
assert.equal(this.get('value'), 'evil');
});
- selectBoxKitSelectNoneRow({ selector: '.combobox' });
+ selectKitSelectNoneRow({ selector: '.combobox' });
andThen(() => {
assert.equal(this.get('value'), null);
@@ -130,10 +130,10 @@ componentTest('with no value and none as an object', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').header.name(), 'none');
+ assert.equal(selectKit('.combobox').header.name(), 'none');
});
}
});
@@ -148,10 +148,10 @@ componentTest('with no value and none string', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').header.name(), 'none');
+ assert.equal(selectKit('.combobox').header.name(), 'none');
});
}
});
@@ -164,10 +164,10 @@ componentTest('with no value and no none', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').header.name(), 'evil', 'it sets the first row as value');
+ assert.equal(selectKit('.combobox').header.name(), 'evil', 'it sets the first row as value');
});
}
});
@@ -182,17 +182,17 @@ componentTest('with no value and no none', {
// test(assert) {
// ();
//
-// andThen(() => assert.equal(find(".select-box-kit-filter-input").length, 1, "it has a search input"));
+// andThen(() => assert.equal(find(".filter-input").length, 1, "it has a search input"));
//
-// selectBoxKitFillInFilter("regis");
+// selectKitFillInFilter("regis");
//
-// andThen(() => assert.equal(selectBox().rows.length, 1, "it filters results"));
+// andThen(() => assert.equal(selectKit().rows.length, 1, "it filters results"));
//
-// selectBoxKitFillInFilter("");
+// selectKitFillInFilter("");
//
// andThen(() => {
// assert.equal(
-// selectBox().rows.length, 2,
+// selectKit().rows.length, 2,
// "it returns to original content when filter is empty"
// );
// });
@@ -209,17 +209,17 @@ componentTest('with no value and no none', {
// test(assert) {
// ();
//
-// selectBoxKitFillInFilter("rob");
+// selectKitFillInFilter("rob");
//
-// andThen(() => assert.equal(selectBox().rows.length, 1) );
+// andThen(() => assert.equal(selectKit().rows.length, 1) );
//
-// collapseSelectBoxKit();
+// collapseSelectKit();
//
-// andThen(() => assert.notOk(selectBox().isExpanded) );
+// andThen(() => assert.notOk(selectKit().isExpanded) );
//
// ();
//
-// andThen(() => assert.equal(selectBox().rows.length, 1) );
+// andThen(() => assert.equal(selectKit().rows.length, 1) );
// }
// });
@@ -232,10 +232,10 @@ componentTest('with empty string as value', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox('.combobox').header.name(), 'evil', 'it sets the first row as value');
+ assert.equal(selectKit('.combobox').header.name(), 'evil', 'it sets the first row as value');
});
}
});
diff --git a/test/javascripts/components/d-button-test.js.es6 b/test/javascripts/components/d-button-test.js.es6
index d283da4f21c..e40d47fe851 100644
--- a/test/javascripts/components/d-button-test.js.es6
+++ b/test/javascripts/components/d-button-test.js.es6
@@ -6,7 +6,7 @@ componentTest('icon only button', {
test(assert) {
assert.ok(this.$('button.btn.btn-icon.no-text').length, 'it has all the classes');
- assert.ok(this.$('button .d-icon.d-icon-plus').length, 'it has the icon');
+ assert.ok(this.$('button .d-icon.d-plus').length, 'it has the icon');
assert.equal(this.$('button').attr('tabindex'), "3", 'it has the tabindex');
}
});
@@ -16,7 +16,7 @@ componentTest('icon and text button', {
test(assert) {
assert.ok(this.$('button.btn.btn-icon-text').length, 'it has all the classes');
- assert.ok(this.$('button .d-icon.d-icon-plus').length, 'it has the icon');
+ assert.ok(this.$('button .d-icon.d-plus').length, 'it has the icon');
assert.ok(this.$('button span.d-button-label').length, 'it has the label');
}
});
diff --git a/test/javascripts/components/list-setting-test.js.es6 b/test/javascripts/components/list-setting-test.js.es6
index c3dd271fb1b..184d86a38d8 100644
--- a/test/javascripts/components/list-setting-test.js.es6
+++ b/test/javascripts/components/list-setting-test.js.es6
@@ -11,10 +11,26 @@ componentTest('default', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.propEqual(selectBox().header.name(), 'bold,italic');
+ assert.propEqual(selectKit().header.name(), 'bold,italic');
+ });
+ }
+});
+
+componentTest('with emptry string as value', {
+ template: '{{list-setting settingValue=settingValue}}',
+
+ beforeEach() {
+ this.set('settingValue', '');
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().header.el.find(".selected-name").length, 0);
});
}
});
@@ -27,10 +43,10 @@ componentTest('with only setting value', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.propEqual(selectBox().header.name(), 'bold,italic');
+ assert.propEqual(selectKit().header.name(), 'bold,italic');
});
}
});
@@ -44,28 +60,28 @@ componentTest('interactions', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
- selectBoxKitSelectRow('underline');
+ selectKitSelectRow('underline');
andThen(() => {
- assert.propEqual(selectBox().header.name(), 'bold,italic,underline');
+ assert.propEqual(selectKit().header.name(), 'bold,italic,underline');
});
- selectBoxKitFillInFilter('strike');
+ selectKitFillInFilter('strike');
andThen(() => {
- assert.equal(selectBox().highlightedRow.name(), 'strike');
+ assert.equal(selectKit().highlightedRow.name(), 'strike');
});
- selectBox().keyboard.enter();
+ selectKit().keyboard.enter();
andThen(() => {
- assert.propEqual(selectBox().header.name(), 'bold,italic,underline,strike');
+ assert.propEqual(selectKit().header.name(), 'bold,italic,underline,strike');
});
- selectBox().keyboard.backspace();
- selectBox().keyboard.backspace();
+ selectKit().keyboard.backspace();
+ selectKit().keyboard.backspace();
andThen(() => {
assert.equal(this.get('choices').length, 3, 'it removes the created content from original list');
diff --git a/test/javascripts/components/multi-combo-box-test.js.es6 b/test/javascripts/components/multi-combo-box-test.js.es6
deleted file mode 100644
index 81f8b209e70..00000000000
--- a/test/javascripts/components/multi-combo-box-test.js.es6
+++ /dev/null
@@ -1,109 +0,0 @@
-import componentTest from 'helpers/component-test';
-moduleForComponent('multi-combo-box', {integration: true});
-
-componentTest('with objects and values', {
- template: '{{multi-combo-box content=items value=value}}',
-
- beforeEach() {
- this.set('items', [{id: 1, name: 'hello'}, {id: 2, name: 'world'}]);
- this.set('value', [1, 2]);
- },
-
- test(assert) {
- andThen(() => {
- assert.propEqual(selectBox().header.name(), 'hello,world');
- });
- }
-});
-
-componentTest('interactions', {
- template: '{{multi-combo-box none=none content=items value=value}}',
-
- beforeEach() {
- I18n.translations[I18n.locale].js.test = {none: 'none'};
- this.set('items', [{id: 1, name: 'regis'}, {id: 2, name: 'sam'}, {id: 3, name: 'robin'}]);
- this.set('value', [1, 2]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- assert.equal(selectBox().highlightedRow.name(), 'robin', 'it highlights the first content row');
- });
-
- this.set('none', 'test.none');
-
- andThen(() => {
- assert.equal(selectBox().noneRow.el.length, 1);
- assert.equal(selectBox().highlightedRow.name(), 'robin', 'it highlights the first content row');
- });
-
- selectBoxKitSelectRow(3);
-
- andThen(() => {
- assert.equal(selectBox().highlightedRow.name(), 'none', 'it highlights none row if no content');
- });
-
- selectBoxKitFillInFilter('joffrey');
-
- andThen(() => {
- assert.equal(selectBox().highlightedRow.name(), 'joffrey', 'it highlights create row when filling filter');
- });
-
- selectBox().keyboard.enter();
-
- andThen(() => {
- assert.equal(selectBox().highlightedRow.name(), 'none', 'it highlights none row after creating content and no content left');
- });
-
- selectBox().keyboard.backspace();
-
- andThen(() => {
- const $lastSelectedName = selectBox().header.el.find('.selected-name').last();
- assert.equal($lastSelectedName.attr('data-name'), 'joffrey');
- assert.ok($lastSelectedName.hasClass('is-highlighted'), 'it highlights the last selected name when using backspace');
- });
-
- selectBox().keyboard.backspace();
-
- andThen(() => {
- const $lastSelectedName = selectBox().header.el.find('.selected-name').last();
- assert.equal($lastSelectedName.attr('data-name'), 'robin', 'it removes the previous highlighted selected content');
- assert.notOk(exists(selectBox().rowByValue('joffrey').el), 'generated content shouldn’t appear in content when removed');
- });
-
- selectBox().keyboard.selectAll();
-
- andThen(() => {
- const $highlightedSelectedNames = selectBox().header.el.find('.selected-name.is-highlighted');
- assert.equal($highlightedSelectedNames.length, 3, 'it highlights each selected name');
- });
-
- selectBox().keyboard.backspace();
-
- andThen(() => {
- const $selectedNames = selectBox().header.el.find('.selected-name');
- assert.equal($selectedNames.length, 0, 'it removed all selected content');
- });
-
- andThen(() => {
- assert.ok(this.$(".select-box-kit").hasClass("is-focused"));
- assert.ok(this.$(".select-box-kit").hasClass("is-expanded"));
- });
-
- selectBox().keyboard.escape();
-
- andThen(() => {
- assert.ok(this.$(".select-box-kit").hasClass("is-focused"));
- assert.notOk(this.$(".select-box-kit").hasClass("is-expanded"));
- });
-
- selectBox().keyboard.escape();
-
- andThen(() => {
- assert.notOk(this.$(".select-box-kit").hasClass("is-focused"));
- assert.notOk(this.$(".select-box-kit").hasClass("is-expanded"));
- });
- }
-});
diff --git a/test/javascripts/components/multi-select-test.js.es6 b/test/javascripts/components/multi-select-test.js.es6
new file mode 100644
index 00000000000..f1c95b17ec2
--- /dev/null
+++ b/test/javascripts/components/multi-select-test.js.es6
@@ -0,0 +1,109 @@
+import componentTest from 'helpers/component-test';
+moduleForComponent('multi-select', {integration: true});
+
+componentTest('with objects and values', {
+ template: '{{multi-select content=items values=values}}',
+
+ beforeEach() {
+ this.set('items', [{id: 1, name: 'hello'}, {id: 2, name: 'world'}]);
+ this.set('values', [1, 2]);
+ },
+
+ test(assert) {
+ andThen(() => {
+ assert.propEqual(selectKit().header.name(), 'hello,world');
+ });
+ }
+});
+
+componentTest('interactions', {
+ template: '{{multi-select none=none content=items values=values}}',
+
+ beforeEach() {
+ I18n.translations[I18n.locale].js.test = {none: 'none'};
+ this.set('items', [{id: 1, name: 'regis'}, {id: 2, name: 'sam'}, {id: 3, name: 'robin'}]);
+ this.set('values', [1, 2]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().highlightedRow.name(), 'robin', 'it highlights the first content row');
+ });
+
+ this.set('none', 'test.none');
+
+ andThen(() => {
+ assert.equal(selectKit().noneRow.el.length, 1);
+ assert.equal(selectKit().highlightedRow.name(), 'robin', 'it highlights the first content row');
+ });
+
+ selectKitSelectRow(3);
+
+ andThen(() => {
+ assert.equal(selectKit().highlightedRow.name(), 'none', 'it highlights none row if no content');
+ });
+
+ selectKitFillInFilter('joffrey');
+
+ andThen(() => {
+ assert.equal(selectKit().highlightedRow.name(), 'joffrey', 'it highlights create row when filling filter');
+ });
+
+ selectKit().keyboard.enter();
+
+ andThen(() => {
+ assert.equal(selectKit().highlightedRow.name(), 'none', 'it highlights none row after creating content and no content left');
+ });
+
+ selectKit().keyboard.backspace();
+
+ andThen(() => {
+ const $lastSelectedName = selectKit().header.el.find('.selected-name').last();
+ assert.equal($lastSelectedName.attr('data-name'), 'joffrey');
+ assert.ok($lastSelectedName.hasClass('is-highlighted'), 'it highlights the last selected name when using backspace');
+ });
+
+ selectKit().keyboard.backspace();
+
+ andThen(() => {
+ const $lastSelectedName = selectKit().header.el.find('.selected-name').last();
+ assert.equal($lastSelectedName.attr('data-name'), 'robin', 'it removes the previous highlighted selected content');
+ assert.notOk(exists(selectKit().rowByValue('joffrey').el), 'generated content shouldn’t appear in content when removed');
+ });
+
+ selectKit().keyboard.selectAll();
+
+ andThen(() => {
+ const $highlightedSelectedNames = selectKit().header.el.find('.selected-name.is-highlighted');
+ assert.equal($highlightedSelectedNames.length, 3, 'it highlights each selected name');
+ });
+
+ selectKit().keyboard.backspace();
+
+ andThen(() => {
+ const $selectedNames = selectKit().header.el.find('.selected-name');
+ assert.equal($selectedNames.length, 0, 'it removed all selected content');
+ });
+
+ andThen(() => {
+ assert.ok(this.$(".select-kit").hasClass("is-focused"));
+ assert.ok(this.$(".select-kit").hasClass("is-expanded"));
+ });
+
+ selectKit().keyboard.escape();
+
+ andThen(() => {
+ assert.ok(this.$(".select-kit").hasClass("is-focused"));
+ assert.notOk(this.$(".select-kit").hasClass("is-expanded"));
+ });
+
+ selectKit().keyboard.escape();
+
+ andThen(() => {
+ assert.notOk(this.$(".select-kit").hasClass("is-focused"));
+ assert.notOk(this.$(".select-kit").hasClass("is-expanded"));
+ });
+ }
+});
diff --git a/test/javascripts/components/pinned-button-test.js.es6 b/test/javascripts/components/pinned-button-test.js.es6
deleted file mode 100644
index 154d321a23c..00000000000
--- a/test/javascripts/components/pinned-button-test.js.es6
+++ /dev/null
@@ -1,40 +0,0 @@
-import componentTest from 'helpers/component-test';
-import Topic from 'discourse/models/topic';
-
-const buildTopic = function() {
- return Topic.create({
- id: 1234,
- title: "Qunit Test Topic",
- deleted: false,
- pinned: true
- });
-};
-
-moduleForComponent('pinned-button', { integration: true });
-
-componentTest('updating the content refreshes the list', {
- template: '{{pinned-button topic=topic}}',
-
- beforeEach() {
- this.siteSettings.automatically_unpin_topics = false;
- this.set("topic", buildTopic());
- },
-
- test(assert) {
- andThen(() => assert.notOk(selectBox().isHidden) );
-
- expandSelectBoxKit();
-
- andThen(() => assert.equal(selectBox().selectedRow.name(), "Pinned") );
-
- andThen(() => {
- this.set("topic.pinned", false);
- assert.equal(selectBox().selectedRow.name(), "Unpinned");
- });
-
- andThen(() => {
- this.set("topic.deleted", true);
- assert.ok(find(".pinned-button").hasClass("is-hidden"), "it hides the button when topic is deleted");
- });
- }
-});
diff --git a/test/javascripts/components/pinned-options-test.js.es6 b/test/javascripts/components/pinned-options-test.js.es6
new file mode 100644
index 00000000000..3808b63dca9
--- /dev/null
+++ b/test/javascripts/components/pinned-options-test.js.es6
@@ -0,0 +1,35 @@
+import componentTest from 'helpers/component-test';
+import Topic from 'discourse/models/topic';
+
+const buildTopic = function() {
+ return Topic.create({
+ id: 1234,
+ title: "Qunit Test Topic",
+ deleted: false,
+ pinned: true
+ });
+};
+
+moduleForComponent('pinned-options', { integration: true });
+
+componentTest('updating the content refreshes the list', {
+ template: '{{pinned-options value=pinned topic=topic}}',
+
+ beforeEach() {
+ this.siteSettings.automatically_unpin_topics = false;
+ this.set("topic", buildTopic());
+ this.set("pinned", true);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => assert.equal(selectKit().header.name(), "Pinned") );
+
+ andThen(() => this.set("pinned", false));
+
+ andThen(() => {
+ assert.equal(selectKit().header.name(), "Unpinned");
+ });
+ }
+});
diff --git a/test/javascripts/components/select-box-kit-test.js.es6 b/test/javascripts/components/select-box-kit-test.js.es6
deleted file mode 100644
index 904684cd8b7..00000000000
--- a/test/javascripts/components/select-box-kit-test.js.es6
+++ /dev/null
@@ -1,288 +0,0 @@
-import componentTest from 'helpers/component-test';
-
-moduleForComponent('select-box-kit', { integration: true });
-
-componentTest('updating the content refreshes the list', {
- template: '{{select-box-kit value=1 content=content}}',
-
- beforeEach() {
- this.set("content", [{ id: 1, name: "robin" }]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- assert.equal(selectBox().rowByValue(1).name(), "robin");
- this.set("content", [{ id: 1, name: "regis" }]);
- assert.equal(selectBox().rowByValue(1).name(), "regis");
- });
- }
-});
-
-componentTest('accepts a value by reference', {
- template: '{{select-box-kit value=value content=content}}',
-
- beforeEach() {
- this.set("value", 1);
- this.set("content", [{ id: 1, name: "robin" }, { id: 2, name: "regis" }]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- assert.equal(
- selectBox().selectedRow.name(), "robin",
- "it highlights the row corresponding to the value"
- );
- });
-
- selectBoxKitSelectRow(1);
-
- andThen(() => {
- assert.equal(this.get("value"), 1, "it mutates the value");
- });
- }
-});
-
-componentTest('no default icon', {
- template: '{{select-box-kit}}',
-
- test(assert) {
- assert.equal(selectBox().header.icon().length, 0, "it doesn’t have an icon if not specified");
- }
-});
-
-componentTest('default search icon', {
- template: '{{select-box-kit filterable=true}}',
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- assert.ok(exists(selectBox().filter.icon), "it has a the correct icon");
- });
- }
-});
-
-componentTest('with no search icon', {
- template: '{{select-box-kit filterable=true filterIcon=null}}',
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- assert.equal(selectBox().filter.icon().length, 0, "it has no icon");
- });
- }
-});
-
-componentTest('custom search icon', {
- template: '{{select-box-kit filterable=true filterIcon="shower"}}',
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- assert.ok(selectBox().filter.icon().hasClass("d-icon-shower"), "it has a the correct icon");
- });
- }
-});
-
-componentTest('select-box is expandable', {
- template: '{{select-box-kit}}',
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => assert.ok(selectBox().isExpanded) );
-
- collapseSelectBoxKit();
-
- andThen(() => assert.notOk(selectBox().isExpanded) );
- }
-});
-
-componentTest('accepts custom value/name keys', {
- template: '{{select-box-kit value=value nameProperty="item" content=content valueAttribute="identifier"}}',
-
- beforeEach() {
- this.set("value", 1);
- this.set("content", [{ identifier: 1, item: "robin" }]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- assert.equal(selectBox().selectedRow.name(), "robin");
- });
- }
-});
-
-componentTest('doesn’t render collection content before first expand', {
- template: '{{select-box-kit value=1 content=content}}',
-
- beforeEach() {
- this.set("content", [{ value: 1, name: "robin" }]);
- },
-
- test(assert) {
- assert.notOk(exists(find(".select-box-kit-collection")));
-
- expandSelectBoxKit();
-
- andThen(() => {
- assert.ok(exists(find(".select-box-kit-collection")));
- });
- }
-});
-
-componentTest('supports options to limit size', {
- template: '{{select-box-kit collectionHeight=20 content=content}}',
-
- beforeEach() {
- this.set("content", ["robin", "régis"]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => {
- const height = find(".select-box-kit-collection").height();
- assert.equal(parseInt(height, 10), 20, "it limits the height");
- });
- }
-});
-
-componentTest('dynamic headerText', {
- template: '{{select-box-kit value=1 content=content}}',
-
- beforeEach() {
- this.set("content", [{ id: 1, name: "robin" }, { id: 2, name: "regis" }]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => assert.equal(selectBox().header.name(), "robin") );
-
- selectBoxKitSelectRow(2);
-
- andThen(() => {
- assert.equal(selectBox().header.name(), "regis", "it changes header text");
- });
- }
-});
-
-componentTest('supports custom row template', {
- template: '{{select-box-kit content=content templateForRow=templateForRow}}',
-
- beforeEach() {
- this.set("content", [{ id: 1, name: "robin" }]);
- this.set("templateForRow", rowComponent => {
- return `${rowComponent.get("content.name")} `;
- });
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => assert.equal(selectBox().rowByValue(1).el.html().trim(), "robin ") );
- }
-});
-
-componentTest('supports converting select value to integer', {
- template: '{{select-box-kit value=value content=content castInteger=true}}',
-
- beforeEach() {
- this.set("value", 2);
- this.set("content", [{ id: "1", name: "robin"}, {id: "2", name: "régis" }]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- andThen(() => assert.equal(selectBox().selectedRow.name(), "régis") );
-
- andThen(() => {
- this.set("value", 3);
- this.set("content", [{ id: "3", name: "jeff" }]);
- });
-
- andThen(() => {
- assert.equal(selectBox().selectedRow.name(), "jeff", "it works with dynamic content");
- });
- }
-});
-
-componentTest('supports keyboard events', {
- template: '{{select-box-kit content=content filterable=true}}',
-
- beforeEach() {
- this.set("content", [{ id: 1, name: "robin" }, { id: 2, name: "regis" }]);
- },
-
- test(assert) {
- expandSelectBoxKit();
-
- selectBox().keyboard.down();
-
- andThen(() => {
- assert.equal(selectBox().highlightedRow.title(), "regis", "the next row is highlighted");
- });
-
- selectBox().keyboard.down();
-
- andThen(() => {
- assert.equal(selectBox().highlightedRow.title(), "robin", "it returns to the first row");
- });
-
- selectBox().keyboard.up();
-
- andThen(() => {
- assert.equal(selectBox().highlightedRow.title(), "regis", "it highlights the last row");
- });
-
- selectBox().keyboard.enter();
-
- andThen(() => {
- assert.equal(selectBox().selectedRow.title(), "regis", "it selects the row when pressing enter");
- assert.notOk(selectBox().isExpanded, "it collapses the select box when selecting a row");
- });
-
- expandSelectBoxKit();
-
- selectBox().keyboard.escape();
-
- andThen(() => {
- assert.notOk(selectBox().isExpanded, "it collapses the select box");
- });
-
- expandSelectBoxKit();
-
- selectBoxKitFillInFilter("regis");
-
- selectBox().keyboard.tab();
-
- andThen(() => {
- assert.notOk(selectBox().isExpanded, "it collapses the select box when selecting a row");
- });
- }
-});
-
-
-componentTest('supports mutating value when no value given', {
- template: '{{select-box-kit value=value content=content}}',
-
- beforeEach() {
- this.set("value", "");
- this.set("content", [{ id: "1", name: "robin"}, {id: "2", name: "régis" }]);
- },
-
- test(assert) {
- andThen(() => {
- assert.equal(this.get("value"), "1");
- });
- }
-});
diff --git a/test/javascripts/components/single-select-test.js.es6 b/test/javascripts/components/single-select-test.js.es6
new file mode 100644
index 00000000000..ca066907625
--- /dev/null
+++ b/test/javascripts/components/single-select-test.js.es6
@@ -0,0 +1,372 @@
+import componentTest from 'helpers/component-test';
+import { withPluginApi } from 'discourse/lib/plugin-api';
+import { clearCallbacks } from 'select-kit/mixins/plugin-api';
+
+moduleForComponent('single-select', { integration: true });
+
+componentTest('updating the content refreshes the list', {
+ template: '{{single-select value=1 content=content}}',
+
+ beforeEach() {
+ this.set("content", [{ id: 1, name: "BEFORE" }]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().rowByValue(1).name(), "BEFORE");
+ });
+
+ andThen(() => {
+ this.set("content", [{ id: 1, name: "AFTER" }]);
+ });
+
+ andThen(() => {
+ assert.equal(selectKit().rowByValue(1).name(), "AFTER");
+ });
+ }
+});
+
+componentTest('accepts a value by reference', {
+ template: '{{single-select value=value content=content}}',
+
+ beforeEach() {
+ this.set("value", 1);
+ this.set("content", [{ id: 1, name: "robin" }, { id: 2, name: "regis" }]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(
+ selectKit().selectedRow.name(), "robin",
+ "it highlights the row corresponding to the value"
+ );
+ });
+
+ selectKitSelectRow(1);
+
+ andThen(() => {
+ assert.equal(this.get("value"), 1, "it mutates the value");
+ });
+ }
+});
+
+componentTest('no default icon', {
+ template: '{{single-select}}',
+
+ test(assert) {
+ assert.equal(selectKit().header.icon().length, 0, "it doesn’t have an icon if not specified");
+ }
+});
+
+componentTest('default search icon', {
+ template: '{{single-select filterable=true}}',
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.ok(exists(selectKit().filter.icon), "it has a the correct icon");
+ });
+ }
+});
+
+componentTest('with no search icon', {
+ template: '{{single-select filterable=true filterIcon=null}}',
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().filter.icon().length, 0, "it has no icon");
+ });
+ }
+});
+
+componentTest('custom search icon', {
+ template: '{{single-select filterable=true filterIcon="shower"}}',
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.ok(selectKit().filter.icon().hasClass("fa-shower"), "it has a the correct icon");
+ });
+ }
+});
+
+componentTest('is expandable', {
+ template: '{{single-select}}',
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => assert.ok(selectKit().isExpanded) );
+
+ collapseSelectKit();
+
+ andThen(() => assert.notOk(selectKit().isExpanded) );
+ }
+});
+
+componentTest('accepts custom value/name keys', {
+ template: '{{single-select value=value nameProperty="item" content=content valueAttribute="identifier"}}',
+
+ beforeEach() {
+ this.set("value", 1);
+ this.set("content", [{ identifier: 1, item: "robin" }]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().selectedRow.name(), "robin");
+ });
+ }
+});
+
+componentTest('doesn’t render collection content before first expand', {
+ template: '{{single-select value=1 content=content}}',
+
+ beforeEach() {
+ this.set("content", [{ value: 1, name: "robin" }]);
+ },
+
+ test(assert) {
+ assert.notOk(exists(find(".select-kit-collection")));
+
+ expandSelectKit();
+
+ andThen(() => {
+ assert.ok(exists(find(".select-kit-collection")));
+ });
+ }
+});
+
+componentTest('supports options to limit size', {
+ template: '{{single-select collectionHeight=20 content=content}}',
+
+ beforeEach() {
+ this.set("content", ["robin", "régis"]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ const height = find(".select-kit-collection").height();
+ assert.equal(parseInt(height, 10), 20, "it limits the height");
+ });
+ }
+});
+
+componentTest('dynamic headerText', {
+ template: '{{single-select value=1 content=content}}',
+
+ beforeEach() {
+ this.set("content", [{ id: 1, name: "robin" }, { id: 2, name: "regis" }]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().header.name(), "robin");
+ });
+
+ selectKitSelectRow(2);
+
+ andThen(() => {
+ assert.equal(selectKit().header.name(), "regis", "it changes header text");
+ });
+ }
+});
+
+componentTest('supports custom row template', {
+ template: '{{single-select content=content templateForRow=templateForRow}}',
+
+ beforeEach() {
+ this.set("content", [{ id: 1, name: "robin" }]);
+ this.set("templateForRow", rowComponent => {
+ return `${rowComponent.get("computedContent.name")} `;
+ });
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => assert.equal(selectKit().rowByValue(1).el.html().trim(), "robin ") );
+ }
+});
+
+componentTest('supports converting select value to integer', {
+ template: '{{single-select value=value content=content castInteger=true}}',
+
+ beforeEach() {
+ this.set("value", 2);
+ this.set("content", [{ id: "1", name: "robin"}, {id: "2", name: "régis" }]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => assert.equal(selectKit().selectedRow.name(), "régis") );
+
+ andThen(() => {
+ this.set("value", 3);
+ this.set("content", [{ id: "3", name: "jeff" }]);
+ });
+
+ andThen(() => {
+ assert.equal(selectKit().selectedRow.name(), "jeff", "it works with dynamic content");
+ });
+ }
+});
+
+componentTest('supports keyboard events', {
+ template: '{{single-select content=content filterable=true}}',
+
+ beforeEach() {
+ this.set("content", [{ id: 1, name: "robin" }, { id: 2, name: "regis" }]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ selectKit().keyboard.down();
+
+ andThen(() => {
+ assert.equal(selectKit().highlightedRow.title(), "regis", "the next row is highlighted");
+ });
+
+ selectKit().keyboard.down();
+
+ andThen(() => {
+ assert.equal(selectKit().highlightedRow.title(), "robin", "it returns to the first row");
+ });
+
+ selectKit().keyboard.up();
+
+ andThen(() => {
+ assert.equal(selectKit().highlightedRow.title(), "regis", "it highlights the last row");
+ });
+
+ selectKit().keyboard.enter();
+
+ andThen(() => {
+ assert.equal(selectKit().selectedRow.title(), "regis", "it selects the row when pressing enter");
+ assert.notOk(selectKit().isExpanded, "it collapses the select box when selecting a row");
+ });
+
+ expandSelectKit();
+
+ selectKit().keyboard.escape();
+
+ andThen(() => {
+ assert.notOk(selectKit().isExpanded, "it collapses the select box");
+ });
+
+ expandSelectKit();
+
+ selectKitFillInFilter("regis");
+
+ selectKit().keyboard.tab();
+
+ andThen(() => {
+ assert.notOk(selectKit().isExpanded, "it collapses the select box when selecting a row");
+ });
+ }
+});
+
+
+componentTest('supports mutating value when no value given', {
+ template: '{{single-select value=value content=content}}',
+
+ beforeEach() {
+ this.set("value", "");
+ this.set("content", [{ id: "1", name: "robin"}, {id: "2", name: "régis" }]);
+ },
+
+ test(assert) {
+ andThen(() => {
+ assert.equal(this.get("value"), "1");
+ });
+ }
+});
+
+componentTest('support appending content through plugin api', {
+ template: '{{single-select content=content}}',
+
+ beforeEach() {
+ withPluginApi('0.8.11', api => {
+ api.modifySelectKit("select-kit")
+ .appendContent([{ id: "2", name: "regis"}]);
+ });
+
+ this.set("content", [{ id: "1", name: "robin"}]);
+ },
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().rows.length, 2);
+ assert.equal(selectKit().rows.eq(1).data("name"), "regis");
+ });
+
+ clearCallbacks();
+ }
+});
+
+componentTest('support modifying content through plugin api', {
+ template: '{{single-select content=content}}',
+
+ beforeEach() {
+ withPluginApi('0.8.11', api => {
+ api.modifySelectKit("select-kit")
+ .modifyContent((existingContent) => {
+ existingContent.splice(1, 0, { id: "2", name: "sam" });
+ return existingContent;
+ });
+ });
+
+ this.set("content", [{ id: "1", name: "robin"}, { id: "3", name: "regis"}]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().rows.length, 3);
+ assert.equal(selectKit().rows.eq(1).data("name"), "sam");
+ });
+
+ clearCallbacks();
+ }
+});
+
+componentTest('support prepending content through plugin api', {
+ template: '{{single-select content=content}}',
+
+ beforeEach() {
+ withPluginApi('0.8.11', api => {
+ api.modifySelectKit("select-kit")
+ .prependContent([{ id: "2", name: "regis"}]);
+ });
+
+ this.set("content", [{ id: "1", name: "robin"}]);
+ },
+
+ test(assert) {
+ expandSelectKit();
+
+ andThen(() => {
+ assert.equal(selectKit().rows.length, 2);
+ assert.equal(selectKit().rows.eq(0).data("name"), "regis");
+ });
+
+ clearCallbacks();
+ }
+});
diff --git a/test/javascripts/components/topic-footer-mobile-dropdown-test.js.es6 b/test/javascripts/components/topic-footer-mobile-dropdown-test.js.es6
index 899bff4545a..9a5534c3cb4 100644
--- a/test/javascripts/components/topic-footer-mobile-dropdown-test.js.es6
+++ b/test/javascripts/components/topic-footer-mobile-dropdown-test.js.es6
@@ -17,16 +17,16 @@ componentTest('default', {
},
test(assert) {
- expandSelectBoxKit();
+ expandSelectKit();
andThen(() => {
- assert.equal(selectBox().header.name(), "Topic Controls");
- assert.equal(selectBox().rowByIndex(0).name(), "Bookmark");
- assert.equal(selectBox().rowByIndex(1).name(), "Share");
- assert.equal(selectBox().selectedRow.el.length, 0, "it doesn’t preselect first row");
+ assert.equal(selectKit().header.name(), "Topic Controls");
+ assert.equal(selectKit().rowByIndex(0).name(), "Bookmark");
+ assert.equal(selectKit().rowByIndex(1).name(), "Share");
+ assert.equal(selectKit().selectedRow.el.length, 0, "it doesn’t preselect first row");
});
- selectBoxKitSelectRow("share");
+ selectKitSelectRow("share");
andThen(() => {
assert.equal(this.get("value"), null, "it resets the value");
diff --git a/test/javascripts/components/topic-notifications-button-test.js.es6 b/test/javascripts/components/topic-notifications-button-test.js.es6
index 67fd3ad70ec..0d41471e31a 100644
--- a/test/javascripts/components/topic-notifications-button-test.js.es6
+++ b/test/javascripts/components/topic-notifications-button-test.js.es6
@@ -1,34 +1,34 @@
import componentTest from 'helpers/component-test';
import Topic from 'discourse/models/topic';
-const buildTopic = function() {
+const buildTopic = function(level) {
return Topic.create({
id: 4563,
title: "Qunit Test Topic",
details: {
- notification_level: 1
+ notification_level: level
}
});
};
-
moduleForComponent('topic-notifications-button', { integration: true });
componentTest('the header has a localized title', {
- template: '{{topic-notifications-button topic=topic}}',
+ template: '{{topic-notifications-button notificationLevel=topic.details.notification_level topic=topic}}',
beforeEach() {
- this.set("topic", buildTopic());
+ this.set("topic", buildTopic(1));
},
test(assert) {
andThen(() => {
- assert.equal(selectBox().header.name(), "Normal", "it has the correct title");
+ assert.equal(selectKit().header.name(), "Normal", "it has the correct title");
});
+ this.set("topic", buildTopic(2));
+
andThen(() => {
- this.set("topic.details.notification_level", 2);
- assert.equal(selectBox().header.name(), "Tracking", "it correctly changes the title");
+ assert.equal(selectKit().header.name(), "Tracking", "it correctly changes the title");
});
}
});
diff --git a/test/javascripts/helpers/select-box-kit-helper.js b/test/javascripts/helpers/select-box-kit-helper.js
deleted file mode 100644
index 6388cff899d..00000000000
--- a/test/javascripts/helpers/select-box-kit-helper.js
+++ /dev/null
@@ -1,146 +0,0 @@
-function checkSelectBoxIsNotExpanded(selectBoxSelector) {
- if (find(selectBoxSelector).hasClass('is-expanded')) {
- throw 'You expected select-box to be collapsed but it is expanded.';
- }
-}
-
-function checkSelectBoxIsNotCollapsed(selectBoxSelector) {
- if (!find(selectBoxSelector).hasClass('is-expanded')) {
- throw 'You expected select-box to be expanded but it is collapsed.';
- }
-}
-
-Ember.Test.registerAsyncHelper('expandSelectBoxKit', function(app, selectBoxSelector) {
- selectBoxSelector = selectBoxSelector || '.select-box-kit';
-
- checkSelectBoxIsNotExpanded(selectBoxSelector);
-
- click(selectBoxSelector + ' .select-box-kit-header');
-});
-
-Ember.Test.registerAsyncHelper('collapseSelectBoxKit', function(app, selectBoxSelector) {
- selectBoxSelector = selectBoxSelector || '.select-box-kit';
-
- checkSelectBoxIsNotCollapsed(selectBoxSelector);
-
- click(selectBoxSelector + ' .select-box-kit-header');
-});
-
-Ember.Test.registerAsyncHelper('selectBoxKitSelectRow', function(app, rowValue, options) {
- options = options || {};
- options.selector = options.selector || '.select-box-kit';
-
- checkSelectBoxIsNotCollapsed(options.selector);
-
- click(options.selector + " .select-box-kit-row[data-value='" + rowValue + "']");
-});
-
-Ember.Test.registerAsyncHelper('selectBoxKitSelectNoneRow', function(app, options) {
- options = options || {};
- options.selector = options.selector || '.select-box-kit';
-
- checkSelectBoxIsNotCollapsed(options.selector);
-
- click(options.selector + " .select-box-kit-row.none");
-});
-
-Ember.Test.registerAsyncHelper('selectBoxKitFillInFilter', function(app, filter, options) {
- options = options || {};
- options.selector = options.selector || '.select-box-kit';
-
- checkSelectBoxIsNotCollapsed(options.selector);
-
- var filterQuerySelector = options.selector + ' .select-box-kit-filter-input';
- fillIn(filterQuerySelector, filter);
-});
-
-function selectBox(selector) { // eslint-disable-line no-unused-vars
- selector = selector || '.select-box-kit';
-
- function rowHelper(row) {
- return {
- name: function() { return row.attr('data-name'); },
- icon: function() { return row.find('.d-icon'); },
- title: function() { return row.attr('title'); },
- value: function() { return row.attr('data-value'); },
- el: row
- };
- }
-
- function headerHelper(header) {
- return {
- name: function() {
- return header.attr('data-name');
- },
- icon: function() { return header.find('.icon'); },
- title: function() { return header.attr('title'); },
- el: header
- };
- }
-
- function filterHelper(filter) {
- return {
- icon: function() { return filter.find('.d-icon'); },
- exists: function() { return exists(filter); },
- el: filter
- };
- }
-
- function keyboardHelper() {
- function createEvent(target, keyCode, options) {
- target = target || ".select-box-kit-filter-input";
- selector = find(selector).find(target);
-
- andThen(function() {
- var event = jQuery.Event(options.type);
- event.keyCode = keyCode;
- if (options && options.metaKey === true) { event.metaKey = true; }
- find(selector).trigger(event);
- });
- }
-
- return {
- down: function(target) { createEvent(target, 40, {type: 'keydown'}); },
- up: function(target) { createEvent(target, 38, {type: 'keydown'}); },
- escape: function(target) { createEvent(target, 27, {type: 'keydown'}); },
- enter: function(target) { createEvent(target, 13, {type: 'keypress'}); },
- tab: function(target) { createEvent(target, 9, {type: 'keydown'}); },
- backspace: function(target) { createEvent(target, 8, {type: 'keydown'}); },
- selectAll: function(target) { createEvent(target, 65, {metaKey: true, type: 'keydown'}); },
- };
- }
-
- return {
- keyboard: keyboardHelper(),
-
- isExpanded: find(selector).hasClass('is-expanded'),
-
- isHidden: find(selector).hasClass('is-hidden'),
-
- header: headerHelper(find(selector).find('.select-box-kit-header')),
-
- filter: filterHelper(find(selector).find('.select-box-kit-filter')),
-
- rows: find(selector).find('.select-box-kit-row'),
-
- rowByValue: function(value) {
- return rowHelper(find(selector).find('.select-box-kit-row[data-value="' + value + '"]'));
- },
-
- rowByName: function(name) {
- return rowHelper(find(selector).find('.select-box-kit-row[data-name="' + name + '"]'));
- },
-
- rowByIndex: function(index) {
- return rowHelper(find(selector).find('.select-box-kit-row:eq(' + index + ')'));
- },
-
- el: find(selector),
-
- noneRow: rowHelper(find(selector).find('.select-box-kit-row.none')),
-
- selectedRow: rowHelper(find(selector).find('.select-box-kit-row.is-selected')),
-
- highlightedRow: rowHelper(find(selector).find('.select-box-kit-row.is-highlighted'))
- };
-}
diff --git a/test/javascripts/helpers/select-kit-helper.js b/test/javascripts/helpers/select-kit-helper.js
new file mode 100644
index 00000000000..80c63736063
--- /dev/null
+++ b/test/javascripts/helpers/select-kit-helper.js
@@ -0,0 +1,149 @@
+function checkSelectKitIsNotExpanded(selector) {
+ if (find(selector).hasClass('is-expanded')) {
+ throw 'You expected select-kit to be collapsed but it is expanded.';
+ }
+}
+
+function checkSelectKitIsNotCollapsed(selector) {
+ if (!find(selector).hasClass('is-expanded')) {
+ throw 'You expected select-kit to be expanded but it is collapsed.';
+ }
+}
+
+Ember.Test.registerAsyncHelper('expandSelectKit', function(app, selector) {
+ selector = selector || '.select-kit';
+
+ checkSelectKitIsNotExpanded(selector);
+
+ click(selector + ' .select-kit-header');
+});
+
+Ember.Test.registerAsyncHelper('collapseSelectKit', function(app, selector) {
+ selector = selector || '.select-kit';
+
+ checkSelectKitIsNotCollapsed(selector);
+
+ click(selector + ' .select-kit-header');
+});
+
+Ember.Test.registerAsyncHelper('selectKitSelectRow', function(app, rowValue, options) {
+ options = options || {};
+ options.selector = options.selector || '.select-kit';
+
+ checkSelectKitIsNotCollapsed(options.selector);
+
+ click(options.selector + " .select-kit-row[data-value='" + rowValue + "']");
+});
+
+Ember.Test.registerAsyncHelper('selectKitSelectNoneRow', function(app, options) {
+ options = options || {};
+ options.selector = options.selector || '.select-kit';
+
+ checkSelectKitIsNotCollapsed(options.selector);
+
+ click(options.selector + " .select-kit-row.none");
+});
+
+Ember.Test.registerAsyncHelper('selectKitFillInFilter', function(app, filter, options) {
+ options = options || {};
+ options.selector = options.selector || '.select-kit';
+
+ checkSelectKitIsNotCollapsed(options.selector);
+
+ var filterQuerySelector = options.selector + ' .filter-input';
+ fillIn(filterQuerySelector, filter);
+
+});
+
+function selectKit(selector) { // eslint-disable-line no-unused-vars
+ selector = selector || '.select-kit';
+
+ function rowHelper(row) {
+ return {
+ name: function() { return row.attr('data-name'); },
+ icon: function() { return row.find('.d-icon'); },
+ title: function() { return row.attr('title'); },
+ value: function() { return row.attr('data-value'); },
+ el: row
+ };
+ }
+
+ function headerHelper(header) {
+ return {
+ name: function() {
+ return header.attr('data-name');
+ },
+ icon: function() { return header.find('.icon'); },
+ title: function() { return header.attr('title'); },
+ el: header
+ };
+ }
+
+ function filterHelper(filter) {
+ return {
+ icon: function() { return filter.find('.d-icon'); },
+ exists: function() { return exists(filter); },
+ el: filter
+ };
+ }
+
+ function keyboardHelper() {
+ function createEvent(target, keyCode, options) {
+ target = target || ".filter-input";
+ selector = find(selector).find(target);
+ options = options || {};
+
+ andThen(function() {
+ var type = options.type || 'keydown';
+ var event = jQuery.Event(type);
+ event.keyCode = keyCode;
+ if (options && options.metaKey === true) { event.metaKey = true; }
+ find(selector).trigger(event);
+ });
+ }
+
+ return {
+ down: function(target) { createEvent(target, 40); },
+ up: function(target) { createEvent(target, 38); },
+ escape: function(target) { createEvent(target, 27); },
+ enter: function(target) { createEvent(target, 13); },
+ tab: function(target) { createEvent(target, 9); },
+ backspace: function(target) { createEvent(target, 8); },
+ selectAll: function(target) { createEvent(target, 65, {metaKey: true}); },
+ };
+ }
+
+ return {
+ keyboard: keyboardHelper(),
+
+ isExpanded: find(selector).hasClass('is-expanded'),
+
+ isHidden: find(selector).hasClass('is-hidden'),
+
+ header: headerHelper(find(selector).find('.select-kit-header')),
+
+ filter: filterHelper(find(selector).find('.select-kit-filter')),
+
+ rows: find(selector).find('.select-kit-row'),
+
+ rowByValue: function(value) {
+ return rowHelper(find(selector).find('.select-kit-row[data-value="' + value + '"]'));
+ },
+
+ rowByName: function(name) {
+ return rowHelper(find(selector).find('.select-kit-row[data-name="' + name + '"]'));
+ },
+
+ rowByIndex: function(index) {
+ return rowHelper(find(selector).find('.select-kit-row:eq(' + index + ')'));
+ },
+
+ el: find(selector),
+
+ noneRow: rowHelper(find(selector).find('.select-kit-row.none')),
+
+ selectedRow: rowHelper(find(selector).find('.select-kit-row.is-selected')),
+
+ highlightedRow: rowHelper(find(selector).find('.select-kit-row.is-highlighted'))
+ };
+}
diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js
index df242fa34ed..83716217317 100644
--- a/test/javascripts/test_helper.js
+++ b/test/javascripts/test_helper.js
@@ -32,7 +32,7 @@
//= require sinon-qunit-1.0.0
//= require helpers/assertions
-//= require helpers/select-box-kit-helper
+//= require helpers/select-kit-helper
//= require helpers/qunit-helpers
//= require_tree ./fixtures
diff --git a/test/javascripts/widgets/actions-summary-test.js.es6 b/test/javascripts/widgets/actions-summary-test.js.es6
index f4eb8b78821..2115d79cf78 100644
--- a/test/javascripts/widgets/actions-summary-test.js.es6
+++ b/test/javascripts/widgets/actions-summary-test.js.es6
@@ -74,7 +74,7 @@ widgetTest('post deleted', {
});
},
test(assert) {
- assert.ok(this.$('.post-action .d-icon-trash-o').length === 1, 'it has the deleted icon');
+ assert.ok(this.$('.post-action .d-trash-o').length === 1, 'it has the deleted icon');
assert.ok(this.$('.avatar[title=eviltrout]').length === 1, 'it has the deleted by avatar');
}
});
diff --git a/test/javascripts/widgets/button-test.js.es6 b/test/javascripts/widgets/button-test.js.es6
index 96bd4b245c7..afe75224448 100644
--- a/test/javascripts/widgets/button-test.js.es6
+++ b/test/javascripts/widgets/button-test.js.es6
@@ -11,7 +11,7 @@ widgetTest('icon only button', {
test(assert) {
assert.ok(this.$('button.btn.btn-icon.no-text').length, 'it has all the classes');
- assert.ok(this.$('button .d-icon.d-icon-smile-o').length, 'it has the icon');
+ assert.ok(this.$('button .d-icon.d-smile-o').length, 'it has the icon');
}
});
@@ -24,7 +24,7 @@ widgetTest('icon and text button', {
test(assert) {
assert.ok(this.$('button.btn.btn-icon-text').length, 'it has all the classes');
- assert.ok(this.$('button .d-icon.d-icon-plus').length, 'it has the icon');
+ assert.ok(this.$('button .d-icon.d-plus').length, 'it has the icon');
assert.ok(this.$('button span.d-button-label').length, 'it has the label');
}
});
diff --git a/test/javascripts/widgets/home-logo-test.js.es6 b/test/javascripts/widgets/home-logo-test.js.es6
index 96bd889f50f..80bec5f4bef 100644
--- a/test/javascripts/widgets/home-logo-test.js.es6
+++ b/test/javascripts/widgets/home-logo-test.js.es6
@@ -66,7 +66,7 @@ widgetTest('no logo - minimized', {
},
test(assert) {
- assert.ok(this.$('.d-icon-home').length === 1);
+ assert.ok(this.$('.d-home').length === 1);
}
});
diff --git a/test/javascripts/widgets/post-test.js.es6 b/test/javascripts/widgets/post-test.js.es6
index 0296c9dcf3d..89d72fdbcd8 100644
--- a/test/javascripts/widgets/post-test.js.es6
+++ b/test/javascripts/widgets/post-test.js.es6
@@ -436,7 +436,7 @@ widgetTest("reply directly above", {
click('a.reply-to-tab');
andThen(() => {
assert.equal(this.$('section.embedded-posts.top .cooked').length, 1);
- assert.equal(this.$('section.embedded-posts .d-icon-arrow-up').length, 1);
+ assert.equal(this.$('section.embedded-posts .d-arrow-up').length, 1);
});
}
});
@@ -673,7 +673,7 @@ widgetTest("replies - one below, not suppressed", {
click('button.show-replies');
andThen(() => {
assert.equal(this.$('section.embedded-posts.bottom .cooked').length, 1);
- assert.equal(this.$('section.embedded-posts .d-icon-arrow-down').length, 1);
+ assert.equal(this.$('section.embedded-posts .d-arrow-down').length, 1);
});
}
});
@@ -760,7 +760,7 @@ widgetTest("topic map - links", {
click('nav.buttons button');
andThen(() => {
assert.equal(this.$('.map.map-collapsed').length, 0);
- assert.equal(this.$('.topic-map .d-icon-chevron-up').length, 1);
+ assert.equal(this.$('.topic-map .d-chevron-up').length, 1);
assert.equal(this.$('.topic-map-expanded').length, 1);
assert.equal(this.$('.topic-map-expanded .topic-link').length, 5, 'it limits the links displayed');
});
diff --git a/test/javascripts/widgets/poster-name-test.js.es6 b/test/javascripts/widgets/poster-name-test.js.es6
index c8ab8391d7a..f324e043254 100644
--- a/test/javascripts/widgets/poster-name-test.js.es6
+++ b/test/javascripts/widgets/poster-name-test.js.es6
@@ -38,7 +38,7 @@ widgetTest('extra classes and glyphs', {
assert.ok(this.$('span.staff').length);
assert.ok(this.$('span.admin').length);
assert.ok(this.$('span.moderator').length);
- assert.ok(this.$('.d-icon-shield').length);
+ assert.ok(this.$('.d-shield').length);
assert.ok(this.$('span.new-user').length);
assert.ok(this.$('span.fish').length);
}