autoui-react 0.0.4-alpha → 0.0.5-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +38 -18
- package/dist/index.d.ts +38 -18
- package/dist/index.js +1568 -298
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1473 -227
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -9,10 +9,41 @@ var React = require('react');
|
|
|
9
9
|
var openai = require('@ai-sdk/openai');
|
|
10
10
|
var ai = require('ai');
|
|
11
11
|
var zod = require('zod');
|
|
12
|
+
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
13
|
+
var lucideReact = require('lucide-react');
|
|
14
|
+
var SelectPrimitive = require('@radix-ui/react-select');
|
|
15
|
+
var CheckboxPrimitive = require('@radix-ui/react-checkbox');
|
|
16
|
+
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
17
|
+
var TabsPrimitive = require('@radix-ui/react-tabs');
|
|
18
|
+
var LabelPrimitive = require('@radix-ui/react-label');
|
|
12
19
|
|
|
13
20
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
21
|
|
|
22
|
+
function _interopNamespace(e) {
|
|
23
|
+
if (e && e.__esModule) return e;
|
|
24
|
+
var n = Object.create(null);
|
|
25
|
+
if (e) {
|
|
26
|
+
Object.keys(e).forEach(function (k) {
|
|
27
|
+
if (k !== 'default') {
|
|
28
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
29
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
get: function () { return e[k]; }
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
n.default = e;
|
|
37
|
+
return Object.freeze(n);
|
|
38
|
+
}
|
|
39
|
+
|
|
15
40
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
41
|
+
var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
|
|
42
|
+
var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
|
|
43
|
+
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
44
|
+
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
45
|
+
var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
|
|
46
|
+
var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
|
|
16
47
|
|
|
17
48
|
var __defProp = Object.defineProperty;
|
|
18
49
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -299,6 +330,72 @@ var initialState = {
|
|
|
299
330
|
};
|
|
300
331
|
|
|
301
332
|
// src/core/action-router.ts
|
|
333
|
+
var UI_GUIDANCE_BASE = `
|
|
334
|
+
UI Guidance:
|
|
335
|
+
1. Create a focused interface that directly addresses the goal
|
|
336
|
+
2. Use appropriate UI patterns (lists, forms, details, etc.)
|
|
337
|
+
3. Include navigation between related views when needed
|
|
338
|
+
4. Keep the interface simple and intuitive
|
|
339
|
+
5. Bind to schema data where appropriate
|
|
340
|
+
6. Provide event handlers for user interactions - make sure to always include both action and target properties`;
|
|
341
|
+
var LIST_BINDING_GUIDANCE = `7. **CRITICAL:** For \`ListView\` or \`Table\` nodes, the \`data\` binding key **MUST** point to the *exact path* of the data *array* within the context.`;
|
|
342
|
+
var LIST_BINDING_EXAMPLE = `Example: If the context has \`{ tasks: { data: [...] } }\`, the binding **MUST** be \`{ "bindings": { "data": "tasks.data" } }\`. If the context has \`{ userList: [...] }\`, the binding **MUST** be \`{ "bindings": { "data": "userList" } }\`. **NEVER** bind to the parent object containing the array (e.g., DO NOT USE \`{ "bindings": { "data": "tasks" } }\`).`;
|
|
343
|
+
var COMMON_UI_GUIDANCE = UI_GUIDANCE_BASE + "\n" + // Add a newline separator
|
|
344
|
+
LIST_BINDING_GUIDANCE + // Add the specific list binding rule
|
|
345
|
+
"\n" + // Add a newline separator
|
|
346
|
+
LIST_BINDING_EXAMPLE;
|
|
347
|
+
function processTemplate(template, values) {
|
|
348
|
+
return template.replace(/\${(.*?)}/g, (match, key) => {
|
|
349
|
+
const trimmedKey = key.trim();
|
|
350
|
+
return trimmedKey in values ? String(values[trimmedKey]) : match;
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
function buildPrompt(input, promptTemplate, templateValues) {
|
|
354
|
+
const { schema, goal, history, userContext } = input;
|
|
355
|
+
const schemaInfo = Object.entries(schema).map(([tableName, tableSchema]) => {
|
|
356
|
+
const schemaString = typeof tableSchema === "object" && tableSchema !== null ? JSON.stringify(tableSchema) : String(tableSchema);
|
|
357
|
+
return `Table: ${tableName}
|
|
358
|
+
Schema: ${schemaString}`;
|
|
359
|
+
}).join("\n\n");
|
|
360
|
+
const recentEvents = history && history.length > 0 ? history.slice(-5).map(
|
|
361
|
+
(event) => `Event: ${event.type} on node ${event.nodeId}${event.payload ? ` with payload ${JSON.stringify(event.payload)}` : ""}`
|
|
362
|
+
).join("\n") : "No recent events";
|
|
363
|
+
const userContextSection = userContext ? `
|
|
364
|
+
|
|
365
|
+
User Context:
|
|
366
|
+
${JSON.stringify(userContext)}` : "";
|
|
367
|
+
if (promptTemplate && templateValues) {
|
|
368
|
+
const fullTemplateValues = {
|
|
369
|
+
...templateValues,
|
|
370
|
+
schemaInfo,
|
|
371
|
+
recentEvents,
|
|
372
|
+
userContextString: userContextSection.trim(),
|
|
373
|
+
// Use trimmed version
|
|
374
|
+
commonUIGuidance: COMMON_UI_GUIDANCE,
|
|
375
|
+
goal
|
|
376
|
+
// Ensure goal is always available to templates
|
|
377
|
+
};
|
|
378
|
+
return processTemplate(promptTemplate, fullTemplateValues);
|
|
379
|
+
}
|
|
380
|
+
const interactionDescription = history && history.length > 0 ? `The user's last action was: ${history[history.length - 1].type} on node ${history[history.length - 1].nodeId}` : "The user initiated the session for the goal";
|
|
381
|
+
return `
|
|
382
|
+
You are an expert UI generator.
|
|
383
|
+
Create a user interface that achieves the following goal: "${goal}".
|
|
384
|
+
${interactionDescription}.
|
|
385
|
+
|
|
386
|
+
Available data schema:
|
|
387
|
+
${schemaInfo}
|
|
388
|
+
|
|
389
|
+
Recent user interactions:
|
|
390
|
+
${recentEvents}${userContextSection}
|
|
391
|
+
|
|
392
|
+
Generate a complete UI specification in JSON format that matches the following TypeScript type:
|
|
393
|
+
type UISpecNode = { id: string; node_type: string; props?: Record<string, unknown>; bindings?: Record<string, unknown>; events?: Record<string, { action: string; target: string; payload?: Record<string, unknown>; }>; children?: UISpecNode[]; };
|
|
394
|
+
${COMMON_UI_GUIDANCE}
|
|
395
|
+
|
|
396
|
+
Respond ONLY with the JSON UI specification and no other text.
|
|
397
|
+
`;
|
|
398
|
+
}
|
|
302
399
|
var ActionType = /* @__PURE__ */ ((ActionType2) => {
|
|
303
400
|
ActionType2["FULL_REFRESH"] = "FULL_REFRESH";
|
|
304
401
|
ActionType2["UPDATE_NODE"] = "UPDATE_NODE";
|
|
@@ -333,19 +430,39 @@ var ActionRouter = class {
|
|
|
333
430
|
* @returns Route resolution or null if no match
|
|
334
431
|
*/
|
|
335
432
|
resolveRoute(event, schema, layout, dataContext, goal, userContext) {
|
|
433
|
+
console.log(
|
|
434
|
+
`[ActionRouter Debug] resolveRoute called for event type: ${event.type}`
|
|
435
|
+
);
|
|
336
436
|
const routes = this.routes[event.type] || [];
|
|
437
|
+
console.log(
|
|
438
|
+
`[ActionRouter Debug] Found ${routes.length} routes for ${event.type}`
|
|
439
|
+
);
|
|
337
440
|
if (routes.length === 0) {
|
|
338
|
-
|
|
441
|
+
console.log(
|
|
442
|
+
`[ActionRouter Debug] No specific route found for ${event.type}, using default FULL_REFRESH.`
|
|
443
|
+
);
|
|
444
|
+
const defaultPlannerInput = {
|
|
445
|
+
schema,
|
|
446
|
+
goal,
|
|
447
|
+
history: [event],
|
|
448
|
+
userContext: userContext || null
|
|
449
|
+
};
|
|
450
|
+
const defaultPrompt = buildPrompt(
|
|
451
|
+
defaultPlannerInput,
|
|
452
|
+
void 0,
|
|
453
|
+
void 0
|
|
454
|
+
);
|
|
455
|
+
const defaultResolution = {
|
|
339
456
|
actionType: "FULL_REFRESH" /* FULL_REFRESH */,
|
|
340
457
|
targetNodeId: layout?.id || "root",
|
|
341
|
-
plannerInput:
|
|
342
|
-
|
|
343
|
-
goal,
|
|
344
|
-
history: [event],
|
|
345
|
-
userContext: userContext || null
|
|
346
|
-
},
|
|
347
|
-
prompt: `Generate a new UI for the goal: "${goal}". The user just triggered: ${event.type} on node ${event.nodeId}`
|
|
458
|
+
plannerInput: defaultPlannerInput,
|
|
459
|
+
prompt: defaultPrompt
|
|
348
460
|
};
|
|
461
|
+
console.log(
|
|
462
|
+
"[ActionRouter Debug] Default Resolution:",
|
|
463
|
+
defaultResolution
|
|
464
|
+
);
|
|
465
|
+
return defaultResolution;
|
|
349
466
|
}
|
|
350
467
|
const sourceNode = layout ? findNodeById(layout, event.nodeId) : void 0;
|
|
351
468
|
const nodeConfig = sourceNode?.events?.[event.type];
|
|
@@ -358,6 +475,7 @@ var ActionRouter = class {
|
|
|
358
475
|
if (!matchingRoute) {
|
|
359
476
|
matchingRoute = routes[0];
|
|
360
477
|
}
|
|
478
|
+
console.log("[ActionRouter Debug] Matching Route Config:", matchingRoute);
|
|
361
479
|
const targetNodeId = nodeConfig?.target || matchingRoute.targetNodeId || event.nodeId;
|
|
362
480
|
const additionalContext = {};
|
|
363
481
|
if (matchingRoute.contextKeys) {
|
|
@@ -402,16 +520,24 @@ var ActionRouter = class {
|
|
|
402
520
|
...additionalContext
|
|
403
521
|
// Spread additionalContext afterwards (can override userContext keys)
|
|
404
522
|
};
|
|
405
|
-
|
|
523
|
+
console.log("[ActionRouter Debug] Template Values:", templateValues);
|
|
524
|
+
const finalPrompt = buildPrompt(
|
|
525
|
+
plannerInput2,
|
|
406
526
|
matchingRoute.promptTemplate,
|
|
527
|
+
// Pass template if it exists (can be undefined)
|
|
407
528
|
templateValues
|
|
529
|
+
// Pass templateValues (used only if promptTemplate exists)
|
|
408
530
|
);
|
|
409
|
-
|
|
531
|
+
console.log("[ActionRouter Debug] Generated Prompt:", finalPrompt);
|
|
532
|
+
const finalResolution = {
|
|
410
533
|
actionType: matchingRoute.actionType,
|
|
411
534
|
targetNodeId,
|
|
412
535
|
plannerInput: plannerInput2,
|
|
413
|
-
prompt
|
|
536
|
+
prompt: finalPrompt
|
|
537
|
+
// Use the generated prompt
|
|
414
538
|
};
|
|
539
|
+
console.log("[ActionRouter Debug] Final Resolution:", finalResolution);
|
|
540
|
+
return finalResolution;
|
|
415
541
|
}
|
|
416
542
|
/**
|
|
417
543
|
* Process a prompt template with variables
|
|
@@ -429,8 +555,11 @@ function createDefaultRouter() {
|
|
|
429
555
|
const router = new ActionRouter();
|
|
430
556
|
router.registerRoute("CLICK", {
|
|
431
557
|
actionType: "FULL_REFRESH" /* FULL_REFRESH */,
|
|
432
|
-
targetNodeId: "root"
|
|
433
|
-
|
|
558
|
+
targetNodeId: "root"
|
|
559
|
+
});
|
|
560
|
+
router.registerRoute("INIT", {
|
|
561
|
+
actionType: "FULL_REFRESH" /* FULL_REFRESH */,
|
|
562
|
+
targetNodeId: "root"
|
|
434
563
|
});
|
|
435
564
|
router.registerRoute("CLICK", {
|
|
436
565
|
actionType: "SHOW_DETAIL" /* SHOW_DETAIL */,
|
|
@@ -460,7 +589,31 @@ function createDefaultRouter() {
|
|
|
460
589
|
});
|
|
461
590
|
return router;
|
|
462
591
|
}
|
|
592
|
+
var componentType = zod.z.enum([
|
|
593
|
+
// Layout components
|
|
594
|
+
"Container",
|
|
595
|
+
"Card",
|
|
596
|
+
"Header",
|
|
597
|
+
// Input components
|
|
598
|
+
"Button",
|
|
599
|
+
"Input",
|
|
600
|
+
"Select",
|
|
601
|
+
"Textarea",
|
|
602
|
+
"Checkbox",
|
|
603
|
+
"RadioGroup",
|
|
604
|
+
// Data display components
|
|
605
|
+
"ListView",
|
|
606
|
+
"Detail",
|
|
607
|
+
"Tabs",
|
|
608
|
+
"Dialog",
|
|
609
|
+
// Typography
|
|
610
|
+
"Heading",
|
|
611
|
+
"Text"
|
|
612
|
+
]);
|
|
613
|
+
|
|
614
|
+
// src/schema/ui.ts
|
|
463
615
|
var uiEventType = zod.z.enum([
|
|
616
|
+
"INIT",
|
|
464
617
|
"CLICK",
|
|
465
618
|
"CHANGE",
|
|
466
619
|
"SUBMIT",
|
|
@@ -481,12 +634,16 @@ var openAISimplifiedValue = zod.z.string().nullable();
|
|
|
481
634
|
var openAIRecordSimplifiedNullable = zod.z.record(openAISimplifiedValue).nullable();
|
|
482
635
|
var openAIEventPayloadSimplifiedNullable = zod.z.record(openAISimplifiedValue).nullable();
|
|
483
636
|
var openAIBaseNode = zod.z.object({
|
|
484
|
-
id: zod.z.string(),
|
|
485
|
-
node_type:
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
637
|
+
id: zod.z.string().describe("Unique identifier for the UI node."),
|
|
638
|
+
node_type: componentType.describe(
|
|
639
|
+
"The type of UI component (e.g., Container, Text, Button, ListView)."
|
|
640
|
+
),
|
|
641
|
+
props: openAIRecordSimplifiedNullable.describe(
|
|
642
|
+
'Component-specific properties (attributes). Values should be strings or null. E.g., for Header use { "title": "My Title" }; for Text use { "text": "My Text" }.'
|
|
643
|
+
),
|
|
644
|
+
bindings: openAIRecordSimplifiedNullable.describe(
|
|
645
|
+
'Data bindings map context paths to component props. Values are paths (e.g., "user.name") or templates (e.g., "{{item.title}}"). **CRITICAL for ListView/Table:** the `data` key MUST point to the *exact array path* (e.g., { "data": "tasks.data" } or { "data": "userList" }), NOT the parent object.'
|
|
646
|
+
),
|
|
490
647
|
events: zod.z.record(
|
|
491
648
|
zod.z.string(),
|
|
492
649
|
zod.z.object({
|
|
@@ -634,67 +791,22 @@ function createSystemEvent(type, data) {
|
|
|
634
791
|
|
|
635
792
|
// src/env.ts
|
|
636
793
|
var rawApiKeyFromEnv = process.env.VITE_OPENAI_API_KEY;
|
|
637
|
-
var defaultApiKeyLiteral = "sk-proj-literal-default-for-debug-in-env-ts";
|
|
638
794
|
var env = {
|
|
639
|
-
MOCK_PLANNER: process.env.VITE_MOCK_PLANNER || "
|
|
795
|
+
MOCK_PLANNER: process.env.VITE_MOCK_PLANNER || "0",
|
|
640
796
|
// Simplified MOCK_PLANNER assignment
|
|
641
|
-
NODE_ENV: process.env.VITE_NODE_ENV || "
|
|
797
|
+
NODE_ENV: process.env.VITE_NODE_ENV || "production",
|
|
642
798
|
// Simplified NODE_ENV assignment
|
|
643
|
-
OPENAI_API_KEY: rawApiKeyFromEnv
|
|
799
|
+
OPENAI_API_KEY: rawApiKeyFromEnv || ""
|
|
644
800
|
};
|
|
645
801
|
|
|
646
802
|
// src/core/planner.ts
|
|
647
|
-
var
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
const schemaInfo = Object.entries(schema).map(([tableName, tableSchema]) => {
|
|
654
|
-
return `Table: ${tableName}
|
|
655
|
-
Schema: ${JSON.stringify(tableSchema)}`;
|
|
656
|
-
}).join("\n\n");
|
|
657
|
-
const recentEvents = history?.slice(-5).map(
|
|
658
|
-
(event) => `Event: ${event.type} on node ${event.nodeId}${event.payload ? ` with payload ${JSON.stringify(event.payload)}` : ""}`
|
|
659
|
-
).join("\n") || "No recent events";
|
|
660
|
-
const userContextSection = userContext ? `
|
|
661
|
-
|
|
662
|
-
User Context:
|
|
663
|
-
${JSON.stringify(userContext)}` : "";
|
|
664
|
-
if (customPrompt) {
|
|
665
|
-
return customPrompt;
|
|
666
|
-
}
|
|
667
|
-
return `
|
|
668
|
-
You are an expert UI generator.
|
|
669
|
-
Create a user interface that achieves the following goal: "${goal}"
|
|
670
|
-
|
|
671
|
-
Available data schema:
|
|
672
|
-
${schemaInfo}
|
|
673
|
-
|
|
674
|
-
Recent user interactions:
|
|
675
|
-
${recentEvents}${userContextSection}
|
|
676
|
-
|
|
677
|
-
Generate a complete UI specification in JSON format that matches the following TypeScript type:
|
|
678
|
-
type UISpecNode = {
|
|
679
|
-
id: string;
|
|
680
|
-
node_type: string;
|
|
681
|
-
props?: Record<string, unknown>;
|
|
682
|
-
bindings?: Record<string, unknown>;
|
|
683
|
-
events?: Record<string, { action: string; target: string; payload?: Record<string, unknown>; }>;
|
|
684
|
-
children?: UISpecNode[];
|
|
803
|
+
var getOpenAIClient = (apiKey) => {
|
|
804
|
+
return openai.createOpenAI({
|
|
805
|
+
apiKey,
|
|
806
|
+
// Use the provided key directly
|
|
807
|
+
compatibility: "strict"
|
|
808
|
+
});
|
|
685
809
|
};
|
|
686
|
-
|
|
687
|
-
UI Guidance:
|
|
688
|
-
1. Create a focused interface that directly addresses the goal
|
|
689
|
-
2. Use appropriate UI patterns (lists, forms, details, etc.)
|
|
690
|
-
3. Include navigation between related views when needed
|
|
691
|
-
4. Keep the interface simple and intuitive
|
|
692
|
-
5. Bind to schema data where appropriate
|
|
693
|
-
6. Provide event handlers for user interactions - make sure to always include both action and target properties
|
|
694
|
-
|
|
695
|
-
Respond ONLY with the JSON UI specification and no other text.
|
|
696
|
-
`;
|
|
697
|
-
}
|
|
698
810
|
function mockPlanner(input, targetNodeId, customPrompt) {
|
|
699
811
|
if (customPrompt) {
|
|
700
812
|
console.log("mockPlanner received customPrompt:", customPrompt);
|
|
@@ -800,7 +912,7 @@ function mockPlanner(input, targetNodeId, customPrompt) {
|
|
|
800
912
|
selectable: "true"
|
|
801
913
|
},
|
|
802
914
|
bindings: {
|
|
803
|
-
|
|
915
|
+
data: "tasks.data",
|
|
804
916
|
fields: JSON.stringify([
|
|
805
917
|
{ key: "id", label: "ID" },
|
|
806
918
|
{ key: "title", label: "Title" },
|
|
@@ -853,24 +965,35 @@ function mockPlanner(input, targetNodeId, customPrompt) {
|
|
|
853
965
|
};
|
|
854
966
|
return mockNode;
|
|
855
967
|
}
|
|
856
|
-
async function callPlannerLLM(input, routeResolution) {
|
|
968
|
+
async function callPlannerLLM(input, openaiApiKey, routeResolution) {
|
|
857
969
|
await systemEvents.emit(
|
|
858
970
|
createSystemEvent("PLAN_START" /* PLAN_START */, { plannerInput: input })
|
|
859
971
|
);
|
|
860
|
-
if (env.MOCK_PLANNER === "1"
|
|
972
|
+
if (env.MOCK_PLANNER === "1") {
|
|
973
|
+
console.warn(
|
|
974
|
+
`Using mock planner because MOCK_PLANNER environment variable is set to "1".`
|
|
975
|
+
);
|
|
976
|
+
return mockPlanner(input);
|
|
977
|
+
}
|
|
978
|
+
if (!openaiApiKey) {
|
|
861
979
|
console.warn(
|
|
862
|
-
|
|
980
|
+
`OpenAI API key was not provided to callPlannerLLM. Falling back to mock planner.`
|
|
863
981
|
);
|
|
864
982
|
return mockPlanner(input);
|
|
865
983
|
}
|
|
866
984
|
const startTime = Date.now();
|
|
867
|
-
const prompt = routeResolution?.prompt
|
|
985
|
+
const prompt = routeResolution?.prompt;
|
|
986
|
+
if (!prompt) {
|
|
987
|
+
throw new Error("ActionRouter did not provide a prompt to callPlannerLLM.");
|
|
988
|
+
}
|
|
868
989
|
await systemEvents.emit(
|
|
869
990
|
createSystemEvent("PLAN_PROMPT_CREATED" /* PLAN_PROMPT_CREATED */, { prompt })
|
|
870
991
|
);
|
|
871
992
|
try {
|
|
872
993
|
const { object: uiSpec } = await ai.generateObject({
|
|
873
|
-
model:
|
|
994
|
+
model: getOpenAIClient(openaiApiKey)("gpt-4o", {
|
|
995
|
+
structuredOutputs: true
|
|
996
|
+
}),
|
|
874
997
|
schema: openAIUISpec,
|
|
875
998
|
messages: [{ role: "user", content: prompt }],
|
|
876
999
|
temperature: 0.2,
|
|
@@ -893,7 +1016,7 @@ async function callPlannerLLM(input, routeResolution) {
|
|
|
893
1016
|
throw error;
|
|
894
1017
|
}
|
|
895
1018
|
}
|
|
896
|
-
async function processEvent(event, router, schema, layout, dataContext, goal, userContext) {
|
|
1019
|
+
async function processEvent(event, router, schema, layout, dataContext, goal, userContext, openaiApiKey) {
|
|
897
1020
|
const routeResolution = await router.resolveRoute(
|
|
898
1021
|
event,
|
|
899
1022
|
schema,
|
|
@@ -913,7 +1036,11 @@ async function processEvent(event, router, schema, layout, dataContext, goal, us
|
|
|
913
1036
|
return layout;
|
|
914
1037
|
}
|
|
915
1038
|
const plannerInputForLLM = routeResolution.plannerInput;
|
|
916
|
-
const newLayout = await callPlannerLLM(
|
|
1039
|
+
const newLayout = await callPlannerLLM(
|
|
1040
|
+
plannerInputForLLM,
|
|
1041
|
+
openaiApiKey || "",
|
|
1042
|
+
routeResolution
|
|
1043
|
+
);
|
|
917
1044
|
return newLayout;
|
|
918
1045
|
}
|
|
919
1046
|
|
|
@@ -921,6 +1048,7 @@ async function processEvent(event, router, schema, layout, dataContext, goal, us
|
|
|
921
1048
|
function useUIStateEngine({
|
|
922
1049
|
schema,
|
|
923
1050
|
goal,
|
|
1051
|
+
openaiApiKey,
|
|
924
1052
|
userContext,
|
|
925
1053
|
mockMode = false,
|
|
926
1054
|
planningConfig,
|
|
@@ -967,7 +1095,11 @@ function useUIStateEngine({
|
|
|
967
1095
|
route.prompt
|
|
968
1096
|
);
|
|
969
1097
|
} else {
|
|
970
|
-
resolvedNode = await callPlannerLLM(
|
|
1098
|
+
resolvedNode = await callPlannerLLM(
|
|
1099
|
+
route.plannerInput,
|
|
1100
|
+
openaiApiKey || "",
|
|
1101
|
+
route
|
|
1102
|
+
);
|
|
971
1103
|
}
|
|
972
1104
|
} else {
|
|
973
1105
|
const input = {
|
|
@@ -979,7 +1111,11 @@ function useUIStateEngine({
|
|
|
979
1111
|
if (mockMode) {
|
|
980
1112
|
resolvedNode = mockPlanner(input);
|
|
981
1113
|
} else {
|
|
982
|
-
resolvedNode = await callPlannerLLM(
|
|
1114
|
+
resolvedNode = await callPlannerLLM(
|
|
1115
|
+
input,
|
|
1116
|
+
openaiApiKey || "",
|
|
1117
|
+
void 0
|
|
1118
|
+
);
|
|
983
1119
|
}
|
|
984
1120
|
}
|
|
985
1121
|
} else {
|
|
@@ -993,7 +1129,11 @@ function useUIStateEngine({
|
|
|
993
1129
|
if (mockMode) {
|
|
994
1130
|
resolvedNode = mockPlanner(input);
|
|
995
1131
|
} else {
|
|
996
|
-
resolvedNode = await callPlannerLLM(
|
|
1132
|
+
resolvedNode = await callPlannerLLM(
|
|
1133
|
+
input,
|
|
1134
|
+
openaiApiKey || "",
|
|
1135
|
+
void 0
|
|
1136
|
+
);
|
|
997
1137
|
}
|
|
998
1138
|
}
|
|
999
1139
|
switch (actionTypeForDispatch) {
|
|
@@ -1039,6 +1179,7 @@ function useUIStateEngine({
|
|
|
1039
1179
|
router,
|
|
1040
1180
|
mockMode,
|
|
1041
1181
|
dataContext,
|
|
1182
|
+
openaiApiKey,
|
|
1042
1183
|
enablePartialUpdates,
|
|
1043
1184
|
dispatch
|
|
1044
1185
|
// Add dispatch
|
|
@@ -1052,13 +1193,48 @@ function useUIStateEngine({
|
|
|
1052
1193
|
schema,
|
|
1053
1194
|
goal,
|
|
1054
1195
|
history: [],
|
|
1196
|
+
// Initial history is empty
|
|
1055
1197
|
userContext
|
|
1056
1198
|
};
|
|
1057
1199
|
let node;
|
|
1058
1200
|
if (mockMode) {
|
|
1059
1201
|
node = mockPlanner(input);
|
|
1060
1202
|
} else {
|
|
1061
|
-
|
|
1203
|
+
const initEvent = {
|
|
1204
|
+
type: "INIT",
|
|
1205
|
+
// Assuming "INIT" is your initial event type
|
|
1206
|
+
nodeId: "system",
|
|
1207
|
+
// Or some other appropriate initial nodeId
|
|
1208
|
+
timestamp: Date.now(),
|
|
1209
|
+
payload: null
|
|
1210
|
+
};
|
|
1211
|
+
const route = router.resolveRoute(
|
|
1212
|
+
initEvent,
|
|
1213
|
+
schema,
|
|
1214
|
+
null,
|
|
1215
|
+
// No existing layout on initial fetch
|
|
1216
|
+
dataContext,
|
|
1217
|
+
goal,
|
|
1218
|
+
userContext
|
|
1219
|
+
);
|
|
1220
|
+
if (!route || !route.prompt) {
|
|
1221
|
+
console.error(
|
|
1222
|
+
"[UIStateEngine] Initial fetch: Failed to resolve route or get prompt for INIT event."
|
|
1223
|
+
);
|
|
1224
|
+
throw new Error("Failed to initialize UI due to routing error.");
|
|
1225
|
+
}
|
|
1226
|
+
systemEvents.emit(
|
|
1227
|
+
createSystemEvent("PLAN_START" /* PLAN_START */, {
|
|
1228
|
+
plannerInput: route.plannerInput
|
|
1229
|
+
})
|
|
1230
|
+
);
|
|
1231
|
+
node = await callPlannerLLM(
|
|
1232
|
+
route.plannerInput,
|
|
1233
|
+
// Use plannerInput from the resolved route
|
|
1234
|
+
openaiApiKey || "",
|
|
1235
|
+
route
|
|
1236
|
+
// Pass the entire route object
|
|
1237
|
+
);
|
|
1062
1238
|
}
|
|
1063
1239
|
dispatch({ type: "AI_RESPONSE", node });
|
|
1064
1240
|
} catch (e) {
|
|
@@ -1075,135 +1251,531 @@ function useUIStateEngine({
|
|
|
1075
1251
|
}
|
|
1076
1252
|
};
|
|
1077
1253
|
initialFetch();
|
|
1078
|
-
}, [goal, schema, userContext, mockMode, dispatch]);
|
|
1254
|
+
}, [goal, schema, userContext, mockMode, dispatch, openaiApiKey]);
|
|
1079
1255
|
return {
|
|
1080
1256
|
state,
|
|
1081
1257
|
dispatch,
|
|
1082
1258
|
handleEvent
|
|
1083
1259
|
};
|
|
1084
1260
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
"
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
"
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
var ShimmerTable = ({ rows = 3 }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-2", children: [
|
|
1108
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-10 bg-gray-200 animate-pulse rounded" }),
|
|
1109
|
-
Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-12 bg-gray-200 animate-pulse rounded" }, i))
|
|
1110
|
-
] });
|
|
1111
|
-
var ShimmerCard = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full p-4 space-y-4 border rounded-lg", children: [
|
|
1112
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3/4 h-6 bg-gray-200 animate-pulse rounded" }),
|
|
1113
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1114
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
|
|
1115
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
|
|
1116
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5/6 h-4 bg-gray-200 animate-pulse rounded" })
|
|
1117
|
-
] })
|
|
1118
|
-
] });
|
|
1119
|
-
var Container = (props) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `autoui-mock-container ${props.className || ""}`, children: props.children });
|
|
1120
|
-
var Header = ({
|
|
1121
|
-
title,
|
|
1122
|
-
className
|
|
1123
|
-
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1124
|
-
"header",
|
|
1125
|
-
{
|
|
1126
|
-
className: `py-4 px-6 border-b border-gray-300 mb-4 bg-gray-50 dark:bg-gray-800 ${className || ""}`,
|
|
1127
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-800 dark:text-white", children: title })
|
|
1128
|
-
}
|
|
1129
|
-
);
|
|
1130
|
-
var Button = ({ onClick, children, variant = "default" }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1131
|
-
"button",
|
|
1132
|
-
{
|
|
1133
|
-
className: `px-4 py-2 rounded-md font-medium transition-colors ${variant === "default" ? "bg-blue-600 text-white hover:bg-blue-700" : variant === "outline" ? "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800" : "bg-red-600 text-white hover:bg-red-700"}`,
|
|
1134
|
-
onClick,
|
|
1135
|
-
children
|
|
1136
|
-
}
|
|
1137
|
-
);
|
|
1138
|
-
var Table = ({ items = [], fields = [], onSelect, selectable }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full border border-gray-300 dark:border-gray-700 rounded-lg overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full", children: [
|
|
1139
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-100 dark:bg-gray-800 border-b border-gray-300 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1140
|
-
"th",
|
|
1141
|
-
{
|
|
1142
|
-
className: "px-6 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider",
|
|
1143
|
-
children: field.label
|
|
1144
|
-
},
|
|
1145
|
-
field.key
|
|
1146
|
-
)) }) }),
|
|
1147
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1148
|
-
"tr",
|
|
1261
|
+
|
|
1262
|
+
// src/adapters/shadcn.tsx
|
|
1263
|
+
init_utils();
|
|
1264
|
+
|
|
1265
|
+
// components/ui/dialog.tsx
|
|
1266
|
+
init_utils();
|
|
1267
|
+
function Dialog({
|
|
1268
|
+
...props
|
|
1269
|
+
}) {
|
|
1270
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "dialog", ...props });
|
|
1271
|
+
}
|
|
1272
|
+
function DialogPortal({
|
|
1273
|
+
...props
|
|
1274
|
+
}) {
|
|
1275
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "dialog-portal", ...props });
|
|
1276
|
+
}
|
|
1277
|
+
function DialogOverlay({
|
|
1278
|
+
className,
|
|
1279
|
+
...props
|
|
1280
|
+
}) {
|
|
1281
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1282
|
+
DialogPrimitive__namespace.Overlay,
|
|
1149
1283
|
{
|
|
1150
|
-
|
|
1151
|
-
className:
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
}
|
|
1183
|
-
if (field.type === "content") {
|
|
1184
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1185
|
-
"div",
|
|
1186
|
-
{
|
|
1187
|
-
className: "text-sm text-gray-700 dark:text-gray-300",
|
|
1188
|
-
children: data?.[field.key] ?? ""
|
|
1189
|
-
},
|
|
1190
|
-
field.key
|
|
1191
|
-
);
|
|
1284
|
+
"data-slot": "dialog-overlay",
|
|
1285
|
+
className: cn(
|
|
1286
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
|
1287
|
+
className
|
|
1288
|
+
),
|
|
1289
|
+
...props
|
|
1290
|
+
}
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
function DialogContent({
|
|
1294
|
+
className,
|
|
1295
|
+
children,
|
|
1296
|
+
...props
|
|
1297
|
+
}) {
|
|
1298
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
1299
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
1300
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1301
|
+
DialogPrimitive__namespace.Content,
|
|
1302
|
+
{
|
|
1303
|
+
"data-slot": "dialog-content",
|
|
1304
|
+
className: cn(
|
|
1305
|
+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
1306
|
+
className
|
|
1307
|
+
),
|
|
1308
|
+
...props,
|
|
1309
|
+
children: [
|
|
1310
|
+
children,
|
|
1311
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
|
|
1312
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
|
|
1313
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
1314
|
+
] })
|
|
1315
|
+
]
|
|
1192
1316
|
}
|
|
1193
|
-
|
|
1194
|
-
"div",
|
|
1195
|
-
{
|
|
1196
|
-
className: "flex flex-col border-b border-gray-100 dark:border-gray-800 py-2",
|
|
1197
|
-
children: [
|
|
1198
|
-
field.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-600 dark:text-gray-400 font-medium", children: field.label }),
|
|
1199
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-800 dark:text-gray-200", children: data?.[field.key] ?? "" })
|
|
1200
|
-
]
|
|
1201
|
-
},
|
|
1202
|
-
field.key
|
|
1203
|
-
);
|
|
1204
|
-
}) })
|
|
1317
|
+
)
|
|
1205
1318
|
] });
|
|
1206
|
-
}
|
|
1319
|
+
}
|
|
1320
|
+
function DialogHeader({ className, ...props }) {
|
|
1321
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1322
|
+
"div",
|
|
1323
|
+
{
|
|
1324
|
+
"data-slot": "dialog-header",
|
|
1325
|
+
className: cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
1326
|
+
...props
|
|
1327
|
+
}
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
function DialogTitle({
|
|
1331
|
+
className,
|
|
1332
|
+
...props
|
|
1333
|
+
}) {
|
|
1334
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1335
|
+
DialogPrimitive__namespace.Title,
|
|
1336
|
+
{
|
|
1337
|
+
"data-slot": "dialog-title",
|
|
1338
|
+
className: cn("text-lg leading-none font-semibold", className),
|
|
1339
|
+
...props
|
|
1340
|
+
}
|
|
1341
|
+
);
|
|
1342
|
+
}
|
|
1343
|
+
function DialogDescription({
|
|
1344
|
+
className,
|
|
1345
|
+
...props
|
|
1346
|
+
}) {
|
|
1347
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1348
|
+
DialogPrimitive__namespace.Description,
|
|
1349
|
+
{
|
|
1350
|
+
"data-slot": "dialog-description",
|
|
1351
|
+
className: cn("text-muted-foreground text-sm", className),
|
|
1352
|
+
...props
|
|
1353
|
+
}
|
|
1354
|
+
);
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
// components/ui/card.tsx
|
|
1358
|
+
init_utils();
|
|
1359
|
+
function Card({ className, ...props }) {
|
|
1360
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1361
|
+
"div",
|
|
1362
|
+
{
|
|
1363
|
+
"data-slot": "card",
|
|
1364
|
+
className: cn(
|
|
1365
|
+
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
|
|
1366
|
+
className
|
|
1367
|
+
),
|
|
1368
|
+
...props
|
|
1369
|
+
}
|
|
1370
|
+
);
|
|
1371
|
+
}
|
|
1372
|
+
function CardContent({ className, ...props }) {
|
|
1373
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1374
|
+
"div",
|
|
1375
|
+
{
|
|
1376
|
+
"data-slot": "card-content",
|
|
1377
|
+
className: cn("px-6", className),
|
|
1378
|
+
...props
|
|
1379
|
+
}
|
|
1380
|
+
);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// components/ui/input.tsx
|
|
1384
|
+
init_utils();
|
|
1385
|
+
function Input({ className, type, ...props }) {
|
|
1386
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1387
|
+
"input",
|
|
1388
|
+
{
|
|
1389
|
+
type,
|
|
1390
|
+
"data-slot": "input",
|
|
1391
|
+
className: cn(
|
|
1392
|
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1393
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
1394
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
1395
|
+
className
|
|
1396
|
+
),
|
|
1397
|
+
...props
|
|
1398
|
+
}
|
|
1399
|
+
);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
// components/ui/textarea.tsx
|
|
1403
|
+
init_utils();
|
|
1404
|
+
function Textarea({ className, ...props }) {
|
|
1405
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1406
|
+
"textarea",
|
|
1407
|
+
{
|
|
1408
|
+
"data-slot": "textarea",
|
|
1409
|
+
className: cn(
|
|
1410
|
+
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1411
|
+
className
|
|
1412
|
+
),
|
|
1413
|
+
...props
|
|
1414
|
+
}
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
// components/ui/select.tsx
|
|
1419
|
+
init_utils();
|
|
1420
|
+
function Select({
|
|
1421
|
+
...props
|
|
1422
|
+
}) {
|
|
1423
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Root, { "data-slot": "select", ...props });
|
|
1424
|
+
}
|
|
1425
|
+
function SelectValue({
|
|
1426
|
+
...props
|
|
1427
|
+
}) {
|
|
1428
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Value, { "data-slot": "select-value", ...props });
|
|
1429
|
+
}
|
|
1430
|
+
function SelectTrigger({
|
|
1431
|
+
className,
|
|
1432
|
+
size = "default",
|
|
1433
|
+
children,
|
|
1434
|
+
...props
|
|
1435
|
+
}) {
|
|
1436
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1437
|
+
SelectPrimitive__namespace.Trigger,
|
|
1438
|
+
{
|
|
1439
|
+
"data-slot": "select-trigger",
|
|
1440
|
+
"data-size": size,
|
|
1441
|
+
className: cn(
|
|
1442
|
+
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
1443
|
+
className
|
|
1444
|
+
),
|
|
1445
|
+
...props,
|
|
1446
|
+
children: [
|
|
1447
|
+
children,
|
|
1448
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "size-4 opacity-50" }) })
|
|
1449
|
+
]
|
|
1450
|
+
}
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
function SelectContent({
|
|
1454
|
+
className,
|
|
1455
|
+
children,
|
|
1456
|
+
position = "popper",
|
|
1457
|
+
...props
|
|
1458
|
+
}) {
|
|
1459
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1460
|
+
SelectPrimitive__namespace.Content,
|
|
1461
|
+
{
|
|
1462
|
+
"data-slot": "select-content",
|
|
1463
|
+
className: cn(
|
|
1464
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
|
1465
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
1466
|
+
className
|
|
1467
|
+
),
|
|
1468
|
+
position,
|
|
1469
|
+
...props,
|
|
1470
|
+
children: [
|
|
1471
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}),
|
|
1472
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1473
|
+
SelectPrimitive__namespace.Viewport,
|
|
1474
|
+
{
|
|
1475
|
+
className: cn(
|
|
1476
|
+
"p-1",
|
|
1477
|
+
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
|
|
1478
|
+
),
|
|
1479
|
+
children
|
|
1480
|
+
}
|
|
1481
|
+
),
|
|
1482
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectScrollDownButton, {})
|
|
1483
|
+
]
|
|
1484
|
+
}
|
|
1485
|
+
) });
|
|
1486
|
+
}
|
|
1487
|
+
function SelectItem({
|
|
1488
|
+
className,
|
|
1489
|
+
children,
|
|
1490
|
+
...props
|
|
1491
|
+
}) {
|
|
1492
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1493
|
+
SelectPrimitive__namespace.Item,
|
|
1494
|
+
{
|
|
1495
|
+
"data-slot": "select-item",
|
|
1496
|
+
className: cn(
|
|
1497
|
+
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
1498
|
+
className
|
|
1499
|
+
),
|
|
1500
|
+
...props,
|
|
1501
|
+
children: [
|
|
1502
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "size-4" }) }) }),
|
|
1503
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemText, { children })
|
|
1504
|
+
]
|
|
1505
|
+
}
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
function SelectScrollUpButton({
|
|
1509
|
+
className,
|
|
1510
|
+
...props
|
|
1511
|
+
}) {
|
|
1512
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1513
|
+
SelectPrimitive__namespace.ScrollUpButton,
|
|
1514
|
+
{
|
|
1515
|
+
"data-slot": "select-scroll-up-button",
|
|
1516
|
+
className: cn(
|
|
1517
|
+
"flex cursor-default items-center justify-center py-1",
|
|
1518
|
+
className
|
|
1519
|
+
),
|
|
1520
|
+
...props,
|
|
1521
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "size-4" })
|
|
1522
|
+
}
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
function SelectScrollDownButton({
|
|
1526
|
+
className,
|
|
1527
|
+
...props
|
|
1528
|
+
}) {
|
|
1529
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1530
|
+
SelectPrimitive__namespace.ScrollDownButton,
|
|
1531
|
+
{
|
|
1532
|
+
"data-slot": "select-scroll-down-button",
|
|
1533
|
+
className: cn(
|
|
1534
|
+
"flex cursor-default items-center justify-center py-1",
|
|
1535
|
+
className
|
|
1536
|
+
),
|
|
1537
|
+
...props,
|
|
1538
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "size-4" })
|
|
1539
|
+
}
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
// components/ui/checkbox.tsx
|
|
1544
|
+
init_utils();
|
|
1545
|
+
function Checkbox({
|
|
1546
|
+
className,
|
|
1547
|
+
...props
|
|
1548
|
+
}) {
|
|
1549
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1550
|
+
CheckboxPrimitive__namespace.Root,
|
|
1551
|
+
{
|
|
1552
|
+
"data-slot": "checkbox",
|
|
1553
|
+
className: cn(
|
|
1554
|
+
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
1555
|
+
className
|
|
1556
|
+
),
|
|
1557
|
+
...props,
|
|
1558
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1559
|
+
CheckboxPrimitive__namespace.Indicator,
|
|
1560
|
+
{
|
|
1561
|
+
"data-slot": "checkbox-indicator",
|
|
1562
|
+
className: "flex items-center justify-center text-current transition-none",
|
|
1563
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "size-3.5" })
|
|
1564
|
+
}
|
|
1565
|
+
)
|
|
1566
|
+
}
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
// components/ui/radio-group.tsx
|
|
1571
|
+
init_utils();
|
|
1572
|
+
function RadioGroup({
|
|
1573
|
+
className,
|
|
1574
|
+
...props
|
|
1575
|
+
}) {
|
|
1576
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1577
|
+
RadioGroupPrimitive__namespace.Root,
|
|
1578
|
+
{
|
|
1579
|
+
"data-slot": "radio-group",
|
|
1580
|
+
className: cn("grid gap-3", className),
|
|
1581
|
+
...props
|
|
1582
|
+
}
|
|
1583
|
+
);
|
|
1584
|
+
}
|
|
1585
|
+
function RadioGroupItem({
|
|
1586
|
+
className,
|
|
1587
|
+
...props
|
|
1588
|
+
}) {
|
|
1589
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1590
|
+
RadioGroupPrimitive__namespace.Item,
|
|
1591
|
+
{
|
|
1592
|
+
"data-slot": "radio-group-item",
|
|
1593
|
+
className: cn(
|
|
1594
|
+
"border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
1595
|
+
className
|
|
1596
|
+
),
|
|
1597
|
+
...props,
|
|
1598
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1599
|
+
RadioGroupPrimitive__namespace.Indicator,
|
|
1600
|
+
{
|
|
1601
|
+
"data-slot": "radio-group-indicator",
|
|
1602
|
+
className: "relative flex items-center justify-center",
|
|
1603
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleIcon, { className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" })
|
|
1604
|
+
}
|
|
1605
|
+
)
|
|
1606
|
+
}
|
|
1607
|
+
);
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// components/ui/tabs.tsx
|
|
1611
|
+
init_utils();
|
|
1612
|
+
function Tabs({
|
|
1613
|
+
className,
|
|
1614
|
+
...props
|
|
1615
|
+
}) {
|
|
1616
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1617
|
+
TabsPrimitive__namespace.Root,
|
|
1618
|
+
{
|
|
1619
|
+
"data-slot": "tabs",
|
|
1620
|
+
className: cn("flex flex-col gap-2", className),
|
|
1621
|
+
...props
|
|
1622
|
+
}
|
|
1623
|
+
);
|
|
1624
|
+
}
|
|
1625
|
+
function TabsList({
|
|
1626
|
+
className,
|
|
1627
|
+
...props
|
|
1628
|
+
}) {
|
|
1629
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1630
|
+
TabsPrimitive__namespace.List,
|
|
1631
|
+
{
|
|
1632
|
+
"data-slot": "tabs-list",
|
|
1633
|
+
className: cn(
|
|
1634
|
+
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
|
1635
|
+
className
|
|
1636
|
+
),
|
|
1637
|
+
...props
|
|
1638
|
+
}
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
function TabsTrigger({
|
|
1642
|
+
className,
|
|
1643
|
+
...props
|
|
1644
|
+
}) {
|
|
1645
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1646
|
+
TabsPrimitive__namespace.Trigger,
|
|
1647
|
+
{
|
|
1648
|
+
"data-slot": "tabs-trigger",
|
|
1649
|
+
className: cn(
|
|
1650
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
1651
|
+
className
|
|
1652
|
+
),
|
|
1653
|
+
...props
|
|
1654
|
+
}
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1657
|
+
function TabsContent({
|
|
1658
|
+
className,
|
|
1659
|
+
...props
|
|
1660
|
+
}) {
|
|
1661
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1662
|
+
TabsPrimitive__namespace.Content,
|
|
1663
|
+
{
|
|
1664
|
+
"data-slot": "tabs-content",
|
|
1665
|
+
className: cn("flex-1 outline-none", className),
|
|
1666
|
+
...props
|
|
1667
|
+
}
|
|
1668
|
+
);
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
// components/ui/label.tsx
|
|
1672
|
+
init_utils();
|
|
1673
|
+
function Label2({
|
|
1674
|
+
className,
|
|
1675
|
+
...props
|
|
1676
|
+
}) {
|
|
1677
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1678
|
+
LabelPrimitive__namespace.Root,
|
|
1679
|
+
{
|
|
1680
|
+
"data-slot": "label",
|
|
1681
|
+
className: cn(
|
|
1682
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
1683
|
+
className
|
|
1684
|
+
),
|
|
1685
|
+
...props
|
|
1686
|
+
}
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
var parseStyleString = (styleString) => {
|
|
1690
|
+
if (typeof styleString !== "string") {
|
|
1691
|
+
return typeof styleString === "object" ? styleString : {};
|
|
1692
|
+
}
|
|
1693
|
+
const style = {};
|
|
1694
|
+
styleString.split(";").forEach((declaration) => {
|
|
1695
|
+
const [property, value] = declaration.split(":");
|
|
1696
|
+
if (property && value) {
|
|
1697
|
+
const camelCasedProperty = property.trim().replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
1698
|
+
style[camelCasedProperty] = value.trim();
|
|
1699
|
+
}
|
|
1700
|
+
});
|
|
1701
|
+
return style;
|
|
1702
|
+
};
|
|
1703
|
+
var isArrayOf = (guard) => (arr) => Array.isArray(arr) && arr.every(guard);
|
|
1704
|
+
var ShimmerBlock = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-8 bg-gray-200 animate-pulse rounded" });
|
|
1705
|
+
var ShimmerTable = ({ rows = 3 }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-2", children: [
|
|
1706
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-10 bg-gray-200 animate-pulse rounded" }),
|
|
1707
|
+
Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-12 bg-gray-200 animate-pulse rounded" }, i))
|
|
1708
|
+
] });
|
|
1709
|
+
var ShimmerCard = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full p-4 space-y-4 border rounded-lg", children: [
|
|
1710
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3/4 h-6 bg-gray-200 animate-pulse rounded" }),
|
|
1711
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1712
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
|
|
1713
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
|
|
1714
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5/6 h-4 bg-gray-200 animate-pulse rounded" })
|
|
1715
|
+
] })
|
|
1716
|
+
] });
|
|
1717
|
+
var Container = (props) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `autoui-mock-container ${props.className || ""}`, children: props.children });
|
|
1718
|
+
var Header = ({
|
|
1719
|
+
title,
|
|
1720
|
+
className
|
|
1721
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1722
|
+
"header",
|
|
1723
|
+
{
|
|
1724
|
+
className: `py-4 px-6 border-b border-gray-300 mb-4 bg-gray-50 dark:bg-gray-800 ${className || ""}`,
|
|
1725
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-800 dark:text-white", children: title })
|
|
1726
|
+
}
|
|
1727
|
+
);
|
|
1728
|
+
var Button = ({ onClick, children, variant = "default" }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1729
|
+
"button",
|
|
1730
|
+
{
|
|
1731
|
+
className: `px-4 py-2 rounded-md font-medium transition-colors ${variant === "default" ? "bg-blue-600 text-white hover:bg-blue-700" : variant === "outline" ? "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800" : "bg-red-600 text-white hover:bg-red-700"}`,
|
|
1732
|
+
onClick: () => onClick?.(),
|
|
1733
|
+
children
|
|
1734
|
+
}
|
|
1735
|
+
);
|
|
1736
|
+
var Detail = ({ data, fields = [], title, visible = true, onBack }) => {
|
|
1737
|
+
if (!visible)
|
|
1738
|
+
return null;
|
|
1739
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full border border-gray-300 dark:border-gray-700 rounded-lg p-6 space-y-4 bg-white dark:bg-gray-900 shadow-sm", children: [
|
|
1740
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center border-b border-gray-200 dark:border-gray-700 pb-3", children: [
|
|
1741
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-medium text-gray-800 dark:text-white", children: title }),
|
|
1742
|
+
onBack && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: onBack, children: "Back" })
|
|
1743
|
+
] }),
|
|
1744
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: fields.map((field) => {
|
|
1745
|
+
if (field.type === "heading") {
|
|
1746
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1747
|
+
"h3",
|
|
1748
|
+
{
|
|
1749
|
+
className: "text-xl font-semibold text-gray-800 dark:text-white",
|
|
1750
|
+
children: data?.[field.key] ?? ""
|
|
1751
|
+
},
|
|
1752
|
+
field.key
|
|
1753
|
+
);
|
|
1754
|
+
}
|
|
1755
|
+
if (field.type === "content") {
|
|
1756
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1757
|
+
"div",
|
|
1758
|
+
{
|
|
1759
|
+
className: "text-sm text-gray-700 dark:text-gray-300",
|
|
1760
|
+
children: data?.[field.key] ?? ""
|
|
1761
|
+
},
|
|
1762
|
+
field.key
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1766
|
+
"div",
|
|
1767
|
+
{
|
|
1768
|
+
className: "flex flex-col border-b border-gray-100 dark:border-gray-800 py-2",
|
|
1769
|
+
children: [
|
|
1770
|
+
field.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-600 dark:text-gray-400 font-medium", children: field.label }),
|
|
1771
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-800 dark:text-gray-200", children: data?.[field.key] ?? "" })
|
|
1772
|
+
]
|
|
1773
|
+
},
|
|
1774
|
+
field.key
|
|
1775
|
+
);
|
|
1776
|
+
}) })
|
|
1777
|
+
] });
|
|
1778
|
+
};
|
|
1207
1779
|
var getSafeProp = (props, key, validator, defaultValue) => {
|
|
1208
1780
|
if (props && typeof props === "object" && key in props) {
|
|
1209
1781
|
const value = props[key];
|
|
@@ -1216,7 +1788,6 @@ var getSafeProp = (props, key, validator, defaultValue) => {
|
|
|
1216
1788
|
var isObject = (value) => typeof value === "object" && value !== null;
|
|
1217
1789
|
var isString = (value) => typeof value === "string";
|
|
1218
1790
|
var isBoolean = (value) => typeof value === "boolean";
|
|
1219
|
-
var isCSSProperties = (value) => isObject(value);
|
|
1220
1791
|
var isButtonVariant = (value) => isString(value) && ["default", "outline", "destructive"].includes(value);
|
|
1221
1792
|
var getSafeBinding = (bindings, key, validator, defaultValue) => {
|
|
1222
1793
|
if (bindings && typeof bindings === "object" && key in bindings) {
|
|
@@ -1227,12 +1798,20 @@ var getSafeBinding = (bindings, key, validator, defaultValue) => {
|
|
|
1227
1798
|
}
|
|
1228
1799
|
return defaultValue;
|
|
1229
1800
|
};
|
|
1230
|
-
var isArrayOf = (itemValidator) => (arr) => Array.isArray(arr) && arr.every(itemValidator);
|
|
1231
1801
|
var isReactNode = (value) => {
|
|
1232
1802
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null || typeof value === "undefined" || typeof value === "object" && value !== null && "$$typeof" in value;
|
|
1233
1803
|
};
|
|
1234
1804
|
var isRecordWithReactNodeValues = (value) => isObject(value) && Object.values(value).every(isReactNode);
|
|
1235
|
-
var
|
|
1805
|
+
var isSelectOptionObject = (item) => isObject(item) && isString(item.value) && isString(item.label);
|
|
1806
|
+
var isTabObject = (item) => (
|
|
1807
|
+
// Allow content to be optional initially
|
|
1808
|
+
isObject(item) && isString(item.value) && isString(item.label) && (item.content === void 0 || isUISpecNode(item.content))
|
|
1809
|
+
);
|
|
1810
|
+
var isUISpecNode = (value) => {
|
|
1811
|
+
if (!isObject(value))
|
|
1812
|
+
return false;
|
|
1813
|
+
return isString(value.id) && isString(value.node_type);
|
|
1814
|
+
};
|
|
1236
1815
|
var isDetailFieldObject = (item) => isObject(item) && isString(item.key) && isString(item.label) && (item.type === void 0 || isString(item.type));
|
|
1237
1816
|
var createEventHandler = (node, eventName, uiEventType2, processEvent2) => {
|
|
1238
1817
|
const eventConfig = node.events?.[uiEventType2];
|
|
@@ -1252,14 +1831,36 @@ var createEventHandler = (node, eventName, uiEventType2, processEvent2) => {
|
|
|
1252
1831
|
};
|
|
1253
1832
|
};
|
|
1254
1833
|
var adapterMap = {
|
|
1255
|
-
Container: (node, processEvent2) =>
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1834
|
+
Container: (node, processEvent2) => {
|
|
1835
|
+
const { className, style: styleProp, key, ...restProps } = node.props || {};
|
|
1836
|
+
const children = node.children?.map(
|
|
1837
|
+
(child) => (
|
|
1838
|
+
// Use React.cloneElement to add the key prop to the element returned by renderNode
|
|
1839
|
+
React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
|
|
1840
|
+
)
|
|
1841
|
+
);
|
|
1842
|
+
const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
|
|
1843
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1844
|
+
"div",
|
|
1845
|
+
{
|
|
1846
|
+
className: cn("autoui-container", className),
|
|
1847
|
+
style,
|
|
1848
|
+
...restProps,
|
|
1849
|
+
"data-id": node.id,
|
|
1850
|
+
children: [
|
|
1851
|
+
(() => {
|
|
1852
|
+
console.log(
|
|
1853
|
+
`[Adapter Debug] Rendering Container: id=${node.id}, props=`,
|
|
1854
|
+
node.props
|
|
1855
|
+
);
|
|
1856
|
+
return null;
|
|
1857
|
+
})(),
|
|
1858
|
+
children
|
|
1859
|
+
]
|
|
1860
|
+
},
|
|
1861
|
+
key
|
|
1862
|
+
);
|
|
1863
|
+
},
|
|
1263
1864
|
Header: (node) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1264
1865
|
Header,
|
|
1265
1866
|
{
|
|
@@ -1276,37 +1877,28 @@ var adapterMap = {
|
|
|
1276
1877
|
}
|
|
1277
1878
|
),
|
|
1278
1879
|
ListView: (node, processEvent2) => {
|
|
1279
|
-
const
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1880
|
+
const { className, style: styleProp, key, ...restProps } = node.props || {};
|
|
1881
|
+
const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
|
|
1882
|
+
console.log(
|
|
1883
|
+
`[Adapter Debug] Rendering ListView: id=${node.id}, props=`,
|
|
1884
|
+
node.props
|
|
1284
1885
|
);
|
|
1285
|
-
const
|
|
1286
|
-
|
|
1287
|
-
"fields",
|
|
1288
|
-
isArrayOf(isFieldObject),
|
|
1289
|
-
[]
|
|
1886
|
+
const children = node.children?.map(
|
|
1887
|
+
(child) => React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
|
|
1290
1888
|
);
|
|
1291
|
-
const selectable = getSafeProp(node.props, "selectable", isBoolean, false);
|
|
1292
1889
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1293
|
-
|
|
1890
|
+
"div",
|
|
1294
1891
|
{
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
if (handler) {
|
|
1306
|
-
handler({ selectedItem: item });
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1892
|
+
className: cn(
|
|
1893
|
+
"autoui-listview-container space-y-2",
|
|
1894
|
+
className
|
|
1895
|
+
),
|
|
1896
|
+
style,
|
|
1897
|
+
...restProps,
|
|
1898
|
+
"data-id": node.id,
|
|
1899
|
+
children
|
|
1900
|
+
},
|
|
1901
|
+
key
|
|
1310
1902
|
);
|
|
1311
1903
|
},
|
|
1312
1904
|
Detail: (node, processEvent2) => {
|
|
@@ -1334,6 +1926,449 @@ var adapterMap = {
|
|
|
1334
1926
|
onBack: createEventHandler(node, "onBack", "CLICK", processEvent2)
|
|
1335
1927
|
}
|
|
1336
1928
|
);
|
|
1929
|
+
},
|
|
1930
|
+
Card: (node, processEvent2) => {
|
|
1931
|
+
const { className, style: styleProp, key, ...restProps } = node.props || {};
|
|
1932
|
+
const children = node.children?.map(
|
|
1933
|
+
(child) => React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
|
|
1934
|
+
);
|
|
1935
|
+
const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
|
|
1936
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1937
|
+
Card,
|
|
1938
|
+
{
|
|
1939
|
+
className: cn("autoui-card", className),
|
|
1940
|
+
style,
|
|
1941
|
+
...restProps,
|
|
1942
|
+
"data-id": node.id,
|
|
1943
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "p-0", children: [
|
|
1944
|
+
" ",
|
|
1945
|
+
children
|
|
1946
|
+
] })
|
|
1947
|
+
},
|
|
1948
|
+
key
|
|
1949
|
+
);
|
|
1950
|
+
},
|
|
1951
|
+
Input: (node, processEvent2) => {
|
|
1952
|
+
const name = getSafeProp(node.props, "name", isString, "inputName");
|
|
1953
|
+
const label = getSafeProp(node.props, "label", isString, "");
|
|
1954
|
+
const value = getSafeBinding(node.bindings, "value", isString, "");
|
|
1955
|
+
const placeholder = getSafeProp(node.props, "placeholder", isString, "");
|
|
1956
|
+
const disabled = getSafeProp(node.props, "disabled", isBoolean, false);
|
|
1957
|
+
const className = getSafeProp(node.props, "className", isString, "");
|
|
1958
|
+
const handleChange = (e) => {
|
|
1959
|
+
const handler = createEventHandler(
|
|
1960
|
+
node,
|
|
1961
|
+
"onChange",
|
|
1962
|
+
"CHANGE",
|
|
1963
|
+
processEvent2
|
|
1964
|
+
);
|
|
1965
|
+
if (handler)
|
|
1966
|
+
handler({ value: e.target.value });
|
|
1967
|
+
};
|
|
1968
|
+
const handleFocus = () => {
|
|
1969
|
+
const handler = createEventHandler(
|
|
1970
|
+
node,
|
|
1971
|
+
"onFocus",
|
|
1972
|
+
"FOCUS",
|
|
1973
|
+
processEvent2
|
|
1974
|
+
);
|
|
1975
|
+
if (handler)
|
|
1976
|
+
handler({});
|
|
1977
|
+
};
|
|
1978
|
+
const handleBlur = () => {
|
|
1979
|
+
const handler = createEventHandler(node, "onBlur", "BLUR", processEvent2);
|
|
1980
|
+
if (handler)
|
|
1981
|
+
handler({});
|
|
1982
|
+
};
|
|
1983
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid w-full max-w-sm items-center gap-1.5", children: [
|
|
1984
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, children: label }),
|
|
1985
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1986
|
+
Input,
|
|
1987
|
+
{
|
|
1988
|
+
id: name,
|
|
1989
|
+
name,
|
|
1990
|
+
placeholder,
|
|
1991
|
+
disabled,
|
|
1992
|
+
value,
|
|
1993
|
+
onChange: handleChange,
|
|
1994
|
+
onFocus: handleFocus,
|
|
1995
|
+
onBlur: handleBlur,
|
|
1996
|
+
className
|
|
1997
|
+
}
|
|
1998
|
+
)
|
|
1999
|
+
] });
|
|
2000
|
+
},
|
|
2001
|
+
Select: (node, processEvent2) => {
|
|
2002
|
+
const name = getSafeProp(node.props, "name", isString, "selectName");
|
|
2003
|
+
const label = getSafeProp(node.props, "label", isString, "");
|
|
2004
|
+
const placeholder = getSafeProp(
|
|
2005
|
+
node.props,
|
|
2006
|
+
"placeholder",
|
|
2007
|
+
isString,
|
|
2008
|
+
"Select..."
|
|
2009
|
+
);
|
|
2010
|
+
const disabled = getSafeProp(node.props, "disabled", isBoolean, false);
|
|
2011
|
+
const value = getSafeBinding(node.bindings, "value", isString, "");
|
|
2012
|
+
const options = getSafeBinding(
|
|
2013
|
+
node.bindings,
|
|
2014
|
+
"options",
|
|
2015
|
+
isArrayOf(isSelectOptionObject),
|
|
2016
|
+
[]
|
|
2017
|
+
);
|
|
2018
|
+
const className = getSafeProp(node.props, "className", isString, "");
|
|
2019
|
+
const handleValueChange = (selectedValue) => {
|
|
2020
|
+
const handler = createEventHandler(
|
|
2021
|
+
node,
|
|
2022
|
+
"onValueChange",
|
|
2023
|
+
"CHANGE",
|
|
2024
|
+
processEvent2
|
|
2025
|
+
);
|
|
2026
|
+
if (handler)
|
|
2027
|
+
handler({ value: selectedValue });
|
|
2028
|
+
};
|
|
2029
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2030
|
+
"div",
|
|
2031
|
+
{
|
|
2032
|
+
className: cn("grid w-full max-w-sm items-center gap-1.5", className),
|
|
2033
|
+
children: [
|
|
2034
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, children: label }),
|
|
2035
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2036
|
+
Select,
|
|
2037
|
+
{
|
|
2038
|
+
name,
|
|
2039
|
+
value,
|
|
2040
|
+
onValueChange: handleValueChange,
|
|
2041
|
+
disabled,
|
|
2042
|
+
children: [
|
|
2043
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: name, children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder }) }),
|
|
2044
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
|
|
2045
|
+
]
|
|
2046
|
+
}
|
|
2047
|
+
)
|
|
2048
|
+
]
|
|
2049
|
+
}
|
|
2050
|
+
);
|
|
2051
|
+
},
|
|
2052
|
+
Textarea: (node, processEvent2) => {
|
|
2053
|
+
const { key, ...propsWithoutKey } = node.props || {};
|
|
2054
|
+
const name = getSafeProp(propsWithoutKey, "name", isString, "textareaName");
|
|
2055
|
+
const label = getSafeProp(propsWithoutKey, "label", isString, "");
|
|
2056
|
+
const placeholder = getSafeProp(
|
|
2057
|
+
propsWithoutKey,
|
|
2058
|
+
"placeholder",
|
|
2059
|
+
isString,
|
|
2060
|
+
""
|
|
2061
|
+
);
|
|
2062
|
+
const disabled = getSafeProp(propsWithoutKey, "disabled", isBoolean, false);
|
|
2063
|
+
const rows = getSafeProp(
|
|
2064
|
+
propsWithoutKey,
|
|
2065
|
+
"rows",
|
|
2066
|
+
(v) => typeof v === "number",
|
|
2067
|
+
3
|
|
2068
|
+
);
|
|
2069
|
+
const value = getSafeBinding(node.bindings, "value", isString, "");
|
|
2070
|
+
const className = getSafeProp(propsWithoutKey, "className", isString, "");
|
|
2071
|
+
const handleChange = (e) => {
|
|
2072
|
+
const handler = createEventHandler(
|
|
2073
|
+
node,
|
|
2074
|
+
"onChange",
|
|
2075
|
+
"CHANGE",
|
|
2076
|
+
processEvent2
|
|
2077
|
+
);
|
|
2078
|
+
if (handler)
|
|
2079
|
+
handler({ value: e.target.value });
|
|
2080
|
+
};
|
|
2081
|
+
const handleFocus = () => {
|
|
2082
|
+
const handler = createEventHandler(
|
|
2083
|
+
node,
|
|
2084
|
+
"onFocus",
|
|
2085
|
+
"FOCUS",
|
|
2086
|
+
processEvent2
|
|
2087
|
+
);
|
|
2088
|
+
if (handler)
|
|
2089
|
+
handler({});
|
|
2090
|
+
};
|
|
2091
|
+
const handleBlur = () => {
|
|
2092
|
+
const handler = createEventHandler(node, "onBlur", "BLUR", processEvent2);
|
|
2093
|
+
if (handler)
|
|
2094
|
+
handler({});
|
|
2095
|
+
};
|
|
2096
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid w-full gap-1.5", children: [
|
|
2097
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, children: label }),
|
|
2098
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2099
|
+
Textarea,
|
|
2100
|
+
{
|
|
2101
|
+
id: name,
|
|
2102
|
+
name,
|
|
2103
|
+
placeholder,
|
|
2104
|
+
disabled,
|
|
2105
|
+
rows,
|
|
2106
|
+
value,
|
|
2107
|
+
onChange: handleChange,
|
|
2108
|
+
onFocus: handleFocus,
|
|
2109
|
+
onBlur: handleBlur,
|
|
2110
|
+
className
|
|
2111
|
+
}
|
|
2112
|
+
)
|
|
2113
|
+
] }, key);
|
|
2114
|
+
},
|
|
2115
|
+
Checkbox: (node, processEvent2) => {
|
|
2116
|
+
const { key, ...propsWithoutKey } = node.props || {};
|
|
2117
|
+
const name = getSafeProp(propsWithoutKey, "name", isString, "checkboxName");
|
|
2118
|
+
const label = getSafeProp(propsWithoutKey, "label", isString, "");
|
|
2119
|
+
const checked = getSafeBinding(node.bindings, "checked", isBoolean, false);
|
|
2120
|
+
const disabled = getSafeProp(propsWithoutKey, "disabled", isBoolean, false);
|
|
2121
|
+
const className = getSafeProp(propsWithoutKey, "className", isString, "");
|
|
2122
|
+
const handleCheckedChange = (isChecked) => {
|
|
2123
|
+
if (typeof isChecked === "boolean") {
|
|
2124
|
+
const handler = createEventHandler(
|
|
2125
|
+
node,
|
|
2126
|
+
"onCheckedChange",
|
|
2127
|
+
"CHANGE",
|
|
2128
|
+
processEvent2
|
|
2129
|
+
);
|
|
2130
|
+
if (handler)
|
|
2131
|
+
handler({ checked: isChecked });
|
|
2132
|
+
}
|
|
2133
|
+
};
|
|
2134
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2135
|
+
"div",
|
|
2136
|
+
{
|
|
2137
|
+
className: cn("flex items-center space-x-2", className),
|
|
2138
|
+
children: [
|
|
2139
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2140
|
+
Checkbox,
|
|
2141
|
+
{
|
|
2142
|
+
id: name,
|
|
2143
|
+
name,
|
|
2144
|
+
checked,
|
|
2145
|
+
disabled,
|
|
2146
|
+
onCheckedChange: handleCheckedChange
|
|
2147
|
+
}
|
|
2148
|
+
),
|
|
2149
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, className: "cursor-pointer", children: label })
|
|
2150
|
+
]
|
|
2151
|
+
},
|
|
2152
|
+
key
|
|
2153
|
+
);
|
|
2154
|
+
},
|
|
2155
|
+
RadioGroup: (node, processEvent2) => {
|
|
2156
|
+
const { key, ...propsWithoutKey } = node.props || {};
|
|
2157
|
+
const name = getSafeProp(
|
|
2158
|
+
propsWithoutKey,
|
|
2159
|
+
"name",
|
|
2160
|
+
isString,
|
|
2161
|
+
"radioGroupName"
|
|
2162
|
+
);
|
|
2163
|
+
const label = getSafeProp(propsWithoutKey, "label", isString, "");
|
|
2164
|
+
const value = getSafeBinding(node.bindings, "value", isString, "");
|
|
2165
|
+
const options = getSafeBinding(
|
|
2166
|
+
node.bindings,
|
|
2167
|
+
"options",
|
|
2168
|
+
isArrayOf(isSelectOptionObject),
|
|
2169
|
+
[]
|
|
2170
|
+
);
|
|
2171
|
+
const disabled = getSafeProp(propsWithoutKey, "disabled", isBoolean, false);
|
|
2172
|
+
const className = getSafeProp(propsWithoutKey, "className", isString, "");
|
|
2173
|
+
const handleValueChange = (selectedValue) => {
|
|
2174
|
+
const handler = createEventHandler(
|
|
2175
|
+
node,
|
|
2176
|
+
"onValueChange",
|
|
2177
|
+
"CHANGE",
|
|
2178
|
+
processEvent2
|
|
2179
|
+
);
|
|
2180
|
+
if (handler)
|
|
2181
|
+
handler({ value: selectedValue });
|
|
2182
|
+
};
|
|
2183
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2184
|
+
"div",
|
|
2185
|
+
{
|
|
2186
|
+
className: cn("grid gap-1.5", className),
|
|
2187
|
+
children: [
|
|
2188
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { className: "mb-1", children: label }),
|
|
2189
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2190
|
+
RadioGroup,
|
|
2191
|
+
{
|
|
2192
|
+
name,
|
|
2193
|
+
value,
|
|
2194
|
+
onValueChange: handleValueChange,
|
|
2195
|
+
disabled,
|
|
2196
|
+
className: "flex flex-col space-y-1",
|
|
2197
|
+
children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
2198
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2199
|
+
RadioGroupItem,
|
|
2200
|
+
{
|
|
2201
|
+
value: option.value,
|
|
2202
|
+
id: `${name}-${option.value}`
|
|
2203
|
+
}
|
|
2204
|
+
),
|
|
2205
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2206
|
+
Label2,
|
|
2207
|
+
{
|
|
2208
|
+
htmlFor: `${name}-${option.value}`,
|
|
2209
|
+
className: "cursor-pointer",
|
|
2210
|
+
children: option.label
|
|
2211
|
+
}
|
|
2212
|
+
)
|
|
2213
|
+
] }, option.value))
|
|
2214
|
+
}
|
|
2215
|
+
)
|
|
2216
|
+
]
|
|
2217
|
+
},
|
|
2218
|
+
key
|
|
2219
|
+
);
|
|
2220
|
+
},
|
|
2221
|
+
Tabs: (node, processEvent2) => {
|
|
2222
|
+
const { key, ...propsWithoutKey } = node.props || {};
|
|
2223
|
+
const rawTabs = getSafeBinding(
|
|
2224
|
+
node.bindings,
|
|
2225
|
+
"tabs",
|
|
2226
|
+
isArrayOf(isTabObject),
|
|
2227
|
+
[]
|
|
2228
|
+
);
|
|
2229
|
+
const defaultValue = getSafeProp(
|
|
2230
|
+
propsWithoutKey,
|
|
2231
|
+
"defaultValue",
|
|
2232
|
+
isString,
|
|
2233
|
+
rawTabs[0]?.value || ""
|
|
2234
|
+
);
|
|
2235
|
+
const className = getSafeProp(propsWithoutKey, "className", isString, "");
|
|
2236
|
+
const handleValueChange = (value) => {
|
|
2237
|
+
const handler = createEventHandler(
|
|
2238
|
+
node,
|
|
2239
|
+
"onValueChange",
|
|
2240
|
+
"CHANGE",
|
|
2241
|
+
processEvent2
|
|
2242
|
+
);
|
|
2243
|
+
if (handler)
|
|
2244
|
+
handler({ value });
|
|
2245
|
+
};
|
|
2246
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2247
|
+
Tabs,
|
|
2248
|
+
{
|
|
2249
|
+
defaultValue,
|
|
2250
|
+
onValueChange: handleValueChange,
|
|
2251
|
+
className: cn("autoui-tabs w-full", className),
|
|
2252
|
+
"data-id": node.id,
|
|
2253
|
+
children: [
|
|
2254
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabsList, { children: rawTabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: tab.value, children: tab.label }, tab.value)) }),
|
|
2255
|
+
rawTabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: tab.value, children: tab.content ? renderNode(tab.content, processEvent2) : null }, tab.value))
|
|
2256
|
+
]
|
|
2257
|
+
},
|
|
2258
|
+
key
|
|
2259
|
+
);
|
|
2260
|
+
},
|
|
2261
|
+
Dialog: (node, processEvent2) => {
|
|
2262
|
+
const isOpen = getSafeBinding(
|
|
2263
|
+
node.bindings,
|
|
2264
|
+
"open",
|
|
2265
|
+
isBoolean,
|
|
2266
|
+
getSafeProp(node.props, "open", isBoolean, false)
|
|
2267
|
+
);
|
|
2268
|
+
const {
|
|
2269
|
+
title,
|
|
2270
|
+
description,
|
|
2271
|
+
className,
|
|
2272
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2273
|
+
style: _styleProp,
|
|
2274
|
+
key,
|
|
2275
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2276
|
+
open: _openProp,
|
|
2277
|
+
...restProps
|
|
2278
|
+
} = node.props || {};
|
|
2279
|
+
const children = node.children?.map(
|
|
2280
|
+
(child) => React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
|
|
2281
|
+
);
|
|
2282
|
+
const handleOpenChange = (open) => {
|
|
2283
|
+
if (!open) {
|
|
2284
|
+
const handler = createEventHandler(
|
|
2285
|
+
node,
|
|
2286
|
+
"onClose",
|
|
2287
|
+
// Assumed event name in UISpec
|
|
2288
|
+
"CLICK",
|
|
2289
|
+
// Use CLICK as the event type for closing dialogs
|
|
2290
|
+
processEvent2
|
|
2291
|
+
);
|
|
2292
|
+
if (handler) {
|
|
2293
|
+
handler({});
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
};
|
|
2297
|
+
console.log(
|
|
2298
|
+
`[Adapter Debug] Rendering Dialog: id=${node.id}, props=`,
|
|
2299
|
+
node.props,
|
|
2300
|
+
`isOpen=${isOpen}`
|
|
2301
|
+
);
|
|
2302
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2303
|
+
Dialog,
|
|
2304
|
+
{
|
|
2305
|
+
open: isOpen,
|
|
2306
|
+
onOpenChange: handleOpenChange,
|
|
2307
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2308
|
+
DialogContent,
|
|
2309
|
+
{
|
|
2310
|
+
className: cn("autoui-dialog-content", className),
|
|
2311
|
+
...restProps,
|
|
2312
|
+
"data-id": node.id,
|
|
2313
|
+
children: [
|
|
2314
|
+
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
|
|
2315
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: title }),
|
|
2316
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: description })
|
|
2317
|
+
] }),
|
|
2318
|
+
children
|
|
2319
|
+
]
|
|
2320
|
+
}
|
|
2321
|
+
)
|
|
2322
|
+
},
|
|
2323
|
+
key
|
|
2324
|
+
);
|
|
2325
|
+
},
|
|
2326
|
+
Heading: (node) => {
|
|
2327
|
+
const { className, style: styleProp, key, ...restProps } = node.props || {};
|
|
2328
|
+
const text = getSafeProp(node.props, "text", isString, "Heading");
|
|
2329
|
+
let level = getSafeProp(
|
|
2330
|
+
node.props,
|
|
2331
|
+
"level",
|
|
2332
|
+
(v) => typeof v === "number" && v >= 1 && v <= 6,
|
|
2333
|
+
2
|
|
2334
|
+
);
|
|
2335
|
+
if (typeof level !== "number" || level < 1 || level > 6) {
|
|
2336
|
+
level = 2;
|
|
2337
|
+
}
|
|
2338
|
+
const Tag = `h${level}`;
|
|
2339
|
+
const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
|
|
2340
|
+
const headingStyles = {
|
|
2341
|
+
1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl",
|
|
2342
|
+
2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0",
|
|
2343
|
+
3: "scroll-m-20 text-2xl font-semibold tracking-tight",
|
|
2344
|
+
4: "scroll-m-20 text-xl font-semibold tracking-tight"
|
|
2345
|
+
// Add styles for h5, h6 if needed, using text-lg, text-base etc.
|
|
2346
|
+
}[level] || "text-lg font-semibold";
|
|
2347
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2348
|
+
Tag,
|
|
2349
|
+
{
|
|
2350
|
+
className: cn(headingStyles, className),
|
|
2351
|
+
style,
|
|
2352
|
+
...restProps,
|
|
2353
|
+
children: text
|
|
2354
|
+
},
|
|
2355
|
+
key
|
|
2356
|
+
);
|
|
2357
|
+
},
|
|
2358
|
+
Text: (node) => {
|
|
2359
|
+
const { className, style: styleProp, key, ...restProps } = node.props || {};
|
|
2360
|
+
const text = getSafeProp(node.props, "text", isString, "Some text");
|
|
2361
|
+
const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
|
|
2362
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2363
|
+
"p",
|
|
2364
|
+
{
|
|
2365
|
+
className: cn("leading-7", className),
|
|
2366
|
+
style,
|
|
2367
|
+
...restProps,
|
|
2368
|
+
children: text
|
|
2369
|
+
},
|
|
2370
|
+
key
|
|
2371
|
+
);
|
|
1337
2372
|
}
|
|
1338
2373
|
};
|
|
1339
2374
|
function renderNode(node, processEvent2) {
|
|
@@ -1430,99 +2465,261 @@ function getValueByPath(context, path) {
|
|
|
1430
2465
|
return current;
|
|
1431
2466
|
}
|
|
1432
2467
|
function setValueByPath(context, path, value) {
|
|
2468
|
+
if (!path) {
|
|
2469
|
+
return context;
|
|
2470
|
+
}
|
|
1433
2471
|
const result = { ...context };
|
|
1434
2472
|
const parts = path.split(".");
|
|
1435
|
-
if (parts.length === 0)
|
|
1436
|
-
return result;
|
|
1437
2473
|
let current = result;
|
|
1438
2474
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
1439
2475
|
const part = parts[i];
|
|
1440
2476
|
if (typeof current !== "object" || current === null) {
|
|
1441
|
-
console.
|
|
2477
|
+
console.warn(
|
|
2478
|
+
`setValueByPath: Cannot traverse path "${path}". Parent segment "${parts[i - 1] || "(root)"}" is not an object.`
|
|
2479
|
+
);
|
|
1442
2480
|
return context;
|
|
1443
2481
|
}
|
|
1444
2482
|
const currentAsObject = current;
|
|
1445
|
-
|
|
2483
|
+
const nextPartValue = currentAsObject[part];
|
|
2484
|
+
if (nextPartValue === void 0 || nextPartValue === null) {
|
|
1446
2485
|
currentAsObject[part] = {};
|
|
2486
|
+
} else if (typeof nextPartValue !== "object") {
|
|
2487
|
+
console.warn(
|
|
2488
|
+
`setValueByPath: Cannot create nested path "${path}". Segment "${part}" is not an object.`
|
|
2489
|
+
);
|
|
2490
|
+
return context;
|
|
2491
|
+
} else {
|
|
2492
|
+
currentAsObject[part] = { ...nextPartValue };
|
|
1447
2493
|
}
|
|
1448
2494
|
current = currentAsObject[part];
|
|
1449
2495
|
}
|
|
1450
2496
|
const lastPart = parts[parts.length - 1];
|
|
1451
2497
|
if (typeof current === "object" && current !== null) {
|
|
1452
2498
|
current[lastPart] = value;
|
|
1453
|
-
} else if (parts.length === 1 && typeof result === "object" && result !== null) {
|
|
1454
|
-
result[lastPart] = value;
|
|
1455
2499
|
} else {
|
|
1456
2500
|
console.warn(
|
|
1457
|
-
`setValueByPath: Could not set value for path "${path}". Final segment
|
|
2501
|
+
`setValueByPath: Could not set value for path "${path}". Final segment parent is not an object.`
|
|
1458
2502
|
);
|
|
1459
2503
|
return context;
|
|
1460
2504
|
}
|
|
1461
2505
|
return result;
|
|
1462
2506
|
}
|
|
1463
|
-
function processBinding(binding, context) {
|
|
2507
|
+
function processBinding(binding, context, itemData) {
|
|
1464
2508
|
if (typeof binding === "string") {
|
|
1465
|
-
|
|
2509
|
+
const exactMatchArr = binding.match(/^{{(.*)}}$/);
|
|
2510
|
+
const pathInsideExact = exactMatchArr ? exactMatchArr[1].trim() : null;
|
|
2511
|
+
if (pathInsideExact !== null && !pathInsideExact.includes("{{") && !pathInsideExact.includes("}}")) {
|
|
2512
|
+
const pathToResolve = pathInsideExact;
|
|
2513
|
+
let resolvedValue = void 0;
|
|
2514
|
+
console.log(
|
|
2515
|
+
`[processBinding Debug] Processing EXACT template: "${binding}", Path: "${pathToResolve}", Has itemData: ${!!itemData}`
|
|
2516
|
+
);
|
|
2517
|
+
if (itemData) {
|
|
2518
|
+
try {
|
|
2519
|
+
console.log(
|
|
2520
|
+
`[processBinding Debug] itemData content (EXACT):`,
|
|
2521
|
+
JSON.parse(JSON.stringify(itemData))
|
|
2522
|
+
);
|
|
2523
|
+
} catch {
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
if ((pathToResolve.startsWith("item.") || pathToResolve.startsWith("row.")) && itemData) {
|
|
2527
|
+
if (pathToResolve.startsWith("item.")) {
|
|
2528
|
+
resolvedValue = getValueByPath(itemData, pathToResolve.substring(5));
|
|
2529
|
+
} else {
|
|
2530
|
+
resolvedValue = getValueByPath(itemData, pathToResolve.substring(4));
|
|
2531
|
+
}
|
|
2532
|
+
} else if (itemData && pathToResolve in itemData) {
|
|
2533
|
+
resolvedValue = getValueByPath(itemData, pathToResolve);
|
|
2534
|
+
}
|
|
2535
|
+
if (resolvedValue === void 0) {
|
|
2536
|
+
resolvedValue = getValueByPath(context, pathToResolve);
|
|
2537
|
+
}
|
|
2538
|
+
return resolvedValue;
|
|
2539
|
+
} else if (binding.includes("{{") && binding.includes("}}")) {
|
|
2540
|
+
console.log(
|
|
2541
|
+
`[processBinding Debug] Processing EMBEDDED templates: "${binding}", Has itemData: ${!!itemData}`
|
|
2542
|
+
);
|
|
2543
|
+
if (itemData) {
|
|
2544
|
+
try {
|
|
2545
|
+
console.log(
|
|
2546
|
+
`[processBinding Debug] itemData content (EMBEDDED):`,
|
|
2547
|
+
JSON.parse(JSON.stringify(itemData))
|
|
2548
|
+
);
|
|
2549
|
+
} catch {
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
const resolvedString = binding.replaceAll(
|
|
2553
|
+
/{{(.*?)}}/g,
|
|
2554
|
+
// Non-greedy match inside braces
|
|
2555
|
+
(match, path) => {
|
|
2556
|
+
const trimmedPath = path.trim();
|
|
2557
|
+
let resolvedValue = void 0;
|
|
2558
|
+
if ((trimmedPath.startsWith("item.") || trimmedPath.startsWith("row.")) && itemData) {
|
|
2559
|
+
if (trimmedPath.startsWith("item.")) {
|
|
2560
|
+
resolvedValue = getValueByPath(
|
|
2561
|
+
itemData,
|
|
2562
|
+
trimmedPath.substring(5)
|
|
2563
|
+
);
|
|
2564
|
+
} else {
|
|
2565
|
+
resolvedValue = getValueByPath(
|
|
2566
|
+
itemData,
|
|
2567
|
+
trimmedPath.substring(4)
|
|
2568
|
+
);
|
|
2569
|
+
}
|
|
2570
|
+
} else if (itemData && trimmedPath in itemData) {
|
|
2571
|
+
resolvedValue = getValueByPath(itemData, trimmedPath);
|
|
2572
|
+
}
|
|
2573
|
+
if (resolvedValue === void 0) {
|
|
2574
|
+
resolvedValue = getValueByPath(context, trimmedPath);
|
|
2575
|
+
}
|
|
2576
|
+
return resolvedValue === null || resolvedValue === void 0 ? "" : String(resolvedValue);
|
|
2577
|
+
}
|
|
2578
|
+
);
|
|
2579
|
+
return resolvedString;
|
|
2580
|
+
} else {
|
|
2581
|
+
const pathToResolve = binding;
|
|
2582
|
+
let resolvedValue = void 0;
|
|
2583
|
+
console.log(
|
|
2584
|
+
`[processBinding Debug] Processing PATH string: "${pathToResolve}", Has itemData: ${!!itemData}`
|
|
2585
|
+
);
|
|
2586
|
+
if (itemData && !pathToResolve.includes(".") && pathToResolve in itemData) {
|
|
2587
|
+
resolvedValue = getValueByPath(itemData, pathToResolve);
|
|
2588
|
+
}
|
|
2589
|
+
if (resolvedValue === void 0) {
|
|
2590
|
+
resolvedValue = getValueByPath(context, pathToResolve);
|
|
2591
|
+
}
|
|
2592
|
+
return resolvedValue;
|
|
2593
|
+
}
|
|
1466
2594
|
}
|
|
1467
2595
|
if (Array.isArray(binding)) {
|
|
1468
|
-
return binding.map((item) => processBinding(item, context));
|
|
2596
|
+
return binding.map((item) => processBinding(item, context, itemData));
|
|
1469
2597
|
}
|
|
1470
2598
|
if (binding !== null && typeof binding === "object") {
|
|
1471
2599
|
const result = {};
|
|
1472
2600
|
for (const [key, value] of Object.entries(binding)) {
|
|
1473
|
-
result[key] = processBinding(value, context);
|
|
2601
|
+
result[key] = processBinding(value, context, itemData);
|
|
1474
2602
|
}
|
|
1475
2603
|
return result;
|
|
1476
2604
|
}
|
|
1477
2605
|
return binding;
|
|
1478
2606
|
}
|
|
1479
|
-
async function resolveBindings(node, context) {
|
|
2607
|
+
async function resolveBindings(node, context, itemData) {
|
|
2608
|
+
const effectiveContext = itemData ? { ...context, item: itemData } : context;
|
|
1480
2609
|
const currentTime = Date.now();
|
|
1481
|
-
const cacheKey = createCacheKey(node.id,
|
|
2610
|
+
const cacheKey = createCacheKey(node.id, effectiveContext);
|
|
1482
2611
|
const cachedNode = bindingsCache.get(cacheKey);
|
|
1483
2612
|
const cachedTimestamp = nodeCacheTimestamps.get(cacheKey);
|
|
1484
2613
|
if (cachedNode && cachedTimestamp && currentTime - cachedTimestamp < CACHE_TTL2) {
|
|
1485
2614
|
return cachedNode;
|
|
1486
2615
|
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
2616
|
+
if (!itemData) {
|
|
2617
|
+
await systemEvents.emit(
|
|
2618
|
+
createSystemEvent("BINDING_RESOLUTION_START" /* BINDING_RESOLUTION_START */, {
|
|
2619
|
+
layout: node
|
|
2620
|
+
})
|
|
2621
|
+
);
|
|
2622
|
+
}
|
|
1492
2623
|
const result = {
|
|
1493
2624
|
...node,
|
|
1494
|
-
props: node.props ?
|
|
1495
|
-
events: node.events ?
|
|
2625
|
+
props: node.props ? JSON.parse(JSON.stringify(node.props)) : null,
|
|
2626
|
+
events: node.events ? JSON.parse(JSON.stringify(node.events)) : null,
|
|
2627
|
+
bindings: node.bindings ? JSON.parse(JSON.stringify(node.bindings)) : null,
|
|
2628
|
+
children: null
|
|
2629
|
+
// Initialize children to null
|
|
1496
2630
|
};
|
|
2631
|
+
const resolvedBindings = {};
|
|
1497
2632
|
if (node.bindings) {
|
|
1498
|
-
for (const [key,
|
|
1499
|
-
const
|
|
1500
|
-
|
|
1501
|
-
|
|
2633
|
+
for (const [key, bindingValue] of Object.entries(node.bindings)) {
|
|
2634
|
+
const resolvedValue = processBinding(bindingValue, context, itemData);
|
|
2635
|
+
resolvedBindings[key] = resolvedValue;
|
|
2636
|
+
if (resolvedValue !== void 0) {
|
|
2637
|
+
if (!result.props)
|
|
1502
2638
|
result.props = {};
|
|
1503
|
-
|
|
1504
|
-
result.props[key] = value;
|
|
2639
|
+
result.props[key] = resolvedValue;
|
|
1505
2640
|
}
|
|
1506
2641
|
}
|
|
1507
2642
|
}
|
|
1508
|
-
|
|
2643
|
+
result.bindings = null;
|
|
2644
|
+
if (node.events) {
|
|
2645
|
+
result.events = processBinding(
|
|
2646
|
+
node.events,
|
|
2647
|
+
context,
|
|
2648
|
+
itemData
|
|
2649
|
+
);
|
|
2650
|
+
} else {
|
|
2651
|
+
result.events = null;
|
|
2652
|
+
}
|
|
2653
|
+
const dataBindingValue = resolvedBindings["data"] ?? resolvedBindings["items"];
|
|
2654
|
+
if ((node.node_type === "ListView" || node.node_type === "Table") && Array.isArray(dataBindingValue) && node.children && node.children.length > 0) {
|
|
2655
|
+
const templateChild = node.children[0];
|
|
2656
|
+
const mappedChildren = await Promise.all(
|
|
2657
|
+
dataBindingValue.map(async (currentItemData, index) => {
|
|
2658
|
+
try {
|
|
2659
|
+
if (typeof currentItemData !== "object" || currentItemData === null) {
|
|
2660
|
+
console.warn(
|
|
2661
|
+
`List item at index ${index} for node ${node.id} is not an object:`,
|
|
2662
|
+
currentItemData
|
|
2663
|
+
);
|
|
2664
|
+
return null;
|
|
2665
|
+
}
|
|
2666
|
+
const currentItemAsRecord = currentItemData;
|
|
2667
|
+
const itemId = currentItemAsRecord.id;
|
|
2668
|
+
const instanceId = `${templateChild.id}-${itemId || index}`;
|
|
2669
|
+
const childNodeInstance = JSON.parse(
|
|
2670
|
+
JSON.stringify(templateChild)
|
|
2671
|
+
);
|
|
2672
|
+
childNodeInstance.id = instanceId;
|
|
2673
|
+
const resolvedChild = await resolveBindings(
|
|
2674
|
+
childNodeInstance,
|
|
2675
|
+
context,
|
|
2676
|
+
currentItemAsRecord
|
|
2677
|
+
);
|
|
2678
|
+
if (!resolvedChild.props)
|
|
2679
|
+
resolvedChild.props = {};
|
|
2680
|
+
resolvedChild.props.key = itemId || `${node.id}-item-${index}`;
|
|
2681
|
+
return resolvedChild;
|
|
2682
|
+
} catch (error) {
|
|
2683
|
+
console.error(
|
|
2684
|
+
`[resolveBindings Error] Error processing item at index ${index} for node ${node.id}:`,
|
|
2685
|
+
error,
|
|
2686
|
+
"Item Data:",
|
|
2687
|
+
currentItemData
|
|
2688
|
+
);
|
|
2689
|
+
return null;
|
|
2690
|
+
}
|
|
2691
|
+
})
|
|
2692
|
+
);
|
|
2693
|
+
result.children = mappedChildren.filter(
|
|
2694
|
+
(child) => child !== null
|
|
2695
|
+
);
|
|
2696
|
+
} else if (node.children && node.children.length > 0) {
|
|
1509
2697
|
result.children = await Promise.all(
|
|
1510
|
-
node.children.map((child) => resolveBindings(child, context))
|
|
2698
|
+
node.children.map((child) => resolveBindings(child, context, itemData))
|
|
2699
|
+
);
|
|
2700
|
+
} else {
|
|
2701
|
+
result.children = [];
|
|
2702
|
+
}
|
|
2703
|
+
if (!itemData) {
|
|
2704
|
+
await systemEvents.emit(
|
|
2705
|
+
createSystemEvent("BINDING_RESOLUTION_COMPLETE" /* BINDING_RESOLUTION_COMPLETE */, {
|
|
2706
|
+
originalLayout: node,
|
|
2707
|
+
resolvedLayout: result
|
|
2708
|
+
})
|
|
1511
2709
|
);
|
|
1512
2710
|
}
|
|
1513
|
-
await systemEvents.emit(
|
|
1514
|
-
createSystemEvent("BINDING_RESOLUTION_COMPLETE" /* BINDING_RESOLUTION_COMPLETE */, {
|
|
1515
|
-
originalLayout: node,
|
|
1516
|
-
resolvedLayout: result
|
|
1517
|
-
})
|
|
1518
|
-
);
|
|
1519
2711
|
bindingsCache.set(cacheKey, result);
|
|
1520
2712
|
nodeCacheTimestamps.set(cacheKey, currentTime);
|
|
1521
2713
|
if (bindingsCache.size > MAX_CACHE_SIZE2) {
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
2714
|
+
let oldestKey = null;
|
|
2715
|
+
let oldestTimestamp = currentTime;
|
|
2716
|
+
for (const [key, timestamp] of nodeCacheTimestamps.entries()) {
|
|
2717
|
+
if (timestamp < oldestTimestamp) {
|
|
2718
|
+
oldestTimestamp = timestamp;
|
|
2719
|
+
oldestKey = key;
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
if (oldestKey) {
|
|
1526
2723
|
bindingsCache.delete(oldestKey);
|
|
1527
2724
|
nodeCacheTimestamps.delete(oldestKey);
|
|
1528
2725
|
}
|
|
@@ -1655,6 +2852,31 @@ function getMissingComponentsMessage() {
|
|
|
1655
2852
|
return `Missing required shadcn components. Please run:
|
|
1656
2853
|
> npm run setup-shadcn`;
|
|
1657
2854
|
}
|
|
2855
|
+
function correctListBindingsRecursive(node, dataContext) {
|
|
2856
|
+
const correctedNode = JSON.parse(JSON.stringify(node));
|
|
2857
|
+
if ((correctedNode.node_type === "ListView" || correctedNode.node_type === "Table") && correctedNode.bindings?.data) {
|
|
2858
|
+
const bindingPath = correctedNode.bindings.data;
|
|
2859
|
+
if (typeof bindingPath === "string") {
|
|
2860
|
+
const pathSegments = bindingPath.split(".");
|
|
2861
|
+
const mainKey = pathSegments[0];
|
|
2862
|
+
if (pathSegments.length === 1) {
|
|
2863
|
+
const potentialDataContextEntry = dataContext[mainKey];
|
|
2864
|
+
if (potentialDataContextEntry && typeof potentialDataContextEntry === "object" && potentialDataContextEntry !== null && "data" in potentialDataContextEntry && Array.isArray(potentialDataContextEntry.data)) {
|
|
2865
|
+
correctedNode.bindings.data = `${mainKey}.data`;
|
|
2866
|
+
console.log(
|
|
2867
|
+
`[AutoUI Debug] Corrected list binding for node '${correctedNode.id}': from '${mainKey}' to '${mainKey}.data'`
|
|
2868
|
+
);
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
if (correctedNode.children) {
|
|
2874
|
+
correctedNode.children = correctedNode.children.map(
|
|
2875
|
+
(child) => correctListBindingsRecursive(child, dataContext)
|
|
2876
|
+
);
|
|
2877
|
+
}
|
|
2878
|
+
return correctedNode;
|
|
2879
|
+
}
|
|
1658
2880
|
var AutoUI = ({
|
|
1659
2881
|
schema,
|
|
1660
2882
|
goal,
|
|
@@ -1664,11 +2886,12 @@ var AutoUI = ({
|
|
|
1664
2886
|
eventHooks,
|
|
1665
2887
|
systemEventHooks,
|
|
1666
2888
|
debugMode = false,
|
|
1667
|
-
mockMode =
|
|
2889
|
+
mockMode = false,
|
|
1668
2890
|
planningConfig,
|
|
1669
2891
|
integration = {},
|
|
1670
2892
|
scope = {},
|
|
1671
|
-
enablePartialUpdates = false
|
|
2893
|
+
enablePartialUpdates = false,
|
|
2894
|
+
openaiApiKey
|
|
1672
2895
|
}) => {
|
|
1673
2896
|
const [schemaAdapterInstance] = React.useState(null);
|
|
1674
2897
|
const [dataContext, setDataContext] = React.useState({});
|
|
@@ -1740,7 +2963,8 @@ var AutoUI = ({
|
|
|
1740
2963
|
planningConfig,
|
|
1741
2964
|
router: void 0,
|
|
1742
2965
|
dataContext,
|
|
1743
|
-
enablePartialUpdates
|
|
2966
|
+
enablePartialUpdates,
|
|
2967
|
+
openaiApiKey
|
|
1744
2968
|
});
|
|
1745
2969
|
const eventManagerRef = React.useRef(new EventManager());
|
|
1746
2970
|
React.useEffect(() => {
|
|
@@ -1840,13 +3064,29 @@ var AutoUI = ({
|
|
|
1840
3064
|
null
|
|
1841
3065
|
);
|
|
1842
3066
|
const resolveLayoutBindings = React.useCallback(async () => {
|
|
1843
|
-
if (state.layout) {
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
3067
|
+
if (state.layout && dataContext) {
|
|
3068
|
+
console.log(
|
|
3069
|
+
"[AutoUI Debug] DataContext before resolving bindings:",
|
|
3070
|
+
JSON.stringify(dataContext, null, 2)
|
|
3071
|
+
);
|
|
3072
|
+
console.log(
|
|
3073
|
+
"[AutoUI Debug] Raw layout before resolving (from planner):",
|
|
3074
|
+
JSON.stringify(state.layout, null, 2)
|
|
3075
|
+
);
|
|
3076
|
+
const correctedLayout = correctListBindingsRecursive(
|
|
3077
|
+
state.layout,
|
|
3078
|
+
dataContext
|
|
3079
|
+
);
|
|
3080
|
+
console.log(
|
|
3081
|
+
"[AutoUI Debug] Layout after binding correction (before resolving):",
|
|
3082
|
+
JSON.stringify(correctedLayout, null, 2)
|
|
3083
|
+
);
|
|
3084
|
+
const resolved = await resolveBindings(correctedLayout, dataContext);
|
|
3085
|
+
setResolvedLayout(resolved);
|
|
3086
|
+
console.log(
|
|
3087
|
+
"[AutoUI Debug] Resolved layout after bindings:",
|
|
3088
|
+
JSON.stringify(resolved, null, 2)
|
|
3089
|
+
);
|
|
1850
3090
|
} else {
|
|
1851
3091
|
setResolvedLayout(void 0);
|
|
1852
3092
|
}
|
|
@@ -2053,12 +3293,23 @@ var generateUIComponent = async (prompt) => {
|
|
|
2053
3293
|
return `<div>Generated UI Component for: ${prompt}</div>`;
|
|
2054
3294
|
};
|
|
2055
3295
|
function usePlanner(options) {
|
|
2056
|
-
const {
|
|
2057
|
-
|
|
3296
|
+
const {
|
|
3297
|
+
schema,
|
|
3298
|
+
goal,
|
|
3299
|
+
openaiApiKey,
|
|
3300
|
+
userContext,
|
|
3301
|
+
initialLayout,
|
|
3302
|
+
mockMode: optionsMockMode
|
|
3303
|
+
} = options;
|
|
3304
|
+
const [layout, setLayout] = React.useState(
|
|
3305
|
+
initialLayout || void 0
|
|
3306
|
+
);
|
|
2058
3307
|
const [loading, setLoading] = React.useState(false);
|
|
2059
3308
|
const [error, setError] = React.useState(null);
|
|
2060
|
-
const router =
|
|
3309
|
+
const router = options.router || createDefaultRouter();
|
|
2061
3310
|
const dataContext = {};
|
|
3311
|
+
const initialFetchAttempted = React.useRef(false);
|
|
3312
|
+
const mockMode = optionsMockMode || !openaiApiKey;
|
|
2062
3313
|
const generateInitialLayout = React.useCallback(async () => {
|
|
2063
3314
|
setLoading(true);
|
|
2064
3315
|
setError(null);
|
|
@@ -2069,14 +3320,26 @@ function usePlanner(options) {
|
|
|
2069
3320
|
userContext: userContext || null,
|
|
2070
3321
|
history: null
|
|
2071
3322
|
};
|
|
2072
|
-
|
|
3323
|
+
let generatedLayout;
|
|
3324
|
+
if (mockMode) {
|
|
3325
|
+
console.warn(
|
|
3326
|
+
"Using mock planner in usePlanner hook (mockMode enabled or API key missing)."
|
|
3327
|
+
);
|
|
3328
|
+
generatedLayout = mockPlanner(plannerInput2);
|
|
3329
|
+
} else {
|
|
3330
|
+
generatedLayout = await callPlannerLLM(
|
|
3331
|
+
plannerInput2,
|
|
3332
|
+
openaiApiKey,
|
|
3333
|
+
void 0
|
|
3334
|
+
);
|
|
3335
|
+
}
|
|
2073
3336
|
setLayout(generatedLayout);
|
|
2074
3337
|
} catch (err) {
|
|
2075
3338
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
2076
3339
|
} finally {
|
|
2077
3340
|
setLoading(false);
|
|
2078
3341
|
}
|
|
2079
|
-
}, [schema, goal, userContext]);
|
|
3342
|
+
}, [schema, goal, userContext, openaiApiKey, mockMode]);
|
|
2080
3343
|
const handleEvent = React.useCallback(
|
|
2081
3344
|
async (event) => {
|
|
2082
3345
|
if (!layout) {
|
|
@@ -2093,7 +3356,8 @@ function usePlanner(options) {
|
|
|
2093
3356
|
layout,
|
|
2094
3357
|
dataContext,
|
|
2095
3358
|
goal,
|
|
2096
|
-
userContext
|
|
3359
|
+
userContext,
|
|
3360
|
+
openaiApiKey
|
|
2097
3361
|
);
|
|
2098
3362
|
setLayout(updatedLayout);
|
|
2099
3363
|
} catch (err) {
|
|
@@ -2102,8 +3366,14 @@ function usePlanner(options) {
|
|
|
2102
3366
|
setLoading(false);
|
|
2103
3367
|
}
|
|
2104
3368
|
},
|
|
2105
|
-
[layout, router, schema, dataContext, goal, userContext]
|
|
3369
|
+
[layout, router, schema, dataContext, goal, userContext, openaiApiKey]
|
|
2106
3370
|
);
|
|
3371
|
+
React.useEffect(() => {
|
|
3372
|
+
if (options.initialLayout === void 0 && layout === void 0 && !initialFetchAttempted.current) {
|
|
3373
|
+
initialFetchAttempted.current = true;
|
|
3374
|
+
generateInitialLayout();
|
|
3375
|
+
}
|
|
3376
|
+
}, [options.initialLayout, layout, generateInitialLayout]);
|
|
2107
3377
|
return {
|
|
2108
3378
|
layout,
|
|
2109
3379
|
loading,
|