mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FIX: Show "no category" in category-chooser (#25917)
CategoryChooser component usually displays just categories, but sometimes it can show two none values: a "no category" or Uncategorized. This commit makes sure that these are rendered correctly. The problem was that the "none" item was automatically inserted in the list of options, but that should not always happen. Toggling option `autoInsertNoneItem` requires setting `none` too.
This commit is contained in:
@@ -19,13 +19,13 @@
|
||||
<label>{{i18n "category.parent"}}</label>
|
||||
<CategoryChooser
|
||||
@value={{this.category.parent_category_id}}
|
||||
@categories={{this.parentCategories}}
|
||||
@allowSubCategories={{true}}
|
||||
@allowRestrictedCategories={{true}}
|
||||
@onChange={{action (mut this.category.parent_category_id)}}
|
||||
@options={{hash
|
||||
allowUncategorized=false
|
||||
excludeCategoryId=this.category.id
|
||||
autoInsertNoneItem=true
|
||||
none=true
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -176,6 +176,25 @@ export default class Category extends RestModel {
|
||||
return category;
|
||||
}
|
||||
|
||||
static async asyncFindBySlugPath(slugPath, opts = {}) {
|
||||
const data = { slug_path: slugPath };
|
||||
if (opts.includePermissions) {
|
||||
data.include_permissions = true;
|
||||
}
|
||||
|
||||
const result = await ajax("/categories/find", { data });
|
||||
|
||||
const categories = result["categories"].map((category) => {
|
||||
category = Site.current().updateCategory(category);
|
||||
if (opts.includePermissions) {
|
||||
category.setupGroupsAndPermissions();
|
||||
}
|
||||
return category;
|
||||
});
|
||||
|
||||
return categories[categories.length - 1];
|
||||
}
|
||||
|
||||
static async asyncFindBySlugPathWithID(slugPathWithID) {
|
||||
const result = await ajax("/categories/find", {
|
||||
data: { slug_path_with_id: slugPathWithID },
|
||||
|
||||
@@ -7,11 +7,9 @@ export default DiscourseRoute.extend({
|
||||
router: service(),
|
||||
|
||||
model(params) {
|
||||
return Category.reloadCategoryWithPermissions(
|
||||
params,
|
||||
this.store,
|
||||
this.site
|
||||
);
|
||||
return this.site.lazy_load_categories
|
||||
? Category.asyncFindBySlugPath(params.slug, { includePermissions: true })
|
||||
: Category.reloadCategoryWithPermissions(params, this.store, this.site);
|
||||
},
|
||||
|
||||
afterModel(model) {
|
||||
|
||||
@@ -145,6 +145,36 @@ acceptance("Category Edit", function (needs) {
|
||||
assert.deepEqual(removePayload.allowed_tag_groups, []);
|
||||
});
|
||||
|
||||
test("Editing parent category (disabled Uncategorized)", async function (assert) {
|
||||
this.siteSettings.allow_uncategorized_topics = false;
|
||||
|
||||
await visit("/c/bug/edit");
|
||||
const categoryChooser = selectKit(".category-chooser");
|
||||
await categoryChooser.expand();
|
||||
await categoryChooser.selectRowByValue(6);
|
||||
|
||||
await categoryChooser.expand();
|
||||
|
||||
const names = [...categoryChooser.rows()].map((row) => row.dataset.name);
|
||||
assert.ok(names.includes("(no category)"));
|
||||
assert.notOk(names.includes("Uncategorized"));
|
||||
});
|
||||
|
||||
test("Editing parent category (enabled Uncategorized)", async function (assert) {
|
||||
this.siteSettings.allow_uncategorized_topics = true;
|
||||
|
||||
await visit("/c/bug/edit");
|
||||
const categoryChooser = selectKit(".category-chooser");
|
||||
await categoryChooser.expand();
|
||||
await categoryChooser.selectRowByValue(6);
|
||||
|
||||
await categoryChooser.expand();
|
||||
|
||||
const names = [...categoryChooser.rows()].map((row) => row.dataset.name);
|
||||
assert.ok(names.includes("(no category)"));
|
||||
assert.notOk(names.includes("Uncategorized"));
|
||||
});
|
||||
|
||||
test("Index Route", async function (assert) {
|
||||
await visit("/c/bug/edit");
|
||||
assert.strictEqual(
|
||||
|
||||
@@ -12,12 +12,13 @@ import ComboBoxComponent from "select-kit/components/combo-box";
|
||||
export default ComboBoxComponent.extend({
|
||||
pluginApiIdentifiers: ["category-chooser"],
|
||||
classNames: ["category-chooser"],
|
||||
allowUncategorizedTopics: setting("allow_uncategorized_topics"),
|
||||
allowUncategorized: setting("allow_uncategorized_topics"),
|
||||
fixedCategoryPositionsOnCreate: setting("fixed_category_positions_on_create"),
|
||||
|
||||
selectKitOptions: {
|
||||
filterable: true,
|
||||
allowUncategorized: false,
|
||||
allowUncategorized: "allowUncategorized",
|
||||
autoInsertNoneItem: false,
|
||||
allowSubCategories: true,
|
||||
permissionType: PermissionType.FULL,
|
||||
excludeCategoryId: null,
|
||||
@@ -30,6 +31,7 @@ export default ComboBoxComponent.extend({
|
||||
|
||||
if (
|
||||
this.site.lazy_load_categories &&
|
||||
this.value &&
|
||||
!Category.hasAsyncFoundAll([this.value])
|
||||
) {
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -54,10 +56,7 @@ export default ComboBoxComponent.extend({
|
||||
I18n.t(isString ? this.selectKit.options.none : "category.none")
|
||||
)
|
||||
);
|
||||
} else if (
|
||||
this.allowUncategorizedTopics ||
|
||||
this.selectKit.options.allowUncategorized
|
||||
) {
|
||||
} else if (this.selectKit.options.allowUncategorized) {
|
||||
return Category.findUncategorized();
|
||||
} else {
|
||||
const defaultCategoryId = parseInt(
|
||||
@@ -94,8 +93,10 @@ export default ComboBoxComponent.extend({
|
||||
search(filter) {
|
||||
if (this.site.lazy_load_categories) {
|
||||
return Category.asyncSearch(this._normalize(filter), {
|
||||
scopedCategoryId: this.selectKit.options?.scopedCategoryId,
|
||||
prioritizedCategoryId: this.selectKit.options?.prioritizedCategoryId,
|
||||
includeUncategorized: this.selectKit.options.allowUncategorized,
|
||||
rejectCategoryIds: [this.selectKit.options.excludeCategoryId],
|
||||
scopedCategoryId: this.selectKit.options.scopedCategoryId,
|
||||
prioritizedCategoryId: this.selectKit.options.prioritizedCategoryId,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ export default ComboBoxComponent.extend({
|
||||
navigateToEdit: false,
|
||||
editingCategory: false,
|
||||
editingCategoryTab: null,
|
||||
allowUncategorized: setting("allow_uncategorized_topics"),
|
||||
|
||||
selectKitOptions: {
|
||||
filterable: true,
|
||||
@@ -40,7 +41,7 @@ export default ComboBoxComponent.extend({
|
||||
displayCategoryDescription: "displayCategoryDescription",
|
||||
headerComponent: "category-drop/category-drop-header",
|
||||
parentCategory: false,
|
||||
allowUncategorized: setting("allow_uncategorized_topics"),
|
||||
allowUncategorized: "allowUncategorized",
|
||||
},
|
||||
|
||||
modifyComponentForRow() {
|
||||
|
||||
@@ -303,9 +303,17 @@ class CategoriesController < ApplicationController
|
||||
|
||||
def find
|
||||
categories = []
|
||||
serializer = params[:include_permissions] ? CategorySerializer : SiteCategorySerializer
|
||||
|
||||
if params[:ids].present?
|
||||
categories = Category.secured(guardian).where(id: params[:ids])
|
||||
elsif params[:slug_path].present?
|
||||
category = Category.find_by_slug_path(params[:slug_path].split("/"))
|
||||
raise Discourse::NotFound if category.blank?
|
||||
guardian.ensure_can_see!(category)
|
||||
|
||||
ancestors = Category.secured(guardian).with_ancestors(category.id).where.not(id: category.id)
|
||||
categories = [*ancestors, category]
|
||||
elsif params[:slug_path_with_id].present?
|
||||
category = Category.find_by_slug_path_with_id(params[:slug_path_with_id])
|
||||
raise Discourse::NotFound if category.blank?
|
||||
@@ -319,7 +327,7 @@ class CategoriesController < ApplicationController
|
||||
|
||||
Category.preload_user_fields!(guardian, categories)
|
||||
|
||||
render_serialized(categories, SiteCategorySerializer, root: :categories, scope: guardian)
|
||||
render_serialized(categories, serializer, root: :categories, scope: guardian)
|
||||
end
|
||||
|
||||
def search
|
||||
@@ -333,8 +341,12 @@ class CategoriesController < ApplicationController
|
||||
true
|
||||
end
|
||||
)
|
||||
select_category_ids = params[:select_category_ids].presence
|
||||
reject_category_ids = params[:reject_category_ids].presence
|
||||
if params[:select_category_ids].is_a?(Array)
|
||||
select_category_ids = params[:select_category_ids].map(&:presence)
|
||||
end
|
||||
if params[:reject_category_ids].is_a?(Array)
|
||||
reject_category_ids = params[:reject_category_ids].map(&:presence)
|
||||
end
|
||||
include_subcategories =
|
||||
if params[:include_subcategories].present?
|
||||
ActiveModel::Type::Boolean.new.cast(params[:include_subcategories])
|
||||
|
||||
Reference in New Issue
Block a user