mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
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:
committed by
GitHub
parent
60e624e768
commit
e94b553e9a
@@ -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>
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user