FEATURE: delete multiple inactive themes/components (#23788)

Ability to select multiple inactive themes or components and delete them all together
This commit is contained in:
Krzysztof Kotlarek
2023-10-09 08:35:53 +11:00
committed by GitHub
parent 60e624e768
commit e94b553e9a
13 changed files with 330 additions and 9 deletions

View File

@@ -8,6 +8,13 @@
</span>
<div class="info">
{{#if @selectInactiveMode}}
<Input
@checked={{this.theme.markedToDelete}}
id={{this.theme.id}}
@type="checkbox"
/>
{{/if}}
<span class="name">
{{this.theme.name}}
</span>

View File

@@ -41,11 +41,61 @@
{{#if this.hasInactiveThemes}}
<div class="themes-list-item inactive-indicator">
<span class="empty">
{{#if this.themesTabActive}}
{{i18n "admin.customize.theme.inactive_themes"}}
{{else}}
{{i18n "admin.customize.theme.inactive_components"}}
{{/if}}
<div class="info">
{{#if this.selectInactiveMode}}
<Input
@type="checkbox"
@checked={{(or
(eq this.allInactiveSelected true)
(eq this.someInactiveSelected true)
)}}
class="toggle-all-inactive"
indeterminate={{this.someInactiveSelected}}
{{on "click" this.toggleAllInactive}}
/>
{{else}}
<DButton
class="btn-flat select-inactive-mode"
@action={{this.toggleInactiveMode}}
>
{{d-icon "list"}}
</DButton>
{{/if}}
{{#if this.selectInactiveMode}}
<span class="select-inactive-mode-label">
{{i18n
"admin.customize.theme.selected"
count=this.selectedCount
}}
</span>
{{else if this.themesTabActive}}
<span class="header">
{{i18n "admin.customize.theme.inactive_themes"}}
</span>
{{else}}
<span class="header">
{{i18n "admin.customize.theme.inactive_components"}}
</span>
{{/if}}
{{#if this.selectInactiveMode}}
<a
href
{{on "click" this.toggleInactiveMode}}
class="cancel-select-inactive-mode"
>
{{i18n "admin.customize.theme.cancel"}}
</a>
<DButton
class="btn btn-delete"
@action={{this.deleteConfirmation}}
@disabled={{(eq this.selectedCount 0)}}
>
{{d-icon "trash-alt"}}
Delete
</DButton>
{{/if}}
</div>
</span>
</div>
{{/if}}
@@ -57,6 +107,7 @@
@classNames="inactive-theme"
@theme={{theme}}
@navigateToTheme={{action "navigateToTheme" theme}}
@selectInactiveMode={{this.selectInactiveMode}}
/>
{{/each}}
{{/if}}

View File

@@ -3,16 +3,19 @@ import { inject as service } from "@ember/service";
import { equal, gt, gte } from "@ember/object/computed";
import { COMPONENTS, THEMES } from "admin/models/theme";
import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";
import discourseComputed, { bind } from "discourse-common/utils/decorators";
import { action } from "@ember/object";
import DeleteThemesConfirm from "discourse/components/modal/delete-themes-confirm";
@classNames("themes-list")
export default class ThemesList extends Component {
@service router;
@service modal;
THEMES = THEMES;
COMPONENTS = COMPONENTS;
filterTerm = null;
selectInactiveMode = false;
@gt("themesList.length", 0) hasThemes;
@@ -40,6 +43,7 @@ export default class ThemesList extends Component {
"currentTab",
"themesList.@each.user_selectable",
"themesList.@each.default",
"themesList.@each.markedToDelete",
"filterTerm"
)
inactiveThemes(themes) {
@@ -56,6 +60,16 @@ export default class ThemesList extends Component {
return this._filterThemes(results, this.filterTerm);
}
@discourseComputed("themesList.@each.markedToDelete")
selectedThemesOrComponents() {
return this.themesList.filter((theme) => theme.markedToDelete);
}
@discourseComputed("themesList.@each.markedToDelete")
selectedCount() {
return this.selectedThemesOrComponents.length;
}
@discourseComputed(
"themesList",
"currentTab",
@@ -84,6 +98,18 @@ export default class ThemesList extends Component {
}
return this._filterThemes(results, this.filterTerm);
}
@discourseComputed("themesList.@each.markedToDelete")
someInactiveSelected() {
return (
this.selectedCount > 0 &&
this.selectedCount !== this.inactiveThemes.length
);
}
@discourseComputed("themesList.@each.markedToDelete")
allInactiveSelected() {
return this.selectedCount === this.inactiveThemes.length;
}
_filterThemes(themes, term) {
term = term?.trim()?.toLowerCase();
@@ -93,9 +119,17 @@ export default class ThemesList extends Component {
return themes.filter(({ name }) => name.toLowerCase().includes(term));
}
@bind
toggleInactiveMode(event) {
event?.preventDefault();
this.inactiveThemes.forEach((theme) => theme.set("markedToDelete", false));
this.toggleProperty("selectInactiveMode");
}
@action
changeView(newTab) {
if (newTab !== this.currentTab) {
this.set("selectInactiveMode", false);
this.set("currentTab", newTab);
if (!this.showFilter) {
this.set("filterTerm", null);
@@ -107,4 +141,41 @@ export default class ThemesList extends Component {
navigateToTheme(theme) {
this.router.transitionTo("adminCustomizeThemes.show", theme);
}
@action
toggleAllInactive() {
const markedToDelete = this.selectedCount === 0;
this.inactiveThemes.forEach((theme) =>
theme.set("markedToDelete", markedToDelete)
);
}
@action
deleteConfirmation() {
this.modal.show(DeleteThemesConfirm, {
model: {
selectedThemesOrComponents: this.selectedThemesOrComponents,
type: this.themesTabActive ? "themes" : "components",
refreshAfterDelete: () => {
this.set("selectInactiveMode", false);
if (this.themesTabActive) {
this.set(
"themes",
this.themes.filter(
(theme) => !this.selectedThemesOrComponents.includes(theme)
)
);
} else {
this.set(
"components",
this.components.filter(
(component) =>
!this.selectedThemesOrComponents.includes(component)
)
);
}
},
},
});
}
}