@tai42/studio-sdk 30.0.0 → 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/combo-draft-editor.d.ts +31 -0
- package/dist/components/combo-draft-editor.d.ts.map +1 -0
- package/dist/components/combo-draft-editor.js +16 -0
- package/dist/components/combo-draft-editor.js.map +1 -0
- package/dist/components/committed-combo-list.d.ts +17 -0
- package/dist/components/committed-combo-list.d.ts.map +1 -0
- package/dist/components/{extension-combo-parts.js → committed-combo-list.js} +2 -22
- package/dist/components/committed-combo-list.js.map +1 -0
- 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-combo-builder.d.ts +4 -4
- package/dist/components/extension-combo-builder.js +3 -2
- package/dist/components/extension-combo-builder.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/selected-tool-badges.d.ts +13 -0
- package/dist/components/selected-tool-badges.d.ts.map +1 -0
- package/dist/components/selected-tool-badges.js +14 -0
- package/dist/components/selected-tool-badges.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/tag-filter-field.d.ts +11 -0
- package/dist/components/tag-filter-field.d.ts.map +1 -0
- package/dist/components/tag-filter-field.js +15 -0
- package/dist/components/tag-filter-field.js.map +1 -0
- 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 +24 -19
- package/dist/components/tool-picker.d.ts.map +1 -1
- package/dist/components/tool-picker.js +55 -35
- package/dist/components/tool-picker.js.map +1 -1
- package/dist/components/tool-select.d.ts +26 -0
- package/dist/components/tool-select.d.ts.map +1 -0
- package/dist/components/tool-select.js +82 -0
- package/dist/components/tool-select.js.map +1 -0
- package/dist/extension-combos.d.ts +6 -1
- package/dist/extension-combos.d.ts.map +1 -1
- package/dist/extension-combos.js +8 -0
- package/dist/extension-combos.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/combo-draft-editor.tsx +96 -0
- package/src/components/{extension-combo-parts.tsx → committed-combo-list.tsx} +4 -105
- 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-combo-builder.tsx +10 -10
- 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/selected-tool-badges.tsx +41 -0
- package/src/components/subject-section.tsx +3 -2
- package/src/components/table.tsx +12 -2
- package/src/components/tag-filter-field.tsx +37 -0
- package/src/components/tool-meta-access.tsx +101 -0
- package/src/components/tool-name-entry.tsx +77 -0
- package/src/components/tool-picker.tsx +87 -52
- package/src/components/tool-select.tsx +136 -0
- package/src/extension-combos.ts +15 -1
- 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
- package/dist/components/extension-combo-parts.d.ts +0 -46
- package/dist/components/extension-combo-parts.d.ts.map +0 -1
- package/dist/components/extension-combo-parts.js.map +0 -1
- package/dist/components/tool-picker-parts.d.ts +0 -43
- package/dist/components/tool-picker-parts.d.ts.map +0 -1
- package/dist/components/tool-picker-parts.js +0 -89
- package/dist/components/tool-picker-parts.js.map +0 -1
- package/src/components/tool-picker-parts.tsx +0 -195
|
@@ -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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const NOTHING = { own: false, any: false, drawn: false };
|
|
2
|
+
/**
|
|
3
|
+
* The folders a screen draws, in the input order.
|
|
4
|
+
*
|
|
5
|
+
* `rows` are the overlay rows (each tool's `folder_id`), `population` the tool names
|
|
6
|
+
* the screen lists. Linear in folders + rows; the subtree walk is cycle-guarded, so a
|
|
7
|
+
* malformed parent chain yields a bounded result rather than looping.
|
|
8
|
+
*/
|
|
9
|
+
export function foldersForView(folders, rows, population) {
|
|
10
|
+
const direct = new Map();
|
|
11
|
+
for (const row of rows) {
|
|
12
|
+
if (row.folder_id === null)
|
|
13
|
+
continue;
|
|
14
|
+
const entry = direct.get(row.folder_id) ?? { own: false, any: false };
|
|
15
|
+
entry.any = true;
|
|
16
|
+
if (population.has(row.tool_name))
|
|
17
|
+
entry.own = true;
|
|
18
|
+
direct.set(row.folder_id, entry);
|
|
19
|
+
}
|
|
20
|
+
const childrenByParent = new Map();
|
|
21
|
+
for (const folder of folders) {
|
|
22
|
+
if (folder.parentId === null)
|
|
23
|
+
continue;
|
|
24
|
+
const siblings = childrenByParent.get(folder.parentId) ?? [];
|
|
25
|
+
siblings.push(folder.id);
|
|
26
|
+
childrenByParent.set(folder.parentId, siblings);
|
|
27
|
+
}
|
|
28
|
+
const settled = new Map();
|
|
29
|
+
const visiting = new Set();
|
|
30
|
+
const stateOf = (id) => {
|
|
31
|
+
const cached = settled.get(id);
|
|
32
|
+
if (cached !== undefined)
|
|
33
|
+
return cached;
|
|
34
|
+
if (visiting.has(id))
|
|
35
|
+
return NOTHING;
|
|
36
|
+
visiting.add(id);
|
|
37
|
+
const held = direct.get(id);
|
|
38
|
+
let own = held?.own ?? false;
|
|
39
|
+
let any = held?.any ?? false;
|
|
40
|
+
let childDrawn = false;
|
|
41
|
+
for (const childId of childrenByParent.get(id) ?? []) {
|
|
42
|
+
const child = stateOf(childId);
|
|
43
|
+
own = own || child.own;
|
|
44
|
+
any = any || child.any;
|
|
45
|
+
childDrawn = childDrawn || child.drawn;
|
|
46
|
+
}
|
|
47
|
+
visiting.delete(id);
|
|
48
|
+
const state = { own, any, drawn: own || !any || childDrawn };
|
|
49
|
+
settled.set(id, state);
|
|
50
|
+
return state;
|
|
51
|
+
};
|
|
52
|
+
return folders.filter((folder) => stateOf(folder.id).drawn);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=folder-occupancy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-occupancy.js","sourceRoot":"","sources":["../../src/components/folder-occupancy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The single-select both `AgentPicker` and `ChannelPicker` render: one list
|
|
3
|
-
* names, drawn in its own `Field` with the read's states (pending, error with Retry,
|
|
2
|
+
* The searchable single-select both `AgentPicker` and `ChannelPicker` render: one list
|
|
3
|
+
* read of names, drawn in its own `Field` with the read's states (pending, error with Retry,
|
|
4
4
|
* refused on a 403, loaded and empty) and a stored value the loaded list does not
|
|
5
5
|
* hold flagged with the picker's unlisted label. Each picker hands in its own copy.
|
|
6
6
|
* The host's `error` shows, and the `Field` claims its control id, exactly while a
|
|
7
|
-
*
|
|
7
|
+
* select renders.
|
|
8
8
|
*/
|
|
9
9
|
import { type ReactNode } from 'react';
|
|
10
10
|
/** The flags of a list read; `data` is each picker's own. */
|
|
@@ -25,6 +25,8 @@ export interface NamedListCopy {
|
|
|
25
25
|
readonly emptyNote: string;
|
|
26
26
|
readonly emptyAction: ReactNode;
|
|
27
27
|
readonly unlistedLabel: string;
|
|
28
|
+
/** Accessible name of the select's search box. */
|
|
29
|
+
readonly searchLabel: string;
|
|
28
30
|
}
|
|
29
31
|
export interface NamedListPickerProps {
|
|
30
32
|
readonly query: ListReadFlags;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"named-list-picker.d.ts","sourceRoot":"","sources":["../../src/components/named-list-picker.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,SAAS,EAAS,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"named-list-picker.d.ts","sourceRoot":"","sources":["../../src/components/named-list-picker.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,SAAS,EAAS,MAAM,OAAO,CAAC;AAW9C,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,6BAA6B;AAC7B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC9B;AAyGD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,KAAK,EACL,aAAa,EACb,KAAK,EACL,IAAI,GACL,EAAE,oBAAoB,GAAG,SAAS,CAuBlC"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* The single-select both `AgentPicker` and `ChannelPicker` render: one list
|
|
4
|
-
* names, drawn in its own `Field` with the read's states (pending, error with Retry,
|
|
3
|
+
* The searchable single-select both `AgentPicker` and `ChannelPicker` render: one list
|
|
4
|
+
* read of names, drawn in its own `Field` with the read's states (pending, error with Retry,
|
|
5
5
|
* refused on a 403, loaded and empty) and a stored value the loaded list does not
|
|
6
6
|
* hold flagged with the picker's unlisted label. Each picker hands in its own copy.
|
|
7
7
|
* The host's `error` shows, and the `Field` claims its control id, exactly while a
|
|
8
|
-
*
|
|
8
|
+
* select renders.
|
|
9
9
|
*/
|
|
10
10
|
import { useId } from 'react';
|
|
11
11
|
import { errorMessage, isForbiddenError } from '../errors';
|
|
12
12
|
import { Badge } from './badge';
|
|
13
13
|
import { Field } from './field';
|
|
14
14
|
import { ErrorState } from './primitives';
|
|
15
|
-
import {
|
|
15
|
+
import { SearchableSelect } from './searchable-select';
|
|
16
16
|
const MUTED_LINE = { margin: 0, color: 'var(--tai-color-text-muted)' };
|
|
17
17
|
function MutedLine({ text }) {
|
|
18
18
|
return (_jsx("p", { role: "status", style: MUTED_LINE, children: text }));
|
|
@@ -44,15 +44,15 @@ function namedListView(query, names, value, unlistedLabel) {
|
|
|
44
44
|
const selectRenders = pending || (refused ? stored !== null : !failed && (!empty || unlisted));
|
|
45
45
|
return { refused, failed, pending, unlisted, empty, options, selectRenders };
|
|
46
46
|
}
|
|
47
|
-
/** The loaded, pending or refused body: the
|
|
47
|
+
/** The loaded, pending or refused body: the select while one renders, then its notes. */
|
|
48
48
|
function NamedListBody({ view, value, onValueChange, copy, }) {
|
|
49
49
|
const unlistedId = useId();
|
|
50
|
-
return (_jsxs(_Fragment, { children: [view.selectRenders ? (_jsx(
|
|
50
|
+
return (_jsxs(_Fragment, { children: [view.selectRenders ? (_jsx(SearchableSelect, { options: view.options, value: value, placeholder: view.pending ? copy.loadingPlaceholder : copy.placeholder, disabled: view.pending, onValueChange: onValueChange, "aria-describedby": view.unlisted ? unlistedId : undefined, searchLabel: copy.searchLabel })) : null, view.refused ? _jsx(MutedLine, { text: copy.forbiddenNote }) : null, view.empty && !view.refused ? (_jsxs(_Fragment, { children: [_jsx(MutedLine, { text: copy.emptyNote }), copy.emptyAction] })) : null, view.unlisted ? (_jsxs("p", { id: unlistedId, className: "tai-field-hint", style: { margin: 0 }, children: [_jsx(Badge, { variant: "warning", children: copy.unlistedLabel }), ' ', `${value} is ${copy.unlistedLabel}. Pick another, or saving is refused.`] })) : null] }));
|
|
51
51
|
}
|
|
52
52
|
export function NamedListPicker({ query, names, value, onValueChange, error, copy, }) {
|
|
53
53
|
const view = namedListView(query, names, value, copy.unlistedLabel);
|
|
54
54
|
return (_jsx(Field, { label: copy.label, description: copy.description, error: view.selectRenders ? error : undefined,
|
|
55
|
-
// Only the
|
|
55
|
+
// Only the select claims the field's control id; with nothing to hold no
|
|
56
56
|
// labelable element renders, so `for` would dangle.
|
|
57
57
|
group: !view.selectRenders, children: view.failed ? (_jsx(ErrorState, { message: errorMessage(query.error), onRetry: () => {
|
|
58
58
|
query.refetch();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"named-list-picker.js","sourceRoot":"","sources":["../../src/components/named-list-picker.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AACH,OAAO,EAAkB,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"named-list-picker.js","sourceRoot":"","sources":["../../src/components/named-list-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,8 @@ import type { AnchorHTMLAttributes, ButtonHTMLAttributes, CSSProperties, ReactNo
|
|
|
36
36
|
* evil.com.
|
|
37
37
|
*
|
|
38
38
|
* Callers render the returned string rather than their input, so the URL that was
|
|
39
|
-
* judged is always the URL that is navigated.
|
|
39
|
+
* judged is always the URL that is navigated. `isSafeHttpUrl` gives the yes/no
|
|
40
|
+
* answer for a caller that does not need the URL itself.
|
|
40
41
|
*/
|
|
41
42
|
export declare function safeHttpUrl(href: string): string | undefined;
|
|
42
43
|
/** True only for an absolute `http://`/`https://` URL. Everything else is unsafe. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/components/primitives.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,GAAG,EACJ,MAAM,OAAO,CAAC;AA2Bf
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/components/primitives.tsx"],"names":[],"mappings":"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"}
|
|
@@ -39,7 +39,8 @@ function normalizeHref(href) {
|
|
|
39
39
|
* evil.com.
|
|
40
40
|
*
|
|
41
41
|
* Callers render the returned string rather than their input, so the URL that was
|
|
42
|
-
* judged is always the URL that is navigated.
|
|
42
|
+
* judged is always the URL that is navigated. `isSafeHttpUrl` gives the yes/no
|
|
43
|
+
* answer for a caller that does not need the URL itself.
|
|
43
44
|
*/
|
|
44
45
|
export function safeHttpUrl(href) {
|
|
45
46
|
const normalized = normalizeHref(href);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/components/primitives.tsx"],"names":[],"mappings":";AA6BA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,gFAAgF;AAEhF;;;;;;;;;GASG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC/C,6EAA6E;IAC7E,0EAA0E;IAC1E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,OAAO,KAAK,GAAG,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI;QAAE,KAAK,EAAE,CAAC;IAC/D,OAAO,GAAG,GAAG,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI;QAAE,GAAG,EAAE,CAAC;IAC/D,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/components/primitives.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SelectGroup, SelectOption } from './select';
|
|
2
|
+
/** One option, with its position in the full list and its label in search form. */
|
|
3
|
+
export interface SearchEntry {
|
|
4
|
+
readonly option: SelectOption;
|
|
5
|
+
/** The option's position across every section; stable while the reader filters. */
|
|
6
|
+
readonly position: number;
|
|
7
|
+
readonly loweredLabel: string;
|
|
8
|
+
}
|
|
9
|
+
/** A run of entries under one group label, or under none for a flat list. */
|
|
10
|
+
export interface SearchSection {
|
|
11
|
+
readonly label: string | undefined;
|
|
12
|
+
readonly entries: readonly SearchEntry[];
|
|
13
|
+
}
|
|
14
|
+
/** What a query leaves: the non-empty sections and their entries in reading order. */
|
|
15
|
+
export interface VisibleOptions {
|
|
16
|
+
readonly sections: readonly SearchSection[];
|
|
17
|
+
readonly entries: readonly SearchEntry[];
|
|
18
|
+
}
|
|
19
|
+
/** Index the caller's options (a flat run, or labelled groups) for search. */
|
|
20
|
+
export declare function indexSections(options: readonly SelectOption[] | undefined, groups: readonly SelectGroup[] | undefined): SearchSection[];
|
|
21
|
+
/**
|
|
22
|
+
* The sections and entries whose label contains `query`. A blank query returns every
|
|
23
|
+
* section as indexed; either way each kept entry is the indexed object itself, so a
|
|
24
|
+
* row memoised on its entry does not re-render because the reader typed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function visibleOptions(sections: readonly SearchSection[], query: string): VisibleOptions;
|
|
27
|
+
/**
|
|
28
|
+
* The entry the keyboard highlight moves to from `current` by one step in
|
|
29
|
+
* `direction`, skipping disabled entries and stopping at either end. With no current
|
|
30
|
+
* highlight among `entries`, a step lands on the first (down) or last (up) one.
|
|
31
|
+
*/
|
|
32
|
+
export declare function stepEntry(entries: readonly SearchEntry[], current: SearchEntry | undefined, direction: 1 | -1): SearchEntry | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* The entry to draw highlighted: the choosable visible entry whose value is `wanted`,
|
|
35
|
+
* else the first choosable one. Keyed by value, so the highlight stays on its option
|
|
36
|
+
* when the list around it changes, and a query that filters it away moves it to the
|
|
37
|
+
* top of what is left instead of to nothing.
|
|
38
|
+
*/
|
|
39
|
+
export declare function shownEntry(entries: readonly SearchEntry[], wanted: string | undefined): SearchEntry | undefined;
|
|
40
|
+
//# sourceMappingURL=searchable-select-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchable-select-model.d.ts","sourceRoot":"","sources":["../../src/components/searchable-select-model.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE1D,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAED,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,EAC5C,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,GACzC,aAAa,EAAE,CAcjB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAWhG;AAMD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,GAChB,WAAW,GAAG,SAAS,CAQzB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,WAAW,GAAG,SAAS,CAMzB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The option model behind `SearchableSelect`: the caller's options indexed once for
|
|
3
|
+
* search, the sections a query leaves, and the keyboard's movement over them. Pure,
|
|
4
|
+
* so the component re-derives nothing per row and the filter is testable alone.
|
|
5
|
+
*/
|
|
6
|
+
import { searchNeedle, textHasNeedle } from '../search-match';
|
|
7
|
+
/** Index the caller's options (a flat run, or labelled groups) for search. */
|
|
8
|
+
export function indexSections(options, groups) {
|
|
9
|
+
const runs = groups !== undefined
|
|
10
|
+
? groups.map((group) => ({ label: group.label, options: group.options }))
|
|
11
|
+
: [{ label: undefined, options: options ?? [] }];
|
|
12
|
+
let position = 0;
|
|
13
|
+
return runs.map((run) => ({
|
|
14
|
+
label: run.label,
|
|
15
|
+
entries: run.options.map((option) => ({
|
|
16
|
+
option,
|
|
17
|
+
position: position++,
|
|
18
|
+
loweredLabel: option.label.toLowerCase(),
|
|
19
|
+
})),
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The sections and entries whose label contains `query`. A blank query returns every
|
|
24
|
+
* section as indexed; either way each kept entry is the indexed object itself, so a
|
|
25
|
+
* row memoised on its entry does not re-render because the reader typed.
|
|
26
|
+
*/
|
|
27
|
+
export function visibleOptions(sections, query) {
|
|
28
|
+
const needle = searchNeedle(query);
|
|
29
|
+
const kept = needle === ''
|
|
30
|
+
? sections
|
|
31
|
+
: sections.map((section) => ({
|
|
32
|
+
label: section.label,
|
|
33
|
+
entries: section.entries.filter((entry) => textHasNeedle(entry.loweredLabel, needle)),
|
|
34
|
+
}));
|
|
35
|
+
const nonEmpty = kept.filter((section) => section.entries.length > 0);
|
|
36
|
+
return { sections: nonEmpty, entries: nonEmpty.flatMap((section) => section.entries) };
|
|
37
|
+
}
|
|
38
|
+
function enabled(entry) {
|
|
39
|
+
return entry.option.disabled !== true;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The entry the keyboard highlight moves to from `current` by one step in
|
|
43
|
+
* `direction`, skipping disabled entries and stopping at either end. With no current
|
|
44
|
+
* highlight among `entries`, a step lands on the first (down) or last (up) one.
|
|
45
|
+
*/
|
|
46
|
+
export function stepEntry(entries, current, direction) {
|
|
47
|
+
const at = current === undefined ? -1 : entries.indexOf(current);
|
|
48
|
+
if (at === -1)
|
|
49
|
+
return direction === 1 ? entries.find(enabled) : entries.findLast(enabled);
|
|
50
|
+
for (let index = at + direction; index >= 0 && index < entries.length; index += direction) {
|
|
51
|
+
const entry = entries[index];
|
|
52
|
+
if (entry !== undefined && enabled(entry))
|
|
53
|
+
return entry;
|
|
54
|
+
}
|
|
55
|
+
return current;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The entry to draw highlighted: the choosable visible entry whose value is `wanted`,
|
|
59
|
+
* else the first choosable one. Keyed by value, so the highlight stays on its option
|
|
60
|
+
* when the list around it changes, and a query that filters it away moves it to the
|
|
61
|
+
* top of what is left instead of to nothing.
|
|
62
|
+
*/
|
|
63
|
+
export function shownEntry(entries, wanted) {
|
|
64
|
+
const kept = wanted === undefined
|
|
65
|
+
? undefined
|
|
66
|
+
: entries.find((entry) => entry.option.value === wanted && enabled(entry));
|
|
67
|
+
return kept ?? entries.find(enabled);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=searchable-select-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchable-select-model.js","sourceRoot":"","sources":["../../src/components/searchable-select-model.ts"],"names":[],"mappings":"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"}
|