@tai42/studio-sdk 30.0.1 → 31.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -10
- package/dist/components/agent-picker.d.ts +1 -1
- package/dist/components/agent-picker.d.ts.map +1 -1
- package/dist/components/agent-picker.js +1 -0
- package/dist/components/agent-picker.js.map +1 -1
- package/dist/components/channel-picker.d.ts +1 -1
- package/dist/components/channel-picker.d.ts.map +1 -1
- package/dist/components/channel-picker.js +1 -0
- package/dist/components/channel-picker.js.map +1 -1
- package/dist/components/components.css +53 -0
- package/dist/components/explorer-body.d.ts +1 -0
- package/dist/components/explorer-body.d.ts.map +1 -1
- package/dist/components/explorer-body.js +6 -4
- package/dist/components/explorer-body.js.map +1 -1
- package/dist/components/explorer-view.d.ts +16 -7
- package/dist/components/explorer-view.d.ts.map +1 -1
- package/dist/components/explorer-view.js +27 -13
- package/dist/components/explorer-view.js.map +1 -1
- package/dist/components/extension-config-editor.js.map +1 -1
- package/dist/components/field.d.ts +6 -0
- package/dist/components/field.d.ts.map +1 -1
- package/dist/components/field.js +15 -2
- package/dist/components/field.js.map +1 -1
- package/dist/components/folder-actions.d.ts +51 -0
- package/dist/components/folder-actions.d.ts.map +1 -0
- package/dist/components/folder-actions.js +173 -0
- package/dist/components/folder-actions.js.map +1 -0
- package/dist/components/folder-filing.d.ts +32 -0
- package/dist/components/folder-filing.d.ts.map +1 -0
- package/dist/components/folder-filing.js +51 -0
- package/dist/components/folder-filing.js.map +1 -0
- package/dist/components/folder-nav.d.ts +9 -4
- package/dist/components/folder-nav.d.ts.map +1 -1
- package/dist/components/folder-nav.js +18 -22
- package/dist/components/folder-nav.js.map +1 -1
- package/dist/components/folder-occupancy.d.ts +27 -0
- package/dist/components/folder-occupancy.d.ts.map +1 -0
- package/dist/components/folder-occupancy.js +54 -0
- package/dist/components/folder-occupancy.js.map +1 -0
- package/dist/components/named-list-picker.d.ts +5 -3
- package/dist/components/named-list-picker.d.ts.map +1 -1
- package/dist/components/named-list-picker.js +7 -7
- package/dist/components/named-list-picker.js.map +1 -1
- package/dist/components/primitives.d.ts +2 -1
- package/dist/components/primitives.d.ts.map +1 -1
- package/dist/components/primitives.js +2 -1
- package/dist/components/primitives.js.map +1 -1
- package/dist/components/searchable-select-model.d.ts +40 -0
- package/dist/components/searchable-select-model.d.ts.map +1 -0
- package/dist/components/searchable-select-model.js +69 -0
- package/dist/components/searchable-select-model.js.map +1 -0
- package/dist/components/searchable-select.d.ts +38 -0
- package/dist/components/searchable-select.d.ts.map +1 -0
- package/dist/components/searchable-select.js +200 -0
- package/dist/components/searchable-select.js.map +1 -0
- package/dist/components/subject-section.d.ts.map +1 -1
- package/dist/components/subject-section.js +2 -2
- package/dist/components/subject-section.js.map +1 -1
- package/dist/components/table.d.ts +7 -1
- package/dist/components/table.d.ts.map +1 -1
- package/dist/components/table.js +2 -2
- package/dist/components/table.js.map +1 -1
- package/dist/components/tool-meta-access.d.ts +28 -0
- package/dist/components/tool-meta-access.d.ts.map +1 -0
- package/dist/components/tool-meta-access.js +65 -0
- package/dist/components/tool-meta-access.js.map +1 -0
- package/dist/components/tool-name-entry.d.ts +26 -0
- package/dist/components/tool-name-entry.d.ts.map +1 -0
- package/dist/components/tool-name-entry.js +43 -0
- package/dist/components/tool-name-entry.js.map +1 -0
- package/dist/components/tool-picker.d.ts +23 -18
- package/dist/components/tool-picker.d.ts.map +1 -1
- package/dist/components/tool-picker.js +51 -33
- package/dist/components/tool-picker.js.map +1 -1
- package/dist/components/tool-select.d.ts +6 -5
- package/dist/components/tool-select.d.ts.map +1 -1
- package/dist/components/tool-select.js +31 -14
- package/dist/components/tool-select.js.map +1 -1
- package/dist/hooks/useApi.d.ts +1 -0
- package/dist/hooks/useApi.d.ts.map +1 -1
- package/dist/hooks/useSystemKinds.d.ts +27 -12
- package/dist/hooks/useSystemKinds.d.ts.map +1 -1
- package/dist/hooks/useSystemKinds.js +56 -16
- package/dist/hooks/useSystemKinds.js.map +1 -1
- package/dist/index.d.ts +51 -49
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -26
- package/dist/index.js.map +1 -1
- package/dist/marketplace-install/use-mount-install.d.ts +6 -6
- package/dist/plugin/version.d.ts +1 -1
- package/dist/plugin/version.js +1 -1
- package/dist/schema-editor/SchemaEditor.d.ts +7 -2
- package/dist/schema-editor/SchemaEditor.d.ts.map +1 -1
- package/dist/schema-editor/SchemaEditor.js +1 -1
- package/dist/schema-editor/SchemaEditor.js.map +1 -1
- package/dist/schema-editor/index.d.ts +2 -2
- package/dist/schema-editor/index.d.ts.map +1 -1
- package/dist/schema-form/array-field.d.ts.map +1 -1
- package/dist/schema-form/array-field.js +6 -2
- package/dist/schema-form/array-field.js.map +1 -1
- package/dist/schema-form/classify.d.ts +4 -1
- package/dist/schema-form/classify.d.ts.map +1 -1
- package/dist/schema-form/classify.js +36 -15
- package/dist/schema-form/classify.js.map +1 -1
- package/dist/schema-form/collapsed-object-field.d.ts +20 -0
- package/dist/schema-form/collapsed-object-field.d.ts.map +1 -0
- package/dist/schema-form/collapsed-object-field.js +14 -0
- package/dist/schema-form/collapsed-object-field.js.map +1 -0
- package/dist/schema-form/context.d.ts +27 -1
- package/dist/schema-form/context.d.ts.map +1 -1
- package/dist/schema-form/context.js +14 -0
- package/dist/schema-form/context.js.map +1 -1
- package/dist/schema-form/default-value.d.ts +21 -6
- package/dist/schema-form/default-value.d.ts.map +1 -1
- package/dist/schema-form/default-value.js +74 -15
- package/dist/schema-form/default-value.js.map +1 -1
- package/dist/schema-form/expression-field.d.ts +48 -0
- package/dist/schema-form/expression-field.d.ts.map +1 -0
- package/dist/schema-form/expression-field.js +88 -0
- package/dist/schema-form/expression-field.js.map +1 -0
- package/dist/schema-form/field-model.d.ts +23 -4
- package/dist/schema-form/field-model.d.ts.map +1 -1
- package/dist/schema-form/field-node.d.ts.map +1 -1
- package/dist/schema-form/field-node.js +16 -3
- package/dist/schema-form/field-node.js.map +1 -1
- package/dist/schema-form/index.d.ts +3 -3
- package/dist/schema-form/index.d.ts.map +1 -1
- package/dist/schema-form/index.js +2 -2
- package/dist/schema-form/index.js.map +1 -1
- package/dist/schema-form/object-fields.d.ts +6 -3
- package/dist/schema-form/object-fields.d.ts.map +1 -1
- package/dist/schema-form/object-fields.js +14 -3
- package/dist/schema-form/object-fields.js.map +1 -1
- package/dist/schema-form/record-field.d.ts.map +1 -1
- package/dist/schema-form/record-field.js +6 -2
- package/dist/schema-form/record-field.js.map +1 -1
- package/dist/schema-form/seeding-action.d.ts +15 -0
- package/dist/schema-form/seeding-action.d.ts.map +1 -0
- package/dist/schema-form/seeding-action.js +35 -0
- package/dist/schema-form/seeding-action.js.map +1 -0
- package/dist/schema-form/string-annotations.d.ts +22 -8
- package/dist/schema-form/string-annotations.d.ts.map +1 -1
- package/dist/schema-form/string-annotations.js +39 -14
- package/dist/schema-form/string-annotations.js.map +1 -1
- package/dist/schema-form/string-field.js +2 -84
- package/dist/schema-form/string-field.js.map +1 -1
- package/dist/schema-form/templated-field.d.ts +13 -0
- package/dist/schema-form/templated-field.d.ts.map +1 -0
- package/dist/schema-form/templated-field.js +43 -0
- package/dist/schema-form/templated-field.js.map +1 -0
- package/dist/schema-form/union-field.d.ts.map +1 -1
- package/dist/schema-form/union-field.js +6 -2
- package/dist/schema-form/union-field.js.map +1 -1
- package/dist/schema-form/union.d.ts +4 -4
- package/dist/schema-form/union.d.ts.map +1 -1
- package/dist/schema-form/union.js +8 -1
- package/dist/schema-form/union.js.map +1 -1
- package/dist/schema-form/validate.d.ts.map +1 -1
- package/dist/schema-form/validate.js +28 -0
- package/dist/schema-form/validate.js.map +1 -1
- package/dist/search-match.d.ts +29 -0
- package/dist/search-match.d.ts.map +1 -0
- package/dist/search-match.js +38 -0
- package/dist/search-match.js.map +1 -0
- package/dist/tool-organization.d.ts +15 -0
- package/dist/tool-organization.d.ts.map +1 -0
- package/dist/tool-organization.js +6 -0
- package/dist/tool-organization.js.map +1 -0
- package/package.json +3 -2
- package/src/components/agent-picker.tsx +2 -1
- package/src/components/channel-picker.tsx +2 -1
- package/src/components/components.css +53 -0
- package/src/components/explorer-body.tsx +29 -5
- package/src/components/explorer-view.tsx +48 -17
- package/src/components/extension-config-editor.tsx +3 -3
- package/src/components/field.tsx +18 -2
- package/src/components/folder-actions.tsx +341 -0
- package/src/components/folder-filing.tsx +109 -0
- package/src/components/folder-nav.tsx +26 -10
- package/src/components/folder-occupancy.ts +83 -0
- package/src/components/named-list-picker.tsx +11 -7
- package/src/components/primitives.tsx +2 -1
- package/src/components/searchable-select-model.ts +105 -0
- package/src/components/searchable-select.tsx +432 -0
- package/src/components/subject-section.tsx +3 -2
- package/src/components/table.tsx +12 -2
- package/src/components/tool-meta-access.tsx +101 -0
- package/src/components/tool-name-entry.tsx +77 -0
- package/src/components/tool-picker.tsx +83 -50
- package/src/components/tool-select.tsx +49 -38
- package/src/hooks/useSystemKinds.tsx +77 -17
- package/src/index.ts +98 -94
- package/src/plugin/version.ts +1 -1
- package/src/schema-editor/SchemaEditor.tsx +9 -3
- package/src/schema-editor/index.ts +2 -2
- package/src/schema-form/array-field.tsx +10 -2
- package/src/schema-form/classify.ts +41 -15
- package/src/schema-form/collapsed-object-field.tsx +56 -0
- package/src/schema-form/context.ts +33 -1
- package/src/schema-form/default-value.ts +89 -15
- package/src/schema-form/expression-field.tsx +162 -0
- package/src/schema-form/field-model.ts +27 -4
- package/src/schema-form/field-node.tsx +41 -2
- package/src/schema-form/index.ts +3 -2
- package/src/schema-form/object-fields.tsx +11 -4
- package/src/schema-form/record-field.tsx +10 -2
- package/src/schema-form/seeding-action.ts +44 -0
- package/src/schema-form/string-annotations.ts +40 -14
- package/src/schema-form/string-field.tsx +2 -147
- package/src/schema-form/templated-field.tsx +124 -0
- package/src/schema-form/union-field.tsx +11 -2
- package/src/schema-form/union.ts +12 -5
- package/src/schema-form/validate.ts +28 -0
- package/src/search-match.ts +41 -0
- package/src/tool-organization.ts +34 -0
|
@@ -24,6 +24,12 @@ export interface FieldControlProps {
|
|
|
24
24
|
* expose its invalid state.
|
|
25
25
|
*/
|
|
26
26
|
export declare function useFieldControl(): FieldControlProps;
|
|
27
|
+
/**
|
|
28
|
+
* The id of the enclosing Field's label while it names one control, else `undefined`.
|
|
29
|
+
* A control whose popup holds a second labelled surface (a listbox, a dialog) points
|
|
30
|
+
* that surface's `aria-labelledby` at it, so the popup carries the field's name.
|
|
31
|
+
*/
|
|
32
|
+
export declare function useFieldLabelId(): string | undefined;
|
|
27
33
|
export interface FieldProps {
|
|
28
34
|
readonly label: string;
|
|
29
35
|
readonly description?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAetD,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,cAAc,EAAE,IAAI,GAAG,SAAS,CAAC;CAC3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,CAUnD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,sFAAsF;IACtF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EACT,KAAa,EACb,SAAiB,GAClB,EAAE,UAAU,+BA+EZ"}
|
package/dist/components/field.js
CHANGED
|
@@ -23,6 +23,14 @@ export function useFieldControl() {
|
|
|
23
23
|
'aria-invalid': ctx.invalid ? true : undefined,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* The id of the enclosing Field's label while it names one control, else `undefined`.
|
|
28
|
+
* A control whose popup holds a second labelled surface (a listbox, a dialog) points
|
|
29
|
+
* that surface's `aria-labelledby` at it, so the popup carries the field's name.
|
|
30
|
+
*/
|
|
31
|
+
export function useFieldLabelId() {
|
|
32
|
+
return useContext(FieldContext)?.labelId;
|
|
33
|
+
}
|
|
26
34
|
export function Field({ label, description, error, children, style, className, group = false, hideLabel = false, }) {
|
|
27
35
|
const controlId = useId();
|
|
28
36
|
const labelId = `${controlId}-label`;
|
|
@@ -41,8 +49,13 @@ export function Field({ label, description, error, children, style, className, g
|
|
|
41
49
|
// if the group Field withheld it too, a group Field carrying an `error` would
|
|
42
50
|
// expose its invalid state NOWHERE in the accessibility tree.
|
|
43
51
|
const value = group
|
|
44
|
-
? {
|
|
45
|
-
|
|
52
|
+
? {
|
|
53
|
+
controlId: undefined,
|
|
54
|
+
labelId: undefined,
|
|
55
|
+
describedBy: undefined,
|
|
56
|
+
invalid: error !== undefined,
|
|
57
|
+
}
|
|
58
|
+
: { controlId, labelId, describedBy, invalid: error !== undefined };
|
|
46
59
|
// The label keeps its `htmlFor`/`id` wiring either way — `hideLabel` only drops
|
|
47
60
|
// its PAINT, so the accessible name it gives the control is unchanged.
|
|
48
61
|
const labelClassName = hideLabel ? 'tai-field-label tai-visually-hidden' : 'tai-field-label';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"field.js","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAUtC,MAAM,YAAY,GAAG,aAAa,CAA2B,IAAI,CAAC,CAAC;AASnE;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;IACrF,CAAC;IACD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,SAAS;QACjB,kBAAkB,EAAE,GAAG,CAAC,WAAW;QACnC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;KAC/C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,UAAU,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;AAC3C,CAAC;AA4DD,MAAM,UAAU,KAAK,CAAC,EACpB,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EACT,KAAK,GAAG,KAAK,EACb,SAAS,GAAG,KAAK,GACN;IACX,MAAM,SAAS,GAAG,KAAK,EAAE,CAAC;IAC1B,MAAM,OAAO,GAAG,GAAG,SAAS,QAAQ,CAAC;IACrC,MAAM,aAAa,GAAG,GAAG,SAAS,OAAO,CAAC;IAC1C,MAAM,OAAO,GAAG,GAAG,SAAS,MAAM,CAAC;IAEnC,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,IAAI,WAAW,KAAK,SAAS;QAAE,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAClE,IAAI,KAAK,KAAK,SAAS;QAAE,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAErF,+EAA+E;IAC/E,2EAA2E;IAC3E,uEAAuE;IACvE,8EAA8E;IAC9E,8EAA8E;IAC9E,8DAA8D;IAC9D,MAAM,KAAK,GAAsB,KAAK;QACpC,CAAC,CAAC;YACE,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,SAAS;YAClB,WAAW,EAAE,SAAS;YACtB,OAAO,EAAE,KAAK,KAAK,SAAS;SAC7B;QACH,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;IAEtE,gFAAgF;IAChF,uEAAuE;IACvE,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAE7F,OAAO,CACL,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACjC,eACE,SAAS,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,SAAS,EAAE,EAC3E,KAAK,EAAE,KAAK,aAEX,KAAK,CAAC,CAAC,CAAC,CACP,eAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,YACzC,KAAK,GACD,CACR,CAAC,CAAC,CAAC,CACF,gBAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,YAC9D,KAAK,GACA,CACT,EAMA,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAC3B,YAAG,EAAE,EAAE,aAAa,EAAE,SAAS,EAAC,gBAAgB,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,YAClE,WAAW,GACV,CACL,CAAC,CAAC,CAAC,IAAI,EACP,KAAK,CAAC,CAAC,CAAC,CACP,cACE,IAAI,EAAC,OAAO,qBACK,OAAO,sBACN,WAAW,EAC7B,SAAS,EAAC,iBAAiB,YAE1B,QAAQ,GACL,CACP,CAAC,CAAC,CAAC,CACF,QAAQ,CACT,EAIA,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACrB,aAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,iBAAiB,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,aAC3E,KAAC,WAAW,KAAG,EACd,KAAK,IACJ,CACL,CAAC,CAAC,CAAC,IAAI,IACJ,GACgB,CACzB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The folder WRITES of the tool-organization tree — create, rename, move and delete —
|
|
3
|
+
* shared by every screen that shows the tree, so each offers the same actions over
|
|
4
|
+
* the same client doors (`createFolder` / `renameFolder` / `moveFolder` /
|
|
5
|
+
* `deleteFolder`).
|
|
6
|
+
*
|
|
7
|
+
* The SDK owns no query cache, so every write takes the screen's
|
|
8
|
+
* `onFoldersChanged`: the screen re-reads the overlay under its own key, and the
|
|
9
|
+
* write resolves only after that refresh, so the tree on screen is never stale when
|
|
10
|
+
* a dialog closes. Each dialog owns its own pending and error state, so a failure on
|
|
11
|
+
* one folder never bleeds onto another, and every failure is shown in its dialog.
|
|
12
|
+
*
|
|
13
|
+
* Move offers every folder EXCEPT the folder itself and its descendants (a folder
|
|
14
|
+
* cannot become its own ancestor), with inline create. Delete asks first and lets the
|
|
15
|
+
* server enforce that only an empty folder can go; a refusal is shown in the dialog.
|
|
16
|
+
*
|
|
17
|
+
* Each action is offered only where the caller may make that write
|
|
18
|
+
* ({@link useToolMetaWriteAccess}): its own route, and the tool_meta store not known
|
|
19
|
+
* off. A not-configured refusal is reported, so every screen withdraws its overlay
|
|
20
|
+
* writes; the open dialog stays to show the server's off note.
|
|
21
|
+
*/
|
|
22
|
+
import { type ReactNode } from 'react';
|
|
23
|
+
import { type Folder } from './folder-nav';
|
|
24
|
+
/** Re-read the folder tree after a write; the write resolves once this settles. */
|
|
25
|
+
export type FoldersChanged = () => Promise<void>;
|
|
26
|
+
/** Create a folder under `parentId` and resolve with its id. */
|
|
27
|
+
export type CreateFolder = (name: string, parentId: string | null) => Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Create a folder through the folder door and refresh the screen's tree, resolving
|
|
30
|
+
* with the new folder's id — the shape {@link FolderPicker}'s `onCreateFolder`
|
|
31
|
+
* takes. `undefined` when the caller may not create a folder, so the picker offers
|
|
32
|
+
* no create. A rejection propagates to the picker, which shows it; a not-configured
|
|
33
|
+
* refusal is also reported, withdrawing every overlay write.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useCreateFolder(onFoldersChanged: FoldersChanged): CreateFolder | undefined;
|
|
36
|
+
/** Props of {@link FolderActionsMenu}. */
|
|
37
|
+
export interface FolderActionsMenuProps {
|
|
38
|
+
/** The folder the actions act on. */
|
|
39
|
+
readonly folder: Folder;
|
|
40
|
+
/** The FULL folder tree, offered as move destinations. */
|
|
41
|
+
readonly folders: readonly Folder[];
|
|
42
|
+
/** The screen's refresh of its overlay read, awaited after every write. */
|
|
43
|
+
readonly onFoldersChanged: FoldersChanged;
|
|
44
|
+
}
|
|
45
|
+
/** The Rename, Move and Delete buttons for one folder row/card, each owning its
|
|
46
|
+
* dialog — for an explorer's `renderFolderActions` slot. Each button shows only
|
|
47
|
+
* where the caller may make that write; a dialog already open stays open after its
|
|
48
|
+
* button is withdrawn, so its outcome is still shown. Renders nothing for a caller
|
|
49
|
+
* who may make none of the three writes. */
|
|
50
|
+
export declare function FolderActionsMenu({ folder, folders, onFoldersChanged, }: FolderActionsMenuProps): ReactNode;
|
|
51
|
+
//# sourceMappingURL=folder-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-actions.d.ts","sourceRoot":"","sources":["../../src/components/folder-actions.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,KAAK,SAAS,EAAyB,MAAM,OAAO,CAAC;AAQ9D,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,cAAc,CAAC;AASzD,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjD,gEAAgE;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,cAAc,GAAG,YAAY,GAAG,SAAS,CAmB1F;AA+LD,0CAA0C;AAC1C,MAAM,WAAW,sBAAsB;IACrC,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,gBAAgB,EAAE,cAAc,CAAC;CAC3C;AAED;;;;6CAI6C;AAC7C,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,OAAO,EACP,gBAAgB,GACjB,EAAE,sBAAsB,GAAG,SAAS,CA4DpC"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The folder WRITES of the tool-organization tree — create, rename, move and delete —
|
|
4
|
+
* shared by every screen that shows the tree, so each offers the same actions over
|
|
5
|
+
* the same client doors (`createFolder` / `renameFolder` / `moveFolder` /
|
|
6
|
+
* `deleteFolder`).
|
|
7
|
+
*
|
|
8
|
+
* The SDK owns no query cache, so every write takes the screen's
|
|
9
|
+
* `onFoldersChanged`: the screen re-reads the overlay under its own key, and the
|
|
10
|
+
* write resolves only after that refresh, so the tree on screen is never stale when
|
|
11
|
+
* a dialog closes. Each dialog owns its own pending and error state, so a failure on
|
|
12
|
+
* one folder never bleeds onto another, and every failure is shown in its dialog.
|
|
13
|
+
*
|
|
14
|
+
* Move offers every folder EXCEPT the folder itself and its descendants (a folder
|
|
15
|
+
* cannot become its own ancestor), with inline create. Delete asks first and lets the
|
|
16
|
+
* server enforce that only an empty folder can go; a refusal is shown in the dialog.
|
|
17
|
+
*
|
|
18
|
+
* Each action is offered only where the caller may make that write
|
|
19
|
+
* ({@link useToolMetaWriteAccess}): its own route, and the tool_meta store not known
|
|
20
|
+
* off. A not-configured refusal is reported, so every screen withdraws its overlay
|
|
21
|
+
* writes; the open dialog stays to show the server's off note.
|
|
22
|
+
*/
|
|
23
|
+
import { useCallback, useState } from 'react';
|
|
24
|
+
import { errorMessage } from '../errors';
|
|
25
|
+
import { FeatureDisabled, featureDisabledMessage, isFeatureDisabled } from '../feature-disabled';
|
|
26
|
+
import { useApi } from '../hooks/useApi';
|
|
27
|
+
import { ConfirmDialog } from './confirm-dialog';
|
|
28
|
+
import { Dialog } from './dialog';
|
|
29
|
+
import { Field } from './field';
|
|
30
|
+
import { FolderPicker } from './folder-nav';
|
|
31
|
+
import { TextInput } from './inputs';
|
|
32
|
+
import { Button, Spinner } from './primitives';
|
|
33
|
+
import { ToolMetaWriteError, useReportToolMetaRefusal, useToolMetaWriteAccess, } from './tool-meta-access';
|
|
34
|
+
/**
|
|
35
|
+
* Create a folder through the folder door and refresh the screen's tree, resolving
|
|
36
|
+
* with the new folder's id — the shape {@link FolderPicker}'s `onCreateFolder`
|
|
37
|
+
* takes. `undefined` when the caller may not create a folder, so the picker offers
|
|
38
|
+
* no create. A rejection propagates to the picker, which shows it; a not-configured
|
|
39
|
+
* refusal is also reported, withdrawing every overlay write.
|
|
40
|
+
*/
|
|
41
|
+
export function useCreateFolder(onFoldersChanged) {
|
|
42
|
+
const api = useApi();
|
|
43
|
+
const { createFolder: allowed } = useToolMetaWriteAccess();
|
|
44
|
+
const reportRefusal = useReportToolMetaRefusal();
|
|
45
|
+
const create = useCallback(async (name, parentId) => {
|
|
46
|
+
let created;
|
|
47
|
+
try {
|
|
48
|
+
created = await api.createFolder(name, parentId);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
reportRefusal(error);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
await onFoldersChanged();
|
|
55
|
+
return created.id;
|
|
56
|
+
}, [api, onFoldersChanged, reportRefusal]);
|
|
57
|
+
return allowed ? create : undefined;
|
|
58
|
+
}
|
|
59
|
+
/** One write's pending + error state: `run` clears the last error, awaits the write
|
|
60
|
+
* and keeps a rejection for the dialog to show, reporting a not-configured one. */
|
|
61
|
+
function useFolderWrite(write) {
|
|
62
|
+
const reportRefusal = useReportToolMetaRefusal();
|
|
63
|
+
const [pending, setPending] = useState(false);
|
|
64
|
+
const [error, setError] = useState(null);
|
|
65
|
+
const run = () => {
|
|
66
|
+
if (pending)
|
|
67
|
+
return;
|
|
68
|
+
setPending(true);
|
|
69
|
+
setError(null);
|
|
70
|
+
write().then(() => {
|
|
71
|
+
setPending(false);
|
|
72
|
+
}, (failure) => {
|
|
73
|
+
setError(failure);
|
|
74
|
+
setPending(false);
|
|
75
|
+
reportRefusal(failure);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
return { run, pending, error };
|
|
79
|
+
}
|
|
80
|
+
/** The ids of `folder` and every folder nested beneath it — linear in the folder
|
|
81
|
+
* count and safe on a cyclic parent chain. */
|
|
82
|
+
function subtreeIds(folder, folders) {
|
|
83
|
+
const childrenByParent = new Map();
|
|
84
|
+
for (const candidate of folders) {
|
|
85
|
+
if (candidate.parentId === null)
|
|
86
|
+
continue;
|
|
87
|
+
const siblings = childrenByParent.get(candidate.parentId) ?? [];
|
|
88
|
+
siblings.push(candidate.id);
|
|
89
|
+
childrenByParent.set(candidate.parentId, siblings);
|
|
90
|
+
}
|
|
91
|
+
const ids = new Set([folder.id]);
|
|
92
|
+
const queue = [folder.id];
|
|
93
|
+
for (let next = queue.pop(); next !== undefined; next = queue.pop()) {
|
|
94
|
+
for (const childId of childrenByParent.get(next) ?? []) {
|
|
95
|
+
if (ids.has(childId))
|
|
96
|
+
continue;
|
|
97
|
+
ids.add(childId);
|
|
98
|
+
queue.push(childId);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return ids;
|
|
102
|
+
}
|
|
103
|
+
function RenameFolderDialog({ folder, onFoldersChanged, onClose }) {
|
|
104
|
+
const api = useApi();
|
|
105
|
+
const [name, setName] = useState(folder.name);
|
|
106
|
+
const trimmed = name.trim();
|
|
107
|
+
const rename = useFolderWrite(async () => {
|
|
108
|
+
await api.renameFolder(folder.id, trimmed);
|
|
109
|
+
await onFoldersChanged();
|
|
110
|
+
onClose();
|
|
111
|
+
});
|
|
112
|
+
const blocked = trimmed === '' || trimmed === folder.name || rename.pending;
|
|
113
|
+
return (_jsxs(Dialog, { title: "Rename folder", open: true, onOpenChange: (next) => {
|
|
114
|
+
if (!next)
|
|
115
|
+
onClose();
|
|
116
|
+
}, children: [_jsx(Field, { label: "Folder name", children: _jsx(TextInput, { value: name, autoComplete: "off", onChange: (event) => {
|
|
117
|
+
setName(event.target.value);
|
|
118
|
+
}, onKeyDown: (event) => {
|
|
119
|
+
if (event.key === 'Enter' && !blocked) {
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
rename.run();
|
|
122
|
+
}
|
|
123
|
+
} }) }), _jsx(ToolMetaWriteError, { error: rename.error }), _jsxs("div", { className: "tai-dialog-actions", children: [_jsx(Button, { type: "button", onClick: onClose, children: "Cancel" }), _jsxs(Button, { type: "button", variant: "primary", disabled: blocked, onClick: rename.run, children: [rename.pending ? _jsx(Spinner, { label: "Renaming folder" }) : null, "Rename"] })] })] }));
|
|
124
|
+
}
|
|
125
|
+
function MoveFolderDialog({ folder, folders, onFoldersChanged, onClose, }) {
|
|
126
|
+
const api = useApi();
|
|
127
|
+
const [parentId, setParentId] = useState(folder.parentId);
|
|
128
|
+
const createFolder = useCreateFolder(onFoldersChanged);
|
|
129
|
+
const move = useFolderWrite(async () => {
|
|
130
|
+
await api.moveFolder(folder.id, parentId);
|
|
131
|
+
await onFoldersChanged();
|
|
132
|
+
onClose();
|
|
133
|
+
});
|
|
134
|
+
const forbidden = subtreeIds(folder, folders);
|
|
135
|
+
const targets = folders.filter((candidate) => !forbidden.has(candidate.id));
|
|
136
|
+
return (_jsxs(Dialog, { title: `Move ${folder.name}`, open: true, onOpenChange: (next) => {
|
|
137
|
+
if (!next)
|
|
138
|
+
onClose();
|
|
139
|
+
}, children: [_jsx(Field, { label: "Destination folder", description: "Choose a new parent, or the root.", group: true, children: _jsx(FolderPicker, { value: parentId, onChange: setParentId, folders: targets, onCreateFolder: createFolder, unfiledLabel: "Root (no folder)" }) }), _jsx(ToolMetaWriteError, { error: move.error }), _jsxs("div", { className: "tai-dialog-actions", children: [_jsx(Button, { type: "button", onClick: onClose, children: "Cancel" }), _jsxs(Button, { type: "button", variant: "primary", disabled: parentId === folder.parentId || move.pending, onClick: move.run, children: [move.pending ? _jsx(Spinner, { label: "Moving folder" }) : null, "Move"] })] })] }));
|
|
140
|
+
}
|
|
141
|
+
function DeleteFolderDialog({ folder, onFoldersChanged, onClose }) {
|
|
142
|
+
const api = useApi();
|
|
143
|
+
const remove = useFolderWrite(async () => {
|
|
144
|
+
await api.deleteFolder(folder.id);
|
|
145
|
+
await onFoldersChanged();
|
|
146
|
+
onClose();
|
|
147
|
+
});
|
|
148
|
+
const off = isFeatureDisabled(remove.error);
|
|
149
|
+
return (_jsx(ConfirmDialog, { title: `Delete ${folder.name}?`, confirmLabel: "Delete folder", pendingLabel: "Deleting folder", onConfirm: remove.run, onClose: onClose, isPending: remove.pending, error: remove.error !== null && !off ? errorMessage(remove.error) : null, disabledNote: off ? (_jsx(FeatureDisabled, { feature: "Tool metadata", message: featureDisabledMessage(remove.error) })) : undefined, children: _jsx("p", { children: "Only an empty folder can be deleted \u2014 one that still holds tools (hidden ones count) or subfolders cannot be." }) }));
|
|
150
|
+
}
|
|
151
|
+
/** The Rename, Move and Delete buttons for one folder row/card, each owning its
|
|
152
|
+
* dialog — for an explorer's `renderFolderActions` slot. Each button shows only
|
|
153
|
+
* where the caller may make that write; a dialog already open stays open after its
|
|
154
|
+
* button is withdrawn, so its outcome is still shown. Renders nothing for a caller
|
|
155
|
+
* who may make none of the three writes. */
|
|
156
|
+
export function FolderActionsMenu({ folder, folders, onFoldersChanged, }) {
|
|
157
|
+
const access = useToolMetaWriteAccess();
|
|
158
|
+
const [action, setAction] = useState(null);
|
|
159
|
+
const close = () => {
|
|
160
|
+
setAction(null);
|
|
161
|
+
};
|
|
162
|
+
if (!access.renameFolder && !access.moveFolder && !access.deleteFolder && action === null) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
return (_jsxs("div", { className: "tai-row", children: [access.renameFolder ? (_jsx(Button, { variant: "ghost", "aria-label": `Rename folder ${folder.name}`, onClick: () => {
|
|
166
|
+
setAction('rename');
|
|
167
|
+
}, children: "Rename" })) : null, access.moveFolder ? (_jsx(Button, { variant: "ghost", "aria-label": `Move folder ${folder.name}`, onClick: () => {
|
|
168
|
+
setAction('move');
|
|
169
|
+
}, children: "Move" })) : null, access.deleteFolder ? (_jsx(Button, { variant: "ghost", "aria-label": `Delete folder ${folder.name}`, onClick: () => {
|
|
170
|
+
setAction('delete');
|
|
171
|
+
}, children: "Delete" })) : null, action === 'rename' ? (_jsx(RenameFolderDialog, { folder: folder, onFoldersChanged: onFoldersChanged, onClose: close })) : null, action === 'move' ? (_jsx(MoveFolderDialog, { folder: folder, folders: folders, onFoldersChanged: onFoldersChanged, onClose: close })) : null, action === 'delete' ? (_jsx(DeleteFolderDialog, { folder: folder, onFoldersChanged: onFoldersChanged, onClose: close })) : null] }));
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=folder-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-actions.js","sourceRoot":"","sources":["../../src/components/folder-actions.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filing ONE tool into a folder of the tool-organization tree — for a screen whose
|
|
3
|
+
* rows have no edit dialog of their own to carry a folder field. The folder is part
|
|
4
|
+
* of the tool's overlay row, so the write is a single `upsertToolMeta` merge-patch of
|
|
5
|
+
* `folder_id`; the tool's display name, tags and visibility are left untouched.
|
|
6
|
+
*
|
|
7
|
+
* The picker offers the FULL tree with inline create. The write resolves only after
|
|
8
|
+
* the screen's `onFoldersChanged` refresh, and a failure is shown in the dialog — a
|
|
9
|
+
* not-configured refusal as the server's off note, reported so every screen withdraws
|
|
10
|
+
* its overlay writes.
|
|
11
|
+
*/
|
|
12
|
+
import { type ReactNode } from 'react';
|
|
13
|
+
import { type FoldersChanged } from './folder-actions';
|
|
14
|
+
import { type Folder } from './folder-nav';
|
|
15
|
+
/** Props of {@link MoveToFolderDialog}. */
|
|
16
|
+
export interface MoveToFolderDialogProps {
|
|
17
|
+
/** The tool whose overlay row is filed (its registered tool name). */
|
|
18
|
+
readonly toolName: string;
|
|
19
|
+
/** What the dialog title calls the item (e.g. the agent's name). */
|
|
20
|
+
readonly label: string;
|
|
21
|
+
/** The tool's current folder (`null` = unfiled). */
|
|
22
|
+
readonly currentFolderId: string | null;
|
|
23
|
+
/** The FULL folder tree, offered as destinations. */
|
|
24
|
+
readonly folders: readonly Folder[];
|
|
25
|
+
/** The screen's refresh of its overlay read, awaited after the write. */
|
|
26
|
+
readonly onFoldersChanged: FoldersChanged;
|
|
27
|
+
/** Close the dialog (Cancel, dismiss, or after a successful move). */
|
|
28
|
+
readonly onClose: () => void;
|
|
29
|
+
}
|
|
30
|
+
/** A dialog that files one tool into a folder (or unfiles it). Mount while open. */
|
|
31
|
+
export declare function MoveToFolderDialog({ toolName, label, currentFolderId, folders, onFoldersChanged, onClose, }: MoveToFolderDialogProps): ReactNode;
|
|
32
|
+
//# sourceMappingURL=folder-filing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-filing.d.ts","sourceRoot":"","sources":["../../src/components/folder-filing.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAKjD,OAAO,EAAE,KAAK,cAAc,EAAmB,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,cAAc,CAAC;AAIzD,2CAA2C;AAC3C,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,gBAAgB,EAAE,cAAc,CAAC;IAC1C,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,KAAK,EACL,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,EAAE,uBAAuB,GAAG,SAAS,CA+DrC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Filing ONE tool into a folder of the tool-organization tree — for a screen whose
|
|
4
|
+
* rows have no edit dialog of their own to carry a folder field. The folder is part
|
|
5
|
+
* of the tool's overlay row, so the write is a single `upsertToolMeta` merge-patch of
|
|
6
|
+
* `folder_id`; the tool's display name, tags and visibility are left untouched.
|
|
7
|
+
*
|
|
8
|
+
* The picker offers the FULL tree with inline create. The write resolves only after
|
|
9
|
+
* the screen's `onFoldersChanged` refresh, and a failure is shown in the dialog — a
|
|
10
|
+
* not-configured refusal as the server's off note, reported so every screen withdraws
|
|
11
|
+
* its overlay writes.
|
|
12
|
+
*/
|
|
13
|
+
import { useState } from 'react';
|
|
14
|
+
import { useApi } from '../hooks/useApi';
|
|
15
|
+
import { Dialog } from './dialog';
|
|
16
|
+
import { Field } from './field';
|
|
17
|
+
import { useCreateFolder } from './folder-actions';
|
|
18
|
+
import { FolderPicker } from './folder-nav';
|
|
19
|
+
import { Button, Spinner } from './primitives';
|
|
20
|
+
import { ToolMetaWriteError, useReportToolMetaRefusal } from './tool-meta-access';
|
|
21
|
+
/** A dialog that files one tool into a folder (or unfiles it). Mount while open. */
|
|
22
|
+
export function MoveToFolderDialog({ toolName, label, currentFolderId, folders, onFoldersChanged, onClose, }) {
|
|
23
|
+
const api = useApi();
|
|
24
|
+
const createFolder = useCreateFolder(onFoldersChanged);
|
|
25
|
+
const reportRefusal = useReportToolMetaRefusal();
|
|
26
|
+
const [folderId, setFolderId] = useState(currentFolderId);
|
|
27
|
+
const [pending, setPending] = useState(false);
|
|
28
|
+
const [error, setError] = useState(null);
|
|
29
|
+
const save = () => {
|
|
30
|
+
if (pending)
|
|
31
|
+
return;
|
|
32
|
+
setPending(true);
|
|
33
|
+
setError(null);
|
|
34
|
+
api
|
|
35
|
+
.upsertToolMeta(toolName, { folder_id: folderId })
|
|
36
|
+
.then(() => onFoldersChanged())
|
|
37
|
+
.then(() => {
|
|
38
|
+
setPending(false);
|
|
39
|
+
onClose();
|
|
40
|
+
}, (failure) => {
|
|
41
|
+
setError(failure);
|
|
42
|
+
setPending(false);
|
|
43
|
+
reportRefusal(failure);
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
return (_jsxs(Dialog, { title: `Move ${label} to a folder`, open: true, onOpenChange: (next) => {
|
|
47
|
+
if (!next)
|
|
48
|
+
onClose();
|
|
49
|
+
}, children: [_jsx(Field, { label: "Destination folder", description: "Choose a folder, or no folder.", group: true, children: _jsx(FolderPicker, { value: folderId, onChange: setFolderId, folders: folders, onCreateFolder: createFolder, unfiledLabel: "No folder", disabled: pending }) }), _jsx(ToolMetaWriteError, { error: error }), _jsxs("div", { className: "tai-dialog-actions", children: [_jsx(Button, { type: "button", onClick: onClose, children: "Cancel" }), _jsxs(Button, { type: "button", variant: "primary", disabled: folderId === currentFolderId || pending, onClick: save, children: [pending ? _jsx(Spinner, { label: "Moving" }) : null, "Move"] })] })] }));
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=folder-filing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-filing.js","sourceRoot":"","sources":["../../src/components/folder-filing.tsx"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
*
|
|
12
12
|
* `FolderPicker` carries inline new-folder creation, so a folder can be created from
|
|
13
13
|
* EVERY consuming screen through this one component — never one screen's own
|
|
14
|
-
* affordance.
|
|
14
|
+
* affordance. A failed creation is shown loudly under the draft by the picker
|
|
15
|
+
* itself, so every screen that files through it surfaces the failure the same way.
|
|
15
16
|
*/
|
|
17
|
+
import type { FolderRecord } from '@tai42/api-client';
|
|
16
18
|
import { type ReactNode } from 'react';
|
|
17
19
|
/** A folder in the tree, in the SDK's camelCase UI shape (`parentId`, `null` = root). */
|
|
18
20
|
export interface Folder {
|
|
@@ -20,6 +22,8 @@ export interface Folder {
|
|
|
20
22
|
readonly name: string;
|
|
21
23
|
readonly parentId: string | null;
|
|
22
24
|
}
|
|
25
|
+
/** Map the overlay's wire folder records into the UI {@link Folder} shape. */
|
|
26
|
+
export declare function toFolders(records: readonly FolderRecord[]): Folder[];
|
|
23
27
|
/** The subfolders directly under `parentId` (`null` = the root directory), name-sorted. */
|
|
24
28
|
export declare function childFolders(folders: readonly Folder[], parentId: string | null): Folder[];
|
|
25
29
|
/**
|
|
@@ -50,10 +54,11 @@ export interface FolderPickerProps {
|
|
|
50
54
|
readonly folders: readonly Folder[];
|
|
51
55
|
/**
|
|
52
56
|
* Create a folder under `parentId` (the current selection) and resolve with its
|
|
53
|
-
* id; the picker selects it.
|
|
54
|
-
*
|
|
57
|
+
* id; the picker selects it. On a rejection the picker shows the error and keeps
|
|
58
|
+
* the draft in place so the operator can retry. Without it the picker offers no
|
|
59
|
+
* create — the caller may not create folders.
|
|
55
60
|
*/
|
|
56
|
-
readonly onCreateFolder
|
|
61
|
+
readonly onCreateFolder?: (name: string, parentId: string | null) => Promise<string>;
|
|
57
62
|
readonly disabled?: boolean;
|
|
58
63
|
/** The unfiled option's label (e.g. "No folder"). */
|
|
59
64
|
readonly unfiledLabel: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder-nav.d.ts","sourceRoot":"","sources":["../../src/components/folder-nav.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"folder-nav.d.ts","sourceRoot":"","sources":["../../src/components/folder-nav.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAQjD,yFAAyF;AACzF,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,EAAE,CAMpE;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAI1F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAc1F;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,eAAe,EACf,UAAU,EACV,SAAS,GACV,EAAE,qBAAqB,GAAG,SAAS,CA6BnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,cAAc,GAAG,SAAS,CAYvE;AAkBD,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrF,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,cAAc,EACd,QAAQ,EACR,YAAY,GACb,EAAE,iBAAiB,GAAG,SAAS,CA+F/B"}
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* Folder navigation primitives for the tool-organization tree — shared by the tools
|
|
4
|
-
* screen and any plugin screen that shows the same tree, so all explore, breadcrumb, and
|
|
5
|
-
* re-file against one identical set of controls.
|
|
6
|
-
*
|
|
7
|
-
* The tree is passed FLAT (a {@link Folder} list keyed by `id`, each naming its
|
|
8
|
-
* `parentId`); these helpers derive the current directory, the breadcrumb path, and
|
|
9
|
-
* the indented picker options from it. Every derivation is cycle-SAFE: a malformed
|
|
10
|
-
* parent chain (a loop, a dangling parent) is bounded by the folder count rather than
|
|
11
|
-
* looping forever — bad data degrades to a truncated path, never a hang.
|
|
12
|
-
*
|
|
13
|
-
* `FolderPicker` carries inline new-folder creation, so a folder can be created from
|
|
14
|
-
* EVERY consuming screen through this one component — never one screen's own
|
|
15
|
-
* affordance.
|
|
16
|
-
*/
|
|
17
2
|
import { useState } from 'react';
|
|
18
3
|
import { ChevronRightIcon, FolderIcon } from './icons';
|
|
19
4
|
import { TextInput } from './inputs';
|
|
20
5
|
import { Button } from './primitives';
|
|
21
6
|
import { Select } from './select';
|
|
7
|
+
import { ToolMetaWriteError } from './tool-meta-access';
|
|
8
|
+
/** Map the overlay's wire folder records into the UI {@link Folder} shape. */
|
|
9
|
+
export function toFolders(records) {
|
|
10
|
+
return records.map((record) => ({
|
|
11
|
+
id: record.id,
|
|
12
|
+
name: record.name,
|
|
13
|
+
parentId: record.parent_id,
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
22
16
|
/** The subfolders directly under `parentId` (`null` = the root directory), name-sorted. */
|
|
23
17
|
export function childFolders(folders, parentId) {
|
|
24
18
|
return folders
|
|
@@ -81,22 +75,23 @@ export function FolderPicker({ value, onChange, folders, onCreateFolder, disable
|
|
|
81
75
|
const [creating, setCreating] = useState(false);
|
|
82
76
|
const [draft, setDraft] = useState('');
|
|
83
77
|
const [busy, setBusy] = useState(false);
|
|
78
|
+
const [createError, setCreateError] = useState(null);
|
|
84
79
|
const options = [{ value: UNFILED_VALUE, label: unfiledLabel }, ...folderOptions(folders)];
|
|
85
80
|
const create = async () => {
|
|
86
81
|
const name = draft.trim();
|
|
87
|
-
if (name === '' || busy)
|
|
82
|
+
if (name === '' || busy || onCreateFolder === undefined)
|
|
88
83
|
return;
|
|
89
84
|
setBusy(true);
|
|
85
|
+
setCreateError(null);
|
|
90
86
|
try {
|
|
91
87
|
const id = await onCreateFolder(name, value);
|
|
92
88
|
onChange(id);
|
|
93
89
|
setDraft('');
|
|
94
90
|
setCreating(false);
|
|
95
91
|
}
|
|
96
|
-
catch {
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
// operator can retry — never to clear it or select nothing.
|
|
92
|
+
catch (error) {
|
|
93
|
+
// Shown under the draft, which stays OPEN with its text for a retry.
|
|
94
|
+
setCreateError(error);
|
|
100
95
|
}
|
|
101
96
|
finally {
|
|
102
97
|
setBusy(false);
|
|
@@ -104,7 +99,7 @@ export function FolderPicker({ value, onChange, folders, onCreateFolder, disable
|
|
|
104
99
|
};
|
|
105
100
|
return (_jsxs("div", { className: "tai-stack tai-stack-2", children: [_jsx(Select, { "aria-label": "Folder", options: options, value: value ?? UNFILED_VALUE, onValueChange: (next) => {
|
|
106
101
|
onChange(next === UNFILED_VALUE ? null : next);
|
|
107
|
-
}, disabled: disabled ?? busy }), creating ? (_jsxs("div", { className: "tai-row", children: [_jsx("div", { style: { flex: 1 }, children: _jsx(TextInput, { value: draft, onChange: (event) => {
|
|
102
|
+
}, disabled: disabled ?? busy }), onCreateFolder === undefined ? null : creating ? (_jsxs("div", { className: "tai-row", children: [_jsx("div", { style: { flex: 1 }, children: _jsx(TextInput, { value: draft, onChange: (event) => {
|
|
108
103
|
setDraft(event.target.value);
|
|
109
104
|
}, onKeyDown: (event) => {
|
|
110
105
|
if (event.key === 'Enter') {
|
|
@@ -116,8 +111,9 @@ export function FolderPicker({ value, onChange, folders, onCreateFolder, disable
|
|
|
116
111
|
}, disabled: busy || draft.trim() === '', children: "Create" }), _jsx(Button, { type: "button", variant: "ghost", onClick: () => {
|
|
117
112
|
setCreating(false);
|
|
118
113
|
setDraft('');
|
|
114
|
+
setCreateError(null);
|
|
119
115
|
}, disabled: busy, children: "Cancel" })] })) : (_jsxs(Button, { type: "button", variant: "ghost", onClick: () => {
|
|
120
116
|
setCreating(true);
|
|
121
|
-
}, disabled: disabled, children: [_jsx(FolderIcon, {}), _jsx("span", { children: "New folder" })] }))] }));
|
|
117
|
+
}, disabled: disabled, children: [_jsx(FolderIcon, {}), _jsx("span", { children: "New folder" })] })), _jsx(ToolMetaWriteError, { error: createError })] }));
|
|
122
118
|
}
|
|
123
119
|
//# sourceMappingURL=folder-nav.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder-nav.js","sourceRoot":"","sources":["../../src/components/folder-nav.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"folder-nav.js","sourceRoot":"","sources":["../../src/components/folder-nav.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which folders of the ONE tool-organization tree a screen draws. Every tool has one
|
|
3
|
+
* folder; a screen lists only its own population (a subset of the tools), so it draws
|
|
4
|
+
* only the part of the tree that concerns that population:
|
|
5
|
+
*
|
|
6
|
+
* - a folder whose subtree holds at least one of the screen's items is drawn;
|
|
7
|
+
* - a folder whose subtree holds no tool at all is drawn (a fresh folder belongs to
|
|
8
|
+
* every screen until something is filed in it);
|
|
9
|
+
* - a folder whose subtree holds only other tools is not drawn;
|
|
10
|
+
* - the ancestors of a drawn folder are drawn, so every drawn folder stays reachable
|
|
11
|
+
* from the root.
|
|
12
|
+
*
|
|
13
|
+
* Occupancy counts EVERY overlay row with a `folder_id` — hidden tools and rows of
|
|
14
|
+
* tools no longer registered included — so a folder never reads as empty while it
|
|
15
|
+
* still holds something. A screen whose population is every tool draws the whole tree.
|
|
16
|
+
*/
|
|
17
|
+
import type { ToolMetaRecord } from '@tai42/api-client';
|
|
18
|
+
import type { Folder } from './folder-nav';
|
|
19
|
+
/**
|
|
20
|
+
* The folders a screen draws, in the input order.
|
|
21
|
+
*
|
|
22
|
+
* `rows` are the overlay rows (each tool's `folder_id`), `population` the tool names
|
|
23
|
+
* the screen lists. Linear in folders + rows; the subtree walk is cycle-guarded, so a
|
|
24
|
+
* malformed parent chain yields a bounded result rather than looping.
|
|
25
|
+
*/
|
|
26
|
+
export declare function foldersForView(folders: readonly Folder[], rows: readonly Pick<ToolMetaRecord, 'tool_name' | 'folder_id'>[], population: ReadonlySet<string>): Folder[];
|
|
27
|
+
//# sourceMappingURL=folder-occupancy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-occupancy.d.ts","sourceRoot":"","sources":["../../src/components/folder-occupancy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAW3C;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,SAAS,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,WAAW,CAAC,EAAE,EAChE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAC9B,MAAM,EAAE,CA0CV"}
|