@object-ui/app-shell 11.3.0 → 11.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +522 -0
  2. package/README.md +23 -0
  3. package/dist/console/ConsoleShell.js +17 -2
  4. package/dist/console/home/CloudOnboardingNext.d.ts +9 -0
  5. package/dist/console/home/CloudOnboardingNext.js +14 -4
  6. package/dist/console/home/HomePage.js +34 -7
  7. package/dist/console/organizations/CreateWorkspaceDialog.js +33 -3
  8. package/dist/console/organizations/OrganizationsPage.js +16 -7
  9. package/dist/hooks/useConsoleActionRuntime.js +32 -3
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.js +3 -0
  12. package/dist/preview/DraftChangesPanel.d.ts +3 -1
  13. package/dist/preview/DraftChangesPanel.js +6 -5
  14. package/dist/utils/deriveRelatedLists.d.ts +20 -5
  15. package/dist/utils/deriveRelatedLists.js +31 -13
  16. package/dist/utils/resolveViewId.d.ts +23 -0
  17. package/dist/utils/resolveViewId.js +37 -0
  18. package/dist/utils/warnSuppressedListNav.d.ts +10 -0
  19. package/dist/utils/warnSuppressedListNav.js +40 -0
  20. package/dist/views/InterfaceListPage.js +6 -4
  21. package/dist/views/ObjectView.js +61 -10
  22. package/dist/views/RecordDetailView.js +131 -104
  23. package/dist/views/RecordFormPage.js +7 -1
  24. package/dist/views/RelatedRecordActionsBridge.d.ts +24 -0
  25. package/dist/views/RelatedRecordActionsBridge.js +114 -0
  26. package/dist/views/metadata-admin/PackagesPage.js +18 -7
  27. package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +18 -1
  28. package/dist/views/metadata-admin/PermissionMatrixEditor.js +73 -14
  29. package/dist/views/metadata-admin/i18n.d.ts +12 -21
  30. package/dist/views/metadata-admin/i18n.js +343 -2
  31. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +25 -11
  32. package/dist/views/metadata-admin/permission-slice.d.ts +66 -0
  33. package/dist/views/metadata-admin/permission-slice.js +70 -0
  34. package/dist/views/metadata-admin/previews/AppNavCanvas.js +11 -7
  35. package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +16 -7
  36. package/dist/views/metadata-admin/previews/FlowRunsPanel.js +18 -2
  37. package/dist/views/studio-design/BuilderLanding.d.ts +15 -0
  38. package/dist/views/studio-design/BuilderLanding.js +133 -0
  39. package/dist/views/studio-design/ObjectFormDesigner.d.ts +31 -0
  40. package/dist/views/studio-design/ObjectFormDesigner.js +226 -0
  41. package/dist/views/studio-design/ObjectSettingsPanel.d.ts +30 -0
  42. package/dist/views/studio-design/ObjectSettingsPanel.js +45 -0
  43. package/dist/views/studio-design/ObjectValidationsPanel.d.ts +30 -0
  44. package/dist/views/studio-design/ObjectValidationsPanel.js +78 -0
  45. package/dist/views/studio-design/StudioDesignSurface.js +793 -146
  46. package/dist/views/studio-design/metadataError.d.ts +23 -0
  47. package/dist/views/studio-design/metadataError.js +44 -0
  48. package/dist/views/studio-design/packages-io.d.ts +27 -0
  49. package/dist/views/studio-design/packages-io.js +61 -0
  50. package/package.json +42 -39
