@asteby/metacore-runtime-react 37.0.0 → 37.0.2
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/CHANGELOG.md +13 -0
- package/dist/dynamic-columns-helpers.d.ts +9 -0
- package/dist/dynamic-columns-helpers.d.ts.map +1 -1
- package/dist/dynamic-columns-helpers.js +15 -0
- package/dist/dynamic-columns.d.ts +15 -3
- package/dist/dynamic-columns.d.ts.map +1 -1
- package/dist/dynamic-columns.js +26 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/model-action-toolbar.d.ts +16 -1
- package/dist/model-action-toolbar.d.ts.map +1 -1
- package/dist/model-action-toolbar.js +30 -2
- package/package.json +3 -3
- package/src/__tests__/metadata-label-i18n.test.ts +19 -0
- package/src/__tests__/model-action-toolbar-i18n.test.tsx +29 -6
- package/src/__tests__/resolve-row-actions.test.ts +14 -0
- package/src/dynamic-columns-helpers.ts +22 -0
- package/src/dynamic-columns.tsx +26 -6
- package/src/index.ts +2 -1
- package/src/model-action-toolbar.tsx +42 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 37.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 653afe4: Never flash raw dotted i18n keys in ModelActionToolbar: humanizeActionLabel fallback + onActionIntent for Module Federation prefetch.
|
|
8
|
+
|
|
9
|
+
## 37.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 53c3b8a: Fix `isActionConditionMet` (row/table action `condition` gate): `truthy`/`falsy` (and the `present`/`set`/`blank`/`empty` aliases, matching the host's document print gate) were unrecognized operators falling through to the permissive `default: return true` — a `condition: {field, operator: "truthy"}` silently gated nothing, rendering the action on every row regardless of the field's value. Confirmed live: an addon's `condition: {field: "amount_due", operator: "truthy"}` row action rendered on every row, including ones with a zero balance.
|
|
14
|
+
- 0d06571: Translate manifest-contributed dynamic table column and row-action labels at render time, with a humanized fallback for missing addon locale keys. Export `translateMetadataLabel` so host-owned dynamic surfaces can apply the same contract to titles and forms.
|
|
15
|
+
|
|
3
16
|
## 37.0.0
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
|
@@ -18,4 +18,13 @@
|
|
|
18
18
|
* non-strings. This keeps it safe to call on arbitrary cell values.
|
|
19
19
|
*/
|
|
20
20
|
export declare function humanizeToken(value: unknown): string;
|
|
21
|
+
export type MetadataTranslator = (key: string, options?: {
|
|
22
|
+
defaultValue?: string;
|
|
23
|
+
}) => string;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve addon-contributed metadata at render time. Known i18n keys use the
|
|
26
|
+
* host locale; missing keys degrade to a readable label instead of leaking a
|
|
27
|
+
* machine path such as `models.orders.table.columns.payment_status`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function translateMetadataLabel(value: string | undefined, translate?: MetadataTranslator): string;
|
|
21
30
|
//# sourceMappingURL=dynamic-columns-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-columns-helpers.d.ts","sourceRoot":"","sources":["../src/dynamic-columns-helpers.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAiBpD"}
|
|
1
|
+
{"version":3,"file":"dynamic-columns-helpers.d.ts","sourceRoot":"","sources":["../src/dynamic-columns-helpers.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAiBpD;AAED,MAAM,MAAM,kBAAkB,GAAG,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,KAClC,MAAM,CAAA;AAEX;;;;GAIG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,SAAS,CAAC,EAAE,kBAAkB,GAC/B,MAAM,CAOR"}
|
|
@@ -57,3 +57,18 @@ export function humanizeToken(value) {
|
|
|
57
57
|
})
|
|
58
58
|
.join(' ');
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Resolve addon-contributed metadata at render time. Known i18n keys use the
|
|
62
|
+
* host locale; missing keys degrade to a readable label instead of leaking a
|
|
63
|
+
* machine path such as `models.orders.table.columns.payment_status`.
|
|
64
|
+
*/
|
|
65
|
+
export function translateMetadataLabel(value, translate) {
|
|
66
|
+
if (!value)
|
|
67
|
+
return '';
|
|
68
|
+
const token = value.includes('.') ? value.split('.').at(-1) ?? value : value;
|
|
69
|
+
const fallback = humanizeToken(token);
|
|
70
|
+
if (!translate)
|
|
71
|
+
return fallback;
|
|
72
|
+
const translated = translate(value, { defaultValue: fallback });
|
|
73
|
+
return translated && translated !== value ? translated : fallback;
|
|
74
|
+
}
|
|
@@ -56,9 +56,21 @@ export declare const isActionAllowedForRowState: (action: any, row: any) => bool
|
|
|
56
56
|
* Declarative `condition` gate for a per-row action: shows the action only when
|
|
57
57
|
* the row's `field` satisfies the operator. Supports both the SDK dialect
|
|
58
58
|
* (`eq` | `neq` | `in` | `not_in`) and the common host dialect
|
|
59
|
-
* (`equals` | `notEquals` | `not_in`)
|
|
60
|
-
*
|
|
61
|
-
*
|
|
59
|
+
* (`equals` | `notEquals` | `not_in`), plus the truthy/falsy family (same
|
|
60
|
+
* operator set as the host's document print gate — services/document_gate.go
|
|
61
|
+
* — kept in sync so a manifest author doesn't have to know which gate a given
|
|
62
|
+
* contribution goes through). Nested paths (`user.verified`) are resolved via
|
|
63
|
+
* `getNestedValue`. No condition → always shown.
|
|
64
|
+
*
|
|
65
|
+
* `default: return true` for a genuinely unknown operator is deliberate — an
|
|
66
|
+
* addon shipped against a newer SDK than the host runs should degrade to
|
|
67
|
+
* "always show" (worst case: an extra menu item), never to "always hide"
|
|
68
|
+
* (worst case: a feature silently vanishes). That same permissiveness is why
|
|
69
|
+
* `truthy`/`falsy` going unrecognized here was a real, silent bug rather
|
|
70
|
+
* than a build error: confirmed live — a `condition: {field: "amount_due",
|
|
71
|
+
* operator: "truthy"}` row action rendered on every row regardless of
|
|
72
|
+
* amount_due, because the switch fell through to the default and nothing
|
|
73
|
+
* ever signaled it wasn't actually gating anything.
|
|
62
74
|
*/
|
|
63
75
|
export declare const isActionConditionMet: (action: any, row: any) => boolean;
|
|
64
76
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-columns.d.ts","sourceRoot":"","sources":["../src/dynamic-columns.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AA0C9C,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE9D,OAAO,KAAK,EAER,iBAAiB,EACpB,MAAM,wBAAwB,CAAA;AAE/B,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IACtC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB;AA0BD;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,gBAAgB,EAAE,cAAc,MAAM,KAAG,MACzB,CAAA;AAQrD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,gBAAgB,KAAG,MAAM,GAAG,SAG5D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC7B,KAAK,gBAAgB,EACrB,OAAO,OAAO,EACd,WAAW,MAAM,EACjB,SAAS,MAAM,KAChB,MAyBF,CAAA;AAsDD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,GAAG,EAAE,KAAK,GAAG,KAAG,OAMlE,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"dynamic-columns.d.ts","sourceRoot":"","sources":["../src/dynamic-columns.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AA0C9C,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE9D,OAAO,KAAK,EAER,iBAAiB,EACpB,MAAM,wBAAwB,CAAA;AAE/B,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IACtC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB;AA0BD;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,gBAAgB,EAAE,cAAc,MAAM,KAAG,MACzB,CAAA;AAQrD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,gBAAgB,KAAG,MAAM,GAAG,SAG5D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC7B,KAAK,gBAAgB,EACrB,OAAO,OAAO,EACd,WAAW,MAAM,EACjB,SAAS,MAAM,KAChB,MAyBF,CAAA;AAsDD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,GAAG,EAAE,KAAK,GAAG,KAAG,OAMlE,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,GAAG,EAAE,KAAK,GAAG,KAAG,OA0C5D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,GAAG,EAAE,KAAK,GAAG,KAAG,OACqB,CAAA;AAwFhF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,KAAG,MAGnE,CAAA;AAED,6EAA6E;AAC7E,eAAO,MAAM,eAAe,2DAA4D,CAAA;AAExF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAClB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA6C5C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,gBAAgB,EAAE,KAAK,GAAG,KAAG,MAWtE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,gBAAgB,EAAE,KAAK,GAAG,KAAG,MAOtE,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,GACjE,MAAM,CAcR;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAOxE;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,GACzB,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACR,OAAO,GAAG,EACV,mBAAe,KAChB,MAAM,GAAG,SAcX,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAAI,KAAK,gBAAgB,EAAE,KAAK,GAAG,KAAG,MAOzE,CAAA;AAgKD;;;;GAIG;AACH;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IACrC,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB,CAgCA,CAAA;AAED,wBAAgB,4BAA4B,CACxC,OAAO,GAAE,qBAA0B,GACpC,iBAAiB,CA0qBnB;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,iBACL,CAAA"}
|
package/dist/dynamic-columns.js
CHANGED
|
@@ -21,7 +21,7 @@ import { Avatar, AvatarFallback, AvatarImage, Badge, Button, Checkbox, DropdownM
|
|
|
21
21
|
import { DataTableColumnHeader, FilterableColumnHeader, } from '@asteby/metacore-ui/data-table';
|
|
22
22
|
import { generateBadgeStyles, getInitials, relationChipStyles, } from '@asteby/metacore-ui/lib';
|
|
23
23
|
import { Progress } from './dialogs/_primitives';
|
|
24
|
-
import { humanizeToken } from './dynamic-columns-helpers';
|
|
24
|
+
import { humanizeToken, translateMetadataLabel } from './dynamic-columns-helpers';
|
|
25
25
|
import { objectLabel } from './dynamic-relation-helpers';
|
|
26
26
|
import { OptionBadge, RelationThumbnail, ImageStack, statusColorFor, useIsDarkTheme, } from './display-value';
|
|
27
27
|
import { MediaValue } from './rich-url';
|
|
@@ -147,9 +147,21 @@ export const isActionAllowedForRowState = (action, row) => {
|
|
|
147
147
|
* Declarative `condition` gate for a per-row action: shows the action only when
|
|
148
148
|
* the row's `field` satisfies the operator. Supports both the SDK dialect
|
|
149
149
|
* (`eq` | `neq` | `in` | `not_in`) and the common host dialect
|
|
150
|
-
* (`equals` | `notEquals` | `not_in`)
|
|
151
|
-
*
|
|
152
|
-
*
|
|
150
|
+
* (`equals` | `notEquals` | `not_in`), plus the truthy/falsy family (same
|
|
151
|
+
* operator set as the host's document print gate — services/document_gate.go
|
|
152
|
+
* — kept in sync so a manifest author doesn't have to know which gate a given
|
|
153
|
+
* contribution goes through). Nested paths (`user.verified`) are resolved via
|
|
154
|
+
* `getNestedValue`. No condition → always shown.
|
|
155
|
+
*
|
|
156
|
+
* `default: return true` for a genuinely unknown operator is deliberate — an
|
|
157
|
+
* addon shipped against a newer SDK than the host runs should degrade to
|
|
158
|
+
* "always show" (worst case: an extra menu item), never to "always hide"
|
|
159
|
+
* (worst case: a feature silently vanishes). That same permissiveness is why
|
|
160
|
+
* `truthy`/`falsy` going unrecognized here was a real, silent bug rather
|
|
161
|
+
* than a build error: confirmed live — a `condition: {field: "amount_due",
|
|
162
|
+
* operator: "truthy"}` row action rendered on every row regardless of
|
|
163
|
+
* amount_due, because the switch fell through to the default and nothing
|
|
164
|
+
* ever signaled it wasn't actually gating anything.
|
|
153
165
|
*/
|
|
154
166
|
export const isActionConditionMet = (action, row) => {
|
|
155
167
|
if (!action?.condition)
|
|
@@ -183,6 +195,14 @@ export const isActionConditionMet = (action, row) => {
|
|
|
183
195
|
case 'not_in':
|
|
184
196
|
case 'notin':
|
|
185
197
|
return !values.includes(rowValue);
|
|
198
|
+
case 'truthy':
|
|
199
|
+
case 'present':
|
|
200
|
+
case 'set':
|
|
201
|
+
return rowValue !== '' && rowValue !== 'false' && rowValue !== '0';
|
|
202
|
+
case 'falsy':
|
|
203
|
+
case 'blank':
|
|
204
|
+
case 'empty':
|
|
205
|
+
return rowValue === '' || rowValue === 'false' || rowValue === '0';
|
|
186
206
|
default:
|
|
187
207
|
return true;
|
|
188
208
|
}
|
|
@@ -580,7 +600,7 @@ export function makeDefaultGetDynamicColumns(helpers = {}) {
|
|
|
580
600
|
// `visibility` scope (skips `'modal'` and `'list'`).
|
|
581
601
|
if (!isColumnVisibleInTable(col))
|
|
582
602
|
return;
|
|
583
|
-
const translatedLabel = col.label;
|
|
603
|
+
const translatedLabel = translateMetadataLabel(col.label, t);
|
|
584
604
|
const filterConfig = filterConfigs?.get(col.key);
|
|
585
605
|
const columnMeta = {
|
|
586
606
|
label: translatedLabel,
|
|
@@ -971,7 +991,7 @@ export function makeDefaultGetDynamicColumns(helpers = {}) {
|
|
|
971
991
|
meta: {},
|
|
972
992
|
cell: ({ row }) => (_jsx("div", { className: "flex items-center justify-end", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", className: "h-8 w-8 p-0", children: [_jsx("span", { className: "sr-only", children: "Abrir men\u00FA" }), _jsx(MoreHorizontal, { className: "h-4 w-4" })] }) }), _jsx(DropdownMenuContent, { align: "end", children: resolvedActions
|
|
973
993
|
.filter((action) => isRowActionVisible(action, row.original))
|
|
974
|
-
.map((action) => (_jsxs(DropdownMenuItem, { onClick: () => onAction && onAction(action.key, row.original), children: [_jsx(DynamicIcon, { name: action.icon, className: "mr-2 h-4 w-4" }), action.label] }, action.key))) })] }) })),
|
|
994
|
+
.map((action) => (_jsxs(DropdownMenuItem, { onClick: () => onAction && onAction(action.key, row.original), children: [_jsx(DynamicIcon, { name: action.icon, className: "mr-2 h-4 w-4" }), translateMetadataLabel(action.label, t)] }, action.key))) })] }) })),
|
|
975
995
|
});
|
|
976
996
|
}
|
|
977
997
|
return columns;
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,8 @@ export { useHotSwapReload, applyHotSwapReload, withVersionParam, clearFederation
|
|
|
47
47
|
export * from './dynamic-icon';
|
|
48
48
|
export type { ColumnFilterConfig, FilterOption as DynamicColumnFilterOption, GetDynamicColumns, DynamicIconComponent, } from './dynamic-columns-shim';
|
|
49
49
|
export { defaultGetDynamicColumns, makeDefaultGetDynamicColumns, relationKeyFor, resolveAvatarSrc, resolveMissingActorLabel, resolveActorDisplayName, resolveRelationLabel, type DynamicColumnsHelpers, } from './dynamic-columns';
|
|
50
|
-
export { humanizeToken } from './dynamic-columns-helpers';
|
|
50
|
+
export { humanizeToken, translateMetadataLabel } from './dynamic-columns-helpers';
|
|
51
|
+
export type { MetadataTranslator } from './dynamic-columns-helpers';
|
|
51
52
|
export { UrlChip, FileChip, ImageThumbnail, MediaValue, RichText, linkifyText, classifyUrl, isImageUrl, isFileUrl, ensureHref, smartUrlLabel, fileNameFromUrl, splitTrailingPunct, type UrlKind, type LinkifyOptions, } from './rich-url';
|
|
52
53
|
export { ImageStack, OptionBadge, statusColorFor, useIsDarkTheme, } from './display-value';
|
|
53
54
|
export { CollectionCell, formatScalar, prettifyKey, countLabel, type CollectionCellProps, type Translate as CollectionCellTranslate, } from './collection-cell';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -51,7 +51,7 @@ export { ADDON_MANIFEST_CHANGED_TYPE, wireHotSwapInvalidation, useManifestHotSwa
|
|
|
51
51
|
export { useHotSwapReload, applyHotSwapReload, withVersionParam, clearFederationContainer, shortenHash, } from './hotswap-reload-policy';
|
|
52
52
|
export * from './dynamic-icon';
|
|
53
53
|
export { defaultGetDynamicColumns, makeDefaultGetDynamicColumns, relationKeyFor, resolveAvatarSrc, resolveMissingActorLabel, resolveActorDisplayName, resolveRelationLabel, } from './dynamic-columns';
|
|
54
|
-
export { humanizeToken } from './dynamic-columns-helpers';
|
|
54
|
+
export { humanizeToken, translateMetadataLabel } from './dynamic-columns-helpers';
|
|
55
55
|
export { UrlChip, FileChip, ImageThumbnail, MediaValue, RichText, linkifyText, classifyUrl, isImageUrl, isFileUrl, ensureHref, smartUrlLabel, fileNameFromUrl, splitTrailingPunct, } from './rich-url';
|
|
56
56
|
export { ImageStack, OptionBadge, statusColorFor, useIsDarkTheme, } from './display-value';
|
|
57
57
|
export { CollectionCell, formatScalar, prettifyKey, countLabel, } from './collection-cell';
|
|
@@ -17,11 +17,26 @@ export interface ModelActionToolbarProps {
|
|
|
17
17
|
onChange?: () => void;
|
|
18
18
|
/** Extra classes on the button row container. */
|
|
19
19
|
className?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Fired on hover/focus of an action button so the host can prefetch a
|
|
22
|
+
* federated remote (e.g. collections) before the click — Module Federation
|
|
23
|
+
* lazy load without blocking first paint of the list page.
|
|
24
|
+
*/
|
|
25
|
+
onActionIntent?: (action: ActionDefinition) => void;
|
|
20
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Last-resort label when `t(key)` has no translation yet: never flash the full
|
|
29
|
+
* dotted key in a primary CTA. Prefers the action/field segment over a trailing
|
|
30
|
+
* `.label` / `.confirm` leaf.
|
|
31
|
+
* "receivables.action.collect_payment_create" → "Collect payment create"
|
|
32
|
+
* "integration_github.action.create_issue.label" → "Create issue"
|
|
33
|
+
* Already-human labels pass through unchanged.
|
|
34
|
+
*/
|
|
35
|
+
export declare function humanizeActionLabel(label: string): string;
|
|
21
36
|
/**
|
|
22
37
|
* Returns the model's actions matching the requested placements. Reads from the
|
|
23
38
|
* `actions` prop when provided, else the metadata cache, else fetches once.
|
|
24
39
|
*/
|
|
25
40
|
export declare function useModelActions(model: string, placements?: ActionPlacement[], provided?: ActionDefinition[]): ActionDefinition[];
|
|
26
|
-
export declare function ModelActionToolbar({ model, endpoint, actions, placements, onChange, className, }: ModelActionToolbarProps): import("react").JSX.Element | null;
|
|
41
|
+
export declare function ModelActionToolbar({ model, endpoint, actions, placements, onChange, className, onActionIntent, }: ModelActionToolbarProps): import("react").JSX.Element | null;
|
|
27
42
|
//# sourceMappingURL=model-action-toolbar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-action-toolbar.d.ts","sourceRoot":"","sources":["../src/model-action-toolbar.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAiC,MAAM,SAAS,CAAA;AAE9E,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;AAExD,MAAM,WAAW,uBAAuB;IACpC,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B,qEAAqE;IACrE,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"model-action-toolbar.d.ts","sourceRoot":"","sources":["../src/model-action-toolbar.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAiC,MAAM,SAAS,CAAA;AAE9E,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;AAExD,MAAM,WAAW,uBAAuB;IACpC,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B,qEAAqE;IACrE,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAA;CACtD;AAID;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBzD;AAiBD;;;GAGG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,eAAe,EAAuB,EAClD,QAAQ,CAAC,EAAE,gBAAgB,EAAE,GAC9B,gBAAgB,EAAE,CA2BpB;AAED,wBAAgB,kBAAkB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,UAA+B,EAC/B,QAAQ,EACR,SAAS,EACT,cAAc,GACjB,EAAE,uBAAuB,sCAgEzB"}
|
|
@@ -27,6 +27,31 @@ import { DynamicIcon } from './dynamic-icon';
|
|
|
27
27
|
import { ActionModalDispatcher } from './action-modal-dispatcher';
|
|
28
28
|
import { useCan, modelCapability } from './permissions-context';
|
|
29
29
|
const DEFAULT_PLACEMENTS = ['table', 'create'];
|
|
30
|
+
/**
|
|
31
|
+
* Last-resort label when `t(key)` has no translation yet: never flash the full
|
|
32
|
+
* dotted key in a primary CTA. Prefers the action/field segment over a trailing
|
|
33
|
+
* `.label` / `.confirm` leaf.
|
|
34
|
+
* "receivables.action.collect_payment_create" → "Collect payment create"
|
|
35
|
+
* "integration_github.action.create_issue.label" → "Create issue"
|
|
36
|
+
* Already-human labels pass through unchanged.
|
|
37
|
+
*/
|
|
38
|
+
export function humanizeActionLabel(label) {
|
|
39
|
+
if (!label)
|
|
40
|
+
return label;
|
|
41
|
+
if (!label.includes('.') || /\s/.test(label))
|
|
42
|
+
return label;
|
|
43
|
+
const parts = label.split('.').filter(Boolean);
|
|
44
|
+
let leaf = parts[parts.length - 1] || label;
|
|
45
|
+
if ((leaf === 'label' || leaf === 'confirm' || leaf === 'title') &&
|
|
46
|
+
parts.length >= 2) {
|
|
47
|
+
leaf = parts[parts.length - 2];
|
|
48
|
+
}
|
|
49
|
+
return leaf
|
|
50
|
+
.split('_')
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
53
|
+
.join(' ');
|
|
54
|
+
}
|
|
30
55
|
function toActionMetadata(a) {
|
|
31
56
|
return {
|
|
32
57
|
key: a.key,
|
|
@@ -71,7 +96,7 @@ export function useModelActions(model, placements = DEFAULT_PLACEMENTS, provided
|
|
|
71
96
|
const all = provided ?? cached?.actions ?? fetched?.actions ?? [];
|
|
72
97
|
return useMemo(() => all.filter((a) => placements.includes((a.placement ?? 'row'))), [all, placements]);
|
|
73
98
|
}
|
|
74
|
-
export function ModelActionToolbar({ model, endpoint, actions, placements = DEFAULT_PLACEMENTS, onChange, className, }) {
|
|
99
|
+
export function ModelActionToolbar({ model, endpoint, actions, placements = DEFAULT_PLACEMENTS, onChange, className, onActionIntent, }) {
|
|
75
100
|
const { t } = useTranslation();
|
|
76
101
|
const all = useModelActions(model, placements, actions);
|
|
77
102
|
// Capability gating — always-true without a <PermissionsProvider>. Custom
|
|
@@ -84,7 +109,10 @@ export function ModelActionToolbar({ model, endpoint, actions, placements = DEFA
|
|
|
84
109
|
return null;
|
|
85
110
|
return (_jsxs(_Fragment, { children: [_jsx("div", { className: className ?? 'flex items-center gap-2', children: surfaced.map((a) => {
|
|
86
111
|
const isCreate = (a.placement ?? 'row') === 'create';
|
|
87
|
-
return (_jsxs(Button, { variant: isCreate ? 'default' : 'outline', onClick: () =>
|
|
112
|
+
return (_jsxs(Button, { variant: isCreate ? 'default' : 'outline', onClick: () => {
|
|
113
|
+
onActionIntent?.(a);
|
|
114
|
+
setActive(toActionMetadata(a));
|
|
115
|
+
}, onMouseEnter: () => onActionIntent?.(a), onFocus: () => onActionIntent?.(a), style: a.color && !isCreate ? { borderColor: a.color, color: a.color } : undefined, children: [_jsx(DynamicIcon, { name: a.icon || (isCreate ? 'Plus' : 'Zap'), className: "mr-2 h-4 w-4" }), t(a.label, { defaultValue: humanizeActionLabel(a.label) })] }, a.key));
|
|
88
116
|
}) }), active && (_jsx(ActionModalDispatcher, { open: !!active, onOpenChange: (open) => {
|
|
89
117
|
if (!open)
|
|
90
118
|
setActive(null);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asteby/metacore-runtime-react",
|
|
3
|
-
"version": "37.0.
|
|
3
|
+
"version": "37.0.2",
|
|
4
4
|
"description": "React runtime for metacore hosts — renders addon contributions dynamically",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
"typescript": "^6.0.0",
|
|
68
68
|
"vitest": "^4.0.0",
|
|
69
69
|
"zustand": "^5.0.0",
|
|
70
|
-
"@asteby/metacore-
|
|
71
|
-
"@asteby/metacore-
|
|
70
|
+
"@asteby/metacore-ui": "2.17.3",
|
|
71
|
+
"@asteby/metacore-sdk": "3.7.0"
|
|
72
72
|
},
|
|
73
73
|
"scripts": {
|
|
74
74
|
"build": "tsc -p tsconfig.json",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { translateMetadataLabel } from '../dynamic-columns-helpers'
|
|
3
|
+
|
|
4
|
+
describe('translateMetadataLabel', () => {
|
|
5
|
+
it('resolves a host translation when available', () => {
|
|
6
|
+
const t = vi.fn(() => 'Estado del pago')
|
|
7
|
+
expect(translateMetadataLabel('models.orders.payment_status', t)).toBe('Estado del pago')
|
|
8
|
+
expect(t).toHaveBeenCalledWith('models.orders.payment_status', { defaultValue: 'Payment Status' })
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('humanizes the final segment when an addon locale is not loaded', () => {
|
|
12
|
+
const t = vi.fn((key: string) => key)
|
|
13
|
+
expect(translateMetadataLabel('models.addon.fields.custom_code', t)).toBe('Custom Code')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('preserves already human labels', () => {
|
|
17
|
+
expect(translateMetadataLabel('Nombre comercial')).toBe('Nombre comercial')
|
|
18
|
+
})
|
|
19
|
+
})
|
|
@@ -56,12 +56,13 @@ describe('ModelActionToolbar — translates addon action labels at render', () =
|
|
|
56
56
|
const inst = makeI18n()
|
|
57
57
|
renderToolbar(inst)
|
|
58
58
|
|
|
59
|
-
// Before the addon bundle loads the toolbar
|
|
60
|
-
//
|
|
61
|
-
//
|
|
59
|
+
// Before the addon bundle loads the toolbar must NOT flash the full
|
|
60
|
+
// dotted key — humanizeActionLabel turns the last segment into a
|
|
61
|
+
// readable fallback until addResourceBundle fires.
|
|
62
|
+
expect(screen.getByText('Create Issue')).toBeTruthy()
|
|
62
63
|
expect(
|
|
63
|
-
screen.
|
|
64
|
-
).
|
|
64
|
+
screen.queryByText('integration_github.action.create_issue.label'),
|
|
65
|
+
).toBeNull()
|
|
65
66
|
|
|
66
67
|
// The addon locale bundle arrives asynchronously (OpsAddonLocaleLoader
|
|
67
68
|
// fetch → addResourceBundle). It is NESTED, as the host loader now merges
|
|
@@ -79,8 +80,30 @@ describe('ModelActionToolbar — translates addon action labels at render', () =
|
|
|
79
80
|
// The toolbar must re-render and show the translated label — the exact
|
|
80
81
|
// behaviour that was missing (a bare {a.label} never re-derived).
|
|
81
82
|
await waitFor(() => expect(screen.getByText('Crear issue')).toBeTruthy())
|
|
83
|
+
expect(screen.queryByText('Create Issue')).toBeNull()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('humanizes collect_payment_create without flashing the receivables key', () => {
|
|
87
|
+
const inst = makeI18n()
|
|
88
|
+
render(
|
|
89
|
+
<I18nextProvider i18n={inst}>
|
|
90
|
+
<ApiProvider client={api}>
|
|
91
|
+
<ModelActionToolbar
|
|
92
|
+
model="account_statements"
|
|
93
|
+
actions={[
|
|
94
|
+
{
|
|
95
|
+
key: 'collect_payment_create',
|
|
96
|
+
label: 'receivables.action.collect_payment_create',
|
|
97
|
+
placement: 'create',
|
|
98
|
+
} as ActionDefinition,
|
|
99
|
+
]}
|
|
100
|
+
/>
|
|
101
|
+
</ApiProvider>
|
|
102
|
+
</I18nextProvider>,
|
|
103
|
+
)
|
|
104
|
+
expect(screen.getByText('Collect Payment Create')).toBeTruthy()
|
|
82
105
|
expect(
|
|
83
|
-
screen.queryByText('
|
|
106
|
+
screen.queryByText('receivables.action.collect_payment_create'),
|
|
84
107
|
).toBeNull()
|
|
85
108
|
})
|
|
86
109
|
|
|
@@ -78,6 +78,20 @@ describe('isRowActionVisible', () => {
|
|
|
78
78
|
expect(isActionConditionMet({ condition: { field: 's', operator: 'neq', value: 'a' } }, { s: 'a' })).toBe(false)
|
|
79
79
|
})
|
|
80
80
|
|
|
81
|
+
it('isActionConditionMet supports truthy/falsy (and the present/set/blank/empty aliases)', () => {
|
|
82
|
+
const hasBalance = { condition: { field: 'amount_due', operator: 'truthy' } }
|
|
83
|
+
const noBalance = { condition: { field: 'amount_due', operator: 'falsy' } }
|
|
84
|
+
expect(isActionConditionMet(hasBalance, { amount_due: 6180 })).toBe(true)
|
|
85
|
+
expect(isActionConditionMet(hasBalance, { amount_due: 0 })).toBe(false)
|
|
86
|
+
expect(isActionConditionMet(hasBalance, { amount_due: undefined })).toBe(false)
|
|
87
|
+
expect(isActionConditionMet(noBalance, { amount_due: 0 })).toBe(true)
|
|
88
|
+
expect(isActionConditionMet(noBalance, { amount_due: 6180 })).toBe(false)
|
|
89
|
+
expect(isActionConditionMet({ condition: { field: 'flag', operator: 'present' } }, { flag: 'x' })).toBe(true)
|
|
90
|
+
expect(isActionConditionMet({ condition: { field: 'flag', operator: 'set' } }, { flag: false })).toBe(false)
|
|
91
|
+
expect(isActionConditionMet({ condition: { field: 'flag', operator: 'blank' } }, { flag: '' })).toBe(true)
|
|
92
|
+
expect(isActionConditionMet({ condition: { field: 'flag', operator: 'empty' } }, { flag: 'x' })).toBe(false)
|
|
93
|
+
})
|
|
94
|
+
|
|
81
95
|
it('isActionConditionMet resolves nested paths and equals/notEquals aliases', () => {
|
|
82
96
|
const approve = {
|
|
83
97
|
condition: { field: 'user.verified', operator: 'equals', value: false },
|
|
@@ -56,3 +56,25 @@ export function humanizeToken(value: unknown): string {
|
|
|
56
56
|
})
|
|
57
57
|
.join(' ')
|
|
58
58
|
}
|
|
59
|
+
|
|
60
|
+
export type MetadataTranslator = (
|
|
61
|
+
key: string,
|
|
62
|
+
options?: { defaultValue?: string },
|
|
63
|
+
) => string
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Resolve addon-contributed metadata at render time. Known i18n keys use the
|
|
67
|
+
* host locale; missing keys degrade to a readable label instead of leaking a
|
|
68
|
+
* machine path such as `models.orders.table.columns.payment_status`.
|
|
69
|
+
*/
|
|
70
|
+
export function translateMetadataLabel(
|
|
71
|
+
value: string | undefined,
|
|
72
|
+
translate?: MetadataTranslator,
|
|
73
|
+
): string {
|
|
74
|
+
if (!value) return ''
|
|
75
|
+
const token = value.includes('.') ? value.split('.').at(-1) ?? value : value
|
|
76
|
+
const fallback = humanizeToken(token)
|
|
77
|
+
if (!translate) return fallback
|
|
78
|
+
const translated = translate(value, { defaultValue: fallback })
|
|
79
|
+
return translated && translated !== value ? translated : fallback
|
|
80
|
+
}
|
package/src/dynamic-columns.tsx
CHANGED
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
relationChipStyles,
|
|
43
43
|
} from '@asteby/metacore-ui/lib'
|
|
44
44
|
import { Progress } from './dialogs/_primitives'
|
|
45
|
-
import { humanizeToken } from './dynamic-columns-helpers'
|
|
45
|
+
import { humanizeToken, translateMetadataLabel } from './dynamic-columns-helpers'
|
|
46
46
|
import { objectLabel } from './dynamic-relation-helpers'
|
|
47
47
|
import {
|
|
48
48
|
OptionBadge,
|
|
@@ -244,9 +244,21 @@ export const isActionAllowedForRowState = (action: any, row: any): boolean => {
|
|
|
244
244
|
* Declarative `condition` gate for a per-row action: shows the action only when
|
|
245
245
|
* the row's `field` satisfies the operator. Supports both the SDK dialect
|
|
246
246
|
* (`eq` | `neq` | `in` | `not_in`) and the common host dialect
|
|
247
|
-
* (`equals` | `notEquals` | `not_in`)
|
|
248
|
-
*
|
|
249
|
-
*
|
|
247
|
+
* (`equals` | `notEquals` | `not_in`), plus the truthy/falsy family (same
|
|
248
|
+
* operator set as the host's document print gate — services/document_gate.go
|
|
249
|
+
* — kept in sync so a manifest author doesn't have to know which gate a given
|
|
250
|
+
* contribution goes through). Nested paths (`user.verified`) are resolved via
|
|
251
|
+
* `getNestedValue`. No condition → always shown.
|
|
252
|
+
*
|
|
253
|
+
* `default: return true` for a genuinely unknown operator is deliberate — an
|
|
254
|
+
* addon shipped against a newer SDK than the host runs should degrade to
|
|
255
|
+
* "always show" (worst case: an extra menu item), never to "always hide"
|
|
256
|
+
* (worst case: a feature silently vanishes). That same permissiveness is why
|
|
257
|
+
* `truthy`/`falsy` going unrecognized here was a real, silent bug rather
|
|
258
|
+
* than a build error: confirmed live — a `condition: {field: "amount_due",
|
|
259
|
+
* operator: "truthy"}` row action rendered on every row regardless of
|
|
260
|
+
* amount_due, because the switch fell through to the default and nothing
|
|
261
|
+
* ever signaled it wasn't actually gating anything.
|
|
250
262
|
*/
|
|
251
263
|
export const isActionConditionMet = (action: any, row: any): boolean => {
|
|
252
264
|
if (!action?.condition) return true
|
|
@@ -279,6 +291,14 @@ export const isActionConditionMet = (action: any, row: any): boolean => {
|
|
|
279
291
|
case 'not_in':
|
|
280
292
|
case 'notin':
|
|
281
293
|
return !values.includes(rowValue)
|
|
294
|
+
case 'truthy':
|
|
295
|
+
case 'present':
|
|
296
|
+
case 'set':
|
|
297
|
+
return rowValue !== '' && rowValue !== 'false' && rowValue !== '0'
|
|
298
|
+
case 'falsy':
|
|
299
|
+
case 'blank':
|
|
300
|
+
case 'empty':
|
|
301
|
+
return rowValue === '' || rowValue === 'false' || rowValue === '0'
|
|
282
302
|
default:
|
|
283
303
|
return true
|
|
284
304
|
}
|
|
@@ -854,7 +874,7 @@ export function makeDefaultGetDynamicColumns(
|
|
|
854
874
|
// `visibility` scope (skips `'modal'` and `'list'`).
|
|
855
875
|
if (!isColumnVisibleInTable(col)) return
|
|
856
876
|
|
|
857
|
-
const translatedLabel = col.label
|
|
877
|
+
const translatedLabel = translateMetadataLabel(col.label, t)
|
|
858
878
|
const filterConfig = filterConfigs?.get(col.key)
|
|
859
879
|
|
|
860
880
|
const columnMeta: Record<string, unknown> = {
|
|
@@ -1478,7 +1498,7 @@ export function makeDefaultGetDynamicColumns(
|
|
|
1478
1498
|
onClick={() => onAction && onAction(action.key, row.original)}
|
|
1479
1499
|
>
|
|
1480
1500
|
<DynamicIcon name={action.icon} className="mr-2 h-4 w-4" />
|
|
1481
|
-
{action.label}
|
|
1501
|
+
{translateMetadataLabel(action.label, t)}
|
|
1482
1502
|
</DropdownMenuItem>
|
|
1483
1503
|
))}
|
|
1484
1504
|
</DropdownMenuContent>
|
package/src/index.ts
CHANGED
|
@@ -265,7 +265,8 @@ export {
|
|
|
265
265
|
resolveRelationLabel,
|
|
266
266
|
type DynamicColumnsHelpers,
|
|
267
267
|
} from './dynamic-columns'
|
|
268
|
-
export { humanizeToken } from './dynamic-columns-helpers'
|
|
268
|
+
export { humanizeToken, translateMetadataLabel } from './dynamic-columns-helpers'
|
|
269
|
+
export type { MetadataTranslator } from './dynamic-columns-helpers'
|
|
269
270
|
export {
|
|
270
271
|
UrlChip,
|
|
271
272
|
FileChip,
|
|
@@ -46,10 +46,42 @@ export interface ModelActionToolbarProps {
|
|
|
46
46
|
onChange?: () => void
|
|
47
47
|
/** Extra classes on the button row container. */
|
|
48
48
|
className?: string
|
|
49
|
+
/**
|
|
50
|
+
* Fired on hover/focus of an action button so the host can prefetch a
|
|
51
|
+
* federated remote (e.g. collections) before the click — Module Federation
|
|
52
|
+
* lazy load without blocking first paint of the list page.
|
|
53
|
+
*/
|
|
54
|
+
onActionIntent?: (action: ActionDefinition) => void
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
const DEFAULT_PLACEMENTS: ActionPlacement[] = ['table', 'create']
|
|
52
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Last-resort label when `t(key)` has no translation yet: never flash the full
|
|
61
|
+
* dotted key in a primary CTA. Prefers the action/field segment over a trailing
|
|
62
|
+
* `.label` / `.confirm` leaf.
|
|
63
|
+
* "receivables.action.collect_payment_create" → "Collect payment create"
|
|
64
|
+
* "integration_github.action.create_issue.label" → "Create issue"
|
|
65
|
+
* Already-human labels pass through unchanged.
|
|
66
|
+
*/
|
|
67
|
+
export function humanizeActionLabel(label: string): string {
|
|
68
|
+
if (!label) return label
|
|
69
|
+
if (!label.includes('.') || /\s/.test(label)) return label
|
|
70
|
+
const parts = label.split('.').filter(Boolean)
|
|
71
|
+
let leaf = parts[parts.length - 1] || label
|
|
72
|
+
if (
|
|
73
|
+
(leaf === 'label' || leaf === 'confirm' || leaf === 'title') &&
|
|
74
|
+
parts.length >= 2
|
|
75
|
+
) {
|
|
76
|
+
leaf = parts[parts.length - 2]
|
|
77
|
+
}
|
|
78
|
+
return leaf
|
|
79
|
+
.split('_')
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
82
|
+
.join(' ')
|
|
83
|
+
}
|
|
84
|
+
|
|
53
85
|
function toActionMetadata(a: ActionDefinition): ActionMetadata {
|
|
54
86
|
return {
|
|
55
87
|
key: a.key,
|
|
@@ -109,6 +141,7 @@ export function ModelActionToolbar({
|
|
|
109
141
|
placements = DEFAULT_PLACEMENTS,
|
|
110
142
|
onChange,
|
|
111
143
|
className,
|
|
144
|
+
onActionIntent,
|
|
112
145
|
}: ModelActionToolbarProps) {
|
|
113
146
|
const { t } = useTranslation()
|
|
114
147
|
const all = useModelActions(model, placements, actions)
|
|
@@ -133,7 +166,12 @@ export function ModelActionToolbar({
|
|
|
133
166
|
<Button
|
|
134
167
|
key={a.key}
|
|
135
168
|
variant={isCreate ? 'default' : 'outline'}
|
|
136
|
-
onClick={() =>
|
|
169
|
+
onClick={() => {
|
|
170
|
+
onActionIntent?.(a)
|
|
171
|
+
setActive(toActionMetadata(a))
|
|
172
|
+
}}
|
|
173
|
+
onMouseEnter={() => onActionIntent?.(a)}
|
|
174
|
+
onFocus={() => onActionIntent?.(a)}
|
|
137
175
|
style={a.color && !isCreate ? { borderColor: a.color, color: a.color } : undefined}
|
|
138
176
|
>
|
|
139
177
|
<DynamicIcon name={a.icon || (isCreate ? 'Plus' : 'Zap')} className="mr-2 h-4 w-4" />
|
|
@@ -142,8 +180,9 @@ export function ModelActionToolbar({
|
|
|
142
180
|
locale bundle loads asynchronously, so translate at render — a
|
|
143
181
|
bare `{a.label}` prints the raw key until (and after) the bundle
|
|
144
182
|
lands because nothing re-derives it. defaultValue keeps an
|
|
145
|
-
already-localized label untouched
|
|
146
|
-
|
|
183
|
+
already-localized label untouched; humanizeLastSegment avoids
|
|
184
|
+
flashing the full dotted key when the bundle is still in flight. */}
|
|
185
|
+
{t(a.label, { defaultValue: humanizeActionLabel(a.label) })}
|
|
147
186
|
</Button>
|
|
148
187
|
)
|
|
149
188
|
})}
|