@flanksource/clicky-ui 0.3.18 → 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ComboboxMenu.cjs +5 -1
- package/dist/components/ComboboxMenu.cjs.map +1 -1
- package/dist/components/ComboboxMenu.d.ts.map +1 -1
- package/dist/components/ComboboxMenu.js +5 -1
- package/dist/components/ComboboxMenu.js.map +1 -1
- package/dist/components/EndpointSelector.model.cjs +96 -0
- package/dist/components/EndpointSelector.model.cjs.map +1 -0
- package/dist/components/EndpointSelector.model.d.ts +2 -0
- package/dist/components/EndpointSelector.model.d.ts.map +1 -1
- package/dist/components/EndpointSelector.model.js +96 -0
- package/dist/components/EndpointSelector.model.js.map +1 -0
- package/dist/components/ErrorWrapper.cjs +1 -1
- package/dist/components/ErrorWrapper.cjs.map +1 -1
- package/dist/components/ErrorWrapper.js +1 -1
- package/dist/components/ErrorWrapper.js.map +1 -1
- package/dist/components/FilterBar.cjs +52 -2
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +20 -2
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +52 -2
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/JSONPathField.cjs +87 -66
- package/dist/components/JSONPathField.cjs.map +1 -1
- package/dist/components/JSONPathField.d.ts +26 -9
- package/dist/components/JSONPathField.d.ts.map +1 -1
- package/dist/components/JSONPathField.js +88 -67
- package/dist/components/JSONPathField.js.map +1 -1
- package/dist/components/JSONPathPlayground.cjs +225 -0
- package/dist/components/JSONPathPlayground.cjs.map +1 -0
- package/dist/components/JSONPathPlayground.d.ts +59 -0
- package/dist/components/JSONPathPlayground.d.ts.map +1 -0
- package/dist/components/JSONPathPlayground.js +225 -0
- package/dist/components/JSONPathPlayground.js.map +1 -0
- package/dist/components/OnePasswordSelector.cjs +178 -0
- package/dist/components/OnePasswordSelector.cjs.map +1 -0
- package/dist/components/OnePasswordSelector.d.ts +8 -0
- package/dist/components/OnePasswordSelector.d.ts.map +1 -0
- package/dist/components/OnePasswordSelector.js +178 -0
- package/dist/components/OnePasswordSelector.js.map +1 -0
- package/dist/components/OnePasswordSelector.model.cjs +31 -0
- package/dist/components/OnePasswordSelector.model.cjs.map +1 -0
- package/dist/components/OnePasswordSelector.model.d.ts +27 -0
- package/dist/components/OnePasswordSelector.model.d.ts.map +1 -0
- package/dist/components/OnePasswordSelector.model.js +31 -0
- package/dist/components/OnePasswordSelector.model.js.map +1 -0
- package/dist/components/SecretFormField.cjs +142 -0
- package/dist/components/SecretFormField.cjs.map +1 -0
- package/dist/components/SecretFormField.d.ts +9 -0
- package/dist/components/SecretFormField.d.ts.map +1 -0
- package/dist/components/SecretFormField.js +142 -0
- package/dist/components/SecretFormField.js.map +1 -0
- package/dist/components/SecretKeySelector.cjs +20 -14
- package/dist/components/SecretKeySelector.cjs.map +1 -1
- package/dist/components/SecretKeySelector.d.ts +4 -1
- package/dist/components/SecretKeySelector.d.ts.map +1 -1
- package/dist/components/SecretKeySelector.js +20 -14
- package/dist/components/SecretKeySelector.js.map +1 -1
- package/dist/components/TreePickerField.cjs +55 -29
- package/dist/components/TreePickerField.cjs.map +1 -1
- package/dist/components/TreePickerField.d.ts +10 -1
- package/dist/components/TreePickerField.d.ts.map +1 -1
- package/dist/components/TreePickerField.js +56 -30
- package/dist/components/TreePickerField.js.map +1 -1
- package/dist/components/UnitStepControls.cjs +55 -0
- package/dist/components/UnitStepControls.cjs.map +1 -0
- package/dist/components/UnitStepControls.d.ts +10 -0
- package/dist/components/UnitStepControls.d.ts.map +1 -0
- package/dist/components/UnitStepControls.js +55 -0
- package/dist/components/UnitStepControls.js.map +1 -0
- package/dist/components/combobox-types.d.ts +9 -0
- package/dist/components/combobox-types.d.ts.map +1 -1
- package/dist/components/filter-bar-utils.cjs +7 -0
- package/dist/components/filter-bar-utils.cjs.map +1 -1
- package/dist/components/filter-bar-utils.d.ts.map +1 -1
- package/dist/components/filter-bar-utils.js +7 -0
- package/dist/components/filter-bar-utils.js.map +1 -1
- package/dist/components/jotai-bindings-core.cjs.map +1 -1
- package/dist/components/jotai-bindings-core.d.ts +4 -1
- package/dist/components/jotai-bindings-core.d.ts.map +1 -1
- package/dist/components/jotai-bindings-core.js.map +1 -1
- package/dist/components/json-schema-form-accordion-array.cjs +5 -73
- package/dist/components/json-schema-form-accordion-array.cjs.map +1 -1
- package/dist/components/json-schema-form-accordion-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-accordion-array.js +3 -71
- package/dist/components/json-schema-form-accordion-array.js.map +1 -1
- package/dist/components/json-schema-form-array.cjs +6 -1
- 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 +6 -1
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-cards-array.cjs +96 -0
- package/dist/components/json-schema-form-cards-array.cjs.map +1 -0
- package/dist/components/json-schema-form-cards-array.d.ts +7 -0
- package/dist/components/json-schema-form-cards-array.d.ts.map +1 -0
- package/dist/components/json-schema-form-cards-array.js +96 -0
- package/dist/components/json-schema-form-cards-array.js.map +1 -0
- package/dist/components/json-schema-form-item-row.cjs +81 -0
- package/dist/components/json-schema-form-item-row.cjs.map +1 -0
- package/dist/components/json-schema-form-item-row.d.ts +19 -0
- package/dist/components/json-schema-form-item-row.d.ts.map +1 -0
- package/dist/components/json-schema-form-item-row.js +81 -0
- package/dist/components/json-schema-form-item-row.js.map +1 -0
- package/dist/components/json-schema-form-render.cjs +4 -3
- 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 +4 -3
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +1 -1
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.js +1 -1
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-tone.cjs +12 -0
- package/dist/components/json-schema-form-tone.cjs.map +1 -1
- package/dist/components/json-schema-form-tone.js +12 -0
- package/dist/components/json-schema-form-tone.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +10 -1
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/jsonPathTree.cjs +189 -0
- package/dist/components/jsonPathTree.cjs.map +1 -0
- package/dist/components/jsonPathTree.d.ts +92 -0
- package/dist/components/jsonPathTree.d.ts.map +1 -0
- package/dist/components/jsonPathTree.js +189 -0
- package/dist/components/jsonPathTree.js.map +1 -0
- package/dist/components/secret-form-extension.cjs +30 -0
- package/dist/components/secret-form-extension.cjs.map +1 -0
- package/dist/components/secret-form-extension.d.ts +23 -0
- package/dist/components/secret-form-extension.d.ts.map +1 -0
- package/dist/components/secret-form-extension.js +30 -0
- package/dist/components/secret-form-extension.js.map +1 -0
- package/dist/components/unit-form-extension.cjs +126 -0
- package/dist/components/unit-form-extension.cjs.map +1 -0
- package/dist/components/unit-form-extension.d.ts +8 -0
- package/dist/components/unit-form-extension.d.ts.map +1 -0
- package/dist/components/unit-form-extension.js +126 -0
- package/dist/components/unit-form-extension.js.map +1 -0
- package/dist/components.cjs +20 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +7 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +20 -0
- package/dist/components.js.map +1 -1
- package/dist/data/TaskExecDetails.cjs +40 -0
- package/dist/data/TaskExecDetails.cjs.map +1 -0
- package/dist/data/TaskExecDetails.d.ts +5 -0
- package/dist/data/TaskExecDetails.d.ts.map +1 -0
- package/dist/data/TaskExecDetails.js +40 -0
- package/dist/data/TaskExecDetails.js.map +1 -0
- package/dist/data/TaskProgress.cjs +9 -3
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +9 -3
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/TaskSnapshot.cjs.map +1 -1
- package/dist/data/TaskSnapshot.d.ts +12 -1
- package/dist/data/TaskSnapshot.d.ts.map +1 -1
- package/dist/data/TaskSnapshot.js.map +1 -1
- package/dist/data/TreeNode.cjs +3 -0
- package/dist/data/TreeNode.cjs.map +1 -1
- package/dist/data/TreeNode.d.ts.map +1 -1
- package/dist/data/TreeNode.js +3 -0
- package/dist/data/TreeNode.js.map +1 -1
- package/dist/data/data-table-filter-values.cjs +20 -0
- package/dist/data/data-table-filter-values.cjs.map +1 -1
- package/dist/data/data-table-filter-values.d.ts +16 -0
- package/dist/data/data-table-filter-values.d.ts.map +1 -1
- package/dist/data/data-table-filter-values.js +20 -0
- package/dist/data/data-table-filter-values.js.map +1 -1
- package/dist/data/data-table-server-filters.cjs +23 -29
- package/dist/data/data-table-server-filters.cjs.map +1 -1
- package/dist/data/data-table-server-filters.d.ts.map +1 -1
- package/dist/data/data-table-server-filters.js +21 -27
- package/dist/data/data-table-server-filters.js.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.cjs +61 -8
- package/dist/data/diagnostics/ErrorDetails.cjs.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.js +61 -8
- package/dist/data/diagnostics/ErrorDetails.js.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.cjs +10 -4
- package/dist/data/diagnostics/error-diagnostics.cjs.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.js +10 -4
- package/dist/data/diagnostics/error-diagnostics.js.map +1 -1
- package/dist/data/query-browser/QueryBrowser.cjs +139 -161
- package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
- package/dist/data/query-browser/QueryBrowser.d.ts +1 -71
- package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
- package/dist/data/query-browser/QueryBrowser.editor.cjs +88 -0
- package/dist/data/query-browser/QueryBrowser.editor.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowser.editor.d.ts +12 -0
- package/dist/data/query-browser/QueryBrowser.editor.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowser.editor.js +88 -0
- package/dist/data/query-browser/QueryBrowser.editor.js.map +1 -0
- package/dist/data/query-browser/QueryBrowser.js +140 -162
- package/dist/data/query-browser/QueryBrowser.js.map +1 -1
- package/dist/data/query-browser/QueryBrowser.types.cjs +12 -0
- package/dist/data/query-browser/QueryBrowser.types.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowser.types.d.ts +94 -0
- package/dist/data/query-browser/QueryBrowser.types.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowser.types.js +12 -0
- package/dist/data/query-browser/QueryBrowser.types.js.map +1 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs +56 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts +5 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js +56 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js.map +1 -0
- package/dist/data/query-browser/QueryBrowserResults.cjs +80 -0
- package/dist/data/query-browser/QueryBrowserResults.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowserResults.d.ts +16 -0
- package/dist/data/query-browser/QueryBrowserResults.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowserResults.js +80 -0
- package/dist/data/query-browser/QueryBrowserResults.js.map +1 -0
- package/dist/data/query-browser/index.d.ts +2 -1
- package/dist/data/query-browser/index.d.ts.map +1 -1
- package/dist/data/task-exec-details.cjs +9 -0
- package/dist/data/task-exec-details.cjs.map +1 -0
- package/dist/data/task-exec-details.d.ts +3 -0
- package/dist/data/task-exec-details.d.ts.map +1 -0
- package/dist/data/task-exec-details.js +9 -0
- package/dist/data/task-exec-details.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +2 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +2 -0
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +22 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/string.cjs +8 -0
- package/dist/lib/string.cjs.map +1 -1
- package/dist/lib/string.d.ts +1 -0
- package/dist/lib/string.d.ts.map +1 -1
- package/dist/lib/string.js +8 -0
- package/dist/lib/string.js.map +1 -1
- package/dist/profiles/catalogTree.cjs +133 -0
- package/dist/profiles/catalogTree.cjs.map +1 -0
- package/dist/profiles/catalogTree.d.ts +11 -0
- package/dist/profiles/catalogTree.d.ts.map +1 -0
- package/dist/profiles/catalogTree.js +133 -0
- package/dist/profiles/catalogTree.js.map +1 -0
- package/dist/profiles/connectionBrowserModel.cjs +185 -0
- package/dist/profiles/connectionBrowserModel.cjs.map +1 -0
- package/dist/profiles/connectionBrowserModel.d.ts +169 -0
- package/dist/profiles/connectionBrowserModel.d.ts.map +1 -0
- package/dist/profiles/connectionBrowserModel.js +185 -0
- package/dist/profiles/connectionBrowserModel.js.map +1 -0
- package/dist/profiles/connectionQueryWorkspace.cjs +185 -0
- package/dist/profiles/connectionQueryWorkspace.cjs.map +1 -0
- package/dist/profiles/connectionQueryWorkspace.d.ts +63 -0
- package/dist/profiles/connectionQueryWorkspace.d.ts.map +1 -0
- package/dist/profiles/connectionQueryWorkspace.js +185 -0
- package/dist/profiles/connectionQueryWorkspace.js.map +1 -0
- package/dist/profiles/connectionQueryWorkspaceModel.cjs +28 -0
- package/dist/profiles/connectionQueryWorkspaceModel.cjs.map +1 -0
- package/dist/profiles/connectionQueryWorkspaceModel.d.ts +38 -0
- package/dist/profiles/connectionQueryWorkspaceModel.d.ts.map +1 -0
- package/dist/profiles/connectionQueryWorkspaceModel.js +28 -0
- package/dist/profiles/connectionQueryWorkspaceModel.js.map +1 -0
- package/dist/profiles/esFieldValues.cjs +64 -0
- package/dist/profiles/esFieldValues.cjs.map +1 -0
- package/dist/profiles/esFieldValues.d.ts +48 -0
- package/dist/profiles/esFieldValues.d.ts.map +1 -0
- package/dist/profiles/esFieldValues.js +64 -0
- package/dist/profiles/esFieldValues.js.map +1 -0
- package/dist/profiles/esParamMappingModel.cjs +301 -0
- package/dist/profiles/esParamMappingModel.cjs.map +1 -0
- package/dist/profiles/esParamMappingModel.d.ts +37 -0
- package/dist/profiles/esParamMappingModel.d.ts.map +1 -0
- package/dist/profiles/esParamMappingModel.js +301 -0
- package/dist/profiles/esParamMappingModel.js.map +1 -0
- package/dist/profiles/esParamMappingPill.cjs +24 -0
- package/dist/profiles/esParamMappingPill.cjs.map +1 -0
- package/dist/profiles/esParamMappingPill.d.ts +13 -0
- package/dist/profiles/esParamMappingPill.d.ts.map +1 -0
- package/dist/profiles/esParamMappingPill.js +24 -0
- package/dist/profiles/esParamMappingPill.js.map +1 -0
- package/dist/profiles/esParamOperandExtension.cjs +75 -0
- package/dist/profiles/esParamOperandExtension.cjs.map +1 -0
- package/dist/profiles/esParamOperandExtension.d.ts +11 -0
- package/dist/profiles/esParamOperandExtension.d.ts.map +1 -0
- package/dist/profiles/esParamOperandExtension.js +75 -0
- package/dist/profiles/esParamOperandExtension.js.map +1 -0
- package/dist/profiles/esQueryBuilder.cjs +205 -0
- package/dist/profiles/esQueryBuilder.cjs.map +1 -0
- package/dist/profiles/esQueryBuilder.d.ts +35 -0
- package/dist/profiles/esQueryBuilder.d.ts.map +1 -0
- package/dist/profiles/esQueryBuilder.js +205 -0
- package/dist/profiles/esQueryBuilder.js.map +1 -0
- package/dist/profiles/esQueryBuilderExtension.cjs +23 -0
- package/dist/profiles/esQueryBuilderExtension.cjs.map +1 -0
- package/dist/profiles/esQueryBuilderExtension.d.ts +5 -0
- package/dist/profiles/esQueryBuilderExtension.d.ts.map +1 -0
- package/dist/profiles/esQueryBuilderExtension.js +23 -0
- package/dist/profiles/esQueryBuilderExtension.js.map +1 -0
- package/dist/profiles/esQueryBuilderForm.cjs +26 -0
- package/dist/profiles/esQueryBuilderForm.cjs.map +1 -0
- package/dist/profiles/esQueryBuilderForm.d.ts +18 -0
- package/dist/profiles/esQueryBuilderForm.d.ts.map +1 -0
- package/dist/profiles/esQueryBuilderForm.js +26 -0
- package/dist/profiles/esQueryBuilderForm.js.map +1 -0
- package/dist/profiles/esQueryBuilderModel.cjs +131 -0
- package/dist/profiles/esQueryBuilderModel.cjs.map +1 -0
- package/dist/profiles/esQueryBuilderModel.d.ts +108 -0
- package/dist/profiles/esQueryBuilderModel.d.ts.map +1 -0
- package/dist/profiles/esQueryBuilderModel.js +131 -0
- package/dist/profiles/esQueryBuilderModel.js.map +1 -0
- package/dist/profiles/esQueryClauseGroup.cjs +144 -0
- package/dist/profiles/esQueryClauseGroup.cjs.map +1 -0
- package/dist/profiles/esQueryClauseGroup.d.ts +10 -0
- package/dist/profiles/esQueryClauseGroup.d.ts.map +1 -0
- package/dist/profiles/esQueryClauseGroup.js +144 -0
- package/dist/profiles/esQueryClauseGroup.js.map +1 -0
- package/dist/profiles/esQueryCompile.cjs +47 -0
- package/dist/profiles/esQueryCompile.cjs.map +1 -0
- package/dist/profiles/esQueryCompile.d.ts +39 -0
- package/dist/profiles/esQueryCompile.d.ts.map +1 -0
- package/dist/profiles/esQueryCompile.js +47 -0
- package/dist/profiles/esQueryCompile.js.map +1 -0
- package/dist/profiles/esQueryConditionRow.cjs +168 -0
- package/dist/profiles/esQueryConditionRow.cjs.map +1 -0
- package/dist/profiles/esQueryConditionRow.d.ts +37 -0
- package/dist/profiles/esQueryConditionRow.d.ts.map +1 -0
- package/dist/profiles/esQueryConditionRow.js +168 -0
- package/dist/profiles/esQueryConditionRow.js.map +1 -0
- package/dist/profiles/esQueryGroupModel.cjs +12 -0
- package/dist/profiles/esQueryGroupModel.cjs.map +1 -0
- package/dist/profiles/esQueryGroupModel.d.ts +9 -0
- package/dist/profiles/esQueryGroupModel.d.ts.map +1 -0
- package/dist/profiles/esQueryGroupModel.js +12 -0
- package/dist/profiles/esQueryGroupModel.js.map +1 -0
- package/dist/profiles/esQueryOccur.cjs +16 -0
- package/dist/profiles/esQueryOccur.cjs.map +1 -0
- package/dist/profiles/esQueryOccur.d.ts +11 -0
- package/dist/profiles/esQueryOccur.d.ts.map +1 -0
- package/dist/profiles/esQueryOccur.js +16 -0
- package/dist/profiles/esQueryOccur.js.map +1 -0
- package/dist/profiles/esQueryOperandEditors.cjs +279 -0
- package/dist/profiles/esQueryOperandEditors.cjs.map +1 -0
- package/dist/profiles/esQueryOperandEditors.d.ts +24 -0
- package/dist/profiles/esQueryOperandEditors.d.ts.map +1 -0
- package/dist/profiles/esQueryOperandEditors.js +279 -0
- package/dist/profiles/esQueryOperandEditors.js.map +1 -0
- package/dist/profiles/esQueryOperandModel.cjs +28 -0
- package/dist/profiles/esQueryOperandModel.cjs.map +1 -0
- package/dist/profiles/esQueryOperandModel.d.ts +17 -0
- package/dist/profiles/esQueryOperandModel.d.ts.map +1 -0
- package/dist/profiles/esQueryOperandModel.js +28 -0
- package/dist/profiles/esQueryOperandModel.js.map +1 -0
- package/dist/profiles/esQueryOperators.cjs +165 -0
- package/dist/profiles/esQueryOperators.cjs.map +1 -0
- package/dist/profiles/esQueryOperators.d.ts +83 -0
- package/dist/profiles/esQueryOperators.d.ts.map +1 -0
- package/dist/profiles/esQueryOperators.js +165 -0
- package/dist/profiles/esQueryOperators.js.map +1 -0
- package/dist/profiles/esQueryOutputEditor.cjs +138 -0
- package/dist/profiles/esQueryOutputEditor.cjs.map +1 -0
- package/dist/profiles/esQueryOutputEditor.d.ts +7 -0
- package/dist/profiles/esQueryOutputEditor.d.ts.map +1 -0
- package/dist/profiles/esQueryOutputEditor.js +138 -0
- package/dist/profiles/esQueryOutputEditor.js.map +1 -0
- package/dist/profiles/esQueryOutputModel.cjs +16 -0
- package/dist/profiles/esQueryOutputModel.cjs.map +1 -0
- package/dist/profiles/esQueryOutputModel.d.ts +14 -0
- package/dist/profiles/esQueryOutputModel.d.ts.map +1 -0
- package/dist/profiles/esQueryOutputModel.js +16 -0
- package/dist/profiles/esQueryOutputModel.js.map +1 -0
- package/dist/profiles/esQueryPreview.cjs +30 -0
- package/dist/profiles/esQueryPreview.cjs.map +1 -0
- package/dist/profiles/esQueryPreview.d.ts +6 -0
- package/dist/profiles/esQueryPreview.d.ts.map +1 -0
- package/dist/profiles/esQueryPreview.js +30 -0
- package/dist/profiles/esQueryPreview.js.map +1 -0
- package/dist/profiles/esQuerySortEditor.cjs +143 -0
- package/dist/profiles/esQuerySortEditor.cjs.map +1 -0
- package/dist/profiles/esQuerySortEditor.d.ts +9 -0
- package/dist/profiles/esQuerySortEditor.d.ts.map +1 -0
- package/dist/profiles/esQuerySortEditor.js +143 -0
- package/dist/profiles/esQuerySortEditor.js.map +1 -0
- package/dist/profiles/esQuerySortModel.cjs +13 -0
- package/dist/profiles/esQuerySortModel.cjs.map +1 -0
- package/dist/profiles/esQuerySortModel.d.ts +4 -0
- package/dist/profiles/esQuerySortModel.d.ts.map +1 -0
- package/dist/profiles/esQuerySortModel.js +13 -0
- package/dist/profiles/esQuerySortModel.js.map +1 -0
- package/dist/profiles/esValueCombobox.cjs +86 -0
- package/dist/profiles/esValueCombobox.cjs.map +1 -0
- package/dist/profiles/esValueCombobox.d.ts +15 -0
- package/dist/profiles/esValueCombobox.d.ts.map +1 -0
- package/dist/profiles/esValueCombobox.js +86 -0
- package/dist/profiles/esValueCombobox.js.map +1 -0
- package/dist/profiles/jsonPathSample.cjs +75 -0
- package/dist/profiles/jsonPathSample.cjs.map +1 -0
- package/dist/profiles/jsonPathSample.d.ts +27 -0
- package/dist/profiles/jsonPathSample.d.ts.map +1 -0
- package/dist/profiles/jsonPathSample.js +75 -0
- package/dist/profiles/jsonPathSample.js.map +1 -0
- package/dist/profiles/jsonPathSampleRow.cjs +14 -0
- package/dist/profiles/jsonPathSampleRow.cjs.map +1 -0
- package/dist/profiles/jsonPathSampleRow.d.ts +6 -0
- package/dist/profiles/jsonPathSampleRow.d.ts.map +1 -0
- package/dist/profiles/jsonPathSampleRow.js +14 -0
- package/dist/profiles/jsonPathSampleRow.js.map +1 -0
- package/dist/profiles/profileApi.cjs +37 -0
- package/dist/profiles/profileApi.cjs.map +1 -0
- package/dist/profiles/profileApi.d.ts +32 -0
- package/dist/profiles/profileApi.d.ts.map +1 -0
- package/dist/profiles/profileApi.js +37 -0
- package/dist/profiles/profileApi.js.map +1 -0
- package/dist/profiles/profileBuilder.cjs +65 -0
- package/dist/profiles/profileBuilder.cjs.map +1 -0
- package/dist/profiles/profileBuilder.d.ts +11 -0
- package/dist/profiles/profileBuilder.d.ts.map +1 -0
- package/dist/profiles/profileBuilder.js +65 -0
- package/dist/profiles/profileBuilder.js.map +1 -0
- package/dist/profiles/profileBuilderExtension.cjs +25 -0
- package/dist/profiles/profileBuilderExtension.cjs.map +1 -0
- package/dist/profiles/profileBuilderExtension.d.ts +5 -0
- package/dist/profiles/profileBuilderExtension.d.ts.map +1 -0
- package/dist/profiles/profileBuilderExtension.js +25 -0
- package/dist/profiles/profileBuilderExtension.js.map +1 -0
- package/dist/profiles/profileBuilderWorkspace.cjs +368 -0
- package/dist/profiles/profileBuilderWorkspace.cjs.map +1 -0
- package/dist/profiles/profileBuilderWorkspace.d.ts +21 -0
- package/dist/profiles/profileBuilderWorkspace.d.ts.map +1 -0
- package/dist/profiles/profileBuilderWorkspace.js +368 -0
- package/dist/profiles/profileBuilderWorkspace.js.map +1 -0
- package/dist/profiles/profileColumnModel.cjs +23 -0
- package/dist/profiles/profileColumnModel.cjs.map +1 -0
- package/dist/profiles/profileColumnModel.d.ts +8 -0
- package/dist/profiles/profileColumnModel.d.ts.map +1 -0
- package/dist/profiles/profileColumnModel.js +23 -0
- package/dist/profiles/profileColumnModel.js.map +1 -0
- package/dist/profiles/profileColumnPicker.cjs +68 -0
- package/dist/profiles/profileColumnPicker.cjs.map +1 -0
- package/dist/profiles/profileColumnPicker.d.ts +11 -0
- package/dist/profiles/profileColumnPicker.d.ts.map +1 -0
- package/dist/profiles/profileColumnPicker.js +68 -0
- package/dist/profiles/profileColumnPicker.js.map +1 -0
- package/dist/profiles/profileEditor.cjs +386 -0
- package/dist/profiles/profileEditor.cjs.map +1 -0
- package/dist/profiles/profileEditor.d.ts +19 -0
- package/dist/profiles/profileEditor.d.ts.map +1 -0
- package/dist/profiles/profileEditor.js +386 -0
- package/dist/profiles/profileEditor.js.map +1 -0
- package/dist/profiles/profileEditorModel.cjs +181 -0
- package/dist/profiles/profileEditorModel.cjs.map +1 -0
- package/dist/profiles/profileEditorModel.d.ts +74 -0
- package/dist/profiles/profileEditorModel.d.ts.map +1 -0
- package/dist/profiles/profileEditorModel.js +181 -0
- package/dist/profiles/profileEditorModel.js.map +1 -0
- package/dist/profiles/profileEditorPreview.cjs +38 -0
- package/dist/profiles/profileEditorPreview.cjs.map +1 -0
- package/dist/profiles/profileEditorPreview.d.ts +12 -0
- package/dist/profiles/profileEditorPreview.d.ts.map +1 -0
- package/dist/profiles/profileEditorPreview.js +38 -0
- package/dist/profiles/profileEditorPreview.js.map +1 -0
- package/dist/profiles/profileEditorRail.cjs +46 -0
- package/dist/profiles/profileEditorRail.cjs.map +1 -0
- package/dist/profiles/profileEditorRail.d.ts +8 -0
- package/dist/profiles/profileEditorRail.d.ts.map +1 -0
- package/dist/profiles/profileEditorRail.js +46 -0
- package/dist/profiles/profileEditorRail.js.map +1 -0
- package/dist/profiles/profileEditorRaw.cjs +118 -0
- package/dist/profiles/profileEditorRaw.cjs.map +1 -0
- package/dist/profiles/profileEditorRaw.d.ts +7 -0
- package/dist/profiles/profileEditorRaw.d.ts.map +1 -0
- package/dist/profiles/profileEditorRaw.js +118 -0
- package/dist/profiles/profileEditorRaw.js.map +1 -0
- package/dist/profiles/profileEditorRoutes.cjs +7 -0
- package/dist/profiles/profileEditorRoutes.cjs.map +1 -0
- package/dist/profiles/profileEditorRoutes.d.ts +2 -0
- package/dist/profiles/profileEditorRoutes.d.ts.map +1 -0
- package/dist/profiles/profileEditorRoutes.js +7 -0
- package/dist/profiles/profileEditorRoutes.js.map +1 -0
- package/dist/profiles/profileEditorSections.cjs +213 -0
- package/dist/profiles/profileEditorSections.cjs.map +1 -0
- package/dist/profiles/profileEditorSections.d.ts +23 -0
- package/dist/profiles/profileEditorSections.d.ts.map +1 -0
- package/dist/profiles/profileEditorSections.js +213 -0
- package/dist/profiles/profileEditorSections.js.map +1 -0
- package/dist/profiles/profileFieldEditor.cjs +200 -0
- package/dist/profiles/profileFieldEditor.cjs.map +1 -0
- package/dist/profiles/profileFieldEditor.d.ts +34 -0
- package/dist/profiles/profileFieldEditor.d.ts.map +1 -0
- package/dist/profiles/profileFieldEditor.js +200 -0
- package/dist/profiles/profileFieldEditor.js.map +1 -0
- package/dist/profiles/profileFieldGrid.cjs +250 -0
- package/dist/profiles/profileFieldGrid.cjs.map +1 -0
- package/dist/profiles/profileFieldGrid.d.ts +20 -0
- package/dist/profiles/profileFieldGrid.d.ts.map +1 -0
- package/dist/profiles/profileFieldGrid.js +250 -0
- package/dist/profiles/profileFieldGrid.js.map +1 -0
- package/dist/profiles/profileFieldManager.cjs +103 -0
- package/dist/profiles/profileFieldManager.cjs.map +1 -0
- package/dist/profiles/profileFieldManager.d.ts +9 -0
- package/dist/profiles/profileFieldManager.d.ts.map +1 -0
- package/dist/profiles/profileFieldManager.js +103 -0
- package/dist/profiles/profileFieldManager.js.map +1 -0
- package/dist/profiles/profileFieldState.cjs +136 -0
- package/dist/profiles/profileFieldState.cjs.map +1 -0
- package/dist/profiles/profileFieldState.d.ts +41 -0
- package/dist/profiles/profileFieldState.d.ts.map +1 -0
- package/dist/profiles/profileFieldState.js +136 -0
- package/dist/profiles/profileFieldState.js.map +1 -0
- package/dist/profiles/profileFieldTypes.cjs +17 -0
- package/dist/profiles/profileFieldTypes.cjs.map +1 -0
- package/dist/profiles/profileFieldTypes.d.ts +8 -0
- package/dist/profiles/profileFieldTypes.d.ts.map +1 -0
- package/dist/profiles/profileFieldTypes.js +17 -0
- package/dist/profiles/profileFieldTypes.js.map +1 -0
- package/dist/profiles/profileParamModel.cjs +78 -0
- package/dist/profiles/profileParamModel.cjs.map +1 -0
- package/dist/profiles/profileParamModel.d.ts +3 -0
- package/dist/profiles/profileParamModel.d.ts.map +1 -0
- package/dist/profiles/profileParamModel.js +78 -0
- package/dist/profiles/profileParamModel.js.map +1 -0
- package/dist/profiles/profileSamplePayload.cjs +15 -0
- package/dist/profiles/profileSamplePayload.cjs.map +1 -0
- package/dist/profiles/profileSamplePayload.d.ts +13 -0
- package/dist/profiles/profileSamplePayload.d.ts.map +1 -0
- package/dist/profiles/profileSamplePayload.js +15 -0
- package/dist/profiles/profileSamplePayload.js.map +1 -0
- package/dist/profiles/profileWizard.cjs +257 -0
- package/dist/profiles/profileWizard.cjs.map +1 -0
- package/dist/profiles/profileWizard.d.ts +12 -0
- package/dist/profiles/profileWizard.d.ts.map +1 -0
- package/dist/profiles/profileWizard.js +257 -0
- package/dist/profiles/profileWizard.js.map +1 -0
- package/dist/profiles/profileWizardHelp.cjs +10 -0
- package/dist/profiles/profileWizardHelp.cjs.map +1 -0
- package/dist/profiles/profileWizardHelp.d.ts +13 -0
- package/dist/profiles/profileWizardHelp.d.ts.map +1 -0
- package/dist/profiles/profileWizardHelp.js +10 -0
- package/dist/profiles/profileWizardHelp.js.map +1 -0
- package/dist/profiles/profileWizardModel.cjs +198 -0
- package/dist/profiles/profileWizardModel.cjs.map +1 -0
- package/dist/profiles/profileWizardModel.d.ts +255 -0
- package/dist/profiles/profileWizardModel.d.ts.map +1 -0
- package/dist/profiles/profileWizardModel.js +198 -0
- package/dist/profiles/profileWizardModel.js.map +1 -0
- package/dist/profiles/profileWizardQueryStep.cjs +215 -0
- package/dist/profiles/profileWizardQueryStep.cjs.map +1 -0
- package/dist/profiles/profileWizardQueryStep.d.ts +18 -0
- package/dist/profiles/profileWizardQueryStep.d.ts.map +1 -0
- package/dist/profiles/profileWizardQueryStep.js +215 -0
- package/dist/profiles/profileWizardQueryStep.js.map +1 -0
- package/dist/profiles/profileWizardSteps.cjs +214 -0
- package/dist/profiles/profileWizardSteps.cjs.map +1 -0
- package/dist/profiles/profileWizardSteps.d.ts +35 -0
- package/dist/profiles/profileWizardSteps.d.ts.map +1 -0
- package/dist/profiles/profileWizardSteps.js +214 -0
- package/dist/profiles/profileWizardSteps.js.map +1 -0
- package/dist/profiles/profileYaml.cjs +19 -0
- package/dist/profiles/profileYaml.cjs.map +1 -0
- package/dist/profiles/profileYaml.d.ts +4 -0
- package/dist/profiles/profileYaml.d.ts.map +1 -0
- package/dist/profiles/profileYaml.js +19 -0
- package/dist/profiles/profileYaml.js.map +1 -0
- package/dist/profiles/prometheusResults.cjs +60 -0
- package/dist/profiles/prometheusResults.cjs.map +1 -0
- package/dist/profiles/prometheusResults.d.ts +7 -0
- package/dist/profiles/prometheusResults.d.ts.map +1 -0
- package/dist/profiles/prometheusResults.js +60 -0
- package/dist/profiles/prometheusResults.js.map +1 -0
- package/dist/profiles/queryRowLimits.cjs +82 -0
- package/dist/profiles/queryRowLimits.cjs.map +1 -0
- package/dist/profiles/queryRowLimits.d.ts +9 -0
- package/dist/profiles/queryRowLimits.d.ts.map +1 -0
- package/dist/profiles/queryRowLimits.js +82 -0
- package/dist/profiles/queryRowLimits.js.map +1 -0
- package/dist/profiles/queryRowLimitsModel.cjs +10 -0
- package/dist/profiles/queryRowLimitsModel.cjs.map +1 -0
- package/dist/profiles/queryRowLimitsModel.d.ts +9 -0
- package/dist/profiles/queryRowLimitsModel.d.ts.map +1 -0
- package/dist/profiles/queryRowLimitsModel.js +10 -0
- package/dist/profiles/queryRowLimitsModel.js.map +1 -0
- package/dist/profiles/queryTargetPicker.cjs +42 -0
- package/dist/profiles/queryTargetPicker.cjs.map +1 -0
- package/dist/profiles/queryTargetPicker.d.ts +8 -0
- package/dist/profiles/queryTargetPicker.d.ts.map +1 -0
- package/dist/profiles/queryTargetPicker.js +42 -0
- package/dist/profiles/queryTargetPicker.js.map +1 -0
- package/dist/profiles/testSchema.d.ts +3 -0
- package/dist/profiles/testSchema.d.ts.map +1 -0
- package/dist/profiles.cjs +223 -0
- package/dist/profiles.cjs.map +1 -0
- package/dist/profiles.d.ts +68 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +223 -0
- package/dist/profiles.js.map +1 -0
- package/dist/rpc/FilterForm.cjs +20 -0
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.js +20 -0
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +34 -0
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +35 -1
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +9 -1
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -1
|
@@ -124,7 +124,11 @@ function ComboboxMenu({
|
|
|
124
124
|
)
|
|
125
125
|
}
|
|
126
126
|
),
|
|
127
|
-
/* @__PURE__ */ jsxRuntime.jsx(ComboboxOptionText, { option })
|
|
127
|
+
/* @__PURE__ */ jsxRuntime.jsx(ComboboxOptionText, { option }),
|
|
128
|
+
option.trailing != null && // Capped and truncating rather than `shrink-0`: in a menu
|
|
129
|
+
// clamped by the viewport edge the label is what identifies
|
|
130
|
+
// the option, so the preview yields first.
|
|
131
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto min-w-0 max-w-[55%] truncate pl-2 text-right text-xs text-muted-foreground", children: option.trailing })
|
|
128
132
|
] })
|
|
129
133
|
}
|
|
130
134
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxMenu.cjs","sources":["../../src/components/ComboboxMenu.tsx"],"sourcesContent":["import { Fragment, type ReactNode, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { Icon, LabelIcon } from \"../data/Icon\";\nimport { UiCheck } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport type {\n ComboboxOption,\n ComboboxTriStateMode,\n} from \"./combobox-types\";\nimport type { ComboboxMenuPosition } from \"./combobox-utils\";\n\nexport function ComboboxMenu({\n customEntry,\n filtered,\n floatingZ,\n footer,\n highlighted,\n isSelected,\n listId,\n listRef,\n loading,\n menuPos,\n modes,\n multiple,\n onHighlight,\n onSelect,\n onSetMode,\n tristate,\n}: {\n customEntry: ComboboxOption | null;\n filtered: ComboboxOption[];\n floatingZ: number;\n footer: ReactNode;\n highlighted: number;\n isSelected: (value: string) => boolean;\n listId: string | undefined;\n listRef: RefObject<HTMLDivElement>;\n loading: boolean | undefined;\n menuPos: ComboboxMenuPosition;\n modes: Record<string, ComboboxTriStateMode>;\n multiple: boolean;\n onHighlight: (index: number) => void;\n onSelect: (option: ComboboxOption) => void;\n onSetMode: (value: string, mode: string) => void;\n tristate: boolean;\n}) {\n return createPortal(\n <div\n id={listId}\n ref={listRef}\n role=\"listbox\"\n aria-multiselectable={multiple || undefined}\n style={{\n position: \"fixed\",\n ...(menuPos.top != null\n ? { top: menuPos.top }\n : { bottom: menuPos.bottom }),\n left: menuPos.left,\n minWidth: menuPos.width,\n maxWidth: menuPos.maxWidth,\n maxHeight: menuPos.maxHeight,\n zIndex: floatingZ,\n }}\n className=\"w-max overflow-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\"\n >\n {loading && filtered.length === 0 && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n Loading…\n </div>\n )}\n {!loading && filtered.length === 0 && !customEntry && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n No results\n </div>\n )}\n {filtered.map((option, index) => {\n const selected = isSelected(option.value);\n const mode = tristate ? modes[option.value] : undefined;\n const showHeader =\n option.group != null &&\n option.group !== filtered[index - 1]?.group;\n return (\n <Fragment key={option.value}>\n {showHeader && (\n <div\n role=\"presentation\"\n className=\"select-none px-2 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {option.group}\n </div>\n )}\n <div\n id={listId ? `${listId}-${index}` : undefined}\n role=\"option\"\n aria-selected={tristate ? mode != null : selected}\n aria-disabled={option.disabled}\n {...(mode != null\n ? {\n \"aria-label\": `${option.label}, ${\n mode === \"include\" ? \"included\" : \"excluded\"\n }`,\n }\n : {})}\n {...(option.title !== undefined ? { title: option.title } : {})}\n {...(tristate\n ? { \"data-filter-option\": option.value }\n : {})}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!tristate && !option.disabled) onSelect(option);\n }}\n {...(tristate\n ? {\n onClick: () => {\n if (!option.disabled) onSelect(option);\n },\n }\n : {})}\n onMouseEnter={() => onHighlight(index)}\n className={cn(\n \"flex cursor-pointer gap-2 rounded-sm px-2 py-1.5 text-sm\",\n option.description ? \"items-start\" : \"items-center\",\n index === highlighted && \"bg-accent\",\n selected && !tristate && \"font-medium\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {tristate ? (\n <div className=\"min-w-0 flex-1\">\n <FilterPill\n mode={mode ?? \"neutral\"}\n togglePosition=\"right\"\n interactive={false}\n label={option.label}\n onModeChange={(next) => onSetMode(option.value, next)}\n className=\"w-full justify-between\"\n />\n <ComboboxOptionDescription description={option.description} />\n </div>\n ) : (\n <>\n <Icon\n icon={UiCheck}\n className={cn(\n \"shrink-0 text-xs\",\n option.description && \"mt-1\",\n selected ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n <LabelIcon\n icon={option.icon}\n className={cn(\n \"text-sm text-muted-foreground\",\n option.description && \"mt-1\",\n )}\n />\n <ComboboxOptionText option={option} />\n </>\n )}\n </div>\n </Fragment>\n );\n })}\n {customEntry && (\n <div\n id={listId ? `${listId}-${filtered.length}` : undefined}\n role=\"option\"\n aria-selected={false}\n data-filter-add-custom={customEntry.value}\n title={customEntry.title}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onSelect(customEntry)}\n onMouseEnter={() => onHighlight(filtered.length)}\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-primary\",\n highlighted === filtered.length && \"bg-accent\",\n )}\n >\n <LabelIcon\n icon={customEntry.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 truncate\">{customEntry.label}</span>\n </div>\n )}\n {footer != null && (\n <div className=\"select-none px-2 py-1.5 text-[11px] text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>,\n document.body,\n );\n}\n\nfunction ComboboxOptionText({ option }: { option: ComboboxOption }) {\n return (\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{option.label}</span>\n <ComboboxOptionDescription description={option.description} />\n </span>\n );\n}\n\nfunction ComboboxOptionDescription({ description }: { description: string | undefined }) {\n return description ? (\n <span className=\"mt-0.5 block whitespace-pre-line text-xs font-normal leading-4 text-muted-foreground\">\n {description}\n </span>\n ) : null;\n}\n"],"names":["createPortal","jsxs","jsx","Fragment","cn","FilterPill","Icon","UiCheck","LabelIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ComboboxMenu.cjs","sources":["../../src/components/ComboboxMenu.tsx"],"sourcesContent":["import { Fragment, type ReactNode, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { Icon, LabelIcon } from \"../data/Icon\";\nimport { UiCheck } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport type {\n ComboboxOption,\n ComboboxTriStateMode,\n} from \"./combobox-types\";\nimport type { ComboboxMenuPosition } from \"./combobox-utils\";\n\nexport function ComboboxMenu({\n customEntry,\n filtered,\n floatingZ,\n footer,\n highlighted,\n isSelected,\n listId,\n listRef,\n loading,\n menuPos,\n modes,\n multiple,\n onHighlight,\n onSelect,\n onSetMode,\n tristate,\n}: {\n customEntry: ComboboxOption | null;\n filtered: ComboboxOption[];\n floatingZ: number;\n footer: ReactNode;\n highlighted: number;\n isSelected: (value: string) => boolean;\n listId: string | undefined;\n listRef: RefObject<HTMLDivElement>;\n loading: boolean | undefined;\n menuPos: ComboboxMenuPosition;\n modes: Record<string, ComboboxTriStateMode>;\n multiple: boolean;\n onHighlight: (index: number) => void;\n onSelect: (option: ComboboxOption) => void;\n onSetMode: (value: string, mode: string) => void;\n tristate: boolean;\n}) {\n return createPortal(\n <div\n id={listId}\n ref={listRef}\n role=\"listbox\"\n aria-multiselectable={multiple || undefined}\n style={{\n position: \"fixed\",\n ...(menuPos.top != null\n ? { top: menuPos.top }\n : { bottom: menuPos.bottom }),\n left: menuPos.left,\n minWidth: menuPos.width,\n maxWidth: menuPos.maxWidth,\n maxHeight: menuPos.maxHeight,\n zIndex: floatingZ,\n }}\n className=\"w-max overflow-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\"\n >\n {loading && filtered.length === 0 && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n Loading…\n </div>\n )}\n {!loading && filtered.length === 0 && !customEntry && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n No results\n </div>\n )}\n {filtered.map((option, index) => {\n const selected = isSelected(option.value);\n const mode = tristate ? modes[option.value] : undefined;\n const showHeader =\n option.group != null &&\n option.group !== filtered[index - 1]?.group;\n return (\n <Fragment key={option.value}>\n {showHeader && (\n <div\n role=\"presentation\"\n className=\"select-none px-2 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {option.group}\n </div>\n )}\n <div\n id={listId ? `${listId}-${index}` : undefined}\n role=\"option\"\n aria-selected={tristate ? mode != null : selected}\n aria-disabled={option.disabled}\n {...(mode != null\n ? {\n \"aria-label\": `${option.label}, ${\n mode === \"include\" ? \"included\" : \"excluded\"\n }`,\n }\n : {})}\n {...(option.title !== undefined ? { title: option.title } : {})}\n {...(tristate\n ? { \"data-filter-option\": option.value }\n : {})}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!tristate && !option.disabled) onSelect(option);\n }}\n {...(tristate\n ? {\n onClick: () => {\n if (!option.disabled) onSelect(option);\n },\n }\n : {})}\n onMouseEnter={() => onHighlight(index)}\n className={cn(\n \"flex cursor-pointer gap-2 rounded-sm px-2 py-1.5 text-sm\",\n option.description ? \"items-start\" : \"items-center\",\n index === highlighted && \"bg-accent\",\n selected && !tristate && \"font-medium\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {tristate ? (\n <div className=\"min-w-0 flex-1\">\n <FilterPill\n mode={mode ?? \"neutral\"}\n togglePosition=\"right\"\n interactive={false}\n label={option.label}\n onModeChange={(next) => onSetMode(option.value, next)}\n className=\"w-full justify-between\"\n />\n <ComboboxOptionDescription description={option.description} />\n </div>\n ) : (\n <>\n <Icon\n icon={UiCheck}\n className={cn(\n \"shrink-0 text-xs\",\n option.description && \"mt-1\",\n selected ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n <LabelIcon\n icon={option.icon}\n className={cn(\n \"text-sm text-muted-foreground\",\n option.description && \"mt-1\",\n )}\n />\n <ComboboxOptionText option={option} />\n {option.trailing != null && (\n // Capped and truncating rather than `shrink-0`: in a menu\n // clamped by the viewport edge the label is what identifies\n // the option, so the preview yields first.\n <span className=\"ml-auto min-w-0 max-w-[55%] truncate pl-2 text-right text-xs text-muted-foreground\">\n {option.trailing}\n </span>\n )}\n </>\n )}\n </div>\n </Fragment>\n );\n })}\n {customEntry && (\n <div\n id={listId ? `${listId}-${filtered.length}` : undefined}\n role=\"option\"\n aria-selected={false}\n data-filter-add-custom={customEntry.value}\n title={customEntry.title}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onSelect(customEntry)}\n onMouseEnter={() => onHighlight(filtered.length)}\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-primary\",\n highlighted === filtered.length && \"bg-accent\",\n )}\n >\n <LabelIcon\n icon={customEntry.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 truncate\">{customEntry.label}</span>\n </div>\n )}\n {footer != null && (\n <div className=\"select-none px-2 py-1.5 text-[11px] text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>,\n document.body,\n );\n}\n\nfunction ComboboxOptionText({ option }: { option: ComboboxOption }) {\n return (\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{option.label}</span>\n <ComboboxOptionDescription description={option.description} />\n </span>\n );\n}\n\nfunction ComboboxOptionDescription({ description }: { description: string | undefined }) {\n return description ? (\n <span className=\"mt-0.5 block whitespace-pre-line text-xs font-normal leading-4 text-muted-foreground\">\n {description}\n </span>\n ) : null;\n}\n"],"names":["createPortal","jsxs","jsx","Fragment","cn","FilterPill","Icon","UiCheck","LabelIcon"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxMenu.d.ts","sourceRoot":"","sources":["../../src/components/ComboboxMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMjE,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,wBAAgB,YAAY,CAAC,EAC3B,WAAW,EACX,QAAQ,EACR,SAAS,EACT,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,cAAc,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACnC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC5C,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,EAAE,OAAO,CAAC;CACnB,+
|
|
1
|
+
{"version":3,"file":"ComboboxMenu.d.ts","sourceRoot":"","sources":["../../src/components/ComboboxMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMjE,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,wBAAgB,YAAY,CAAC,EAC3B,WAAW,EACX,QAAQ,EACR,SAAS,EACT,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,cAAc,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACnC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC5C,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,EAAE,OAAO,CAAC;CACnB,+BA4JA"}
|
|
@@ -122,7 +122,11 @@ function ComboboxMenu({
|
|
|
122
122
|
)
|
|
123
123
|
}
|
|
124
124
|
),
|
|
125
|
-
/* @__PURE__ */ jsx(ComboboxOptionText, { option })
|
|
125
|
+
/* @__PURE__ */ jsx(ComboboxOptionText, { option }),
|
|
126
|
+
option.trailing != null && // Capped and truncating rather than `shrink-0`: in a menu
|
|
127
|
+
// clamped by the viewport edge the label is what identifies
|
|
128
|
+
// the option, so the preview yields first.
|
|
129
|
+
/* @__PURE__ */ jsx("span", { className: "ml-auto min-w-0 max-w-[55%] truncate pl-2 text-right text-xs text-muted-foreground", children: option.trailing })
|
|
126
130
|
] })
|
|
127
131
|
}
|
|
128
132
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxMenu.js","sources":["../../src/components/ComboboxMenu.tsx"],"sourcesContent":["import { Fragment, type ReactNode, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { Icon, LabelIcon } from \"../data/Icon\";\nimport { UiCheck } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport type {\n ComboboxOption,\n ComboboxTriStateMode,\n} from \"./combobox-types\";\nimport type { ComboboxMenuPosition } from \"./combobox-utils\";\n\nexport function ComboboxMenu({\n customEntry,\n filtered,\n floatingZ,\n footer,\n highlighted,\n isSelected,\n listId,\n listRef,\n loading,\n menuPos,\n modes,\n multiple,\n onHighlight,\n onSelect,\n onSetMode,\n tristate,\n}: {\n customEntry: ComboboxOption | null;\n filtered: ComboboxOption[];\n floatingZ: number;\n footer: ReactNode;\n highlighted: number;\n isSelected: (value: string) => boolean;\n listId: string | undefined;\n listRef: RefObject<HTMLDivElement>;\n loading: boolean | undefined;\n menuPos: ComboboxMenuPosition;\n modes: Record<string, ComboboxTriStateMode>;\n multiple: boolean;\n onHighlight: (index: number) => void;\n onSelect: (option: ComboboxOption) => void;\n onSetMode: (value: string, mode: string) => void;\n tristate: boolean;\n}) {\n return createPortal(\n <div\n id={listId}\n ref={listRef}\n role=\"listbox\"\n aria-multiselectable={multiple || undefined}\n style={{\n position: \"fixed\",\n ...(menuPos.top != null\n ? { top: menuPos.top }\n : { bottom: menuPos.bottom }),\n left: menuPos.left,\n minWidth: menuPos.width,\n maxWidth: menuPos.maxWidth,\n maxHeight: menuPos.maxHeight,\n zIndex: floatingZ,\n }}\n className=\"w-max overflow-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\"\n >\n {loading && filtered.length === 0 && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n Loading…\n </div>\n )}\n {!loading && filtered.length === 0 && !customEntry && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n No results\n </div>\n )}\n {filtered.map((option, index) => {\n const selected = isSelected(option.value);\n const mode = tristate ? modes[option.value] : undefined;\n const showHeader =\n option.group != null &&\n option.group !== filtered[index - 1]?.group;\n return (\n <Fragment key={option.value}>\n {showHeader && (\n <div\n role=\"presentation\"\n className=\"select-none px-2 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {option.group}\n </div>\n )}\n <div\n id={listId ? `${listId}-${index}` : undefined}\n role=\"option\"\n aria-selected={tristate ? mode != null : selected}\n aria-disabled={option.disabled}\n {...(mode != null\n ? {\n \"aria-label\": `${option.label}, ${\n mode === \"include\" ? \"included\" : \"excluded\"\n }`,\n }\n : {})}\n {...(option.title !== undefined ? { title: option.title } : {})}\n {...(tristate\n ? { \"data-filter-option\": option.value }\n : {})}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!tristate && !option.disabled) onSelect(option);\n }}\n {...(tristate\n ? {\n onClick: () => {\n if (!option.disabled) onSelect(option);\n },\n }\n : {})}\n onMouseEnter={() => onHighlight(index)}\n className={cn(\n \"flex cursor-pointer gap-2 rounded-sm px-2 py-1.5 text-sm\",\n option.description ? \"items-start\" : \"items-center\",\n index === highlighted && \"bg-accent\",\n selected && !tristate && \"font-medium\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {tristate ? (\n <div className=\"min-w-0 flex-1\">\n <FilterPill\n mode={mode ?? \"neutral\"}\n togglePosition=\"right\"\n interactive={false}\n label={option.label}\n onModeChange={(next) => onSetMode(option.value, next)}\n className=\"w-full justify-between\"\n />\n <ComboboxOptionDescription description={option.description} />\n </div>\n ) : (\n <>\n <Icon\n icon={UiCheck}\n className={cn(\n \"shrink-0 text-xs\",\n option.description && \"mt-1\",\n selected ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n <LabelIcon\n icon={option.icon}\n className={cn(\n \"text-sm text-muted-foreground\",\n option.description && \"mt-1\",\n )}\n />\n <ComboboxOptionText option={option} />\n </>\n )}\n </div>\n </Fragment>\n );\n })}\n {customEntry && (\n <div\n id={listId ? `${listId}-${filtered.length}` : undefined}\n role=\"option\"\n aria-selected={false}\n data-filter-add-custom={customEntry.value}\n title={customEntry.title}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onSelect(customEntry)}\n onMouseEnter={() => onHighlight(filtered.length)}\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-primary\",\n highlighted === filtered.length && \"bg-accent\",\n )}\n >\n <LabelIcon\n icon={customEntry.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 truncate\">{customEntry.label}</span>\n </div>\n )}\n {footer != null && (\n <div className=\"select-none px-2 py-1.5 text-[11px] text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>,\n document.body,\n );\n}\n\nfunction ComboboxOptionText({ option }: { option: ComboboxOption }) {\n return (\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{option.label}</span>\n <ComboboxOptionDescription description={option.description} />\n </span>\n );\n}\n\nfunction ComboboxOptionDescription({ description }: { description: string | undefined }) {\n return description ? (\n <span className=\"mt-0.5 block whitespace-pre-line text-xs font-normal leading-4 text-muted-foreground\">\n {description}\n </span>\n ) : null;\n}\n"],"names":["Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ComboboxMenu.js","sources":["../../src/components/ComboboxMenu.tsx"],"sourcesContent":["import { Fragment, type ReactNode, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { Icon, LabelIcon } from \"../data/Icon\";\nimport { UiCheck } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport type {\n ComboboxOption,\n ComboboxTriStateMode,\n} from \"./combobox-types\";\nimport type { ComboboxMenuPosition } from \"./combobox-utils\";\n\nexport function ComboboxMenu({\n customEntry,\n filtered,\n floatingZ,\n footer,\n highlighted,\n isSelected,\n listId,\n listRef,\n loading,\n menuPos,\n modes,\n multiple,\n onHighlight,\n onSelect,\n onSetMode,\n tristate,\n}: {\n customEntry: ComboboxOption | null;\n filtered: ComboboxOption[];\n floatingZ: number;\n footer: ReactNode;\n highlighted: number;\n isSelected: (value: string) => boolean;\n listId: string | undefined;\n listRef: RefObject<HTMLDivElement>;\n loading: boolean | undefined;\n menuPos: ComboboxMenuPosition;\n modes: Record<string, ComboboxTriStateMode>;\n multiple: boolean;\n onHighlight: (index: number) => void;\n onSelect: (option: ComboboxOption) => void;\n onSetMode: (value: string, mode: string) => void;\n tristate: boolean;\n}) {\n return createPortal(\n <div\n id={listId}\n ref={listRef}\n role=\"listbox\"\n aria-multiselectable={multiple || undefined}\n style={{\n position: \"fixed\",\n ...(menuPos.top != null\n ? { top: menuPos.top }\n : { bottom: menuPos.bottom }),\n left: menuPos.left,\n minWidth: menuPos.width,\n maxWidth: menuPos.maxWidth,\n maxHeight: menuPos.maxHeight,\n zIndex: floatingZ,\n }}\n className=\"w-max overflow-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\"\n >\n {loading && filtered.length === 0 && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n Loading…\n </div>\n )}\n {!loading && filtered.length === 0 && !customEntry && (\n <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">\n No results\n </div>\n )}\n {filtered.map((option, index) => {\n const selected = isSelected(option.value);\n const mode = tristate ? modes[option.value] : undefined;\n const showHeader =\n option.group != null &&\n option.group !== filtered[index - 1]?.group;\n return (\n <Fragment key={option.value}>\n {showHeader && (\n <div\n role=\"presentation\"\n className=\"select-none px-2 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {option.group}\n </div>\n )}\n <div\n id={listId ? `${listId}-${index}` : undefined}\n role=\"option\"\n aria-selected={tristate ? mode != null : selected}\n aria-disabled={option.disabled}\n {...(mode != null\n ? {\n \"aria-label\": `${option.label}, ${\n mode === \"include\" ? \"included\" : \"excluded\"\n }`,\n }\n : {})}\n {...(option.title !== undefined ? { title: option.title } : {})}\n {...(tristate\n ? { \"data-filter-option\": option.value }\n : {})}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!tristate && !option.disabled) onSelect(option);\n }}\n {...(tristate\n ? {\n onClick: () => {\n if (!option.disabled) onSelect(option);\n },\n }\n : {})}\n onMouseEnter={() => onHighlight(index)}\n className={cn(\n \"flex cursor-pointer gap-2 rounded-sm px-2 py-1.5 text-sm\",\n option.description ? \"items-start\" : \"items-center\",\n index === highlighted && \"bg-accent\",\n selected && !tristate && \"font-medium\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {tristate ? (\n <div className=\"min-w-0 flex-1\">\n <FilterPill\n mode={mode ?? \"neutral\"}\n togglePosition=\"right\"\n interactive={false}\n label={option.label}\n onModeChange={(next) => onSetMode(option.value, next)}\n className=\"w-full justify-between\"\n />\n <ComboboxOptionDescription description={option.description} />\n </div>\n ) : (\n <>\n <Icon\n icon={UiCheck}\n className={cn(\n \"shrink-0 text-xs\",\n option.description && \"mt-1\",\n selected ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n <LabelIcon\n icon={option.icon}\n className={cn(\n \"text-sm text-muted-foreground\",\n option.description && \"mt-1\",\n )}\n />\n <ComboboxOptionText option={option} />\n {option.trailing != null && (\n // Capped and truncating rather than `shrink-0`: in a menu\n // clamped by the viewport edge the label is what identifies\n // the option, so the preview yields first.\n <span className=\"ml-auto min-w-0 max-w-[55%] truncate pl-2 text-right text-xs text-muted-foreground\">\n {option.trailing}\n </span>\n )}\n </>\n )}\n </div>\n </Fragment>\n );\n })}\n {customEntry && (\n <div\n id={listId ? `${listId}-${filtered.length}` : undefined}\n role=\"option\"\n aria-selected={false}\n data-filter-add-custom={customEntry.value}\n title={customEntry.title}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onSelect(customEntry)}\n onMouseEnter={() => onHighlight(filtered.length)}\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-primary\",\n highlighted === filtered.length && \"bg-accent\",\n )}\n >\n <LabelIcon\n icon={customEntry.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 truncate\">{customEntry.label}</span>\n </div>\n )}\n {footer != null && (\n <div className=\"select-none px-2 py-1.5 text-[11px] text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>,\n document.body,\n );\n}\n\nfunction ComboboxOptionText({ option }: { option: ComboboxOption }) {\n return (\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{option.label}</span>\n <ComboboxOptionDescription description={option.description} />\n </span>\n );\n}\n\nfunction ComboboxOptionDescription({ description }: { description: string | undefined }) {\n return description ? (\n <span className=\"mt-0.5 block whitespace-pre-line text-xs font-normal leading-4 text-muted-foreground\">\n {description}\n </span>\n ) : null;\n}\n"],"names":["Fragment"],"mappings":";;;;;;;AAYO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAiBG;AACD,SAAO;AAAA,IACL;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAI;AAAA,QACJ,KAAK;AAAA,QACL,MAAK;AAAA,QACL,wBAAsB,YAAY;AAAA,QAClC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,GAAI,QAAQ,OAAO,OACf,EAAE,KAAK,QAAQ,QACf,EAAE,QAAQ,QAAQ,OAAA;AAAA,UACtB,MAAM,QAAQ;AAAA,UACd,UAAU,QAAQ;AAAA,UAClB,UAAU,QAAQ;AAAA,UAClB,WAAW,QAAQ;AAAA,UACnB,QAAQ;AAAA,QAAA;AAAA,QAEV,WAAU;AAAA,QAET,UAAA;AAAA,UAAA,WAAW,SAAS,WAAW,yBAC7B,OAAA,EAAI,WAAU,uDAAsD,UAAA,WAAA,CAErE;AAAA,UAED,CAAC,WAAW,SAAS,WAAW,KAAK,CAAC,eACrC,oBAAC,OAAA,EAAI,WAAU,uDAAsD,UAAA,aAAA,CAErE;AAAA,UAED,SAAS,IAAI,CAAC,QAAQ,UAAU;;AAC/B,kBAAM,WAAW,WAAW,OAAO,KAAK;AACxC,kBAAM,OAAO,WAAW,MAAM,OAAO,KAAK,IAAI;AAC9C,kBAAM,aACJ,OAAO,SAAS,QAChB,OAAO,YAAU,cAAS,QAAQ,CAAC,MAAlB,mBAAqB;AACxC,mBACE,qBAACA,UAAA,EACE,UAAA;AAAA,cAAA,cACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBAET,UAAA,OAAO;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGZ;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,IAAI,SAAS,GAAG,MAAM,IAAI,KAAK,KAAK;AAAA,kBACpC,MAAK;AAAA,kBACL,iBAAe,WAAW,QAAQ,OAAO;AAAA,kBACzC,iBAAe,OAAO;AAAA,kBACrB,GAAI,QAAQ,OACT;AAAA,oBACE,cAAc,GAAG,OAAO,KAAK,KAC3B,SAAS,YAAY,aAAa,UACpC;AAAA,kBAAA,IAEF,CAAA;AAAA,kBACH,GAAI,OAAO,UAAU,SAAY,EAAE,OAAO,OAAO,MAAA,IAAU,CAAA;AAAA,kBAC3D,GAAI,WACD,EAAE,sBAAsB,OAAO,MAAA,IAC/B,CAAA;AAAA,kBACJ,aAAa,CAAC,UAAU;AACtB,0BAAM,eAAA;AACN,wBAAI,CAAC,YAAY,CAAC,OAAO,mBAAmB,MAAM;AAAA,kBACpD;AAAA,kBACC,GAAI,WACD;AAAA,oBACE,SAAS,MAAM;AACb,0BAAI,CAAC,OAAO,SAAU,UAAS,MAAM;AAAA,oBACvC;AAAA,kBAAA,IAEF,CAAA;AAAA,kBACJ,cAAc,MAAM,YAAY,KAAK;AAAA,kBACrC,WAAW;AAAA,oBACT;AAAA,oBACA,OAAO,cAAc,gBAAgB;AAAA,oBACrC,UAAU,eAAe;AAAA,oBACzB,YAAY,CAAC,YAAY;AAAA,oBACzB,OAAO,YAAY;AAAA,kBAAA;AAAA,kBAGpB,UAAA,WACC,qBAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,oBAAA;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,MAAM,QAAQ;AAAA,wBACd,gBAAe;AAAA,wBACf,aAAa;AAAA,wBACb,OAAO,OAAO;AAAA,wBACd,cAAc,CAAC,SAAS,UAAU,OAAO,OAAO,IAAI;AAAA,wBACpD,WAAU;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBAEZ,oBAAC,2BAAA,EAA0B,aAAa,OAAO,YAAA,CAAa;AAAA,kBAAA,EAAA,CAC9D,IAEA,qBAAAA,YAAA,EACE,UAAA;AAAA,oBAAA;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,MAAM;AAAA,wBACN,WAAW;AAAA,0BACT;AAAA,0BACA,OAAO,eAAe;AAAA,0BACtB,WAAW,gBAAgB;AAAA,wBAAA;AAAA,sBAC7B;AAAA,oBAAA;AAAA,oBAEF;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,MAAM,OAAO;AAAA,wBACb,WAAW;AAAA,0BACT;AAAA,0BACA,OAAO,eAAe;AAAA,wBAAA;AAAA,sBACxB;AAAA,oBAAA;AAAA,oBAEF,oBAAC,sBAAmB,QAAgB;AAAA,oBACnC,OAAO,YAAY;AAAA;AAAA;AAAA,oBAIlB,oBAAC,QAAA,EAAK,WAAU,sFACb,iBAAO,SAAA,CACV;AAAA,kBAAA,EAAA,CAEJ;AAAA,gBAAA;AAAA,cAAA;AAAA,YAEJ,EAAA,GArFa,OAAO,KAsFtB;AAAA,UAEJ,CAAC;AAAA,UACA,eACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI,SAAS,GAAG,MAAM,IAAI,SAAS,MAAM,KAAK;AAAA,cAC9C,MAAK;AAAA,cACL,iBAAe;AAAA,cACf,0BAAwB,YAAY;AAAA,cACpC,OAAO,YAAY;AAAA,cACnB,aAAa,CAAC,UAAU,MAAM,eAAA;AAAA,cAC9B,SAAS,MAAM,SAAS,WAAW;AAAA,cACnC,cAAc,MAAM,YAAY,SAAS,MAAM;AAAA,cAC/C,WAAW;AAAA,gBACT;AAAA,gBACA,gBAAgB,SAAS,UAAU;AAAA,cAAA;AAAA,cAGrC,UAAA;AAAA,gBAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAM,YAAY;AAAA,oBAClB,WAAU;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEZ,oBAAC,QAAA,EAAK,WAAU,oBAAoB,sBAAY,MAAA,CAAM;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGzD,UAAU,QACT,oBAAC,OAAA,EAAI,WAAU,6DACZ,UAAA,OAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGJ,SAAS;AAAA,EAAA;AAEb;AAEA,SAAS,mBAAmB,EAAE,UAAsC;AAClE,SACE,qBAAC,QAAA,EAAK,WAAU,kBACd,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,WAAU,kBAAkB,UAAA,OAAO,OAAM;AAAA,IAC/C,oBAAC,2BAAA,EAA0B,aAAa,OAAO,YAAA,CAAa;AAAA,EAAA,GAC9D;AAEJ;AAEA,SAAS,0BAA0B,EAAE,eAAoD;AACvF,SAAO,cACL,oBAAC,QAAA,EAAK,WAAU,wFACb,uBACH,IACE;AACN;"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const SecretKeySelector_model = require("./SecretKeySelector.model.cjs");
|
|
4
|
+
const SCHEME_TO_MODE = {
|
|
5
|
+
svc: "service",
|
|
6
|
+
ip: "cluster-ip",
|
|
7
|
+
proxy: "api-proxy",
|
|
8
|
+
host: "ingress",
|
|
9
|
+
portforward: "port-forward"
|
|
10
|
+
};
|
|
11
|
+
const MODE_TO_SCHEME = Object.fromEntries(
|
|
12
|
+
Object.entries(SCHEME_TO_MODE).map(([scheme, mode]) => [mode, scheme])
|
|
13
|
+
);
|
|
14
|
+
const WORKLOAD_URL = /^([a-z]+):\/\/([^/:?#]*)(?::(\d+))?([^?#]*)(?:\?(.+))?$/;
|
|
15
|
+
function validPort(port) {
|
|
16
|
+
return /^\d+$/.test(port) && Number(port) >= 1 && Number(port) <= 65535;
|
|
17
|
+
}
|
|
18
|
+
function parseTarget(mode, host, query) {
|
|
19
|
+
const dot = host.indexOf(".");
|
|
20
|
+
const name = dot >= 0 ? host.slice(0, dot) : host;
|
|
21
|
+
const namespace = dot >= 0 ? host.slice(dot + 1) : "";
|
|
22
|
+
if (!name) return void 0;
|
|
23
|
+
const kind = mode === "ingress" ? "ingress" : mode === "port-forward" && new URLSearchParams(query).get("kind") === "deployment" ? "deployment" : "service";
|
|
24
|
+
return {
|
|
25
|
+
kind,
|
|
26
|
+
name,
|
|
27
|
+
...namespace ? { namespace } : {}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function parseWorkloadValue(raw) {
|
|
31
|
+
const match = WORKLOAD_URL.exec(raw);
|
|
32
|
+
if (!match) return void 0;
|
|
33
|
+
const [, scheme = "", host = "", port = "", path = "", query = ""] = match;
|
|
34
|
+
const mode = SCHEME_TO_MODE[scheme];
|
|
35
|
+
if (!mode || port && !validPort(port)) return void 0;
|
|
36
|
+
if (mode === "port-forward" && (new URLSearchParams(query).has("selector") || !["", "service", "deployment"].includes(
|
|
37
|
+
new URLSearchParams(query).get("kind") ?? ""
|
|
38
|
+
))) {
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
const target = parseTarget(mode, host, query);
|
|
42
|
+
if (!target) return void 0;
|
|
43
|
+
return {
|
|
44
|
+
mode,
|
|
45
|
+
target,
|
|
46
|
+
...port ? { port } : {},
|
|
47
|
+
...path ? { path } : {}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function parseEndpointValue(raw) {
|
|
51
|
+
if (typeof raw !== "string" || raw === "") return void 0;
|
|
52
|
+
return parseWorkloadValue(raw) ?? {
|
|
53
|
+
mode: "url",
|
|
54
|
+
source: SecretKeySelector_model.parseSecretRef(raw)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function workloadHost(target) {
|
|
58
|
+
if (!target.name) {
|
|
59
|
+
throw new Error("Endpoint workload mode requires a workload name");
|
|
60
|
+
}
|
|
61
|
+
return target.namespace ? `${target.name}.${target.namespace}` : target.name;
|
|
62
|
+
}
|
|
63
|
+
function validateWorkloadValue(value) {
|
|
64
|
+
if (value.mode === "ingress" && value.target.kind !== "ingress") {
|
|
65
|
+
throw new Error("Ingress endpoint mode requires an ingress target");
|
|
66
|
+
}
|
|
67
|
+
if (value.mode !== "ingress" && value.mode !== "port-forward" && value.target.kind !== "service") {
|
|
68
|
+
throw new Error(`${value.mode} endpoint mode requires a service target`);
|
|
69
|
+
}
|
|
70
|
+
if (value.mode === "port-forward" && !["service", "deployment"].includes(value.target.kind)) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
"Port-forward endpoint mode requires a service or deployment target"
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (value.port && !validPort(value.port)) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`Endpoint port "${value.port}" must be between 1 and 65535`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if (value.path && !value.path.startsWith("/")) {
|
|
81
|
+
throw new Error(`Endpoint path "${value.path}" must start with /`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function serializeEndpointValue(value) {
|
|
85
|
+
if (!value) return "";
|
|
86
|
+
if (value.mode === "url") return SecretKeySelector_model.serializeSecretRef(value.source);
|
|
87
|
+
validateWorkloadValue(value);
|
|
88
|
+
const scheme = MODE_TO_SCHEME[value.mode];
|
|
89
|
+
const port = value.port ? `:${value.port}` : "";
|
|
90
|
+
const path = value.path ?? "";
|
|
91
|
+
const kind = value.mode === "port-forward" && value.target.kind === "deployment" ? "?kind=deployment" : "";
|
|
92
|
+
return `${scheme}://${workloadHost(value.target)}${port}${path}${kind}`;
|
|
93
|
+
}
|
|
94
|
+
exports.parseEndpointValue = parseEndpointValue;
|
|
95
|
+
exports.serializeEndpointValue = serializeEndpointValue;
|
|
96
|
+
//# sourceMappingURL=EndpointSelector.model.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EndpointSelector.model.cjs","sources":["../../src/components/EndpointSelector.model.ts"],"sourcesContent":["import type { SecretKeySelectorProps, SecretKeyValue } from \"./SecretKeySelector\";\nimport type {\n WorkloadKind,\n WorkloadResource,\n} from \"./workload-picker-utils\";\nimport type { WorkloadPickerProps } from \"./WorkloadPicker\";\nimport {\n parseSecretRef,\n serializeSecretRef,\n} from \"./SecretKeySelector.model\";\n\nexport type EndpointMode =\n | \"url\"\n | \"service\"\n | \"cluster-ip\"\n | \"api-proxy\"\n | \"ingress\"\n | \"port-forward\";\n\nexport type EndpointWorkloadMode = Exclude<EndpointMode, \"url\">;\n\nexport type EndpointTarget =\n | {\n kind: \"ingress\";\n name: string;\n host?: string;\n namespace?: string;\n }\n | {\n kind: Exclude<WorkloadKind, \"ingress\">;\n name: string;\n namespace?: string;\n };\n\nexport type EndpointWorkloadValue = {\n mode: EndpointWorkloadMode;\n target: EndpointTarget;\n scheme?: string;\n port?: string;\n path?: string;\n};\n\nexport type EndpointSelectorValue =\n | {\n mode: \"url\";\n source: SecretKeyValue;\n }\n | EndpointWorkloadValue;\n\nexport type EndpointSelectorDefaults = {\n scheme?: string;\n path?: string;\n};\n\nexport type EndpointUrlSelectorProps = Omit<\n SecretKeySelectorProps,\n \"value\" | \"onChange\"\n>;\n\nexport type EndpointSelectorProps = {\n value: EndpointSelectorValue | undefined;\n onChange: (value: EndpointSelectorValue | undefined) => void;\n namespace?: string;\n modes: EndpointMode[];\n defaultMode?: EndpointMode;\n loadWorkloads: WorkloadPickerProps[\"loadWorkloads\"];\n urlSelector?: EndpointUrlSelectorProps;\n modeKinds?: Partial<Record<EndpointWorkloadMode, WorkloadKind[]>>;\n defaults?: EndpointSelectorDefaults;\n preferredPorts?: readonly number[];\n schemes?: string[];\n allowCustomScheme?: boolean;\n allowCustomPort?: boolean;\n showScheme?: boolean;\n showPath?: boolean;\n showIngressPort?: boolean;\n className?: string;\n};\n\nexport type EndpointResources = Partial<\n Record<WorkloadKind, WorkloadResource[]>\n>;\n\nconst SCHEME_TO_MODE = {\n svc: \"service\",\n ip: \"cluster-ip\",\n proxy: \"api-proxy\",\n host: \"ingress\",\n portforward: \"port-forward\",\n} as const satisfies Record<string, EndpointMode>;\n\nconst MODE_TO_SCHEME = Object.fromEntries(\n Object.entries(SCHEME_TO_MODE).map(([scheme, mode]) => [mode, scheme]),\n) as Record<EndpointWorkloadMode, keyof typeof SCHEME_TO_MODE>;\n\nconst WORKLOAD_URL =\n /^([a-z]+):\\/\\/([^/:?#]*)(?::(\\d+))?([^?#]*)(?:\\?(.+))?$/;\n\nfunction validPort(port: string) {\n return /^\\d+$/.test(port) && Number(port) >= 1 && Number(port) <= 65535;\n}\n\nfunction parseTarget(\n mode: EndpointWorkloadMode,\n host: string,\n query: string,\n): EndpointTarget | undefined {\n const dot = host.indexOf(\".\");\n const name = dot >= 0 ? host.slice(0, dot) : host;\n const namespace = dot >= 0 ? host.slice(dot + 1) : \"\";\n if (!name) return undefined;\n\n const kind =\n mode === \"ingress\"\n ? \"ingress\"\n : mode === \"port-forward\" &&\n new URLSearchParams(query).get(\"kind\") === \"deployment\"\n ? \"deployment\"\n : \"service\";\n return {\n kind,\n name,\n ...(namespace ? { namespace } : {}),\n };\n}\n\nfunction parseWorkloadValue(raw: string): EndpointWorkloadValue | undefined {\n const match = WORKLOAD_URL.exec(raw);\n if (!match) return undefined;\n const [, scheme = \"\", host = \"\", port = \"\", path = \"\", query = \"\"] =\n match;\n const mode = SCHEME_TO_MODE[scheme as keyof typeof SCHEME_TO_MODE];\n if (!mode || (port && !validPort(port))) return undefined;\n if (\n mode === \"port-forward\" &&\n (new URLSearchParams(query).has(\"selector\") ||\n ![\"\", \"service\", \"deployment\"].includes(\n new URLSearchParams(query).get(\"kind\") ?? \"\",\n ))\n ) {\n return undefined;\n }\n\n const target = parseTarget(mode, host, query);\n if (!target) return undefined;\n return {\n mode,\n target,\n ...(port ? { port } : {}),\n ...(path ? { path } : {}),\n };\n}\n\nexport function parseEndpointValue(\n raw: unknown,\n): EndpointSelectorValue | undefined {\n if (typeof raw !== \"string\" || raw === \"\") return undefined;\n return (\n parseWorkloadValue(raw) ?? {\n mode: \"url\",\n source: parseSecretRef(raw)!,\n }\n );\n}\n\nfunction workloadHost(target: EndpointTarget) {\n if (!target.name) {\n throw new Error(\"Endpoint workload mode requires a workload name\");\n }\n return target.namespace\n ? `${target.name}.${target.namespace}`\n : target.name;\n}\n\nfunction validateWorkloadValue(value: EndpointWorkloadValue) {\n if (value.mode === \"ingress\" && value.target.kind !== \"ingress\") {\n throw new Error(\"Ingress endpoint mode requires an ingress target\");\n }\n if (\n value.mode !== \"ingress\" &&\n value.mode !== \"port-forward\" &&\n value.target.kind !== \"service\"\n ) {\n throw new Error(`${value.mode} endpoint mode requires a service target`);\n }\n if (\n value.mode === \"port-forward\" &&\n ![\"service\", \"deployment\"].includes(value.target.kind)\n ) {\n throw new Error(\n \"Port-forward endpoint mode requires a service or deployment target\",\n );\n }\n if (value.port && !validPort(value.port)) {\n throw new Error(\n `Endpoint port \"${value.port}\" must be between 1 and 65535`,\n );\n }\n if (value.path && !value.path.startsWith(\"/\")) {\n throw new Error(`Endpoint path \"${value.path}\" must start with /`);\n }\n}\n\nexport function serializeEndpointValue(\n value: EndpointSelectorValue | undefined,\n): string {\n if (!value) return \"\";\n if (value.mode === \"url\") return serializeSecretRef(value.source);\n validateWorkloadValue(value);\n const scheme = MODE_TO_SCHEME[value.mode];\n const port = value.port ? `:${value.port}` : \"\";\n const path = value.path ?? \"\";\n const kind =\n value.mode === \"port-forward\" && value.target.kind === \"deployment\"\n ? \"?kind=deployment\"\n : \"\";\n return `${scheme}://${workloadHost(value.target)}${port}${path}${kind}`;\n}\n"],"names":["parseSecretRef","serializeSecretRef"],"mappings":"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"}
|
|
@@ -49,4 +49,6 @@ export type EndpointSelectorProps = {
|
|
|
49
49
|
className?: string;
|
|
50
50
|
};
|
|
51
51
|
export type EndpointResources = Partial<Record<WorkloadKind, WorkloadResource[]>>;
|
|
52
|
+
export declare function parseEndpointValue(raw: unknown): EndpointSelectorValue | undefined;
|
|
53
|
+
export declare function serializeEndpointValue(value: EndpointSelectorValue | undefined): string;
|
|
52
54
|
//# sourceMappingURL=EndpointSelector.model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EndpointSelector.model.d.ts","sourceRoot":"","sources":["../../src/components/EndpointSelector.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"EndpointSelector.model.d.ts","sourceRoot":"","sources":["../../src/components/EndpointSelector.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAM5D,MAAM,MAAM,YAAY,GACpB,KAAK,GACL,SAAS,GACT,YAAY,GACZ,WAAW,GACX,SAAS,GACT,cAAc,CAAC;AAEnB,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAEhE,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,MAAM,EAAE,cAAc,CAAC;CACxB,GACD,qBAAqB,CAAC;AAE1B,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,sBAAsB,EACtB,OAAO,GAAG,UAAU,CACrB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzC,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,KAAK,IAAI,CAAC;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACpD,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;IAClE,QAAQ,CAAC,EAAE,wBAAwB,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,OAAO,CACrC,MAAM,CAAC,YAAY,EAAE,gBAAgB,EAAE,CAAC,CACzC,CAAC;AAwEF,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,GACX,qBAAqB,GAAG,SAAS,CAQnC;AAwCD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GACvC,MAAM,CAYR"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { parseSecretRef, serializeSecretRef } from "./SecretKeySelector.model.js";
|
|
2
|
+
const SCHEME_TO_MODE = {
|
|
3
|
+
svc: "service",
|
|
4
|
+
ip: "cluster-ip",
|
|
5
|
+
proxy: "api-proxy",
|
|
6
|
+
host: "ingress",
|
|
7
|
+
portforward: "port-forward"
|
|
8
|
+
};
|
|
9
|
+
const MODE_TO_SCHEME = Object.fromEntries(
|
|
10
|
+
Object.entries(SCHEME_TO_MODE).map(([scheme, mode]) => [mode, scheme])
|
|
11
|
+
);
|
|
12
|
+
const WORKLOAD_URL = /^([a-z]+):\/\/([^/:?#]*)(?::(\d+))?([^?#]*)(?:\?(.+))?$/;
|
|
13
|
+
function validPort(port) {
|
|
14
|
+
return /^\d+$/.test(port) && Number(port) >= 1 && Number(port) <= 65535;
|
|
15
|
+
}
|
|
16
|
+
function parseTarget(mode, host, query) {
|
|
17
|
+
const dot = host.indexOf(".");
|
|
18
|
+
const name = dot >= 0 ? host.slice(0, dot) : host;
|
|
19
|
+
const namespace = dot >= 0 ? host.slice(dot + 1) : "";
|
|
20
|
+
if (!name) return void 0;
|
|
21
|
+
const kind = mode === "ingress" ? "ingress" : mode === "port-forward" && new URLSearchParams(query).get("kind") === "deployment" ? "deployment" : "service";
|
|
22
|
+
return {
|
|
23
|
+
kind,
|
|
24
|
+
name,
|
|
25
|
+
...namespace ? { namespace } : {}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function parseWorkloadValue(raw) {
|
|
29
|
+
const match = WORKLOAD_URL.exec(raw);
|
|
30
|
+
if (!match) return void 0;
|
|
31
|
+
const [, scheme = "", host = "", port = "", path = "", query = ""] = match;
|
|
32
|
+
const mode = SCHEME_TO_MODE[scheme];
|
|
33
|
+
if (!mode || port && !validPort(port)) return void 0;
|
|
34
|
+
if (mode === "port-forward" && (new URLSearchParams(query).has("selector") || !["", "service", "deployment"].includes(
|
|
35
|
+
new URLSearchParams(query).get("kind") ?? ""
|
|
36
|
+
))) {
|
|
37
|
+
return void 0;
|
|
38
|
+
}
|
|
39
|
+
const target = parseTarget(mode, host, query);
|
|
40
|
+
if (!target) return void 0;
|
|
41
|
+
return {
|
|
42
|
+
mode,
|
|
43
|
+
target,
|
|
44
|
+
...port ? { port } : {},
|
|
45
|
+
...path ? { path } : {}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function parseEndpointValue(raw) {
|
|
49
|
+
if (typeof raw !== "string" || raw === "") return void 0;
|
|
50
|
+
return parseWorkloadValue(raw) ?? {
|
|
51
|
+
mode: "url",
|
|
52
|
+
source: parseSecretRef(raw)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function workloadHost(target) {
|
|
56
|
+
if (!target.name) {
|
|
57
|
+
throw new Error("Endpoint workload mode requires a workload name");
|
|
58
|
+
}
|
|
59
|
+
return target.namespace ? `${target.name}.${target.namespace}` : target.name;
|
|
60
|
+
}
|
|
61
|
+
function validateWorkloadValue(value) {
|
|
62
|
+
if (value.mode === "ingress" && value.target.kind !== "ingress") {
|
|
63
|
+
throw new Error("Ingress endpoint mode requires an ingress target");
|
|
64
|
+
}
|
|
65
|
+
if (value.mode !== "ingress" && value.mode !== "port-forward" && value.target.kind !== "service") {
|
|
66
|
+
throw new Error(`${value.mode} endpoint mode requires a service target`);
|
|
67
|
+
}
|
|
68
|
+
if (value.mode === "port-forward" && !["service", "deployment"].includes(value.target.kind)) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
"Port-forward endpoint mode requires a service or deployment target"
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
if (value.port && !validPort(value.port)) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Endpoint port "${value.port}" must be between 1 and 65535`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
if (value.path && !value.path.startsWith("/")) {
|
|
79
|
+
throw new Error(`Endpoint path "${value.path}" must start with /`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function serializeEndpointValue(value) {
|
|
83
|
+
if (!value) return "";
|
|
84
|
+
if (value.mode === "url") return serializeSecretRef(value.source);
|
|
85
|
+
validateWorkloadValue(value);
|
|
86
|
+
const scheme = MODE_TO_SCHEME[value.mode];
|
|
87
|
+
const port = value.port ? `:${value.port}` : "";
|
|
88
|
+
const path = value.path ?? "";
|
|
89
|
+
const kind = value.mode === "port-forward" && value.target.kind === "deployment" ? "?kind=deployment" : "";
|
|
90
|
+
return `${scheme}://${workloadHost(value.target)}${port}${path}${kind}`;
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
parseEndpointValue,
|
|
94
|
+
serializeEndpointValue
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=EndpointSelector.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EndpointSelector.model.js","sources":["../../src/components/EndpointSelector.model.ts"],"sourcesContent":["import type { SecretKeySelectorProps, SecretKeyValue } from \"./SecretKeySelector\";\nimport type {\n WorkloadKind,\n WorkloadResource,\n} from \"./workload-picker-utils\";\nimport type { WorkloadPickerProps } from \"./WorkloadPicker\";\nimport {\n parseSecretRef,\n serializeSecretRef,\n} from \"./SecretKeySelector.model\";\n\nexport type EndpointMode =\n | \"url\"\n | \"service\"\n | \"cluster-ip\"\n | \"api-proxy\"\n | \"ingress\"\n | \"port-forward\";\n\nexport type EndpointWorkloadMode = Exclude<EndpointMode, \"url\">;\n\nexport type EndpointTarget =\n | {\n kind: \"ingress\";\n name: string;\n host?: string;\n namespace?: string;\n }\n | {\n kind: Exclude<WorkloadKind, \"ingress\">;\n name: string;\n namespace?: string;\n };\n\nexport type EndpointWorkloadValue = {\n mode: EndpointWorkloadMode;\n target: EndpointTarget;\n scheme?: string;\n port?: string;\n path?: string;\n};\n\nexport type EndpointSelectorValue =\n | {\n mode: \"url\";\n source: SecretKeyValue;\n }\n | EndpointWorkloadValue;\n\nexport type EndpointSelectorDefaults = {\n scheme?: string;\n path?: string;\n};\n\nexport type EndpointUrlSelectorProps = Omit<\n SecretKeySelectorProps,\n \"value\" | \"onChange\"\n>;\n\nexport type EndpointSelectorProps = {\n value: EndpointSelectorValue | undefined;\n onChange: (value: EndpointSelectorValue | undefined) => void;\n namespace?: string;\n modes: EndpointMode[];\n defaultMode?: EndpointMode;\n loadWorkloads: WorkloadPickerProps[\"loadWorkloads\"];\n urlSelector?: EndpointUrlSelectorProps;\n modeKinds?: Partial<Record<EndpointWorkloadMode, WorkloadKind[]>>;\n defaults?: EndpointSelectorDefaults;\n preferredPorts?: readonly number[];\n schemes?: string[];\n allowCustomScheme?: boolean;\n allowCustomPort?: boolean;\n showScheme?: boolean;\n showPath?: boolean;\n showIngressPort?: boolean;\n className?: string;\n};\n\nexport type EndpointResources = Partial<\n Record<WorkloadKind, WorkloadResource[]>\n>;\n\nconst SCHEME_TO_MODE = {\n svc: \"service\",\n ip: \"cluster-ip\",\n proxy: \"api-proxy\",\n host: \"ingress\",\n portforward: \"port-forward\",\n} as const satisfies Record<string, EndpointMode>;\n\nconst MODE_TO_SCHEME = Object.fromEntries(\n Object.entries(SCHEME_TO_MODE).map(([scheme, mode]) => [mode, scheme]),\n) as Record<EndpointWorkloadMode, keyof typeof SCHEME_TO_MODE>;\n\nconst WORKLOAD_URL =\n /^([a-z]+):\\/\\/([^/:?#]*)(?::(\\d+))?([^?#]*)(?:\\?(.+))?$/;\n\nfunction validPort(port: string) {\n return /^\\d+$/.test(port) && Number(port) >= 1 && Number(port) <= 65535;\n}\n\nfunction parseTarget(\n mode: EndpointWorkloadMode,\n host: string,\n query: string,\n): EndpointTarget | undefined {\n const dot = host.indexOf(\".\");\n const name = dot >= 0 ? host.slice(0, dot) : host;\n const namespace = dot >= 0 ? host.slice(dot + 1) : \"\";\n if (!name) return undefined;\n\n const kind =\n mode === \"ingress\"\n ? \"ingress\"\n : mode === \"port-forward\" &&\n new URLSearchParams(query).get(\"kind\") === \"deployment\"\n ? \"deployment\"\n : \"service\";\n return {\n kind,\n name,\n ...(namespace ? { namespace } : {}),\n };\n}\n\nfunction parseWorkloadValue(raw: string): EndpointWorkloadValue | undefined {\n const match = WORKLOAD_URL.exec(raw);\n if (!match) return undefined;\n const [, scheme = \"\", host = \"\", port = \"\", path = \"\", query = \"\"] =\n match;\n const mode = SCHEME_TO_MODE[scheme as keyof typeof SCHEME_TO_MODE];\n if (!mode || (port && !validPort(port))) return undefined;\n if (\n mode === \"port-forward\" &&\n (new URLSearchParams(query).has(\"selector\") ||\n ![\"\", \"service\", \"deployment\"].includes(\n new URLSearchParams(query).get(\"kind\") ?? \"\",\n ))\n ) {\n return undefined;\n }\n\n const target = parseTarget(mode, host, query);\n if (!target) return undefined;\n return {\n mode,\n target,\n ...(port ? { port } : {}),\n ...(path ? { path } : {}),\n };\n}\n\nexport function parseEndpointValue(\n raw: unknown,\n): EndpointSelectorValue | undefined {\n if (typeof raw !== \"string\" || raw === \"\") return undefined;\n return (\n parseWorkloadValue(raw) ?? {\n mode: \"url\",\n source: parseSecretRef(raw)!,\n }\n );\n}\n\nfunction workloadHost(target: EndpointTarget) {\n if (!target.name) {\n throw new Error(\"Endpoint workload mode requires a workload name\");\n }\n return target.namespace\n ? `${target.name}.${target.namespace}`\n : target.name;\n}\n\nfunction validateWorkloadValue(value: EndpointWorkloadValue) {\n if (value.mode === \"ingress\" && value.target.kind !== \"ingress\") {\n throw new Error(\"Ingress endpoint mode requires an ingress target\");\n }\n if (\n value.mode !== \"ingress\" &&\n value.mode !== \"port-forward\" &&\n value.target.kind !== \"service\"\n ) {\n throw new Error(`${value.mode} endpoint mode requires a service target`);\n }\n if (\n value.mode === \"port-forward\" &&\n ![\"service\", \"deployment\"].includes(value.target.kind)\n ) {\n throw new Error(\n \"Port-forward endpoint mode requires a service or deployment target\",\n );\n }\n if (value.port && !validPort(value.port)) {\n throw new Error(\n `Endpoint port \"${value.port}\" must be between 1 and 65535`,\n );\n }\n if (value.path && !value.path.startsWith(\"/\")) {\n throw new Error(`Endpoint path \"${value.path}\" must start with /`);\n }\n}\n\nexport function serializeEndpointValue(\n value: EndpointSelectorValue | undefined,\n): string {\n if (!value) return \"\";\n if (value.mode === \"url\") return serializeSecretRef(value.source);\n validateWorkloadValue(value);\n const scheme = MODE_TO_SCHEME[value.mode];\n const port = value.port ? `:${value.port}` : \"\";\n const path = value.path ?? \"\";\n const kind =\n value.mode === \"port-forward\" && value.target.kind === \"deployment\"\n ? \"?kind=deployment\"\n : \"\";\n return `${scheme}://${workloadHost(value.target)}${port}${path}${kind}`;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -103,7 +103,7 @@ function ErrorFallback({
|
|
|
103
103
|
onClick: () => void copyDetails(),
|
|
104
104
|
children: [
|
|
105
105
|
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: copyState === "copied" ? UiCheck.UiCheck : UiCopy.UiCopy }),
|
|
106
|
-
copyState === "copied" ? "Copied" : "Copy error
|
|
106
|
+
copyState === "copied" ? "Copied" : "Copy error report"
|
|
107
107
|
]
|
|
108
108
|
}
|
|
109
109
|
),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorWrapper.cjs","sources":["../../src/components/ErrorWrapper.tsx"],"sourcesContent":["import {\n Component,\n useMemo,\n useState,\n type ErrorInfo,\n type ReactNode,\n} from \"react\";\nimport { ErrorDetails } from \"../data/diagnostics/ErrorDetails\";\nimport {\n normalizeErrorDiagnostics,\n type ErrorDiagnostics,\n} from \"../data/diagnostics/error-diagnostics\";\nimport { Icon } from \"../data/Icon\";\nimport { UiCheck, UiCopy, UiWarningTriangle } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\nexport type ErrorWrapperProps = {\n children: ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n};\n\ntype ErrorWrapperState = {\n error: Error | null;\n componentStack: string | null;\n};\n\nexport class ErrorWrapper extends Component<\n ErrorWrapperProps,\n ErrorWrapperState\n> {\n override state: ErrorWrapperState = {\n error: null,\n componentStack: null,\n };\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n override componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n this.setState({ componentStack: errorInfo.componentStack ?? null });\n this.props.onError?.(error, errorInfo);\n }\n\n override render() {\n if (this.state.error) {\n return (\n <ErrorFallback\n error={this.state.error}\n componentStack={this.state.componentStack}\n />\n );\n }\n return this.props.children;\n }\n}\n\ntype CopyState = \"idle\" | \"copied\" | \"failed\";\n\nfunction copyStatusMessage(copyState: CopyState): string {\n if (copyState === \"copied\") return \"Error details copied to clipboard.\";\n if (copyState === \"failed\") {\n return \"Clipboard access failed. Expand the error details to copy individual values.\";\n }\n return \"\";\n}\n\nfunction ErrorFallback({\n error,\n componentStack,\n}: {\n error: Error;\n componentStack: string | null;\n}) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n const diagnostics = useMemo(\n () => errorDiagnostics(error, componentStack),\n [componentStack, error],\n );\n\n const copyDetails = async () => {\n if (!navigator.clipboard?.writeText) {\n setCopyState(\"failed\");\n return;\n }\n try {\n await navigator.clipboard.writeText(errorReport(error, componentStack));\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n };\n\n return (\n <main\n data-slot=\"error-wrapper\"\n role=\"alert\"\n aria-labelledby=\"error-wrapper-title\"\n className=\"flex min-h-dvh w-full items-center justify-center bg-background p-density-6 text-foreground\"\n >\n <div className=\"w-full max-w-3xl\">\n <div className=\"mb-density-4 flex items-start gap-density-3\">\n <span className=\"grid size-12 shrink-0 place-items-center rounded-full bg-destructive/10 text-destructive\">\n <Icon icon={UiWarningTriangle} className=\"size-6\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-destructive\">\n Unexpected application error\n </p>\n <h1\n id=\"error-wrapper-title\"\n className=\"mt-density-1 text-2xl font-semibold tracking-tight\"\n >\n Something went wrong\n </h1>\n <p className=\"mt-density-2 break-words text-sm text-muted-foreground\">\n {diagnostics.message}\n </p>\n </div>\n </div>\n\n <div className=\"mb-density-3 flex items-center gap-density-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => void copyDetails()}\n >\n <Icon icon={copyState === \"copied\" ? UiCheck : UiCopy} />\n {copyState === \"copied\" ? \"Copied\" : \"Copy error
|
|
1
|
+
{"version":3,"file":"ErrorWrapper.cjs","sources":["../../src/components/ErrorWrapper.tsx"],"sourcesContent":["import {\n Component,\n useMemo,\n useState,\n type ErrorInfo,\n type ReactNode,\n} from \"react\";\nimport { ErrorDetails } from \"../data/diagnostics/ErrorDetails\";\nimport {\n normalizeErrorDiagnostics,\n type ErrorDiagnostics,\n} from \"../data/diagnostics/error-diagnostics\";\nimport { Icon } from \"../data/Icon\";\nimport { UiCheck, UiCopy, UiWarningTriangle } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\nexport type ErrorWrapperProps = {\n children: ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n};\n\ntype ErrorWrapperState = {\n error: Error | null;\n componentStack: string | null;\n};\n\nexport class ErrorWrapper extends Component<\n ErrorWrapperProps,\n ErrorWrapperState\n> {\n override state: ErrorWrapperState = {\n error: null,\n componentStack: null,\n };\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n override componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n this.setState({ componentStack: errorInfo.componentStack ?? null });\n this.props.onError?.(error, errorInfo);\n }\n\n override render() {\n if (this.state.error) {\n return (\n <ErrorFallback\n error={this.state.error}\n componentStack={this.state.componentStack}\n />\n );\n }\n return this.props.children;\n }\n}\n\ntype CopyState = \"idle\" | \"copied\" | \"failed\";\n\nfunction copyStatusMessage(copyState: CopyState): string {\n if (copyState === \"copied\") return \"Error details copied to clipboard.\";\n if (copyState === \"failed\") {\n return \"Clipboard access failed. Expand the error details to copy individual values.\";\n }\n return \"\";\n}\n\nfunction ErrorFallback({\n error,\n componentStack,\n}: {\n error: Error;\n componentStack: string | null;\n}) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n const diagnostics = useMemo(\n () => errorDiagnostics(error, componentStack),\n [componentStack, error],\n );\n\n const copyDetails = async () => {\n if (!navigator.clipboard?.writeText) {\n setCopyState(\"failed\");\n return;\n }\n try {\n await navigator.clipboard.writeText(errorReport(error, componentStack));\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n };\n\n return (\n <main\n data-slot=\"error-wrapper\"\n role=\"alert\"\n aria-labelledby=\"error-wrapper-title\"\n className=\"flex min-h-dvh w-full items-center justify-center bg-background p-density-6 text-foreground\"\n >\n <div className=\"w-full max-w-3xl\">\n <div className=\"mb-density-4 flex items-start gap-density-3\">\n <span className=\"grid size-12 shrink-0 place-items-center rounded-full bg-destructive/10 text-destructive\">\n <Icon icon={UiWarningTriangle} className=\"size-6\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-destructive\">\n Unexpected application error\n </p>\n <h1\n id=\"error-wrapper-title\"\n className=\"mt-density-1 text-2xl font-semibold tracking-tight\"\n >\n Something went wrong\n </h1>\n <p className=\"mt-density-2 break-words text-sm text-muted-foreground\">\n {diagnostics.message}\n </p>\n </div>\n </div>\n\n <div className=\"mb-density-3 flex items-center gap-density-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => void copyDetails()}\n >\n <Icon icon={copyState === \"copied\" ? UiCheck : UiCopy} />\n {/* Distinct from ErrorDetails' own \"Copy error details\" control\n below: this copies the page-level report (URL, user agent,\n React component stack), and two identically named buttons in\n one view are ambiguous to assistive tech. */}\n {copyState === \"copied\" ? \"Copied\" : \"Copy error report\"}\n </Button>\n <span\n aria-live=\"polite\"\n className={cn(\n \"text-xs\",\n copyState === \"failed\"\n ? \"text-destructive\"\n : \"text-muted-foreground\",\n )}\n >\n {copyStatusMessage(copyState)}\n </span>\n </div>\n\n <ErrorDetails diagnostics={diagnostics} />\n </div>\n </main>\n );\n}\n\nfunction errorDiagnostics(\n error: Error,\n componentStack: string | null,\n): ErrorDiagnostics {\n const diagnostics = normalizeErrorDiagnostics(\n error,\n \"An unexpected error was thrown without a message.\",\n );\n if (!diagnostics) {\n throw new Error(\"ErrorWrapper could not normalize the captured error\");\n }\n\n const cause =\n error.cause === undefined\n ? []\n : [[\"cause\", String(error.cause)] as [string, string]];\n const reactStack = componentStack?.trim();\n return {\n ...diagnostics,\n context: [...diagnostics.context, ...cause],\n ...(reactStack\n ? {\n stacktrace: [\n diagnostics.stacktrace,\n \"React component stack:\",\n reactStack,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n }\n : {}),\n };\n}\n\nfunction errorReport(error: Error, componentStack: string | null) {\n const lines = [\n `Error: ${error.message || \"An unexpected error was thrown without a message.\"}`,\n ];\n if (error.name !== \"Error\") lines.push(`Type: ${error.name}`);\n if (error.cause !== undefined) lines.push(`Cause: ${String(error.cause)}`);\n if (typeof window !== \"undefined\")\n lines.push(`Page: ${window.location.href}`);\n if (typeof navigator !== \"undefined\" && navigator.userAgent) {\n lines.push(`User agent: ${navigator.userAgent}`);\n }\n lines.push(`Time: ${new Date().toISOString()}`);\n if (error.stack) lines.push(\"\", \"Stack trace:\", error.stack);\n if (componentStack?.trim()) {\n lines.push(\"\", \"React component stack:\", componentStack.trim());\n }\n return lines.join(\"\\n\");\n}\n"],"names":["Component","jsx","useState","useMemo","jsxs","Icon","UiWarningTriangle","Button","UiCheck","UiCopy","cn","ErrorDetails","normalizeErrorDiagnostics"],"mappings":"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"}
|
|
@@ -101,7 +101,7 @@ function ErrorFallback({
|
|
|
101
101
|
onClick: () => void copyDetails(),
|
|
102
102
|
children: [
|
|
103
103
|
/* @__PURE__ */ jsx(Icon, { icon: copyState === "copied" ? UiCheck : UiCopy }),
|
|
104
|
-
copyState === "copied" ? "Copied" : "Copy error
|
|
104
|
+
copyState === "copied" ? "Copied" : "Copy error report"
|
|
105
105
|
]
|
|
106
106
|
}
|
|
107
107
|
),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorWrapper.js","sources":["../../src/components/ErrorWrapper.tsx"],"sourcesContent":["import {\n Component,\n useMemo,\n useState,\n type ErrorInfo,\n type ReactNode,\n} from \"react\";\nimport { ErrorDetails } from \"../data/diagnostics/ErrorDetails\";\nimport {\n normalizeErrorDiagnostics,\n type ErrorDiagnostics,\n} from \"../data/diagnostics/error-diagnostics\";\nimport { Icon } from \"../data/Icon\";\nimport { UiCheck, UiCopy, UiWarningTriangle } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\nexport type ErrorWrapperProps = {\n children: ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n};\n\ntype ErrorWrapperState = {\n error: Error | null;\n componentStack: string | null;\n};\n\nexport class ErrorWrapper extends Component<\n ErrorWrapperProps,\n ErrorWrapperState\n> {\n override state: ErrorWrapperState = {\n error: null,\n componentStack: null,\n };\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n override componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n this.setState({ componentStack: errorInfo.componentStack ?? null });\n this.props.onError?.(error, errorInfo);\n }\n\n override render() {\n if (this.state.error) {\n return (\n <ErrorFallback\n error={this.state.error}\n componentStack={this.state.componentStack}\n />\n );\n }\n return this.props.children;\n }\n}\n\ntype CopyState = \"idle\" | \"copied\" | \"failed\";\n\nfunction copyStatusMessage(copyState: CopyState): string {\n if (copyState === \"copied\") return \"Error details copied to clipboard.\";\n if (copyState === \"failed\") {\n return \"Clipboard access failed. Expand the error details to copy individual values.\";\n }\n return \"\";\n}\n\nfunction ErrorFallback({\n error,\n componentStack,\n}: {\n error: Error;\n componentStack: string | null;\n}) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n const diagnostics = useMemo(\n () => errorDiagnostics(error, componentStack),\n [componentStack, error],\n );\n\n const copyDetails = async () => {\n if (!navigator.clipboard?.writeText) {\n setCopyState(\"failed\");\n return;\n }\n try {\n await navigator.clipboard.writeText(errorReport(error, componentStack));\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n };\n\n return (\n <main\n data-slot=\"error-wrapper\"\n role=\"alert\"\n aria-labelledby=\"error-wrapper-title\"\n className=\"flex min-h-dvh w-full items-center justify-center bg-background p-density-6 text-foreground\"\n >\n <div className=\"w-full max-w-3xl\">\n <div className=\"mb-density-4 flex items-start gap-density-3\">\n <span className=\"grid size-12 shrink-0 place-items-center rounded-full bg-destructive/10 text-destructive\">\n <Icon icon={UiWarningTriangle} className=\"size-6\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-destructive\">\n Unexpected application error\n </p>\n <h1\n id=\"error-wrapper-title\"\n className=\"mt-density-1 text-2xl font-semibold tracking-tight\"\n >\n Something went wrong\n </h1>\n <p className=\"mt-density-2 break-words text-sm text-muted-foreground\">\n {diagnostics.message}\n </p>\n </div>\n </div>\n\n <div className=\"mb-density-3 flex items-center gap-density-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => void copyDetails()}\n >\n <Icon icon={copyState === \"copied\" ? UiCheck : UiCopy} />\n {copyState === \"copied\" ? \"Copied\" : \"Copy error
|
|
1
|
+
{"version":3,"file":"ErrorWrapper.js","sources":["../../src/components/ErrorWrapper.tsx"],"sourcesContent":["import {\n Component,\n useMemo,\n useState,\n type ErrorInfo,\n type ReactNode,\n} from \"react\";\nimport { ErrorDetails } from \"../data/diagnostics/ErrorDetails\";\nimport {\n normalizeErrorDiagnostics,\n type ErrorDiagnostics,\n} from \"../data/diagnostics/error-diagnostics\";\nimport { Icon } from \"../data/Icon\";\nimport { UiCheck, UiCopy, UiWarningTriangle } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\nexport type ErrorWrapperProps = {\n children: ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n};\n\ntype ErrorWrapperState = {\n error: Error | null;\n componentStack: string | null;\n};\n\nexport class ErrorWrapper extends Component<\n ErrorWrapperProps,\n ErrorWrapperState\n> {\n override state: ErrorWrapperState = {\n error: null,\n componentStack: null,\n };\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n override componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n this.setState({ componentStack: errorInfo.componentStack ?? null });\n this.props.onError?.(error, errorInfo);\n }\n\n override render() {\n if (this.state.error) {\n return (\n <ErrorFallback\n error={this.state.error}\n componentStack={this.state.componentStack}\n />\n );\n }\n return this.props.children;\n }\n}\n\ntype CopyState = \"idle\" | \"copied\" | \"failed\";\n\nfunction copyStatusMessage(copyState: CopyState): string {\n if (copyState === \"copied\") return \"Error details copied to clipboard.\";\n if (copyState === \"failed\") {\n return \"Clipboard access failed. Expand the error details to copy individual values.\";\n }\n return \"\";\n}\n\nfunction ErrorFallback({\n error,\n componentStack,\n}: {\n error: Error;\n componentStack: string | null;\n}) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n const diagnostics = useMemo(\n () => errorDiagnostics(error, componentStack),\n [componentStack, error],\n );\n\n const copyDetails = async () => {\n if (!navigator.clipboard?.writeText) {\n setCopyState(\"failed\");\n return;\n }\n try {\n await navigator.clipboard.writeText(errorReport(error, componentStack));\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n };\n\n return (\n <main\n data-slot=\"error-wrapper\"\n role=\"alert\"\n aria-labelledby=\"error-wrapper-title\"\n className=\"flex min-h-dvh w-full items-center justify-center bg-background p-density-6 text-foreground\"\n >\n <div className=\"w-full max-w-3xl\">\n <div className=\"mb-density-4 flex items-start gap-density-3\">\n <span className=\"grid size-12 shrink-0 place-items-center rounded-full bg-destructive/10 text-destructive\">\n <Icon icon={UiWarningTriangle} className=\"size-6\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-destructive\">\n Unexpected application error\n </p>\n <h1\n id=\"error-wrapper-title\"\n className=\"mt-density-1 text-2xl font-semibold tracking-tight\"\n >\n Something went wrong\n </h1>\n <p className=\"mt-density-2 break-words text-sm text-muted-foreground\">\n {diagnostics.message}\n </p>\n </div>\n </div>\n\n <div className=\"mb-density-3 flex items-center gap-density-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => void copyDetails()}\n >\n <Icon icon={copyState === \"copied\" ? UiCheck : UiCopy} />\n {/* Distinct from ErrorDetails' own \"Copy error details\" control\n below: this copies the page-level report (URL, user agent,\n React component stack), and two identically named buttons in\n one view are ambiguous to assistive tech. */}\n {copyState === \"copied\" ? \"Copied\" : \"Copy error report\"}\n </Button>\n <span\n aria-live=\"polite\"\n className={cn(\n \"text-xs\",\n copyState === \"failed\"\n ? \"text-destructive\"\n : \"text-muted-foreground\",\n )}\n >\n {copyStatusMessage(copyState)}\n </span>\n </div>\n\n <ErrorDetails diagnostics={diagnostics} />\n </div>\n </main>\n );\n}\n\nfunction errorDiagnostics(\n error: Error,\n componentStack: string | null,\n): ErrorDiagnostics {\n const diagnostics = normalizeErrorDiagnostics(\n error,\n \"An unexpected error was thrown without a message.\",\n );\n if (!diagnostics) {\n throw new Error(\"ErrorWrapper could not normalize the captured error\");\n }\n\n const cause =\n error.cause === undefined\n ? []\n : [[\"cause\", String(error.cause)] as [string, string]];\n const reactStack = componentStack?.trim();\n return {\n ...diagnostics,\n context: [...diagnostics.context, ...cause],\n ...(reactStack\n ? {\n stacktrace: [\n diagnostics.stacktrace,\n \"React component stack:\",\n reactStack,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n }\n : {}),\n };\n}\n\nfunction errorReport(error: Error, componentStack: string | null) {\n const lines = [\n `Error: ${error.message || \"An unexpected error was thrown without a message.\"}`,\n ];\n if (error.name !== \"Error\") lines.push(`Type: ${error.name}`);\n if (error.cause !== undefined) lines.push(`Cause: ${String(error.cause)}`);\n if (typeof window !== \"undefined\")\n lines.push(`Page: ${window.location.href}`);\n if (typeof navigator !== \"undefined\" && navigator.userAgent) {\n lines.push(`User agent: ${navigator.userAgent}`);\n }\n lines.push(`Time: ${new Date().toISOString()}`);\n if (error.stack) lines.push(\"\", \"Stack trace:\", error.stack);\n if (componentStack?.trim()) {\n lines.push(\"\", \"React component stack:\", componentStack.trim());\n }\n return lines.join(\"\\n\");\n}\n"],"names":[],"mappings":"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"}
|