DEV: Address review comments

This commit is contained in:
Ted Johansson 2024-11-22 15:34:10 +08:00
parent 9d021187f9
commit 34396d7f52
No known key found for this signature in database
GPG Key ID: 2E801F82D9A4C6E9
17 changed files with 195 additions and 87 deletions

View File

@ -10,6 +10,7 @@ import UserField from "admin/models/user-field";
export default class AdminConfigAreasUserFieldsList extends Component {
@service dialog;
@service store;
@service toasts;
@service adminUserFields;
fieldTypes = UserField.fieldTypes();
@ -60,29 +61,45 @@ export default class AdminConfigAreasUserFieldsList extends Component {
try {
await field.destroyRecord();
this.fields.removeObject(field);
this.toasts.success({
duration: 3000,
data: {
message: i18n("admin.config_areas.user_fields.delete_successful"),
},
});
} catch (error) {
popupAjaxError(error);
}
}
<template>
{{#if this.fields}}
{{#each this.sortedFields as |field|}}
<AdminUserFieldItem
@userField={{field}}
@fieldTypes={{this.fieldTypes}}
@destroyAction={{this.destroyField}}
@moveUpAction={{this.moveUp}}
@moveDownAction={{this.moveDown}}
<div class="container admin-user_fields">
{{#if this.fields}}
<table class="d-admin-table admin-flags__items">
<thead>
<th>{{i18n "admin.config_areas.user_fields.field"}}</th>
<th>{{i18n "admin.config_areas.user_fields.type"}}</th>
</thead>
<tbody>
{{#each this.sortedFields as |field|}}
<AdminUserFieldItem
@userField={{field}}
@fieldTypes={{this.fieldTypes}}
@destroyAction={{this.destroyField}}
@moveUpAction={{this.moveUp}}
@moveDownAction={{this.moveDown}}
/>
{{/each}}
</tbody>
</table>
{{else}}
<AdminConfigAreaEmptyList
@ctaLabel="admin.user_fields.add"
@ctaRoute="adminUserFields.new"
@ctaClass="admin-user_fields__add-emoji"
@emptyLabel="admin.user_fields.no_user_fields"
/>
{{/each}}
{{else}}
<AdminConfigAreaEmptyList
@ctaLabel="admin.user_fields.add"
@ctaRoute="adminUserFields.new"
@ctaClass="admin-user_fields__add-emoji"
@emptyLabel="admin.user_fields.no_user_fields"
/>
{{/if}}
{{/if}}
</div>
</template>
}

View File

@ -1,14 +1,14 @@
import Component from "@glimmer/component";
import { fn } from "@ember/helper";
import { action } from "@ember/object";
import { service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import { tagName } from "@ember-decorators/component";
import DButton from "discourse/components/d-button";
import DropdownMenu from "discourse/components/dropdown-menu";
import { USER_FIELD_FLAGS } from "discourse/lib/constants";
import { i18n } from "discourse-i18n";
import UserField from "admin/models/user-field";
import DMenu from "float-kit/components/d-menu";
@tagName("")
export default class AdminUserFieldItem extends Component {
@service adminUserFields;
@service adminCustomUserFields;
@ -28,65 +28,107 @@ export default class AdminUserFieldItem extends Component {
}
get flags() {
const flags = [
"editable",
"show_on_profile",
"show_on_user_card",
"searchable",
];
return flags
.map((flag) => {
if (this.args.userField[flag]) {
return i18n(`admin.user_fields.${flag}.enabled`);
}
})
return USER_FIELD_FLAGS.map((flag) => {
if (this.args.userField[flag]) {
return i18n(`admin.user_fields.${flag}.enabled`);
}
})
.filter(Boolean)
.join(", ");
}
@action
moveUp() {
this.args.moveUpAction(this.args.userField);
this.dMenu.close();
}
@action
moveDown() {
this.args.moveDownAction(this.args.userField);
this.dMenu.close();
}
@action
destroy() {
this.args.destroyAction(this.args.userField);
this.dMenu.close();
}
@action
onRegisterApi(api) {
this.dMenu = api;
}
@action
edit() {
this.router.transitionTo("adminUserFields.edit", this.args.userField);
}
<template>
<div class="user-field">
<div class="row">
<div class="form-display">
<b class="name">{{@userField.name}}</b>
<br />
<span class="description">{{htmlSafe @userField.description}}</span>
</div>
<div class="form-display field-type">{{@userField.fieldTypeName}}</div>
<div class="form-element controls">
<tr class="d-admin-row__content admin-user_field-item">
<td class="d-admin-row__overview">
<div
class="d-admin-row__overview-name admin-user_field-item__name"
>{{@userField.name}}</div>
<div class="d-admin-row__overview-about">{{htmlSafe
@userField.description
}}</div>
<div class="d-admin-row__overview-flags">{{this.flags}}</div>
</td>
<td class="d-admin-row__detail">
{{@userField.fieldTypeName}}
</td>
<td class="d-admin-row__controls">
<div class="d-admin-row__controls-options">
<DButton
class="btn-small admin-user_field-item__edit"
@action={{this.edit}}
@icon="pencil"
@label="admin.user_fields.edit"
class="btn-default edit"
/>
<DButton
@action={{fn @destroyAction @userField}}
@icon="trash-can"
@label="admin.user_fields.delete"
class="btn-danger cancel"
/>
<DButton
@action={{fn @moveUpAction @userField}}
@icon="arrow-up"
@disabled={{this.cantMoveUp}}
class="btn-default"
/>
<DButton
@action={{fn @moveDownAction @userField}}
@icon="arrow-down"
@disabled={{this.cantMoveDown}}
class="btn-default"
/>
<DMenu
@identifier="user_field-menu"
@title={{i18n "admin.config_areas.user_fields.more_options.title"}}
@icon="ellipsis-vertical"
@onRegisterApi={{this.onRegisterApi}}
>
<:content>
<DropdownMenu as |dropdown|>
{{#unless this.cantMoveUp}}
<dropdown.item>
<DButton
@label="admin.config_areas.user_fields.more_options.move_up"
@icon="arrow-up"
class="btn-transparent admin-user_field-item__move-up"
@action={{this.moveUp}}
/>
</dropdown.item>
{{/unless}}
{{#unless this.cantMoveDown}}
<dropdown.item>
<DButton
@label="admin.config_areas.user_fields.more_options.move_down"
@icon="arrow-down"
class="btn-transparent admin-user_field-item__move-down"
@action={{this.moveDown}}
/>
</dropdown.item>
{{/unless}}
<dropdown.item>
<DButton
@label="admin.config_areas.user_fields.delete"
@icon="trash-can"
class="btn-transparent admin-user_field-item__delete"
@action={{this.destroy}}
/>
</dropdown.item>
</DropdownMenu>
</:content>
</DMenu>
</div>
</div>
<div class="row user-field-flags">{{this.flags}}</div>
</div>
</td>
</tr>
</template>
}

View File

@ -18,6 +18,7 @@ export default class AdminUserFieldsForm extends Component {
@service router;
@service adminUserFields;
@service adminCustomUserFields;
@service toasts;
@tracked
editableDisabled = this.args.userField.requirement === "for_all_users";
@ -83,6 +84,12 @@ export default class AdminUserFieldsForm extends Component {
}
this.router.transitionTo("adminUserFields.index");
this.toasts.success({
duration: 3000,
data: {
message: i18n("admin.config_areas.user_fields.save_successful"),
},
});
} catch (error) {
popupAjaxError(error);
}

View File

@ -1,7 +0,0 @@
import Controller from "@ember/controller";
export default class AdminUserFieldsController extends Controller {
get hideTabs() {
return true;
}
}

View File

@ -73,7 +73,7 @@ export default function () {
{ path: "/user_fields", resetNamespace: true },
function () {
this.route("new");
this.route("edit", { path: "/:id" });
this.route("edit", { path: "/:id/edit" });
this.route("index", { path: "/" });
}
);

View File

@ -2,7 +2,7 @@
<AdminPageHeader
@titleLabel="admin.user_fields.title"
@descriptionLabel="admin.user_fields.help"
@hideTabs={{this.hideTabs}}
@hideTabs={{true}}
>
<:breadcrumbs>
<DBreadcrumbsItem

View File

@ -99,3 +99,10 @@ export const SITE_SETTING_REQUIRES_CONFIRMATION_TYPES = {
};
export const MAX_UNOPTIMIZED_CATEGORIES = 1000;
export const USER_FIELD_FLAGS = [
"editable",
"show_on_profile",
"show_on_user_card",
"searchable",
];

View File

@ -1078,6 +1078,7 @@ a.inline-editable-field {
@import "common/admin/badges";
@import "common/admin/emails";
@import "common/admin/flags";
@import "common/admin/user_fields";
@import "common/admin/json_schema_editor";
@import "common/admin/schema_field";
@import "common/admin/staff_logs";

View File

@ -94,6 +94,16 @@
margin-bottom: 0.1em;
}
}
&-flags {
color: var(--primary-high);
font-size: var(--font-down-1);
text-transform: lowercase;
&::first-letter {
text-transform: uppercase;
}
}
}
.d-admin-row__controls {

View File

@ -0,0 +1,10 @@
.admin-user_field-item {
&__delete.btn,
&__delete.btn:hover {
border-top: 1px solid var(--primary-low);
color: var(--danger);
svg {
color: var(--danger);
}
}
}

View File

@ -30,9 +30,12 @@ class Admin::UserFieldsController < Admin::AdminController
render_serialized(user_fields, UserFieldSerializer, root: "user_fields")
end
def edit
def show
user_field = UserField.find(params[:id])
render_serialized(user_field, UserFieldSerializer, root: "user_field")
render_serialized(user_field, UserFieldSerializer)
end
def edit
end
def update

View File

@ -5,6 +5,8 @@ class UserField < ActiveRecord::Base
include HasDeprecatedColumns
include HasSanitizableFields
FLAG_ATTRIBUTES = %w[editable show_on_profile show_on_user_card searchable].freeze
deprecate_column :required, drop_from: "3.3"
self.ignored_columns += %i[field_type]

View File

@ -5737,6 +5737,16 @@ en:
themes_description: "Themes are expansive customizations that change multiple elements of the style of your forum design, and often also include additional front-end features."
new_theme: "New theme"
user_selectable: "User selectable"
user_fields:
field: "Field"
type: "Type"
more_options:
title: "More options"
move_up: "Move up"
move_down: "Move down"
delete: "Delete"
delete_successful: "User field deleted."
save_successful: "User field saved."
plugins:
title: "Plugins"
installed: "Installed plugins"
@ -6980,20 +6990,20 @@ en:
confirmation: "This will prompt existing users to fill in this field and will not allow them to do anything else on your site until the field is filled. Proceed?"
editable:
title: "Editable after signup"
enabled: "editable"
disabled: "not editable"
enabled: "Editable"
disabled: "Not editable"
show_on_profile:
title: "Show on public profile"
enabled: "shown on profile"
disabled: "not shown on profile"
enabled: "Shown on profile"
disabled: "Not shown on profile"
show_on_user_card:
title: "Show on user card"
enabled: "shown on user card"
disabled: "not shown on user card"
enabled: "Shown on user card"
disabled: "Not shown on user card"
searchable:
title: "Searchable"
enabled: "searchable"
disabled: "not searchable"
enabled: "Searchable"
disabled: "Not searchable"
field_types:
text: "Text Field"

View File

@ -246,7 +246,8 @@ Discourse::Application.routes.draw do
only: %i[index create update destroy],
constraints: AdminConstraint.new
get "user_fields/new" => "user_fields#index"
get "user_fields/:id" => "user_fields#edit"
get "user_fields/:id" => "user_fields#show"
get "user_fields/:id/edit" => "user_fields#edit"
resources :emojis, only: %i[index create destroy], constraints: AdminConstraint.new
get "emojis/new" => "emojis#index"
get "emojis/settings" => "emojis#index"

View File

@ -165,6 +165,8 @@ task "javascript:update_constants" => :environment do
export const SITE_SETTING_REQUIRES_CONFIRMATION_TYPES = #{SiteSettings::TypeSupervisor::REQUIRES_CONFIRMATION_TYPES.to_json};
export const MAX_UNOPTIMIZED_CATEGORIES = #{CategoryList::MAX_UNOPTIMIZED_CATEGORIES};
export const USER_FIELD_FLAGS = #{UserField::FLAG_ATTRIBUTES};
JS
pretty_notifications = Notification.types.map { |n| " #{n[0]}: #{n[1]}," }.join("\n")

View File

@ -63,8 +63,7 @@ describe "Admin User Fields", type: :system do
it "does not require confirmation if the field already applies to all users" do
user_fields_page.visit
page.find(".user-field .edit").click
user_fields_page.click_edit
form = page.find(".user-field")

View File

@ -22,6 +22,10 @@ module PageObjects
page.find(".admin-page-header__actions .btn-primary").click
end
def click_edit
page.find(".admin-user_field-item__edit").click
end
def add_field(name: nil, description: nil, requirement: nil, preferences: [])
click_add_field