mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 11:15:05 +08:00
DEV: Convert edit-badge-groupings
modal to component-based API (#22984)
<img width="603" alt="Screenshot 2023-08-04 at 4 43 02 PM" src="https://github.com/discourse/discourse/assets/50783505/033192cc-2c5c-4be6-adde-9dd89b6b05c3"> <img width="594" alt="Screenshot 2023-08-04 at 4 42 59 PM" src="https://github.com/discourse/discourse/assets/50783505/efe8d8fe-f06c-4940-9c99-66a2f8fb3532">
This commit is contained in:
parent
d546f34f2f
commit
ac4e854a04
|
@ -0,0 +1,55 @@
|
|||
<DModal
|
||||
@title={{i18n "admin.badges.badge_groupings.modal_title"}}
|
||||
@bodyClass="badge-groupings-modal"
|
||||
@closeModal={{@closeModal}}
|
||||
>
|
||||
<:body>
|
||||
<div class="badge-groupings">
|
||||
<ul class="badge-groupings-list">
|
||||
{{#each this.workingCopy as |wc|}}
|
||||
<li class="badge-grouping-item">
|
||||
<div class="badge-grouping">
|
||||
{{#if wc.editing}}
|
||||
<Input @value={{wc.name}} class="badge-grouping-name-input" />
|
||||
{{else}}
|
||||
<span>{{wc.displayName}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="actions">
|
||||
{{#if wc.editing}}
|
||||
<DButton @action={{fn (mut wc.editing) false}} @icon="check" />
|
||||
{{else}}
|
||||
<DButton
|
||||
@action={{fn (mut wc.editing) true}}
|
||||
@disabled={{wc.system}}
|
||||
@icon="pencil-alt"
|
||||
/>
|
||||
{{/if}}
|
||||
<DButton @action={{fn this.up wc}} @icon="chevron-up" />
|
||||
<DButton @action={{fn this.down wc}} @icon="chevron-down" />
|
||||
<DButton
|
||||
@action={{fn this.delete wc}}
|
||||
@disabled={{wc.system}}
|
||||
@icon="times"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<DButton @action={{this.add}} @label="admin.badges.new" />
|
||||
</:body>
|
||||
<:footer>
|
||||
<DButton
|
||||
@action={{this.saveAll}}
|
||||
@label="admin.badges.save"
|
||||
class="btn-primary"
|
||||
@disabled={{this.submitDisabled}}
|
||||
/>
|
||||
<DButton
|
||||
class="btn-flat d-modal-cancel"
|
||||
@action={{@closeModal}}
|
||||
@label="cancel"
|
||||
/>
|
||||
</:footer>
|
||||
</DModal>
|
|
@ -0,0 +1,84 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { action } from "@ember/object";
|
||||
import I18n from "I18n";
|
||||
import { A } from "@ember/array";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { TrackedArray } from "@ember-compat/tracked-built-ins";
|
||||
|
||||
export default class EditBadgeGroupings extends Component {
|
||||
@service dialog;
|
||||
@service store;
|
||||
|
||||
@tracked workingCopy = new TrackedArray();
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
let copy = A();
|
||||
if (this.args.model.badgeGroupings) {
|
||||
this.args.model.badgeGroupings.forEach((o) =>
|
||||
copy.pushObject(this.store.createRecord("badge-grouping", o))
|
||||
);
|
||||
}
|
||||
this.workingCopy = copy;
|
||||
}
|
||||
|
||||
@action
|
||||
up(item) {
|
||||
this.moveItem(item, -1);
|
||||
}
|
||||
|
||||
@action
|
||||
down(item) {
|
||||
this.moveItem(item, 1);
|
||||
}
|
||||
|
||||
@action
|
||||
delete(item) {
|
||||
this.workingCopy.removeObject(item);
|
||||
}
|
||||
|
||||
@action
|
||||
add() {
|
||||
const obj = this.store.createRecord("badge-grouping", {
|
||||
editing: true,
|
||||
name: I18n.t("admin.badges.badge_grouping"),
|
||||
});
|
||||
this.workingCopy.pushObject(obj);
|
||||
}
|
||||
|
||||
@action
|
||||
async saveAll() {
|
||||
const groupIds = this.workingCopy.map((i) => i.id || -1);
|
||||
const names = this.workingCopy.map((i) => i.name);
|
||||
try {
|
||||
const data = await ajax("/admin/badges/badge_groupings", {
|
||||
data: { ids: groupIds, names },
|
||||
type: "POST",
|
||||
});
|
||||
this.workingCopy.clear();
|
||||
data.badge_groupings.forEach((badgeGroup) => {
|
||||
this.workingCopy.pushObject(
|
||||
this.store.createRecord("badge-grouping", {
|
||||
...badgeGroup,
|
||||
editing: false,
|
||||
})
|
||||
);
|
||||
});
|
||||
this.args.model.updateGroupings(this.workingCopy);
|
||||
this.args.closeModal();
|
||||
} catch {
|
||||
this.dialog.alert(I18n.t("generic_error"));
|
||||
}
|
||||
}
|
||||
|
||||
moveItem(item, delta) {
|
||||
const index = this.workingCopy.indexOf(item);
|
||||
if (index + delta < 0 || index + delta >= this.workingCopy.length) {
|
||||
return;
|
||||
}
|
||||
this.workingCopy.removeAt(index);
|
||||
this.workingCopy.insertAt(index + delta, item);
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { A } from "@ember/array";
|
||||
import Controller from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default class AdminEditBadgeGroupingsController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@service dialog;
|
||||
|
||||
@observes("model")
|
||||
modelChanged() {
|
||||
const model = this.model;
|
||||
const copy = A();
|
||||
const store = this.store;
|
||||
|
||||
if (model) {
|
||||
model.forEach((o) =>
|
||||
copy.pushObject(store.createRecord("badge-grouping", o))
|
||||
);
|
||||
}
|
||||
|
||||
this.set("workingCopy", copy);
|
||||
}
|
||||
|
||||
moveItem(item, delta) {
|
||||
const copy = this.workingCopy;
|
||||
const index = copy.indexOf(item);
|
||||
if (index + delta < 0 || index + delta >= copy.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
copy.removeAt(index);
|
||||
copy.insertAt(index + delta, item);
|
||||
}
|
||||
|
||||
@action
|
||||
up(item) {
|
||||
this.moveItem(item, -1);
|
||||
}
|
||||
|
||||
@action
|
||||
down(item) {
|
||||
this.moveItem(item, 1);
|
||||
}
|
||||
|
||||
@action
|
||||
delete(item) {
|
||||
this.workingCopy.removeObject(item);
|
||||
}
|
||||
|
||||
@action
|
||||
cancel() {
|
||||
this.setProperties({ model: null, workingCopy: null });
|
||||
this.send("closeModal");
|
||||
}
|
||||
|
||||
@action
|
||||
edit(item) {
|
||||
item.set("editing", true);
|
||||
}
|
||||
|
||||
@action
|
||||
save(item) {
|
||||
item.set("editing", false);
|
||||
}
|
||||
|
||||
@action
|
||||
add() {
|
||||
const obj = this.store.createRecord("badge-grouping", {
|
||||
editing: true,
|
||||
name: I18n.t("admin.badges.badge_grouping"),
|
||||
});
|
||||
this.workingCopy.pushObject(obj);
|
||||
}
|
||||
|
||||
@action
|
||||
saveAll() {
|
||||
let items = this.workingCopy;
|
||||
const groupIds = items.map((i) => i.get("id") || -1);
|
||||
const names = items.map((i) => i.get("name"));
|
||||
|
||||
ajax("/admin/badges/badge_groupings", {
|
||||
data: { ids: groupIds, names },
|
||||
type: "POST",
|
||||
}).then(
|
||||
(data) => {
|
||||
items = this.model;
|
||||
items.clear();
|
||||
data.badge_groupings.forEach((g) => {
|
||||
items.pushObject(this.store.createRecord("badge-grouping", g));
|
||||
});
|
||||
this.setProperties({ model: null, workingCopy: null });
|
||||
this.send("closeModal");
|
||||
},
|
||||
() => this.dialog.alert(I18n.t("generic_error"))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -5,9 +5,11 @@ import { ajax } from "discourse/lib/ajax";
|
|||
import { action, get } from "@ember/object";
|
||||
import showModal from "discourse/lib/show-modal";
|
||||
import { inject as service } from "@ember/service";
|
||||
import EditBadgeGroupingsModal from "../../components/modal/edit-badge-groupings";
|
||||
|
||||
export default class AdminBadgesShowRoute extends Route {
|
||||
@service dialog;
|
||||
@service modal;
|
||||
|
||||
serialize(m) {
|
||||
return { badge_id: get(m, "id") || "new" };
|
||||
|
@ -37,7 +39,17 @@ export default class AdminBadgesShowRoute extends Route {
|
|||
@action
|
||||
editGroupings() {
|
||||
const model = this.controllerFor("admin-badges").get("badgeGroupings");
|
||||
showModal("admin-edit-badge-groupings", { model, admin: true });
|
||||
this.modal.show(EditBadgeGroupingsModal, {
|
||||
model: {
|
||||
badgeGroupings: model,
|
||||
updateGroupings: this.updateGroupings,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
updateGroupings(groupings) {
|
||||
this.controllerFor("admin-badges").set("badgeGroupings", groupings);
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<DModalBody
|
||||
@title="admin.badges.badge_groupings.modal_title"
|
||||
@class="badge-groupings-modal"
|
||||
>
|
||||
<div class="badge-groupings">
|
||||
<ul class="badge-groupings-list">
|
||||
{{#each this.workingCopy as |wc|}}
|
||||
<li class="badge-grouping-item">
|
||||
<div class="badge-grouping">
|
||||
{{#if wc.editing}}
|
||||
<Input @value={{wc.name}} class="badge-grouping-name-input" />
|
||||
<DButton @action={{action "save" wc}} @icon="check" />
|
||||
{{else}}
|
||||
<span>{{wc.displayName}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="actions">
|
||||
<DButton
|
||||
@action={{action "edit" wc}}
|
||||
@disabled={{wc.system}}
|
||||
@icon="pencil-alt"
|
||||
/>
|
||||
<DButton @action={{action "up" wc}} @icon="chevron-up" />
|
||||
<DButton @action={{action "down" wc}} @icon="chevron-down" />
|
||||
<DButton
|
||||
@action={{action "delete" wc}}
|
||||
@disabled={{wc.system}}
|
||||
@icon="times"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<DButton @action={{action "add"}} @label="admin.badges.new" />
|
||||
</DModalBody>
|
||||
|
||||
<div class="modal-footer">
|
||||
<DButton
|
||||
@action={{action "saveAll"}}
|
||||
@label="admin.badges.save"
|
||||
@class="btn-primary"
|
||||
@disabled={{this.submitDisabled}}
|
||||
/>
|
||||
<DModalCancel @close={{route-action "closeModal"}} />
|
||||
</div>
|
|
@ -47,7 +47,6 @@ const KNOWN_LEGACY_MODALS = [
|
|||
"user-status",
|
||||
"admin-penalize-user",
|
||||
"admin-badge-preview",
|
||||
"admin-edit-badge-groupings",
|
||||
"admin-reseed",
|
||||
"admin-theme-item",
|
||||
"admin-color-scheme-select-base",
|
||||
|
|
Loading…
Reference in New Issue
Block a user