@asteby/metacore-runtime-react 44.0.0 → 45.2.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/CHANGELOG.md +28 -0
- package/dist/approval-events.d.ts +16 -0
- package/dist/approval-events.d.ts.map +1 -0
- package/dist/approval-events.js +27 -0
- package/dist/approval-gate.d.ts +39 -0
- package/dist/approval-gate.d.ts.map +1 -0
- package/dist/approval-gate.js +110 -0
- package/dist/approval-pin-dialog.d.ts +25 -0
- package/dist/approval-pin-dialog.d.ts.map +1 -0
- package/dist/approval-pin-dialog.js +66 -0
- package/dist/business/catalog.d.ts +16 -0
- package/dist/business/catalog.d.ts.map +1 -0
- package/dist/business/catalog.js +42 -0
- package/dist/business/customer-picker.d.ts +39 -0
- package/dist/business/customer-picker.d.ts.map +1 -0
- package/dist/business/customer-picker.js +51 -0
- package/dist/business/feedback.d.ts +72 -0
- package/dist/business/feedback.d.ts.map +1 -0
- package/dist/business/feedback.js +52 -0
- package/dist/business/field-errors.d.ts +26 -0
- package/dist/business/field-errors.d.ts.map +1 -0
- package/dist/business/field-errors.js +59 -0
- package/dist/business/format.d.ts +49 -0
- package/dist/business/format.d.ts.map +1 -0
- package/dist/business/format.js +128 -0
- package/dist/business/index.d.ts +14 -0
- package/dist/business/index.d.ts.map +1 -0
- package/dist/business/index.js +13 -0
- package/dist/business/line-items-editor.d.ts +25 -0
- package/dist/business/line-items-editor.d.ts.map +1 -0
- package/dist/business/line-items-editor.js +36 -0
- package/dist/business/line-items.d.ts +69 -0
- package/dist/business/line-items.d.ts.map +1 -0
- package/dist/business/line-items.js +133 -0
- package/dist/business/payment-capture.d.ts +21 -0
- package/dist/business/payment-capture.d.ts.map +1 -0
- package/dist/business/payment-capture.js +24 -0
- package/dist/business/payment.d.ts +61 -0
- package/dist/business/payment.d.ts.map +1 -0
- package/dist/business/payment.js +74 -0
- package/dist/business/product-picker.d.ts +24 -0
- package/dist/business/product-picker.d.ts.map +1 -0
- package/dist/business/product-picker.js +48 -0
- package/dist/business/product-search.d.ts +70 -0
- package/dist/business/product-search.d.ts.map +1 -0
- package/dist/business/product-search.js +51 -0
- package/dist/business/refund-destination.d.ts +19 -0
- package/dist/business/refund-destination.d.ts.map +1 -0
- package/dist/business/refund-destination.js +31 -0
- package/dist/business/refund.d.ts +29 -0
- package/dist/business/refund.d.ts.map +1 -0
- package/dist/business/refund.js +43 -0
- package/dist/business/use-async-search.d.ts +10 -0
- package/dist/business/use-async-search.d.ts.map +1 -0
- package/dist/business/use-async-search.js +38 -0
- package/dist/document/action-bar.d.ts +12 -0
- package/dist/document/action-bar.d.ts.map +1 -0
- package/dist/document/action-bar.js +39 -0
- package/dist/document/cancel-with-reason.d.ts +47 -0
- package/dist/document/cancel-with-reason.d.ts.map +1 -0
- package/dist/document/cancel-with-reason.js +52 -0
- package/dist/document/document-header.d.ts +41 -0
- package/dist/document/document-header.d.ts.map +1 -0
- package/dist/document/document-header.js +30 -0
- package/dist/document/document-page.d.ts +37 -0
- package/dist/document/document-page.d.ts.map +1 -0
- package/dist/document/document-page.js +137 -0
- package/dist/document/document-timeline.d.ts +20 -0
- package/dist/document/document-timeline.d.ts.map +1 -0
- package/dist/document/document-timeline.js +26 -0
- package/dist/document/evaluate.d.ts +31 -0
- package/dist/document/evaluate.d.ts.map +1 -0
- package/dist/document/evaluate.js +170 -0
- package/dist/document/format.d.ts +9 -0
- package/dist/document/format.d.ts.map +1 -0
- package/dist/document/format.js +52 -0
- package/dist/document/index.d.ts +13 -0
- package/dist/document/index.d.ts.map +1 -0
- package/dist/document/index.js +12 -0
- package/dist/document/registry.d.ts +20 -0
- package/dist/document/registry.d.ts.map +1 -0
- package/dist/document/registry.js +20 -0
- package/dist/document/smart-buttons.d.ts +16 -0
- package/dist/document/smart-buttons.d.ts.map +1 -0
- package/dist/document/smart-buttons.js +16 -0
- package/dist/document/status-badge.d.ts +16 -0
- package/dist/document/status-badge.d.ts.map +1 -0
- package/dist/document/status-badge.js +23 -0
- package/dist/document/types.d.ts +196 -0
- package/dist/document/types.d.ts.map +1 -0
- package/dist/document/types.js +1 -0
- package/dist/document/use-document-sources.d.ts +14 -0
- package/dist/document/use-document-sources.d.ts.map +1 -0
- package/dist/document/use-document-sources.js +72 -0
- package/dist/dynamic-columns.d.ts +11 -0
- package/dist/dynamic-columns.d.ts.map +1 -1
- package/dist/dynamic-columns.js +13 -1
- package/dist/dynamic-kanban.d.ts.map +1 -1
- package/dist/dynamic-kanban.js +4 -5
- package/dist/dynamic-row-actions.d.ts.map +1 -1
- package/dist/dynamic-row-actions.js +12 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/model-action-toolbar.d.ts.map +1 -1
- package/dist/model-action-toolbar.js +16 -3
- package/dist/requires-addon.d.ts +37 -0
- package/dist/requires-addon.d.ts.map +1 -0
- package/dist/requires-addon.js +104 -0
- package/dist/server-error.d.ts.map +1 -1
- package/dist/server-error.js +19 -0
- package/dist/types.d.ts +23 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/approval-gate.test.tsx +134 -0
- package/src/__tests__/requires-addon.test.tsx +201 -0
- package/src/approval-events.ts +39 -0
- package/src/approval-gate.tsx +180 -0
- package/src/approval-pin-dialog.tsx +162 -0
- package/src/business/business.test.ts +164 -0
- package/src/business/catalog.ts +60 -0
- package/src/business/customer-picker.tsx +201 -0
- package/src/business/feedback.tsx +141 -0
- package/src/business/field-errors.ts +92 -0
- package/src/business/format.ts +151 -0
- package/src/business/index.ts +13 -0
- package/src/business/line-items-editor.tsx +259 -0
- package/src/business/line-items.ts +190 -0
- package/src/business/payment-capture.tsx +158 -0
- package/src/business/payment.ts +125 -0
- package/src/business/product-picker.tsx +171 -0
- package/src/business/product-search.ts +108 -0
- package/src/business/refund-destination.tsx +121 -0
- package/src/business/refund.ts +71 -0
- package/src/business/use-async-search.ts +43 -0
- package/src/document/__tests__/document-page.test.tsx +107 -0
- package/src/document/__tests__/evaluate.test.ts +140 -0
- package/src/document/action-bar.tsx +140 -0
- package/src/document/cancel-with-reason.tsx +214 -0
- package/src/document/document-header.tsx +140 -0
- package/src/document/document-page.tsx +268 -0
- package/src/document/document-timeline.tsx +66 -0
- package/src/document/evaluate.ts +180 -0
- package/src/document/format.ts +59 -0
- package/src/document/index.ts +28 -0
- package/src/document/registry.ts +39 -0
- package/src/document/smart-buttons.tsx +54 -0
- package/src/document/status-badge.tsx +44 -0
- package/src/document/types.ts +203 -0
- package/src/document/use-document-sources.ts +91 -0
- package/src/dynamic-columns.tsx +36 -6
- package/src/dynamic-kanban.tsx +6 -7
- package/src/dynamic-row-actions.tsx +15 -1
- package/src/index.ts +34 -0
- package/src/model-action-toolbar.tsx +28 -3
- package/src/requires-addon.tsx +160 -0
- package/src/server-error.ts +20 -0
- package/src/types.ts +24 -0
package/dist/types.d.ts
CHANGED
|
@@ -597,6 +597,15 @@ export interface FieldOptionsConfig {
|
|
|
597
597
|
/** Optional column projected into `option.image`. */
|
|
598
598
|
image?: string;
|
|
599
599
|
}
|
|
600
|
+
/** An optional addon an action needs before it can run. */
|
|
601
|
+
export interface RequiresAddon {
|
|
602
|
+
/** Addon key, e.g. "connector_whatsapp". */
|
|
603
|
+
key: string;
|
|
604
|
+
/** Localized display name, e.g. "Conector WhatsApp". Falls back to `key`. */
|
|
605
|
+
name?: string;
|
|
606
|
+
/** Why the action needs it (literal or i18n key). */
|
|
607
|
+
reason?: string;
|
|
608
|
+
}
|
|
600
609
|
export interface ActionDefinition {
|
|
601
610
|
key: string;
|
|
602
611
|
name: string;
|
|
@@ -623,6 +632,13 @@ export interface ActionDefinition {
|
|
|
623
632
|
* "create" — toolbar button that replaces the generic create button.
|
|
624
633
|
*/
|
|
625
634
|
placement?: 'row' | 'table' | 'create';
|
|
635
|
+
/**
|
|
636
|
+
* Optional addon this action depends on, stamped by the host only while it
|
|
637
|
+
* is NOT installed (served as `requires_addon`; read through
|
|
638
|
+
* resolveRequiresAddon). The action stays visible but locked: a click opens
|
|
639
|
+
* the "requires addon" dialog instead of executing.
|
|
640
|
+
*/
|
|
641
|
+
requiresAddon?: RequiresAddon;
|
|
626
642
|
}
|
|
627
643
|
export interface ApiResponse<T> {
|
|
628
644
|
success: boolean;
|
|
@@ -660,5 +676,12 @@ export interface ActionMetadata {
|
|
|
660
676
|
/** Federated modal slug "<addon_key>.<action_key>"; see ActionModalDispatcher. */
|
|
661
677
|
modal?: string;
|
|
662
678
|
placement?: 'row' | 'table' | 'create';
|
|
679
|
+
/**
|
|
680
|
+
* Optional addon this action depends on, stamped by the host only while it
|
|
681
|
+
* is NOT installed (served as `requires_addon`; read through
|
|
682
|
+
* resolveRequiresAddon). The action stays visible but locked: a click opens
|
|
683
|
+
* the "requires addon" dialog instead of executing.
|
|
684
|
+
*/
|
|
685
|
+
requiresAddon?: RequiresAddon;
|
|
663
686
|
}
|
|
664
687
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA;gCACgC;AAChC,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,YAAY,EAAE,CAAA;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,aAAa,EAAE,CAAA;IAC7B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;CAClC;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC3D,CAAA;CACJ;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC1D;AAED,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;CACb;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,IAAI,EAAE,aAAa,GAAG,cAAc,CAAA;IACpC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,IAAI,EAAE,QAAQ,GAAG,gBAAgB,GAAG,SAAS,GAAG,YAAY,GAAG,cAAc,GAAG,MAAM,CAAA;IACtF,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACrF,cAAc,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEjF,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EACE,MAAM,GACN,QAAQ,GACR,MAAM,GAGN,UAAU,GACV,WAAW,GACX,aAAa,GACb,QAAQ,GACR,QAAQ,GACR,qBAAqB,GACrB,QAAQ,GACR,SAAS,GACT,OAAO,GACP,eAAe,GACf,OAAO,GAEP,aAAa,GAEb,KAAK,GACL,MAAM,GACN,OAAO,GACP,UAAU,GACV,SAAS,GACT,UAAU,GACV,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,GACP,MAAM,GACN,eAAe,GACf,SAAS,GACT,MAAM,GAKN,UAAU,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;IACnB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,QAAQ,GAAG,gBAAgB,GAAG,SAAS,GAAG,YAAY,GAAG,cAAc,GAAG,MAAM,CAAA;IAC7F,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC3E;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,GAAG,MAAM,CAAA;IACrC;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,8DAA8D;IAC9D,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;IAC/B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAA;IACxC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;IACb;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAOD,MAAM,WAAW,eAAe;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAID,MAAM,MAAM,WAAW,GACjB,MAAM,GACN,UAAU,GACV,UAAU,GACV,OAAO,GACP,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,gBAAgB,GAChB,QAAQ,GACR,QAAQ,GACR,MAAM,CAAA;AAEZ;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACvB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,UAAU,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,SAAS,EAAE,CAAA;IACrB,YAAY,CAAC,EAAE,GAAG,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,eAAe,GAAG,MAAM,CAAA;IACrC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;IAC7B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAA;IAClC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,kBAAkB,CAAA;IACnC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,kCAAkC;IAClC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,cAAc,EAAE,CAAA;IAC7B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAC/B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC1B,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAA;IACX,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;IACpD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,cAAc,EAAE,CAAA;IACzB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;IACtC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;CAChC;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,CAAC,CAAA;IACP,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;CAChB;AAKD,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,cAAc,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,cAAc,EAAE,CAAA;IACzB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;IACtC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;CAChC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asteby/metacore-runtime-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "45.2.0",
|
|
4
4
|
"description": "React runtime for metacore hosts — renders addon contributions dynamically",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"zod": "^4.3.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"@asteby/metacore-sdk": "^3.
|
|
29
|
+
"@asteby/metacore-sdk": "^3.11.0",
|
|
30
30
|
"@asteby/metacore-ui": "^2.23.0",
|
|
31
31
|
"@tanstack/react-query": ">=5",
|
|
32
32
|
"@tanstack/react-router": ">=1.100",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@asteby/metacore-sdk": "3.
|
|
53
|
+
"@asteby/metacore-sdk": "3.11.0",
|
|
54
54
|
"@asteby/metacore-ui": "2.23.0",
|
|
55
55
|
"@tanstack/react-query": "^5.95.0",
|
|
56
56
|
"@tanstack/react-router": "^1.168.0",
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
//
|
|
3
|
+
// ApprovalGate: inline PIN grants + parked-request approval, and the capability
|
|
4
|
+
// bypass that lets a supervisor skip their own prompt.
|
|
5
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
6
|
+
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
|
7
|
+
|
|
8
|
+
vi.mock('react-i18next', () => ({
|
|
9
|
+
useTranslation: () => ({
|
|
10
|
+
t: (_k: string, opts?: { defaultValue?: string }) => opts?.defaultValue ?? _k,
|
|
11
|
+
}),
|
|
12
|
+
}))
|
|
13
|
+
vi.mock('sonner', () => ({ toast: Object.assign(vi.fn(), { info: vi.fn(), success: vi.fn(), error: vi.fn() }) }))
|
|
14
|
+
|
|
15
|
+
import { ApiProvider, type ApiClient } from '../api-context'
|
|
16
|
+
import { PermissionsProvider } from '../permissions-context'
|
|
17
|
+
import {
|
|
18
|
+
ApprovalGateProvider,
|
|
19
|
+
useApprovalGate,
|
|
20
|
+
approvalRequiredInfo,
|
|
21
|
+
APPROVAL_PARKED_EVENT,
|
|
22
|
+
type ApprovalGrant,
|
|
23
|
+
} from '../approval-gate'
|
|
24
|
+
import { toastServerError } from '../server-error'
|
|
25
|
+
import { toast } from 'sonner'
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
cleanup()
|
|
29
|
+
vi.clearAllMocks()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
function makeApi(post: ApiClient['post']): ApiClient {
|
|
33
|
+
return { get: vi.fn(), post, put: vi.fn(), delete: vi.fn() } as unknown as ApiClient
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let lastGrant: ApprovalGrant | null | undefined
|
|
37
|
+
function Probe({ policy }: { policy: string }) {
|
|
38
|
+
const gate = useApprovalGate()
|
|
39
|
+
return (
|
|
40
|
+
<button
|
|
41
|
+
onClick={async () => {
|
|
42
|
+
lastGrant = await gate.requestApproval({ policy, label: 'Venta sin existencias', context: { qty: 3 } })
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
ask
|
|
46
|
+
</button>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function mount(post: ApiClient['post'], caps: string[] = [], isAdmin = false) {
|
|
51
|
+
lastGrant = undefined
|
|
52
|
+
return render(
|
|
53
|
+
<ApiProvider client={makeApi(post)}>
|
|
54
|
+
<PermissionsProvider permissions={caps} isAdmin={isAdmin}>
|
|
55
|
+
<ApprovalGateProvider>
|
|
56
|
+
<Probe policy="oversell" />
|
|
57
|
+
</ApprovalGateProvider>
|
|
58
|
+
</PermissionsProvider>
|
|
59
|
+
</ApiProvider>,
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function fill(reason: string, pin: string) {
|
|
64
|
+
fireEvent.change(screen.getByLabelText('Motivo'), { target: { value: reason } })
|
|
65
|
+
fireEvent.change(screen.getByLabelText('PIN del supervisor'), { target: { value: pin } })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
describe('ApprovalGate', () => {
|
|
69
|
+
it('a holder of general.approve_<policy> passes without a prompt', async () => {
|
|
70
|
+
const post = vi.fn()
|
|
71
|
+
mount(post, ['general.approve_oversell'])
|
|
72
|
+
await act(async () => fireEvent.click(screen.getByText('ask')))
|
|
73
|
+
expect(lastGrant).toEqual({ id: null, policy: 'oversell', bypassed: true })
|
|
74
|
+
expect(post).not.toHaveBeenCalled()
|
|
75
|
+
expect(screen.queryByLabelText('PIN del supervisor')).toBeNull()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('posts pin-grant with reason + context and resolves the audit id', async () => {
|
|
79
|
+
const post = vi.fn().mockResolvedValue({ data: { success: true, data: { id: 'audit-1' } } })
|
|
80
|
+
mount(post)
|
|
81
|
+
await act(async () => fireEvent.click(screen.getByText('ask')))
|
|
82
|
+
const submit = screen.getByText('Autorizar').closest('button')!
|
|
83
|
+
expect(submit.hasAttribute('disabled')).toBe(true) // reason + PIN required
|
|
84
|
+
fill('cliente esperando', '4321')
|
|
85
|
+
await act(async () => fireEvent.click(submit))
|
|
86
|
+
await waitFor(() => expect(lastGrant).toBeDefined())
|
|
87
|
+
expect(post).toHaveBeenCalledWith(
|
|
88
|
+
'/approvals/pin-grant',
|
|
89
|
+
expect.objectContaining({ policy: 'oversell', pin: '4321', reason: 'cliente esperando', context: { qty: 3 } }),
|
|
90
|
+
)
|
|
91
|
+
expect(lastGrant).toMatchObject({ id: 'audit-1', bypassed: false })
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('a wrong PIN keeps the dialog open with an inline message and nothing resolves', async () => {
|
|
95
|
+
const post = vi.fn().mockRejectedValue({ response: { data: { error: { code: 'approval_pin_invalid' } } } })
|
|
96
|
+
mount(post)
|
|
97
|
+
await act(async () => fireEvent.click(screen.getByText('ask')))
|
|
98
|
+
fill('r', '0000')
|
|
99
|
+
await act(async () => fireEvent.click(screen.getByText('Autorizar').closest('button')!))
|
|
100
|
+
expect(await screen.findByRole('alert')).toBeTruthy()
|
|
101
|
+
expect(lastGrant).toBeUndefined()
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('cancelling resolves null (fail closed)', async () => {
|
|
105
|
+
mount(vi.fn())
|
|
106
|
+
await act(async () => fireEvent.click(screen.getByText('ask')))
|
|
107
|
+
await act(async () => fireEvent.click(screen.getByText('Cancelar')))
|
|
108
|
+
await waitFor(() => expect(lastGrant).toBeNull())
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('a parked approval_required toast offers the PIN and approves through approve-pin', async () => {
|
|
112
|
+
const post = vi.fn().mockResolvedValue({ data: { success: true } })
|
|
113
|
+
mount(post)
|
|
114
|
+
const err = {
|
|
115
|
+
response: {
|
|
116
|
+
data: { success: false, error: { code: 'approval_required' }, meta: { approval_request_id: 'req-9', approval_label: 'Precio bajo el piso', approval_roles: ['gerente'] } },
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
expect(approvalRequiredInfo(err)).toMatchObject({ requestId: 'req-9', roles: ['gerente'] })
|
|
120
|
+
toastServerError(err)
|
|
121
|
+
const opts = (toast.info as unknown as ReturnType<typeof vi.fn>).mock.calls[0][1]
|
|
122
|
+
expect(toast.error).not.toHaveBeenCalled()
|
|
123
|
+
await act(async () => opts.action.onClick())
|
|
124
|
+
fill('autorizado', '1234')
|
|
125
|
+
await act(async () => fireEvent.click(screen.getByText('Autorizar').closest('button')!))
|
|
126
|
+
await waitFor(() => expect(post).toHaveBeenCalledWith('/approvals/req-9/approve-pin', { pin: '1234', reason: 'autorizado' }))
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('without a gate mounted the parked toast has no PIN action and the event is inert', () => {
|
|
130
|
+
toastServerError({ response: { data: { error: { code: 'approval_required' }, meta: { approval_request_id: 'x' } } } })
|
|
131
|
+
expect((toast.info as unknown as ReturnType<typeof vi.fn>).mock.calls[0][1].action).toBeUndefined()
|
|
132
|
+
window.dispatchEvent(new CustomEvent(APPROVAL_PARKED_EVENT, { detail: { requestId: 'x', roles: [] } }))
|
|
133
|
+
})
|
|
134
|
+
})
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
//
|
|
3
|
+
// requiresAddon: an action gated by a missing optional addon stays visible but
|
|
4
|
+
// locked. A click must NOT reach the dispatcher / federated modal / backend; it
|
|
5
|
+
// opens the "requires addon" dialog whose "Instalar" hands the key to the host
|
|
6
|
+
// handler, or routes to /marketplace/<key> through the SDK router.
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
8
|
+
import { act, cleanup, fireEvent, render, renderHook, screen } from '@testing-library/react'
|
|
9
|
+
|
|
10
|
+
const I18N_T = (_k: string, opts?: { defaultValue?: string; [k: string]: unknown }) =>
|
|
11
|
+
(opts?.defaultValue ?? _k).replace(/\{\{(\w+)\}\}/g, (_: string, v: string) => String(opts?.[v] ?? ''))
|
|
12
|
+
const USE_TRANSLATION = { t: I18N_T, i18n: { language: 'es' } }
|
|
13
|
+
vi.mock('react-i18next', () => ({
|
|
14
|
+
useTranslation: () => USE_TRANSLATION,
|
|
15
|
+
}))
|
|
16
|
+
|
|
17
|
+
const navigate = vi.fn()
|
|
18
|
+
vi.mock('@tanstack/react-router', () => ({
|
|
19
|
+
useNavigate: () => navigate,
|
|
20
|
+
}))
|
|
21
|
+
|
|
22
|
+
// The dispatcher must never mount for a gated action.
|
|
23
|
+
const dispatcherSpy = vi.fn()
|
|
24
|
+
vi.mock('../action-modal-dispatcher', () => ({
|
|
25
|
+
ActionModalDispatcher: (props: unknown) => {
|
|
26
|
+
dispatcherSpy(props)
|
|
27
|
+
return <div data-testid="dispatcher" />
|
|
28
|
+
},
|
|
29
|
+
}))
|
|
30
|
+
|
|
31
|
+
import { useDynamicRowActions } from '../dynamic-row-actions'
|
|
32
|
+
import { ModelActionToolbar } from '../model-action-toolbar'
|
|
33
|
+
import { RowActionMenuItem } from '../dynamic-columns'
|
|
34
|
+
import { ApiProvider } from '../api-context'
|
|
35
|
+
import { resolveRequiresAddon, setAddonInstallHandler } from '../requires-addon'
|
|
36
|
+
import type { ActionDefinition, TableMetadata } from '../types'
|
|
37
|
+
import { DropdownMenu, DropdownMenuContent } from '@asteby/metacore-ui/primitives'
|
|
38
|
+
|
|
39
|
+
const post = vi.fn(async () => ({ data: { success: true } }))
|
|
40
|
+
const api = {
|
|
41
|
+
get: async () => ({ data: { data: {} } }),
|
|
42
|
+
post,
|
|
43
|
+
put: async () => ({ data: { success: true } }),
|
|
44
|
+
delete: async () => ({ data: { success: true } }),
|
|
45
|
+
} as never
|
|
46
|
+
|
|
47
|
+
const WIRE_REQUIREMENT = {
|
|
48
|
+
key: 'connector_whatsapp',
|
|
49
|
+
name: 'Conector WhatsApp',
|
|
50
|
+
reason: 'Necesitas el conector para vincular un número.',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Exactly as ops serves it: snake_case, plus a federated modal + executable so
|
|
54
|
+
// that, without the gate, the click would open the dispatcher.
|
|
55
|
+
const gatedRowAction = {
|
|
56
|
+
key: 'connect_device',
|
|
57
|
+
name: 'connect_device',
|
|
58
|
+
label: 'Conectar WhatsApp',
|
|
59
|
+
icon: 'QrCode',
|
|
60
|
+
class: '',
|
|
61
|
+
type: 'custom',
|
|
62
|
+
modal: 'link_inbox.connect_device',
|
|
63
|
+
executable: true,
|
|
64
|
+
requires_addon: WIRE_REQUIREMENT,
|
|
65
|
+
} as unknown as ActionDefinition
|
|
66
|
+
|
|
67
|
+
const metadata = { title: 'Devices', actions: [gatedRowAction] } as unknown as TableMetadata
|
|
68
|
+
|
|
69
|
+
function Wrapper({ children }: { children: React.ReactNode }) {
|
|
70
|
+
return <ApiProvider client={api}>{children}</ApiProvider>
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
post.mockClear()
|
|
75
|
+
navigate.mockClear()
|
|
76
|
+
dispatcherSpy.mockClear()
|
|
77
|
+
setAddonInstallHandler(null)
|
|
78
|
+
})
|
|
79
|
+
afterEach(cleanup)
|
|
80
|
+
|
|
81
|
+
describe('resolveRequiresAddon', () => {
|
|
82
|
+
it('normalizes the snake_case requires_addon served by the host', () => {
|
|
83
|
+
expect(resolveRequiresAddon({ requires_addon: WIRE_REQUIREMENT })).toEqual(WIRE_REQUIREMENT)
|
|
84
|
+
})
|
|
85
|
+
it('reads camelCase requiresAddon', () => {
|
|
86
|
+
expect(resolveRequiresAddon({ requiresAddon: { key: 'x' } })).toEqual({ key: 'x' })
|
|
87
|
+
})
|
|
88
|
+
it('treats absent / keyless requirements as runnable', () => {
|
|
89
|
+
expect(resolveRequiresAddon({ key: 'a' })).toBeNull()
|
|
90
|
+
expect(resolveRequiresAddon({ requires_addon: { name: 'Sin key' } })).toBeNull()
|
|
91
|
+
expect(resolveRequiresAddon(undefined)).toBeNull()
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
function RowHarness() {
|
|
96
|
+
const { handleInternalAction, dialogs } = useDynamicRowActions({
|
|
97
|
+
model: 'Device',
|
|
98
|
+
metadata,
|
|
99
|
+
onRefresh: () => {},
|
|
100
|
+
})
|
|
101
|
+
return (
|
|
102
|
+
<>
|
|
103
|
+
<button onClick={() => handleInternalAction('connect_device', { id: 'r1' })}>run</button>
|
|
104
|
+
{dialogs}
|
|
105
|
+
</>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
describe('row actions (table / kanban shared handler)', () => {
|
|
110
|
+
it('does not dispatch nor post; opens the requires-addon dialog', async () => {
|
|
111
|
+
const onAction = vi.fn()
|
|
112
|
+
const { result } = renderHook(
|
|
113
|
+
() => useDynamicRowActions({ model: 'Device', metadata, onAction, onRefresh: () => {} }),
|
|
114
|
+
{ wrapper: Wrapper },
|
|
115
|
+
)
|
|
116
|
+
await act(() => result.current.handleInternalAction('connect_device', { id: 'r1' }))
|
|
117
|
+
expect(onAction).not.toHaveBeenCalled()
|
|
118
|
+
|
|
119
|
+
render(<RowHarness />, { wrapper: Wrapper })
|
|
120
|
+
await act(async () => fireEvent.click(screen.getByText('run')))
|
|
121
|
+
|
|
122
|
+
expect(screen.getByText('Esta acción requiere «Conector WhatsApp»')).toBeTruthy()
|
|
123
|
+
expect(screen.getByText(WIRE_REQUIREMENT.reason)).toBeTruthy()
|
|
124
|
+
expect(screen.queryByTestId('dispatcher')).toBeNull()
|
|
125
|
+
expect(dispatcherSpy).not.toHaveBeenCalled()
|
|
126
|
+
expect(post).not.toHaveBeenCalled()
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('Instalar invokes the host handler with the addon key', async () => {
|
|
130
|
+
const handler = vi.fn()
|
|
131
|
+
setAddonInstallHandler(handler)
|
|
132
|
+
render(<RowHarness />, { wrapper: Wrapper })
|
|
133
|
+
await act(async () => fireEvent.click(screen.getByText('run')))
|
|
134
|
+
await act(async () => fireEvent.click(screen.getByText('Instalar «Conector WhatsApp»')))
|
|
135
|
+
expect(handler).toHaveBeenCalledWith('connector_whatsapp')
|
|
136
|
+
expect(navigate).not.toHaveBeenCalled()
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('without a handler navigates through the router to /marketplace/<key>', async () => {
|
|
140
|
+
render(<RowHarness />, { wrapper: Wrapper })
|
|
141
|
+
await act(async () => fireEvent.click(screen.getByText('run')))
|
|
142
|
+
await act(async () => fireEvent.click(screen.getByText('Instalar «Conector WhatsApp»')))
|
|
143
|
+
expect(navigate).toHaveBeenCalledWith({ to: '/marketplace/connector_whatsapp' })
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('menu entry stays visible with a lock and the addon name as tooltip', () => {
|
|
147
|
+
render(
|
|
148
|
+
<DropdownMenu open>
|
|
149
|
+
<DropdownMenuContent>
|
|
150
|
+
<RowActionMenuItem action={gatedRowAction} label="Conectar WhatsApp" onSelect={() => {}} />
|
|
151
|
+
</DropdownMenuContent>
|
|
152
|
+
</DropdownMenu>,
|
|
153
|
+
)
|
|
154
|
+
const item = screen.getByText('Conectar WhatsApp').closest('[data-requires-addon]')
|
|
155
|
+
expect(item?.getAttribute('data-requires-addon')).toBe('connector_whatsapp')
|
|
156
|
+
expect(item?.getAttribute('title')).toBe('Requiere «Conector WhatsApp»')
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
describe('ModelActionToolbar', () => {
|
|
161
|
+
const toolbarAction = {
|
|
162
|
+
...gatedRowAction,
|
|
163
|
+
placement: 'table',
|
|
164
|
+
requires_addon: undefined,
|
|
165
|
+
requiresAddon: { key: 'connector_whatsapp', name: 'Conector WhatsApp' },
|
|
166
|
+
} as unknown as ActionDefinition
|
|
167
|
+
|
|
168
|
+
it('renders the action locked and opens the dialog instead of the dispatcher', async () => {
|
|
169
|
+
const intent = vi.fn()
|
|
170
|
+
render(
|
|
171
|
+
<Wrapper>
|
|
172
|
+
<ModelActionToolbar model="Device" actions={[toolbarAction]} onActionIntent={intent} />
|
|
173
|
+
</Wrapper>,
|
|
174
|
+
)
|
|
175
|
+
const button = screen.getByText('Conectar WhatsApp').closest('button')!
|
|
176
|
+
expect(button.getAttribute('title')).toBe('Requiere «Conector WhatsApp»')
|
|
177
|
+
expect(button.querySelector('[data-requires-addon="connector_whatsapp"]')).toBeTruthy()
|
|
178
|
+
|
|
179
|
+
await act(async () => fireEvent.click(button))
|
|
180
|
+
expect(screen.getByText('Esta acción requiere «Conector WhatsApp»')).toBeTruthy()
|
|
181
|
+
// No reason from the host → generic copy.
|
|
182
|
+
expect(screen.getByText('Instala «Conector WhatsApp» para habilitar esta acción.')).toBeTruthy()
|
|
183
|
+
expect(dispatcherSpy).not.toHaveBeenCalled()
|
|
184
|
+
expect(intent).not.toHaveBeenCalled()
|
|
185
|
+
expect(post).not.toHaveBeenCalled()
|
|
186
|
+
|
|
187
|
+
await act(async () => fireEvent.click(screen.getByText('Instalar «Conector WhatsApp»')))
|
|
188
|
+
expect(navigate).toHaveBeenCalledWith({ to: '/marketplace/connector_whatsapp' })
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it('an ungated action still opens the dispatcher', async () => {
|
|
192
|
+
const plain = { ...toolbarAction, key: 'other', label: 'Otra', requiresAddon: undefined } as ActionDefinition
|
|
193
|
+
render(
|
|
194
|
+
<Wrapper>
|
|
195
|
+
<ModelActionToolbar model="Device" actions={[plain]} />
|
|
196
|
+
</Wrapper>,
|
|
197
|
+
)
|
|
198
|
+
await act(async () => fireEvent.click(screen.getByText('Otra')))
|
|
199
|
+
expect(dispatcherSpy).toHaveBeenCalled()
|
|
200
|
+
})
|
|
201
|
+
})
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// approval-events — dependency-free glue between server-error.ts (which sees a
|
|
2
|
+
// parked `approval_required` write) and <ApprovalGateProvider> (which owns the
|
|
3
|
+
// PIN dialog). Kept apart so the error toaster never imports React/UI code.
|
|
4
|
+
|
|
5
|
+
/** Window event toastServerError fires for a parked `approval_required` write. */
|
|
6
|
+
export const APPROVAL_PARKED_EVENT = 'metacore:approval-parked'
|
|
7
|
+
/** Fired after a parked request was approved (and replayed) with a PIN. */
|
|
8
|
+
export const APPROVAL_DECIDED_EVENT = 'metacore:approval-decided'
|
|
9
|
+
|
|
10
|
+
let gateMounted = 0
|
|
11
|
+
/** @internal provider bookkeeping. */
|
|
12
|
+
export function gateMountedDelta(d: number): void {
|
|
13
|
+
gateMounted += d
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** True while an <ApprovalGateProvider> is mounted (toastServerError offers the PIN action only then). */
|
|
17
|
+
export function approvalGateAvailable(): boolean {
|
|
18
|
+
return gateMounted > 0
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ApprovalRequiredInfo {
|
|
22
|
+
requestId: string
|
|
23
|
+
label?: string
|
|
24
|
+
roles: string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Extracts the parked-request info from an axios error / response body, or null. */
|
|
28
|
+
export function approvalRequiredInfo(err: unknown): ApprovalRequiredInfo | null {
|
|
29
|
+
const data = ((err as { response?: { data?: unknown } })?.response?.data ?? err) as
|
|
30
|
+
| { error?: { code?: string }; meta?: { approval_request_id?: string; approval_label?: string; approval_roles?: string[] } }
|
|
31
|
+
| undefined
|
|
32
|
+
if (data?.error?.code !== 'approval_required') return null
|
|
33
|
+
return {
|
|
34
|
+
requestId: data.meta?.approval_request_id ?? '',
|
|
35
|
+
label: data.meta?.approval_label,
|
|
36
|
+
roles: data.meta?.approval_roles ?? [],
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// ApprovalGate — one place for "this needs a supervisor" in hosts that mount an
|
|
2
|
+
// ApiProvider. It answers two situations with the same PIN dialog:
|
|
3
|
+
//
|
|
4
|
+
// 1. INLINE policy (POS oversell, discount over the cap, refund…): the client
|
|
5
|
+
// calls `requestApproval({policy, …})`. A user who already holds the policy's
|
|
6
|
+
// `general.approve_<policy>` capability passes straight through (`bypassed`);
|
|
7
|
+
// everyone else gets the dialog, which posts `/approvals/pin-grant`.
|
|
8
|
+
// 2. PARKED request: a write answered 422 `approval_required`. toastServerError
|
|
9
|
+
// shows "Enviado a aprobación" with an "Aprobar con PIN" action that opens the
|
|
10
|
+
// dialog against `/approvals/:id/approve-pin` (kernel approvals_pin.go).
|
|
11
|
+
//
|
|
12
|
+
// Federated addons with their own HTTP client use <ApprovalPinDialog> directly
|
|
13
|
+
// (approval-pin-dialog.tsx) and post to the same endpoints.
|
|
14
|
+
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'
|
|
15
|
+
import { useTranslation } from 'react-i18next'
|
|
16
|
+
import { toast } from 'sonner'
|
|
17
|
+
import { useApi } from './api-context'
|
|
18
|
+
import { useCan } from './permissions-context'
|
|
19
|
+
import { ApprovalPinDialog, type ApprovalPinSubmit } from './approval-pin-dialog'
|
|
20
|
+
import {
|
|
21
|
+
APPROVAL_DECIDED_EVENT,
|
|
22
|
+
APPROVAL_PARKED_EVENT,
|
|
23
|
+
gateMountedDelta,
|
|
24
|
+
type ApprovalRequiredInfo,
|
|
25
|
+
} from './approval-events'
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
APPROVAL_DECIDED_EVENT,
|
|
29
|
+
APPROVAL_PARKED_EVENT,
|
|
30
|
+
approvalGateAvailable,
|
|
31
|
+
approvalRequiredInfo,
|
|
32
|
+
type ApprovalRequiredInfo,
|
|
33
|
+
} from './approval-events'
|
|
34
|
+
|
|
35
|
+
/** Capability that authorizes `policy` (and lets its holder skip the prompt). */
|
|
36
|
+
export function approvalCapability(policy: string): string {
|
|
37
|
+
return `general.approve_${policy}`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ApprovalGrant {
|
|
41
|
+
/** Audit row id (ApprovalRequest.kind=pin); null when the caller bypassed. */
|
|
42
|
+
id: string | null
|
|
43
|
+
policy: string
|
|
44
|
+
bypassed: boolean
|
|
45
|
+
reason?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface RequestApprovalOptions {
|
|
49
|
+
/** Policy key: oversell | discount | price_below_min | refund | cancel_cfdi | inventory_adjust | <addon-declared>. */
|
|
50
|
+
policy: string
|
|
51
|
+
label: string
|
|
52
|
+
description?: React.ReactNode
|
|
53
|
+
/** Free-form audit data stored with the grant (product, qty, before → after…). */
|
|
54
|
+
context?: Record<string, unknown>
|
|
55
|
+
model?: string
|
|
56
|
+
recordId?: string
|
|
57
|
+
addonKey?: string
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ApprovalGateValue {
|
|
61
|
+
/** Resolves the grant, or null when the operator cancelled. */
|
|
62
|
+
requestApproval: (opts: RequestApprovalOptions) => Promise<ApprovalGrant | null>
|
|
63
|
+
/** True when the current user may do `policy` without asking anyone. */
|
|
64
|
+
canSelfApprove: (policy: string) => boolean
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const ApprovalGateContext = createContext<ApprovalGateValue | null>(null)
|
|
68
|
+
|
|
69
|
+
type Pending =
|
|
70
|
+
| { kind: 'inline'; opts: RequestApprovalOptions; resolve: (g: ApprovalGrant | null) => void }
|
|
71
|
+
| { kind: 'parked'; info: ApprovalRequiredInfo }
|
|
72
|
+
|
|
73
|
+
export function ApprovalGateProvider({ children }: { children: React.ReactNode }) {
|
|
74
|
+
const { t } = useTranslation()
|
|
75
|
+
const api = useApi()
|
|
76
|
+
const can = useCan()
|
|
77
|
+
const [pending, setPending] = useState<Pending | null>(null)
|
|
78
|
+
const pendingRef = useRef<Pending | null>(null)
|
|
79
|
+
pendingRef.current = pending
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
gateMountedDelta(1)
|
|
83
|
+
const onParked = (e: Event) => {
|
|
84
|
+
const info = (e as CustomEvent<ApprovalRequiredInfo>).detail
|
|
85
|
+
if (info?.requestId) setPending({ kind: 'parked', info })
|
|
86
|
+
}
|
|
87
|
+
window.addEventListener(APPROVAL_PARKED_EVENT, onParked)
|
|
88
|
+
return () => {
|
|
89
|
+
gateMountedDelta(-1)
|
|
90
|
+
window.removeEventListener(APPROVAL_PARKED_EVENT, onParked)
|
|
91
|
+
}
|
|
92
|
+
}, [])
|
|
93
|
+
|
|
94
|
+
const canSelfApprove = useCallback((policy: string) => can(approvalCapability(policy)), [can])
|
|
95
|
+
|
|
96
|
+
const requestApproval = useCallback(
|
|
97
|
+
(opts: RequestApprovalOptions) => {
|
|
98
|
+
if (can(approvalCapability(opts.policy))) {
|
|
99
|
+
return Promise.resolve<ApprovalGrant>({ id: null, policy: opts.policy, bypassed: true })
|
|
100
|
+
}
|
|
101
|
+
return new Promise<ApprovalGrant | null>((resolve) => {
|
|
102
|
+
pendingRef.current?.kind === 'inline' && pendingRef.current.resolve(null)
|
|
103
|
+
setPending({ kind: 'inline', opts, resolve })
|
|
104
|
+
})
|
|
105
|
+
},
|
|
106
|
+
[can],
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
const close = () => {
|
|
110
|
+
const p = pendingRef.current
|
|
111
|
+
if (p?.kind === 'inline') p.resolve(null)
|
|
112
|
+
setPending(null)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const submit = async ({ pin, reason }: ApprovalPinSubmit) => {
|
|
116
|
+
const p = pendingRef.current
|
|
117
|
+
if (!p) return
|
|
118
|
+
if (p.kind === 'inline') {
|
|
119
|
+
const res = await api.post('/approvals/pin-grant', {
|
|
120
|
+
policy: p.opts.policy,
|
|
121
|
+
label: p.opts.label,
|
|
122
|
+
pin,
|
|
123
|
+
reason,
|
|
124
|
+
context: p.opts.context,
|
|
125
|
+
model: p.opts.model,
|
|
126
|
+
record_id: p.opts.recordId,
|
|
127
|
+
addon_key: p.opts.addonKey,
|
|
128
|
+
})
|
|
129
|
+
const row = res.data?.data
|
|
130
|
+
p.resolve({ id: row?.id ?? null, policy: p.opts.policy, bypassed: false, reason })
|
|
131
|
+
} else {
|
|
132
|
+
await api.post(`/approvals/${p.info.requestId}/approve-pin`, { pin, reason })
|
|
133
|
+
toast.success(t('approvals.approved_applied', { defaultValue: 'Aprobado y aplicado' }))
|
|
134
|
+
window.dispatchEvent(new CustomEvent(APPROVAL_DECIDED_EVENT, { detail: p.info }))
|
|
135
|
+
}
|
|
136
|
+
setPending(null)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const value = useMemo<ApprovalGateValue>(() => ({ requestApproval, canSelfApprove }), [requestApproval, canSelfApprove])
|
|
140
|
+
|
|
141
|
+
const title =
|
|
142
|
+
pending?.kind === 'inline'
|
|
143
|
+
? pending.opts.label
|
|
144
|
+
: pending?.kind === 'parked'
|
|
145
|
+
? pending.info.label || t('approvals.parked_title', { defaultValue: 'Requiere aprobación' })
|
|
146
|
+
: ''
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<ApprovalGateContext.Provider value={value}>
|
|
150
|
+
{children}
|
|
151
|
+
<ApprovalPinDialog
|
|
152
|
+
open={pending !== null}
|
|
153
|
+
title={title}
|
|
154
|
+
description={pending?.kind === 'inline' ? pending.opts.description : undefined}
|
|
155
|
+
onSubmit={submit}
|
|
156
|
+
onCancel={close}
|
|
157
|
+
/>
|
|
158
|
+
</ApprovalGateContext.Provider>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Access the gate. Without a provider the gate fails CLOSED for inline requests
|
|
164
|
+
* (resolves null) — never silently authorizes — but honours the capability
|
|
165
|
+
* bypass, and `canSelfApprove` follows `useCan()` (always-true with no
|
|
166
|
+
* <PermissionsProvider>, i.e. legacy hosts keep today's behaviour).
|
|
167
|
+
*/
|
|
168
|
+
export function useApprovalGate(): ApprovalGateValue {
|
|
169
|
+
const ctx = useContext(ApprovalGateContext)
|
|
170
|
+
const can = useCan()
|
|
171
|
+
return useMemo<ApprovalGateValue>(
|
|
172
|
+
() =>
|
|
173
|
+
ctx ?? {
|
|
174
|
+
canSelfApprove: (policy) => can(approvalCapability(policy)),
|
|
175
|
+
requestApproval: async (opts) =>
|
|
176
|
+
can(approvalCapability(opts.policy)) ? { id: null, policy: opts.policy, bypassed: true } : null,
|
|
177
|
+
},
|
|
178
|
+
[ctx, can],
|
|
179
|
+
)
|
|
180
|
+
}
|