@datatechsolutions/ui 3.5.0 → 3.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.
Files changed (167) hide show
  1. package/dist/astrlabe/contracts.d.mts +517 -0
  2. package/dist/astrlabe/contracts.d.ts +517 -0
  3. package/dist/astrlabe/graph-node.d.mts +28 -0
  4. package/dist/astrlabe/graph-node.d.ts +28 -0
  5. package/dist/astrlabe/index.d.mts +743 -0
  6. package/dist/astrlabe/index.d.ts +743 -0
  7. package/dist/astrlabe/index.js +108 -108
  8. package/dist/astrlabe/index.mjs +4 -4
  9. package/dist/astrlabe/utils.d.mts +60 -0
  10. package/dist/astrlabe/utils.d.ts +60 -0
  11. package/dist/astrlabe/workflow-canvas.d.mts +6 -0
  12. package/dist/astrlabe/workflow-canvas.d.ts +6 -0
  13. package/dist/astrlabe/workflow-canvas.js +4 -4
  14. package/dist/astrlabe/workflow-canvas.mjs +3 -3
  15. package/dist/astrlabe/workflow-preview-canvas.d.mts +10 -0
  16. package/dist/astrlabe/workflow-preview-canvas.d.ts +10 -0
  17. package/dist/billing-panel-DsHhhJqG.d.mts +18 -0
  18. package/dist/billing-panel-DsHhhJqG.d.ts +18 -0
  19. package/dist/brand/index.d.mts +71 -0
  20. package/dist/brand/index.d.ts +71 -0
  21. package/dist/{chunk-AVM53A3Y.js → chunk-3WXMBAGN.js} +46 -44
  22. package/dist/chunk-3WXMBAGN.js.map +1 -0
  23. package/dist/{chunk-NOHHZ6FM.mjs → chunk-4OFG6POC.mjs} +10 -6
  24. package/dist/chunk-4OFG6POC.mjs.map +1 -0
  25. package/dist/{chunk-QLFSJ6HK.mjs → chunk-7LILNZMR.mjs} +3 -3
  26. package/dist/{chunk-QLFSJ6HK.mjs.map → chunk-7LILNZMR.mjs.map} +1 -1
  27. package/dist/{chunk-NKXQYFS7.js → chunk-AMYQSPQC.js} +16 -16
  28. package/dist/{chunk-NKXQYFS7.js.map → chunk-AMYQSPQC.js.map} +1 -1
  29. package/dist/{chunk-2MJAHST4.mjs → chunk-DYWSG42B.mjs} +4 -4
  30. package/dist/{chunk-2MJAHST4.mjs.map → chunk-DYWSG42B.mjs.map} +1 -1
  31. package/dist/{chunk-NJ5RVWLA.mjs → chunk-ESLKQJQS.mjs} +4 -4
  32. package/dist/{chunk-NJ5RVWLA.mjs.map → chunk-ESLKQJQS.mjs.map} +1 -1
  33. package/dist/{chunk-AWDH6WNA.js → chunk-GCYYGSHU.js} +10 -6
  34. package/dist/chunk-GCYYGSHU.js.map +1 -0
  35. package/dist/{chunk-UHMAKUON.mjs → chunk-HGWVJ3VB.mjs} +21 -21
  36. package/dist/{chunk-UHMAKUON.mjs.map → chunk-HGWVJ3VB.mjs.map} +1 -1
  37. package/dist/{chunk-4PFU6A2B.mjs → chunk-I63NFWIA.mjs} +3 -3
  38. package/dist/{chunk-4PFU6A2B.mjs.map → chunk-I63NFWIA.mjs.map} +1 -1
  39. package/dist/{chunk-QPSHM2JQ.mjs → chunk-IHHGT3LP.mjs} +19 -19
  40. package/dist/{chunk-QPSHM2JQ.mjs.map → chunk-IHHGT3LP.mjs.map} +1 -1
  41. package/dist/{chunk-6W7VTZG6.mjs → chunk-JQYDJ75Q.mjs} +3 -3
  42. package/dist/{chunk-6W7VTZG6.mjs.map → chunk-JQYDJ75Q.mjs.map} +1 -1
  43. package/dist/{chunk-V5VBYOF5.js → chunk-LVK7VXW7.js} +54 -54
  44. package/dist/{chunk-V5VBYOF5.js.map → chunk-LVK7VXW7.js.map} +1 -1
  45. package/dist/{chunk-7CEZB3ZD.mjs → chunk-MRRFDIUQ.mjs} +3 -3
  46. package/dist/{chunk-7CEZB3ZD.mjs.map → chunk-MRRFDIUQ.mjs.map} +1 -1
  47. package/dist/{chunk-A7FI4K7Z.js → chunk-NJZIE4EH.js} +5 -5
  48. package/dist/{chunk-A7FI4K7Z.js.map → chunk-NJZIE4EH.js.map} +1 -1
  49. package/dist/{chunk-P43PX75J.js → chunk-P5F257N3.js} +33 -33
  50. package/dist/{chunk-P43PX75J.js.map → chunk-P5F257N3.js.map} +1 -1
  51. package/dist/{chunk-BVXATTTA.js → chunk-QHP2MR2F.js} +4 -4
  52. package/dist/{chunk-BVXATTTA.js.map → chunk-QHP2MR2F.js.map} +1 -1
  53. package/dist/{chunk-CY2MBKVG.js → chunk-QRNFTG6A.js} +4 -4
  54. package/dist/{chunk-CY2MBKVG.js.map → chunk-QRNFTG6A.js.map} +1 -1
  55. package/dist/{chunk-OASC7NYV.mjs → chunk-QTA5I6FC.mjs} +3 -3
  56. package/dist/{chunk-OASC7NYV.mjs.map → chunk-QTA5I6FC.mjs.map} +1 -1
  57. package/dist/{chunk-QSMPKL27.js → chunk-S7AV6XEY.js} +74 -74
  58. package/dist/{chunk-QSMPKL27.js.map → chunk-S7AV6XEY.js.map} +1 -1
  59. package/dist/{chunk-VMGNQFRO.js → chunk-UGJZ3M4Q.js} +53 -53
  60. package/dist/{chunk-VMGNQFRO.js.map → chunk-UGJZ3M4Q.js.map} +1 -1
  61. package/dist/{chunk-5BEVTOZV.mjs → chunk-UOABOFKO.mjs} +4 -4
  62. package/dist/{chunk-5BEVTOZV.mjs.map → chunk-UOABOFKO.mjs.map} +1 -1
  63. package/dist/{chunk-74MHWEDC.js → chunk-UWSMHKOF.js} +161 -161
  64. package/dist/{chunk-74MHWEDC.js.map → chunk-UWSMHKOF.js.map} +1 -1
  65. package/dist/{chunk-ZM2Q2SMC.mjs → chunk-VDLAZR7S.mjs} +3 -3
  66. package/dist/{chunk-ZM2Q2SMC.mjs.map → chunk-VDLAZR7S.mjs.map} +1 -1
  67. package/dist/{chunk-FK3WDELF.js → chunk-VPOIX2DY.js} +40 -40
  68. package/dist/{chunk-FK3WDELF.js.map → chunk-VPOIX2DY.js.map} +1 -1
  69. package/dist/{chunk-IOEQ2GET.mjs → chunk-VUAGVZJM.mjs} +4 -4
  70. package/dist/{chunk-IOEQ2GET.mjs.map → chunk-VUAGVZJM.mjs.map} +1 -1
  71. package/dist/{chunk-Z7VY5M4T.js → chunk-W5YCZOXO.js} +77 -77
  72. package/dist/{chunk-Z7VY5M4T.js.map → chunk-W5YCZOXO.js.map} +1 -1
  73. package/dist/{chunk-C4NRF2G2.js → chunk-WBEZATIB.js} +13 -13
  74. package/dist/{chunk-C4NRF2G2.js.map → chunk-WBEZATIB.js.map} +1 -1
  75. package/dist/{chunk-6V3DUBOZ.mjs → chunk-WEZ722BS.mjs} +7 -7
  76. package/dist/{chunk-6V3DUBOZ.mjs.map → chunk-WEZ722BS.mjs.map} +1 -1
  77. package/dist/{chunk-3OLYSMI5.mjs → chunk-XTXLRQ3H.mjs} +24 -22
  78. package/dist/chunk-XTXLRQ3H.mjs.map +1 -0
  79. package/dist/{chunk-5I7F7KZ6.js → chunk-YOJIPZ72.js} +10 -10
  80. package/dist/{chunk-5I7F7KZ6.js.map → chunk-YOJIPZ72.js.map} +1 -1
  81. package/dist/{chunk-NCDBNGIB.js → chunk-YTE6WCBX.js} +76 -76
  82. package/dist/{chunk-NCDBNGIB.js.map → chunk-YTE6WCBX.js.map} +1 -1
  83. package/dist/{chunk-7UHV6A4C.mjs → chunk-ZYVDDSAC.mjs} +6 -6
  84. package/dist/{chunk-7UHV6A4C.mjs.map → chunk-ZYVDDSAC.mjs.map} +1 -1
  85. package/dist/dynamic-island-confirm-BKsZkAEP.d.mts +17 -0
  86. package/dist/dynamic-island-confirm-BKsZkAEP.d.ts +17 -0
  87. package/dist/index-BNRGVAS5.d.mts +222 -0
  88. package/dist/index-BoebbJ44.d.mts +49 -0
  89. package/dist/index-BoebbJ44.d.ts +49 -0
  90. package/dist/index-CnCY-b5V.d.ts +222 -0
  91. package/dist/index.d.mts +5310 -0
  92. package/dist/index.d.ts +5310 -0
  93. package/dist/index.js +721 -721
  94. package/dist/index.mjs +2 -2
  95. package/dist/layout-engine-YZcVr20M.d.mts +19 -0
  96. package/dist/layout-engine-YZcVr20M.d.ts +19 -0
  97. package/dist/lib/i18n-context.d.mts +36 -0
  98. package/dist/lib/i18n-context.d.ts +36 -0
  99. package/dist/lib/router-context.d.mts +35 -0
  100. package/dist/lib/router-context.d.ts +35 -0
  101. package/dist/navigation-BiWVffAN.d.mts +49 -0
  102. package/dist/navigation-BiWVffAN.d.ts +49 -0
  103. package/dist/platform/admin/index.d.mts +17 -0
  104. package/dist/platform/admin/index.d.ts +17 -0
  105. package/dist/platform/admin/index.js +11 -11
  106. package/dist/platform/admin/index.mjs +5 -5
  107. package/dist/platform/agents-workspace.d.mts +19 -0
  108. package/dist/platform/agents-workspace.d.ts +19 -0
  109. package/dist/platform/agents-workspace.js +7 -7
  110. package/dist/platform/agents-workspace.mjs +6 -6
  111. package/dist/platform/app-shell.d.mts +58 -0
  112. package/dist/platform/app-shell.d.ts +58 -0
  113. package/dist/platform/app-shell.js +4 -4
  114. package/dist/platform/app-shell.mjs +3 -3
  115. package/dist/platform/auth/index.d.mts +73 -0
  116. package/dist/platform/auth/index.d.ts +73 -0
  117. package/dist/platform/auth/index.js +28 -28
  118. package/dist/platform/auth/index.mjs +5 -5
  119. package/dist/platform/billing/index.d.mts +29 -0
  120. package/dist/platform/billing/index.d.ts +29 -0
  121. package/dist/platform/billing/index.js +4 -4
  122. package/dist/platform/billing/index.mjs +3 -3
  123. package/dist/platform/impersonation/index.d.mts +19 -0
  124. package/dist/platform/impersonation/index.d.ts +19 -0
  125. package/dist/platform/impersonation/index.js +4 -4
  126. package/dist/platform/impersonation/index.mjs +3 -3
  127. package/dist/platform/index.d.mts +188 -0
  128. package/dist/platform/index.d.ts +188 -0
  129. package/dist/platform/index.js +89 -89
  130. package/dist/platform/index.mjs +19 -19
  131. package/dist/platform/pages/index.d.mts +441 -0
  132. package/dist/platform/pages/index.d.ts +441 -0
  133. package/dist/platform/pages/index.js +326 -302
  134. package/dist/platform/pages/index.js.map +1 -1
  135. package/dist/platform/pages/index.mjs +148 -124
  136. package/dist/platform/pages/index.mjs.map +1 -1
  137. package/dist/platform/rbac.d.mts +42 -0
  138. package/dist/platform/rbac.d.ts +42 -0
  139. package/dist/platform/settings/index.d.mts +31 -0
  140. package/dist/platform/settings/index.d.ts +31 -0
  141. package/dist/platform/settings/index.js +8 -8
  142. package/dist/platform/settings/index.mjs +7 -7
  143. package/dist/platform/telemetry/index.d.mts +51 -0
  144. package/dist/platform/telemetry/index.d.ts +51 -0
  145. package/dist/platform/utils/index.d.mts +32 -0
  146. package/dist/platform/utils/index.d.ts +32 -0
  147. package/dist/platform/windsock-admin-client.d.mts +57 -0
  148. package/dist/platform/windsock-admin-client.d.ts +57 -0
  149. package/dist/platform/workflow-api-client.d.mts +6 -0
  150. package/dist/platform/workflow-api-client.d.ts +6 -0
  151. package/dist/platform/workflow-canvas-shell.d.mts +18 -0
  152. package/dist/platform/workflow-canvas-shell.d.ts +18 -0
  153. package/dist/platform/workflow-canvas-shell.js +5 -5
  154. package/dist/platform/workflow-canvas-shell.mjs +4 -4
  155. package/dist/rule-form-BYJzyork.d.mts +128 -0
  156. package/dist/rule-form-BYJzyork.d.ts +128 -0
  157. package/dist/workflow-api-client-CpFl3WcG.d.mts +468 -0
  158. package/dist/workflow-api-client-uLICOanv.d.ts +468 -0
  159. package/dist/workflow-canvas--qaYKuMm.d.ts +113 -0
  160. package/dist/workflow-canvas-B80fmD_n.d.mts +113 -0
  161. package/dist/workflow-store-o17I6L6A.d.ts +79 -0
  162. package/dist/workflow-store-ppVHdMZi.d.mts +79 -0
  163. package/package.json +1 -1
  164. package/dist/chunk-3OLYSMI5.mjs.map +0 -1
  165. package/dist/chunk-AVM53A3Y.js.map +0 -1
  166. package/dist/chunk-AWDH6WNA.js.map +0 -1
  167. package/dist/chunk-NOHHZ6FM.mjs.map +0 -1
