DEV: Refactor build-category-route to define abstract controller
This makes more sense (and is likely faster) than redefining the entire route for every call to `buildCategoryRoute`
This commit is contained in:
parent
5aaf5cbaf4
commit
d5107d1aba
|
@ -23,18 +23,17 @@ export default {
|
|||
DiscoverySortableController.extend()
|
||||
);
|
||||
|
||||
app.register("route:discovery.category", buildCategoryRoute("default"));
|
||||
app.register(
|
||||
"route:discovery.category",
|
||||
buildCategoryRoute({ filter: "default" })
|
||||
);
|
||||
app.register(
|
||||
"route:discovery.category-none",
|
||||
buildCategoryRoute("default", {
|
||||
no_subcategories: true,
|
||||
})
|
||||
buildCategoryRoute({ filter: "default", no_subcategories: true })
|
||||
);
|
||||
app.register(
|
||||
"route:discovery.category-all",
|
||||
buildCategoryRoute("default", {
|
||||
no_subcategories: false,
|
||||
})
|
||||
buildCategoryRoute({ filter: "default", no_subcategories: false })
|
||||
);
|
||||
|
||||
const site = Site.current();
|
||||
|
@ -83,11 +82,11 @@ export default {
|
|||
|
||||
app.register(
|
||||
`route:discovery.${filterDasherized}-category`,
|
||||
buildCategoryRoute(filter)
|
||||
buildCategoryRoute({ filter })
|
||||
);
|
||||
app.register(
|
||||
`route:discovery.${filterDasherized}-category-none`,
|
||||
buildCategoryRoute(filter, { no_subcategories: true })
|
||||
buildCategoryRoute({ filter, no_subcategories: true })
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -18,240 +18,243 @@ import { action } from "@ember/object";
|
|||
import PreloadStore from "discourse/lib/preload-store";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
// A helper function to create a category route with parameters
|
||||
export default (filterArg, params) => {
|
||||
return DiscourseRoute.extend({
|
||||
queryParams,
|
||||
composer: service(),
|
||||
const AbstractCategoryRoute = DiscourseRoute.extend({
|
||||
queryParams,
|
||||
composer: service(),
|
||||
|
||||
model(modelParams) {
|
||||
const category = Category.findBySlugPathWithID(
|
||||
model(modelParams) {
|
||||
const category = Category.findBySlugPathWithID(
|
||||
modelParams.category_slug_path_with_id
|
||||
);
|
||||
|
||||
if (!category) {
|
||||
const parts = modelParams.category_slug_path_with_id.split("/");
|
||||
if (parts.length > 0 && parts[parts.length - 1].match(/^\d+$/)) {
|
||||
parts.pop();
|
||||
}
|
||||
|
||||
return Category.reloadBySlugPath(parts.join("/")).then((result) => {
|
||||
const record = this.store.createRecord("category", result.category);
|
||||
record.setupGroupsAndPermissions();
|
||||
this.site.updateCategory(record);
|
||||
return { category: record, modelParams };
|
||||
});
|
||||
}
|
||||
|
||||
if (category) {
|
||||
return { category, modelParams };
|
||||
}
|
||||
},
|
||||
|
||||
afterModel(model, transition) {
|
||||
if (!model) {
|
||||
this.replaceWith("/404");
|
||||
return;
|
||||
}
|
||||
|
||||
const { category, modelParams } = model;
|
||||
|
||||
if (
|
||||
this.routeConfig?.no_subcategories === undefined &&
|
||||
category.default_list_filter === "none" &&
|
||||
this.routeConfig?.filter === "default" &&
|
||||
modelParams
|
||||
) {
|
||||
// TODO: avoid throwing away preload data by redirecting on the server
|
||||
PreloadStore.getAndRemove("topic_list");
|
||||
return this.replaceWith(
|
||||
"discovery.categoryNone",
|
||||
modelParams.category_slug_path_with_id
|
||||
);
|
||||
}
|
||||
|
||||
if (!category) {
|
||||
const parts = modelParams.category_slug_path_with_id.split("/");
|
||||
if (parts.length > 0 && parts[parts.length - 1].match(/^\d+$/)) {
|
||||
parts.pop();
|
||||
}
|
||||
this._setupNavigation(category);
|
||||
return all([
|
||||
this._createSubcategoryList(category),
|
||||
this._retrieveTopicList(category, transition, modelParams),
|
||||
]);
|
||||
},
|
||||
|
||||
return Category.reloadBySlugPath(parts.join("/")).then((result) => {
|
||||
const record = this.store.createRecord("category", result.category);
|
||||
record.setupGroupsAndPermissions();
|
||||
this.site.updateCategory(record);
|
||||
return { category: record, modelParams };
|
||||
});
|
||||
}
|
||||
filter(category) {
|
||||
return this.routeConfig?.filter === "default"
|
||||
? category.get("default_view") || "latest"
|
||||
: this.routeConfig?.filter;
|
||||
},
|
||||
|
||||
if (category) {
|
||||
return { category, modelParams };
|
||||
}
|
||||
},
|
||||
_setupNavigation(category) {
|
||||
const noSubcategories =
|
||||
this.routeConfig && !!this.routeConfig.no_subcategories,
|
||||
filterType = this.filter(category).split("/")[0];
|
||||
|
||||
afterModel(model, transition) {
|
||||
if (!model) {
|
||||
this.replaceWith("/404");
|
||||
return;
|
||||
}
|
||||
this.controllerFor("navigation/category").setProperties({
|
||||
category,
|
||||
filterType,
|
||||
noSubcategories,
|
||||
});
|
||||
},
|
||||
|
||||
const { category, modelParams } = model;
|
||||
_createSubcategoryList(category) {
|
||||
this._categoryList = null;
|
||||
|
||||
if (
|
||||
(!params || params.no_subcategories === undefined) &&
|
||||
category.default_list_filter === "none" &&
|
||||
filterArg === "default" &&
|
||||
modelParams
|
||||
) {
|
||||
// TODO: avoid throwing away preload data by redirecting on the server
|
||||
PreloadStore.getAndRemove("topic_list");
|
||||
return this.replaceWith(
|
||||
"discovery.categoryNone",
|
||||
modelParams.category_slug_path_with_id
|
||||
);
|
||||
}
|
||||
|
||||
this._setupNavigation(category);
|
||||
return all([
|
||||
this._createSubcategoryList(category),
|
||||
this._retrieveTopicList(category, transition, modelParams),
|
||||
]);
|
||||
},
|
||||
|
||||
filter(category) {
|
||||
return filterArg === "default"
|
||||
? category.get("default_view") || "latest"
|
||||
: filterArg;
|
||||
},
|
||||
|
||||
_setupNavigation(category) {
|
||||
const noSubcategories = params && !!params.no_subcategories,
|
||||
filterType = this.filter(category).split("/")[0];
|
||||
|
||||
this.controllerFor("navigation/category").setProperties({
|
||||
category,
|
||||
filterType,
|
||||
noSubcategories,
|
||||
});
|
||||
},
|
||||
|
||||
_createSubcategoryList(category) {
|
||||
this._categoryList = null;
|
||||
|
||||
if (category.isParent && category.show_subcategory_list) {
|
||||
return CategoryList.listForParent(this.store, category).then(
|
||||
(list) => (this._categoryList = list)
|
||||
);
|
||||
}
|
||||
|
||||
// If we're not loading a subcategory list just resolve
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
_retrieveTopicList(category, transition, modelParams) {
|
||||
const findOpts = filterQueryParams(modelParams, params);
|
||||
const extras = { cached: this.isPoppedState(transition) };
|
||||
|
||||
let listFilter = `c/${Category.slugFor(category)}/${category.id}`;
|
||||
if (findOpts.no_subcategories) {
|
||||
listFilter += "/none";
|
||||
}
|
||||
listFilter += `/l/${this.filter(category)}`;
|
||||
|
||||
return findTopicList(
|
||||
this.store,
|
||||
this.topicTrackingState,
|
||||
listFilter,
|
||||
findOpts,
|
||||
extras
|
||||
).then((list) => {
|
||||
TopicList.hideUniformCategory(list, category);
|
||||
this.set("topics", list);
|
||||
return list;
|
||||
});
|
||||
},
|
||||
|
||||
titleToken() {
|
||||
const category = this.currentModel.category;
|
||||
|
||||
const filterText = I18n.t(
|
||||
"filters." + this.filter(category).replace("/", ".") + ".title"
|
||||
if (category.isParent && category.show_subcategory_list) {
|
||||
return CategoryList.listForParent(this.store, category).then(
|
||||
(list) => (this._categoryList = list)
|
||||
);
|
||||
}
|
||||
|
||||
let categoryName = category.name;
|
||||
if (category.parent_category_id) {
|
||||
const list = Category.list();
|
||||
const parentCategory = list.findBy("id", category.parent_category_id);
|
||||
categoryName = `${parentCategory.name}/${categoryName}`;
|
||||
}
|
||||
// If we're not loading a subcategory list just resolve
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
return I18n.t("filters.with_category", {
|
||||
filter: filterText,
|
||||
category: categoryName,
|
||||
});
|
||||
},
|
||||
_retrieveTopicList(category, transition, modelParams) {
|
||||
const findOpts = filterQueryParams(modelParams, this.routeConfig);
|
||||
const extras = { cached: this.isPoppedState(transition) };
|
||||
|
||||
setupController(controller, model) {
|
||||
const topics = this.topics,
|
||||
category = model.category,
|
||||
canCreateTopic = topics.get("can_create_topic");
|
||||
let listFilter = `c/${Category.slugFor(category)}/${category.id}`;
|
||||
if (findOpts.no_subcategories) {
|
||||
listFilter += "/none";
|
||||
}
|
||||
listFilter += `/l/${this.filter(category)}`;
|
||||
|
||||
let canCreateTopicOnCategory =
|
||||
canCreateTopic && category.get("permission") === PermissionType.FULL;
|
||||
let cannotCreateTopicOnCategory = !canCreateTopicOnCategory;
|
||||
let defaultSubcategory;
|
||||
let canCreateTopicOnSubCategory;
|
||||
return findTopicList(
|
||||
this.store,
|
||||
this.topicTrackingState,
|
||||
listFilter,
|
||||
findOpts,
|
||||
extras
|
||||
).then((list) => {
|
||||
TopicList.hideUniformCategory(list, category);
|
||||
this.set("topics", list);
|
||||
return list;
|
||||
});
|
||||
},
|
||||
|
||||
if (this.siteSettings.default_subcategory_on_read_only_category) {
|
||||
cannotCreateTopicOnCategory = false;
|
||||
titleToken() {
|
||||
const category = this.currentModel.category;
|
||||
|
||||
if (!canCreateTopicOnCategory && category.subcategories) {
|
||||
defaultSubcategory = category.subcategories.find((subcategory) => {
|
||||
return subcategory.get("permission") === PermissionType.FULL;
|
||||
});
|
||||
canCreateTopicOnSubCategory = !!defaultSubcategory;
|
||||
}
|
||||
}
|
||||
const filterText = I18n.t(
|
||||
"filters." + this.filter(category).replace("/", ".") + ".title"
|
||||
);
|
||||
|
||||
this.controllerFor("navigation/category").setProperties({
|
||||
canCreateTopicOnCategory,
|
||||
cannotCreateTopicOnCategory,
|
||||
canCreateTopic,
|
||||
canCreateTopicOnSubCategory,
|
||||
defaultSubcategory,
|
||||
});
|
||||
let categoryName = category.name;
|
||||
if (category.parent_category_id) {
|
||||
const list = Category.list();
|
||||
const parentCategory = list.findBy("id", category.parent_category_id);
|
||||
categoryName = `${parentCategory.name}/${categoryName}`;
|
||||
}
|
||||
|
||||
let topicOpts = {
|
||||
model: topics,
|
||||
category,
|
||||
period:
|
||||
topics.get("for_period") ||
|
||||
(model.modelParams && model.modelParams.period),
|
||||
selected: [],
|
||||
noSubcategories: params && !!params.no_subcategories,
|
||||
expandAllPinned: true,
|
||||
canCreateTopic,
|
||||
canCreateTopicOnCategory,
|
||||
canCreateTopicOnSubCategory,
|
||||
defaultSubcategory,
|
||||
};
|
||||
return I18n.t("filters.with_category", {
|
||||
filter: filterText,
|
||||
category: categoryName,
|
||||
});
|
||||
},
|
||||
|
||||
const p = category.get("params");
|
||||
if (p && Object.keys(p).length) {
|
||||
if (p.order !== undefined) {
|
||||
topicOpts.order = p.order;
|
||||
}
|
||||
if (p.ascending !== undefined) {
|
||||
topicOpts.ascending = p.ascending;
|
||||
}
|
||||
}
|
||||
setupController(controller, model) {
|
||||
const topics = this.topics,
|
||||
category = model.category,
|
||||
canCreateTopic = topics.get("can_create_topic");
|
||||
|
||||
this.controllerFor("discovery/topics").setProperties(topicOpts);
|
||||
this.searchService.searchContext = category.get("searchContext");
|
||||
this.set("topics", null);
|
||||
},
|
||||
let canCreateTopicOnCategory =
|
||||
canCreateTopic && category.get("permission") === PermissionType.FULL;
|
||||
let cannotCreateTopicOnCategory = !canCreateTopicOnCategory;
|
||||
let defaultSubcategory;
|
||||
let canCreateTopicOnSubCategory;
|
||||
|
||||
renderTemplate() {
|
||||
this.render("navigation/category", { outlet: "navigation-bar" });
|
||||
if (this.siteSettings.default_subcategory_on_read_only_category) {
|
||||
cannotCreateTopicOnCategory = false;
|
||||
|
||||
if (this._categoryList) {
|
||||
this.render("discovery/categories", {
|
||||
outlet: "header-list-container",
|
||||
model: this._categoryList,
|
||||
if (!canCreateTopicOnCategory && category.subcategories) {
|
||||
defaultSubcategory = category.subcategories.find((subcategory) => {
|
||||
return subcategory.get("permission") === PermissionType.FULL;
|
||||
});
|
||||
} else {
|
||||
this.disconnectOutlet({ outlet: "header-list-container" });
|
||||
canCreateTopicOnSubCategory = !!defaultSubcategory;
|
||||
}
|
||||
this.render("discovery/topics", {
|
||||
controller: "discovery/topics",
|
||||
outlet: "list-container",
|
||||
}
|
||||
|
||||
this.controllerFor("navigation/category").setProperties({
|
||||
canCreateTopicOnCategory,
|
||||
cannotCreateTopicOnCategory,
|
||||
canCreateTopic,
|
||||
canCreateTopicOnSubCategory,
|
||||
defaultSubcategory,
|
||||
});
|
||||
|
||||
let topicOpts = {
|
||||
model: topics,
|
||||
category,
|
||||
period:
|
||||
topics.get("for_period") ||
|
||||
(model.modelParams && model.modelParams.period),
|
||||
selected: [],
|
||||
noSubcategories: this.routeConfig && !!this.routeConfig.no_subcategories,
|
||||
expandAllPinned: true,
|
||||
canCreateTopic,
|
||||
canCreateTopicOnCategory,
|
||||
canCreateTopicOnSubCategory,
|
||||
defaultSubcategory,
|
||||
};
|
||||
|
||||
const p = category.get("params");
|
||||
if (p && Object.keys(p).length) {
|
||||
if (p.order !== undefined) {
|
||||
topicOpts.order = p.order;
|
||||
}
|
||||
if (p.ascending !== undefined) {
|
||||
topicOpts.ascending = p.ascending;
|
||||
}
|
||||
}
|
||||
|
||||
this.controllerFor("discovery/topics").setProperties(topicOpts);
|
||||
this.searchService.searchContext = category.get("searchContext");
|
||||
this.set("topics", null);
|
||||
},
|
||||
|
||||
renderTemplate() {
|
||||
this.render("navigation/category", { outlet: "navigation-bar" });
|
||||
|
||||
if (this._categoryList) {
|
||||
this.render("discovery/categories", {
|
||||
outlet: "header-list-container",
|
||||
model: this._categoryList,
|
||||
});
|
||||
},
|
||||
} else {
|
||||
this.disconnectOutlet({ outlet: "header-list-container" });
|
||||
}
|
||||
this.render("discovery/topics", {
|
||||
controller: "discovery/topics",
|
||||
outlet: "list-container",
|
||||
});
|
||||
},
|
||||
|
||||
deactivate() {
|
||||
this._super(...arguments);
|
||||
deactivate() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.composer.set("prioritizedCategoryId", null);
|
||||
this.searchService.searchContext = null;
|
||||
},
|
||||
this.composer.set("prioritizedCategoryId", null);
|
||||
this.searchService.searchContext = null;
|
||||
},
|
||||
|
||||
@action
|
||||
setNotification(notification_level) {
|
||||
this.currentModel.setNotification(notification_level);
|
||||
},
|
||||
@action
|
||||
setNotification(notification_level) {
|
||||
this.currentModel.setNotification(notification_level);
|
||||
},
|
||||
|
||||
@action
|
||||
triggerRefresh() {
|
||||
this.refresh();
|
||||
},
|
||||
@action
|
||||
triggerRefresh() {
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
@action
|
||||
changeSort(sortBy) {
|
||||
changeSort.call(this, sortBy);
|
||||
},
|
||||
@action
|
||||
changeSort(sortBy) {
|
||||
changeSort.call(this, sortBy);
|
||||
},
|
||||
|
||||
@action
|
||||
resetParams(skipParams = []) {
|
||||
resetParams.call(this, skipParams);
|
||||
},
|
||||
});
|
||||
};
|
||||
@action
|
||||
resetParams(skipParams = []) {
|
||||
resetParams.call(this, skipParams);
|
||||
},
|
||||
});
|
||||
|
||||
// A helper function to create a category route with parameters
|
||||
export default function buildCategoryRoute(routeConfig) {
|
||||
return AbstractCategoryRoute.extend({ routeConfig });
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue