mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 02:40:53 -06:00
DEV: Clean up sidebar modals (#26999)
1. async/await 2. TrackedSet 3. don't rely on ember array methods 4. list used props 5. move stuff out of constructors 6. don't use ember's Input component 7. convert a function to a method (to avoid passing in a class prop) 8. add missing `@tracked` 9. remove tracking from props that don't need it (not used in templates)
This commit is contained in:
parent
fe12cfeab2
commit
eb2df2b7d6
@ -1,12 +1,12 @@
|
||||
import Component from "@glimmer/component";
|
||||
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 didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
||||
import { service } from "@ember/service";
|
||||
import { gt, includes, not } from "truth-helpers";
|
||||
import { TrackedSet } from "@ember-compat/tracked-built-ins";
|
||||
import { gt, has, includes, not } from "truth-helpers";
|
||||
import EditNavigationMenuModal from "discourse/components/sidebar/edit-navigation-menu/modal";
|
||||
import borderColor from "discourse/helpers/border-color";
|
||||
import categoryBadge from "discourse/helpers/category-badge";
|
||||
@ -46,19 +46,6 @@ function findAncestors(categories) {
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
function applyMode(mode, categories, selectedSidebarCategoryIds) {
|
||||
return categories.filter((c) => {
|
||||
switch (mode) {
|
||||
case "everything":
|
||||
return true;
|
||||
case "only-selected":
|
||||
return selectedSidebarCategoryIds.includes(c.id);
|
||||
case "only-unselected":
|
||||
return !selectedSidebarCategoryIds.includes(c.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default class SidebarEditNavigationMenuCategoriesModal extends Component {
|
||||
@service currentUser;
|
||||
@service site;
|
||||
@ -67,26 +54,32 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component
|
||||
@tracked initialLoad = true;
|
||||
@tracked filteredCategoriesGroupings = [];
|
||||
@tracked filteredCategoryIds = [];
|
||||
// TODO: tracked array, no ember array methods
|
||||
@tracked
|
||||
selectedSidebarCategoryIds = [...this.currentUser.sidebar_category_ids];
|
||||
selectedSidebarCategoryIds = new TrackedSet([
|
||||
...this.currentUser.sidebar_category_ids,
|
||||
]);
|
||||
hasMorePages;
|
||||
loadedFilter;
|
||||
loadedMode;
|
||||
loadedPage;
|
||||
processing = false;
|
||||
requestedFilter;
|
||||
requestedMode;
|
||||
saving = false;
|
||||
observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
this.observer.disconnect();
|
||||
this.loadMore();
|
||||
}
|
||||
},
|
||||
{
|
||||
threshold: 1.0,
|
||||
}
|
||||
);
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
this.observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries.some((entry) => entry.isIntersecting)) {
|
||||
this.observer.disconnect();
|
||||
this.loadMore();
|
||||
}
|
||||
},
|
||||
{
|
||||
threshold: 1.0,
|
||||
}
|
||||
);
|
||||
|
||||
this.processing = false;
|
||||
this.setFilterAndMode("", "everything");
|
||||
}
|
||||
|
||||
@ -108,15 +101,24 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component
|
||||
}
|
||||
|
||||
setFetchedCategories(mode, categories) {
|
||||
this.setFilteredCategories(
|
||||
applyMode(mode, categories, this.selectedSidebarCategoryIds)
|
||||
);
|
||||
this.setFilteredCategories(this.applyMode(mode, categories));
|
||||
}
|
||||
|
||||
concatFetchedCategories(mode, categories) {
|
||||
this.concatFilteredCategories(
|
||||
applyMode(mode, categories, this.selectedSidebarCategoryIds)
|
||||
);
|
||||
this.concatFilteredCategories(this.applyMode(mode, categories));
|
||||
}
|
||||
|
||||
applyMode(mode, categories) {
|
||||
return categories.filter((c) => {
|
||||
switch (mode) {
|
||||
case "everything":
|
||||
return true;
|
||||
case "only-selected":
|
||||
return this.selectedSidebarCategoryIds.has(c.id);
|
||||
case "only-unselected":
|
||||
return !this.selectedSidebarCategoryIds.has(c.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
@ -128,7 +130,7 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component
|
||||
async searchCategories(filter, mode) {
|
||||
if (filter === "" && mode === "only-selected") {
|
||||
this.setFilteredCategories(
|
||||
await Category.asyncFindByIds(this.selectedSidebarCategoryIds)
|
||||
await Category.asyncFindByIds([...this.selectedSidebarCategoryIds])
|
||||
);
|
||||
|
||||
this.loadedPage = null;
|
||||
@ -241,43 +243,40 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component
|
||||
|
||||
@action
|
||||
toggleCategory(categoryId) {
|
||||
if (this.selectedSidebarCategoryIds.includes(categoryId)) {
|
||||
this.selectedSidebarCategoryIds.removeObject(categoryId);
|
||||
if (this.selectedSidebarCategoryIds.has(categoryId)) {
|
||||
this.selectedSidebarCategoryIds.delete(categoryId);
|
||||
} else {
|
||||
this.selectedSidebarCategoryIds.addObject(categoryId);
|
||||
this.selectedSidebarCategoryIds.add(categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
resetToDefaults() {
|
||||
this.selectedSidebarCategoryIds =
|
||||
this.selectedSidebarCategoryIds = new TrackedSet(
|
||||
this.siteSettings.default_navigation_menu_categories
|
||||
.split("|")
|
||||
.map((id) => parseInt(id, 10));
|
||||
.map((id) => parseInt(id, 10))
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
save() {
|
||||
async save() {
|
||||
this.saving = true;
|
||||
const initialSidebarCategoryIds = this.currentUser.sidebar_category_ids;
|
||||
|
||||
this.currentUser.set(
|
||||
"sidebar_category_ids",
|
||||
this.selectedSidebarCategoryIds
|
||||
);
|
||||
this.currentUser.set("sidebar_category_ids", [
|
||||
...this.selectedSidebarCategoryIds,
|
||||
]);
|
||||
|
||||
this.currentUser
|
||||
.save(["sidebar_category_ids"])
|
||||
.then(() => {
|
||||
this.args.closeModal();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.currentUser.set("sidebar_category_ids", initialSidebarCategoryIds);
|
||||
popupAjaxError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.saving = false;
|
||||
});
|
||||
try {
|
||||
await this.currentUser.save(["sidebar_category_ids"]);
|
||||
this.args.closeModal();
|
||||
} catch (error) {
|
||||
this.currentUser.set("sidebar_category_ids", initialSidebarCategoryIds);
|
||||
popupAjaxError(error);
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
<template>
|
||||
@ -344,10 +343,10 @@ export default class SidebarEditNavigationMenuCategoriesModal extends Component
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
||||
<Input
|
||||
<input
|
||||
{{on "click" (fn this.toggleCategory category.id)}}
|
||||
@type="checkbox"
|
||||
@checked={{includes
|
||||
type="checkbox"
|
||||
checked={{has
|
||||
this.selectedSidebarCategoryIds
|
||||
category.id
|
||||
}}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { Input } from "@ember/component";
|
||||
import { hash } from "@ember/helper";
|
||||
import { fn, hash } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import { action } from "@ember/object";
|
||||
import DButton from "discourse/components/d-button";
|
||||
@ -15,7 +14,6 @@ import DropdownSelectBox from "select-kit/components/dropdown-select-box";
|
||||
export default class SidebarEditNavigationMenuModal extends Component {
|
||||
@tracked filter = "";
|
||||
@tracked filterDropdownValue = "all";
|
||||
|
||||
filterDropdownContent = [
|
||||
{
|
||||
id: "all",
|
||||
@ -80,10 +78,11 @@ export default class SidebarEditNavigationMenuModal extends Component {
|
||||
class="sidebar__edit-navigation-menu__filter-input-icon"
|
||||
}}
|
||||
|
||||
<Input
|
||||
<input
|
||||
{{on "input" (withEventValue (fn (mut this.filter)))}}
|
||||
{{on "input" (withEventValue @onFilterInput)}}
|
||||
@type="text"
|
||||
@value={{this.filter}}
|
||||
type="text"
|
||||
value={{this.filter}}
|
||||
placeholder={{@inputFilterPlaceholder}}
|
||||
autofocus="true"
|
||||
class="sidebar__edit-navigation-menu__filter-input-field"
|
||||
|
@ -1,12 +1,12 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { Input } from "@ember/component";
|
||||
import { concat, fn } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import { action } from "@ember/object";
|
||||
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
||||
import { service } from "@ember/service";
|
||||
import { gt, includes, or } from "truth-helpers";
|
||||
import { TrackedSet } from "@ember-compat/tracked-built-ins";
|
||||
import { gt, has, or } from "truth-helpers";
|
||||
import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner";
|
||||
import loadingSpinner from "discourse/helpers/loading-spinner";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
@ -20,13 +20,14 @@ export default class SidebarEditNavigationMenuTagsModal extends Component {
|
||||
@service siteSettings;
|
||||
@service store;
|
||||
|
||||
@tracked filter = "";
|
||||
@tracked onlySelected = false;
|
||||
@tracked onlyUnSelected = false;
|
||||
@tracked disableFiltering = false;
|
||||
@tracked saving = false;
|
||||
@tracked selectedTags = new TrackedSet([...this.currentUser.sidebarTagNames]);
|
||||
@tracked tags = [];
|
||||
@tracked tagsLoading;
|
||||
@tracked disableFiltering;
|
||||
@tracked selectedTags = [...this.currentUser.sidebarTagNames];
|
||||
@tracked tagsLoading = false;
|
||||
observer;
|
||||
onlySelected = false;
|
||||
onlyUnselected = false;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
@ -38,30 +39,25 @@ export default class SidebarEditNavigationMenuTagsModal extends Component {
|
||||
|
||||
const findArgs = {};
|
||||
|
||||
if (this.filter !== "") {
|
||||
if (this.filter) {
|
||||
findArgs.filter = this.filter;
|
||||
}
|
||||
|
||||
if (this.onlySelected) {
|
||||
findArgs.only_tags = this.selectedTags.join(",");
|
||||
findArgs.only_tags = [...this.selectedTags].join(",");
|
||||
} else if (this.onlyUnselected) {
|
||||
findArgs.exclude_tags = [...this.selectedTags].join(",");
|
||||
}
|
||||
|
||||
if (this.onlyUnselected) {
|
||||
findArgs.exclude_tags = this.selectedTags.join(",");
|
||||
try {
|
||||
const tags = await this.store.findAll("listTag", findArgs);
|
||||
this.tags = tags;
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
} finally {
|
||||
this.tagsLoading = false;
|
||||
this.disableFiltering = false;
|
||||
}
|
||||
|
||||
await this.store
|
||||
.findAll("listTag", findArgs)
|
||||
.then((tags) => {
|
||||
this.tags = tags;
|
||||
})
|
||||
.catch((error) => {
|
||||
popupAjaxError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.tagsLoading = false;
|
||||
this.disableFiltering = false;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
@ -137,38 +133,36 @@ export default class SidebarEditNavigationMenuTagsModal extends Component {
|
||||
|
||||
@action
|
||||
resetToDefaults() {
|
||||
this.selectedTags =
|
||||
this.siteSettings.default_navigation_menu_tags.split("|");
|
||||
this.selectedTags = new TrackedSet(
|
||||
this.siteSettings.default_navigation_menu_tags.split("|")
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
toggleTag(tag) {
|
||||
if (this.selectedTags.includes(tag)) {
|
||||
this.selectedTags.removeObject(tag);
|
||||
if (this.selectedTags.has(tag)) {
|
||||
this.selectedTags.delete(tag);
|
||||
} else {
|
||||
this.selectedTags.addObject(tag);
|
||||
this.selectedTags.add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
save() {
|
||||
async save() {
|
||||
this.saving = true;
|
||||
const initialSidebarTags = this.currentUser.sidebar_tags;
|
||||
this.currentUser.set("sidebar_tag_names", this.selectedTags);
|
||||
this.currentUser.set("sidebar_tag_names", [...this.selectedTags]);
|
||||
|
||||
this.currentUser
|
||||
.save(["sidebar_tag_names"])
|
||||
.then((result) => {
|
||||
this.currentUser.set("sidebar_tags", result.user.sidebar_tags);
|
||||
this.args.closeModal();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.currentUser.set("sidebar_tags", initialSidebarTags);
|
||||
popupAjaxError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.saving = false;
|
||||
});
|
||||
try {
|
||||
const result = await this.currentUser.save(["sidebar_tag_names"]);
|
||||
this.currentUser.set("sidebar_tags", result.user.sidebar_tags);
|
||||
this.args.closeModal();
|
||||
} catch (error) {
|
||||
this.currentUser.set("sidebar_tags", initialSidebarTags);
|
||||
popupAjaxError(error);
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
<template>
|
||||
@ -204,10 +198,10 @@ export default class SidebarEditNavigationMenuTagsModal extends Component {
|
||||
data-tag-name={{tag.name}}
|
||||
class="sidebar-tags-form__tag"
|
||||
>
|
||||
<Input
|
||||
<input
|
||||
{{on "click" (fn this.toggleTag tag.name)}}
|
||||
@type="checkbox"
|
||||
@checked={{includes this.selectedTags tag.name}}
|
||||
type="checkbox"
|
||||
checked={{has this.selectedTags tag.name}}
|
||||
id={{concat "sidebar-tags-form__input--" tag.name}}
|
||||
class="sidebar-tags-form__input"
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user