@qoretechnologies/reqraft 0.10.55-pr.124.g43fa138 → 0.10.55
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/.claude/CLAUDE.md +25 -0
- package/.tasks/INDEX.md +1 -0
- package/.tasks/STORY_NETWORK_ISOLATION.md +98 -0
- package/README.md +1 -1
- package/design/FORM_ENGINE_COMPACT.md +34 -0
- package/design/FORM_ENGINE_EXPRESSIONS.md +110 -0
- package/design/FORM_ENGINE_FIELD_MIGRATION.md +155 -1
- package/design/IDE_INTEGRATION.md +13 -0
- package/design/RENDER_EXPRESSION_TRANSPORT.md +76 -10
- package/design/SELECT_DIALOG_FLOOR.md +86 -0
- package/design/SMART_EDITOR_UX.md +21 -0
- package/design/UNAVAILABLE_ALLOWED_VALUES.md +226 -0
- package/dist/components/composer/Composer.d.ts +8 -3
- package/dist/components/composer/Composer.d.ts.map +1 -1
- package/dist/components/composer/Composer.js.map +1 -1
- package/dist/components/dpqlEditor/DpqlEditor.d.ts.map +1 -1
- package/dist/components/dpqlEditor/DpqlEditor.js +3 -3
- package/dist/components/dpqlEditor/DpqlEditor.js.map +1 -1
- package/dist/components/dpqlEditor/dpqlHelpers.d.ts +6 -0
- package/dist/components/dpqlEditor/dpqlHelpers.d.ts.map +1 -1
- package/dist/components/dpqlEditor/dpqlHelpers.js +21 -2
- package/dist/components/dpqlEditor/dpqlHelpers.js.map +1 -1
- package/dist/components/dpqlEditor/dpqlProbe.d.ts +37 -0
- package/dist/components/dpqlEditor/dpqlProbe.d.ts.map +1 -0
- package/dist/components/dpqlEditor/dpqlProbe.js +203 -0
- package/dist/components/dpqlEditor/dpqlProbe.js.map +1 -0
- package/dist/components/dpqlEditor/dpqlTags.d.ts +8 -0
- package/dist/components/dpqlEditor/dpqlTags.d.ts.map +1 -1
- package/dist/components/dpqlEditor/dpqlTags.js +5 -1
- package/dist/components/dpqlEditor/dpqlTags.js.map +1 -1
- package/dist/components/dpqlEditor/index.d.ts +4 -0
- package/dist/components/dpqlEditor/index.d.ts.map +1 -1
- package/dist/components/dpqlEditor/index.js +5 -1
- package/dist/components/dpqlEditor/index.js.map +1 -1
- package/dist/components/dpqlEditor/types.d.ts +42 -2
- package/dist/components/dpqlEditor/types.d.ts.map +1 -1
- package/dist/components/dpqlEditor/types.js +0 -4
- package/dist/components/dpqlEditor/types.js.map +1 -1
- package/dist/components/dpqlEditor/useDpqlProbe.d.ts +4 -0
- package/dist/components/dpqlEditor/useDpqlProbe.d.ts.map +1 -0
- package/dist/components/dpqlEditor/useDpqlProbe.js +29 -0
- package/dist/components/dpqlEditor/useDpqlProbe.js.map +1 -0
- package/dist/components/dpqlEditor/useDpqlSession.d.ts +5 -2
- package/dist/components/dpqlEditor/useDpqlSession.d.ts.map +1 -1
- package/dist/components/dpqlEditor/useDpqlSession.js +8 -2
- package/dist/components/dpqlEditor/useDpqlSession.js.map +1 -1
- package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
- package/dist/components/form/engine/CompactRow.js +414 -128
- package/dist/components/form/engine/CompactRow.js.map +1 -1
- package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
- package/dist/components/form/engine/CompactToolbar.js +5 -2
- package/dist/components/form/engine/CompactToolbar.js.map +1 -1
- package/dist/components/form/engine/FormEngine.d.ts +273 -22
- package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
- package/dist/components/form/engine/FormEngine.js +669 -192
- package/dist/components/form/engine/FormEngine.js.map +1 -1
- package/dist/components/form/engine/FormFieldsSkeleton.d.ts +48 -0
- package/dist/components/form/engine/FormFieldsSkeleton.d.ts.map +1 -0
- package/dist/components/form/engine/FormFieldsSkeleton.js +41 -0
- package/dist/components/form/engine/FormFieldsSkeleton.js.map +1 -0
- package/dist/components/form/engine/OptionFieldMessages.d.ts +108 -2
- package/dist/components/form/engine/OptionFieldMessages.d.ts.map +1 -1
- package/dist/components/form/engine/OptionFieldMessages.js +203 -13
- package/dist/components/form/engine/OptionFieldMessages.js.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.js +68 -5
- package/dist/components/form/engine/_structuredData/SchemaDataView.js.map +1 -1
- package/dist/components/form/engine/compactRowContext.d.ts +15 -1
- package/dist/components/form/engine/compactRowContext.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowContext.js.map +1 -1
- package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowStyles.js +55 -29
- package/dist/components/form/engine/compactRowStyles.js.map +1 -1
- package/dist/components/form/engine/compactToolbarContext.d.ts +1 -0
- package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
- package/dist/components/form/engine/optionActions.d.ts +37 -1
- package/dist/components/form/engine/optionActions.d.ts.map +1 -1
- package/dist/components/form/engine/optionActions.js +71 -1
- package/dist/components/form/engine/optionActions.js.map +1 -1
- package/dist/components/form/engine/optionsContext.d.ts +22 -0
- package/dist/components/form/engine/optionsContext.d.ts.map +1 -0
- package/dist/components/form/engine/optionsContext.js +20 -0
- package/dist/components/form/engine/optionsContext.js.map +1 -0
- package/dist/components/form/engine/readFirst.d.ts +42 -1
- package/dist/components/form/engine/readFirst.d.ts.map +1 -1
- package/dist/components/form/engine/readFirst.js +76 -8
- package/dist/components/form/engine/readFirst.js.map +1 -1
- package/dist/components/form/engine/rendererTypes.d.ts +42 -3
- package/dist/components/form/engine/rendererTypes.d.ts.map +1 -1
- package/dist/components/form/engine/rendererTypes.js +3 -1
- package/dist/components/form/engine/rendererTypes.js.map +1 -1
- package/dist/components/form/engine/rowFocus.d.ts +30 -0
- package/dist/components/form/engine/rowFocus.d.ts.map +1 -0
- package/dist/components/form/engine/rowFocus.js +93 -0
- package/dist/components/form/engine/rowFocus.js.map +1 -0
- package/dist/components/form/engine/rowMenuContext.d.ts +78 -0
- package/dist/components/form/engine/rowMenuContext.d.ts.map +1 -0
- package/dist/components/form/engine/rowMenuContext.js +103 -0
- package/dist/components/form/engine/rowMenuContext.js.map +1 -0
- package/dist/components/form/engine/rowOpenPicker.d.ts +27 -0
- package/dist/components/form/engine/rowOpenPicker.d.ts.map +1 -0
- package/dist/components/form/engine/rowOpenPicker.js +30 -0
- package/dist/components/form/engine/rowOpenPicker.js.map +1 -0
- package/dist/components/form/engine/typeChoices.d.ts +42 -0
- package/dist/components/form/engine/typeChoices.d.ts.map +1 -0
- package/dist/components/form/engine/typeChoices.js +33 -0
- package/dist/components/form/engine/typeChoices.js.map +1 -0
- package/dist/components/form/expressions/DpqlRendering.d.ts +26 -0
- package/dist/components/form/expressions/DpqlRendering.d.ts.map +1 -0
- package/dist/components/form/expressions/DpqlRendering.js +53 -0
- package/dist/components/form/expressions/DpqlRendering.js.map +1 -0
- package/dist/components/form/expressions/ExpressionField.d.ts +7 -1
- package/dist/components/form/expressions/ExpressionField.d.ts.map +1 -1
- package/dist/components/form/expressions/ExpressionField.js +203 -45
- package/dist/components/form/expressions/ExpressionField.js.map +1 -1
- package/dist/components/form/expressions/argumentPresence.d.ts +84 -0
- package/dist/components/form/expressions/argumentPresence.d.ts.map +1 -0
- package/dist/components/form/expressions/argumentPresence.js +217 -0
- package/dist/components/form/expressions/argumentPresence.js.map +1 -0
- package/dist/components/form/expressions/builder/argumentLabel.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/argumentLabel.js +9 -4
- package/dist/components/form/expressions/builder/argumentLabel.js.map +1 -1
- package/dist/components/form/expressions/builder/index.d.ts +15 -2
- package/dist/components/form/expressions/builder/index.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/index.js +21 -65
- package/dist/components/form/expressions/builder/index.js.map +1 -1
- package/dist/components/form/expressions/builder/renderTemplate.d.ts +4 -1
- package/dist/components/form/expressions/builder/renderTemplate.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/renderTemplate.js +10 -67
- package/dist/components/form/expressions/builder/renderTemplate.js.map +1 -1
- package/dist/components/form/expressions/mockExpressions.d.ts.map +1 -1
- package/dist/components/form/expressions/mockExpressions.js +8 -4
- package/dist/components/form/expressions/mockExpressions.js.map +1 -1
- package/dist/components/form/expressions/renderExpressionToText.d.ts +1 -1
- package/dist/components/form/expressions/renderExpressionToText.d.ts.map +1 -1
- package/dist/components/form/expressions/renderExpressionToText.js +95 -19
- package/dist/components/form/expressions/renderExpressionToText.js.map +1 -1
- package/dist/components/form/expressions/types.d.ts +17 -2
- package/dist/components/form/expressions/types.d.ts.map +1 -1
- package/dist/components/form/expressions/useExpressions.d.ts.map +1 -1
- package/dist/components/form/expressions/useExpressions.js +5 -2
- package/dist/components/form/expressions/useExpressions.js.map +1 -1
- package/dist/components/form/expressions/useRenderExpression.d.ts +7 -16
- package/dist/components/form/expressions/useRenderExpression.d.ts.map +1 -1
- package/dist/components/form/expressions/useRenderExpression.js +50 -126
- package/dist/components/form/expressions/useRenderExpression.js.map +1 -1
- package/dist/components/form/fields/Field.d.ts +21 -0
- package/dist/components/form/fields/Field.d.ts.map +1 -1
- package/dist/components/form/fields/Field.js +54 -8
- package/dist/components/form/fields/Field.js.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.d.ts +11 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.js +52 -8
- package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.d.ts +7 -1
- package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.js +91 -28
- package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
- package/dist/components/form/fields/date/Date.d.ts +1 -1
- package/dist/components/form/fields/date/Date.d.ts.map +1 -1
- package/dist/components/form/fields/date/Date.js +16 -2
- package/dist/components/form/fields/date/Date.js.map +1 -1
- package/dist/components/form/fields/long-string/LongString.d.ts.map +1 -1
- package/dist/components/form/fields/long-string/LongString.js +14 -2
- package/dist/components/form/fields/long-string/LongString.js.map +1 -1
- package/dist/components/form/fields/multi-select/MultiSelectFormField.d.ts.map +1 -1
- package/dist/components/form/fields/multi-select/MultiSelectFormField.js +50 -4
- package/dist/components/form/fields/multi-select/MultiSelectFormField.js.map +1 -1
- package/dist/components/form/fields/number/Number.d.ts +12 -1
- package/dist/components/form/fields/number/Number.d.ts.map +1 -1
- package/dist/components/form/fields/number/Number.js +6 -3
- package/dist/components/form/fields/number/Number.js.map +1 -1
- package/dist/components/form/fields/rich-text/RichText.d.ts +47 -2
- package/dist/components/form/fields/rich-text/RichText.d.ts.map +1 -1
- package/dist/components/form/fields/rich-text/RichText.js +153 -12
- package/dist/components/form/fields/rich-text/RichText.js.map +1 -1
- package/dist/components/form/fields/select/Select.d.ts.map +1 -1
- package/dist/components/form/fields/select/Select.js +120 -20
- package/dist/components/form/fields/select/Select.js.map +1 -1
- package/dist/components/form/fields/select/SelectCollection.d.ts +166 -9
- package/dist/components/form/fields/select/SelectCollection.d.ts.map +1 -1
- package/dist/components/form/fields/select/SelectCollection.js +200 -7
- package/dist/components/form/fields/select/SelectCollection.js.map +1 -1
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts +2 -1
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts.map +1 -1
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.js +3 -2
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.js.map +1 -1
- package/dist/components/form/fields/template/TemplateField.d.ts +34 -2
- package/dist/components/form/fields/template/TemplateField.d.ts.map +1 -1
- package/dist/components/form/fields/template/TemplateField.js +606 -58
- package/dist/components/form/fields/template/TemplateField.js.map +1 -1
- package/dist/components/form/fields/template/TemplateText.d.ts +36 -0
- package/dist/components/form/fields/template/TemplateText.d.ts.map +1 -0
- package/dist/components/form/fields/template/TemplateText.js +80 -0
- package/dist/components/form/fields/template/TemplateText.js.map +1 -0
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/index.js +4 -0
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/smartEditor/SmartEditor.d.ts.map +1 -1
- package/dist/components/smartEditor/SmartEditor.js +29 -8
- package/dist/components/smartEditor/SmartEditor.js.map +1 -1
- package/dist/components/smartEditor/useLspSession.d.ts +5 -1
- package/dist/components/smartEditor/useLspSession.d.ts.map +1 -1
- package/dist/components/smartEditor/useLspSession.js +16 -2
- package/dist/components/smartEditor/useLspSession.js.map +1 -1
- package/dist/components/supportTicket/TicketReplyBox.d.ts +8 -4
- package/dist/components/supportTicket/TicketReplyBox.d.ts.map +1 -1
- package/dist/components/supportTicket/TicketReplyBox.js.map +1 -1
- package/dist/helpers/common.d.ts.map +1 -1
- package/dist/helpers/common.js +7 -3
- package/dist/helpers/common.js.map +1 -1
- package/dist/helpers/dpqlDetection.d.ts +58 -0
- package/dist/helpers/dpqlDetection.d.ts.map +1 -0
- package/dist/helpers/dpqlDetection.js +164 -0
- package/dist/helpers/dpqlDetection.js.map +1 -0
- package/dist/helpers/optionUiTypes.d.ts +31 -3
- package/dist/helpers/optionUiTypes.d.ts.map +1 -1
- package/dist/helpers/optionUiTypes.js +36 -1
- package/dist/helpers/optionUiTypes.js.map +1 -1
- package/dist/helpers/options.d.ts +57 -0
- package/dist/helpers/options.d.ts.map +1 -1
- package/dist/helpers/options.js +97 -1
- package/dist/helpers/options.js.map +1 -1
- package/dist/helpers/templateItems.d.ts +47 -0
- package/dist/helpers/templateItems.d.ts.map +1 -0
- package/dist/helpers/templateItems.js +88 -0
- package/dist/helpers/templateItems.js.map +1 -0
- package/dist/helpers/templateText.d.ts +80 -0
- package/dist/helpers/templateText.d.ts.map +1 -0
- package/dist/helpers/templateText.js +291 -0
- package/dist/helpers/templateText.js.map +1 -0
- package/dist/helpers/templates.d.ts +30 -12
- package/dist/helpers/templates.d.ts.map +1 -1
- package/dist/helpers/templates.js +91 -33
- package/dist/helpers/templates.js.map +1 -1
- package/dist/helpers/validations.d.ts +35 -8
- package/dist/helpers/validations.d.ts.map +1 -1
- package/dist/helpers/validations.js +162 -25
- package/dist/helpers/validations.js.map +1 -1
- package/dist/hooks/useArgSchema.d.ts +2 -1
- package/dist/hooks/useArgSchema.d.ts.map +1 -1
- package/dist/hooks/useFetch/useFetch.d.ts +3 -1
- package/dist/hooks/useFetch/useFetch.d.ts.map +1 -1
- package/dist/hooks/useFetch/useFetch.js +47 -9
- package/dist/hooks/useFetch/useFetch.js.map +1 -1
- package/dist/hooks/useTemplates.d.ts +20 -0
- package/dist/hooks/useTemplates.d.ts.map +1 -1
- package/dist/hooks/useTemplates.js +34 -2
- package/dist/hooks/useTemplates.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/fetch.d.ts +151 -1
- package/dist/utils/fetch.d.ts.map +1 -1
- package/dist/utils/fetch.js +256 -44
- package/dist/utils/fetch.js.map +1 -1
- package/dist/utils/lspClient.d.ts +6 -0
- package/dist/utils/lspClient.d.ts.map +1 -1
- package/dist/utils/lspClient.js +62 -11
- package/dist/utils/lspClient.js.map +1 -1
- package/dist/utils/websocket.d.ts +6 -0
- package/dist/utils/websocket.d.ts.map +1 -1
- package/dist/utils/websocket.js +15 -7
- package/dist/utils/websocket.js.map +1 -1
- package/package.json +10 -6
- package/src/components/composer/Composer.tsx +7 -2
- package/src/components/dpqlEditor/DpqlEditor.stories.tsx +3 -119
- package/src/components/dpqlEditor/DpqlEditor.tsx +5 -2
- package/src/components/dpqlEditor/dpqlHelpers.ts +20 -1
- package/src/components/dpqlEditor/dpqlProbe.ts +165 -0
- package/src/components/dpqlEditor/dpqlTags.ts +13 -0
- package/src/components/dpqlEditor/index.ts +4 -0
- package/src/components/dpqlEditor/types.ts +38 -2
- package/src/components/dpqlEditor/useDpqlProbe.ts +33 -0
- package/src/components/dpqlEditor/useDpqlSession.ts +20 -4
- package/src/components/form/engine/CompactRow.tsx +487 -160
- package/src/components/form/engine/CompactToolbar.tsx +10 -3
- package/src/components/form/engine/FormEngine.stories.tsx +1269 -201
- package/src/components/form/engine/FormEngine.tsx +922 -270
- package/src/components/form/engine/FormEngineStickyHeaders.stories.tsx +331 -0
- package/src/components/form/engine/FormFieldsSkeleton.tsx +77 -0
- package/src/components/form/engine/OptionFieldMessages.tsx +300 -14
- package/src/components/form/engine/_structuredData/SchemaDataView.tsx +94 -3
- package/src/components/form/engine/compactRowContext.ts +15 -6
- package/src/components/form/engine/compactRowStyles.ts +56 -2
- package/src/components/form/engine/compactToolbarContext.ts +1 -1
- package/src/components/form/engine/optionActions.ts +89 -1
- package/src/components/form/engine/optionsContext.ts +24 -0
- package/src/components/form/engine/readFirst.ts +88 -8
- package/src/components/form/engine/rendererTypes.ts +48 -4
- package/src/components/form/engine/rowFocus.ts +101 -0
- package/src/components/form/engine/rowMenuContext.ts +159 -0
- package/src/components/form/engine/rowOpenPicker.ts +27 -0
- package/src/components/form/engine/typeChoices.ts +63 -0
- package/src/components/form/expressions/DpqlRendering.tsx +85 -0
- package/src/components/form/expressions/ExpressionField.stories.tsx +826 -48
- package/src/components/form/expressions/ExpressionField.tsx +269 -55
- package/src/components/form/expressions/argumentPresence.ts +213 -0
- package/src/components/form/expressions/builder/ExpressionBuilder.stories.tsx +38 -21
- package/src/components/form/expressions/builder/argumentLabel.tsx +10 -4
- package/src/components/form/expressions/builder/index.tsx +39 -81
- package/src/components/form/expressions/builder/renderTemplate.tsx +23 -56
- package/src/components/form/expressions/dpqlMockLanguage.ts +565 -0
- package/src/components/form/expressions/dpqlMockLsp.ts +109 -83
- package/src/components/form/expressions/mockExpressions.ts +8 -4
- package/src/components/form/expressions/renderExpressionToText.ts +112 -22
- package/src/components/form/expressions/types.ts +17 -2
- package/src/components/form/expressions/useExpressions.ts +5 -1
- package/src/components/form/expressions/useRenderExpression.ts +43 -127
- package/src/components/form/fields/Field.tsx +102 -20
- package/src/components/form/fields/allowed-values/AllowedValues.tsx +106 -44
- package/src/components/form/fields/auto/AutoFormField.stories.tsx +85 -18
- package/src/components/form/fields/auto/AutoFormField.tsx +97 -21
- package/src/components/form/fields/date/Date.tsx +17 -1
- package/src/components/form/fields/long-string/LongString.tsx +15 -3
- package/src/components/form/fields/multi-select/MultiSelectFormField.tsx +65 -6
- package/src/components/form/fields/number/Number.tsx +25 -0
- package/src/components/form/fields/rich-text/RichText.tsx +248 -30
- package/src/components/form/fields/select/Select.stories.tsx +392 -0
- package/src/components/form/fields/select/Select.tsx +164 -27
- package/src/components/form/fields/select/SelectCollection.tsx +350 -6
- package/src/components/form/fields/template/ReadOnlyTemplateTag.tsx +4 -2
- package/src/components/form/fields/template/TemplateField.stories.tsx +93 -14
- package/src/components/form/fields/template/TemplateField.tsx +825 -131
- package/src/components/form/fields/template/TemplateText.tsx +115 -0
- package/src/components/form/index.tsx +4 -0
- package/src/components/log/Log.stories.tsx +2 -1
- package/src/components/searchFilterBar/SearchFilterBar.stories.tsx +3 -3
- package/src/components/smartEditor/SmartEditor.tsx +41 -9
- package/src/components/smartEditor/__fixtures__/mockLspServer.ts +52 -3
- package/src/components/smartEditor/useLspSession.ts +21 -3
- package/src/components/supportTicket/TicketReplyBox.tsx +8 -4
- package/src/components/ticketThread/TicketThread.stories.tsx +1 -0
- package/src/helpers/common.ts +7 -3
- package/src/helpers/dpqlDetection.ts +209 -0
- package/src/helpers/optionUiTypes.ts +38 -0
- package/src/helpers/options.ts +96 -0
- package/src/helpers/templateItems.ts +81 -0
- package/src/helpers/templateText.ts +350 -0
- package/src/helpers/templates.ts +94 -41
- package/src/helpers/validations.ts +203 -51
- package/src/hooks/useFetch/useFetch.stories.tsx +6 -5
- package/src/hooks/useFetch/useFetch.tsx +53 -7
- package/src/hooks/useStorage/useStorage.stories.tsx +2 -1
- package/src/hooks/useTemplates.ts +41 -0
- package/src/hooks/useWebSocket/useWebsocket.stories.tsx +2 -1
- package/src/index.tsx +14 -1
- package/src/stores/currentUser/currentUser.stories.tsx +2 -1
- package/src/stories/storyNetwork.ts +92 -0
- package/src/utils/fetch.ts +311 -21
- package/src/utils/lspClient.ts +68 -11
- package/src/utils/websocket.ts +20 -9
- package/dist/components/form/engine/__fixtures__/basicFormOptions.d.ts +0 -73
- package/dist/components/form/engine/__fixtures__/basicFormOptions.d.ts.map +0 -1
- package/dist/components/form/engine/__fixtures__/basicFormOptions.js +0 -317
- package/dist/components/form/engine/__fixtures__/basicFormOptions.js.map +0 -1
- package/dist/components/form/engine/__fixtures__/fieldChromeOptions.d.ts +0 -41
- package/dist/components/form/engine/__fixtures__/fieldChromeOptions.d.ts.map +0 -1
- package/dist/components/form/engine/__fixtures__/fieldChromeOptions.js +0 -45
- package/dist/components/form/engine/__fixtures__/fieldChromeOptions.js.map +0 -1
- package/dist/components/form/expressions/dpqlMockLsp.d.ts +0 -3
- package/dist/components/form/expressions/dpqlMockLsp.d.ts.map +0 -1
- package/dist/components/form/expressions/dpqlMockLsp.js +0 -91
- package/dist/components/form/expressions/dpqlMockLsp.js.map +0 -1
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.d.ts +0 -2
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.d.ts.map +0 -1
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.js +0 -9
- package/dist/components/form/fields/template/__fixtures__/longExampleValue.js.map +0 -1
- package/dist/components/smartEditor/__fixtures__/mockLspServer.d.ts +0 -55
- package/dist/components/smartEditor/__fixtures__/mockLspServer.d.ts.map +0 -1
- package/dist/components/smartEditor/__fixtures__/mockLspServer.js +0 -126
- package/dist/components/smartEditor/__fixtures__/mockLspServer.js.map +0 -1
- package/dist/stories/Data/fileFieldArgSchema.json +0 -86
|
@@ -4,15 +4,115 @@ import {
|
|
|
4
4
|
ReqoreControlGroup,
|
|
5
5
|
ReqoreMessage,
|
|
6
6
|
ReqoreModal,
|
|
7
|
+
ReqoreTag,
|
|
7
8
|
} from '@qoretechnologies/reqore';
|
|
8
9
|
import { IReqoreCollectionItemProps } from '@qoretechnologies/reqore/dist/components/Collection/item';
|
|
9
10
|
import { TReqoreBadge } from '@qoretechnologies/reqore/dist/components/Button';
|
|
11
|
+
import { IReqorePanelAction } from '@qoretechnologies/reqore/dist/components/Panel';
|
|
10
12
|
import { TReqoreIntent } from '@qoretechnologies/reqore/dist/constants/theme';
|
|
13
|
+
import { IReqoreTooltip } from '@qoretechnologies/reqore/dist/types/global';
|
|
11
14
|
import { IReqoreIconName } from '@qoretechnologies/reqore/dist/types/icons';
|
|
12
15
|
import { capitalize, isEqual, size } from 'lodash';
|
|
13
16
|
import { useMemo, useState } from 'react';
|
|
17
|
+
import styled from 'styled-components';
|
|
18
|
+
import {
|
|
19
|
+
UNAVAILABLE_VALUE_FALLBACK_REASON,
|
|
20
|
+
getRefusalMessage,
|
|
21
|
+
} from '../../../../helpers/options';
|
|
14
22
|
import { Description } from '../../../Description';
|
|
15
23
|
|
|
24
|
+
/**
|
|
25
|
+
* The size the picker cannot be dragged below, measured on its own content.
|
|
26
|
+
*
|
|
27
|
+
* reqore floors a modal at what the DRAWER's chrome needs — its title and its
|
|
28
|
+
* close control — which is all reqore can answer for. The picker needs more
|
|
29
|
+
* than that, and said so the hard way: dragged to roughly 45px wide it still
|
|
30
|
+
* held a search box, a list and a close button, stacked in a column nobody
|
|
31
|
+
* could read.
|
|
32
|
+
*
|
|
33
|
+
* Measured on `components-form-select--item-actions-in-the-title-bar` at
|
|
34
|
+
* 1400x1000, sweeping the width and the height of the dialog box:
|
|
35
|
+
*
|
|
36
|
+
* - **320px wide.** The collection is laid out in 300px columns
|
|
37
|
+
* (`minColumnWidth`), so a row is 300px wide whatever the dialog does. At
|
|
38
|
+
* 300px the row overhangs the dialog by 13px and at 310px by 3px; 320px is
|
|
39
|
+
* the first round width that contains it (-7px), and from 340px the row
|
|
40
|
+
* grows with the box instead of overhanging it.
|
|
41
|
+
* - **180px tall.** The panel header is 55px and the search field 26px, and
|
|
42
|
+
* both are whole from 100px — but the list below them has to show one entry
|
|
43
|
+
* in full, or there is nothing choosable in the dialog. A plain row is 56px
|
|
44
|
+
* and is whole from 160px; a row carrying a description is 70px and needs
|
|
45
|
+
* 174px. The floor takes the taller of the two, because the same dialog
|
|
46
|
+
* serves both and a floor that clips the rows it is actually used with is
|
|
47
|
+
* the defect this constant exists to prevent — the assertion-kind picker in
|
|
48
|
+
* qorus-ide is the described-row case. 180px is the first round height that
|
|
49
|
+
* contains it.
|
|
50
|
+
*/
|
|
51
|
+
export const SELECT_DIALOG_MIN_WIDTH = 320;
|
|
52
|
+
/** See {@link SELECT_DIALOG_MIN_WIDTH}. */
|
|
53
|
+
export const SELECT_DIALOG_MIN_HEIGHT = 180;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The hook a row wears while its value cannot be picked — for the stylesheet
|
|
57
|
+
* below, and for a host's own tests and styling.
|
|
58
|
+
*/
|
|
59
|
+
export const UNAVAILABLE_ITEM_CLASS = 'reqraft-select-item-unavailable';
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The picker's floor, expressed where it survives the reqore we pin.
|
|
63
|
+
*
|
|
64
|
+
* `className` reaches the element `re-resizable` sizes and drags, and a CSS
|
|
65
|
+
* `min-width` clamps THAT element's rendered box however far the drag goes —
|
|
66
|
+
* so this holds against reqore 0.74.1, where a modal's floor is a hardcoded
|
|
67
|
+
* 40px and `minSize` never reaches it, as well as against the `minWidth` /
|
|
68
|
+
* `minHeight` props reqore grew later.
|
|
69
|
+
*
|
|
70
|
+
* `!important` is load-bearing, not decoration: `re-resizable` writes its own
|
|
71
|
+
* `min-width` / `min-height` INLINE on this same element, and an inline
|
|
72
|
+
* declaration beats a normal one from a stylesheet.
|
|
73
|
+
*
|
|
74
|
+
* Clamping the box from outside `re-resizable` rather than through it costs
|
|
75
|
+
* one thing, and it is not the thing it looks like. The drag stays exact: each
|
|
76
|
+
* move sizes the box from where the drag STARTED plus the pointer's delta, not
|
|
77
|
+
* from the last size, so coming back out tracks the pointer with no dead zone
|
|
78
|
+
* (measured — past the floor the box holds 320px while the inline width reads
|
|
79
|
+
* 40px, and 300px back out it is 400px again). What is left behind is that
|
|
80
|
+
* divergence: an inline width smaller than the box anyone can see. Read this
|
|
81
|
+
* dialog's size from its rect, never from `style.width`. Once reqraft can pin
|
|
82
|
+
* a reqore that has them this becomes `minWidth` / `minHeight` on the modal,
|
|
83
|
+
* and the two agree again.
|
|
84
|
+
*
|
|
85
|
+
* Capped at the viewport so a phone gets a dialog it can see all of rather
|
|
86
|
+
* than a floor wider than its screen — reqore's own maximum is 90vw / 90vh.
|
|
87
|
+
*/
|
|
88
|
+
const StyledSelectDialog = styled(ReqoreModal)`
|
|
89
|
+
min-width: min(${SELECT_DIALOG_MIN_WIDTH}px, 90vw) !important;
|
|
90
|
+
min-height: min(${SELECT_DIALOG_MIN_HEIGHT}px, 90vh) !important;
|
|
91
|
+
|
|
92
|
+
/*
|
|
93
|
+
* A value that cannot be picked, said in the row's own stylesheet.
|
|
94
|
+
*
|
|
95
|
+
* Reqore's "disabled" is NOT what marks it. That applies DisabledElement,
|
|
96
|
+
* which is "pointer-events: none" — and the two places the reason can be
|
|
97
|
+
* read, the row's tooltip and whatever control its title bar carries, both
|
|
98
|
+
* need the pointer. Dropping onClick is what actually makes the row inert:
|
|
99
|
+
* reqore derives "interactive" from the handlers a panel was given, so a row
|
|
100
|
+
* with none gets no pointer cursor and no hover lift while keeping every
|
|
101
|
+
* pointer event it had.
|
|
102
|
+
*
|
|
103
|
+
* The dimming lands on the TITLE rather than on the row, because "opacity"
|
|
104
|
+
* creates a stacking context: dimming the row would dim the reason inside it,
|
|
105
|
+
* and the reason is the one thing on an unavailable row that has to read.
|
|
106
|
+
*/
|
|
107
|
+
.${UNAVAILABLE_ITEM_CLASS} {
|
|
108
|
+
cursor: not-allowed;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.${UNAVAILABLE_ITEM_CLASS} > .reqore-panel-title {
|
|
112
|
+
opacity: 0.55;
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
|
|
16
116
|
const PositiveColorEffect = {
|
|
17
117
|
gradient: {
|
|
18
118
|
colors: {
|
|
@@ -22,6 +122,48 @@ const PositiveColorEffect = {
|
|
|
22
122
|
},
|
|
23
123
|
};
|
|
24
124
|
|
|
125
|
+
/**
|
|
126
|
+
* One affordance on an offered item, as a DESCRIPTOR rather than a node.
|
|
127
|
+
*
|
|
128
|
+
* A caller's items routinely travel through a `JSON.stringify(items)` memo key
|
|
129
|
+
* (`FieldAllowedValues`, `MultiSelectFormField`), and a rendered React element
|
|
130
|
+
* is circular through its fibre — putting one on an item throws and takes the
|
|
131
|
+
* whole form down with it. So an item names the component and hands it props;
|
|
132
|
+
* `as` is a function or a memo object, which `JSON.stringify` simply omits.
|
|
133
|
+
*/
|
|
134
|
+
export interface ISelectFieldCollectionItemAction {
|
|
135
|
+
/** The component to render. Defaults to {@link ReqoreButton}. */
|
|
136
|
+
as?: React.ElementType;
|
|
137
|
+
/** Props handed to it. Keep them JSON-serialisable. */
|
|
138
|
+
props?: Record<string, unknown>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Content for a tooltip an item puts on its own row, under the same
|
|
143
|
+
* no-React-elements rule as {@link ISelectFieldCollectionItemAction}: a plain
|
|
144
|
+
* string, or a component named by `as` and given plain props.
|
|
145
|
+
*/
|
|
146
|
+
export type TSelectFieldCollectionItemTooltipContent =
|
|
147
|
+
| string
|
|
148
|
+
| { as: React.ElementType; props?: Record<string, unknown> };
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* A per-item tooltip: a bare string, or reqore's tooltip options with the
|
|
152
|
+
* content given as a descriptor.
|
|
153
|
+
*/
|
|
154
|
+
export type TSelectFieldCollectionItemTooltip =
|
|
155
|
+
| string
|
|
156
|
+
| (Omit<IReqoreTooltip, 'content'> & {
|
|
157
|
+
content?: TSelectFieldCollectionItemTooltipContent;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
/** A note rendered in an item's body, in the same shape a schema sends one. */
|
|
161
|
+
export interface ISelectFieldCollectionItemMessage {
|
|
162
|
+
intent?: TReqoreIntent;
|
|
163
|
+
title?: string;
|
|
164
|
+
content: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
25
167
|
export interface ISelectFieldCollectionItem {
|
|
26
168
|
value?: unknown;
|
|
27
169
|
name?: unknown;
|
|
@@ -34,8 +176,54 @@ export interface ISelectFieldCollectionItem {
|
|
|
34
176
|
intent?: TReqoreIntent;
|
|
35
177
|
disabled?: boolean;
|
|
36
178
|
groups?: string[];
|
|
37
|
-
|
|
38
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Affordances rendered in the row's BODY, stacked under the description.
|
|
181
|
+
* Each one costs the row a line of its own, which is right for something
|
|
182
|
+
* with a label and wrong for a single icon on a long list — see
|
|
183
|
+
* `title_actions`.
|
|
184
|
+
*/
|
|
185
|
+
actions?: ISelectFieldCollectionItemAction[];
|
|
186
|
+
/**
|
|
187
|
+
* Affordances rendered in the row's TITLE BAR, inline with the name and to
|
|
188
|
+
* the right of it, where a row already reserves the height.
|
|
189
|
+
*
|
|
190
|
+
* Separate from `actions` rather than a relocation of it: an item's body
|
|
191
|
+
* actions have been rendered under the description since this collection
|
|
192
|
+
* existed, and callers size and lay them out on that basis. This is the
|
|
193
|
+
* opt-in for the other placement.
|
|
194
|
+
*/
|
|
195
|
+
title_actions?: ISelectFieldCollectionItemAction[];
|
|
196
|
+
/**
|
|
197
|
+
* A tooltip on the ROW — the whole item is the hover target, not one control
|
|
198
|
+
* inside it. Content that is more than a sentence belongs here rather than
|
|
199
|
+
* in `content`, which every row pays for in height whether it is read or not.
|
|
200
|
+
*/
|
|
201
|
+
tooltip?: TSelectFieldCollectionItemTooltip;
|
|
202
|
+
messages?: ISelectFieldCollectionItemMessage[];
|
|
203
|
+
/**
|
|
204
|
+
* Why the value cannot be picked, when it cannot.
|
|
205
|
+
*
|
|
206
|
+
* Rendered FIRST in the row — above the description, not under it, where a
|
|
207
|
+
* `messages` entry would land. A reader who has just been refused a choice is
|
|
208
|
+
* looking for the reason, and a row that answers with its description and
|
|
209
|
+
* makes them read on has answered a different question.
|
|
210
|
+
*
|
|
211
|
+
* Set it together with `disabled`, which is what drops the click handler.
|
|
212
|
+
* Carried as data rather than as a node for the reason in
|
|
213
|
+
* {@link ISelectFieldCollectionItemAction}.
|
|
214
|
+
*/
|
|
215
|
+
unavailable?: ISelectFieldCollectionItemMessage;
|
|
216
|
+
/** Added to the row's own classes — see {@link UNAVAILABLE_ITEM_CLASS}. */
|
|
217
|
+
className?: string;
|
|
218
|
+
/**
|
|
219
|
+
* Extra words the list's search matches this row on.
|
|
220
|
+
*
|
|
221
|
+
* Reqore searches a row's label and the STRING of its content, and this
|
|
222
|
+
* collection's content is a React element — which stringifies to
|
|
223
|
+
* `[object Object]` and matches every query equally. Anything that has to be
|
|
224
|
+
* findable belongs here.
|
|
225
|
+
*/
|
|
226
|
+
searchString?: string;
|
|
39
227
|
[key: string]: unknown;
|
|
40
228
|
}
|
|
41
229
|
|
|
@@ -109,6 +297,121 @@ export const getSelectItemDescriptionProps = (
|
|
|
109
297
|
return { shortDescription };
|
|
110
298
|
};
|
|
111
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Why an item cannot be picked, in the words the row will print.
|
|
302
|
+
*
|
|
303
|
+
* Two shapes reach here and they mean the same thing. A caller that resolved
|
|
304
|
+
* the availability itself sends `unavailable`; a caller — or a server — that
|
|
305
|
+
* only marked the value `disabled` and explained it in `messages` gets the same
|
|
306
|
+
* treatment, because a refusal nobody worded is still a refusal, and a row that
|
|
307
|
+
* silently ignores a click is the defect this answers.
|
|
308
|
+
*
|
|
309
|
+
* Which message explains a refusal is decided in one place
|
|
310
|
+
* ({@link getRefusalMessage}), so the picker and the form's own resolver cannot
|
|
311
|
+
* word the same refusal differently.
|
|
312
|
+
*/
|
|
313
|
+
export const getSelectItemUnavailability = (
|
|
314
|
+
item: Pick<ISelectFieldCollectionItem, 'unavailable' | 'disabled' | 'messages'>
|
|
315
|
+
): ISelectFieldCollectionItemMessage | undefined => {
|
|
316
|
+
if (item.unavailable) {
|
|
317
|
+
return item.unavailable;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (!item.disabled) {
|
|
321
|
+
return undefined;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const explanation = getRefusalMessage(item.messages);
|
|
325
|
+
|
|
326
|
+
return {
|
|
327
|
+
intent: explanation?.intent || 'warning',
|
|
328
|
+
title: explanation?.title,
|
|
329
|
+
content: explanation?.content || UNAVAILABLE_VALUE_FALLBACK_REASON,
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* An item's title-bar affordances as reqore panel actions.
|
|
335
|
+
*
|
|
336
|
+
* `as` is defaulted here rather than left to reqore: reqore renders an action
|
|
337
|
+
* with no `as` as a `ReqoreButton` built from the action's OWN keys and drops
|
|
338
|
+
* `props` on the floor, so a descriptor that named only props would render an
|
|
339
|
+
* empty button. Defaulting `as` keeps one descriptor shape for both
|
|
340
|
+
* placements.
|
|
341
|
+
*
|
|
342
|
+
* `size` is a default, not an override — the row is `tiny`, so a control in
|
|
343
|
+
* its title bar is too unless the caller says otherwise. The body renderer
|
|
344
|
+
* below forces `size` after the caller's props and cannot be given a
|
|
345
|
+
* different one; that is the older behaviour and it is left alone.
|
|
346
|
+
*
|
|
347
|
+
* An unavailable row leads with a padlock, before whatever the caller declared.
|
|
348
|
+
* It is a TAG, not a control: the words are already on the row and in its
|
|
349
|
+
* tooltip, and a second popover saying the same thing over the first is worse
|
|
350
|
+
* than one. It is also not the compact form's "Depends on" chip, whose whole
|
|
351
|
+
* value is clicking through to the blocking field — from inside a modal that
|
|
352
|
+
* covers that field, there is nowhere for such a click to go.
|
|
353
|
+
*/
|
|
354
|
+
export const getSelectItemTitleActions = (
|
|
355
|
+
item: Pick<ISelectFieldCollectionItem, 'title_actions'>,
|
|
356
|
+
unavailable?: ISelectFieldCollectionItemMessage
|
|
357
|
+
): IReqorePanelAction[] | undefined => {
|
|
358
|
+
const declared = (item.title_actions || []).map(
|
|
359
|
+
({ as = ReqoreButton, props, ...rest }): IReqorePanelAction => ({
|
|
360
|
+
...rest,
|
|
361
|
+
as,
|
|
362
|
+
props: { size: 'tiny', ...props },
|
|
363
|
+
})
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
const actions = unavailable ? [UNAVAILABLE_TITLE_ACTION, ...declared] : declared;
|
|
367
|
+
|
|
368
|
+
return actions.length ? actions : undefined;
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
/** The padlock an unavailable row wears — see {@link getSelectItemTitleActions}. */
|
|
372
|
+
const UNAVAILABLE_TITLE_ACTION: IReqorePanelAction = {
|
|
373
|
+
as: ReqoreTag,
|
|
374
|
+
props: {
|
|
375
|
+
size: 'tiny',
|
|
376
|
+
icon: 'LockLine',
|
|
377
|
+
minimal: true,
|
|
378
|
+
className: 'reqraft-select-item-lock',
|
|
379
|
+
},
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* An item's row tooltip as reqore's own tooltip prop.
|
|
384
|
+
*
|
|
385
|
+
* The descriptor is turned into an element HERE — after the caller's items
|
|
386
|
+
* have been through whatever memo key they travel under — which is the whole
|
|
387
|
+
* reason the item carries `{ as, props }` and not a node.
|
|
388
|
+
*/
|
|
389
|
+
export const buildSelectItemTooltip = (
|
|
390
|
+
tooltip: ISelectFieldCollectionItem['tooltip']
|
|
391
|
+
): string | IReqoreTooltip | undefined => {
|
|
392
|
+
if (!tooltip) {
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (typeof tooltip === 'string') {
|
|
397
|
+
return tooltip;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const { content, ...rest } = tooltip;
|
|
401
|
+
|
|
402
|
+
if (content === undefined) {
|
|
403
|
+
return rest;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (typeof content === 'string') {
|
|
407
|
+
return { ...rest, content };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const { as: Component, props } = content;
|
|
411
|
+
|
|
412
|
+
return { ...rest, content: <Component {...props} /> };
|
|
413
|
+
};
|
|
414
|
+
|
|
112
415
|
export const SelectFieldCollection = ({
|
|
113
416
|
onClose,
|
|
114
417
|
items,
|
|
@@ -131,7 +434,7 @@ export const SelectFieldCollection = ({
|
|
|
131
434
|
}, [items, appliedFilters]);
|
|
132
435
|
|
|
133
436
|
return (
|
|
134
|
-
<
|
|
437
|
+
<StyledSelectDialog
|
|
135
438
|
isOpen
|
|
136
439
|
// A library-owned hook for hosts and their tests to target the picker
|
|
137
440
|
// (qorus-ide's helpers looked for its own `.q-select-dialog`, which
|
|
@@ -166,15 +469,53 @@ export const SelectFieldCollection = ({
|
|
|
166
469
|
showLayoutSwitch={false}
|
|
167
470
|
items={filteredItems.map((item): IReqoreCollectionItemProps => {
|
|
168
471
|
const { longDescription, shortDescription } = getSelectItemDescriptionProps(item);
|
|
472
|
+
const unavailable = getSelectItemUnavailability(item);
|
|
473
|
+
/* One `messages` entry can be the refusal itself — a server that sent
|
|
474
|
+
`disabled` with its reason, resolved into `unavailable` upstream.
|
|
475
|
+
It is already printed above the description, so it is not printed
|
|
476
|
+
again underneath it. */
|
|
477
|
+
const messages = (item.messages || []).filter(
|
|
478
|
+
(message) => !unavailable || message.content !== unavailable.content
|
|
479
|
+
);
|
|
169
480
|
|
|
170
481
|
return {
|
|
171
482
|
label: item.display_name || item.value?.toString(),
|
|
172
483
|
size: 'tiny',
|
|
173
484
|
groups: item.groups,
|
|
485
|
+
className: [item.className, unavailable ? UNAVAILABLE_ITEM_CLASS : undefined]
|
|
486
|
+
.filter(Boolean)
|
|
487
|
+
.join(' '),
|
|
488
|
+
/* Inline with the name, in height the title bar already spends.
|
|
489
|
+
`actions` on the item stays where it has always been, in the
|
|
490
|
+
body under the description. */
|
|
491
|
+
actions: getSelectItemTitleActions(item, unavailable),
|
|
492
|
+
/* The row is the hover target, so an explanation costs the list
|
|
493
|
+
nothing until it is asked for. */
|
|
494
|
+
tooltip: buildSelectItemTooltip(item.tooltip ?? unavailable?.content),
|
|
495
|
+
/* Reqore searches a row's label and its stringified content, and
|
|
496
|
+
the content below is an element — so every row matches
|
|
497
|
+
`[object Object]` and nothing matches a word inside it. A reason
|
|
498
|
+
nobody can search for in a list of hundreds is a reason nobody
|
|
499
|
+
finds. */
|
|
500
|
+
searchString: [item.searchString, unavailable?.title, unavailable?.content]
|
|
501
|
+
.filter(Boolean)
|
|
502
|
+
.join(' '),
|
|
174
503
|
customTheme: { main: '#08182d' },
|
|
175
504
|
responsiveTitle: false,
|
|
176
505
|
content: (
|
|
177
506
|
<ReqoreControlGroup vertical fluid>
|
|
507
|
+
{unavailable ? (
|
|
508
|
+
<ReqoreMessage
|
|
509
|
+
flat
|
|
510
|
+
icon='LockLine'
|
|
511
|
+
intent={unavailable.intent || 'warning'}
|
|
512
|
+
title={unavailable.title}
|
|
513
|
+
size='small'
|
|
514
|
+
opaque={false}
|
|
515
|
+
>
|
|
516
|
+
{unavailable.content}
|
|
517
|
+
</ReqoreMessage>
|
|
518
|
+
) : null}
|
|
178
519
|
{longDescription || shortDescription ? (
|
|
179
520
|
<Description
|
|
180
521
|
longDescription={longDescription || ''}
|
|
@@ -192,7 +533,7 @@ export const SelectFieldCollection = ({
|
|
|
192
533
|
size='tiny'
|
|
193
534
|
/>
|
|
194
535
|
))}
|
|
195
|
-
{
|
|
536
|
+
{messages.map(({ intent, title, content }, index) => (
|
|
196
537
|
<ReqoreMessage
|
|
197
538
|
flat
|
|
198
539
|
intent={intent}
|
|
@@ -220,7 +561,10 @@ export const SelectFieldCollection = ({
|
|
|
220
561
|
size: '20px',
|
|
221
562
|
rounded: true,
|
|
222
563
|
},
|
|
223
|
-
|
|
564
|
+
/* No handler is what makes an unavailable row inert, and it is
|
|
565
|
+
deliberately NOT reqore's `disabled`: see the stylesheet on
|
|
566
|
+
`StyledSelectDialog`. */
|
|
567
|
+
onClick: !item.disabled && !unavailable
|
|
224
568
|
? (e) => {
|
|
225
569
|
if (e.currentTarget.contains(e.target as Node)) {
|
|
226
570
|
onItemSelect(item);
|
|
@@ -245,6 +589,6 @@ export const SelectFieldCollection = ({
|
|
|
245
589
|
},
|
|
246
590
|
}))}
|
|
247
591
|
/>
|
|
248
|
-
</
|
|
592
|
+
</StyledSelectDialog>
|
|
249
593
|
);
|
|
250
594
|
};
|
|
@@ -5,6 +5,7 @@ import { memo } from 'react';
|
|
|
5
5
|
import {
|
|
6
6
|
getTemplateTagStyle,
|
|
7
7
|
describeTemplateReference,
|
|
8
|
+
templateTooltip,
|
|
8
9
|
TTemplateMeta,
|
|
9
10
|
} from '../../../../helpers/templates';
|
|
10
11
|
|
|
@@ -18,7 +19,8 @@ export interface IReadOnlyTemplateTagProps {
|
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* The read-only representation of a selected template — a picker-shaped chip:
|
|
21
|
-
* the `$`-dollar icon, the resolved display name (
|
|
22
|
+
* the `$`-dollar icon, the resolved display name (and what the value IS in the
|
|
23
|
+
* tooltip, not the reference that names it), the
|
|
22
24
|
* app image when present, coloured by qorus-ide's scheme (info / qorus purple /
|
|
23
25
|
* success — see `getTemplateTagStyle`). Shared by `TemplateField`'s disabled
|
|
24
26
|
* branch and the compact read-first row so a template reads identically wherever
|
|
@@ -34,7 +36,7 @@ export const ReadOnlyTemplateTag = memo(
|
|
|
34
36
|
icon='ExchangeDollarLine'
|
|
35
37
|
leftIconProps={{ image: metadata?.image }}
|
|
36
38
|
label={label}
|
|
37
|
-
tooltip={value}
|
|
39
|
+
tooltip={templateTooltip(templates, value)}
|
|
38
40
|
{...getTemplateTagStyle(metadata)}
|
|
39
41
|
/>
|
|
40
42
|
</ReqoreTagGroup>
|
|
@@ -264,10 +264,20 @@ export const AutoComponent: StoryObj<typeof meta> = {
|
|
|
264
264
|
docs: {
|
|
265
265
|
description: {
|
|
266
266
|
story:
|
|
267
|
-
'Renders TemplateField over an untyped (`auto`) field that accepts templates. While the field is empty it opens on
|
|
267
|
+
'Renders TemplateField over an untyped (`auto`) field that accepts templates. While the field is empty it opens on an editor to type into, which offers the templates — never on a data-type picker, so the author can write the value they mean without answering how it is stored.',
|
|
268
268
|
},
|
|
269
269
|
},
|
|
270
270
|
},
|
|
271
|
+
play: async ({ canvasElement }) => {
|
|
272
|
+
/* The editor itself, not a class: TemplateField puts `.template-selector`
|
|
273
|
+
on every control it draws, the data-type picker included, so asserting
|
|
274
|
+
the class passed while the story showed "Please select data type". */
|
|
275
|
+
await waitFor(() => expect(canvasElement.querySelector('[contenteditable="true"]')).toBeTruthy(), {
|
|
276
|
+
timeout: 5000,
|
|
277
|
+
});
|
|
278
|
+
expect(canvasElement.textContent).not.toContain('Please select data type');
|
|
279
|
+
expect(canvasElement.textContent).not.toContain('Select Template');
|
|
280
|
+
},
|
|
271
281
|
};
|
|
272
282
|
|
|
273
283
|
export const AllowedValuesWithTemplate: StoryObj<typeof meta> = {
|
|
@@ -674,7 +684,7 @@ export const TemplateCanBeSelected: StoryObj<typeof meta> = {
|
|
|
674
684
|
docs: {
|
|
675
685
|
description: {
|
|
676
686
|
story:
|
|
677
|
-
'Renders TemplateField for a string, opens the templates popover and clicks the Interface ID template — the field switches to the $local:id
|
|
687
|
+
'Renders TemplateField for a string, opens the templates popover and clicks the Interface ID template — the field switches to template mode, where the $local:id reference is a chip named Interface ID inside an editor that can still be typed into.',
|
|
678
688
|
},
|
|
679
689
|
},
|
|
680
690
|
},
|
|
@@ -684,9 +694,16 @@ export const TemplateCanBeSelected: StoryObj<typeof meta> = {
|
|
|
684
694
|
await ShowsTemplatesListForString.play({ canvasElement, ...rest });
|
|
685
695
|
await _testsClickButton({ label: 'Interface ID' });
|
|
686
696
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
await
|
|
697
|
+
// The chosen reference reads as the name it was chosen by, in an editor
|
|
698
|
+
// that can still be typed into — not as its spelling.
|
|
699
|
+
await waitFor(
|
|
700
|
+
() => {
|
|
701
|
+
const chip = canvasElement.querySelector('.template-selector [contenteditable="true"] .reqore-tag');
|
|
702
|
+
expect(chip?.textContent).toContain('Interface ID');
|
|
703
|
+
},
|
|
704
|
+
{ timeout: 5000 }
|
|
705
|
+
);
|
|
706
|
+
await expect(canvas.queryByDisplayValue('$local:id')).toBeNull();
|
|
690
707
|
},
|
|
691
708
|
};
|
|
692
709
|
|
|
@@ -991,14 +1008,73 @@ export const EmptyAnyOpensOnTemplates: StoryObj<typeof meta> = {
|
|
|
991
1008
|
docs: {
|
|
992
1009
|
description: {
|
|
993
1010
|
story:
|
|
994
|
-
'An untyped, empty field that accepts templates opens
|
|
1011
|
+
'An untyped, empty field that accepts templates opens on an editor to type into, which offers the templates — never on a data-type picker.',
|
|
995
1012
|
},
|
|
996
1013
|
},
|
|
997
1014
|
},
|
|
998
1015
|
play: async ({ canvasElement }) => {
|
|
1016
|
+
/* The editor itself, not a class: TemplateField puts `.template-selector`
|
|
1017
|
+
on every control it draws, the data-type picker included, so asserting
|
|
1018
|
+
the class passed while the story showed "Please select data type". */
|
|
1019
|
+
await waitFor(() => expect(canvasElement.querySelector('[contenteditable="true"]')).toBeTruthy(), {
|
|
1020
|
+
timeout: 5000,
|
|
1021
|
+
});
|
|
1022
|
+
expect(canvasElement.textContent).not.toContain('Please select data type');
|
|
1023
|
+
expect(canvasElement.textContent).not.toContain('Select Template');
|
|
1024
|
+
},
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
/** A string mixing text with template references, as template mode edits it. */
|
|
1028
|
+
const templateReferencesInText: StoryObj<typeof meta> = {
|
|
1029
|
+
args: {
|
|
1030
|
+
type: 'string',
|
|
1031
|
+
defaultType: 'string',
|
|
1032
|
+
defaultInternalType: 'string',
|
|
1033
|
+
value: 'Interface $local:id failed at $timestamp:now',
|
|
1034
|
+
},
|
|
1035
|
+
play: async ({ canvasElement }) => {
|
|
1036
|
+
const editor = await waitFor(
|
|
1037
|
+
() => {
|
|
1038
|
+
const element = canvasElement.querySelector<HTMLElement>('.template-selector [contenteditable="true"]');
|
|
1039
|
+
expect(element).toBeTruthy();
|
|
1040
|
+
return element!;
|
|
1041
|
+
},
|
|
1042
|
+
{ timeout: 5000 }
|
|
1043
|
+
);
|
|
1044
|
+
// Each reference is its catalogue name; the text between them is untouched.
|
|
999
1045
|
await waitFor(() =>
|
|
1000
|
-
expect(
|
|
1046
|
+
expect(Array.from(editor.querySelectorAll('.reqore-tag')).map((chip) => chip.textContent?.trim())).toEqual([
|
|
1047
|
+
'Interface ID',
|
|
1048
|
+
'Current Timestamp',
|
|
1049
|
+
])
|
|
1001
1050
|
);
|
|
1051
|
+
expect(editor.textContent).toContain('failed at');
|
|
1052
|
+
expect(editor.textContent).not.toContain('$local:id');
|
|
1053
|
+
},
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
export const TemplateReferencesInText: StoryObj<typeof meta> = {
|
|
1057
|
+
...templateReferencesInText,
|
|
1058
|
+
parameters: {
|
|
1059
|
+
docs: {
|
|
1060
|
+
description: {
|
|
1061
|
+
story:
|
|
1062
|
+
'Renders TemplateField holding the string "Interface $local:id failed at $timestamp:now". Template mode draws each reference as a chip named from the catalogue (Interface ID, Current Timestamp) inside an editor that can still be typed into; the text between them reads as typed.',
|
|
1063
|
+
},
|
|
1064
|
+
},
|
|
1065
|
+
},
|
|
1066
|
+
};
|
|
1067
|
+
|
|
1068
|
+
export const TemplateReferencesInTextOnPhone: StoryObj<typeof meta> = {
|
|
1069
|
+
...templateReferencesInText,
|
|
1070
|
+
parameters: {
|
|
1071
|
+
qlip: { viewport: { width: 390, height: 844 } },
|
|
1072
|
+
docs: {
|
|
1073
|
+
description: {
|
|
1074
|
+
story:
|
|
1075
|
+
'Renders the same string with two template references at phone width (390px): the named chips and the text around them wrap inside the editor rather than overflowing it.',
|
|
1076
|
+
},
|
|
1077
|
+
},
|
|
1002
1078
|
},
|
|
1003
1079
|
};
|
|
1004
1080
|
|
|
@@ -1021,7 +1097,7 @@ export const AnyWithLiteralOpensOnTheValue: StoryObj<typeof meta> = {
|
|
|
1021
1097
|
docs: {
|
|
1022
1098
|
description: {
|
|
1023
1099
|
story:
|
|
1024
|
-
'An untyped field holding a literal keeps showing that literal — only an empty one defaults to the template selector.',
|
|
1100
|
+
'An untyped field holding a literal keeps showing that literal — only an empty one defaults to the template selector. Where the field offers templates that editor is the chip editor (a contenteditable box), not a textarea, so the literal appears there.',
|
|
1025
1101
|
},
|
|
1026
1102
|
},
|
|
1027
1103
|
},
|
|
@@ -1031,12 +1107,15 @@ export const AnyWithLiteralOpensOnTheValue: StoryObj<typeof meta> = {
|
|
|
1031
1107
|
// a control that renders either way, so it says nothing about which view is
|
|
1032
1108
|
// active.
|
|
1033
1109
|
await waitFor(() => {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1110
|
+
// Its editor may be a field or, where templates are offered, the chip editor.
|
|
1111
|
+
const shown = [
|
|
1112
|
+
...canvasElement.querySelectorAll<HTMLElement>('input, textarea, [contenteditable="true"]'),
|
|
1113
|
+
].map((el) =>
|
|
1114
|
+
el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement ?
|
|
1115
|
+
el.value
|
|
1116
|
+
: (el.textContent ?? '').replace(/\uFEFF/g, '').trim()
|
|
1117
|
+
);
|
|
1118
|
+
expect(shown).toContain('already-typed');
|
|
1040
1119
|
});
|
|
1041
1120
|
},
|
|
1042
1121
|
};
|