@byline/admin 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fields/array/array-field.d.ts +14 -0
- package/dist/fields/array/array-field.js +177 -0
- package/dist/fields/array/array-field.module.js +11 -0
- package/dist/fields/array/array-field_module.css +32 -0
- package/dist/fields/blocks/blocks-field.d.ts +13 -0
- package/dist/fields/blocks/blocks-field.js +245 -0
- package/dist/fields/blocks/blocks-field.module.js +26 -0
- package/dist/fields/blocks/blocks-field_module.css +107 -0
- package/dist/fields/checkbox/checkbox-field.d.ts +16 -0
- package/dist/fields/checkbox/checkbox-field.js +28 -0
- package/dist/fields/checkbox/checkbox-field.module.js +6 -0
- package/dist/fields/checkbox/checkbox-field_module.css +4 -0
- package/dist/fields/column-formatter.d.ts +20 -0
- package/dist/fields/column-formatter.js +15 -0
- package/dist/fields/date-time-formatter.d.ts +16 -0
- package/dist/fields/date-time-formatter.js +8 -0
- package/dist/fields/datetime/datetime-field.d.ts +16 -0
- package/dist/fields/datetime/datetime-field.js +37 -0
- package/dist/fields/datetime/datetime-field.module.js +5 -0
- package/dist/fields/datetime/datetime-field_module.css +4 -0
- package/dist/fields/draggable-context-menu.d.ts +6 -0
- package/dist/fields/draggable-context-menu.js +85 -0
- package/dist/fields/draggable-context-menu.module.js +15 -0
- package/dist/fields/draggable-context-menu_module.css +91 -0
- package/dist/fields/field-helpers.d.ts +26 -0
- package/dist/fields/field-helpers.js +50 -0
- package/dist/fields/field-renderer.d.ts +37 -0
- package/dist/fields/field-renderer.js +206 -0
- package/dist/fields/field-renderer.module.js +8 -0
- package/dist/fields/field-renderer_module.css +11 -0
- package/dist/fields/field-services-context.d.ts +16 -0
- package/dist/fields/field-services-context.js +13 -0
- package/dist/fields/field-services-types.d.ts +63 -0
- package/dist/fields/field-services-types.js +1 -0
- package/dist/fields/file/file-field.d.ts +19 -0
- package/dist/fields/file/file-field.js +225 -0
- package/dist/fields/file/file-field.module.js +18 -0
- package/dist/fields/file/file-field_module.css +131 -0
- package/dist/fields/file/file-upload-field.d.ts +21 -0
- package/dist/fields/file/file-upload-field.js +130 -0
- package/dist/fields/file/file-upload-field.module.js +15 -0
- package/dist/fields/file/file-upload-field_module.css +74 -0
- package/dist/fields/group/group-field.d.ts +15 -0
- package/dist/fields/group/group-field.js +59 -0
- package/dist/fields/group/group-field.module.js +9 -0
- package/dist/fields/group/group-field_module.css +27 -0
- package/dist/fields/image/image-field.d.ts +19 -0
- package/dist/fields/image/image-field.js +241 -0
- package/dist/fields/image/image-field.module.js +22 -0
- package/dist/fields/image/image-field_module.css +121 -0
- package/dist/fields/image/image-upload-field.d.ts +21 -0
- package/dist/fields/image/image-upload-field.js +190 -0
- package/dist/fields/image/image-upload-field.module.js +19 -0
- package/dist/fields/image/image-upload-field_module.css +92 -0
- package/dist/fields/local-date-time.d.ts +27 -0
- package/dist/fields/local-date-time.js +49 -0
- package/dist/fields/locale-badge.d.ts +18 -0
- package/dist/fields/locale-badge.js +10 -0
- package/dist/fields/locale-badge.module.js +5 -0
- package/dist/fields/locale-badge_module.css +27 -0
- package/dist/fields/numerical/numerical-field.d.ts +18 -0
- package/dist/fields/numerical/numerical-field.js +74 -0
- package/dist/fields/relation/relation-display.d.ts +40 -0
- package/dist/fields/relation/relation-display.js +58 -0
- package/dist/fields/relation/relation-display.module.js +9 -0
- package/dist/fields/relation/relation-display_module.css +21 -0
- package/dist/fields/relation/relation-field.d.ts +18 -0
- package/dist/fields/relation/relation-field.js +138 -0
- package/dist/fields/relation/relation-field.module.js +13 -0
- package/dist/fields/relation/relation-field_module.css +62 -0
- package/dist/fields/relation/relation-picker.d.ts +49 -0
- package/dist/fields/relation/relation-picker.js +236 -0
- package/dist/fields/relation/relation-picker.module.js +26 -0
- package/dist/fields/relation/relation-picker_module.css +124 -0
- package/dist/fields/relation/relation-summary.d.ts +31 -0
- package/dist/fields/relation/relation-summary.js +50 -0
- package/dist/fields/relation/relation-summary.module.js +11 -0
- package/dist/fields/relation/relation-summary_module.css +37 -0
- package/dist/fields/select/select-field.d.ts +16 -0
- package/dist/fields/select/select-field.js +50 -0
- package/dist/fields/select/select-field.module.js +5 -0
- package/dist/fields/select/select-field_module.css +4 -0
- package/dist/fields/sortable-item.d.ts +15 -0
- package/dist/fields/sortable-item.js +81 -0
- package/dist/fields/sortable-item.module.js +22 -0
- package/dist/fields/sortable-item_module.css +124 -0
- package/dist/fields/text/text-field.d.ts +20 -0
- package/dist/fields/text/text-field.js +104 -0
- package/dist/fields/text/text-field.module.js +6 -0
- package/dist/fields/text/text-field_module.css +5 -0
- package/dist/fields/text-area/text-area-field.d.ts +20 -0
- package/dist/fields/text-area/text-area-field.js +105 -0
- package/dist/fields/text-area/text-area-field.module.js +6 -0
- package/dist/fields/text-area/text-area-field_module.css +5 -0
- package/dist/fields/use-field-change-handler.d.ts +23 -0
- package/dist/fields/use-field-change-handler.js +52 -0
- package/dist/forms/document-actions.d.ts +48 -0
- package/dist/forms/document-actions.js +475 -0
- package/dist/forms/document-actions.module.js +34 -0
- package/dist/forms/document-actions_module.css +118 -0
- package/dist/forms/form-context.d.ts +89 -0
- package/dist/forms/form-context.js +466 -0
- package/dist/forms/form-renderer.d.ts +98 -0
- package/dist/forms/form-renderer.js +597 -0
- package/dist/forms/form-renderer.module.js +46 -0
- package/dist/forms/form-renderer_module.css +245 -0
- package/dist/forms/navigation-guard.d.ts +54 -0
- package/dist/forms/navigation-guard.js +22 -0
- package/dist/forms/path-widget.d.ts +36 -0
- package/dist/forms/path-widget.js +116 -0
- package/dist/forms/path-widget.module.js +8 -0
- package/dist/forms/path-widget_module.css +29 -0
- package/dist/forms/upload-executor.d.ts +57 -0
- package/dist/forms/upload-executor.js +94 -0
- package/dist/lib/translate-validation-error.d.ts +36 -0
- package/dist/lib/translate-validation-error.js +11 -0
- package/dist/modules/admin-account/commands.d.ts +2 -1
- package/dist/modules/admin-account/commands.js +13 -2
- package/dist/modules/admin-account/components/change-password.js +45 -36
- package/dist/modules/admin-account/components/container.js +185 -134
- package/dist/modules/admin-account/components/preferences.d.ts +8 -0
- package/dist/modules/admin-account/components/preferences.js +152 -0
- package/dist/modules/admin-account/components/preferences.module.js +11 -0
- package/dist/modules/admin-account/components/preferences_module.css +41 -0
- package/dist/modules/admin-account/components/update.js +50 -31
- package/dist/modules/admin-account/index.d.ts +3 -3
- package/dist/modules/admin-account/index.js +2 -2
- package/dist/modules/admin-account/schemas.d.ts +4 -0
- package/dist/modules/admin-account/schemas.js +4 -1
- package/dist/modules/admin-account/service.d.ts +1 -0
- package/dist/modules/admin-account/service.js +8 -0
- package/dist/modules/admin-permissions/components/inspector.js +31 -41
- package/dist/modules/admin-roles/components/create.js +43 -26
- package/dist/modules/admin-roles/components/permissions.js +26 -35
- package/dist/modules/admin-roles/components/update.js +26 -16
- package/dist/modules/admin-users/components/create.js +60 -40
- package/dist/modules/admin-users/components/roles.js +9 -15
- package/dist/modules/admin-users/components/set-password.js +30 -31
- package/dist/modules/admin-users/components/update.js +58 -39
- package/dist/modules/admin-users/dto.js +1 -0
- package/dist/modules/admin-users/repository.d.ts +17 -0
- package/dist/modules/admin-users/schemas.d.ts +4 -0
- package/dist/modules/admin-users/schemas.js +6 -2
- package/dist/modules/auth/components/sign-in-form.js +10 -8
- package/dist/presentation/group.d.ts +27 -0
- package/dist/presentation/group.js +14 -0
- package/dist/presentation/group.module.js +6 -0
- package/dist/presentation/group_module.css +19 -0
- package/dist/presentation/row.d.ts +25 -0
- package/dist/presentation/row.js +8 -0
- package/dist/presentation/row.module.js +5 -0
- package/dist/presentation/row_module.css +18 -0
- package/dist/presentation/tabs.d.ts +25 -0
- package/dist/presentation/tabs.js +39 -0
- package/dist/presentation/tabs.module.js +10 -0
- package/dist/presentation/tabs_module.css +68 -0
- package/dist/react.d.ts +66 -0
- package/dist/react.js +36 -0
- package/dist/services/admin-services-types.d.ts +16 -0
- package/dist/widgets/diff-viewer/diff-modal.d.ts +22 -0
- package/dist/widgets/diff-viewer/diff-modal.js +149 -0
- package/dist/widgets/diff-viewer/diff-modal.module.js +14 -0
- package/dist/widgets/diff-viewer/diff-modal_module.css +56 -0
- package/dist/widgets/status-badge/status-badge.d.ts +25 -0
- package/dist/widgets/status-badge/status-badge.js +37 -0
- package/dist/widgets/status-badge/status-badge.module.js +7 -0
- package/dist/widgets/status-badge/status-badge_module.css +20 -0
- package/package.json +14 -4
- package/src/fields/array/array-field.module.css +48 -0
- package/src/fields/array/array-field.tsx +267 -0
- package/src/fields/blocks/blocks-field.module.css +148 -0
- package/src/fields/blocks/blocks-field.tsx +323 -0
- package/src/fields/checkbox/checkbox-field.module.css +4 -0
- package/src/fields/checkbox/checkbox-field.tsx +54 -0
- package/src/fields/column-formatter.tsx +31 -0
- package/src/fields/date-time-formatter.tsx +22 -0
- package/src/fields/datetime/datetime-field.module.css +13 -0
- package/src/fields/datetime/datetime-field.tsx +54 -0
- package/src/fields/draggable-context-menu.module.css +127 -0
- package/src/fields/draggable-context-menu.tsx +87 -0
- package/src/fields/field-helpers.ts +69 -0
- package/src/fields/field-renderer.module.css +22 -0
- package/src/fields/field-renderer.tsx +288 -0
- package/src/fields/field-services-context.tsx +35 -0
- package/src/fields/field-services-types.ts +68 -0
- package/src/fields/file/file-field.module.css +153 -0
- package/src/fields/file/file-field.tsx +286 -0
- package/src/fields/file/file-upload-field.module.css +101 -0
- package/src/fields/file/file-upload-field.tsx +187 -0
- package/src/fields/group/group-field.module.css +43 -0
- package/src/fields/group/group-field.tsx +84 -0
- package/src/fields/image/image-field.module.css +155 -0
- package/src/fields/image/image-field.tsx +306 -0
- package/src/fields/image/image-upload-field.module.css +123 -0
- package/src/fields/image/image-upload-field.tsx +276 -0
- package/src/fields/local-date-time.tsx +88 -0
- package/src/fields/locale-badge.module.css +37 -0
- package/src/fields/locale-badge.tsx +32 -0
- package/src/fields/numerical/numerical-field.tsx +114 -0
- package/src/fields/relation/relation-display.module.css +36 -0
- package/src/fields/relation/relation-display.tsx +130 -0
- package/src/fields/relation/relation-field.module.css +83 -0
- package/src/fields/relation/relation-field.tsx +211 -0
- package/src/fields/relation/relation-picker.module.css +168 -0
- package/src/fields/relation/relation-picker.tsx +326 -0
- package/src/fields/relation/relation-summary.module.css +55 -0
- package/src/fields/relation/relation-summary.tsx +123 -0
- package/src/fields/select/select-field.module.css +13 -0
- package/src/fields/select/select-field.tsx +61 -0
- package/src/fields/sortable-item.module.css +167 -0
- package/src/fields/sortable-item.tsx +106 -0
- package/src/fields/text/text-field.module.css +13 -0
- package/src/fields/text/text-field.tsx +146 -0
- package/src/fields/text-area/text-area-field.module.css +13 -0
- package/src/fields/text-area/text-area-field.tsx +147 -0
- package/src/fields/use-field-change-handler.ts +112 -0
- package/src/forms/document-actions.module.css +160 -0
- package/src/forms/document-actions.tsx +482 -0
- package/src/forms/form-context.tsx +704 -0
- package/src/forms/form-renderer.module.css +321 -0
- package/src/forms/form-renderer.tsx +891 -0
- package/src/forms/navigation-guard.tsx +98 -0
- package/src/forms/path-widget.module.css +41 -0
- package/src/forms/path-widget.test.tsx +217 -0
- package/src/forms/path-widget.tsx +183 -0
- package/src/forms/upload-executor.ts +192 -0
- package/src/lib/translate-validation-error.ts +56 -0
- package/src/modules/admin-account/commands.ts +13 -0
- package/src/modules/admin-account/components/change-password.tsx +46 -31
- package/src/modules/admin-account/components/container.tsx +83 -38
- package/src/modules/admin-account/components/preferences.module.css +60 -0
- package/src/modules/admin-account/components/preferences.tsx +203 -0
- package/src/modules/admin-account/components/update.tsx +53 -27
- package/src/modules/admin-account/index.ts +3 -0
- package/src/modules/admin-account/schemas.ts +13 -0
- package/src/modules/admin-account/service.ts +12 -0
- package/src/modules/admin-permissions/components/inspector.tsx +22 -14
- package/src/modules/admin-roles/components/create.tsx +51 -23
- package/src/modules/admin-roles/components/permissions.tsx +25 -21
- package/src/modules/admin-roles/components/update.tsx +37 -19
- package/src/modules/admin-users/components/create.tsx +63 -34
- package/src/modules/admin-users/components/roles.tsx +9 -8
- package/src/modules/admin-users/components/set-password.tsx +34 -28
- package/src/modules/admin-users/components/update.tsx +58 -36
- package/src/modules/admin-users/dto.ts +1 -0
- package/src/modules/admin-users/repository.ts +17 -0
- package/src/modules/admin-users/schemas.ts +12 -0
- package/src/modules/auth/components/sign-in-form.tsx +14 -8
- package/src/presentation/group.module.css +41 -0
- package/src/presentation/group.tsx +40 -0
- package/src/presentation/row.module.css +32 -0
- package/src/presentation/row.tsx +33 -0
- package/src/presentation/tabs.module.css +107 -0
- package/src/presentation/tabs.tsx +84 -0
- package/src/react.ts +84 -0
- package/src/services/admin-services-types.ts +18 -0
- package/src/widgets/diff-viewer/diff-modal.module.css +79 -0
- package/src/widgets/diff-viewer/diff-modal.tsx +186 -0
- package/src/widgets/status-badge/status-badge.module.css +31 -0
- package/src/widgets/status-badge/status-badge.tsx +71 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
|
+
import { useTranslation } from "@byline/i18n/react";
|
|
4
5
|
import { Alert, Button, Checkbox, LoaderEllipsis } from "@byline/ui/react";
|
|
5
6
|
import classnames from "classnames";
|
|
6
7
|
import { useBylineAdminServices } from "../../../services/admin-services-context.js";
|
|
@@ -11,6 +12,7 @@ function setsEqual(a, b) {
|
|
|
11
12
|
return true;
|
|
12
13
|
}
|
|
13
14
|
function GroupSection({ group, selected, mode, saving, onToggle, onSelectAll, onClearAll }) {
|
|
15
|
+
const { t } = useTranslation('byline-admin');
|
|
14
16
|
const groupKeys = useMemo(()=>group.abilities.map((a)=>a.key), [
|
|
15
17
|
group.abilities
|
|
16
18
|
]);
|
|
@@ -28,15 +30,13 @@ function GroupSection({ group, selected, mode, saving, onToggle, onSelectAll, on
|
|
|
28
30
|
className: classnames('byline-role-permissions-group-name', permissions_module["group-name"]),
|
|
29
31
|
children: group.group
|
|
30
32
|
}),
|
|
31
|
-
/*#__PURE__*/
|
|
33
|
+
/*#__PURE__*/ jsx("span", {
|
|
32
34
|
className: classnames('muted', 'byline-role-permissions-group-count', permissions_module["group-count"]),
|
|
33
|
-
children:
|
|
34
|
-
selectedInGroup,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
isEdit ? 'selected' : 'granted'
|
|
39
|
-
]
|
|
35
|
+
children: t('adminRoles.permissions.groupCount', {
|
|
36
|
+
selected: selectedInGroup,
|
|
37
|
+
total: group.abilities.length,
|
|
38
|
+
mode
|
|
39
|
+
})
|
|
40
40
|
})
|
|
41
41
|
]
|
|
42
42
|
}),
|
|
@@ -49,7 +49,7 @@ function GroupSection({ group, selected, mode, saving, onToggle, onSelectAll, on
|
|
|
49
49
|
type: "button",
|
|
50
50
|
disabled: saving || selectedInGroup === group.abilities.length,
|
|
51
51
|
onClick: ()=>onSelectAll(groupKeys),
|
|
52
|
-
children:
|
|
52
|
+
children: t('adminRoles.permissions.selectAll')
|
|
53
53
|
}),
|
|
54
54
|
/*#__PURE__*/ jsx(Button, {
|
|
55
55
|
size: "xs",
|
|
@@ -57,7 +57,7 @@ function GroupSection({ group, selected, mode, saving, onToggle, onSelectAll, on
|
|
|
57
57
|
type: "button",
|
|
58
58
|
disabled: saving || 0 === selectedInGroup,
|
|
59
59
|
onClick: ()=>onClearAll(groupKeys),
|
|
60
|
-
children:
|
|
60
|
+
children: t('adminRoles.permissions.clear')
|
|
61
61
|
})
|
|
62
62
|
]
|
|
63
63
|
}) : null
|
|
@@ -111,6 +111,7 @@ function GroupSection({ group, selected, mode, saving, onToggle, onSelectAll, on
|
|
|
111
111
|
}
|
|
112
112
|
function RolePermissions({ role, registered, initialAbilities, onSaved }) {
|
|
113
113
|
const { setRoleAbilities } = useBylineAdminServices();
|
|
114
|
+
const { t } = useTranslation('byline-admin');
|
|
114
115
|
const [mode, setMode] = useState('view');
|
|
115
116
|
const [initialSet, setInitialSet] = useState(()=>new Set(initialAbilities));
|
|
116
117
|
const [selected, setSelected] = useState(()=>new Set(initialAbilities));
|
|
@@ -172,8 +173,8 @@ function RolePermissions({ role, registered, initialAbilities, onSaved }) {
|
|
|
172
173
|
onSaved?.(response);
|
|
173
174
|
} catch (err) {
|
|
174
175
|
const code = getErrorCode(err);
|
|
175
|
-
if ('admin.permissions.roleNotFound' === code) setError('
|
|
176
|
-
else 'admin.permissions.abilityUnregistered' === code ? setError('
|
|
176
|
+
if ('admin.permissions.roleNotFound' === code) setError(t('adminRoles.permissions.errors.roleNotFound'));
|
|
177
|
+
else 'admin.permissions.abilityUnregistered' === code ? setError(t('adminRoles.permissions.errors.abilityUnregistered')) : setError(t('adminRoles.permissions.errors.fallback'));
|
|
177
178
|
} finally{
|
|
178
179
|
setSaving(false);
|
|
179
180
|
}
|
|
@@ -192,25 +193,14 @@ function RolePermissions({ role, registered, initialAbilities, onSaved }) {
|
|
|
192
193
|
onView: handleEnterView,
|
|
193
194
|
onEdit: handleEnterEdit
|
|
194
195
|
}),
|
|
195
|
-
/*#__PURE__*/
|
|
196
|
+
/*#__PURE__*/ jsx("p", {
|
|
196
197
|
className: classnames('muted', 'byline-role-permissions-counter', permissions_module.counter),
|
|
197
|
-
children:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
"of",
|
|
204
|
-
' ',
|
|
205
|
-
/*#__PURE__*/ jsx("span", {
|
|
206
|
-
className: classnames('byline-role-permissions-counter-num', permissions_module["counter-num"]),
|
|
207
|
-
children: registered.total
|
|
208
|
-
}),
|
|
209
|
-
' ',
|
|
210
|
-
isEdit ? 'selected' : 'granted',
|
|
211
|
-
" for ",
|
|
212
|
-
role.name
|
|
213
|
-
]
|
|
198
|
+
children: t('adminRoles.permissions.counter', {
|
|
199
|
+
selected: totalSelected,
|
|
200
|
+
total: registered.total,
|
|
201
|
+
mode,
|
|
202
|
+
role: role.name
|
|
203
|
+
})
|
|
214
204
|
}),
|
|
215
205
|
isEdit && isDirty ? /*#__PURE__*/ jsxs("div", {
|
|
216
206
|
className: classnames('byline-role-permissions-actions', permissions_module.actions),
|
|
@@ -222,7 +212,7 @@ function RolePermissions({ role, registered, initialAbilities, onSaved }) {
|
|
|
222
212
|
onClick: handleCancel,
|
|
223
213
|
disabled: saving,
|
|
224
214
|
className: classnames('byline-role-permissions-action', permissions_module.action),
|
|
225
|
-
children:
|
|
215
|
+
children: t('common.actions.cancel')
|
|
226
216
|
}),
|
|
227
217
|
/*#__PURE__*/ jsx(Button, {
|
|
228
218
|
type: "button",
|
|
@@ -233,7 +223,7 @@ function RolePermissions({ role, registered, initialAbilities, onSaved }) {
|
|
|
233
223
|
className: classnames('byline-role-permissions-action', permissions_module.action),
|
|
234
224
|
children: saving ? /*#__PURE__*/ jsx(LoaderEllipsis, {
|
|
235
225
|
size: 30
|
|
236
|
-
}) : '
|
|
226
|
+
}) : t('common.actions.save')
|
|
237
227
|
})
|
|
238
228
|
]
|
|
239
229
|
}) : null
|
|
@@ -259,13 +249,14 @@ function RolePermissions({ role, registered, initialAbilities, onSaved }) {
|
|
|
259
249
|
});
|
|
260
250
|
}
|
|
261
251
|
function ModeToggle({ mode, dirty, saving, onView, onEdit }) {
|
|
252
|
+
const { t } = useTranslation('byline-admin');
|
|
262
253
|
const isView = 'view' === mode;
|
|
263
254
|
const isEdit = 'edit' === mode;
|
|
264
255
|
const viewDisabled = dirty || saving;
|
|
265
256
|
const editDisabled = saving;
|
|
266
257
|
return /*#__PURE__*/ jsxs("div", {
|
|
267
258
|
role: "group",
|
|
268
|
-
"aria-label":
|
|
259
|
+
"aria-label": t('adminRoles.permissions.modeAriaLabel'),
|
|
269
260
|
className: classnames('byline-role-permissions-mode-toggle', permissions_module["mode-toggle"]),
|
|
270
261
|
children: [
|
|
271
262
|
/*#__PURE__*/ jsx("button", {
|
|
@@ -279,7 +270,7 @@ function ModeToggle({ mode, dirty, saving, onView, onEdit }) {
|
|
|
279
270
|
'byline-role-permissions-mode-button-disabled',
|
|
280
271
|
permissions_module["mode-button-disabled"]
|
|
281
272
|
]),
|
|
282
|
-
children:
|
|
273
|
+
children: t('adminRoles.permissions.viewMode')
|
|
283
274
|
}),
|
|
284
275
|
/*#__PURE__*/ jsx("button", {
|
|
285
276
|
type: "button",
|
|
@@ -292,7 +283,7 @@ function ModeToggle({ mode, dirty, saving, onView, onEdit }) {
|
|
|
292
283
|
'byline-role-permissions-mode-button-disabled',
|
|
293
284
|
permissions_module["mode-button-disabled"]
|
|
294
285
|
]),
|
|
295
|
-
children:
|
|
286
|
+
children: t('adminRoles.permissions.editMode')
|
|
296
287
|
})
|
|
297
288
|
]
|
|
298
289
|
});
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from "react";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
4
|
import { revalidateLogic, useForm } from "@tanstack/react-form-start";
|
|
5
|
+
import { useTranslation } from "@byline/i18n/react";
|
|
5
6
|
import { Alert, Button, Input, LoaderEllipsis, TextArea } from "@byline/ui/react";
|
|
6
7
|
import classnames from "classnames";
|
|
7
8
|
import { z } from "zod";
|
|
8
9
|
import { useBylineAdminServices } from "../../../services/admin-services-context.js";
|
|
9
10
|
import update_module from "./update.module.js";
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
description: z.string().max(2000, "Description must not exceed 2000 characters")
|
|
13
|
-
});
|
|
11
|
+
const MAX_NAME = 128;
|
|
12
|
+
const MAX_DESCRIPTION = 2000;
|
|
14
13
|
function defaultsFrom(role) {
|
|
15
14
|
return {
|
|
16
15
|
name: role.name,
|
|
@@ -28,8 +27,19 @@ function buildPatch(values, role) {
|
|
|
28
27
|
}
|
|
29
28
|
function UpdateRole({ role, onClose, onSuccess }) {
|
|
30
29
|
const { updateAdminRole } = useBylineAdminServices();
|
|
30
|
+
const { t } = useTranslation('byline-admin');
|
|
31
31
|
const [formError, setFormError] = useState(null);
|
|
32
32
|
const [successMessage, setSuccessMessage] = useState(null);
|
|
33
|
+
const updateRoleSchema = useMemo(()=>z.object({
|
|
34
|
+
name: z.string().min(1, t('adminRoles.create.errors.nameRequired')).max(MAX_NAME, t('adminRoles.create.errors.nameTooLong', {
|
|
35
|
+
max: MAX_NAME
|
|
36
|
+
})),
|
|
37
|
+
description: z.string().max(MAX_DESCRIPTION, t("adminRoles.create.errors.descriptionTooLong", {
|
|
38
|
+
max: MAX_DESCRIPTION
|
|
39
|
+
}))
|
|
40
|
+
}), [
|
|
41
|
+
t
|
|
42
|
+
]);
|
|
33
43
|
const form = useForm({
|
|
34
44
|
defaultValues: defaultsFrom(role),
|
|
35
45
|
validationLogic: revalidateLogic({
|
|
@@ -43,7 +53,7 @@ function UpdateRole({ role, onClose, onSuccess }) {
|
|
|
43
53
|
setFormError(null);
|
|
44
54
|
setSuccessMessage(null);
|
|
45
55
|
const patch = buildPatch(value, role);
|
|
46
|
-
if (0 === Object.keys(patch).length) return void setSuccessMessage('
|
|
56
|
+
if (0 === Object.keys(patch).length) return void setSuccessMessage(t('common.feedback.noChanges'));
|
|
47
57
|
try {
|
|
48
58
|
const updated = await updateAdminRole({
|
|
49
59
|
data: {
|
|
@@ -52,13 +62,13 @@ function UpdateRole({ role, onClose, onSuccess }) {
|
|
|
52
62
|
patch
|
|
53
63
|
}
|
|
54
64
|
});
|
|
55
|
-
setSuccessMessage('
|
|
65
|
+
setSuccessMessage(t('common.feedback.saved'));
|
|
56
66
|
onSuccess?.(updated);
|
|
57
67
|
} catch (err) {
|
|
58
68
|
const code = getErrorCode(err);
|
|
59
|
-
if ('admin.roles.versionConflict' === code) return void setFormError('
|
|
60
|
-
if ('admin.roles.notFound' === code) return void setFormError('
|
|
61
|
-
setFormError('
|
|
69
|
+
if ('admin.roles.versionConflict' === code) return void setFormError(t('adminRoles.update.errors.versionConflict'));
|
|
70
|
+
if ('admin.roles.notFound' === code) return void setFormError(t('adminRoles.update.errors.notFound'));
|
|
71
|
+
setFormError(t('common.errors.couldNotSave'));
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
});
|
|
@@ -84,7 +94,7 @@ function UpdateRole({ role, onClose, onSuccess }) {
|
|
|
84
94
|
/*#__PURE__*/ jsx(form.Field, {
|
|
85
95
|
name: "name",
|
|
86
96
|
children: (field)=>/*#__PURE__*/ jsx(Input, {
|
|
87
|
-
label:
|
|
97
|
+
label: t('adminRoles.fields.name'),
|
|
88
98
|
id: "role-name",
|
|
89
99
|
name: field.name,
|
|
90
100
|
value: field.state.value,
|
|
@@ -96,18 +106,18 @@ function UpdateRole({ role, onClose, onSuccess }) {
|
|
|
96
106
|
})
|
|
97
107
|
}),
|
|
98
108
|
/*#__PURE__*/ jsx(Input, {
|
|
99
|
-
label:
|
|
109
|
+
label: t('adminRoles.fields.machineName'),
|
|
100
110
|
id: "role-machine-name",
|
|
101
111
|
name: "machine_name",
|
|
102
112
|
value: role.machine_name,
|
|
103
113
|
readOnly: true,
|
|
104
114
|
disabled: true,
|
|
105
|
-
helpText:
|
|
115
|
+
helpText: t('adminRoles.update.fields.machineNameHelp')
|
|
106
116
|
}),
|
|
107
117
|
/*#__PURE__*/ jsx(form.Field, {
|
|
108
118
|
name: "description",
|
|
109
119
|
children: (field)=>/*#__PURE__*/ jsx(TextArea, {
|
|
110
|
-
label: "
|
|
120
|
+
label: t("adminRoles.fields.description"),
|
|
111
121
|
id: "role-description",
|
|
112
122
|
name: field.name,
|
|
113
123
|
value: field.state.value,
|
|
@@ -127,7 +137,7 @@ function UpdateRole({ role, onClose, onSuccess }) {
|
|
|
127
137
|
size: "sm",
|
|
128
138
|
onClick: onClose,
|
|
129
139
|
className: classnames('byline-role-update-action', update_module.action),
|
|
130
|
-
children: successMessage ? '
|
|
140
|
+
children: successMessage ? t('common.actions.close') : t('common.actions.cancel')
|
|
131
141
|
}),
|
|
132
142
|
/*#__PURE__*/ jsx(form.Subscribe, {
|
|
133
143
|
selector: (state)=>({
|
|
@@ -142,7 +152,7 @@ function UpdateRole({ role, onClose, onSuccess }) {
|
|
|
142
152
|
className: classnames('byline-role-update-action', update_module.action),
|
|
143
153
|
children: true === isSubmitting ? /*#__PURE__*/ jsx(LoaderEllipsis, {
|
|
144
154
|
size: 42
|
|
145
|
-
}) : '
|
|
155
|
+
}) : t('common.actions.save')
|
|
146
156
|
})
|
|
147
157
|
})
|
|
148
158
|
]
|
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from "react";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
4
|
import { revalidateLogic, useForm } from "@tanstack/react-form-start";
|
|
5
5
|
import { passwordSchema } from "@byline/core/validation";
|
|
6
|
+
import { useTranslation } from "@byline/i18n/react";
|
|
6
7
|
import { Alert, Button, Checkbox, Input, LoaderEllipsis } from "@byline/ui/react";
|
|
7
8
|
import classnames from "classnames";
|
|
8
9
|
import { z } from "zod";
|
|
10
|
+
import { translateValidationError } from "../../../lib/translate-validation-error.js";
|
|
9
11
|
import { useBylineAdminServices } from "../../../services/admin-services-context.js";
|
|
10
12
|
import create_module from "./create.module.js";
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}).min(3).max(254, 'Email must not exceed 254 characters'),
|
|
15
|
-
password: passwordSchema,
|
|
16
|
-
given_name: z.string().max(100, 'Given name must not exceed 100 characters'),
|
|
17
|
-
family_name: z.string().max(100, 'Family name must not exceed 100 characters'),
|
|
18
|
-
username: z.string().max(100, 'Username must not exceed 100 characters'),
|
|
19
|
-
is_super_admin: z.boolean(),
|
|
20
|
-
is_enabled: z.boolean(),
|
|
21
|
-
is_email_verified: z.boolean()
|
|
22
|
-
});
|
|
13
|
+
const MAX_NAME = 100;
|
|
14
|
+
const MAX_USERNAME = 100;
|
|
15
|
+
const MAX_EMAIL = 254;
|
|
23
16
|
const initialValues = {
|
|
24
17
|
email: '',
|
|
25
18
|
password: '',
|
|
@@ -35,7 +28,30 @@ function normaliseText(value) {
|
|
|
35
28
|
}
|
|
36
29
|
function CreateAdminUser({ onClose, onSuccess }) {
|
|
37
30
|
const { createAdminUser } = useBylineAdminServices();
|
|
31
|
+
const { t } = useTranslation('byline-admin');
|
|
38
32
|
const [formError, setFormError] = useState(null);
|
|
33
|
+
const createAdminUserFormSchema = useMemo(()=>z.object({
|
|
34
|
+
email: z.email({
|
|
35
|
+
message: t('account.update.errors.invalidEmail')
|
|
36
|
+
}).min(3).max(MAX_EMAIL, t('account.update.errors.emailTooLong', {
|
|
37
|
+
max: MAX_EMAIL
|
|
38
|
+
})),
|
|
39
|
+
password: passwordSchema,
|
|
40
|
+
given_name: z.string().max(MAX_NAME, t('account.update.errors.givenNameTooLong', {
|
|
41
|
+
max: MAX_NAME
|
|
42
|
+
})),
|
|
43
|
+
family_name: z.string().max(MAX_NAME, t('account.update.errors.familyNameTooLong', {
|
|
44
|
+
max: MAX_NAME
|
|
45
|
+
})),
|
|
46
|
+
username: z.string().max(MAX_USERNAME, t('account.update.errors.usernameTooLong', {
|
|
47
|
+
max: MAX_USERNAME
|
|
48
|
+
})),
|
|
49
|
+
is_super_admin: z.boolean(),
|
|
50
|
+
is_enabled: z.boolean(),
|
|
51
|
+
is_email_verified: z.boolean()
|
|
52
|
+
}), [
|
|
53
|
+
t
|
|
54
|
+
]);
|
|
39
55
|
const form = useForm({
|
|
40
56
|
defaultValues: initialValues,
|
|
41
57
|
validationLogic: revalidateLogic({
|
|
@@ -64,17 +80,21 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
64
80
|
onSuccess?.(created);
|
|
65
81
|
} catch (err) {
|
|
66
82
|
const code = getErrorCode(err);
|
|
67
|
-
if ('admin.users.emailInUse' === code)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
...meta
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
if ('admin.users.emailInUse' === code) {
|
|
84
|
+
const message = t('account.update.errors.emailInUse');
|
|
85
|
+
form.setFieldMeta('email', (meta)=>({
|
|
86
|
+
...meta,
|
|
87
|
+
errorMap: {
|
|
88
|
+
...meta.errorMap,
|
|
89
|
+
onServer: message
|
|
90
|
+
},
|
|
91
|
+
errors: [
|
|
92
|
+
message
|
|
93
|
+
]
|
|
94
|
+
}));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
setFormError(t('adminUsers.create.errors.fallback'));
|
|
78
98
|
}
|
|
79
99
|
}
|
|
80
100
|
});
|
|
@@ -99,7 +119,7 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
99
119
|
/*#__PURE__*/ jsx(form.Field, {
|
|
100
120
|
name: "given_name",
|
|
101
121
|
children: (field)=>/*#__PURE__*/ jsx(Input, {
|
|
102
|
-
label:
|
|
122
|
+
label: t('account.update.fields.givenName'),
|
|
103
123
|
id: "new-given-name",
|
|
104
124
|
name: field.name,
|
|
105
125
|
value: field.state.value,
|
|
@@ -113,7 +133,7 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
113
133
|
/*#__PURE__*/ jsx(form.Field, {
|
|
114
134
|
name: "family_name",
|
|
115
135
|
children: (field)=>/*#__PURE__*/ jsx(Input, {
|
|
116
|
-
label:
|
|
136
|
+
label: t('account.update.fields.familyName'),
|
|
117
137
|
id: "new-family-name",
|
|
118
138
|
name: field.name,
|
|
119
139
|
value: field.state.value,
|
|
@@ -129,7 +149,7 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
129
149
|
/*#__PURE__*/ jsx(form.Field, {
|
|
130
150
|
name: "username",
|
|
131
151
|
children: (field)=>/*#__PURE__*/ jsx(Input, {
|
|
132
|
-
label:
|
|
152
|
+
label: t('account.update.fields.username'),
|
|
133
153
|
id: "new-username",
|
|
134
154
|
name: field.name,
|
|
135
155
|
value: field.state.value,
|
|
@@ -137,14 +157,14 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
137
157
|
onChange: (e)=>field.handleChange(e.currentTarget.value),
|
|
138
158
|
error: field.state.meta.errors.length > 0,
|
|
139
159
|
errorText: firstError(field.state.meta.errors),
|
|
140
|
-
helpText:
|
|
160
|
+
helpText: t('adminUsers.create.fields.usernameHelp'),
|
|
141
161
|
autoComplete: "username"
|
|
142
162
|
})
|
|
143
163
|
}),
|
|
144
164
|
/*#__PURE__*/ jsx(form.Field, {
|
|
145
165
|
name: "email",
|
|
146
166
|
children: (field)=>/*#__PURE__*/ jsx(Input, {
|
|
147
|
-
label:
|
|
167
|
+
label: t('common.fields.email'),
|
|
148
168
|
id: "new-email",
|
|
149
169
|
name: field.name,
|
|
150
170
|
type: "email",
|
|
@@ -160,7 +180,7 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
160
180
|
/*#__PURE__*/ jsx(form.Field, {
|
|
161
181
|
name: "password",
|
|
162
182
|
children: (field)=>/*#__PURE__*/ jsx(Input, {
|
|
163
|
-
label:
|
|
183
|
+
label: t('adminUsers.create.fields.password'),
|
|
164
184
|
id: "new-password",
|
|
165
185
|
name: field.name,
|
|
166
186
|
type: "password",
|
|
@@ -168,8 +188,8 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
168
188
|
onBlur: field.handleBlur,
|
|
169
189
|
onChange: (e)=>field.handleChange(e.currentTarget.value),
|
|
170
190
|
error: field.state.meta.errors.length > 0,
|
|
171
|
-
errorText: firstError(field.state.meta.errors),
|
|
172
|
-
helpText:
|
|
191
|
+
errorText: translateValidationError(t, firstError(field.state.meta.errors)),
|
|
192
|
+
helpText: t('adminUsers.create.fields.passwordHelp'),
|
|
173
193
|
autoComplete: "new-password",
|
|
174
194
|
required: true
|
|
175
195
|
})
|
|
@@ -182,10 +202,10 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
182
202
|
children: (field)=>/*#__PURE__*/ jsx(Checkbox, {
|
|
183
203
|
id: "new-is-enabled",
|
|
184
204
|
name: field.name,
|
|
185
|
-
label:
|
|
205
|
+
label: t('adminUsers.create.flags.enabledLabel'),
|
|
186
206
|
checked: field.state.value,
|
|
187
207
|
onCheckedChange: (checked)=>field.handleChange(true === checked),
|
|
188
|
-
helpText:
|
|
208
|
+
helpText: t('adminUsers.create.flags.enabledHelp')
|
|
189
209
|
})
|
|
190
210
|
}),
|
|
191
211
|
/*#__PURE__*/ jsx(form.Field, {
|
|
@@ -193,10 +213,10 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
193
213
|
children: (field)=>/*#__PURE__*/ jsx(Checkbox, {
|
|
194
214
|
id: "new-is-email-verified",
|
|
195
215
|
name: field.name,
|
|
196
|
-
label:
|
|
216
|
+
label: t('adminUsers.create.flags.emailVerifiedLabel'),
|
|
197
217
|
checked: field.state.value,
|
|
198
218
|
onCheckedChange: (checked)=>field.handleChange(true === checked),
|
|
199
|
-
helpText:
|
|
219
|
+
helpText: t('adminUsers.create.flags.emailVerifiedHelp')
|
|
200
220
|
})
|
|
201
221
|
}),
|
|
202
222
|
/*#__PURE__*/ jsx(form.Field, {
|
|
@@ -204,10 +224,10 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
204
224
|
children: (field)=>/*#__PURE__*/ jsx(Checkbox, {
|
|
205
225
|
id: "new-is-super-admin",
|
|
206
226
|
name: field.name,
|
|
207
|
-
label:
|
|
227
|
+
label: t('adminUsers.create.flags.superAdminLabel'),
|
|
208
228
|
checked: field.state.value,
|
|
209
229
|
onCheckedChange: (checked)=>field.handleChange(true === checked),
|
|
210
|
-
helpText:
|
|
230
|
+
helpText: t('adminUsers.create.flags.superAdminHelp')
|
|
211
231
|
})
|
|
212
232
|
})
|
|
213
233
|
]
|
|
@@ -221,7 +241,7 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
221
241
|
size: "sm",
|
|
222
242
|
onClick: onClose,
|
|
223
243
|
className: classnames('byline-user-create-action', create_module.action),
|
|
224
|
-
children:
|
|
244
|
+
children: t('common.actions.cancel')
|
|
225
245
|
}),
|
|
226
246
|
/*#__PURE__*/ jsx(form.Subscribe, {
|
|
227
247
|
selector: (state)=>({
|
|
@@ -236,7 +256,7 @@ function CreateAdminUser({ onClose, onSuccess }) {
|
|
|
236
256
|
className: classnames('byline-user-create-action', create_module.action),
|
|
237
257
|
children: true === isSubmitting ? /*#__PURE__*/ jsx(LoaderEllipsis, {
|
|
238
258
|
size: 42
|
|
239
|
-
}) : '
|
|
259
|
+
}) : t('common.actions.save')
|
|
240
260
|
})
|
|
241
261
|
})
|
|
242
262
|
]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
import { useTranslation } from "@byline/i18n/react";
|
|
4
5
|
import { Alert, Button, Checkbox, LoaderEllipsis } from "@byline/ui/react";
|
|
5
6
|
import classnames from "classnames";
|
|
6
7
|
import { useBylineAdminServices } from "../../../services/admin-services-context.js";
|
|
@@ -12,6 +13,7 @@ function setsEqual(a, b) {
|
|
|
12
13
|
}
|
|
13
14
|
function UserRoles({ user, allRoles, initialRoleIds, onClose, onSaved }) {
|
|
14
15
|
const { setUserRoles } = useBylineAdminServices();
|
|
16
|
+
const { t } = useTranslation('byline-admin');
|
|
15
17
|
const [initialSet, setInitialSet] = useState(()=>new Set(initialRoleIds));
|
|
16
18
|
const [selected, setSelected] = useState(()=>new Set(initialRoleIds));
|
|
17
19
|
const [saving, setSaving] = useState(false);
|
|
@@ -42,12 +44,12 @@ function UserRoles({ user, allRoles, initialRoleIds, onClose, onSaved }) {
|
|
|
42
44
|
const storedSet = new Set(response.roles.map((r)=>r.id));
|
|
43
45
|
setInitialSet(storedSet);
|
|
44
46
|
setSelected(new Set(storedSet));
|
|
45
|
-
setSuccessMessage('
|
|
47
|
+
setSuccessMessage(t('common.feedback.saved'));
|
|
46
48
|
onSaved?.(response);
|
|
47
49
|
} catch (err) {
|
|
48
50
|
const code = getErrorCode(err);
|
|
49
|
-
if ('admin.roles.userNotFound' === code) setError('
|
|
50
|
-
else 'admin.roles.notFound' === code ? setError('
|
|
51
|
+
if ('admin.roles.userNotFound' === code) setError(t('adminUsers.roles.errors.userNotFound'));
|
|
52
|
+
else 'admin.roles.notFound' === code ? setError(t('adminUsers.roles.errors.roleNotFound')) : setError(t('adminUsers.roles.errors.fallback'));
|
|
51
53
|
} finally{
|
|
52
54
|
setSaving(false);
|
|
53
55
|
}
|
|
@@ -63,17 +65,9 @@ function UserRoles({ user, allRoles, initialRoleIds, onClose, onSaved }) {
|
|
|
63
65
|
intent: "success",
|
|
64
66
|
children: successMessage
|
|
65
67
|
}) : null,
|
|
66
|
-
0 === allRoles.length ? /*#__PURE__*/
|
|
68
|
+
0 === allRoles.length ? /*#__PURE__*/ jsx("p", {
|
|
67
69
|
className: classnames('muted', 'byline-user-roles-empty', roles_module.empty),
|
|
68
|
-
children:
|
|
69
|
-
"No roles have been created yet. Create roles in",
|
|
70
|
-
' ',
|
|
71
|
-
/*#__PURE__*/ jsx("span", {
|
|
72
|
-
className: "muted",
|
|
73
|
-
children: "/admin/roles"
|
|
74
|
-
}),
|
|
75
|
-
" first."
|
|
76
|
-
]
|
|
70
|
+
children: t('adminUsers.roles.emptyCatalog')
|
|
77
71
|
}) : /*#__PURE__*/ jsx("div", {
|
|
78
72
|
className: classnames('byline-user-roles-list', roles_module.list),
|
|
79
73
|
children: allRoles.map((role)=>/*#__PURE__*/ jsxs("div", {
|
|
@@ -124,7 +118,7 @@ function UserRoles({ user, allRoles, initialRoleIds, onClose, onSaved }) {
|
|
|
124
118
|
onClick: onClose,
|
|
125
119
|
disabled: saving,
|
|
126
120
|
className: classnames('byline-user-roles-action', roles_module.action),
|
|
127
|
-
children: successMessage ? '
|
|
121
|
+
children: successMessage ? t('common.actions.close') : t('common.actions.cancel')
|
|
128
122
|
}),
|
|
129
123
|
/*#__PURE__*/ jsx(Button, {
|
|
130
124
|
type: "button",
|
|
@@ -135,7 +129,7 @@ function UserRoles({ user, allRoles, initialRoleIds, onClose, onSaved }) {
|
|
|
135
129
|
className: classnames('byline-user-roles-action', roles_module.action),
|
|
136
130
|
children: saving ? /*#__PURE__*/ jsx(LoaderEllipsis, {
|
|
137
131
|
size: 30
|
|
138
|
-
}) : '
|
|
132
|
+
}) : t('common.actions.save')
|
|
139
133
|
})
|
|
140
134
|
]
|
|
141
135
|
})
|