Skip to content

Commit

Permalink
UX: Move category editing/creation to its own page (#10973)
Browse files Browse the repository at this point in the history
* Move new/edit category modals to its own page

* Fix JS tests

* Minor fixes to new-category UI

* Add mobile toggle

* Use global pretender endpoint so plugins can benefit too

* Alignment fix

* Minor review fixes

* Styling refactor

* Move some SCSS out of the modal
  • Loading branch information
pmusaraj committed Oct 23, 2020
1 parent 2bcca46 commit 6f5d8ca
Show file tree
Hide file tree
Showing 25 changed files with 505 additions and 351 deletions.
Expand Up @@ -106,9 +106,13 @@ export default buildCategoryPanel("general", {
return Category.list().filterBy("parent_category_id", categoryId);
},

@discourseComputed("category.isUncategorizedCategory", "category.id")
showDescription(isUncategorizedCategory, categoryId) {
return !isUncategorizedCategory && categoryId;
@discourseComputed(
"category.isUncategorizedCategory",
"category.id",
"category.topic_url"
)
showDescription(isUncategorizedCategory, categoryId, topicUrl) {
return !isUncategorizedCategory && categoryId && topicUrl;
},

@action
Expand Down
Expand Up @@ -9,7 +9,7 @@ export function buildCategoryPanel(tab, extras) {
{
activeTab: equal("selectedTab", tab),
classNameBindings: [
":modal-tab",
":edit-category-tab",
"activeTab::hide",
`:edit-category-tab-${tab}`,
],
Expand Down
97 changes: 40 additions & 57 deletions app/assets/javascripts/discourse/app/controllers/edit-category.js
@@ -1,22 +1,20 @@
import I18n from "I18n";
import { isEmpty } from "@ember/utils";
import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import DiscourseURL from "discourse/lib/url";
import { extractError } from "discourse/lib/ajax-error";
import discourseComputed, {
on,
observes,
} from "discourse-common/utils/decorators";
import Category from "discourse/models/category";
import discourseComputed, { on } from "discourse-common/utils/decorators";
import bootbox from "bootbox";
import { extractError } from "discourse/lib/ajax-error";
import DiscourseURL from "discourse/lib/url";
import { readOnly } from "@ember/object/computed";

export default Controller.extend(ModalFunctionality, {
selectedTab: null,
export default Controller.extend({
selectedTab: "general",
saving: false,
deleting: false,
panels: null,
hiddenTooltip: true,
createdCategory: false,
expandedMenu: false,
mobileView: readOnly("site.mobileView"),

@on("init")
_initPanels() {
Expand All @@ -26,36 +24,6 @@ export default Controller.extend(ModalFunctionality, {
});
},

onShow() {
this.changeSize();
this.titleChanged();
this.set("hiddenTooltip", true);
},

@observes("model.description")
changeSize() {
if (!isEmpty(this.get("model.description"))) {
this.set("modal.modalClass", "edit-category-modal full");
} else {
this.set("modal.modalClass", "edit-category-modal small");
}
},

@discourseComputed("model.{id,name}")
title(model) {
if (model.id) {
return I18n.t("category.edit_dialog_title", {
categoryName: model.name,
});
}
return I18n.t("category.create");
},

@observes("title")
titleChanged() {
this.set("modal.title", this.title);
},

@discourseComputed("saving", "model.name", "model.color", "deleting")
disabled(saving, name, color, deleting) {
if (saving || deleting) {
Expand Down Expand Up @@ -89,6 +57,15 @@ export default Controller.extend(ModalFunctionality, {
return id ? "category.save" : "category.create";
},

@discourseComputed("model.id", "model.name")
title(id, name) {
return id
? I18n.t("category.edit_dialog_title", {
categoryName: name,
})
: I18n.t("category.create");
},

actions: {
registerValidator(validator) {
this.validators.push(validator);
Expand All @@ -111,23 +88,22 @@ export default Controller.extend(ModalFunctionality, {
.save()
.then((result) => {
this.set("saving", false);
this.send("closeModal");
model.setProperties({
slug: result.category.slug,
id: result.category.id,
});
DiscourseURL.redirectTo(`/c/${Category.slugFor(model)}/${model.id}`);
if (!model.id) {
model.setProperties({
slug: result.category.slug,
id: result.category.id,
createdCategory: true,
});
}
})
.catch((error) => {
this.flash(extractError(error), "error");
bootbox.alert(extractError(error));
this.set("saving", false);
});
},

deleteCategory() {
this.set("deleting", true);

this.send("hideModal");
bootbox.confirm(
I18n.t("category.delete_confirm"),
I18n.t("no_value"),
Expand All @@ -136,19 +112,14 @@ export default Controller.extend(ModalFunctionality, {
if (result) {
this.model.destroy().then(
() => {
// success
this.send("closeModal");
DiscourseURL.redirectTo("/categories");
this.transitionToRoute("discovery.categories");
},
(error) => {
this.flash(extractError(error), "error");
this.send("reopenModal");
() => {
this.displayErrors([I18n.t("category.delete_error")]);
this.set("deleting", false);
}
);
} else {
this.send("reopenModal");
this.set("deleting", false);
}
}
Expand All @@ -158,5 +129,17 @@ export default Controller.extend(ModalFunctionality, {
toggleDeleteTooltip() {
this.toggleProperty("hiddenTooltip");
},

goBack() {
if (this.model.createdCategory) {
DiscourseURL.redirectTo(this.model.url);
} else {
DiscourseURL.routeTo(this.model.url);
}
},

toggleMenu() {
this.toggleProperty("expandedMenu");
},
},
});
4 changes: 4 additions & 0 deletions app/assets/javascripts/discourse/app/routes/app-route-map.js
Expand Up @@ -21,6 +21,8 @@ export default function () {

this.route("topicBySlugOrId", { path: "/t/:slugOrId", resetNamespace: true });

this.route("newCategory", { path: "/new-category" });

this.route("discovery", { path: "/", resetNamespace: true }, function () {
// legacy route
this.route("topParentCategory", { path: "/c/:slug/l/top" });
Expand Down Expand Up @@ -63,6 +65,8 @@ export default function () {
});

this.route("categories");
this.route("editCategory", { path: "/c/:slug/edit" });
this.route("editChildCategory", { path: "/c/:parentSlug/:slug/edit" });

// legacy routes
this.route("parentCategory", { path: "/c/:slug" });
Expand Down
10 changes: 2 additions & 8 deletions app/assets/javascripts/discourse/app/routes/application.js
Expand Up @@ -10,7 +10,7 @@ import Category from "discourse/models/category";
import mobile from "discourse/lib/mobile";
import { findAll } from "discourse/models/login-method";
import { getOwner } from "discourse-common/lib/get-owner";
import { userPath } from "discourse/lib/url";
import DiscourseURL, { userPath } from "discourse/lib/url";
import Composer from "discourse/models/composer";
import { inject as service } from "@ember/service";
import bootbox from "bootbox";
Expand Down Expand Up @@ -203,13 +203,7 @@ const ApplicationRoute = DiscourseRoute.extend(OpenComposer, {
},

editCategory(category) {
Category.reloadById(category.get("id")).then((atts) => {
const model = this.store.createRecord("category", atts.category);
model.setupGroupsAndPermissions();
this.site.updateCategory(model);
showModal("edit-category", { model });
this.controllerFor("edit-category").set("selectedTab", "general");
});
DiscourseURL.routeTo(`/c/${Category.slugFor(category)}/edit`);
},

checkEmail(user) {
Expand Down
Expand Up @@ -9,7 +9,6 @@ import { defaultHomepage } from "discourse/lib/utilities";
import TopicList from "discourse/models/topic-list";
import { ajax } from "discourse/lib/ajax";
import PreloadStore from "discourse/lib/preload-store";
import { SEARCH_PRIORITIES } from "discourse/lib/constants";
import { hash } from "rsvp";
import Site from "discourse/models/site";

Expand Down Expand Up @@ -111,7 +110,7 @@ const DiscoveryCategoriesRoute = DiscourseRoute.extend(OpenComposer, {
},

createCategory() {
openNewCategoryModal(this);
this.transitionTo("newCategory");
},

reorderCategories() {
Expand All @@ -134,22 +133,4 @@ const DiscoveryCategoriesRoute = DiscourseRoute.extend(OpenComposer, {
},
});

export function openNewCategoryModal(context) {
const groups = context.site.groups,
everyoneName = groups.findBy("id", 0).name;

const model = context.store.createRecord("category", {
color: "0088CC",
text_color: "FFFFFF",
group_permissions: [{ group_name: everyoneName, permission_type: 1 }],
available_groups: groups.map((g) => g.name),
allow_badges: true,
topic_featured_link_allowed: true,
custom_fields: {},
search_priority: SEARCH_PRIORITIES.normal,
});

showModal("edit-category", { model }).set("selectedTab", "general");
}

export default DiscoveryCategoriesRoute;
@@ -0,0 +1,28 @@
import I18n from "I18n";
import DiscourseRoute from "discourse/routes/discourse";
import Category from "discourse/models/category";

export default DiscourseRoute.extend({
model(params) {
return Category.reloadBySlugPath(params.slug).then((result) => {
const record = this.store.createRecord("category", result.category);
record.setupGroupsAndPermissions();
this.site.updateCategory(record);
return record;
});
},

titleToken() {
return I18n.t("category.edit_dialog_title", {
categoryName: this.currentModel.name,
});
},

renderTemplate() {
this.render("edit-category", {
controller: "edit-category",
outlet: "list-container",
model: this.currentModel,
});
},
});
@@ -0,0 +1,30 @@
import I18n from "I18n";
import DiscourseRoute from "discourse/routes/discourse";
import Category from "discourse/models/category";

export default DiscourseRoute.extend({
model(params) {
return Category.reloadBySlug(params.slug, params.parentSlug).then(
(result) => {
const record = this.store.createRecord("category", result.category);
record.setupGroupsAndPermissions();
this.site.updateCategory(record);
return record;
}
);
},

titleToken() {
return I18n.t("category.edit_dialog_title", {
categoryName: this.currentModel.name,
});
},

renderTemplate() {
this.render("edit-category", {
controller: "edit-category",
outlet: "list-container",
model: this.currentModel,
});
},
});
32 changes: 32 additions & 0 deletions app/assets/javascripts/discourse/app/routes/new-category.js
@@ -0,0 +1,32 @@
import I18n from "I18n";
import DiscourseRoute from "discourse/routes/discourse";
import { SEARCH_PRIORITIES } from "discourse/lib/constants";

export default DiscourseRoute.extend({
model() {
const groups = this.site.groups,
everyoneName = groups.findBy("id", 0).name;

return this.store.createRecord("category", {
color: "0088CC",
text_color: "FFFFFF",
group_permissions: [{ group_name: everyoneName, permission_type: 1 }],
available_groups: groups.map((g) => g.name),
allow_badges: true,
topic_featured_link_allowed: true,
custom_fields: {},
search_priority: SEARCH_PRIORITIES.normal,
});
},

titleToken() {
return I18n.t("category.create");
},

renderTemplate() {
this.render("edit-category", {
controller: "edit-category",
model: this.currentModel,
});
},
});
Expand Up @@ -19,7 +19,7 @@
id="category-allowed-tag-groups"
tagGroups=category.allowed_tag_groups
}}
{{#link-to "tagGroups"}}{{i18n "category.manage_tag_groups_link"}}{{/link-to}}
{{#link-to "tagGroups" class="manage-tag-groups"}}{{i18n "category.manage_tag_groups_link"}}{{/link-to}}
</section>

<section class="field">
Expand Down

1 comment on commit 6f5d8ca

@discoursebot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit has been mentioned on Discourse Meta. There might be relevant details there:

https://meta.discourse.org/t/how-to-edit-category/168510/4

Please sign in to comment.