@@ -0,0 +1,60 @@
1
+ import { WorkflowNodeType, LogicNodeConfig, WorkflowNode, WorkflowEdge, WorkflowGraph } from './contracts.js';
2
+ export { L as LayoutDirection, a as applyDagreLayout } from '../layout-engine-YZcVr20M.js';
3
+ import '@xyflow/react';
4
+
5
+ /**
6
+ * Logic Node Default Configs
7
+ * ==========================
8
+ * Factory function to create default configs for each logic node type.
9
+ */
10
+
11
+ declare function createDefaultLogicNodeConfig(nodeType: WorkflowNodeType): LogicNodeConfig | null;
12
+
13
+ /**
14
+ * Workflow Validator
15
+ * =================
16
+ * Localizes validation output inside the UI package while keeping issue codes
17
+ * stable enough for future contract tests against the backend validator.
18
+ */
19
+
20
+ type SupportedLocale = 'en' | 'pt-BR' | 'es' | 'fr' | 'de' | 'it';
21
+ type ValidationParams = Record<string, string | number | undefined>;
22
+ type ValidationLocale = SupportedLocale | string;
23
+ type ValidationIssueCode = 'graph.noAgents' | 'graph.missingSource' | 'graph.missingTarget' | 'graph.orphanNode' | 'graph.toolToNonAgent' | 'graph.ruleNoAgent' | 'graph.cycleDetected' | 'graph.multipleStartNodes' | 'graph.multipleEndNodes' | 'graph.startHasIncoming' | 'graph.endHasOutgoing' | 'graph.iterationNoOutgoing' | 'node.required' | 'node.requiredWhenLanguageSet' | 'node.codeShapeRequired' | 'node.mustBeArray' | 'node.mustBeReferenceArray' | 'node.mustBeNonEmptyReferenceArray' | 'node.assignmentNeedsSourceOrValue' | 'node.invalidAggregationMode' | 'node.invalidListOperation' | 'node.invalidLogicalOperator' | 'node.mustBeNumber' | 'node.invalidHttpMethod' | 'node.providerIdentityRequired' | 'node.inputOrInstructionsRequired' | 'node.invalidExtractionMode' | 'node.s3WriteSourceOrBodyRequired' | 'node.unknownType';
24
+ type ValidationIssue = {
25
+ code: ValidationIssueCode;
26
+ message: string;
27
+ params?: ValidationParams;
28
+ };
29
+ type NodeValidationIssue = ValidationIssue & {
30
+ nodeId: string;
31
+ nodeType: string;
32
+ field?: string;
33
+ };
34
+ type ValidationResult = {
35
+ valid: boolean;
36
+ errors: string[];
37
+ issues: ValidationIssue[];
38
+ nodeIssues: NodeValidationIssue[];
39
+ };
40
+ type ValidationOptions = {
41
+ locale?: ValidationLocale;
42
+ };
43
+ declare function validateNodeConfig(node: WorkflowNode, options?: ValidationOptions): NodeValidationIssue[];
44
+ declare function validateGraphNodeConfigs(graph: WorkflowGraph, options?: ValidationOptions): NodeValidationIssue[];
45
+ declare function validateWorkflowGraph(graph: WorkflowGraph, options?: ValidationOptions): ValidationResult;
46
+ declare function topologicalSortAgents(agentNodes: WorkflowNode[], edges: WorkflowEdge[], nodeMap: Map<string, WorkflowNode>): WorkflowNode[];
47
+
48
+ /**
49
+ * Agent ELO Tier
50
+ * ==============
51
+ * Derives difficulty tier from agent ELO rating.
52
+ * Used in node palette, agent flow node, and agent modal.
53
+ */
54
+ type AgentTier = {
55
+ key: 'beginner' | 'intermediate' | 'advanced' | 'expert';
56
+ pillColor: string;
57
+ };
58
+ declare function getAgentTier(elo: number | undefined): AgentTier;
59
+
60
+ export { type AgentTier, type NodeValidationIssue, type ValidationResult, createDefaultLogicNodeConfig, getAgentTier, topologicalSortAgents, validateGraphNodeConfigs, validateNodeConfig, validateWorkflowGraph };
@@ -0,0 +1,6 @@
1
+ import 'react/jsx-runtime';
2
+ import 'react';
3
+ export { a as Workspace, W as WorkspaceProps } from '../workflow-canvas-B80fmD_n.mjs';
4
+ import './contracts.mjs';
5
+ import '../index-BNRGVAS5.mjs';
6
+ import '@xyflow/react';
@@ -0,0 +1,6 @@
1
+ import 'react/jsx-runtime';
2
+ import 'react';
3
+ export { a as Workspace, W as WorkspaceProps } from '../workflow-canvas--qaYKuMm.js';
4
+ import './contracts.js';
5
+ import '../index-CnCY-b5V.js';
6
+ import '@xyflow/react';
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkQSMPKL27_js = require('../chunk-QSMPKL27.js');
5
- require('../chunk-AWDH6WNA.js');
4
+ var chunkS7AV6XEY_js = require('../chunk-S7AV6XEY.js');
5
+ require('../chunk-GCYYGSHU.js');
6
6
  require('../chunk-UZ3CMNUJ.js');
