@flanksource/clicky-ui 0.3.40 → 0.3.41
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 +24 -0
- package/dist/ai.cjs +10 -0
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +10 -0
- package/dist/ai.js.map +1 -1
- package/dist/components/AccordionList.cjs +5 -1
- package/dist/components/AccordionList.cjs.map +1 -1
- package/dist/components/AccordionList.d.ts +3 -1
- package/dist/components/AccordionList.d.ts.map +1 -1
- package/dist/components/AccordionList.js +5 -1
- package/dist/components/AccordionList.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +9 -4
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +8 -3
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/json-schema-form-accordion-array.cjs +3 -1
- package/dist/components/json-schema-form-accordion-array.cjs.map +1 -1
- package/dist/components/json-schema-form-accordion-array.d.ts +4 -1
- package/dist/components/json-schema-form-accordion-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-accordion-array.js +3 -1
- package/dist/components/json-schema-form-accordion-array.js.map +1 -1
- package/dist/components/json-schema-form-array-view.cjs +63 -0
- package/dist/components/json-schema-form-array-view.cjs.map +1 -0
- package/dist/components/json-schema-form-array-view.d.ts +21 -0
- package/dist/components/json-schema-form-array-view.d.ts.map +1 -0
- package/dist/components/json-schema-form-array-view.js +63 -0
- package/dist/components/json-schema-form-array-view.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +3 -7
- package/dist/components/json-schema-form-array.cjs.map +1 -1
- package/dist/components/json-schema-form-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-array.js +3 -7
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-conditionals.cjs +67 -0
- package/dist/components/json-schema-form-conditionals.cjs.map +1 -0
- package/dist/components/json-schema-form-conditionals.d.ts +9 -0
- package/dist/components/json-schema-form-conditionals.d.ts.map +1 -0
- package/dist/components/json-schema-form-conditionals.js +67 -0
- package/dist/components/json-schema-form-conditionals.js.map +1 -0
- package/dist/components/json-schema-form-defaults.cjs +68 -0
- package/dist/components/json-schema-form-defaults.cjs.map +1 -0
- package/dist/components/json-schema-form-defaults.d.ts +4 -0
- package/dist/components/json-schema-form-defaults.d.ts.map +1 -0
- package/dist/components/json-schema-form-defaults.js +68 -0
- package/dist/components/json-schema-form-defaults.js.map +1 -0
- package/dist/components/json-schema-form-errors.cjs +49 -31
- package/dist/components/json-schema-form-errors.cjs.map +1 -1
- package/dist/components/json-schema-form-errors.d.ts +4 -2
- package/dist/components/json-schema-form-errors.d.ts.map +1 -1
- package/dist/components/json-schema-form-errors.js +51 -33
- package/dist/components/json-schema-form-errors.js.map +1 -1
- package/dist/components/json-schema-form-filter.cjs +2 -1
- package/dist/components/json-schema-form-filter.cjs.map +1 -1
- package/dist/components/json-schema-form-filter.js +2 -1
- package/dist/components/json-schema-form-filter.js.map +1 -1
- package/dist/components/json-schema-form-item-summary.cjs +6 -2
- package/dist/components/json-schema-form-item-summary.cjs.map +1 -1
- package/dist/components/json-schema-form-item-summary.d.ts.map +1 -1
- package/dist/components/json-schema-form-item-summary.js +6 -2
- package/dist/components/json-schema-form-item-summary.js.map +1 -1
- package/dist/components/json-schema-form-layout.cjs +28 -19
- package/dist/components/json-schema-form-layout.cjs.map +1 -1
- package/dist/components/json-schema-form-layout.d.ts +8 -6
- package/dist/components/json-schema-form-layout.d.ts.map +1 -1
- package/dist/components/json-schema-form-layout.js +29 -20
- package/dist/components/json-schema-form-layout.js.map +1 -1
- package/dist/components/json-schema-form-listener-paths.cjs +52 -0
- package/dist/components/json-schema-form-listener-paths.cjs.map +1 -0
- package/dist/components/json-schema-form-listener-paths.d.ts +10 -0
- package/dist/components/json-schema-form-listener-paths.d.ts.map +1 -0
- package/dist/components/json-schema-form-listener-paths.js +52 -0
- package/dist/components/json-schema-form-listener-paths.js.map +1 -0
- package/dist/components/json-schema-form-listener-types.d.ts +22 -0
- package/dist/components/json-schema-form-listener-types.d.ts.map +1 -0
- package/dist/components/json-schema-form-listeners.cjs +250 -0
- package/dist/components/json-schema-form-listeners.cjs.map +1 -0
- package/dist/components/json-schema-form-listeners.d.ts +13 -0
- package/dist/components/json-schema-form-listeners.d.ts.map +1 -0
- package/dist/components/json-schema-form-listeners.js +250 -0
- package/dist/components/json-schema-form-listeners.js.map +1 -0
- package/dist/components/json-schema-form-object-array-view.cjs +62 -0
- package/dist/components/json-schema-form-object-array-view.cjs.map +1 -0
- package/dist/components/json-schema-form-object-array-view.d.ts +14 -0
- package/dist/components/json-schema-form-object-array-view.d.ts.map +1 -0
- package/dist/components/json-schema-form-object-array-view.js +62 -0
- package/dist/components/json-schema-form-object-array-view.js.map +1 -0
- package/dist/components/json-schema-form-object.cjs +3 -0
- package/dist/components/json-schema-form-object.cjs.map +1 -1
- package/dist/components/json-schema-form-object.d.ts.map +1 -1
- package/dist/components/json-schema-form-object.js +3 -0
- package/dist/components/json-schema-form-object.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +17 -9
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +19 -11
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +6 -99
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts +1 -8
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +5 -98
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-runtime-types.d.ts +15 -0
- package/dist/components/json-schema-form-runtime-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-table-array.cjs +67 -16
- package/dist/components/json-schema-form-table-array.cjs.map +1 -1
- package/dist/components/json-schema-form-table-array.d.ts +4 -1
- package/dist/components/json-schema-form-table-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-table-array.js +70 -19
- package/dist/components/json-schema-form-table-array.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +16 -0
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.cjs +7 -1
- package/dist/components/json-schema-form-utils.cjs.map +1 -1
- package/dist/components/json-schema-form-utils.d.ts +2 -1
- package/dist/components/json-schema-form-utils.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.js +7 -1
- package/dist/components/json-schema-form-utils.js.map +1 -1
- package/dist/components.cjs +3 -2
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -2
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +2 -1
- package/dist/components.js.map +1 -1
- package/dist/data/DataTable.cjs +9 -3
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +6 -0
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +9 -3
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/FixtureEditor/FixtureEditor.cjs +43 -24
- package/dist/data/FixtureEditor/FixtureEditor.cjs.map +1 -1
- package/dist/data/FixtureEditor/FixtureEditor.d.ts.map +1 -1
- package/dist/data/FixtureEditor/FixtureEditor.js +43 -24
- package/dist/data/FixtureEditor/FixtureEditor.js.map +1 -1
- package/dist/data/Tree.cjs +10 -2
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.d.ts +6 -1
- package/dist/data/Tree.d.ts.map +1 -1
- package/dist/data/Tree.js +10 -2
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/ai/SessionInspector.cjs +143 -167
- package/dist/data/ai/SessionInspector.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.collection-types.d.ts +5 -0
- package/dist/data/ai/SessionInspector.collection-types.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.collection.cjs +18 -5
- package/dist/data/ai/SessionInspector.collection.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.collection.d.ts +2 -0
- package/dist/data/ai/SessionInspector.collection.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.collection.fixtures.d.ts +6 -0
- package/dist/data/ai/SessionInspector.collection.fixtures.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.collection.js +18 -5
- package/dist/data/ai/SessionInspector.collection.js.map +1 -1
- package/dist/data/ai/SessionInspector.d.ts +24 -2
- package/dist/data/ai/SessionInspector.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.cjs +105 -7
- package/dist/data/ai/SessionInspector.hierarchy-state.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.d.ts +12 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy-state.js +107 -9
- package/dist/data/ai/SessionInspector.hierarchy-state.js.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js.map +1 -1
- package/dist/data/ai/SessionInspector.js +144 -168
- package/dist/data/ai/SessionInspector.js.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.cjs +116 -0
- package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.legacy.d.ts +19 -0
- package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.legacy.js +116 -0
- package/dist/data/ai/SessionInspector.legacy.js.map +1 -0
- package/dist/data/ai/SessionInspector.panels.cjs +3 -0
- package/dist/data/ai/SessionInspector.panels.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.panels.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.panels.js +3 -0
- package/dist/data/ai/SessionInspector.panels.js.map +1 -1
- package/dist/data/ai/SessionInspector.plan.cjs +29 -12
- package/dist/data/ai/SessionInspector.plan.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.plan.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.plan.js +30 -13
- package/dist/data/ai/SessionInspector.plan.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.cjs +44 -0
- package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.remote-view.d.ts +11 -0
- package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.remote-view.js +44 -0
- package/dist/data/ai/SessionInspector.remote-view.js.map +1 -0
- package/dist/data/ai/SessionInspector.remote.cjs +275 -0
- package/dist/data/ai/SessionInspector.remote.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.remote.d.ts +57 -0
- package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.remote.js +275 -0
- package/dist/data/ai/SessionInspector.remote.js.map +1 -0
- package/dist/data/ai/SessionInspector.summary.cjs +0 -156
- package/dist/data/ai/SessionInspector.summary.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.summary.d.ts +0 -3
- package/dist/data/ai/SessionInspector.summary.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.summary.js +2 -158
- package/dist/data/ai/SessionInspector.summary.js.map +1 -1
- package/dist/data/ai/SessionInspector.tab-state.cjs +15 -0
- package/dist/data/ai/SessionInspector.tab-state.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.tab-state.d.ts +3 -0
- package/dist/data/ai/SessionInspector.tab-state.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.tab-state.js +15 -0
- package/dist/data/ai/SessionInspector.tab-state.js.map +1 -0
- package/dist/data/ai/SessionInspector.tabs.model.cjs +31 -18
- package/dist/data/ai/SessionInspector.tabs.model.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.tabs.model.d.ts +3 -1
- package/dist/data/ai/SessionInspector.tabs.model.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.tabs.model.js +32 -19
- package/dist/data/ai/SessionInspector.tabs.model.js.map +1 -1
- package/dist/data/ai/SessionInspector.verification.cjs +53 -0
- package/dist/data/ai/SessionInspector.verification.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.verification.d.ts +7 -0
- package/dist/data/ai/SessionInspector.verification.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.verification.js +53 -0
- package/dist/data/ai/SessionInspector.verification.js.map +1 -0
- package/dist/data/ai/SessionViewer.model.cjs +7 -1
- package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.model.d.ts +21 -3
- package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.model.js +7 -1
- package/dist/data/ai/SessionViewer.model.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +13 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/index.d.ts +3 -1
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/devtools/useDebugStream.cjs +5 -1
- package/dist/devtools/useDebugStream.cjs.map +1 -1
- package/dist/devtools/useDebugStream.d.ts.map +1 -1
- package/dist/devtools/useDebugStream.js +6 -2
- package/dist/devtools/useDebugStream.js.map +1 -1
- package/dist/hooks/event-source-provider.cjs +9 -0
- package/dist/hooks/event-source-provider.cjs.map +1 -0
- package/dist/hooks/event-source-provider.d.ts +15 -0
- package/dist/hooks/event-source-provider.d.ts.map +1 -0
- package/dist/hooks/event-source-provider.js +9 -0
- package/dist/hooks/event-source-provider.js.map +1 -0
- package/dist/hooks/event-source.cjs +11 -0
- package/dist/hooks/event-source.cjs.map +1 -0
- package/dist/hooks/event-source.d.ts +22 -0
- package/dist/hooks/event-source.d.ts.map +1 -0
- package/dist/hooks/event-source.js +11 -0
- package/dist/hooks/event-source.js.map +1 -0
- package/dist/hooks/use-log-tail.cjs +5 -1
- package/dist/hooks/use-log-tail.cjs.map +1 -1
- package/dist/hooks/use-log-tail.d.ts.map +1 -1
- package/dist/hooks/use-log-tail.js +5 -1
- package/dist/hooks/use-log-tail.js.map +1 -1
- package/dist/hooks/use-prompts.cjs +5 -1
- package/dist/hooks/use-prompts.cjs.map +1 -1
- package/dist/hooks/use-prompts.d.ts.map +1 -1
- package/dist/hooks/use-prompts.js +6 -2
- package/dist/hooks/use-prompts.js.map +1 -1
- package/dist/hooks/use-task-run.cjs +9 -2
- package/dist/hooks/use-task-run.cjs.map +1 -1
- package/dist/hooks/use-task-run.d.ts.map +1 -1
- package/dist/hooks/use-task-run.js +10 -3
- package/dist/hooks/use-task-run.js.map +1 -1
- package/dist/hooks.cjs +4 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +4 -0
- package/dist/hooks.js.map +1 -1
- package/dist/icons/programmingCatalog.cjs +34 -34
- package/dist/icons/programmingCatalog.cjs.map +1 -1
- package/dist/icons/programmingCatalog.js +34 -34
- package/dist/icons/programmingCatalog.js.map +1 -1
- package/dist/index.cjs +9 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/monaco/MonacoEditor.cjs +4 -1
- package/dist/monaco/MonacoEditor.cjs.map +1 -1
- package/dist/monaco/MonacoEditor.d.ts +1 -1
- package/dist/monaco/MonacoEditor.d.ts.map +1 -1
- package/dist/monaco/MonacoEditor.js +4 -1
- package/dist/monaco/MonacoEditor.js.map +1 -1
- package/dist/monaco/types.d.ts +2 -1
- package/dist/monaco/types.d.ts.map +1 -1
- package/dist/overlay/CommandPalette.cjs +14 -4
- package/dist/overlay/CommandPalette.cjs.map +1 -1
- package/dist/overlay/CommandPalette.d.ts +5 -1
- package/dist/overlay/CommandPalette.d.ts.map +1 -1
- package/dist/overlay/CommandPalette.js +14 -4
- package/dist/overlay/CommandPalette.js.map +1 -1
- package/dist/overlay/CommandPaletteList.cjs +5 -0
- package/dist/overlay/CommandPaletteList.cjs.map +1 -1
- package/dist/overlay/CommandPaletteList.d.ts +4 -2
- package/dist/overlay/CommandPaletteList.d.ts.map +1 -1
- package/dist/overlay/CommandPaletteList.js +5 -0
- package/dist/overlay/CommandPaletteList.js.map +1 -1
- package/dist/overlay/DropdownMenu.cjs +1 -0
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.js +1 -0
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +29 -26
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +9 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +29 -26
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.cjs +62 -256
- package/dist/rpc/OperationEntityContextPicker.cjs.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.d.ts.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.js +64 -258
- package/dist/rpc/OperationEntityContextPicker.js.map +1 -1
- package/dist/rpc/OperationEntityPicker.cjs +185 -0
- package/dist/rpc/OperationEntityPicker.cjs.map +1 -0
- package/dist/rpc/OperationEntityPicker.d.ts +51 -0
- package/dist/rpc/OperationEntityPicker.d.ts.map +1 -0
- package/dist/rpc/OperationEntityPicker.js +185 -0
- package/dist/rpc/OperationEntityPicker.js.map +1 -0
- package/dist/rpc/OperationEntityPicker.model.cjs +39 -0
- package/dist/rpc/OperationEntityPicker.model.cjs.map +1 -0
- package/dist/rpc/OperationEntityPicker.model.d.ts +27 -0
- package/dist/rpc/OperationEntityPicker.model.d.ts.map +1 -0
- package/dist/rpc/OperationEntityPicker.model.js +39 -0
- package/dist/rpc/OperationEntityPicker.model.js.map +1 -0
- package/dist/rpc/operationCatalogRowSelection.cjs +85 -0
- package/dist/rpc/operationCatalogRowSelection.cjs.map +1 -0
- package/dist/rpc/operationCatalogRowSelection.d.ts +57 -0
- package/dist/rpc/operationCatalogRowSelection.d.ts.map +1 -0
- package/dist/rpc/operationCatalogRowSelection.js +85 -0
- package/dist/rpc/operationCatalogRowSelection.js.map +1 -0
- package/dist/rpc/operationEntityPicker.fixtures.d.ts +13 -0
- package/dist/rpc/operationEntityPicker.fixtures.d.ts.map +1 -0
- package/dist/rpc.cjs +2 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +2 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +4 -1
- package/schemas/json-schema-form.schema.json +566 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const reactQuery = require("@tanstack/react-query");
|
|
6
|
+
const button = require("../components/button.cjs");
|
|
7
|
+
const Modal = require("../overlay/Modal.cjs");
|
|
8
|
+
const clickyMetadata = require("./clickyMetadata.cjs");
|
|
9
|
+
const formMetadata = require("./formMetadata.cjs");
|
|
10
|
+
const OperationCatalog = require("./OperationCatalog.cjs");
|
|
11
|
+
const operationCatalogRowSelection = require("./operationCatalogRowSelection.cjs");
|
|
12
|
+
const OperationEntityPicker_model = require("./OperationEntityPicker.model.cjs");
|
|
13
|
+
const rowNavigation = require("./rowNavigation.cjs");
|
|
14
|
+
const useOperations = require("./useOperations.cjs");
|
|
15
|
+
const EMPTY_VALUES = {};
|
|
16
|
+
const EMPTY_IDS = [];
|
|
17
|
+
const defaultSelectLabel = ({ pending }) => pending ? "Selecting…" : "Select";
|
|
18
|
+
const pickerRenderLink = () => {
|
|
19
|
+
throw new Error("OperationEntityPicker renders no endpoint links");
|
|
20
|
+
};
|
|
21
|
+
function OperationEntityPicker({
|
|
22
|
+
open,
|
|
23
|
+
onClose,
|
|
24
|
+
title,
|
|
25
|
+
client,
|
|
26
|
+
surfaceKey,
|
|
27
|
+
mode = "single",
|
|
28
|
+
selected = EMPTY_IDS,
|
|
29
|
+
onSelect,
|
|
30
|
+
lockedValues = EMPTY_VALUES,
|
|
31
|
+
lockedLabels,
|
|
32
|
+
initialValues = EMPTY_VALUES,
|
|
33
|
+
unavailableRows,
|
|
34
|
+
selectLabel = defaultSelectLabel,
|
|
35
|
+
note,
|
|
36
|
+
filterPre,
|
|
37
|
+
hiddenColumns,
|
|
38
|
+
cellRenderers
|
|
39
|
+
}) {
|
|
40
|
+
const openingContext = react.useMemo(
|
|
41
|
+
() => ({ filters: { ...initialValues, ...lockedValues } }),
|
|
42
|
+
[initialValues, lockedValues]
|
|
43
|
+
);
|
|
44
|
+
const [ids, setIds] = react.useState(selected);
|
|
45
|
+
const [rowsById, setRowsById] = react.useState({});
|
|
46
|
+
const [context, setContext] = react.useState(openingContext);
|
|
47
|
+
const [pending, setPending] = react.useState(false);
|
|
48
|
+
const [error, setError] = react.useState("");
|
|
49
|
+
const [wasOpen, setWasOpen] = react.useState(false);
|
|
50
|
+
if (open !== wasOpen) {
|
|
51
|
+
setWasOpen(open);
|
|
52
|
+
if (open) {
|
|
53
|
+
setIds(selected);
|
|
54
|
+
setRowsById({});
|
|
55
|
+
setContext(openingContext);
|
|
56
|
+
setPending(false);
|
|
57
|
+
setError("");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const { operations, spec } = useOperations.useOperations(client);
|
|
61
|
+
const listOperation = react.useMemo(
|
|
62
|
+
() => clickyMetadata.findSurfaceListOperation(clickyMetadata.filterOperationsBySurface(operations, surfaceKey), surfaceKey),
|
|
63
|
+
[operations, surfaceKey]
|
|
64
|
+
);
|
|
65
|
+
const surface = clickyMetadata.getClickySurfaces(spec).find((entry) => entry.key === surfaceKey);
|
|
66
|
+
const listParameters = listOperation == null ? void 0 : listOperation.operation.parameters;
|
|
67
|
+
const lookup = reactQuery.useQuery({
|
|
68
|
+
...operationCatalogRowSelection.operationLookupQuery(
|
|
69
|
+
client,
|
|
70
|
+
listOperation,
|
|
71
|
+
formMetadata.packLookupParameterValues(openingContext.filters, listParameters ?? [])
|
|
72
|
+
),
|
|
73
|
+
enabled: false
|
|
74
|
+
});
|
|
75
|
+
const scope = react.useMemo(
|
|
76
|
+
() => {
|
|
77
|
+
var _a;
|
|
78
|
+
return listParameters ? OperationEntityPicker_model.lockedScopeEntries({
|
|
79
|
+
lockedValues,
|
|
80
|
+
lockedLabels,
|
|
81
|
+
parameters: listParameters,
|
|
82
|
+
lookup: lookup.data,
|
|
83
|
+
components: (_a = spec == null ? void 0 : spec.components) == null ? void 0 : _a["x-clicky-filters"]
|
|
84
|
+
}) : [];
|
|
85
|
+
},
|
|
86
|
+
[listParameters, lockedLabels, lockedValues, lookup.data, spec]
|
|
87
|
+
);
|
|
88
|
+
const pickedRows = ids.flatMap((id) => {
|
|
89
|
+
const row = rowsById[id];
|
|
90
|
+
return row ? [row] : [];
|
|
91
|
+
});
|
|
92
|
+
const confirm = async () => {
|
|
93
|
+
setPending(true);
|
|
94
|
+
setError("");
|
|
95
|
+
try {
|
|
96
|
+
await onSelect(ids, pickedRows, context);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
99
|
+
setPending(false);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
setPending(false);
|
|
103
|
+
onClose();
|
|
104
|
+
};
|
|
105
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
106
|
+
Modal.Modal,
|
|
107
|
+
{
|
|
108
|
+
open,
|
|
109
|
+
onClose,
|
|
110
|
+
title,
|
|
111
|
+
size: "2xl",
|
|
112
|
+
expandable: true,
|
|
113
|
+
scrollBody: false,
|
|
114
|
+
footer: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
115
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
116
|
+
ids.length,
|
|
117
|
+
" selected"
|
|
118
|
+
] }),
|
|
119
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", variant: "outline", onClick: onClose, disabled: pending, children: "Cancel" }),
|
|
121
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
122
|
+
button.Button,
|
|
123
|
+
{
|
|
124
|
+
type: "button",
|
|
125
|
+
onClick: () => void confirm(),
|
|
126
|
+
disabled: ids.length === 0 || pending,
|
|
127
|
+
children: selectLabel({ count: ids.length, pending })
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
] })
|
|
131
|
+
] }),
|
|
132
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-3", children: [
|
|
133
|
+
scope.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", "data-slot": "operation-picker-scope", children: `Scoped to: ${scope.map((entry) => `${entry.label} = ${entry.value}`).join(" · ")}` }) : null,
|
|
134
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
135
|
+
"div",
|
|
136
|
+
{
|
|
137
|
+
role: "alert",
|
|
138
|
+
className: "rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive",
|
|
139
|
+
children: error
|
|
140
|
+
}
|
|
141
|
+
) : null,
|
|
142
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
143
|
+
OperationCatalog.OperationCatalog,
|
|
144
|
+
{
|
|
145
|
+
definition: {
|
|
146
|
+
key: surfaceKey,
|
|
147
|
+
title: (surface == null ? void 0 : surface.title) ?? surfaceKey,
|
|
148
|
+
description: (surface == null ? void 0 : surface.description) ?? ""
|
|
149
|
+
},
|
|
150
|
+
entities: [],
|
|
151
|
+
client,
|
|
152
|
+
surfaceKey,
|
|
153
|
+
renderLink: pickerRenderLink,
|
|
154
|
+
urlState: false,
|
|
155
|
+
lockedValues,
|
|
156
|
+
initialValues,
|
|
157
|
+
...filterPre ? { filterPre } : {},
|
|
158
|
+
...hiddenColumns ? { hiddenColumns } : {},
|
|
159
|
+
...cellRenderers ? { cellRenderers } : {},
|
|
160
|
+
rowSelection: {
|
|
161
|
+
mode,
|
|
162
|
+
selectedRowIds: ids,
|
|
163
|
+
onSelectionChange: (next, rows, nextContext) => {
|
|
164
|
+
const loaded = new Map(
|
|
165
|
+
rows.flatMap((row) => {
|
|
166
|
+
const id = rowNavigation.getClickyRowId(row);
|
|
167
|
+
return id ? [[id, row]] : [];
|
|
168
|
+
})
|
|
169
|
+
);
|
|
170
|
+
setIds(next);
|
|
171
|
+
setRowsById((prev) => OperationEntityPicker_model.reconcilePickedRows(prev, next, loaded));
|
|
172
|
+
setContext(nextContext);
|
|
173
|
+
},
|
|
174
|
+
...unavailableRows ? { unavailableRows } : {}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
surfaceKey
|
|
178
|
+
) }),
|
|
179
|
+
note
|
|
180
|
+
] })
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
exports.OperationEntityPicker = OperationEntityPicker;
|
|
185
|
+
//# sourceMappingURL=OperationEntityPicker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperationEntityPicker.cjs","sources":["../../src/rpc/OperationEntityPicker.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { Button } from \"../components/button\";\nimport type { FilterExtension } from \"../components/filter-bar-utils\";\nimport type { ClickyCellRenderers, ClickyRow } from \"../data/Clicky\";\nimport { Modal } from \"../overlay/Modal\";\nimport {\n filterOperationsBySurface,\n findSurfaceListOperation,\n getClickySurfaces,\n} from \"./clickyMetadata\";\nimport type { RenderLink } from \"./EndpointList\";\nimport { packLookupParameterValues } from \"./formMetadata\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport {\n operationLookupQuery,\n type OperationCatalogRowSelectionContext,\n type OperationCatalogRowSelectionMode,\n type OperationCatalogUnavailableRows,\n} from \"./operationCatalogRowSelection\";\nimport { lockedScopeEntries, reconcilePickedRows } from \"./OperationEntityPicker.model\";\nimport { getClickyRowId } from \"./rowNavigation\";\nimport { useOperations, type OperationsApiClient } from \"./useOperations\";\n\nexport type OperationEntityPickerProps = {\n open: boolean;\n onClose: () => void;\n title: string;\n client: OperationsApiClient;\n /** The clicky surface whose list operation supplies the rows. */\n surfaceKey: string;\n /** Defaults to \"single\": checking a row replaces the previous one. */\n mode?: OperationCatalogRowSelectionMode;\n /** Ids checked each time the dialog opens. */\n selected?: string[];\n /**\n * Called by Select with the checked ids and, in the same order, the row of\n * each id the reader checked while the dialog was open — an id carried in\n * through `selected` and left untouched has no row. `context.filters` is the\n * list scope at the last selection change (the opening scope when the reader\n * never changed it). The dialog closes when this returns or resolves; a\n * rejection is shown in the dialog, which stays open.\n */\n onSelect: (\n ids: string[],\n rows: ClickyRow[],\n context: OperationCatalogRowSelectionContext,\n ) => void | Promise<void>;\n /** Pinned list parameters, shown only as the read-only \"Scoped to\" line. */\n lockedValues?: Record<string, string>;\n /** Display names for locked parameter keys, overriding the filter labels. */\n lockedLabels?: Record<string, string>;\n /** Editable starting values for the dialog's filters. */\n initialValues?: Record<string, string>;\n unavailableRows?: OperationCatalogUnavailableRows;\n /** Label of the confirm button; defaults to \"Select\" / \"Selecting…\". */\n selectLabel?: (state: { count: number; pending: boolean }) => string;\n /** Extra content under the table. */\n note?: ReactNode;\n filterPre?: FilterExtension[];\n hiddenColumns?: string[];\n cellRenderers?: ClickyCellRenderers;\n};\n\nconst EMPTY_VALUES: Record<string, string> = {};\nconst EMPTY_IDS: string[] = [];\n\nconst defaultSelectLabel = ({ pending }: { pending: boolean }) =>\n pending ? \"Selecting…\" : \"Select\";\n\n// In picker mode OperationCatalog refuses a surface without a list operation\n// before it would render its endpoint links, so no link is ever rendered.\nconst pickerRenderLink: RenderLink = () => {\n throw new Error(\"OperationEntityPicker renders no endpoint links\");\n};\n\n/**\n * OperationEntityPicker is a dialog for picking one or more rows from a clicky\n * surface's list operation, optionally scoped by locked parameter values. It is\n * OperationCatalog in picker mode (a checkbox per row, row click toggles) plus\n * a Cancel / Select footer.\n */\nexport function OperationEntityPicker({\n open,\n onClose,\n title,\n client,\n surfaceKey,\n mode = \"single\",\n selected = EMPTY_IDS,\n onSelect,\n lockedValues = EMPTY_VALUES,\n lockedLabels,\n initialValues = EMPTY_VALUES,\n unavailableRows,\n selectLabel = defaultSelectLabel,\n note,\n filterPre,\n hiddenColumns,\n cellRenderers,\n}: OperationEntityPickerProps) {\n const openingContext = useMemo(\n () => ({ filters: { ...initialValues, ...lockedValues } }),\n [initialValues, lockedValues],\n );\n const [ids, setIds] = useState<string[]>(selected);\n const [rowsById, setRowsById] = useState<Record<string, ClickyRow>>({});\n const [context, setContext] = useState(openingContext);\n const [pending, setPending] = useState(false);\n const [error, setError] = useState(\"\");\n // Reset on every open, during render so the table never shows the last\n // session's checks for a frame (Modal stays mounted for its exit transition).\n const [wasOpen, setWasOpen] = useState(false);\n if (open !== wasOpen) {\n setWasOpen(open);\n if (open) {\n setIds(selected);\n setRowsById({});\n setContext(openingContext);\n setPending(false);\n setError(\"\");\n }\n }\n\n const { operations, spec } = useOperations(client);\n const listOperation = useMemo(\n () =>\n findSurfaceListOperation(filterOperationsBySurface(operations, surfaceKey), surfaceKey),\n [operations, surfaceKey],\n );\n const surface = getClickySurfaces(spec).find((entry) => entry.key === surfaceKey);\n const listParameters = listOperation?.operation.parameters;\n // Observes (never fetches) the lookup the catalog issues for the opening\n // scope, so the scope line can name a locked GUID by its option label.\n const lookup = useQuery({\n ...operationLookupQuery(\n client,\n listOperation,\n packLookupParameterValues(openingContext.filters, listParameters ?? []),\n ),\n enabled: false,\n });\n const scope = useMemo(\n () =>\n listParameters\n ? lockedScopeEntries({\n lockedValues,\n lockedLabels,\n parameters: listParameters,\n lookup: lookup.data,\n components: spec?.components?.[\"x-clicky-filters\"],\n })\n : [],\n [listParameters, lockedLabels, lockedValues, lookup.data, spec],\n );\n\n const pickedRows = ids.flatMap((id) => {\n const row = rowsById[id];\n return row ? [row] : [];\n });\n const confirm = async () => {\n setPending(true);\n setError(\"\");\n try {\n await onSelect(ids, pickedRows, context);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setPending(false);\n return;\n }\n setPending(false);\n onClose();\n };\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n size=\"2xl\"\n expandable\n scrollBody={false}\n footer={\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-xs text-muted-foreground\">{ids.length} selected</span>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={onClose} disabled={pending}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={() => void confirm()}\n disabled={ids.length === 0 || pending}\n >\n {selectLabel({ count: ids.length, pending })}\n </Button>\n </div>\n </div>\n }\n >\n <div className=\"flex min-h-0 flex-1 flex-col gap-3\">\n {scope.length > 0 ? (\n <p className=\"text-xs text-muted-foreground\" data-slot=\"operation-picker-scope\">\n {`Scoped to: ${scope.map((entry) => `${entry.label} = ${entry.value}`).join(\" · \")}`}\n </p>\n ) : null}\n {error ? (\n <div\n role=\"alert\"\n className=\"rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\"\n >\n {error}\n </div>\n ) : null}\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <OperationCatalog\n key={surfaceKey}\n definition={{\n key: surfaceKey,\n title: surface?.title ?? surfaceKey,\n description: surface?.description ?? \"\",\n }}\n entities={[]}\n client={client}\n surfaceKey={surfaceKey}\n renderLink={pickerRenderLink}\n urlState={false}\n lockedValues={lockedValues}\n initialValues={initialValues}\n {...(filterPre ? { filterPre } : {})}\n {...(hiddenColumns ? { hiddenColumns } : {})}\n {...(cellRenderers ? { cellRenderers } : {})}\n rowSelection={{\n mode,\n selectedRowIds: ids,\n onSelectionChange: (next, rows, nextContext) => {\n const loaded = new Map(\n rows.flatMap((row) => {\n const id = getClickyRowId(row);\n return id ? [[id, row] as const] : [];\n }),\n );\n setIds(next);\n setRowsById((prev) => reconcilePickedRows(prev, next, loaded));\n setContext(nextContext);\n },\n ...(unavailableRows ? { unavailableRows } : {}),\n }}\n />\n </div>\n {note}\n </div>\n </Modal>\n );\n}\n"],"names":["useMemo","useState","useOperations","findSurfaceListOperation","filterOperationsBySurface","getClickySurfaces","useQuery","operationLookupQuery","packLookupParameterValues","lockedScopeEntries","jsx","Modal","jsxs","Button","OperationCatalog","getClickyRowId","reconcilePickedRows"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { FilterExtension } from '../components/filter-bar-utils.js';
|
|
3
|
+
import { ClickyCellRenderers, ClickyRow } from '../data/Clicky.js';
|
|
4
|
+
import { OperationCatalogRowSelectionContext, OperationCatalogRowSelectionMode, OperationCatalogUnavailableRows } from './operationCatalogRowSelection.js';
|
|
5
|
+
import { OperationsApiClient } from './useOperations.js';
|
|
6
|
+
export type OperationEntityPickerProps = {
|
|
7
|
+
open: boolean;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
title: string;
|
|
10
|
+
client: OperationsApiClient;
|
|
11
|
+
/** The clicky surface whose list operation supplies the rows. */
|
|
12
|
+
surfaceKey: string;
|
|
13
|
+
/** Defaults to "single": checking a row replaces the previous one. */
|
|
14
|
+
mode?: OperationCatalogRowSelectionMode;
|
|
15
|
+
/** Ids checked each time the dialog opens. */
|
|
16
|
+
selected?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Called by Select with the checked ids and, in the same order, the row of
|
|
19
|
+
* each id the reader checked while the dialog was open — an id carried in
|
|
20
|
+
* through `selected` and left untouched has no row. `context.filters` is the
|
|
21
|
+
* list scope at the last selection change (the opening scope when the reader
|
|
22
|
+
* never changed it). The dialog closes when this returns or resolves; a
|
|
23
|
+
* rejection is shown in the dialog, which stays open.
|
|
24
|
+
*/
|
|
25
|
+
onSelect: (ids: string[], rows: ClickyRow[], context: OperationCatalogRowSelectionContext) => void | Promise<void>;
|
|
26
|
+
/** Pinned list parameters, shown only as the read-only "Scoped to" line. */
|
|
27
|
+
lockedValues?: Record<string, string>;
|
|
28
|
+
/** Display names for locked parameter keys, overriding the filter labels. */
|
|
29
|
+
lockedLabels?: Record<string, string>;
|
|
30
|
+
/** Editable starting values for the dialog's filters. */
|
|
31
|
+
initialValues?: Record<string, string>;
|
|
32
|
+
unavailableRows?: OperationCatalogUnavailableRows;
|
|
33
|
+
/** Label of the confirm button; defaults to "Select" / "Selecting…". */
|
|
34
|
+
selectLabel?: (state: {
|
|
35
|
+
count: number;
|
|
36
|
+
pending: boolean;
|
|
37
|
+
}) => string;
|
|
38
|
+
/** Extra content under the table. */
|
|
39
|
+
note?: ReactNode;
|
|
40
|
+
filterPre?: FilterExtension[];
|
|
41
|
+
hiddenColumns?: string[];
|
|
42
|
+
cellRenderers?: ClickyCellRenderers;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* OperationEntityPicker is a dialog for picking one or more rows from a clicky
|
|
46
|
+
* surface's list operation, optionally scoped by locked parameter values. It is
|
|
47
|
+
* OperationCatalog in picker mode (a checkbox per row, row click toggles) plus
|
|
48
|
+
* a Cancel / Select footer.
|
|
49
|
+
*/
|
|
50
|
+
export declare function OperationEntityPicker({ open, onClose, title, client, surfaceKey, mode, selected, onSelect, lockedValues, lockedLabels, initialValues, unavailableRows, selectLabel, note, filterPre, hiddenColumns, cellRenderers, }: OperationEntityPickerProps): import("react").JSX.Element;
|
|
51
|
+
//# sourceMappingURL=OperationEntityPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperationEntityPicker.d.ts","sourceRoot":"","sources":["../../src/rpc/OperationEntityPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAUrE,OAAO,EAEL,KAAK,mCAAmC,EACxC,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,EACrC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,mBAAmB,CAAC;IAC5B,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,IAAI,CAAC,EAAE,gCAAgC,CAAC;IACxC,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;;;OAOG;IACH,QAAQ,EAAE,CACR,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,SAAS,EAAE,EACjB,OAAO,EAAE,mCAAmC,KACzC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,+BAA+B,CAAC;IAClD,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,MAAM,CAAC;IACrE,qCAAqC;IACrC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC,CAAC;AAcF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,UAAU,EACV,IAAe,EACf,QAAoB,EACpB,QAAQ,EACR,YAA2B,EAC3B,YAAY,EACZ,aAA4B,EAC5B,eAAe,EACf,WAAgC,EAChC,IAAI,EACJ,SAAS,EACT,aAAa,EACb,aAAa,GACd,EAAE,0BAA0B,+BA0J5B"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
|
+
import { useQuery } from "@tanstack/react-query";
|
|
4
|
+
import { Button } from "../components/button.js";
|
|
5
|
+
import { Modal } from "../overlay/Modal.js";
|
|
6
|
+
import { findSurfaceListOperation, filterOperationsBySurface, getClickySurfaces } from "./clickyMetadata.js";
|
|
7
|
+
import { packLookupParameterValues } from "./formMetadata.js";
|
|
8
|
+
import { OperationCatalog } from "./OperationCatalog.js";
|
|
9
|
+
import { operationLookupQuery } from "./operationCatalogRowSelection.js";
|
|
10
|
+
import { lockedScopeEntries, reconcilePickedRows } from "./OperationEntityPicker.model.js";
|
|
11
|
+
import { getClickyRowId } from "./rowNavigation.js";
|
|
12
|
+
import { useOperations } from "./useOperations.js";
|
|
13
|
+
const EMPTY_VALUES = {};
|
|
14
|
+
const EMPTY_IDS = [];
|
|
15
|
+
const defaultSelectLabel = ({ pending }) => pending ? "Selecting…" : "Select";
|
|
16
|
+
const pickerRenderLink = () => {
|
|
17
|
+
throw new Error("OperationEntityPicker renders no endpoint links");
|
|
18
|
+
};
|
|
19
|
+
function OperationEntityPicker({
|
|
20
|
+
open,
|
|
21
|
+
onClose,
|
|
22
|
+
title,
|
|
23
|
+
client,
|
|
24
|
+
surfaceKey,
|
|
25
|
+
mode = "single",
|
|
26
|
+
selected = EMPTY_IDS,
|
|
27
|
+
onSelect,
|
|
28
|
+
lockedValues = EMPTY_VALUES,
|
|
29
|
+
lockedLabels,
|
|
30
|
+
initialValues = EMPTY_VALUES,
|
|
31
|
+
unavailableRows,
|
|
32
|
+
selectLabel = defaultSelectLabel,
|
|
33
|
+
note,
|
|
34
|
+
filterPre,
|
|
35
|
+
hiddenColumns,
|
|
36
|
+
cellRenderers
|
|
37
|
+
}) {
|
|
38
|
+
const openingContext = useMemo(
|
|
39
|
+
() => ({ filters: { ...initialValues, ...lockedValues } }),
|
|
40
|
+
[initialValues, lockedValues]
|
|
41
|
+
);
|
|
42
|
+
const [ids, setIds] = useState(selected);
|
|
43
|
+
const [rowsById, setRowsById] = useState({});
|
|
44
|
+
const [context, setContext] = useState(openingContext);
|
|
45
|
+
const [pending, setPending] = useState(false);
|
|
46
|
+
const [error, setError] = useState("");
|
|
47
|
+
const [wasOpen, setWasOpen] = useState(false);
|
|
48
|
+
if (open !== wasOpen) {
|
|
49
|
+
setWasOpen(open);
|
|
50
|
+
if (open) {
|
|
51
|
+
setIds(selected);
|
|
52
|
+
setRowsById({});
|
|
53
|
+
setContext(openingContext);
|
|
54
|
+
setPending(false);
|
|
55
|
+
setError("");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const { operations, spec } = useOperations(client);
|
|
59
|
+
const listOperation = useMemo(
|
|
60
|
+
() => findSurfaceListOperation(filterOperationsBySurface(operations, surfaceKey), surfaceKey),
|
|
61
|
+
[operations, surfaceKey]
|
|
62
|
+
);
|
|
63
|
+
const surface = getClickySurfaces(spec).find((entry) => entry.key === surfaceKey);
|
|
64
|
+
const listParameters = listOperation == null ? void 0 : listOperation.operation.parameters;
|
|
65
|
+
const lookup = useQuery({
|
|
66
|
+
...operationLookupQuery(
|
|
67
|
+
client,
|
|
68
|
+
listOperation,
|
|
69
|
+
packLookupParameterValues(openingContext.filters, listParameters ?? [])
|
|
70
|
+
),
|
|
71
|
+
enabled: false
|
|
72
|
+
});
|
|
73
|
+
const scope = useMemo(
|
|
74
|
+
() => {
|
|
75
|
+
var _a;
|
|
76
|
+
return listParameters ? lockedScopeEntries({
|
|
77
|
+
lockedValues,
|
|
78
|
+
lockedLabels,
|
|
79
|
+
parameters: listParameters,
|
|
80
|
+
lookup: lookup.data,
|
|
81
|
+
components: (_a = spec == null ? void 0 : spec.components) == null ? void 0 : _a["x-clicky-filters"]
|
|
82
|
+
}) : [];
|
|
83
|
+
},
|
|
84
|
+
[listParameters, lockedLabels, lockedValues, lookup.data, spec]
|
|
85
|
+
);
|
|
86
|
+
const pickedRows = ids.flatMap((id) => {
|
|
87
|
+
const row = rowsById[id];
|
|
88
|
+
return row ? [row] : [];
|
|
89
|
+
});
|
|
90
|
+
const confirm = async () => {
|
|
91
|
+
setPending(true);
|
|
92
|
+
setError("");
|
|
93
|
+
try {
|
|
94
|
+
await onSelect(ids, pickedRows, context);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
97
|
+
setPending(false);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
setPending(false);
|
|
101
|
+
onClose();
|
|
102
|
+
};
|
|
103
|
+
return /* @__PURE__ */ jsx(
|
|
104
|
+
Modal,
|
|
105
|
+
{
|
|
106
|
+
open,
|
|
107
|
+
onClose,
|
|
108
|
+
title,
|
|
109
|
+
size: "2xl",
|
|
110
|
+
expandable: true,
|
|
111
|
+
scrollBody: false,
|
|
112
|
+
footer: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
113
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
114
|
+
ids.length,
|
|
115
|
+
" selected"
|
|
116
|
+
] }),
|
|
117
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
118
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: onClose, disabled: pending, children: "Cancel" }),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
Button,
|
|
121
|
+
{
|
|
122
|
+
type: "button",
|
|
123
|
+
onClick: () => void confirm(),
|
|
124
|
+
disabled: ids.length === 0 || pending,
|
|
125
|
+
children: selectLabel({ count: ids.length, pending })
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
] })
|
|
129
|
+
] }),
|
|
130
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-3", children: [
|
|
131
|
+
scope.length > 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", "data-slot": "operation-picker-scope", children: `Scoped to: ${scope.map((entry) => `${entry.label} = ${entry.value}`).join(" · ")}` }) : null,
|
|
132
|
+
error ? /* @__PURE__ */ jsx(
|
|
133
|
+
"div",
|
|
134
|
+
{
|
|
135
|
+
role: "alert",
|
|
136
|
+
className: "rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive",
|
|
137
|
+
children: error
|
|
138
|
+
}
|
|
139
|
+
) : null,
|
|
140
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ jsx(
|
|
141
|
+
OperationCatalog,
|
|
142
|
+
{
|
|
143
|
+
definition: {
|
|
144
|
+
key: surfaceKey,
|
|
145
|
+
title: (surface == null ? void 0 : surface.title) ?? surfaceKey,
|
|
146
|
+
description: (surface == null ? void 0 : surface.description) ?? ""
|
|
147
|
+
},
|
|
148
|
+
entities: [],
|
|
149
|
+
client,
|
|
150
|
+
surfaceKey,
|
|
151
|
+
renderLink: pickerRenderLink,
|
|
152
|
+
urlState: false,
|
|
153
|
+
lockedValues,
|
|
154
|
+
initialValues,
|
|
155
|
+
...filterPre ? { filterPre } : {},
|
|
156
|
+
...hiddenColumns ? { hiddenColumns } : {},
|
|
157
|
+
...cellRenderers ? { cellRenderers } : {},
|
|
158
|
+
rowSelection: {
|
|
159
|
+
mode,
|
|
160
|
+
selectedRowIds: ids,
|
|
161
|
+
onSelectionChange: (next, rows, nextContext) => {
|
|
162
|
+
const loaded = new Map(
|
|
163
|
+
rows.flatMap((row) => {
|
|
164
|
+
const id = getClickyRowId(row);
|
|
165
|
+
return id ? [[id, row]] : [];
|
|
166
|
+
})
|
|
167
|
+
);
|
|
168
|
+
setIds(next);
|
|
169
|
+
setRowsById((prev) => reconcilePickedRows(prev, next, loaded));
|
|
170
|
+
setContext(nextContext);
|
|
171
|
+
},
|
|
172
|
+
...unavailableRows ? { unavailableRows } : {}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
surfaceKey
|
|
176
|
+
) }),
|
|
177
|
+
note
|
|
178
|
+
] })
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
export {
|
|
183
|
+
OperationEntityPicker
|
|
184
|
+
};
|
|
185
|
+
//# sourceMappingURL=OperationEntityPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperationEntityPicker.js","sources":["../../src/rpc/OperationEntityPicker.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { Button } from \"../components/button\";\nimport type { FilterExtension } from \"../components/filter-bar-utils\";\nimport type { ClickyCellRenderers, ClickyRow } from \"../data/Clicky\";\nimport { Modal } from \"../overlay/Modal\";\nimport {\n filterOperationsBySurface,\n findSurfaceListOperation,\n getClickySurfaces,\n} from \"./clickyMetadata\";\nimport type { RenderLink } from \"./EndpointList\";\nimport { packLookupParameterValues } from \"./formMetadata\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport {\n operationLookupQuery,\n type OperationCatalogRowSelectionContext,\n type OperationCatalogRowSelectionMode,\n type OperationCatalogUnavailableRows,\n} from \"./operationCatalogRowSelection\";\nimport { lockedScopeEntries, reconcilePickedRows } from \"./OperationEntityPicker.model\";\nimport { getClickyRowId } from \"./rowNavigation\";\nimport { useOperations, type OperationsApiClient } from \"./useOperations\";\n\nexport type OperationEntityPickerProps = {\n open: boolean;\n onClose: () => void;\n title: string;\n client: OperationsApiClient;\n /** The clicky surface whose list operation supplies the rows. */\n surfaceKey: string;\n /** Defaults to \"single\": checking a row replaces the previous one. */\n mode?: OperationCatalogRowSelectionMode;\n /** Ids checked each time the dialog opens. */\n selected?: string[];\n /**\n * Called by Select with the checked ids and, in the same order, the row of\n * each id the reader checked while the dialog was open — an id carried in\n * through `selected` and left untouched has no row. `context.filters` is the\n * list scope at the last selection change (the opening scope when the reader\n * never changed it). The dialog closes when this returns or resolves; a\n * rejection is shown in the dialog, which stays open.\n */\n onSelect: (\n ids: string[],\n rows: ClickyRow[],\n context: OperationCatalogRowSelectionContext,\n ) => void | Promise<void>;\n /** Pinned list parameters, shown only as the read-only \"Scoped to\" line. */\n lockedValues?: Record<string, string>;\n /** Display names for locked parameter keys, overriding the filter labels. */\n lockedLabels?: Record<string, string>;\n /** Editable starting values for the dialog's filters. */\n initialValues?: Record<string, string>;\n unavailableRows?: OperationCatalogUnavailableRows;\n /** Label of the confirm button; defaults to \"Select\" / \"Selecting…\". */\n selectLabel?: (state: { count: number; pending: boolean }) => string;\n /** Extra content under the table. */\n note?: ReactNode;\n filterPre?: FilterExtension[];\n hiddenColumns?: string[];\n cellRenderers?: ClickyCellRenderers;\n};\n\nconst EMPTY_VALUES: Record<string, string> = {};\nconst EMPTY_IDS: string[] = [];\n\nconst defaultSelectLabel = ({ pending }: { pending: boolean }) =>\n pending ? \"Selecting…\" : \"Select\";\n\n// In picker mode OperationCatalog refuses a surface without a list operation\n// before it would render its endpoint links, so no link is ever rendered.\nconst pickerRenderLink: RenderLink = () => {\n throw new Error(\"OperationEntityPicker renders no endpoint links\");\n};\n\n/**\n * OperationEntityPicker is a dialog for picking one or more rows from a clicky\n * surface's list operation, optionally scoped by locked parameter values. It is\n * OperationCatalog in picker mode (a checkbox per row, row click toggles) plus\n * a Cancel / Select footer.\n */\nexport function OperationEntityPicker({\n open,\n onClose,\n title,\n client,\n surfaceKey,\n mode = \"single\",\n selected = EMPTY_IDS,\n onSelect,\n lockedValues = EMPTY_VALUES,\n lockedLabels,\n initialValues = EMPTY_VALUES,\n unavailableRows,\n selectLabel = defaultSelectLabel,\n note,\n filterPre,\n hiddenColumns,\n cellRenderers,\n}: OperationEntityPickerProps) {\n const openingContext = useMemo(\n () => ({ filters: { ...initialValues, ...lockedValues } }),\n [initialValues, lockedValues],\n );\n const [ids, setIds] = useState<string[]>(selected);\n const [rowsById, setRowsById] = useState<Record<string, ClickyRow>>({});\n const [context, setContext] = useState(openingContext);\n const [pending, setPending] = useState(false);\n const [error, setError] = useState(\"\");\n // Reset on every open, during render so the table never shows the last\n // session's checks for a frame (Modal stays mounted for its exit transition).\n const [wasOpen, setWasOpen] = useState(false);\n if (open !== wasOpen) {\n setWasOpen(open);\n if (open) {\n setIds(selected);\n setRowsById({});\n setContext(openingContext);\n setPending(false);\n setError(\"\");\n }\n }\n\n const { operations, spec } = useOperations(client);\n const listOperation = useMemo(\n () =>\n findSurfaceListOperation(filterOperationsBySurface(operations, surfaceKey), surfaceKey),\n [operations, surfaceKey],\n );\n const surface = getClickySurfaces(spec).find((entry) => entry.key === surfaceKey);\n const listParameters = listOperation?.operation.parameters;\n // Observes (never fetches) the lookup the catalog issues for the opening\n // scope, so the scope line can name a locked GUID by its option label.\n const lookup = useQuery({\n ...operationLookupQuery(\n client,\n listOperation,\n packLookupParameterValues(openingContext.filters, listParameters ?? []),\n ),\n enabled: false,\n });\n const scope = useMemo(\n () =>\n listParameters\n ? lockedScopeEntries({\n lockedValues,\n lockedLabels,\n parameters: listParameters,\n lookup: lookup.data,\n components: spec?.components?.[\"x-clicky-filters\"],\n })\n : [],\n [listParameters, lockedLabels, lockedValues, lookup.data, spec],\n );\n\n const pickedRows = ids.flatMap((id) => {\n const row = rowsById[id];\n return row ? [row] : [];\n });\n const confirm = async () => {\n setPending(true);\n setError(\"\");\n try {\n await onSelect(ids, pickedRows, context);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setPending(false);\n return;\n }\n setPending(false);\n onClose();\n };\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n size=\"2xl\"\n expandable\n scrollBody={false}\n footer={\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-xs text-muted-foreground\">{ids.length} selected</span>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={onClose} disabled={pending}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={() => void confirm()}\n disabled={ids.length === 0 || pending}\n >\n {selectLabel({ count: ids.length, pending })}\n </Button>\n </div>\n </div>\n }\n >\n <div className=\"flex min-h-0 flex-1 flex-col gap-3\">\n {scope.length > 0 ? (\n <p className=\"text-xs text-muted-foreground\" data-slot=\"operation-picker-scope\">\n {`Scoped to: ${scope.map((entry) => `${entry.label} = ${entry.value}`).join(\" · \")}`}\n </p>\n ) : null}\n {error ? (\n <div\n role=\"alert\"\n className=\"rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\"\n >\n {error}\n </div>\n ) : null}\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <OperationCatalog\n key={surfaceKey}\n definition={{\n key: surfaceKey,\n title: surface?.title ?? surfaceKey,\n description: surface?.description ?? \"\",\n }}\n entities={[]}\n client={client}\n surfaceKey={surfaceKey}\n renderLink={pickerRenderLink}\n urlState={false}\n lockedValues={lockedValues}\n initialValues={initialValues}\n {...(filterPre ? { filterPre } : {})}\n {...(hiddenColumns ? { hiddenColumns } : {})}\n {...(cellRenderers ? { cellRenderers } : {})}\n rowSelection={{\n mode,\n selectedRowIds: ids,\n onSelectionChange: (next, rows, nextContext) => {\n const loaded = new Map(\n rows.flatMap((row) => {\n const id = getClickyRowId(row);\n return id ? [[id, row] as const] : [];\n }),\n );\n setIds(next);\n setRowsById((prev) => reconcilePickedRows(prev, next, loaded));\n setContext(nextContext);\n },\n ...(unavailableRows ? { unavailableRows } : {}),\n }}\n />\n </div>\n {note}\n </div>\n </Modal>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const filterShapes = require("./filterShapes.cjs");
|
|
4
|
+
const rowNavigation = require("./rowNavigation.cjs");
|
|
5
|
+
function lockedScopeEntries({
|
|
6
|
+
lockedValues,
|
|
7
|
+
lockedLabels,
|
|
8
|
+
parameters,
|
|
9
|
+
lookup,
|
|
10
|
+
components
|
|
11
|
+
}) {
|
|
12
|
+
const shapes = filterShapes.filterShapesByName(parameters, components);
|
|
13
|
+
return Object.entries(lockedValues).map(([key, value]) => {
|
|
14
|
+
var _a, _b, _c;
|
|
15
|
+
if (!shapes.has(key)) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`lockedValues.${key} is not a parameter of the list operation (declared: ${[...shapes.keys()].join(", ")})`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
const filter = lookup == null ? void 0 : lookup.filters[key];
|
|
21
|
+
const option = ((_a = filter == null ? void 0 : filter.options) == null ? void 0 : _a[value]) ?? ((_b = filter == null ? void 0 : filter.selected) == null ? void 0 : _b[value]);
|
|
22
|
+
return {
|
|
23
|
+
key,
|
|
24
|
+
label: (lockedLabels == null ? void 0 : lockedLabels[key]) ?? ((_c = shapes.get(key)) == null ? void 0 : _c.label) ?? (filter == null ? void 0 : filter.label) ?? key,
|
|
25
|
+
value: option && rowNavigation.clickyNodeText(option) || value
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function reconcilePickedRows(previous, ids, loaded) {
|
|
30
|
+
return Object.fromEntries(
|
|
31
|
+
ids.flatMap((id) => {
|
|
32
|
+
const row = loaded.get(id) ?? previous[id];
|
|
33
|
+
return row ? [[id, row]] : [];
|
|
34
|
+
})
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
exports.lockedScopeEntries = lockedScopeEntries;
|
|
38
|
+
exports.reconcilePickedRows = reconcilePickedRows;
|
|
39
|
+
//# sourceMappingURL=OperationEntityPicker.model.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperationEntityPicker.model.cjs","sources":["../../src/rpc/OperationEntityPicker.model.ts"],"sourcesContent":["import { filterShapesByName } from \"./filterShapes\";\nimport { clickyNodeText } from \"./rowNavigation\";\nimport type {\n ClickyFilterShape,\n OpenAPIParameter,\n OperationLookupResponse,\n} from \"./types\";\n\nexport type LockedScopeEntry = { key: string; label: string; value: string };\n\n/**\n * lockedScopeEntries names each locked parameter for the picker's read-only\n * \"Scoped to\" line. The label is the host's (`lockedLabels`), else the filter\n * label the catalog itself would show (spec shape, then lookup), else the raw\n * key; the value is its lookup option label when the lookup has one (a GUID\n * reads as the product it names), else the raw value.\n *\n * A locked key the list operation does not declare is an error: the catalog\n * only sends declared parameters, so the list would silently ignore the scope\n * the reader is told it is in.\n */\nexport function lockedScopeEntries({\n lockedValues,\n lockedLabels,\n parameters,\n lookup,\n components,\n}: {\n lockedValues: Record<string, string>;\n lockedLabels?: Record<string, string> | undefined;\n parameters: OpenAPIParameter[];\n lookup?: OperationLookupResponse | undefined;\n components?: Record<string, ClickyFilterShape> | undefined;\n}): LockedScopeEntry[] {\n const shapes = filterShapesByName(parameters, components);\n return Object.entries(lockedValues).map(([key, value]) => {\n if (!shapes.has(key)) {\n throw new Error(\n `lockedValues.${key} is not a parameter of the list operation (declared: ${[...shapes.keys()].join(\", \")})`,\n );\n }\n const filter = lookup?.filters[key];\n const option = filter?.options?.[value] ?? filter?.selected?.[value];\n return {\n key,\n label: lockedLabels?.[key] ?? shapes.get(key)?.label ?? filter?.label ?? key,\n value: (option && clickyNodeText(option)) || value,\n };\n });\n}\n\n/** Keeps the row of every picked id, from this page or one read earlier. */\nexport function reconcilePickedRows<Row>(\n previous: Record<string, Row>,\n ids: readonly string[],\n loaded: ReadonlyMap<string, Row>,\n): Record<string, Row> {\n return Object.fromEntries(\n ids.flatMap((id) => {\n const row = loaded.get(id) ?? previous[id];\n return row ? [[id, row] as const] : [];\n }),\n );\n}\n"],"names":["filterShapesByName","clickyNodeText"],"mappings":";;;;AAqBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMuB;AACrB,QAAM,SAASA,aAAAA,mBAAmB,YAAY,UAAU;AACxD,SAAO,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;;AACxD,QAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AACpB,YAAM,IAAI;AAAA,QACR,gBAAgB,GAAG,wDAAwD,CAAC,GAAG,OAAO,KAAA,CAAM,EAAE,KAAK,IAAI,CAAC;AAAA,MAAA;AAAA,IAE5G;AACA,UAAM,SAAS,iCAAQ,QAAQ;AAC/B,UAAM,WAAS,sCAAQ,YAAR,mBAAkB,aAAU,sCAAQ,aAAR,mBAAmB;AAC9D,WAAO;AAAA,MACL;AAAA,MACA,QAAO,6CAAe,WAAQ,YAAO,IAAI,GAAG,MAAd,mBAAiB,WAAS,iCAAQ,UAAS;AAAA,MACzE,OAAQ,UAAUC,6BAAe,MAAM,KAAM;AAAA,IAAA;AAAA,EAEjD,CAAC;AACH;AAGO,SAAS,oBACd,UACA,KACA,QACqB;AACrB,SAAO,OAAO;AAAA,IACZ,IAAI,QAAQ,CAAC,OAAO;AAClB,YAAM,MAAM,OAAO,IAAI,EAAE,KAAK,SAAS,EAAE;AACzC,aAAO,MAAM,CAAC,CAAC,IAAI,GAAG,CAAU,IAAI,CAAA;AAAA,IACtC,CAAC;AAAA,EAAA;AAEL;;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ClickyFilterShape, OpenAPIParameter, OperationLookupResponse } from './types.js';
|
|
2
|
+
export type LockedScopeEntry = {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* lockedScopeEntries names each locked parameter for the picker's read-only
|
|
9
|
+
* "Scoped to" line. The label is the host's (`lockedLabels`), else the filter
|
|
10
|
+
* label the catalog itself would show (spec shape, then lookup), else the raw
|
|
11
|
+
* key; the value is its lookup option label when the lookup has one (a GUID
|
|
12
|
+
* reads as the product it names), else the raw value.
|
|
13
|
+
*
|
|
14
|
+
* A locked key the list operation does not declare is an error: the catalog
|
|
15
|
+
* only sends declared parameters, so the list would silently ignore the scope
|
|
16
|
+
* the reader is told it is in.
|
|
17
|
+
*/
|
|
18
|
+
export declare function lockedScopeEntries({ lockedValues, lockedLabels, parameters, lookup, components, }: {
|
|
19
|
+
lockedValues: Record<string, string>;
|
|
20
|
+
lockedLabels?: Record<string, string> | undefined;
|
|
21
|
+
parameters: OpenAPIParameter[];
|
|
22
|
+
lookup?: OperationLookupResponse | undefined;
|
|
23
|
+
components?: Record<string, ClickyFilterShape> | undefined;
|
|
24
|
+
}): LockedScopeEntry[];
|
|
25
|
+
/** Keeps the row of every picked id, from this page or one read earlier. */
|
|
26
|
+
export declare function reconcilePickedRows<Row>(previous: Record<string, Row>, ids: readonly string[], loaded: ReadonlyMap<string, Row>): Record<string, Row>;
|
|
27
|
+
//# sourceMappingURL=OperationEntityPicker.model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperationEntityPicker.model.d.ts","sourceRoot":"","sources":["../../src/rpc/OperationEntityPicker.model.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,gBAAgB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,MAAM,EACN,UAAU,GACX,EAAE;IACD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAClD,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,SAAS,CAAC;CAC5D,GAAG,gBAAgB,EAAE,CAgBrB;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,GAAG,EACrC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAOrB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { filterShapesByName } from "./filterShapes.js";
|
|
2
|
+
import { clickyNodeText } from "./rowNavigation.js";
|
|
3
|
+
function lockedScopeEntries({
|
|
4
|
+
lockedValues,
|
|
5
|
+
lockedLabels,
|
|
6
|
+
parameters,
|
|
7
|
+
lookup,
|
|
8
|
+
components
|
|
9
|
+
}) {
|
|
10
|
+
const shapes = filterShapesByName(parameters, components);
|
|
11
|
+
return Object.entries(lockedValues).map(([key, value]) => {
|
|
12
|
+
var _a, _b, _c;
|
|
13
|
+
if (!shapes.has(key)) {
|
|
14
|
+
throw new Error(
|
|
15
|
+
`lockedValues.${key} is not a parameter of the list operation (declared: ${[...shapes.keys()].join(", ")})`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
const filter = lookup == null ? void 0 : lookup.filters[key];
|
|
19
|
+
const option = ((_a = filter == null ? void 0 : filter.options) == null ? void 0 : _a[value]) ?? ((_b = filter == null ? void 0 : filter.selected) == null ? void 0 : _b[value]);
|
|
20
|
+
return {
|
|
21
|
+
key,
|
|
22
|
+
label: (lockedLabels == null ? void 0 : lockedLabels[key]) ?? ((_c = shapes.get(key)) == null ? void 0 : _c.label) ?? (filter == null ? void 0 : filter.label) ?? key,
|
|
23
|
+
value: option && clickyNodeText(option) || value
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function reconcilePickedRows(previous, ids, loaded) {
|
|
28
|
+
return Object.fromEntries(
|
|
29
|
+
ids.flatMap((id) => {
|
|
30
|
+
const row = loaded.get(id) ?? previous[id];
|
|
31
|
+
return row ? [[id, row]] : [];
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
lockedScopeEntries,
|
|
37
|
+
reconcilePickedRows
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=OperationEntityPicker.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperationEntityPicker.model.js","sources":["../../src/rpc/OperationEntityPicker.model.ts"],"sourcesContent":["import { filterShapesByName } from \"./filterShapes\";\nimport { clickyNodeText } from \"./rowNavigation\";\nimport type {\n ClickyFilterShape,\n OpenAPIParameter,\n OperationLookupResponse,\n} from \"./types\";\n\nexport type LockedScopeEntry = { key: string; label: string; value: string };\n\n/**\n * lockedScopeEntries names each locked parameter for the picker's read-only\n * \"Scoped to\" line. The label is the host's (`lockedLabels`), else the filter\n * label the catalog itself would show (spec shape, then lookup), else the raw\n * key; the value is its lookup option label when the lookup has one (a GUID\n * reads as the product it names), else the raw value.\n *\n * A locked key the list operation does not declare is an error: the catalog\n * only sends declared parameters, so the list would silently ignore the scope\n * the reader is told it is in.\n */\nexport function lockedScopeEntries({\n lockedValues,\n lockedLabels,\n parameters,\n lookup,\n components,\n}: {\n lockedValues: Record<string, string>;\n lockedLabels?: Record<string, string> | undefined;\n parameters: OpenAPIParameter[];\n lookup?: OperationLookupResponse | undefined;\n components?: Record<string, ClickyFilterShape> | undefined;\n}): LockedScopeEntry[] {\n const shapes = filterShapesByName(parameters, components);\n return Object.entries(lockedValues).map(([key, value]) => {\n if (!shapes.has(key)) {\n throw new Error(\n `lockedValues.${key} is not a parameter of the list operation (declared: ${[...shapes.keys()].join(\", \")})`,\n );\n }\n const filter = lookup?.filters[key];\n const option = filter?.options?.[value] ?? filter?.selected?.[value];\n return {\n key,\n label: lockedLabels?.[key] ?? shapes.get(key)?.label ?? filter?.label ?? key,\n value: (option && clickyNodeText(option)) || value,\n };\n });\n}\n\n/** Keeps the row of every picked id, from this page or one read earlier. */\nexport function reconcilePickedRows<Row>(\n previous: Record<string, Row>,\n ids: readonly string[],\n loaded: ReadonlyMap<string, Row>,\n): Record<string, Row> {\n return Object.fromEntries(\n ids.flatMap((id) => {\n const row = loaded.get(id) ?? previous[id];\n return row ? [[id, row] as const] : [];\n }),\n );\n}\n"],"names":[],"mappings":";;AAqBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMuB;AACrB,QAAM,SAAS,mBAAmB,YAAY,UAAU;AACxD,SAAO,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;;AACxD,QAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AACpB,YAAM,IAAI;AAAA,QACR,gBAAgB,GAAG,wDAAwD,CAAC,GAAG,OAAO,KAAA,CAAM,EAAE,KAAK,IAAI,CAAC;AAAA,MAAA;AAAA,IAE5G;AACA,UAAM,SAAS,iCAAQ,QAAQ;AAC/B,UAAM,WAAS,sCAAQ,YAAR,mBAAkB,aAAU,sCAAQ,aAAR,mBAAmB;AAC9D,WAAO;AAAA,MACL;AAAA,MACA,QAAO,6CAAe,WAAQ,YAAO,IAAI,GAAG,MAAd,mBAAiB,WAAS,iCAAQ,UAAS;AAAA,MACzE,OAAQ,UAAU,eAAe,MAAM,KAAM;AAAA,IAAA;AAAA,EAEjD,CAAC;AACH;AAGO,SAAS,oBACd,UACA,KACA,QACqB;AACrB,SAAO,OAAO;AAAA,IACZ,IAAI,QAAQ,CAAC,OAAO;AAClB,YAAM,MAAM,OAAO,IAAI,EAAE,KAAK,SAAS,EAAE;AACzC,aAAO,MAAM,CAAC,CAAC,IAAI,GAAG,CAAU,IAAI,CAAA;AAAA,IACtC,CAAC;AAAA,EAAA;AAEL;"}
|