mirror of
https://github.com/discourse/discourse.git
synced 2026-08-05 10:47:46 -05:00
DEV: code improvements to upsert category (#37572)
Follow-up to #37540. This continues the code cleanup work for the upsert-category components. Changes: - consolidate 8 upload actions into a single pair using fn partial application to reduce repetition - move appearance-related properties (views, sorts, periods, filters, subcategory list styles) from settings to appearance where they actually belong - use site.periods as the single source of truth for top periods instead of hardcoding values - add none option to ComboBoxes so values can be cleared back to default - remove enable_simplified_category_creation guard from text_color and slug fields since they should always be available - remove unnecessary placementStrategy="absolute" from ComboBoxes - add missing "hot" to available default views - pass form to category-email-in plugin outlet so plugins can use it - rename properties for consistency (eg. availableSorts → sortOrders, parentIsRestricted → isParentRestricted) Ref - t/173336
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { cached } from "@glimmer/tracking";
|
||||
import { hash } from "@ember/helper";
|
||||
import { fn, hash } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import PluginOutlet from "discourse/components/plugin-outlet";
|
||||
@@ -14,7 +13,7 @@ import { eq } from "discourse/truth-helpers";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
export default class UpsertCategoryAppearance extends Component {
|
||||
@service siteSettings;
|
||||
@service site;
|
||||
|
||||
get isDefaultSortOrder() {
|
||||
return !this.args.transientData?.sort_order;
|
||||
@@ -36,7 +35,7 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
return this.args.transientData?.uploaded_logo?.url ?? "";
|
||||
}
|
||||
|
||||
get logoImageDarkUrl() {
|
||||
get logoDarkImageUrl() {
|
||||
return this.args.transientData?.uploaded_logo_dark?.url ?? "";
|
||||
}
|
||||
|
||||
@@ -48,52 +47,13 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
}
|
||||
|
||||
@action
|
||||
logoUploadDone(upload) {
|
||||
this.args.form.set("uploaded_logo", { url: upload.url, id: upload.id });
|
||||
onUploadDone(field, upload) {
|
||||
this.args.form.set(field, { url: upload.url, id: upload.id });
|
||||
}
|
||||
|
||||
@action
|
||||
logoUploadDeleted() {
|
||||
this.args.form.set("uploaded_logo", { id: null, url: null });
|
||||
}
|
||||
|
||||
@action
|
||||
logoDarkUploadDone(upload) {
|
||||
this.args.form.set("uploaded_logo_dark", {
|
||||
url: upload.url,
|
||||
id: upload.id,
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
logoDarkUploadDeleted() {
|
||||
this.args.form.set("uploaded_logo_dark", { id: null, url: null });
|
||||
}
|
||||
|
||||
@action
|
||||
backgroundUploadDone(upload) {
|
||||
this.args.form.set("uploaded_background", {
|
||||
url: upload.url,
|
||||
id: upload.id,
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
backgroundUploadDeleted() {
|
||||
this.args.form.set("uploaded_background", { id: null, url: null });
|
||||
}
|
||||
|
||||
@action
|
||||
backgroundDarkUploadDone(upload) {
|
||||
this.args.form.set("uploaded_background_dark", {
|
||||
url: upload.url,
|
||||
id: upload.id,
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
backgroundDarkUploadDeleted() {
|
||||
this.args.form.set("uploaded_background_dark", { id: null, url: null });
|
||||
onUploadDeleted(field) {
|
||||
this.args.form.set(field, { id: null, url: null });
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -101,8 +61,7 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
this.args.form.set("sort_ascending", value);
|
||||
}
|
||||
|
||||
@cached
|
||||
get availableSubcategoryListStyles() {
|
||||
get subcategoryListStyles() {
|
||||
return [
|
||||
{ name: i18n("category.subcategory_list_styles.rows"), value: "rows" },
|
||||
{
|
||||
@@ -124,12 +83,11 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
];
|
||||
}
|
||||
|
||||
@cached
|
||||
get availableViews() {
|
||||
const views = [
|
||||
{ name: i18n("filters.latest.title"), value: "latest" },
|
||||
{ name: i18n("filters.top.title"), value: "top" },
|
||||
];
|
||||
const views = ["hot", "latest", "top"].map((value) => ({
|
||||
name: i18n(`filters.${value}.title`),
|
||||
value,
|
||||
}));
|
||||
|
||||
const context = {
|
||||
categoryId: this.args.category.id,
|
||||
@@ -143,21 +101,21 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
get availableTopPeriods() {
|
||||
return ["all", "yearly", "quarterly", "monthly", "weekly", "daily"].map(
|
||||
(p) => {
|
||||
return { name: i18n(`filters.top.${p}.title`), value: p };
|
||||
}
|
||||
);
|
||||
get topPeriods() {
|
||||
return this.site.periods.map((value) => ({
|
||||
name: i18n(`filters.top.${value}.title`),
|
||||
value,
|
||||
}));
|
||||
}
|
||||
|
||||
get availableListFilters() {
|
||||
return ["all", "none"].map((p) => {
|
||||
return { name: i18n(`category.list_filters.${p}`), value: p };
|
||||
});
|
||||
get listFilters() {
|
||||
return ["all", "none"].map((value) => ({
|
||||
name: i18n(`category.list_filters.${value}`),
|
||||
value,
|
||||
}));
|
||||
}
|
||||
|
||||
get availableSorts() {
|
||||
get sortOrders() {
|
||||
return applyMutableValueTransformer("category-sort-orders", [
|
||||
"likes",
|
||||
"op_likes",
|
||||
@@ -204,8 +162,8 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
>
|
||||
<UppyImageUploader
|
||||
@imageUrl={{this.logoImageUrl}}
|
||||
@onUploadDone={{this.logoUploadDone}}
|
||||
@onUploadDeleted={{this.logoUploadDeleted}}
|
||||
@onUploadDone={{fn this.onUploadDone "uploaded_logo"}}
|
||||
@onUploadDeleted={{fn this.onUploadDeleted "uploaded_logo"}}
|
||||
@type="category_logo"
|
||||
@id="category-logo-uploader"
|
||||
class="no-repeat contain-image"
|
||||
@@ -217,9 +175,9 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
@subtitle={{i18n "category.logo_description"}}
|
||||
>
|
||||
<UppyImageUploader
|
||||
@imageUrl={{this.logoImageDarkUrl}}
|
||||
@onUploadDone={{this.logoDarkUploadDone}}
|
||||
@onUploadDeleted={{this.logoDarkUploadDeleted}}
|
||||
@imageUrl={{this.logoDarkImageUrl}}
|
||||
@onUploadDone={{fn this.onUploadDone "uploaded_logo_dark"}}
|
||||
@onUploadDeleted={{fn this.onUploadDeleted "uploaded_logo_dark"}}
|
||||
@type="category_logo_dark"
|
||||
@id="category-dark-logo-uploader"
|
||||
class="no-repeat contain-image"
|
||||
@@ -229,8 +187,8 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
<@form.Container @title={{i18n "category.background_image"}}>
|
||||
<UppyImageUploader
|
||||
@imageUrl={{this.backgroundImageUrl}}
|
||||
@onUploadDone={{this.backgroundUploadDone}}
|
||||
@onUploadDeleted={{this.backgroundUploadDeleted}}
|
||||
@onUploadDone={{fn this.onUploadDone "uploaded_background"}}
|
||||
@onUploadDeleted={{fn this.onUploadDeleted "uploaded_background"}}
|
||||
@type="category_background"
|
||||
@id="category-background-uploader"
|
||||
/>
|
||||
@@ -239,24 +197,24 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
<@form.Container @title={{i18n "category.background_image_dark"}}>
|
||||
<UppyImageUploader
|
||||
@imageUrl={{this.backgroundDarkImageUrl}}
|
||||
@onUploadDone={{this.backgroundDarkUploadDone}}
|
||||
@onUploadDeleted={{this.backgroundDarkUploadDeleted}}
|
||||
@onUploadDone={{fn this.onUploadDone "uploaded_background_dark"}}
|
||||
@onUploadDeleted={{fn
|
||||
this.onUploadDeleted
|
||||
"uploaded_background_dark"
|
||||
}}
|
||||
@type="category_background_dark"
|
||||
@id="category-dark-background-uploader"
|
||||
/>
|
||||
</@form.Container>
|
||||
|
||||
{{! This field is removed from edit-category-general when the UC is active }}
|
||||
{{#if this.siteSettings.enable_simplified_category_creation}}
|
||||
<@form.Field
|
||||
@name="text_color"
|
||||
@title={{i18n "category.foreground_color"}}
|
||||
@format="large"
|
||||
as |field|
|
||||
>
|
||||
<field.Color @colors={{CATEGORY_TEXT_COLORS}} />
|
||||
</@form.Field>
|
||||
{{/if}}
|
||||
<@form.Field
|
||||
@name="text_color"
|
||||
@title={{i18n "category.foreground_color"}}
|
||||
@format="large"
|
||||
as |field|
|
||||
>
|
||||
<field.Color @colors={{CATEGORY_TEXT_COLORS}} />
|
||||
</@form.Field>
|
||||
|
||||
<@form.Field
|
||||
@name="default_view"
|
||||
@@ -266,12 +224,12 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
>
|
||||
<field.Custom>
|
||||
<ComboBox
|
||||
@valueProperty="value"
|
||||
@id="category-default-view"
|
||||
@content={{this.availableViews}}
|
||||
@value={{field.value}}
|
||||
@valueProperty="value"
|
||||
@onChange={{field.set}}
|
||||
@options={{hash placementStrategy="absolute"}}
|
||||
@options={{hash none="category.sort_options.default"}}
|
||||
/>
|
||||
</field.Custom>
|
||||
</@form.Field>
|
||||
@@ -284,12 +242,12 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
>
|
||||
<field.Custom>
|
||||
<ComboBox
|
||||
@valueProperty="value"
|
||||
@id="category-default-period"
|
||||
@content={{this.availableTopPeriods}}
|
||||
@id="category-default-top-period"
|
||||
@content={{this.topPeriods}}
|
||||
@value={{field.value}}
|
||||
@valueProperty="value"
|
||||
@onChange={{field.set}}
|
||||
@options={{hash placementStrategy="absolute"}}
|
||||
@options={{hash none="category.sort_options.default"}}
|
||||
/>
|
||||
</field.Custom>
|
||||
</@form.Field>
|
||||
@@ -302,22 +260,22 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
>
|
||||
<field.Custom>
|
||||
<ComboBox
|
||||
@valueProperty="value"
|
||||
@content={{this.availableSorts}}
|
||||
@id="category-sort-order"
|
||||
@content={{this.sortOrders}}
|
||||
@value={{field.value}}
|
||||
@options={{hash none="category.sort_options.default"}}
|
||||
@valueProperty="value"
|
||||
@onChange={{field.set}}
|
||||
@options={{hash none="category.sort_options.default"}}
|
||||
/>
|
||||
|
||||
{{#unless this.isDefaultSortOrder}}
|
||||
<ComboBox
|
||||
@valueProperty="value"
|
||||
@id="category-sort-ascending"
|
||||
@content={{this.sortAscendingOptions}}
|
||||
@value={{this.sortAscendingOption}}
|
||||
@options={{hash
|
||||
none="category.sort_options.default"
|
||||
placementStrategy="absolute"
|
||||
}}
|
||||
@valueProperty="value"
|
||||
@onChange={{this.onSortAscendingChange}}
|
||||
@options={{hash none="category.sort_options.default"}}
|
||||
/>
|
||||
{{/unless}}
|
||||
</field.Custom>
|
||||
@@ -331,11 +289,12 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
>
|
||||
<field.Custom>
|
||||
<ComboBox
|
||||
@id="category-default-filter"
|
||||
@valueProperty="value"
|
||||
@content={{this.availableListFilters}}
|
||||
@id="category-default-list-filter"
|
||||
@content={{this.listFilters}}
|
||||
@value={{field.value}}
|
||||
@valueProperty="value"
|
||||
@onChange={{field.set}}
|
||||
@options={{hash none="category.sort_options.default"}}
|
||||
/>
|
||||
</field.Custom>
|
||||
</@form.Field>
|
||||
@@ -359,12 +318,11 @@ export default class UpsertCategoryAppearance extends Component {
|
||||
>
|
||||
<field.Custom>
|
||||
<ComboBox
|
||||
@valueProperty="value"
|
||||
@id="subcategory-list-style"
|
||||
@content={{this.availableSubcategoryListStyles}}
|
||||
@content={{this.subcategoryListStyles}}
|
||||
@value={{field.value}}
|
||||
@valueProperty="value"
|
||||
@onChange={{field.set}}
|
||||
@options={{hash placementStrategy="absolute"}}
|
||||
/>
|
||||
</field.Custom>
|
||||
</@form.Field>
|
||||
|
||||
@@ -49,7 +49,7 @@ export default class UpsertCategorySecurity extends Component {
|
||||
: parent.group_permissions;
|
||||
}
|
||||
|
||||
get parentIsRestricted() {
|
||||
get isParentRestricted() {
|
||||
const parentPerms = this.parentPermissions;
|
||||
if (!parentPerms?.length) {
|
||||
return false;
|
||||
@@ -64,7 +64,7 @@ export default class UpsertCategorySecurity extends Component {
|
||||
|
||||
let groups = this.site.groups.filter((g) => !permissionGroupIds.has(g.id));
|
||||
|
||||
if (this.parentIsRestricted) {
|
||||
if (this.isParentRestricted) {
|
||||
const parentGroupIds = new Set(
|
||||
this.parentPermissions.map((p) => p.group_id)
|
||||
);
|
||||
@@ -79,7 +79,7 @@ export default class UpsertCategorySecurity extends Component {
|
||||
}
|
||||
|
||||
get allParentGroupsUsed() {
|
||||
return this.parentIsRestricted && !this.hasAvailableGroups;
|
||||
return this.isParentRestricted && !this.hasAvailableGroups;
|
||||
}
|
||||
|
||||
get everyonePermission() {
|
||||
|
||||
@@ -11,7 +11,6 @@ import lazyHash from "discourse/helpers/lazy-hash";
|
||||
import withEventValue from "discourse/helpers/with-event-value";
|
||||
import { SEARCH_PRIORITIES } from "discourse/lib/constants";
|
||||
import getUrl from "discourse/lib/get-url";
|
||||
import { applyMutableValueTransformer } from "discourse/lib/transformer";
|
||||
import ComboBox from "discourse/select-kit/components/combo-box";
|
||||
import GroupChooser from "discourse/select-kit/components/group-chooser";
|
||||
import { eq } from "discourse/truth-helpers";
|
||||
@@ -29,68 +28,6 @@ export default class UpsertCategorySettings extends Component {
|
||||
return this.siteSettings.fixed_category_positions;
|
||||
}
|
||||
|
||||
get isParentCategory() {
|
||||
const parentCategoryId =
|
||||
this.args.transientData?.parent_category_id ??
|
||||
this.args.category.parent_category_id;
|
||||
return this.args.category.isParent || !parentCategoryId;
|
||||
}
|
||||
|
||||
get availableSubcategoryListStyles() {
|
||||
return [
|
||||
{ name: i18n("category.subcategory_list_styles.rows"), value: "rows" },
|
||||
{
|
||||
name: i18n(
|
||||
"category.subcategory_list_styles.rows_with_featured_topics"
|
||||
),
|
||||
value: "rows_with_featured_topics",
|
||||
},
|
||||
{
|
||||
name: i18n("category.subcategory_list_styles.boxes"),
|
||||
value: "boxes",
|
||||
},
|
||||
{
|
||||
name: i18n(
|
||||
"category.subcategory_list_styles.boxes_with_featured_topics"
|
||||
),
|
||||
value: "boxes_with_featured_topics",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
get availableViews() {
|
||||
const views = [
|
||||
{ name: i18n("filters.hot.title"), value: "hot" },
|
||||
{ name: i18n("filters.latest.title"), value: "latest" },
|
||||
{ name: i18n("filters.top.title"), value: "top" },
|
||||
];
|
||||
|
||||
const context = {
|
||||
categoryId: this.args.category.id,
|
||||
customFields: this.args.category.custom_fields,
|
||||
};
|
||||
|
||||
return applyMutableValueTransformer(
|
||||
"category-available-views",
|
||||
views,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
get availableTopPeriods() {
|
||||
return ["all", "yearly", "quarterly", "monthly", "weekly", "daily"].map(
|
||||
(p) => {
|
||||
return { name: i18n(`filters.top.${p}.title`), value: p };
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get availableListFilters() {
|
||||
return ["all", "none"].map((p) => {
|
||||
return { name: i18n(`category.list_filters.${p}`), value: p };
|
||||
});
|
||||
}
|
||||
|
||||
get searchPrioritiesOptions() {
|
||||
const options = [];
|
||||
|
||||
@@ -106,39 +43,6 @@ export default class UpsertCategorySettings extends Component {
|
||||
return options;
|
||||
}
|
||||
|
||||
get availableSorts() {
|
||||
return applyMutableValueTransformer("category-sort-orders", [
|
||||
"likes",
|
||||
"op_likes",
|
||||
"views",
|
||||
"posts",
|
||||
"activity",
|
||||
"posters",
|
||||
"category",
|
||||
"created",
|
||||
])
|
||||
.map((s) => ({ name: i18n("category.sort_options." + s), value: s }))
|
||||
.toSorted((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
get sortAscendingOption() {
|
||||
const sortAscending = this.args.transientData?.sort_ascending;
|
||||
if (sortAscending === "false") {
|
||||
return false;
|
||||
}
|
||||
if (sortAscending === "true") {
|
||||
return true;
|
||||
}
|
||||
return sortAscending;
|
||||
}
|
||||
|
||||
get sortAscendingOptions() {
|
||||
return [
|
||||
{ name: i18n("category.sort_ascending"), value: true },
|
||||
{ name: i18n("category.sort_descending"), value: false },
|
||||
];
|
||||
}
|
||||
|
||||
get hiddenRelativeIntervals() {
|
||||
return ["mins"];
|
||||
}
|
||||
@@ -237,20 +141,17 @@ export default class UpsertCategorySettings extends Component {
|
||||
(if (eq @selectedTab "settings") "active")
|
||||
}}
|
||||
>
|
||||
{{! This field is removed from edit-category-general when the UC is active }}
|
||||
{{#if this.siteSettings.enable_simplified_category_creation}}
|
||||
<@form.Field
|
||||
@name="slug"
|
||||
@title={{i18n "category.slug"}}
|
||||
@format="large"
|
||||
as |field|
|
||||
>
|
||||
<field.Input
|
||||
placeholder={{i18n "category.slug_placeholder"}}
|
||||
@maxlength="255"
|
||||
/>
|
||||
</@form.Field>
|
||||
{{/if}}
|
||||
<@form.Field
|
||||
@name="slug"
|
||||
@title={{i18n "category.slug"}}
|
||||
@format="large"
|
||||
as |field|
|
||||
>
|
||||
<field.Input
|
||||
placeholder={{i18n "category.slug_placeholder"}}
|
||||
@maxlength="255"
|
||||
/>
|
||||
</@form.Field>
|
||||
|
||||
{{#if this.showPositionInput}}
|
||||
<@form.Field
|
||||
@@ -454,7 +355,7 @@ export default class UpsertCategorySettings extends Component {
|
||||
<PluginOutlet
|
||||
@name="category-email-in"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{lazyHash category=@category}}
|
||||
@outletArgs={{lazyHash category=@category form=@form}}
|
||||
/>
|
||||
{{else}}
|
||||
<@form.Alert @type="info">
|
||||
|
||||
Reference in New Issue
Block a user