7
+ require('../chunk-YXN2K77G.js');
7
8
  require('../chunk-S7KHTUHA.js');
8
9
  require('../chunk-SY4MUT5V.js');
9
10
  require('../chunk-2OZZH2IO.js');
10
- require('../chunk-YXN2K77G.js');
11
11
  require('../chunk-P4YYEM4B.js');
12
12
  require('../chunk-72SWXOD5.js');
13
13
 
@@ -15,7 +15,7 @@ require('../chunk-72SWXOD5.js');
15
15
 
16
16
  Object.defineProperty(exports, "Workspace", {
17
17
  enumerable: true,
18
- get: function () { return chunkQSMPKL27_js.Workspace; }
18
+ get: function () { return chunkS7AV6XEY_js.Workspace; }
19
19
  });
20
20
  //# sourceMappingURL=workflow-canvas.js.map
21
21
  //# sourceMappingURL=workflow-canvas.js.map
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- export { Workspace } from '../chunk-OASC7NYV.mjs';
3
- import '../chunk-NOHHZ6FM.mjs';
2
+ export { Workspace } from '../chunk-QTA5I6FC.mjs';
3
+ import '../chunk-4OFG6POC.mjs';
4
4
  import '../chunk-D2JF6C3E.mjs';
5
+ import '../chunk-7VJ7CMMT.mjs';
5
6
  import '../chunk-QWG2FMUN.mjs';
