mirror of
https://github.com/discourse/discourse.git
synced 2025-02-06 19:38:24 +00:00
DEV: Convert sidebar edit navigation modal/categories modal to gjs (#25662)
This commit is contained in:
parent
9a6406d4bb
commit
d1ebca90ff
@ -1,11 +1,22 @@
|
|||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { tracked } from "@glimmer/tracking";
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { Input } from "@ember/component";
|
||||||
|
import { concat, fn, get } from "@ember/helper";
|
||||||
|
import { on } from "@ember/modifier";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import EditNavigationMenuModal from "discourse/components/sidebar/edit-navigation-menu/modal";
|
||||||
|
import borderColor from "discourse/helpers/border-color";
|
||||||
|
import categoryBadge from "discourse/helpers/category-badge";
|
||||||
|
import dirSpan from "discourse/helpers/dir-span";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import Category from "discourse/models/category";
|
import Category from "discourse/models/category";
|
||||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||||
|
import i18n from "discourse-common/helpers/i18n";
|
||||||
import discourseDebounce from "discourse-common/lib/debounce";
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
|
import gt from "truth-helpers/helpers/gt";
|
||||||
|
import includes from "truth-helpers/helpers/includes";
|
||||||
|
import not from "truth-helpers/helpers/not";
|
||||||
|
|
||||||
export default class extends Component {
|
export default class extends Component {
|
||||||
@service currentUser;
|
@service currentUser;
|
||||||
@ -174,4 +185,93 @@ export default class extends Component {
|
|||||||
this.saving = false;
|
this.saving = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<EditNavigationMenuModal
|
||||||
|
@title="sidebar.categories_form_modal.title"
|
||||||
|
@disableSaveButton={{this.saving}}
|
||||||
|
@save={{this.save}}
|
||||||
|
@showResetDefaultsButton={{gt
|
||||||
|
this.siteSettings.default_navigation_menu_categories.length
|
||||||
|
0
|
||||||
|
}}
|
||||||
|
@resetToDefaults={{this.resetToDefaults}}
|
||||||
|
@deselectAll={{this.deselectAll}}
|
||||||
|
@deselectAllText={{i18n "sidebar.categories_form_modal.subtitle.text"}}
|
||||||
|
@inputFilterPlaceholder={{i18n
|
||||||
|
"sidebar.categories_form_modal.filter_placeholder"
|
||||||
|
}}
|
||||||
|
@onFilterInput={{this.onFilterInput}}
|
||||||
|
@resetFilter={{this.resetFilter}}
|
||||||
|
@filterSelected={{this.filterSelected}}
|
||||||
|
@filterUnselected={{this.filterUnselected}}
|
||||||
|
@closeModal={{@closeModal}}
|
||||||
|
class="sidebar__edit-navigation-menu__categories-modal"
|
||||||
|
>
|
||||||
|
<form class="sidebar-categories-form">
|
||||||
|
{{#if (gt this.filteredCategoriesGroupings.length 0)}}
|
||||||
|
{{#each this.filteredCategoriesGroupings as |categories|}}
|
||||||
|
<div
|
||||||
|
class="sidebar-categories-form__row"
|
||||||
|
style={{borderColor (get categories "0.color") "left"}}
|
||||||
|
>
|
||||||
|
|
||||||
|
{{#each categories as |category|}}
|
||||||
|
<div
|
||||||
|
class="sidebar-categories-form__category-row"
|
||||||
|
data-category-id={{category.id}}
|
||||||
|
data-category-level={{category.level}}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="sidebar-categories-form__category-label"
|
||||||
|
for={{concat
|
||||||
|
"sidebar-categories-form__input--"
|
||||||
|
category.id
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="sidebar-categories-form__category-wrapper">
|
||||||
|
<div class="sidebar-categories-form__category-badge">
|
||||||
|
{{categoryBadge category}}
|
||||||
|
</div>
|
||||||
|
{{#unless category.parentCategory}}
|
||||||
|
<div
|
||||||
|
class="sidebar-categories-form__category-description"
|
||||||
|
>
|
||||||
|
{{dirSpan
|
||||||
|
category.description_excerpt
|
||||||
|
htmlSafe="true"
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
id={{concat
|
||||||
|
"sidebar-categories-form__input--"
|
||||||
|
category.id
|
||||||
|
}}
|
||||||
|
class="sidebar-categories-form__input"
|
||||||
|
@type="checkbox"
|
||||||
|
@checked={{includes
|
||||||
|
this.selectedSidebarCategoryIds
|
||||||
|
category.id
|
||||||
|
}}
|
||||||
|
disabled={{not
|
||||||
|
(includes this.filteredCategoryIds category.id)
|
||||||
|
}}
|
||||||
|
{{on "click" (fn this.toggleCategory category.id)}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
{{else}}
|
||||||
|
<div class="sidebar-categories-form__no-categories">
|
||||||
|
{{i18n "sidebar.categories_form_modal.no_categories"}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</form>
|
||||||
|
</EditNavigationMenuModal>
|
||||||
|
</template>
|
||||||
}
|
}
|
@ -1,75 +0,0 @@
|
|||||||
<Sidebar::EditNavigationMenu::Modal
|
|
||||||
@title="sidebar.categories_form_modal.title"
|
|
||||||
@disableSaveButton={{this.saving}}
|
|
||||||
@save={{this.save}}
|
|
||||||
@showResetDefaultsButton={{gt
|
|
||||||
this.siteSettings.default_navigation_menu_categories.length
|
|
||||||
0
|
|
||||||
}}
|
|
||||||
@resetToDefaults={{this.resetToDefaults}}
|
|
||||||
@deselectAll={{this.deselectAll}}
|
|
||||||
@deselectAllText={{i18n "sidebar.categories_form_modal.subtitle.text"}}
|
|
||||||
@inputFilterPlaceholder={{i18n
|
|
||||||
"sidebar.categories_form_modal.filter_placeholder"
|
|
||||||
}}
|
|
||||||
@onFilterInput={{this.onFilterInput}}
|
|
||||||
@resetFilter={{this.resetFilter}}
|
|
||||||
@filterSelected={{this.filterSelected}}
|
|
||||||
@filterUnselected={{this.filterUnselected}}
|
|
||||||
@closeModal={{@closeModal}}
|
|
||||||
class="sidebar__edit-navigation-menu__categories-modal"
|
|
||||||
>
|
|
||||||
<form class="sidebar-categories-form">
|
|
||||||
{{#if (gt this.filteredCategoriesGroupings.length 0)}}
|
|
||||||
{{#each this.filteredCategoriesGroupings as |categories|}}
|
|
||||||
<div
|
|
||||||
class="sidebar-categories-form__row"
|
|
||||||
style={{border-color (get categories "0.color") "left"}}
|
|
||||||
>
|
|
||||||
|
|
||||||
{{#each categories as |category|}}
|
|
||||||
<div
|
|
||||||
class="sidebar-categories-form__category-row"
|
|
||||||
data-category-id={{category.id}}
|
|
||||||
data-category-level={{category.level}}
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
class="sidebar-categories-form__category-label"
|
|
||||||
for={{concat "sidebar-categories-form__input--" category.id}}
|
|
||||||
>
|
|
||||||
<div class="sidebar-categories-form__category-wrapper">
|
|
||||||
<div class="sidebar-categories-form__category-badge">
|
|
||||||
{{category-badge category}}
|
|
||||||
</div>
|
|
||||||
{{#unless category.parentCategory}}
|
|
||||||
<div class="sidebar-categories-form__category-description">
|
|
||||||
{{dir-span category.description_excerpt htmlSafe="true"}}
|
|
||||||
</div>
|
|
||||||
{{/unless}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
id={{concat "sidebar-categories-form__input--" category.id}}
|
|
||||||
class="sidebar-categories-form__input"
|
|
||||||
@type="checkbox"
|
|
||||||
@checked={{includes
|
|
||||||
this.selectedSidebarCategoryIds
|
|
||||||
category.id
|
|
||||||
}}
|
|
||||||
disabled={{not
|
|
||||||
(includes this.filteredCategoryIds category.id)
|
|
||||||
}}
|
|
||||||
{{on "click" (fn this.toggleCategory category.id)}}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
{{else}}
|
|
||||||
<div class="sidebar-categories-form__no-categories">
|
|
||||||
{{i18n "sidebar.categories_form_modal.no_categories"}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</form>
|
|
||||||
</Sidebar::EditNavigationMenu::Modal>
|
|
@ -0,0 +1,135 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { Input } from "@ember/component";
|
||||||
|
import { hash } from "@ember/helper";
|
||||||
|
import { on } from "@ember/modifier";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import DButton from "discourse/components/d-button";
|
||||||
|
import DModal from "discourse/components/d-modal";
|
||||||
|
import dIcon from "discourse-common/helpers/d-icon";
|
||||||
|
import i18n from "discourse-common/helpers/i18n";
|
||||||
|
import I18n from "discourse-i18n";
|
||||||
|
import DropdownSelectBox from "select-kit/components/dropdown-select-box";
|
||||||
|
|
||||||
|
export default class extends Component {
|
||||||
|
@tracked filter = "";
|
||||||
|
@tracked filterDropdownValue = "all";
|
||||||
|
|
||||||
|
filterDropdownContent = [
|
||||||
|
{
|
||||||
|
id: "all",
|
||||||
|
name: I18n.t("sidebar.edit_navigation_modal_form.filter_dropdown.all"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "selected",
|
||||||
|
name: I18n.t(
|
||||||
|
"sidebar.edit_navigation_modal_form.filter_dropdown.selected"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "unselected",
|
||||||
|
name: I18n.t(
|
||||||
|
"sidebar.edit_navigation_modal_form.filter_dropdown.unselected"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@action
|
||||||
|
onFilterInput(input) {
|
||||||
|
this.args.onFilterInput(input.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
onFilterDropdownChange(value) {
|
||||||
|
this.filterDropdownValue = value;
|
||||||
|
|
||||||
|
switch (value) {
|
||||||
|
case "all":
|
||||||
|
this.args.resetFilter();
|
||||||
|
break;
|
||||||
|
case "selected":
|
||||||
|
this.args.filterSelected();
|
||||||
|
break;
|
||||||
|
case "unselected":
|
||||||
|
this.args.filterUnselected();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DModal
|
||||||
|
@title={{i18n @title}}
|
||||||
|
@closeModal={{@closeModal}}
|
||||||
|
class="sidebar__edit-navigation-menu__modal -large"
|
||||||
|
...attributes
|
||||||
|
>
|
||||||
|
<:belowModalTitle>
|
||||||
|
<p class="sidebar__edit-navigation-menu__deselect-wrapper">
|
||||||
|
<DButton
|
||||||
|
@label="sidebar.edit_navigation_modal_form.deselect_button_text"
|
||||||
|
@ariaLabel="sidebar.edit_navigation_modal_form.deselect_button_text"
|
||||||
|
@action={{@deselectAll}}
|
||||||
|
class="btn-flat sidebar__edit-navigation-menu__deselect-button"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{{@deselectAllText}}
|
||||||
|
</p>
|
||||||
|
</:belowModalTitle>
|
||||||
|
|
||||||
|
<:belowHeader>
|
||||||
|
<div class="sidebar__edit-navigation-menu__filter">
|
||||||
|
<div class="sidebar__edit-navigation-menu__filter-input">
|
||||||
|
{{dIcon
|
||||||
|
"search"
|
||||||
|
class="sidebar__edit-navigation-menu__filter-input-icon"
|
||||||
|
}}
|
||||||
|
|
||||||
|
<Input
|
||||||
|
class="sidebar__edit-navigation-menu__filter-input-field"
|
||||||
|
placeholder={{@inputFilterPlaceholder}}
|
||||||
|
@type="text"
|
||||||
|
@value={{this.filter}}
|
||||||
|
{{on "input" this.onFilterInput}}
|
||||||
|
autofocus="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar__edit-navigation-menu__filter-dropdown-wrapper">
|
||||||
|
<DropdownSelectBox
|
||||||
|
@value={{this.filterDropdownValue}}
|
||||||
|
@content={{this.filterDropdownContent}}
|
||||||
|
@onChange={{this.onFilterDropdownChange}}
|
||||||
|
@options={{hash showCaret=true disabled=@loading}}
|
||||||
|
class="sidebar__edit-navigation-menu__filter-dropdown"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</:belowHeader>
|
||||||
|
|
||||||
|
<:body>
|
||||||
|
{{yield}}
|
||||||
|
</:body>
|
||||||
|
|
||||||
|
<:footer>
|
||||||
|
<div class="sidebar__edit-navigation-menu__footer">
|
||||||
|
<DButton
|
||||||
|
@label="save"
|
||||||
|
@disabled={{@saving}}
|
||||||
|
@action={{@save}}
|
||||||
|
class="btn-primary sidebar__edit-navigation-menu__save-button"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{{#if @showResetDefaultsButton}}
|
||||||
|
<DButton
|
||||||
|
@icon="undo"
|
||||||
|
@label="sidebar.edit_navigation_modal_form.reset_to_defaults"
|
||||||
|
@disabled={{@saving}}
|
||||||
|
@action={{@resetToDefaults}}
|
||||||
|
class="btn-flat btn-text sidebar__edit-navigation-menu__reset-defaults-button"
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</:footer>
|
||||||
|
</DModal>
|
||||||
|
</template>
|
||||||
|
}
|
@ -1,74 +0,0 @@
|
|||||||
<DModal
|
|
||||||
@title={{i18n @title}}
|
|
||||||
@closeModal={{@closeModal}}
|
|
||||||
class="sidebar__edit-navigation-menu__modal -large"
|
|
||||||
...attributes
|
|
||||||
>
|
|
||||||
<:belowModalTitle>
|
|
||||||
<p class="sidebar__edit-navigation-menu__deselect-wrapper">
|
|
||||||
<DButton
|
|
||||||
@label="sidebar.edit_navigation_modal_form.deselect_button_text"
|
|
||||||
@ariaLabel="sidebar.edit_navigation_modal_form.deselect_button_text"
|
|
||||||
@action={{@deselectAll}}
|
|
||||||
class="btn-flat sidebar__edit-navigation-menu__deselect-button"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{{@deselectAllText}}
|
|
||||||
</p>
|
|
||||||
</:belowModalTitle>
|
|
||||||
|
|
||||||
<:belowHeader>
|
|
||||||
<div class="sidebar__edit-navigation-menu__filter">
|
|
||||||
<div class="sidebar__edit-navigation-menu__filter-input">
|
|
||||||
{{d-icon
|
|
||||||
"search"
|
|
||||||
class="sidebar__edit-navigation-menu__filter-input-icon"
|
|
||||||
}}
|
|
||||||
|
|
||||||
<Input
|
|
||||||
class="sidebar__edit-navigation-menu__filter-input-field"
|
|
||||||
placeholder={{@inputFilterPlaceholder}}
|
|
||||||
@type="text"
|
|
||||||
@value={{this.filter}}
|
|
||||||
{{on "input" (action @onFilterInput value="target.value")}}
|
|
||||||
autofocus="true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sidebar__edit-navigation-menu__filter-dropdown-wrapper">
|
|
||||||
<DropdownSelectBox
|
|
||||||
@value={{this.filterDropdownValue}}
|
|
||||||
@content={{this.filterDropdownContent}}
|
|
||||||
@onChange={{this.onFilterDropdownChange}}
|
|
||||||
@options={{hash showCaret=true disabled=@loading}}
|
|
||||||
class="sidebar__edit-navigation-menu__filter-dropdown"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</:belowHeader>
|
|
||||||
|
|
||||||
<:body>
|
|
||||||
{{yield}}
|
|
||||||
</:body>
|
|
||||||
|
|
||||||
<:footer>
|
|
||||||
<div class="sidebar__edit-navigation-menu__footer">
|
|
||||||
<DButton
|
|
||||||
@label="save"
|
|
||||||
@disabled={{@saving}}
|
|
||||||
@action={{@save}}
|
|
||||||
class="btn-primary sidebar__edit-navigation-menu__save-button"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{{#if @showResetDefaultsButton}}
|
|
||||||
<DButton
|
|
||||||
@icon="undo"
|
|
||||||
@label="sidebar.edit_navigation_modal_form.reset_to_defaults"
|
|
||||||
@disabled={{@saving}}
|
|
||||||
@action={{@resetToDefaults}}
|
|
||||||
class="btn-flat btn-text sidebar__edit-navigation-menu__reset-defaults-button"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</:footer>
|
|
||||||
</DModal>
|
|
@ -1,50 +0,0 @@
|
|||||||
import Component from "@glimmer/component";
|
|
||||||
import { tracked } from "@glimmer/tracking";
|
|
||||||
import { action } from "@ember/object";
|
|
||||||
import I18n from "discourse-i18n";
|
|
||||||
|
|
||||||
export default class extends Component {
|
|
||||||
@tracked filter = "";
|
|
||||||
@tracked filterDropdownValue = "all";
|
|
||||||
|
|
||||||
filterDropdownContent = [
|
|
||||||
{
|
|
||||||
id: "all",
|
|
||||||
name: I18n.t("sidebar.edit_navigation_modal_form.filter_dropdown.all"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "selected",
|
|
||||||
name: I18n.t(
|
|
||||||
"sidebar.edit_navigation_modal_form.filter_dropdown.selected"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "unselected",
|
|
||||||
name: I18n.t(
|
|
||||||
"sidebar.edit_navigation_modal_form.filter_dropdown.unselected"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
@action
|
|
||||||
onFilterInput(value) {
|
|
||||||
this.args.onFilterInput(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
onFilterDropdownChange(value) {
|
|
||||||
this.filterDropdownValue = value;
|
|
||||||
|
|
||||||
switch (value) {
|
|
||||||
case "all":
|
|
||||||
this.args.resetFilter();
|
|
||||||
break;
|
|
||||||
case "selected":
|
|
||||||
this.args.filterSelected();
|
|
||||||
break;
|
|
||||||
case "unselected":
|
|
||||||
this.args.filterUnselected();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user