@@ -0,0 +1,78 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ObjectUI
4
+ * Copyright (c) 2024-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ /**
10
+ * Data pillar — Validations view (builder-ui Phase B).
11
+ *
12
+ * Edits `ObjectSchema.validations` (spec `ValidationRuleSchema`, a
13
+ * discriminated union on `type`). The no-code surface targets the `script`
14
+ * rule — `{ type: 'script', name, message, condition }` where the CEL
15
+ * `condition` is a FAIL predicate (TRUE ⇒ the write is rejected with
16
+ * `message`). The condition editor reuses the metadata-admin
17
+ * `ConditionBuilder`, fed with the DRAFT field list so unpublished fields
18
+ * are pickable.
19
+ *
20
+ * Non-`script` rule types (state_machine / format / cross_field / json /
21
+ * conditional) are surfaced read-only with their type badge — they carry
22
+ * structures a row editor can't honestly express; authoring them stays in
23
+ * code for now. Showing them (rather than hiding) keeps the list a truthful
24
+ * inventory of everything that will run on save.
25
+ */
26
+ import React from 'react';
27
+ import { Plus, Trash2, ShieldAlert } from 'lucide-react';
28
+ import { ConditionBuilder } from '../metadata-admin/inspectors/ConditionBuilder';
29
+ import { readFields } from '../metadata-admin/previews/object-fields-io';
30
+ function readRules(input) {
31
+ if (!Array.isArray(input))
32
+ return [];
33
+ return input.filter((r) => !!r && typeof r === 'object');
34
+ }
35
+ function nextRuleName(existing) {
36
+ let i = existing.length + 1;
37
+ let name = `validation_${i}`;
38
+ const taken = new Set(existing);
39
+ while (taken.has(name))
40
+ name = `validation_${++i}`;
41
+ return name;
42
+ }
43
+ export function ObjectValidationsPanel({ draft, onPatch, disabled, }) {
44
+ const rules = readRules(draft.validations);
45
+ const [selected, setSelected] = React.useState(null);
46
+ const fields = React.useMemo(() => readFields(draft.fields).entries.map((e) => ({
47
+ name: e.name,
48
+ label: typeof e.def.label === 'string' ? e.def.label : undefined,
49
+ hidden: e.def.hidden === true,
50
+ })), [draft.fields]);
51
+ const commit = (next) => onPatch({ validations: next });
52
+ const patchRule = (name, patch) => commit(rules.map((r) => (r.name === name ? { ...r, ...patch } : r)));
53
+ const addRule = () => {
54
+ const name = nextRuleName(rules.map((r) => r.name ?? ''));
55
+ // `condition: 'false'` — a VALID never-failing CEL placeholder. An empty
56
+ // condition is rejected by the spec's ExpressionInputSchema, which would
57
+ // 422 the whole draft save and dead-end the create flow (the same
58
+ // required-field-blocks-authoring class as dashboard `layout` / page
59
+ // `regions`). A rule that never fires is safe to save mid-authoring.
60
+ commit([...rules, { type: 'script', name, message: '', condition: 'false', severity: 'error' }]);
61
+ setSelected(name);
62
+ };
63
+ const removeRule = (name) => {
64
+ commit(rules.filter((r) => r.name !== name));
65
+ if (selected === name)
66
+ setSelected(null);
67
+ };
68
+ const sel = rules.find((r) => r.name === selected) ?? null;
69
+ return (_jsxs("div", { className: "flex min-h-0 flex-1 gap-4", children: [_jsxs("div", { className: "flex w-72 shrink-0 flex-col rounded-lg border", children: [_jsxs("header", { className: "flex items-center gap-2 border-b px-3 py-2", children: [_jsx(ShieldAlert, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-[13px] font-medium", children: "\u9A8C\u8BC1\u89C4\u5219" }), _jsxs("span", { className: "text-[11px] text-muted-foreground", children: ["(", rules.length, ")"] }), !disabled && (_jsxs("button", { type: "button", onClick: addRule, className: "ml-auto inline-flex items-center gap-1 rounded border px-1.5 py-0.5 text-[11px] hover:bg-muted", children: [_jsx(Plus, { className: "h-3 w-3" }), " \u65B0\u589E"] }))] }), _jsx("div", { className: "min-h-0 flex-1 overflow-auto", children: rules.length === 0 ? (_jsxs("p", { className: "px-3 py-6 text-center text-[11px] leading-5 text-muted-foreground", children: ["\u8FD8\u6CA1\u6709\u9A8C\u8BC1\u89C4\u5219\u3002", _jsx("br", {}), "\u89C4\u5219\u5728\u4FDD\u5B58\u8BB0\u5F55\u65F6\u6267\u884C:\u6761\u4EF6\u4E3A\u771F \u21D2 \u62D2\u7EDD\u4FDD\u5B58\u5E76\u63D0\u793A\u6D88\u606F\u3002"] })) : (rules.map((r) => (_jsxs("button", { type: "button", onClick: () => setSelected(r.name ?? null), className: 'flex w-full items-start gap-2 border-b px-3 py-2 text-left text-[12px] ' +
70
+ (selected === r.name ? 'bg-muted' : 'hover:bg-muted/50'), children: [_jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate font-medium", children: r.label || r.name }), _jsx("span", { className: "block truncate text-[11px] text-muted-foreground", children: r.message || '(无消息)' })] }), _jsx("span", { className: 'shrink-0 rounded-full px-1.5 py-0.5 text-[10px] ' +
71
+ (r.type === 'script'
72
+ ? 'bg-primary/10 text-primary'
73
+ : 'bg-muted text-muted-foreground'), children: r.type ?? 'script' })] }, r.name)))) })] }), _jsx("div", { className: "flex min-w-0 flex-1 flex-col rounded-lg border", children: !sel ? (_jsx("div", { className: "flex flex-1 items-center justify-center p-6 text-center text-[12px] text-muted-foreground", children: "\u9009\u62E9\u5DE6\u4FA7\u7684\u89C4\u5219\u8FDB\u884C\u7F16\u8F91,\u6216\u70B9\u300C\u65B0\u589E\u300D\u521B\u5EFA\u4E00\u6761\u3002" })) : sel.type !== 'script' ? (_jsxs("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [_jsxs("p", { className: "text-[13px] font-medium", children: [sel.label || sel.name, _jsx("span", { className: "ml-2 rounded-full bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground", children: sel.type })] }), _jsxs("p", { className: "text-[12px] leading-5 text-muted-foreground", children: ["\u300C", sel.type, "\u300D\u7C7B\u578B\u7684\u89C4\u5219\u5E26\u6709\u7ED3\u6784\u5316\u914D\u7F6E(\u72B6\u6001\u673A\u8F6C\u79FB\u8868 / \u683C\u5F0F\u7EA6\u675F\u7B49),\u6682\u4E0D\u652F\u6301\u5728\u6B64\u7F16\u8F91 \u2014\u2014 \u8BF7\u5728\u4EE3\u7801\u5305\u4E2D\u7EF4\u62A4\u3002\u6D88\u606F:", sel.message || '(无)'] }), !disabled && (_jsxs("button", { type: "button", onClick: () => removeRule(sel.name), className: "mt-auto inline-flex w-fit items-center gap-1 rounded border border-destructive/40 px-2 py-1 text-[11px] text-destructive hover:bg-destructive/10", children: [_jsx(Trash2, { className: "h-3 w-3" }), " \u5220\u9664\u89C4\u5219"] }))] })) : (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-auto p-4", children: [_jsxs("label", { className: "block", children: [_jsx("span", { className: "mb-1 block text-[11px] text-muted-foreground", children: "\u89C4\u5219\u540D(snake_case,\u552F\u4E00)" }), _jsx("input", { value: sel.name ?? '', disabled: disabled, onChange: (e) => {
74
+ const name = e.target.value;
75
+ patchRule(sel.name, { name });
76
+ setSelected(name);
77
+ }, className: "w-full rounded border bg-background px-2 py-1 text-[12px]" })] }), _jsxs("label", { className: "block", children: [_jsx("span", { className: "mb-1 block text-[11px] text-muted-foreground", children: "\u9519\u8BEF\u6D88\u606F(\u6821\u9A8C\u5931\u8D25\u65F6\u5C55\u793A\u7ED9\u7528\u6237)" }), _jsx("input", { value: sel.message ?? '', disabled: disabled, onChange: (e) => patchRule(sel.name, { message: e.target.value }), placeholder: "\u4F8B\u5982:\u5B8C\u6210\u65E5\u671F\u5728\u72B6\u6001\u4E3A\u5DF2\u5B8C\u6210\u65F6\u5FC5\u586B", className: "w-full rounded border bg-background px-2 py-1 text-[12px]" })] }), _jsxs("div", { children: [_jsxs("span", { className: "mb-1 block text-[11px] text-muted-foreground", children: ["\u5931\u8D25\u6761\u4EF6(CEL)\u2014\u2014 \u6761\u4EF6\u4E3A ", _jsx("b", { children: "\u771F" }), " \u65F6,\u62D2\u7EDD\u4FDD\u5B58\u5E76\u663E\u793A\u4E0A\u9762\u7684\u6D88\u606F;\u65B0\u89C4\u5219\u9ED8\u8BA4", ' ', _jsx("code", { className: "rounded bg-muted px-1", children: "false" }), "(\u6C38\u4E0D\u89E6\u53D1),\u8BF7\u6539\u4E3A\u771F\u5B9E\u6761\u4EF6"] }), _jsx(ConditionBuilder, { value: typeof sel.condition === 'string' ? sel.condition : '', onCommit: (cel) => patchRule(sel.name, { condition: cel }), fields: fields, disabled: disabled })] }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("label", { className: "flex items-center gap-1.5 text-[12px]", children: [_jsx("span", { className: "text-muted-foreground", children: "\u4E25\u91CD\u5EA6" }), _jsxs("select", { value: sel.severity ?? 'error', disabled: disabled, onChange: (e) => patchRule(sel.name, { severity: e.target.value }), className: "rounded border bg-background px-1.5 py-0.5 text-[12px]", children: [_jsx("option", { value: "error", children: "error(\u62D2\u7EDD\u4FDD\u5B58)" }), _jsx("option", { value: "warning", children: "warning" }), _jsx("option", { value: "info", children: "info" })] })] }), _jsxs("label", { className: "flex items-center gap-1.5 text-[12px]", children: [_jsx("input", { type: "checkbox", checked: sel.active !== false, disabled: disabled, onChange: (e) => patchRule(sel.name, { active: e.target.checked }) }), "\u542F\u7528"] }), !disabled && (_jsxs("button", { type: "button", onClick: () => removeRule(sel.name), className: "ml-auto inline-flex items-center gap-1 rounded border border-destructive/40 px-2 py-1 text-[11px] text-destructive hover:bg-destructive/10", children: [_jsx(Trash2, { className: "h-3 w-3" }), " \u5220\u9664"] }))] })] })) })] }));
78
+ }