6
7
  import '../chunk-RHRJXK5R.mjs';
7
8
  import '../chunk-3AY5HIQ6.mjs';
8
- import '../chunk-7VJ7CMMT.mjs';
9
9
  import '../chunk-OZNTQROP.mjs';
10
10
  import '../chunk-G7JQ4OCE.mjs';
11
11
  //# sourceMappingURL=workflow-canvas.mjs.map
@@ -0,0 +1,10 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { WorkflowGraph } from './contracts.mjs';
3
+
4
+ type WorkflowPreviewCanvasProps = {
5
+ graph: WorkflowGraph;
6
+ className?: string;
7
+ };
8
+ declare function WorkflowPreviewCanvas({ graph, className }: WorkflowPreviewCanvasProps): react_jsx_runtime.JSX.Element;
9
+
10
+ export { WorkflowPreviewCanvas, type WorkflowPreviewCanvasProps };
@@ -0,0 +1,10 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { WorkflowGraph } from './contracts.js';
3
+
4
+ type WorkflowPreviewCanvasProps = {
5
+ graph: WorkflowGraph;
6
+ className?: string;
7
+ };
8
+ declare function WorkflowPreviewCanvas({ graph, className }: WorkflowPreviewCanvasProps): react_jsx_runtime.JSX.Element;
9
+
10
+ export { WorkflowPreviewCanvas, type WorkflowPreviewCanvasProps };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface BillingPanelProps {
4
+ /**
5
+ * Which billing interval to prefer when starting checkout. Defaults to
6
+ * `'monthly'`. Surface a toggle in the host app if both matter.
7
+ */
8
+ defaultBillingInterval?: 'monthly' | 'yearly';
9
+ /**
10
+ * Called after the portal/checkout URL is resolved. Defaults to
11
+ * `window.location.assign(url)`. Override to open in a new tab, use a
12
+ * router, etc.
13
+ */
14
+ onRedirect?: (url: string) => void;
15
+ }
16
+ declare function BillingPanel({ defaultBillingInterval, onRedirect, }: BillingPanelProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { BillingPanel as B, type BillingPanelProps as a };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface BillingPanelProps {
4
+ /**
5
+ * Which billing interval to prefer when starting checkout. Defaults to
6
+ * `'monthly'`. Surface a toggle in the host app if both matter.
7
+ */
8
+ defaultBillingInterval?: 'monthly' | 'yearly';
9
+ /**
10
+ * Called after the portal/checkout URL is resolved. Defaults to
11
+ * `window.location.assign(url)`. Override to open in a new tab, use a
12
+ * router, etc.
13
+ */
14
+ onRedirect?: (url: string) => void;
15
+ }
16
+ declare function BillingPanel({ defaultBillingInterval, onRedirect, }: BillingPanelProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { BillingPanel as B, type BillingPanelProps as a };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Brand — centralized app themes, icons, and logos
3
+ * =================================================
4
+ * Single source of truth for all app branding across the platform.
5
+ *
6
+ * Logo SVGs live in src/brand/logos/ and are published as-is.
7
+ * Vite apps can import them directly:
8
+ * import astrlabeIcon from '@datatechsolutions/ui/src/brand/logos/astrlabe-icon.svg'
9
+ * Or use the APP_LOGOS/APP_THEMES which re-export them (works in Vite).
10
+ */
11
+ interface AppTheme {
12
+ text: string;
13
+ textLight: string;
14
+ badgeBg: string;
15
+ badgeText: string;
16
+ ring: string;
17
+ border: string;
18
+ borderGlow: string;
19
+ surfaceBg: string;
20
+ dot: string;
21
+ tileGradient: string;
22
+ tileShadow: string;
23
+ gradient: string;
24
+ }
25
+ declare const APP_THEMES: {
26
+ readonly astrlabe: {
27
+ readonly text: "text-violet-400";
28
+ readonly textLight: "text-violet-300";
29
+ readonly badgeBg: "bg-violet-500/10";
30
+ readonly badgeText: "text-violet-300";
31
+ readonly ring: "ring-violet-500/30";
32
+ readonly border: "border-violet-500/30";
33
+ readonly borderGlow: "border-violet-500/20";
34
+ readonly surfaceBg: "bg-violet-500/[0.06]";
35
+ readonly dot: "bg-violet-400";
36
+ readonly tileGradient: "from-violet-600/80 to-purple-600/80";
37
+ readonly tileShadow: "shadow-violet-500/20";
38
+ readonly gradient: "from-violet-400 to-purple-400";
39
+ };
40
+ readonly windsock: {
41
+ readonly text: "text-emerald-400";
42
+ readonly textLight: "text-emerald-300";
43
+ readonly badgeBg: "bg-emerald-500/10";
44
+ readonly badgeText: "text-emerald-300";
45
+ readonly ring: "ring-emerald-500/30";
46
+ readonly border: "border-emerald-500/30";
47
+ readonly borderGlow: "border-emerald-500/20";
48
+ readonly surfaceBg: "bg-emerald-500/[0.06]";
49
+ readonly dot: "bg-emerald-400";
50
+ readonly tileGradient: "from-emerald-600/80 to-teal-600/80";
51
+ readonly tileShadow: "shadow-emerald-500/20";
52
+ readonly gradient: "from-emerald-400 to-teal-400";
53
+ };
54
+ readonly fakhir: {
55
+ readonly text: "text-red-400";
56
+ readonly textLight: "text-red-300";
57
+ readonly badgeBg: "bg-red-500/10";
58
+ readonly badgeText: "text-red-300";
59
+ readonly ring: "ring-red-500/30";
60
+ readonly border: "border-red-500/30";
61
+ readonly borderGlow: "border-red-500/20";
62
+ readonly surfaceBg: "bg-red-500/[0.06]";
63
+ readonly dot: "bg-red-400";
64
+ readonly tileGradient: "from-red-600/80 to-rose-600/80";
65
+ readonly tileShadow: "shadow-red-500/20";
66
+ readonly gradient: "from-red-400 to-rose-400";
67
+ };
68
+ };
69
+ type AppId = keyof typeof APP_THEMES;
70
+
71
+ export { APP_THEMES, type AppId, type AppTheme };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Brand — centralized app themes, icons, and logos
3
+ * =================================================
4
+ * Single source of truth for all app branding across the platform.
5
+ *
6
+ * Logo SVGs live in src/brand/logos/ and are published as-is.
7
+ * Vite apps can import them directly:
8
+ * import astrlabeIcon from '@datatechsolutions/ui/src/brand/logos/astrlabe-icon.svg'
9
+ * Or use the APP_LOGOS/APP_THEMES which re-export them (works in Vite).
10
+ */
11
+ interface AppTheme {
12
+ text: string;
13
+ textLight: string;
14
+ badgeBg: string;
15
+ badgeText: string;
16
+ ring: string;
17
+ border: string;
18
+ borderGlow: string;
19
+ surfaceBg: string;
20
+ dot: string;
21
+ tileGradient: string;
22
+ tileShadow: string;
23
+ gradient: string;
24
+ }
25
+ declare const APP_THEMES: {
26
+ readonly astrlabe: {
27
+ readonly text: "text-violet-400";
28
+ readonly textLight: "text-violet-300";
29
+ readonly badgeBg: "bg-violet-500/10";
30
+ readonly badgeText: "text-violet-300";
31
+ readonly ring: "ring-violet-500/30";
32
+ readonly border: "border-violet-500/30";
33
+ readonly borderGlow: "border-violet-500/20";
34
+ readonly surfaceBg: "bg-violet-500/[0.06]";
35
+ readonly dot: "bg-violet-400";
36
+ readonly tileGradient: "from-violet-600/80 to-purple-600/80";
37
+ readonly tileShadow: "shadow-violet-500/20";
38
+ readonly gradient: "from-violet-400 to-purple-400";
39
+ };
40
+ readonly windsock: {
41
+ readonly text: "text-emerald-400";
42
+ readonly textLight: "text-emerald-300";
43
+ readonly badgeBg: "bg-emerald-500/10";
44
+ readonly badgeText: "text-emerald-300";
45
+ readonly ring: "ring-emerald-500/30";
46
+ readonly border: "border-emerald-500/30";
47
+ readonly borderGlow: "border-emerald-500/20";
48
+ readonly surfaceBg: "bg-emerald-500/[0.06]";
49
+ readonly dot: "bg-emerald-400";
50
+ readonly tileGradient: "from-emerald-600/80 to-teal-600/80";
51
+ readonly tileShadow: "shadow-emerald-500/20";
52
+ readonly gradient: "from-emerald-400 to-teal-400";
53
+ };
54
+ readonly fakhir: {
55
+ readonly text: "text-red-400";
56
+ readonly textLight: "text-red-300";
57
+ readonly badgeBg: "bg-red-500/10";
58
+ readonly badgeText: "text-red-300";
59
+ readonly ring: "ring-red-500/30";
60
+ readonly border: "border-red-500/30";
61
+ readonly borderGlow: "border-red-500/20";
62
+ readonly surfaceBg: "bg-red-500/[0.06]";
63
+ readonly dot: "bg-red-400";
64
+ readonly tileGradient: "from-red-600/80 to-rose-600/80";
65
+ readonly tileShadow: "shadow-red-500/20";
66
+ readonly gradient: "from-red-400 to-rose-400";
67
+ };
68
+ };
69
+ type AppId = keyof typeof APP_THEMES;
70
+
71
+ export { APP_THEMES, type AppId, type AppTheme };
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkQSMPKL27_js = require('./chunk-QSMPKL27.js');
5
- var chunkAWDH6WNA_js = require('./chunk-AWDH6WNA.js');
4
+ var chunkS7AV6XEY_js = require('./chunk-S7AV6XEY.js');
5
+ var chunkGCYYGSHU_js = require('./chunk-GCYYGSHU.js');
6
6
  var chunkYXN2K77G_js = require('./chunk-YXN2K77G.js');
7
7
  var react = require('react');
8
8
  var outline = require('@heroicons/react/24/outline');
@@ -26,15 +26,24 @@ function UsersPageView({ labels, users, onCreateUser, onUpdateRole }) {
26
26
  const labelsAny = labels;
27
27
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
28
28
  /* @__PURE__ */ jsxRuntime.jsx(
29
- chunkAWDH6WNA_js.HeroSection,
29
+ chunkGCYYGSHU_js.HeroSection,
30
30
  {
31
31
  icon: /* @__PURE__ */ jsxRuntime.jsx(outline.UserGroupIcon, { className: "h-5 w-5" }),
32
32
  label: labels.title,
33
33
  title: labels.title,
34
34
  subtitle: labels.subtitle,
35
35
  gradient: "from-violet-500 to-indigo-600",
36
- toolbar: /* @__PURE__ */ jsxRuntime.jsx(
37
- chunkAWDH6WNA_js.CreateActionButton,
36
+ toolbar: !isEmpty ? /* @__PURE__ */ jsxRuntime.jsx(
37
+ chunkGCYYGSHU_js.SearchBar,
38
+ {
39
+ searchTerm,
40
+ onSearchChange: setSearchTerm,
41
+ placeholder: labelsAny.searchPlaceholder ?? labels.title,
42
+ noBorder: true
43
+ }
44
+ ) : void 0,
45
+ actions: /* @__PURE__ */ jsxRuntime.jsx(
46
+ chunkGCYYGSHU_js.CreateActionButton,
38
47
  {
39
48
  mode: "desktop",
40
49
  label: labels.create,
@@ -45,7 +54,7 @@ function UsersPageView({ labels, users, onCreateUser, onUpdateRole }) {
45
54
  }
46
55
  ),
47
56
  /* @__PURE__ */ jsxRuntime.jsx(
48
- chunkAWDH6WNA_js.CreateActionButton,
57
+ chunkGCYYGSHU_js.CreateActionButton,
49
58
  {
50
59
  mode: "mobile",
51
60
  label: labels.create,
@@ -53,18 +62,10 @@ function UsersPageView({ labels, users, onCreateUser, onUpdateRole }) {
53
62
  accent: "violet"
54
63
  }
55
64
  ),
56
- !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(
57
- chunkAWDH6WNA_js.SearchBar,
58
- {
59
- searchTerm,
60
- onSearchChange: setSearchTerm,
61
- placeholder: labelsAny.searchPlaceholder ?? labels.title
62
- }
63
- ),
64
65
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
65
66
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: labels.list }),
66
67
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filteredUsers.map((user) => /* @__PURE__ */ jsxRuntime.jsx(
67
- chunkAWDH6WNA_js.EntityCard,
68
+ chunkGCYYGSHU_js.EntityCard,
68
69
  {
69
70
  accentGradient: "from-violet-500 to-indigo-700",
70
71
  icon: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-lg bg-violet-500/10 text-violet-600 dark:bg-violet-500/20 dark:text-violet-400", children: /* @__PURE__ */ jsxRuntime.jsx(outline.UserGroupIcon, { className: "h-6 w-6" }) }),
@@ -86,9 +87,9 @@ function UsersPageView({ labels, users, onCreateUser, onUpdateRole }) {
86
87
  const role = String(formData.get("role") ?? "viewer");
87
88
  onUpdateRole({ email: user.email, role });
88
89
  },
89
- children: /* @__PURE__ */ jsxRuntime.jsxs(chunkAWDH6WNA_js.InlineForm, { children: [
90
- /* @__PURE__ */ jsxRuntime.jsx(chunkAWDH6WNA_js.FormSelect, { name: "role", options: ROLE_OPTIONS, defaultValue: user.role }),
91
- /* @__PURE__ */ jsxRuntime.jsx(chunkAWDH6WNA_js.Button, { type: "submit", outline: true, size: "sm", children: labels.save })
90
+ children: /* @__PURE__ */ jsxRuntime.jsxs(chunkGCYYGSHU_js.InlineForm, { children: [
91
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGCYYGSHU_js.FormSelect, { name: "role", options: ROLE_OPTIONS, defaultValue: user.role }),
92
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGCYYGSHU_js.Button, { type: "submit", outline: true, size: "sm", children: labels.save })
92
93
  ] })
93
94
  }
94
95
  )
@@ -97,7 +98,7 @@ function UsersPageView({ labels, users, onCreateUser, onUpdateRole }) {
97
98
  )) })
98
99
  ] }),
99
100
  /* @__PURE__ */ jsxRuntime.jsx(
100
- chunkAWDH6WNA_js.GlassModal,
101
+ chunkGCYYGSHU_js.GlassModal,
101
102
  {
102
103
  open: createOpen,
103
104
  onClose: () => setCreateOpen(false),
@@ -115,10 +116,10 @@ function UsersPageView({ labels, users, onCreateUser, onUpdateRole }) {
115
116
  onCreateUser({ name, email, role });
116
117
  setCreateOpen(false);
117
118
  },
118
- children: /* @__PURE__ */ jsxRuntime.jsxs(chunkAWDH6WNA_js.FormGrid, { children: [
119
- /* @__PURE__ */ jsxRuntime.jsx(chunkAWDH6WNA_js.FormInput, { name: "name", label: labels.name, placeholder: labels.userNamePlaceholder, required: true }),
120
- /* @__PURE__ */ jsxRuntime.jsx(chunkAWDH6WNA_js.FormInput, { name: "email", label: labels.email, placeholder: labels.userEmailPlaceholder, required: true, type: "email" }),
121
- /* @__PURE__ */ jsxRuntime.jsx(chunkAWDH6WNA_js.FormSelect, { name: "role", label: labels.role, options: ROLE_OPTIONS })
119
+ children: /* @__PURE__ */ jsxRuntime.jsxs(chunkGCYYGSHU_js.FormGrid, { children: [
120
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGCYYGSHU_js.FormInput, { name: "name", label: labels.name, placeholder: labels.userNamePlaceholder, required: true }),
121
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGCYYGSHU_js.FormInput, { name: "email", label: labels.email, placeholder: labels.userEmailPlaceholder, required: true, type: "email" }),
122
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGCYYGSHU_js.FormSelect, { name: "role", label: labels.role, options: ROLE_OPTIONS })
122
123
  ] })
123
124
  }
124
125
  )
@@ -144,15 +145,24 @@ function RolesPageView({
144
145
  const labelsAny = labels;
145
146
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
146
147
  /* @__PURE__ */ jsxRuntime.jsx(
147
- chunkAWDH6WNA_js.HeroSection,
148
+ chunkGCYYGSHU_js.HeroSection,
148
149
  {
149
150
  icon: /* @__PURE__ */ jsxRuntime.jsx(outline.ShieldCheckIcon, { className: "h-5 w-5" }),
150
151
  label: labels.title,
151
152
  title: labels.title,
152
153
  subtitle: labels.subtitle,
153
154
  gradient: "from-emerald-500 to-teal-600",
154
- toolbar: /* @__PURE__ */ jsxRuntime.jsx(
155
- chunkAWDH6WNA_js.CreateActionButton,
155
+ toolbar: !isEmpty ? /* @__PURE__ */ jsxRuntime.jsx(
156
+ chunkGCYYGSHU_js.SearchBar,
157
+ {
158
+ searchTerm,
159
+ onSearchChange: setSearchTerm,
160
+ placeholder: labelsAny.searchPlaceholder ?? labels.title,
161
+ noBorder: true
162
+ }
163
+ ) : void 0,
164
+ actions: /* @__PURE__ */ jsxRuntime.jsx(
165
+ chunkGCYYGSHU_js.CreateActionButton,
156
166
  {
157
167
  mode: "desktop",
158
168
  label: labels.assign,
@@ -163,7 +173,7 @@ function RolesPageView({
163
173
  }
164
174
  ),
165
175
  /* @__PURE__ */ jsxRuntime.jsx(
166
- chunkAWDH6WNA_js.CreateActionButton,
176
+ chunkGCYYGSHU_js.CreateActionButton,
167
177
  {
168
178
  mode: "mobile",
169
179
  label: labels.assign,
@@ -171,18 +181,10 @@ function RolesPageView({
171
181
  accent: "emerald"
172
182
  }
173
183
  ),
174
- !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(
175
- chunkAWDH6WNA_js.SearchBar,
176
- {
177
- searchTerm,
178
- onSearchChange: setSearchTerm,
179
- placeholder: labelsAny.searchPlaceholder ?? labels.title
180
- }
181
- ),
182
184
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
183
185
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: labels.definitions }),
184
186
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", children: filteredRoleDefinitions.map((role) => /* @__PURE__ */ jsxRuntime.jsxs(
185
- chunkAWDH6WNA_js.EntityCard,
187
+ chunkGCYYGSHU_js.EntityCard,
186
188
  {
187
189
  accentGradient: "from-emerald-500 to-teal-700",
188
190
  icon: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-lg bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400", children: /* @__PURE__ */ jsxRuntime.jsx(outline.ShieldCheckIcon, { className: "h-6 w-6" }) }),
@@ -199,7 +201,7 @@ function RolesPageView({
199
201
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
200
202
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: labels.current }),
201
203
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filteredUsers.map((user) => /* @__PURE__ */ jsxRuntime.jsx(
202
- chunkAWDH6WNA_js.EntityCard,
204
+ chunkGCYYGSHU_js.EntityCard,
203
205
  {
204
206
  accentGradient: "from-violet-500 to-indigo-700",
205
207
  icon: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-lg bg-violet-500/10 text-violet-600 dark:bg-violet-500/20 dark:text-violet-400", children: /* @__PURE__ */ jsxRuntime.jsx(outline.ShieldCheckIcon, { className: "h-6 w-6" }) }),
@@ -211,7 +213,7 @@ function RolesPageView({
211
213
  )) })
212
214
  ] }),
213
215
  /* @__PURE__ */ jsxRuntime.jsx(
214
- chunkAWDH6WNA_js.GlassModal,
216
+ chunkGCYYGSHU_js.GlassModal,
215
217
  {
216
218
  open: assignOpen,
217
219
  onClose: () => setAssignOpen(false),
@@ -228,9 +230,9 @@ function RolesPageView({
228
230
  onAssignRole({ email, role });
229
231
  setAssignOpen(false);
230
232
  },
231
- children: /* @__PURE__ */ jsxRuntime.jsxs(chunkAWDH6WNA_js.FormGrid, { children: [
232
- /* @__PURE__ */ jsxRuntime.jsx(chunkAWDH6WNA_js.FormInput, { name: "email", label: labels.userEmail, placeholder: "user@company.com", required: true }),
233
- /* @__PURE__ */ jsxRuntime.jsx(chunkAWDH6WNA_js.FormSelect, { name: "role", label: labels.role, options: roleOptions })
233
+ children: /* @__PURE__ */ jsxRuntime.jsxs(chunkGCYYGSHU_js.FormGrid, { children: [
234
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGCYYGSHU_js.FormInput, { name: "email", label: labels.userEmail, placeholder: "user@company.com", required: true }),
235
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGCYYGSHU_js.FormSelect, { name: "role", label: labels.role, options: roleOptions })
234
236
  ] })
235
237
  }
236
238
  )
@@ -238,11 +240,11 @@ function RolesPageView({
238
240
  }
239
241
  function WorkflowWorkspace({ graph }) {
240
242
  const locale = chunkYXN2K77G_js.useLocale();
241
- return /* @__PURE__ */ jsxRuntime.jsx(chunkQSMPKL27_js.Workspace, { initialGraph: graph, locale });
243
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkS7AV6XEY_js.Workspace, { initialGraph: graph, locale });
242
244
  }
243
245
 
244
246
  exports.RolesPageView = RolesPageView;
245
247
  exports.UsersPageView = UsersPageView;
246
248
  exports.WorkflowWorkspace = WorkflowWorkspace;
247
- //# sourceMappingURL=chunk-AVM53A3Y.js.map
248
- //# sourceMappingURL=chunk-AVM53A3Y.js.map
249
+ //# sourceMappingURL=chunk-3WXMBAGN.js.map
250
+ //# sourceMappingURL=chunk-3WXMBAGN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platform/pages/users-page-view.tsx","../src/platform/pages/roles-page-view.tsx","../src/platform/workflow-workspace.tsx"],"names":["useState","jsxs","jsx","HeroSection","UserGroupIcon","SearchBar","CreateActionButton","EntityCard","InlineForm","FormSelect","Button","GlassModal","FormGrid","FormInput","ShieldCheckIcon","useLocale","Workspace"],"mappings":"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","file":"chunk-3WXMBAGN.js","sourcesContent":["import { useState, type FormEvent } from 'react'\nimport { UserGroupIcon } from '@heroicons/react/24/outline'\nimport {\n Button,\n CreateActionButton,\n EntityCard,\n FormGrid,\n FormInput,\n GlassModal,\n FormSelect,\n HeroSection,\n InlineForm,\n SearchBar,\n} from '@ui/index'\nimport type { UserRole, ManagedUser, UsersPageViewProps } from '@datatechsolutions/shared-domain/common'\n\nconst ROLE_OPTIONS: Array<{ value: UserRole; label: string }> = [\n { value: 'admin', label: 'Admin' },\n { value: 'manager', label: 'Manager' },\n { value: 'analyst', label: 'Analyst' },\n { value: 'viewer', label: 'Viewer' },\n]\n\nexport function UsersPageView({ labels, users, onCreateUser, onUpdateRole }: UsersPageViewProps) {\n const [createOpen, setCreateOpen] = useState(false)\n const [searchTerm, setSearchTerm] = useState('')\n\n const allUsers = users\n const term = searchTerm.trim().toLowerCase()\n const filteredUsers = term\n ? allUsers.filter((user) =>\n user.name.toLowerCase().includes(term) || user.email.toLowerCase().includes(term),\n )\n : allUsers\n const isEmpty = allUsers.length === 0\n const labelsAny = labels as Record<string, string>\n\n return (\n <div className=\"space-y-4\">\n <HeroSection\n icon={<UserGroupIcon className=\"h-5 w-5\" />}\n label={labels.title}\n title={labels.title}\n subtitle={labels.subtitle}\n gradient=\"from-violet-500 to-indigo-600\"\n toolbar={!isEmpty ? (\n <SearchBar\n searchTerm={searchTerm}\n onSearchChange={setSearchTerm}\n placeholder={labelsAny.searchPlaceholder ?? labels.title}\n noBorder\n />\n ) : undefined}\n actions={(\n <CreateActionButton\n mode=\"desktop\"\n label={labels.create}\n onClick={() => setCreateOpen(true)}\n accent=\"violet\"\n />\n )}\n />\n\n <CreateActionButton\n mode=\"mobile\"\n label={labels.create}\n onClick={() => setCreateOpen(true)}\n accent=\"violet\"\n />\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-slate-900 dark:text-slate-100\">{labels.list}</h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filteredUsers.map((user: ManagedUser) => (\n <EntityCard\n key={user.email}\n accentGradient=\"from-violet-500 to-indigo-700\"\n icon={(\n <div className=\"flex h-11 w-11 items-center justify-center rounded-lg bg-violet-500/10 text-violet-600 dark:bg-violet-500/20 dark:text-violet-400\">\n <UserGroupIcon className=\"h-6 w-6\" />\n </div>\n )}\n title={user.name}\n subtitle={user.email}\n status={(\n <span\n className={`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold ${\n user.active\n ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300'\n : 'bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300'\n }`}\n >\n {user.active ? labels.statusActive : labels.statusInactive}\n </span>\n )}\n footer={(\n <form\n onSubmit={(event) => {\n event.preventDefault()\n const formData = new FormData(event.currentTarget)\n const role = String(formData.get('role') ?? 'viewer') as UserRole\n onUpdateRole({ email: user.email, role })\n }}\n >\n <InlineForm>\n <FormSelect name=\"role\" options={ROLE_OPTIONS} defaultValue={user.role} />\n <Button type=\"submit\" outline size=\"sm\">{labels.save}</Button>\n </InlineForm>\n </form>\n )}\n />\n ))}\n </div>\n </section>\n\n <GlassModal\n open={createOpen}\n onClose={() => setCreateOpen(false)}\n title={labels.create}\n maxWidth=\"lg\"\n showFormFooter\n cancelLabel={labels.list}\n submitLabel={labels.add}\n onSubmit={(event: FormEvent) => {\n const formData = new FormData(event.currentTarget as HTMLFormElement)\n const name = String(formData.get('name') ?? '').trim()\n const email = String(formData.get('email') ?? '').trim().toLowerCase()\n const role = String(formData.get('role') ?? 'viewer') as UserRole\n if (!name || !email) return\n onCreateUser({ name, email, role })\n setCreateOpen(false)\n }}\n >\n <FormGrid>\n <FormInput name=\"name\" label={labels.name} placeholder={labels.userNamePlaceholder} required />\n <FormInput name=\"email\" label={labels.email} placeholder={labels.userEmailPlaceholder} required type=\"email\" />\n <FormSelect name=\"role\" label={labels.role} options={ROLE_OPTIONS} />\n </FormGrid>\n </GlassModal>\n </div>\n )\n}\n","import { useState, type FormEvent } from 'react'\nimport { ShieldCheckIcon } from '@heroicons/react/24/outline'\nimport {\n CreateActionButton,\n EntityCard,\n FormGrid,\n FormInput,\n GlassModal,\n FormSelect,\n HeroSection,\n SearchBar,\n} from '@ui/index'\nimport type { UserRole, RolesPageViewProps } from '@datatechsolutions/shared-domain/common'\nimport type { PlatformRoleDefinition } from '../rbac'\n\nexport type RolesPageViewExtraProps = {\n /**\n * App-defined role definitions, e.g. `{ admin: { id, label, description }, ... }`.\n * Each app passes the output of its own `createPlatformRbac()` call.\n */\n roleDefinitions: Record<string, PlatformRoleDefinition<string>>\n /**\n * Display options surfaced in the role-assignment modal select. Each\n * entry is `{ value: roleId, label: localizedLabel }`.\n */\n roleOptions: Array<{ value: string; label: string }>\n}\n\nexport function RolesPageView({\n labels,\n users,\n onAssignRole,\n roleDefinitions,\n roleOptions,\n}: RolesPageViewProps & RolesPageViewExtraProps) {\n const [assignOpen, setAssignOpen] = useState(false)\n const [searchTerm, setSearchTerm] = useState('')\n\n const allRoleDefinitions = Object.values(roleDefinitions)\n const allUsers = users\n const term = searchTerm.trim().toLowerCase()\n const filteredRoleDefinitions = term\n ? allRoleDefinitions.filter((role) => role.label.toLowerCase().includes(term))\n : allRoleDefinitions\n const filteredUsers = term\n ? allUsers.filter((user) =>\n user.name.toLowerCase().includes(term) || user.email.toLowerCase().includes(term),\n )\n : allUsers\n const isEmpty = allRoleDefinitions.length === 0 && allUsers.length === 0\n const labelsAny = labels as Record<string, string>\n\n return (\n <div className=\"space-y-4\">\n <HeroSection\n icon={<ShieldCheckIcon className=\"h-5 w-5\" />}\n label={labels.title}\n title={labels.title}\n subtitle={labels.subtitle}\n gradient=\"from-emerald-500 to-teal-600\"\n toolbar={!isEmpty ? (\n <SearchBar\n searchTerm={searchTerm}\n onSearchChange={setSearchTerm}\n placeholder={labelsAny.searchPlaceholder ?? labels.title}\n noBorder\n />\n ) : undefined}\n actions={(\n <CreateActionButton\n mode=\"desktop\"\n label={labels.assign}\n onClick={() => setAssignOpen(true)}\n accent=\"emerald\"\n />\n )}\n />\n\n <CreateActionButton\n mode=\"mobile\"\n label={labels.assign}\n onClick={() => setAssignOpen(true)}\n accent=\"emerald\"\n />\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-slate-900 dark:text-slate-100\">{labels.definitions}</h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {filteredRoleDefinitions.map((role) => (\n <EntityCard\n key={role.id}\n accentGradient=\"from-emerald-500 to-teal-700\"\n icon={(\n <div className=\"flex h-11 w-11 items-center justify-center rounded-lg bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400\">\n <ShieldCheckIcon className=\"h-6 w-6\" />\n </div>\n )}\n title={role.label}\n subtitle={role.id}\n >\n <p className=\"text-xs text-slate-500 dark:text-slate-400\">{role.description}</p>\n <p className=\"mt-2 text-xs font-medium text-slate-600 dark:text-slate-300\">\n {labels.permissionsEnabled}\n </p>\n </EntityCard>\n ))}\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-slate-900 dark:text-slate-100\">{labels.current}</h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filteredUsers.map((user) => (\n <EntityCard\n key={user.email}\n accentGradient=\"from-violet-500 to-indigo-700\"\n icon={(\n <div className=\"flex h-11 w-11 items-center justify-center rounded-lg bg-violet-500/10 text-violet-600 dark:bg-violet-500/20 dark:text-violet-400\">\n <ShieldCheckIcon className=\"h-6 w-6\" />\n </div>\n )}\n title={user.name}\n subtitle={user.email}\n status={(\n <span className=\"shrink-0 rounded-full bg-violet-100 px-2 py-0.5 text-[10px] font-semibold text-violet-700 dark:bg-violet-900/30 dark:text-violet-300\">\n {user.role}\n </span>\n )}\n />\n ))}\n </div>\n </section>\n\n <GlassModal\n open={assignOpen}\n onClose={() => setAssignOpen(false)}\n title={labels.assign}\n maxWidth=\"lg\"\n showFormFooter\n cancelLabel={labels.current}\n submitLabel={labels.apply}\n onSubmit={(event: FormEvent) => {\n const formData = new FormData(event.currentTarget as HTMLFormElement)\n const email = String(formData.get('email') ?? '').trim().toLowerCase()\n const role = String(formData.get('role') ?? 'viewer') as UserRole\n if (!email) return\n onAssignRole({ email, role })\n setAssignOpen(false)\n }}\n >\n <FormGrid>\n <FormInput name=\"email\" label={labels.userEmail} placeholder=\"user@company.com\" required />\n <FormSelect name=\"role\" label={labels.role} options={roleOptions} />\n </FormGrid>\n </GlassModal>\n </div>\n )\n}\n","import { Workspace } from '@ui/astrlabe/workflow-canvas'\nimport type { WorkflowGraph as UiWorkflowGraph } from '@ui/astrlabe/contracts'\nimport type { WorkflowWorkspaceProps } from '@datatechsolutions/shared-domain/common'\nimport { useLocale } from '@ui/lib/i18n-context'\n\n/**\n * Thin wrapper that forwards a workflow graph into the visual canvas while\n * threading the active locale from the i18n context. The graph type from\n * `shared-domain` is structurally identical to ui's contract type — the\n * cast keeps callers from having to import both.\n */\nexport function WorkflowWorkspace({ graph }: WorkflowWorkspaceProps) {\n const locale = useLocale()\n return <Workspace initialGraph={graph as unknown as UiWorkflowGraph} locale={locale} />\n}\n"]}