@qoretechnologies/reqraft 0.10.62 → 0.10.63-pr.142.g0b675cd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/dist/components/Description/describedControl.d.ts +48 -0
- package/dist/components/Description/describedControl.d.ts.map +1 -0
- package/dist/components/Description/describedControl.js +81 -0
- package/dist/components/Description/describedControl.js.map +1 -0
- package/dist/components/Description/index.d.ts.map +1 -1
- package/dist/components/Description/index.js +3 -2
- package/dist/components/Description/index.js.map +1 -1
- package/dist/components/colorValue/colorValue.d.ts +59 -0
- package/dist/components/colorValue/colorValue.d.ts.map +1 -0
- package/dist/components/colorValue/colorValue.js +245 -0
- package/dist/components/colorValue/colorValue.js.map +1 -0
- package/dist/components/colorValue/index.d.ts +34 -0
- package/dist/components/colorValue/index.d.ts.map +1 -0
- package/dist/components/colorValue/index.js +136 -0
- package/dist/components/colorValue/index.js.map +1 -0
- package/dist/components/colorValue/labels.d.ts +12 -0
- package/dist/components/colorValue/labels.d.ts.map +1 -0
- package/dist/components/colorValue/labels.js +11 -0
- package/dist/components/colorValue/labels.js.map +1 -0
- package/dist/components/composer/Composer.d.ts +1 -1
- package/dist/components/composer/Composer.d.ts.map +1 -1
- package/dist/components/composer/Composer.js +2 -2
- 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 +25 -5
- package/dist/components/dpqlEditor/DpqlEditor.js.map +1 -1
- package/dist/components/dpqlEditor/dpqlHelpers.d.ts +10 -1
- package/dist/components/dpqlEditor/dpqlHelpers.d.ts.map +1 -1
- package/dist/components/dpqlEditor/dpqlHelpers.js +30 -13
- package/dist/components/dpqlEditor/dpqlHelpers.js.map +1 -1
- package/dist/components/dpqlEditor/dpqlTags.d.ts +11 -7
- package/dist/components/dpqlEditor/dpqlTags.d.ts.map +1 -1
- package/dist/components/dpqlEditor/dpqlTags.js +11 -6
- package/dist/components/dpqlEditor/dpqlTags.js.map +1 -1
- package/dist/components/dpqlEditor/types.d.ts +47 -8
- package/dist/components/dpqlEditor/types.d.ts.map +1 -1
- package/dist/components/dpqlEditor/useDpqlSession.d.ts +2 -2
- package/dist/components/dpqlEditor/useDpqlSession.d.ts.map +1 -1
- package/dist/components/dpqlEditor/useDpqlSession.js +16 -7
- 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 +151 -83
- 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 +29 -3
- package/dist/components/form/engine/CompactToolbar.js.map +1 -1
- package/dist/components/form/engine/FormEngine.d.ts +34 -1
- package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
- package/dist/components/form/engine/FormEngine.js +487 -87
- package/dist/components/form/engine/FormEngine.js.map +1 -1
- package/dist/components/form/engine/HiddenFieldsNote.d.ts +28 -0
- package/dist/components/form/engine/HiddenFieldsNote.d.ts.map +1 -0
- package/dist/components/form/engine/HiddenFieldsNote.js +32 -0
- package/dist/components/form/engine/HiddenFieldsNote.js.map +1 -0
- package/dist/components/form/engine/OptionFieldMessages.d.ts.map +1 -1
- package/dist/components/form/engine/OptionFieldMessages.js +24 -3
- package/dist/components/form/engine/OptionFieldMessages.js.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts +2 -2
- package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.js +12 -6
- package/dist/components/form/engine/_structuredData/SchemaDataView.js.map +1 -1
- package/dist/components/form/engine/compactRowContext.d.ts +19 -0
- 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 +0 -1
- package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowStyles.js +12 -20
- package/dist/components/form/engine/compactRowStyles.js.map +1 -1
- package/dist/components/form/engine/compactToolbarColors.d.ts +16 -0
- package/dist/components/form/engine/compactToolbarColors.d.ts.map +1 -0
- package/dist/components/form/engine/compactToolbarColors.js +21 -0
- package/dist/components/form/engine/compactToolbarColors.js.map +1 -0
- package/dist/components/form/engine/readFirst.d.ts +24 -8
- package/dist/components/form/engine/readFirst.d.ts.map +1 -1
- package/dist/components/form/engine/readFirst.js +77 -109
- package/dist/components/form/engine/readFirst.js.map +1 -1
- package/dist/components/form/engine/readFirstColors.d.ts +30 -0
- package/dist/components/form/engine/readFirstColors.d.ts.map +1 -0
- package/dist/components/form/engine/readFirstColors.js +51 -0
- package/dist/components/form/engine/readFirstColors.js.map +1 -0
- package/dist/components/form/engine/rowFocus.d.ts +2 -0
- package/dist/components/form/engine/rowFocus.d.ts.map +1 -1
- package/dist/components/form/engine/rowFocus.js +26 -3
- package/dist/components/form/engine/rowFocus.js.map +1 -1
- package/dist/components/form/engine/typeChoices.d.ts +1 -1
- package/dist/components/form/engine/variants/VariantCalmTable.d.ts.map +1 -1
- package/dist/components/form/engine/variants/VariantCalmTable.js +2 -1
- package/dist/components/form/engine/variants/VariantCalmTable.js.map +1 -1
- package/dist/components/form/engine/variants/VariantCards.d.ts.map +1 -1
- package/dist/components/form/engine/variants/VariantCards.js +2 -1
- package/dist/components/form/engine/variants/VariantCards.js.map +1 -1
- package/dist/components/form/engine/variants/VariantFocus.js +1 -1
- package/dist/components/form/engine/variants/VariantFocus.js.map +1 -1
- package/dist/components/form/engine/variants/VariantMinimal.d.ts.map +1 -1
- package/dist/components/form/engine/variants/VariantMinimal.js +2 -1
- package/dist/components/form/engine/variants/VariantMinimal.js.map +1 -1
- package/dist/components/form/engine/variants/variantParts.d.ts +1 -1
- package/dist/components/form/engine/variants/variantParts.d.ts.map +1 -1
- package/dist/components/form/engine/variants/variantParts.js +25 -17
- package/dist/components/form/engine/variants/variantParts.js.map +1 -1
- package/dist/components/form/expressions/DpqlRendering.d.ts +1 -1
- package/dist/components/form/expressions/DpqlRendering.d.ts.map +1 -1
- package/dist/components/form/expressions/DpqlRendering.js +3 -3
- package/dist/components/form/expressions/DpqlRendering.js.map +1 -1
- package/dist/components/form/expressions/ExpressionField.d.ts +41 -3
- package/dist/components/form/expressions/ExpressionField.d.ts.map +1 -1
- package/dist/components/form/expressions/ExpressionField.js +396 -99
- package/dist/components/form/expressions/ExpressionField.js.map +1 -1
- package/dist/components/form/expressions/builder/argumentDetail.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/argumentDetail.js +4 -1
- package/dist/components/form/expressions/builder/argumentDetail.js.map +1 -1
- package/dist/components/form/expressions/builder/argumentLabel.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/argumentLabel.js +27 -9
- package/dist/components/form/expressions/builder/argumentLabel.js.map +1 -1
- package/dist/components/form/expressions/builder/argumentWrapper.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/argumentWrapper.js +4 -2
- package/dist/components/form/expressions/builder/argumentWrapper.js.map +1 -1
- package/dist/components/form/expressions/builder/confirmMismatchedTypesModal.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/confirmMismatchedTypesModal.js +5 -4
- package/dist/components/form/expressions/builder/confirmMismatchedTypesModal.js.map +1 -1
- package/dist/components/form/expressions/builder/confirmUnsupportedTypeModal.d.ts +1 -1
- package/dist/components/form/expressions/builder/confirmUnsupportedTypeModal.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/confirmUnsupportedTypeModal.js +6 -3
- package/dist/components/form/expressions/builder/confirmUnsupportedTypeModal.js.map +1 -1
- package/dist/components/form/expressions/builder/index.d.ts +24 -2
- package/dist/components/form/expressions/builder/index.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/index.js +121 -77
- package/dist/components/form/expressions/builder/index.js.map +1 -1
- package/dist/components/form/expressions/builder/item.d.ts +6 -2
- package/dist/components/form/expressions/builder/item.d.ts.map +1 -1
- package/dist/components/form/expressions/builder/item.js +19 -5
- package/dist/components/form/expressions/builder/item.js.map +1 -1
- package/dist/components/form/expressions/builder/renderTemplate.js +1 -1
- package/dist/components/form/expressions/builder/renderTemplate.js.map +1 -1
- package/dist/components/form/expressions/expressionOperands.d.ts +16 -0
- package/dist/components/form/expressions/expressionOperands.d.ts.map +1 -0
- package/dist/components/form/expressions/expressionOperands.js +97 -0
- package/dist/components/form/expressions/expressionOperands.js.map +1 -0
- package/dist/components/form/expressions/mockExpressions.d.ts.map +1 -1
- package/dist/components/form/expressions/mockExpressions.js +22 -5
- package/dist/components/form/expressions/mockExpressions.js.map +1 -1
- package/dist/components/form/expressions/renderExpressionToText.d.ts +2 -0
- package/dist/components/form/expressions/renderExpressionToText.d.ts.map +1 -1
- package/dist/components/form/expressions/renderExpressionToText.js +35 -9
- package/dist/components/form/expressions/renderExpressionToText.js.map +1 -1
- package/dist/components/form/expressions/textOfExpression.d.ts +18 -0
- package/dist/components/form/expressions/textOfExpression.d.ts.map +1 -0
- package/dist/components/form/expressions/textOfExpression.js +37 -0
- package/dist/components/form/expressions/textOfExpression.js.map +1 -0
- package/dist/components/form/expressions/useExpressionType.d.ts +26 -0
- package/dist/components/form/expressions/useExpressionType.d.ts.map +1 -0
- package/dist/components/form/expressions/useExpressionType.js +181 -0
- package/dist/components/form/expressions/useExpressionType.js.map +1 -0
- package/dist/components/form/expressions/useRenderExpression.d.ts.map +1 -1
- package/dist/components/form/expressions/useRenderExpression.js +7 -7
- package/dist/components/form/expressions/useRenderExpression.js.map +1 -1
- package/dist/components/form/fields/Field.d.ts.map +1 -1
- package/dist/components/form/fields/Field.js +20 -7
- package/dist/components/form/fields/Field.js.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.js +17 -4
- package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
- package/dist/components/form/fields/array/ArrayAuto.d.ts.map +1 -1
- package/dist/components/form/fields/array/ArrayAuto.js +24 -0
- package/dist/components/form/fields/array/ArrayAuto.js.map +1 -1
- package/dist/components/form/fields/array/ArrayAutoField.d.ts.map +1 -1
- package/dist/components/form/fields/array/ArrayAutoField.js +36 -13
- package/dist/components/form/fields/array/ArrayAutoField.js.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.d.ts +20 -1
- package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
- package/dist/components/form/fields/auto/AutoFormField.js +81 -36
- package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
- package/dist/components/form/fields/auto/hostEditorValue.d.ts +30 -0
- package/dist/components/form/fields/auto/hostEditorValue.d.ts.map +1 -0
- package/dist/components/form/fields/auto/hostEditorValue.js +53 -0
- package/dist/components/form/fields/auto/hostEditorValue.js.map +1 -0
- package/dist/components/form/fields/binary/Binary.d.ts.map +1 -1
- package/dist/components/form/fields/binary/Binary.js +23 -3
- package/dist/components/form/fields/binary/Binary.js.map +1 -1
- package/dist/components/form/fields/boolean/Boolean.d.ts +5 -0
- package/dist/components/form/fields/boolean/Boolean.d.ts.map +1 -1
- package/dist/components/form/fields/boolean/Boolean.js +9 -1
- package/dist/components/form/fields/boolean/Boolean.js.map +1 -1
- package/dist/components/form/fields/color/Color.d.ts +103 -16
- package/dist/components/form/fields/color/Color.d.ts.map +1 -1
- package/dist/components/form/fields/color/Color.js +611 -16
- package/dist/components/form/fields/color/Color.js.map +1 -1
- package/dist/components/form/fields/emittedValues.d.ts +34 -3
- package/dist/components/form/fields/emittedValues.d.ts.map +1 -1
- package/dist/components/form/fields/emittedValues.js +24 -1
- package/dist/components/form/fields/emittedValues.js.map +1 -1
- package/dist/components/form/fields/file/File.d.ts +1 -1
- package/dist/components/form/fields/file/File.d.ts.map +1 -1
- package/dist/components/form/fields/file/File.js +4 -2
- package/dist/components/form/fields/file/File.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 +17 -3
- package/dist/components/form/fields/long-string/LongString.js.map +1 -1
- package/dist/components/form/fields/markdown/MarkdownView.js +1 -1
- package/dist/components/form/fields/multi-select/MultiSelectFormField.d.ts.map +1 -1
- package/dist/components/form/fields/multi-select/MultiSelectFormField.js +4 -1
- package/dist/components/form/fields/multi-select/MultiSelectFormField.js.map +1 -1
- package/dist/components/form/fields/number/Number.d.ts +6 -0
- package/dist/components/form/fields/number/Number.d.ts.map +1 -1
- package/dist/components/form/fields/number/Number.js +41 -6
- package/dist/components/form/fields/number/Number.js.map +1 -1
- package/dist/components/form/fields/object/Object.d.ts +1 -1
- package/dist/components/form/fields/object/Object.d.ts.map +1 -1
- package/dist/components/form/fields/object/Object.js +4 -2
- package/dist/components/form/fields/object/Object.js.map +1 -1
- package/dist/components/form/fields/pendingEdit.d.ts +52 -0
- package/dist/components/form/fields/pendingEdit.d.ts.map +1 -0
- package/dist/components/form/fields/pendingEdit.js +79 -0
- package/dist/components/form/fields/pendingEdit.js.map +1 -0
- package/dist/components/form/fields/rich-text/RichText.d.ts +8 -1
- package/dist/components/form/fields/rich-text/RichText.d.ts.map +1 -1
- package/dist/components/form/fields/rich-text/RichText.js +190 -81
- package/dist/components/form/fields/rich-text/RichText.js.map +1 -1
- package/dist/components/form/fields/rich-text/useTemplateTags.d.ts +18 -0
- package/dist/components/form/fields/rich-text/useTemplateTags.d.ts.map +1 -0
- package/dist/components/form/fields/rich-text/useTemplateTags.js +49 -0
- package/dist/components/form/fields/rich-text/useTemplateTags.js.map +1 -0
- package/dist/components/form/fields/schema-definition/CatalogLeafForm.d.ts.map +1 -1
- package/dist/components/form/fields/schema-definition/CatalogLeafForm.js +4 -1
- package/dist/components/form/fields/schema-definition/CatalogLeafForm.js.map +1 -1
- package/dist/components/form/fields/schema-definition/CatalogNodeEditor.d.ts.map +1 -1
- package/dist/components/form/fields/schema-definition/CatalogNodeEditor.js +20 -5
- package/dist/components/form/fields/schema-definition/CatalogNodeEditor.js.map +1 -1
- package/dist/components/form/fields/schema-definition/TableEditor.d.ts.map +1 -1
- package/dist/components/form/fields/schema-definition/TableEditor.js +10 -2
- package/dist/components/form/fields/schema-definition/TableEditor.js.map +1 -1
- package/dist/components/form/fields/schema-definition/index.d.ts.map +1 -1
- package/dist/components/form/fields/schema-definition/index.js +8 -4
- package/dist/components/form/fields/schema-definition/index.js.map +1 -1
- package/dist/components/form/fields/select/Select.d.ts +2 -0
- package/dist/components/form/fields/select/Select.d.ts.map +1 -1
- package/dist/components/form/fields/select/Select.js +19 -10
- package/dist/components/form/fields/select/Select.js.map +1 -1
- package/dist/components/form/fields/select/SelectCollection.d.ts.map +1 -1
- package/dist/components/form/fields/select/SelectCollection.js +8 -2
- package/dist/components/form/fields/select/SelectCollection.js.map +1 -1
- package/dist/components/form/fields/select/unavailableRow.d.ts +23 -0
- package/dist/components/form/fields/select/unavailableRow.d.ts.map +1 -0
- package/dist/components/form/fields/select/unavailableRow.js +55 -0
- package/dist/components/form/fields/select/unavailableRow.js.map +1 -0
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts +5 -5
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts.map +1 -1
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.js +11 -4
- package/dist/components/form/fields/template/ReadOnlyTemplateTag.js.map +1 -1
- package/dist/components/form/fields/template/TemplateBrowser.d.ts +22 -0
- package/dist/components/form/fields/template/TemplateBrowser.d.ts.map +1 -0
- package/dist/components/form/fields/template/TemplateBrowser.js +54 -0
- package/dist/components/form/fields/template/TemplateBrowser.js.map +1 -0
- package/dist/components/form/fields/template/TemplateField.d.ts +83 -1
- package/dist/components/form/fields/template/TemplateField.d.ts.map +1 -1
- package/dist/components/form/fields/template/TemplateField.js +535 -85
- package/dist/components/form/fields/template/TemplateField.js.map +1 -1
- package/dist/components/form/fields/template/TemplateText.d.ts +0 -17
- package/dist/components/form/fields/template/TemplateText.d.ts.map +1 -1
- package/dist/components/form/fields/template/TemplateText.js +8 -4
- package/dist/components/form/fields/template/TemplateText.js.map +1 -1
- package/dist/components/form/fields/template/writtenAsText.d.ts +55 -0
- package/dist/components/form/fields/template/writtenAsText.d.ts.map +1 -0
- package/dist/components/form/fields/template/writtenAsText.js +188 -0
- package/dist/components/form/fields/template/writtenAsText.js.map +1 -0
- package/dist/components/form/index.d.ts +10 -0
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/index.js +23 -1
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/imageLightbox/ImageLightbox.d.ts.map +1 -1
- package/dist/components/imageLightbox/ImageLightbox.js +19 -7
- package/dist/components/imageLightbox/ImageLightbox.js.map +1 -1
- package/dist/components/log/Log.d.ts.map +1 -1
- package/dist/components/log/Log.js +15 -7
- package/dist/components/log/Log.js.map +1 -1
- package/dist/components/menu/Menu.d.ts.map +1 -1
- package/dist/components/menu/Menu.js +19 -10
- package/dist/components/menu/Menu.js.map +1 -1
- package/dist/components/smartEditor/CompletionMenu.d.ts +43 -0
- package/dist/components/smartEditor/CompletionMenu.d.ts.map +1 -0
- package/dist/components/smartEditor/CompletionMenu.js +196 -0
- package/dist/components/smartEditor/CompletionMenu.js.map +1 -0
- package/dist/components/smartEditor/MarkdownDoc.d.ts +1 -1
- package/dist/components/smartEditor/MarkdownDoc.js +1 -1
- package/dist/components/smartEditor/MarkdownDoc.js.map +1 -1
- package/dist/components/smartEditor/SmartEditor.d.ts.map +1 -1
- package/dist/components/smartEditor/SmartEditor.js +51 -136
- package/dist/components/smartEditor/SmartEditor.js.map +1 -1
- package/dist/components/smartEditor/completionStyle.d.ts +27 -0
- package/dist/components/smartEditor/completionStyle.d.ts.map +1 -0
- package/dist/components/smartEditor/completionStyle.js +66 -0
- package/dist/components/smartEditor/completionStyle.js.map +1 -0
- package/dist/components/smartEditor/index.d.ts +5 -1
- package/dist/components/smartEditor/index.d.ts.map +1 -1
- package/dist/components/smartEditor/index.js +19 -1
- package/dist/components/smartEditor/index.js.map +1 -1
- package/dist/components/smartEditor/templateCompletions.d.ts +18 -0
- package/dist/components/smartEditor/templateCompletions.d.ts.map +1 -0
- package/dist/components/smartEditor/templateCompletions.js +94 -0
- package/dist/components/smartEditor/templateCompletions.js.map +1 -0
- package/dist/components/smartEditor/types.d.ts +12 -1
- package/dist/components/smartEditor/types.d.ts.map +1 -1
- package/dist/components/smartEditor/useLspAutocomplete.d.ts +32 -0
- package/dist/components/smartEditor/useLspAutocomplete.d.ts.map +1 -1
- package/dist/components/smartEditor/useLspAutocomplete.js +228 -118
- package/dist/components/smartEditor/useLspAutocomplete.js.map +1 -1
- package/dist/components/smartEditor/useLspHover.d.ts +22 -7
- package/dist/components/smartEditor/useLspHover.d.ts.map +1 -1
- package/dist/components/smartEditor/useLspHover.js +86 -17
- package/dist/components/smartEditor/useLspHover.js.map +1 -1
- package/dist/components/smartEditor/useLspSemanticTokens.js +1 -1
- package/dist/components/smartEditor/useLspSemanticTokens.js.map +1 -1
- package/dist/components/smartEditor/useLspSession.d.ts +6 -0
- package/dist/components/smartEditor/useLspSession.d.ts.map +1 -1
- package/dist/components/smartEditor/useLspSession.js +7 -6
- package/dist/components/smartEditor/useLspSession.js.map +1 -1
- package/dist/components/supportTicket/AttachmentChips.d.ts.map +1 -1
- package/dist/components/supportTicket/AttachmentChips.js +15 -5
- package/dist/components/supportTicket/AttachmentChips.js.map +1 -1
- package/dist/components/supportTicket/ReferencePicker.d.ts +9 -2
- package/dist/components/supportTicket/ReferencePicker.d.ts.map +1 -1
- package/dist/components/supportTicket/ReferencePicker.js +27 -6
- package/dist/components/supportTicket/ReferencePicker.js.map +1 -1
- package/dist/components/supportTicket/TicketHeader.d.ts +3 -4
- package/dist/components/supportTicket/TicketHeader.d.ts.map +1 -1
- package/dist/components/supportTicket/TicketHeader.js +20 -2
- package/dist/components/supportTicket/TicketHeader.js.map +1 -1
- package/dist/components/supportTicket/TicketMetaTags.d.ts +1 -1
- package/dist/components/ticketReferences/TicketReferences.d.ts.map +1 -1
- package/dist/components/ticketReferences/TicketReferences.js +9 -4
- package/dist/components/ticketReferences/TicketReferences.js.map +1 -1
- package/dist/components/ticketThread/TicketThread.d.ts.map +1 -1
- package/dist/components/ticketThread/TicketThread.js +36 -11
- package/dist/components/ticketThread/TicketThread.js.map +1 -1
- package/dist/helpers/descriptionTooltip.d.ts +43 -0
- package/dist/helpers/descriptionTooltip.d.ts.map +1 -0
- package/dist/helpers/descriptionTooltip.js +70 -0
- package/dist/helpers/descriptionTooltip.js.map +1 -0
- package/dist/helpers/domProps.d.ts +5 -0
- package/dist/helpers/domProps.d.ts.map +1 -0
- package/dist/helpers/domProps.js +47 -0
- package/dist/helpers/domProps.js.map +1 -0
- package/dist/helpers/expressions.d.ts +107 -2
- package/dist/helpers/expressions.d.ts.map +1 -1
- package/dist/helpers/expressions.js +223 -8
- package/dist/helpers/expressions.js.map +1 -1
- package/dist/helpers/hoveringPointer.d.ts +26 -0
- package/dist/helpers/hoveringPointer.d.ts.map +1 -0
- package/dist/helpers/hoveringPointer.js +29 -0
- package/dist/helpers/hoveringPointer.js.map +1 -0
- package/dist/helpers/markdownText.d.ts +14 -0
- package/dist/helpers/markdownText.d.ts.map +1 -0
- package/dist/helpers/markdownText.js +160 -0
- package/dist/helpers/markdownText.js.map +1 -0
- package/dist/helpers/qorusTypeCatalogue.d.ts +53 -0
- package/dist/helpers/qorusTypeCatalogue.d.ts.map +1 -0
- package/dist/helpers/qorusTypeCatalogue.js +262 -0
- package/dist/helpers/qorusTypeCatalogue.js.map +1 -0
- package/dist/helpers/readableColors.d.ts +36 -0
- package/dist/helpers/readableColors.d.ts.map +1 -0
- package/dist/helpers/readableColors.js +116 -0
- package/dist/helpers/readableColors.js.map +1 -0
- package/dist/helpers/templateItems.d.ts +2 -2
- package/dist/helpers/templateItems.d.ts.map +1 -1
- package/dist/helpers/templateItems.js +6 -4
- package/dist/helpers/templateItems.js.map +1 -1
- package/dist/helpers/templates.d.ts +26 -1
- package/dist/helpers/templates.d.ts.map +1 -1
- package/dist/helpers/templates.js +41 -6
- package/dist/helpers/templates.js.map +1 -1
- package/dist/helpers/validations.d.ts +9 -0
- package/dist/helpers/validations.d.ts.map +1 -1
- package/dist/helpers/validations.js +139 -33
- package/dist/helpers/validations.js.map +1 -1
- package/dist/hooks/useQorusTypes.d.ts +7 -15
- package/dist/hooks/useQorusTypes.d.ts.map +1 -1
- package/dist/hooks/useQorusTypes.js +25 -166
- package/dist/hooks/useQorusTypes.js.map +1 -1
- package/dist/hooks/useReadableIntentShade.d.ts +9 -0
- package/dist/hooks/useReadableIntentShade.d.ts.map +1 -0
- package/dist/hooks/useReadableIntentShade.js +23 -0
- package/dist/hooks/useReadableIntentShade.js.map +1 -0
- package/dist/hooks/useReadableOpacity.d.ts +6 -0
- package/dist/hooks/useReadableOpacity.d.ts.map +1 -0
- package/dist/hooks/useReadableOpacity.js +17 -0
- package/dist/hooks/useReadableOpacity.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/tracking/ui/ExperimentCard.d.ts +1 -1
- package/dist/tracking/ui/ExperimentCard.d.ts.map +1 -1
- package/dist/tracking/ui/ExperimentCard.js +26 -10
- package/dist/tracking/ui/ExperimentCard.js.map +1 -1
- package/dist/tracking/ui/card.d.ts +2 -2
- package/dist/tracking/ui/card.d.ts.map +1 -1
- package/dist/tracking/ui/card.js +2 -2
- package/dist/tracking/ui/card.js.map +1 -1
- package/dist/tracking/ui/readable.d.ts +14 -0
- package/dist/tracking/ui/readable.d.ts.map +1 -0
- package/dist/tracking/ui/readable.js +60 -0
- package/dist/tracking/ui/readable.js.map +1 -0
- package/package.json +14 -5
- package/.claude/CLAUDE.md +0 -317
- package/.tasks/EXPORT_EXPRESSION_BUILDER.md +0 -38
- package/.tasks/EXPRESSION_BUILDER_REPORT.md +0 -149
- package/.tasks/EXPRESSION_FIELD_SEAMS.md +0 -66
- package/.tasks/FIELD_STACK_REPORT.md +0 -234
- package/.tasks/FORM_ENGINE_COMPACT_READ_FIRST.md +0 -558
- package/.tasks/FORM_ENGINE_EXPRESSIONS.md +0 -197
- package/.tasks/FORM_ENGINE_OPTIONS_SYNC.md +0 -95
- package/.tasks/FORM_FIELD_EXTRAS.md +0 -72
- package/.tasks/INDEX.md +0 -111
- package/.tasks/LSP_SHARED_CONNECTION.md +0 -75
- package/.tasks/QONSOLE_ASSIST_FEATURES.md +0 -306
- package/.tasks/RENDER_EXPRESSION_LSP.md +0 -159
- package/.tasks/REQRAFT_AUTO_FIELD.md +0 -176
- package/.tasks/SCHEMA_DEFINITION_FIELD.md +0 -250
- package/.tasks/SMART_EDITOR_CONTEXT_AND_POLISH.md +0 -340
- package/.tasks/SMART_EDITOR_LSP_FEATURES.md +0 -299
- package/.tasks/SMART_EDITOR_REVIEW_FOLLOWUPS.md +0 -280
- package/.tasks/SMART_EDITOR_UX_POLISH.md +0 -383
- package/.tasks/SMART_EDITOR_VISUAL_POLISH.md +0 -246
- package/.tasks/STORY_NETWORK_ISOLATION.md +0 -98
- package/.tasks/TEMPLATE_TOKEN_GRAMMAR.md +0 -72
- package/CODE_OF_CONDUCT.md +0 -105
- package/CONTRIBUTING.MD +0 -78
- package/SECURITY.md +0 -3
- package/chromatic.config.json +0 -5
- package/design/COMPACT_ENGINE_REDESIGN.md +0 -156
- package/design/COMPACT_INFO_DISPLAY.md +0 -87
- package/design/COMPACT_PARITY.md +0 -85
- package/design/EXPRESSION_BUILDER_REPORT_STRATEGY.md +0 -92
- package/design/FORM_ENGINE_COMPACT.md +0 -300
- package/design/FORM_ENGINE_COMPACT_UX_PLAN.md +0 -353
- package/design/FORM_ENGINE_EXPRESSIONS.md +0 -257
- package/design/FORM_ENGINE_FIELD_MIGRATION.md +0 -419
- package/design/IDE_INTEGRATION.md +0 -64
- package/design/RENDER_EXPRESSION_TRANSPORT.md +0 -156
- package/design/SELECT_DIALOG_FLOOR.md +0 -86
- package/design/SMART_EDITOR_UX.md +0 -438
- package/design/TRACKING.md +0 -290
- package/design/UNAVAILABLE_ALLOWED_VALUES.md +0 -226
- package/src/components/Description/index.tsx +0 -254
- package/src/components/Description/markdownRendererContext.tsx +0 -29
- package/src/components/FocusedEditing/index.tsx +0 -50
- package/src/components/codeSize/index.tsx +0 -79
- package/src/components/composer/Composer.stories.tsx +0 -238
- package/src/components/composer/Composer.tsx +0 -554
- package/src/components/composer/helpers.ts +0 -74
- package/src/components/composer/index.ts +0 -2
- package/src/components/dpqlEditor/DpqlEditor.stories.tsx +0 -1183
- package/src/components/dpqlEditor/DpqlEditor.tsx +0 -219
- package/src/components/dpqlEditor/dpqlHelpers.ts +0 -287
- package/src/components/dpqlEditor/dpqlInserter.ts +0 -121
- package/src/components/dpqlEditor/dpqlProbe.ts +0 -165
- package/src/components/dpqlEditor/dpqlTags.ts +0 -114
- package/src/components/dpqlEditor/index.ts +0 -41
- package/src/components/dpqlEditor/types.ts +0 -203
- package/src/components/dpqlEditor/useDpqlProbe.ts +0 -33
- package/src/components/dpqlEditor/useDpqlSession.ts +0 -411
- package/src/components/form/engine/CompactRow.tsx +0 -2620
- package/src/components/form/engine/CompactToolbar.tsx +0 -330
- package/src/components/form/engine/FormEngine.stories.tsx +0 -9920
- package/src/components/form/engine/FormEngine.tsx +0 -4569
- package/src/components/form/engine/FormEngineRemote.stories.tsx +0 -679
- package/src/components/form/engine/FormEngineStickyHeaders.stories.tsx +0 -331
- package/src/components/form/engine/FormFieldsSkeleton.tsx +0 -82
- package/src/components/form/engine/OptionFieldMessages.tsx +0 -477
- package/src/components/form/engine/OptionsHelpDialog.tsx +0 -29
- package/src/components/form/engine/__fixtures__/basicFormOptions.ts +0 -309
- package/src/components/form/engine/__fixtures__/fieldChromeOptions.ts +0 -45
- package/src/components/form/engine/_structuredData/SchemaDataView.stories.tsx +0 -233
- package/src/components/form/engine/_structuredData/SchemaDataView.tsx +0 -742
- package/src/components/form/engine/_structuredData/StructuredDataView.stories.tsx +0 -85
- package/src/components/form/engine/_structuredData/StructuredDataView.tsx +0 -75
- package/src/components/form/engine/_structuredData/structuredData.ts +0 -145
- package/src/components/form/engine/compactRowContext.ts +0 -148
- package/src/components/form/engine/compactRowStyles.ts +0 -898
- package/src/components/form/engine/compactToolbarContext.ts +0 -69
- package/src/components/form/engine/optionActions.ts +0 -128
- package/src/components/form/engine/optionsContext.ts +0 -24
- package/src/components/form/engine/readFirst.ts +0 -1077
- package/src/components/form/engine/rendererTypes.ts +0 -107
- package/src/components/form/engine/revealRow.ts +0 -123
- package/src/components/form/engine/rowFocus.ts +0 -101
- package/src/components/form/engine/rowMenuContext.ts +0 -159
- package/src/components/form/engine/rowOpenPicker.ts +0 -27
- package/src/components/form/engine/typeChoices.ts +0 -63
- package/src/components/form/engine/variants/FormEngineVariants.stories.tsx +0 -159
- package/src/components/form/engine/variants/VariantCalmTable.tsx +0 -244
- package/src/components/form/engine/variants/VariantCards.tsx +0 -212
- package/src/components/form/engine/variants/VariantFocus.tsx +0 -382
- package/src/components/form/engine/variants/VariantMinimal.tsx +0 -170
- package/src/components/form/engine/variants/focusDemo.ts +0 -145
- package/src/components/form/engine/variants/variantModel.ts +0 -223
- package/src/components/form/engine/variants/variantParts.tsx +0 -313
- package/src/components/form/expressions/DpqlRendering.tsx +0 -85
- package/src/components/form/expressions/ExpressionField.stories.tsx +0 -1395
- package/src/components/form/expressions/ExpressionField.tsx +0 -503
- package/src/components/form/expressions/argumentPresence.ts +0 -213
- package/src/components/form/expressions/builder/ExpressionBuilder.stories.tsx +0 -1683
- package/src/components/form/expressions/builder/argumentDetail.tsx +0 -17
- package/src/components/form/expressions/builder/argumentLabel.tsx +0 -146
- package/src/components/form/expressions/builder/argumentSlot.tsx +0 -101
- package/src/components/form/expressions/builder/argumentWrapper.tsx +0 -243
- package/src/components/form/expressions/builder/confirmMismatchedTypesModal.tsx +0 -120
- package/src/components/form/expressions/builder/confirmUnsupportedTypeModal.tsx +0 -69
- package/src/components/form/expressions/builder/index.tsx +0 -1545
- package/src/components/form/expressions/builder/item.tsx +0 -89
- package/src/components/form/expressions/builder/moveToPositionStrip.tsx +0 -156
- package/src/components/form/expressions/builder/renderTemplate.tsx +0 -42
- package/src/components/form/expressions/dpqlMockLanguage.ts +0 -566
- package/src/components/form/expressions/dpqlMockLsp.ts +0 -126
- package/src/components/form/expressions/mockExpressions.ts +0 -317
- package/src/components/form/expressions/renderExpressionToText.ts +0 -137
- package/src/components/form/expressions/types.ts +0 -110
- package/src/components/form/expressions/useExpressions.ts +0 -101
- package/src/components/form/expressions/useRenderExpression.ts +0 -165
- package/src/components/form/fields/Field.stories.tsx +0 -143
- package/src/components/form/fields/Field.tsx +0 -732
- package/src/components/form/fields/allowed-values/AllowedValues.tsx +0 -297
- package/src/components/form/fields/array/ArrayAuto.tsx +0 -237
- package/src/components/form/fields/array/ArrayAutoField.stories.tsx +0 -475
- package/src/components/form/fields/array/ArrayAutoField.tsx +0 -367
- package/src/components/form/fields/auto/AutoFormField.stories.tsx +0 -825
- package/src/components/form/fields/auto/AutoFormField.tsx +0 -1164
- package/src/components/form/fields/binary/Binary.stories.tsx +0 -122
- package/src/components/form/fields/binary/Binary.tsx +0 -91
- package/src/components/form/fields/boolean/Boolean.stories.tsx +0 -125
- package/src/components/form/fields/boolean/Boolean.tsx +0 -34
- package/src/components/form/fields/byte-size/ByteSize.stories.tsx +0 -87
- package/src/components/form/fields/byte-size/ByteSize.tsx +0 -58
- package/src/components/form/fields/color/Color.stories.tsx +0 -99
- package/src/components/form/fields/color/Color.tsx +0 -46
- package/src/components/form/fields/cron/Cron.stories.tsx +0 -68
- package/src/components/form/fields/cron/Cron.tsx +0 -80
- package/src/components/form/fields/date/Date.stories.tsx +0 -77
- package/src/components/form/fields/date/Date.tsx +0 -55
- package/src/components/form/fields/emittedValues.ts +0 -70
- package/src/components/form/fields/file/File.stories.tsx +0 -161
- package/src/components/form/fields/file/File.tsx +0 -227
- package/src/components/form/fields/long-string/LongString.stories.tsx +0 -120
- package/src/components/form/fields/long-string/LongString.tsx +0 -130
- package/src/components/form/fields/markdown/Markdown.stories.tsx +0 -76
- package/src/components/form/fields/markdown/Markdown.tsx +0 -81
- package/src/components/form/fields/markdown/MarkdownView.tsx +0 -222
- package/src/components/form/fields/multi-select/MultiSelectFormField.tsx +0 -139
- package/src/components/form/fields/number/Number.stories.tsx +0 -159
- package/src/components/form/fields/number/Number.tsx +0 -160
- package/src/components/form/fields/object/Object.stories.tsx +0 -398
- package/src/components/form/fields/object/Object.tsx +0 -255
- package/src/components/form/fields/radio-group/RadioGroup.stories.tsx +0 -95
- package/src/components/form/fields/radio-group/RadioGroup.tsx +0 -46
- package/src/components/form/fields/radio-group/images/java-96x128.png +0 -0
- package/src/components/form/fields/radio-group/images/python-129x128.png +0 -0
- package/src/components/form/fields/radio-group/images/qore-106x128.png +0 -0
- package/src/components/form/fields/rich-text/RichText.stories.tsx +0 -260
- package/src/components/form/fields/rich-text/RichText.tsx +0 -537
- package/src/components/form/fields/schema-definition/CatalogLeafForm.tsx +0 -242
- package/src/components/form/fields/schema-definition/CatalogNodeEditor.tsx +0 -758
- package/src/components/form/fields/schema-definition/Hint.tsx +0 -22
- package/src/components/form/fields/schema-definition/InlineValidationBanner.tsx +0 -138
- package/src/components/form/fields/schema-definition/Loader.tsx +0 -20
- package/src/components/form/fields/schema-definition/MigrationsTab.tsx +0 -187
- package/src/components/form/fields/schema-definition/SchemaDefinitionField.stories.tsx +0 -286
- package/src/components/form/fields/schema-definition/TableEditor.tsx +0 -155
- package/src/components/form/fields/schema-definition/TablesTab.tsx +0 -138
- package/src/components/form/fields/schema-definition/catalog.ts +0 -237
- package/src/components/form/fields/schema-definition/helpers.ts +0 -90
- package/src/components/form/fields/schema-definition/index.tsx +0 -418
- package/src/components/form/fields/schema-definition/mockCatalog.ts +0 -325
- package/src/components/form/fields/schema-definition/mockDefinition.ts +0 -111
- package/src/components/form/fields/schema-definition/referenceSuggestions.tsx +0 -152
- package/src/components/form/fields/schema-definition/starterTemplate.ts +0 -68
- package/src/components/form/fields/schema-definition/types.ts +0 -185
- package/src/components/form/fields/schema-definition/useSchemaOptionCatalog.ts +0 -49
- package/src/components/form/fields/select/Select.stories.tsx +0 -872
- package/src/components/form/fields/select/Select.tsx +0 -624
- package/src/components/form/fields/select/SelectCollection.tsx +0 -594
- package/src/components/form/fields/string/String.stories.tsx +0 -86
- package/src/components/form/fields/string/String.tsx +0 -43
- package/src/components/form/fields/template/ExampleValueModal.stories.tsx +0 -114
- package/src/components/form/fields/template/ExampleValueModal.tsx +0 -99
- package/src/components/form/fields/template/ReadOnlyTemplateTag.tsx +0 -47
- package/src/components/form/fields/template/TemplateField.stories.tsx +0 -1121
- package/src/components/form/fields/template/TemplateField.tsx +0 -1717
- package/src/components/form/fields/template/TemplateText.tsx +0 -115
- package/src/components/form/fields/template/__fixtures__/longExampleValue.ts +0 -7
- package/src/components/form/fields/template/__fixtures__/multiLevelTemplates.json +0 -147
- package/src/components/form/fields/template/__fixtures__/templates.json +0 -83
- package/src/components/form/fields/timeout/Timeout.stories.tsx +0 -228
- package/src/components/form/fields/timeout/Timeout.tsx +0 -87
- package/src/components/form/fields/url/Url.stories.tsx +0 -94
- package/src/components/form/fields/url/Url.tsx +0 -85
- package/src/components/form/index.tsx +0 -47
- package/src/components/imageLightbox/ImageLightbox.stories.tsx +0 -238
- package/src/components/imageLightbox/ImageLightbox.tsx +0 -236
- package/src/components/imageLightbox/index.ts +0 -1
- package/src/components/log/Log.stories.tsx +0 -333
- package/src/components/log/Log.tsx +0 -285
- package/src/components/menu/Menu.stories.tsx +0 -155
- package/src/components/menu/Menu.tsx +0 -312
- package/src/components/qonsoleSmartInput/QonsoleSmartInput.stories.tsx +0 -797
- package/src/components/qonsoleSmartInput/QonsoleSmartInput.tsx +0 -105
- package/src/components/qonsoleSmartInput/index.ts +0 -16
- package/src/components/qonsoleSmartInput/qonsoleInserter.ts +0 -77
- package/src/components/qonsoleSmartInput/types.ts +0 -133
- package/src/components/qonsoleSmartInput/useQonsoleSession.ts +0 -124
- package/src/components/searchFilterBar/SearchFilterBar.stories.tsx +0 -62
- package/src/components/searchFilterBar/SearchFilterBar.tsx +0 -144
- package/src/components/searchFilterBar/index.ts +0 -1
- package/src/components/smartEditor/MarkdownDoc.tsx +0 -190
- package/src/components/smartEditor/SmartEditor.stories.tsx +0 -475
- package/src/components/smartEditor/SmartEditor.tsx +0 -808
- package/src/components/smartEditor/__fixtures__/mockLspServer.ts +0 -205
- package/src/components/smartEditor/helpers.ts +0 -217
- package/src/components/smartEditor/index.ts +0 -35
- package/src/components/smartEditor/styling.ts +0 -45
- package/src/components/smartEditor/types.ts +0 -211
- package/src/components/smartEditor/useLspAutocomplete.ts +0 -758
- package/src/components/smartEditor/useLspDiagnosticDecorations.ts +0 -125
- package/src/components/smartEditor/useLspHover.ts +0 -230
- package/src/components/smartEditor/useLspSemanticTokens.ts +0 -298
- package/src/components/smartEditor/useLspSession.ts +0 -231
- package/src/components/smartEditor/useLspSignatureHelp.ts +0 -198
- package/src/components/supportTicket/AttachmentChips.stories.tsx +0 -171
- package/src/components/supportTicket/AttachmentChips.tsx +0 -147
- package/src/components/supportTicket/InterfaceReferenceTags.stories.tsx +0 -257
- package/src/components/supportTicket/InterfaceReferenceTags.tsx +0 -129
- package/src/components/supportTicket/ReferencePicker.stories.tsx +0 -584
- package/src/components/supportTicket/ReferencePicker.tsx +0 -563
- package/src/components/supportTicket/TicketConversation.stories.tsx +0 -121
- package/src/components/supportTicket/TicketHeader.stories.tsx +0 -183
- package/src/components/supportTicket/TicketHeader.tsx +0 -247
- package/src/components/supportTicket/TicketMetaTags.stories.tsx +0 -103
- package/src/components/supportTicket/TicketMetaTags.tsx +0 -85
- package/src/components/supportTicket/TicketReplyBox.stories.tsx +0 -354
- package/src/components/supportTicket/TicketReplyBox.tsx +0 -150
- package/src/components/supportTicket/__fixtures__/kindMarks.ts +0 -28
- package/src/components/supportTicket/attachmentAccess.ts +0 -97
- package/src/components/supportTicket/fileToAttachment.ts +0 -24
- package/src/components/supportTicket/index.ts +0 -10
- package/src/components/supportTicket/meta.ts +0 -206
- package/src/components/supportTicket/ticketModel.ts +0 -131
- package/src/components/supportTicket/useLoadedImages.ts +0 -73
- package/src/components/ticketReferences/TicketReferences.stories.tsx +0 -315
- package/src/components/ticketReferences/TicketReferences.tsx +0 -906
- package/src/components/ticketReferences/index.ts +0 -2
- package/src/components/ticketThread/TicketThread.stories.tsx +0 -829
- package/src/components/ticketThread/TicketThread.tsx +0 -719
- package/src/components/ticketThread/index.ts +0 -6
- package/src/contexts/FetchContext.tsx +0 -25
- package/src/contexts/ReqraftContext.tsx +0 -9
- package/src/contexts/StorageContext.tsx +0 -33
- package/src/global.d.ts +0 -4
- package/src/helpers/allowedValues.ts +0 -249
- package/src/helpers/choiceChip.ts +0 -227
- package/src/helpers/common.ts +0 -326
- package/src/helpers/dpqlDetection.ts +0 -209
- package/src/helpers/expressions.ts +0 -140
- package/src/helpers/optionUiTypes.ts +0 -199
- package/src/helpers/options.ts +0 -150
- package/src/helpers/providerValue.ts +0 -125
- package/src/helpers/scrollbar.ts +0 -32
- package/src/helpers/singleLineString.ts +0 -61
- package/src/helpers/templateItems.ts +0 -81
- package/src/helpers/templateText.ts +0 -350
- package/src/helpers/templates.ts +0 -602
- package/src/helpers/validations.ts +0 -2085
- package/src/hooks/useArgSchema.ts +0 -37
- package/src/hooks/useCoarsePointer.ts +0 -30
- package/src/hooks/useFetch/useFetch.stories.tsx +0 -379
- package/src/hooks/useFetch/useFetch.tsx +0 -154
- package/src/hooks/usePhoneViewport.ts +0 -34
- package/src/hooks/useQorusTypes.ts +0 -233
- package/src/hooks/useReqraftProperty.ts +0 -16
- package/src/hooks/useStorage/useStorage.stories.tsx +0 -168
- package/src/hooks/useStorage/useStorage.ts +0 -35
- package/src/hooks/useTemplates.ts +0 -123
- package/src/hooks/useValidation.ts +0 -9
- package/src/hooks/useWebSocket/useWebSocket.ts +0 -224
- package/src/hooks/useWebSocket/useWebsocket.stories.tsx +0 -640
- package/src/hooks/useWhyDidYouUpdate.ts +0 -38
- package/src/index.tsx +0 -86
- package/src/providers/FetchProvider.tsx +0 -40
- package/src/providers/ReqraftProvider.tsx +0 -52
- package/src/providers/StorageProvider.tsx +0 -131
- package/src/stores/currentUser/currentUser.stories.tsx +0 -100
- package/src/stores/currentUser/currentUser.tsx +0 -94
- package/src/stories/Data/fileFieldArgSchema.json +0 -86
- package/src/stories/Tests/utils.ts +0 -320
- package/src/stories/storyNetwork.ts +0 -92
- package/src/stories/tracking.tsx +0 -206
- package/src/tracking/browser/attach.ts +0 -186
- package/src/tracking/browser/env.ts +0 -78
- package/src/tracking/core/consent.ts +0 -37
- package/src/tracking/core/engagement.ts +0 -47
- package/src/tracking/core/experiments.ts +0 -258
- package/src/tracking/core/hash.ts +0 -26
- package/src/tracking/core/ids.ts +0 -25
- package/src/tracking/core/observable.ts +0 -23
- package/src/tracking/core/queue.ts +0 -131
- package/src/tracking/core/sections.ts +0 -166
- package/src/tracking/core/storage.ts +0 -69
- package/src/tracking/core/tracker.ts +0 -417
- package/src/tracking/core/types.ts +0 -162
- package/src/tracking/core/utm.ts +0 -23
- package/src/tracking/index.ts +0 -72
- package/src/tracking/markup.ts +0 -17
- package/src/tracking/react/Experiment.tsx +0 -44
- package/src/tracking/react/TrackingProvider.tsx +0 -56
- package/src/tracking/react/hooks.ts +0 -106
- package/src/tracking/react/index.ts +0 -13
- package/src/tracking/testing.ts +0 -108
- package/src/tracking/ui/ExperimentCard.stories.tsx +0 -296
- package/src/tracking/ui/ExperimentCard.tsx +0 -667
- package/src/tracking/ui/ExperimentsOverlay.stories.tsx +0 -155
- package/src/tracking/ui/ExperimentsOverlay.tsx +0 -437
- package/src/tracking/ui/anchor.ts +0 -180
- package/src/tracking/ui/card.ts +0 -464
- package/src/tracking/ui/client.ts +0 -117
- package/src/tracking/ui/index.ts +0 -77
- package/src/tracking/ui/types.ts +0 -110
- package/src/tracking/ui/useExperimentsAdmin.ts +0 -103
- package/src/types/Form.ts +0 -29
- package/src/types.ts +0 -14
- package/src/utils/datetime.ts +0 -10
- package/src/utils/fetch.ts +0 -457
- package/src/utils/lspClient.ts +0 -711
- package/src/utils/lspClient.types.ts +0 -211
- package/src/utils/queryUnlessCancelled.ts +0 -28
- package/src/utils/websocket.ts +0 -293
- package/vite.config.ts +0 -58
- package/vitest.config.ts +0 -69
|
@@ -1,1717 +0,0 @@
|
|
|
1
|
-
// Verbatim port of qorus-ide `src/components/Field/template.tsx` (774 LOC,
|
|
2
|
-
// FIELD_STACK_REPORT batch) — keep edits to the documented seams (leaf-API
|
|
3
|
-
// onChange adapters, the reqraft `useExpressions` signature, dropped
|
|
4
|
-
// SaveValueButton / useGetAppActionData). Full seam list:
|
|
5
|
-
// `.tasks/FIELD_STACK_REPORT.md`.
|
|
6
|
-
import {
|
|
7
|
-
ReqoreButton,
|
|
8
|
-
ReqoreControlGroup,
|
|
9
|
-
ReqoreDropdown,
|
|
10
|
-
ReqoreErrorBoundary,
|
|
11
|
-
ReqoreMenu,
|
|
12
|
-
ReqoreMenuItem,
|
|
13
|
-
ReqoreMenuSection,
|
|
14
|
-
ReqoreMessage,
|
|
15
|
-
ReqorePopover,
|
|
16
|
-
ReqoreSkeleton,
|
|
17
|
-
} from '@qoretechnologies/reqore';
|
|
18
|
-
import { IReqoreButtonProps } from '@qoretechnologies/reqore/dist/components/Button';
|
|
19
|
-
import { IReqoreDropdownProps } from '@qoretechnologies/reqore/dist/components/Dropdown';
|
|
20
|
-
import { IReqoreMenuItemProps } from '@qoretechnologies/reqore/dist/components/Menu/item';
|
|
21
|
-
import { IReqoreIconName } from '@qoretechnologies/reqore/dist/types/icons';
|
|
22
|
-
import ReqoreMenuDivider, {
|
|
23
|
-
IReqoreMenuDividerProps,
|
|
24
|
-
} from '@qoretechnologies/reqore/dist/components/Menu/divider';
|
|
25
|
-
import { IReqoreRichTextEditorProps } from '@qoretechnologies/reqore/dist/components/RichTextEditor';
|
|
26
|
-
import {
|
|
27
|
-
IReqoreFormTemplates,
|
|
28
|
-
IReqoreTextareaProps,
|
|
29
|
-
} from '@qoretechnologies/reqore/dist/components/Textarea';
|
|
30
|
-
import { IQorusFormFieldSchemaBase, TQorusType } from '@qoretechnologies/ts-toolkit';
|
|
31
|
-
import { size } from 'lodash';
|
|
32
|
-
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
33
|
-
import { useUpdateEffect } from 'react-use';
|
|
34
|
-
import {
|
|
35
|
-
filterTemplatesByType as templatesFilterFunc,
|
|
36
|
-
getTemplateKey,
|
|
37
|
-
getTemplateValue,
|
|
38
|
-
isBracedTemplateToken,
|
|
39
|
-
isCompleteTemplateToken,
|
|
40
|
-
describeTemplateReference,
|
|
41
|
-
isValueTemplate,
|
|
42
|
-
} from '../../../../helpers/templates';
|
|
43
|
-
import { classifyTypedText, mightBeDpqlExpression } from '../../../../helpers/dpqlDetection';
|
|
44
|
-
import {
|
|
45
|
-
renderTemplateItemDescriptions,
|
|
46
|
-
templateItemsToShow,
|
|
47
|
-
} from '../../../../helpers/templateItems';
|
|
48
|
-
import { useMarkdownRenderer } from '../../../Description/markdownRendererContext';
|
|
49
|
-
import { getTypeFromValue } from '../../../../helpers/validations';
|
|
50
|
-
import { useDpqlProbe } from '../../../dpqlEditor/useDpqlProbe';
|
|
51
|
-
import { useQorusTypes } from '../../../../hooks/useQorusTypes';
|
|
52
|
-
import { useWhyDidYouUpdate } from '../../../../hooks/useWhyDidYouUpdate';
|
|
53
|
-
import { ExpressionBuilder, IExpressionBuilderProps } from '../../expressions/builder';
|
|
54
|
-
// Direct import — the cycle (TemplateField → ExpressionField → builder →
|
|
55
|
-
// TemplateField) is render-time only, safe like the other Field cycles.
|
|
56
|
-
import { ExpressionField } from '../../expressions/ExpressionField';
|
|
57
|
-
import { IExpression, TExpressionReorder } from '../../expressions/types';
|
|
58
|
-
import { useExpressions } from '../../expressions/useExpressions';
|
|
59
|
-
import { AutoFormField as Auto, IQorusType as IQorusFormType } from '../auto/AutoFormField';
|
|
60
|
-
import BooleanFormField from '../boolean/Boolean';
|
|
61
|
-
import { DateFormField } from '../date/Date';
|
|
62
|
-
import { ReqraftFileFormField } from '../file/File';
|
|
63
|
-
import LongStringFormField from '../long-string/LongString';
|
|
64
|
-
import NumberFormField from '../number/Number';
|
|
65
|
-
import { ReadOnlyTemplateTag } from './ReadOnlyTemplateTag';
|
|
66
|
-
import { RichTextFormField } from '../rich-text/RichText';
|
|
67
|
-
import { richtextToString } from '../../../../helpers/common';
|
|
68
|
-
import { isSingleLineStringType } from '../../../../helpers/singleLineString';
|
|
69
|
-
import { isUntypedOptionType } from '../../../../helpers/optionUiTypes';
|
|
70
|
-
import {
|
|
71
|
-
IRowMenuRegistration,
|
|
72
|
-
RowMenuContext,
|
|
73
|
-
useRowMenu,
|
|
74
|
-
useRowMenuPublisher,
|
|
75
|
-
} from '../../engine/rowMenuContext';
|
|
76
|
-
|
|
77
|
-
// Re-export template utilities for consumers
|
|
78
|
-
export { getTemplateKey, getTemplateValue, isValueTemplate };
|
|
79
|
-
export type { IQorusFormType as IQorusType };
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* How long the author must pause before typed text is sent to the DPQL
|
|
83
|
-
* probe. Long enough that a probe is not sent for every prefix of what is
|
|
84
|
-
* being typed, short enough that the offer appears while they are still
|
|
85
|
-
* looking at the field.
|
|
86
|
-
*/
|
|
87
|
-
const DPQL_DETECT_DEBOUNCE_MS = 400;
|
|
88
|
-
|
|
89
|
-
export const TemplatesListProps: IReqoreDropdownProps = {
|
|
90
|
-
useTargetWidth: true,
|
|
91
|
-
handler: 'focus',
|
|
92
|
-
minWidth: '300px',
|
|
93
|
-
listCustomTheme: {
|
|
94
|
-
main: '#1e0d29',
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// IDE leaf-field modules take `onChange(name, value)` and a `name` prop;
|
|
99
|
-
// reqraft leaf fields are single-arg. These wrappers restore the IDE API for
|
|
100
|
-
// the ComponentMap (and the template-string editor below) so the ported
|
|
101
|
-
// markup stays verbatim. `type`/`level`/`allowTemplates` are destructured
|
|
102
|
-
// only to keep them off the underlying ReQore component / DOM.
|
|
103
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
104
|
-
// `type` is FORWARDED here, unlike the other wrappers below: the long-string
|
|
105
|
-
// field consumes it to decide whether it holds one line (a `string` does, a
|
|
106
|
-
// `long-string`, `hash` or `list` does not) and never spreads it to the DOM.
|
|
107
|
-
// Dropping it made every string field in every FormEngine form a growing
|
|
108
|
-
// textarea, so an alert rule's Internal Name took Enter.
|
|
109
|
-
const LongStringField = ({ name, onChange, type, level, allowTemplates, ...rest }: any) => (
|
|
110
|
-
<LongStringFormField
|
|
111
|
-
{...rest}
|
|
112
|
-
type={type}
|
|
113
|
-
onChange={(value: string) => onChange?.(name, value)}
|
|
114
|
-
/>
|
|
115
|
-
);
|
|
116
|
-
const Number = ({ name, onChange, type, level, allowTemplates, ...rest }: any) => (
|
|
117
|
-
<NumberFormField {...rest} onChange={(value: number | string) => onChange?.(name, value)} />
|
|
118
|
-
);
|
|
119
|
-
const BooleanField = ({ name, onChange, value, type, level, allowTemplates, ...rest }: any) => (
|
|
120
|
-
<BooleanFormField
|
|
121
|
-
{...rest}
|
|
122
|
-
checked={!!value}
|
|
123
|
-
onChange={(checked: boolean) => onChange?.(name, checked)}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
const DateField = ({ name, onChange, type, level, allowTemplates, ...rest }: any) => (
|
|
127
|
-
<DateFormField {...rest} onChange={(value: string) => onChange?.(name, value)} />
|
|
128
|
-
);
|
|
129
|
-
const RichTextField = ({ name, onChange, type, level, ...rest }: any) => (
|
|
130
|
-
<RichTextFormField {...rest} onChange={(value: any) => onChange?.(name, value)} />
|
|
131
|
-
);
|
|
132
|
-
const FileField = ({ name, onChange, type, level, allowTemplates, ...rest }: any) => (
|
|
133
|
-
<ReqraftFileFormField {...rest} onChange={(value: any) => onChange?.(name, value)} />
|
|
134
|
-
);
|
|
135
|
-
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
136
|
-
|
|
137
|
-
export interface ITemplateFieldProps extends Partial<
|
|
138
|
-
Omit<IQorusFormFieldSchemaBase, 'default_value'>
|
|
139
|
-
> {
|
|
140
|
-
value?: any;
|
|
141
|
-
name?: string;
|
|
142
|
-
uniqueName?: string;
|
|
143
|
-
label?: string;
|
|
144
|
-
onChange?: (name: string, value: any, type?: TQorusType, isFunction?: boolean) => void;
|
|
145
|
-
// React element
|
|
146
|
-
component?: React.FC<any>;
|
|
147
|
-
interfaceContext?: string;
|
|
148
|
-
allowTemplates?: boolean;
|
|
149
|
-
templates?: IReqoreTextareaProps['templates'];
|
|
150
|
-
componentFromType?: boolean;
|
|
151
|
-
allowCustomValues?: boolean;
|
|
152
|
-
allowFunctions?: boolean;
|
|
153
|
-
|
|
154
|
-
filterTemplatesByType?: boolean;
|
|
155
|
-
filterTemplatesFunc?: (templates: IReqoreFormTemplates) => IReqoreFormTemplates;
|
|
156
|
-
returnType?: TQorusType | IQorusFormType[];
|
|
157
|
-
level?: number;
|
|
158
|
-
className?: string;
|
|
159
|
-
|
|
160
|
-
isFunction?: boolean;
|
|
161
|
-
isDefaultFunction?: boolean;
|
|
162
|
-
isDefaultTemplate?: boolean;
|
|
163
|
-
menuItems?: TCustomTemplateItems;
|
|
164
|
-
/**
|
|
165
|
-
* SEAM (reqraft, additive): a collapsed section in the field's `⋮` menu,
|
|
166
|
-
* rendered before "Set Custom Value"; a row click closes the menu. The
|
|
167
|
-
* expression builder puts its operand reorder actions here.
|
|
168
|
-
*/
|
|
169
|
-
menuActions?: ITemplateMenuActions;
|
|
170
|
-
/**
|
|
171
|
-
* SEAM (reqraft, additive): rows appended at the end of the `⋮` menu, after
|
|
172
|
-
* a divider — where an operand's destructive action goes on a phone, whose
|
|
173
|
-
* row has no room for it inline. Clicking a row closes the menu.
|
|
174
|
-
*/
|
|
175
|
-
menuTrailingItems?: IReqoreMenuItemProps[];
|
|
176
|
-
/** SEAM (reqraft, additive): forwarded to a nested expression builder. */
|
|
177
|
-
reorder?: TExpressionReorder;
|
|
178
|
-
/**
|
|
179
|
-
* SEAM (reqraft, additive): render expression mode through the
|
|
180
|
-
* `ExpressionField` shell — Visual (the ported builder) + Text (the
|
|
181
|
-
* net-new DPQL editor) — instead of the IDE's bare builder. FormEngine
|
|
182
|
-
* turns this on for its (top-level) fields; nested operands (builder
|
|
183
|
-
* arguments, array items) never receive it and stay IDE-verbatim.
|
|
184
|
-
*/
|
|
185
|
-
allowTextExpressions?: boolean;
|
|
186
|
-
/**
|
|
187
|
-
* SEAM (reqraft): host-injected per-card actions for the expression editor
|
|
188
|
-
* this field renders in expression mode (the IDE's AI-assist button).
|
|
189
|
-
* Declared here — not left to the index signature — so it is destructured
|
|
190
|
-
* out of `rest` and never spread onto a leaf input.
|
|
191
|
-
*/
|
|
192
|
-
extraActions?: IExpressionBuilderProps['extraActions'];
|
|
193
|
-
/**
|
|
194
|
-
* SEAM (reqraft): the host's per-`ui_type` editors, forwarded to the field
|
|
195
|
-
* component and to the expression editor's operand rows. Declared here — not
|
|
196
|
-
* left to the index signature — for the same reason as `extraActions` above:
|
|
197
|
-
* so it is destructured out of `rest` and never spread onto a leaf input or a
|
|
198
|
-
* Reqore layout component, both of which pass unknown props to the DOM.
|
|
199
|
-
*/
|
|
200
|
-
componentOverrides?: Record<string, React.FC<any>>;
|
|
201
|
-
[key: string]: any;
|
|
202
|
-
default_value?: unknown;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
export const ComponentMap = {
|
|
206
|
-
string: LongStringField,
|
|
207
|
-
number: Number,
|
|
208
|
-
int: Number,
|
|
209
|
-
float: Number,
|
|
210
|
-
list: LongStringField,
|
|
211
|
-
hash: LongStringField,
|
|
212
|
-
binary: LongStringField,
|
|
213
|
-
bool: BooleanField,
|
|
214
|
-
boolean: BooleanField,
|
|
215
|
-
date: DateField,
|
|
216
|
-
richtext: RichTextField,
|
|
217
|
-
file: FileField,
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
export interface ITemplateDropdownSelectorProps extends IReqoreDropdownProps {
|
|
221
|
-
onRemoveClick?: IReqoreButtonProps['onClick'];
|
|
222
|
-
allowCustomValues?: boolean;
|
|
223
|
-
hasOnlyAllowedValues?: boolean;
|
|
224
|
-
templates?: IReqoreFormTemplates;
|
|
225
|
-
value?: string;
|
|
226
|
-
size?: IReqoreButtonProps['size'];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export type TCustomTemplateItems = (
|
|
230
|
-
| (Omit<IReqoreButtonProps, 'onClick'> & {
|
|
231
|
-
onClick?: (e?: React.MouseEvent<HTMLButtonElement>, removeTemplate?: () => void) => void;
|
|
232
|
-
})
|
|
233
|
-
| (IReqoreMenuDividerProps & { isDivider?: true })
|
|
234
|
-
)[];
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* The `menuActions` seam: a collapsed section of menu items, dividers, nested
|
|
238
|
-
* sections, or custom content — rendered with the popover's close callback so
|
|
239
|
-
* an inline control can shut the menu after acting.
|
|
240
|
-
*/
|
|
241
|
-
export interface ITemplateMenuActions {
|
|
242
|
-
label: string;
|
|
243
|
-
icon?: IReqoreIconName;
|
|
244
|
-
className?: string;
|
|
245
|
-
items: (
|
|
246
|
-
| IReqoreMenuItemProps
|
|
247
|
-
| (IReqoreMenuDividerProps & { isDivider: true })
|
|
248
|
-
| (ITemplateMenuActions & { isSection: true })
|
|
249
|
-
| { isCustom: true; content: (closePopover?: () => void) => React.ReactNode }
|
|
250
|
-
)[];
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const renderMenuActionRows = (
|
|
254
|
-
actions: ITemplateMenuActions,
|
|
255
|
-
closePopover: (() => void) | undefined,
|
|
256
|
-
size: IReqoreButtonProps['size']
|
|
257
|
-
): React.ReactNode =>
|
|
258
|
-
actions.items.map((item, index) => {
|
|
259
|
-
if ('isDivider' in item) {
|
|
260
|
-
return <ReqoreMenuDivider key={index} {...item} />;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if ('isCustom' in item) {
|
|
264
|
-
return <React.Fragment key={index}>{item.content(closePopover)}</React.Fragment>;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if ('isSection' in item) {
|
|
268
|
-
return (
|
|
269
|
-
<ReqoreMenuSection
|
|
270
|
-
key={index}
|
|
271
|
-
label={item.label}
|
|
272
|
-
icon={item.icon}
|
|
273
|
-
className={item.className}
|
|
274
|
-
isCollapsed
|
|
275
|
-
transparent
|
|
276
|
-
size={size}
|
|
277
|
-
>
|
|
278
|
-
{renderMenuActionRows(item, closePopover, size)}
|
|
279
|
-
</ReqoreMenuSection>
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// The menu hands its size to direct children only; rows inside a
|
|
284
|
-
// section get it from here, or they render at the default size next to
|
|
285
|
-
// rows that do not.
|
|
286
|
-
return (
|
|
287
|
-
<ReqoreMenuItem
|
|
288
|
-
size={size}
|
|
289
|
-
{...item}
|
|
290
|
-
key={index}
|
|
291
|
-
onClick={(event, itemId) => {
|
|
292
|
-
item.onClick?.(event, itemId, closePopover);
|
|
293
|
-
closePopover?.();
|
|
294
|
-
}}
|
|
295
|
-
/>
|
|
296
|
-
);
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
// The `menuTrailingItems` rows: last in the menu, behind a divider. A direct
|
|
300
|
-
// child of `ReqoreMenu` for the same reason as `MenuActionsSection` below.
|
|
301
|
-
const MenuTrailingItems = memo(
|
|
302
|
-
({
|
|
303
|
-
items,
|
|
304
|
-
closePopover,
|
|
305
|
-
size,
|
|
306
|
-
}: {
|
|
307
|
-
items: IReqoreMenuItemProps[];
|
|
308
|
-
closePopover?: () => void;
|
|
309
|
-
size?: IReqoreButtonProps['size'];
|
|
310
|
-
}) => (
|
|
311
|
-
<>
|
|
312
|
-
<ReqoreMenuDivider size={size} />
|
|
313
|
-
{items.map((item, index) => (
|
|
314
|
-
<ReqoreMenuItem
|
|
315
|
-
size={size}
|
|
316
|
-
{...item}
|
|
317
|
-
key={index}
|
|
318
|
-
onClick={(event, itemId) => {
|
|
319
|
-
item.onClick?.(event, itemId);
|
|
320
|
-
closePopover?.();
|
|
321
|
-
}}
|
|
322
|
-
/>
|
|
323
|
-
))}
|
|
324
|
-
</>
|
|
325
|
-
)
|
|
326
|
-
);
|
|
327
|
-
|
|
328
|
-
// A direct child of `ReqoreMenu`, like `CustomMenuItems`, so the menu hands it
|
|
329
|
-
// the popover's `closePopover` — a section does not pass it on to its rows.
|
|
330
|
-
const MenuActionsSection = memo(
|
|
331
|
-
({
|
|
332
|
-
actions,
|
|
333
|
-
closePopover,
|
|
334
|
-
size,
|
|
335
|
-
startExpanded,
|
|
336
|
-
...rest
|
|
337
|
-
}: {
|
|
338
|
-
actions: ITemplateMenuActions;
|
|
339
|
-
closePopover?: () => void;
|
|
340
|
-
size?: IReqoreButtonProps['size'];
|
|
341
|
-
/** @see `loneSectionStartsExpanded` — the menu's only group opens itself. */
|
|
342
|
-
startExpanded?: boolean;
|
|
343
|
-
}) => (
|
|
344
|
-
<ReqoreMenuSection
|
|
345
|
-
label={actions.label}
|
|
346
|
-
icon={actions.icon}
|
|
347
|
-
isCollapsed={!startExpanded}
|
|
348
|
-
transparent
|
|
349
|
-
className='template-menu-actions'
|
|
350
|
-
size={size}
|
|
351
|
-
{...rest}
|
|
352
|
-
>
|
|
353
|
-
{renderMenuActionRows(actions, closePopover, size)}
|
|
354
|
-
</ReqoreMenuSection>
|
|
355
|
-
)
|
|
356
|
-
);
|
|
357
|
-
|
|
358
|
-
export const CustomMenuItems = memo(
|
|
359
|
-
({
|
|
360
|
-
items,
|
|
361
|
-
closePopover,
|
|
362
|
-
setIsTemplate,
|
|
363
|
-
setTemplateValue,
|
|
364
|
-
startExpanded,
|
|
365
|
-
...rest
|
|
366
|
-
}: {
|
|
367
|
-
items: TCustomTemplateItems | undefined;
|
|
368
|
-
closePopover?: () => void;
|
|
369
|
-
setIsTemplate: React.Dispatch<React.SetStateAction<boolean>>;
|
|
370
|
-
setTemplateValue: React.Dispatch<React.SetStateAction<string | null>>;
|
|
371
|
-
/** @see `loneSectionStartsExpanded` — the menu's only group opens itself. */
|
|
372
|
-
startExpanded?: boolean;
|
|
373
|
-
}) => {
|
|
374
|
-
return (
|
|
375
|
-
<ReqoreMenuSection
|
|
376
|
-
label='Set Custom Value'
|
|
377
|
-
isCollapsed={!startExpanded}
|
|
378
|
-
transparent
|
|
379
|
-
icon='Text'
|
|
380
|
-
{...rest}
|
|
381
|
-
>
|
|
382
|
-
{items.map((menuItem, index) =>
|
|
383
|
-
'isDivider' in menuItem ?
|
|
384
|
-
<ReqoreMenuDivider key={index} {...menuItem} />
|
|
385
|
-
: <ReqoreButton
|
|
386
|
-
{...(rest as any)}
|
|
387
|
-
{...menuItem}
|
|
388
|
-
key={index}
|
|
389
|
-
onClick={(e) => {
|
|
390
|
-
(menuItem as any).onClick?.(e, () => {
|
|
391
|
-
setIsTemplate(false);
|
|
392
|
-
setTemplateValue(null);
|
|
393
|
-
closePopover?.();
|
|
394
|
-
});
|
|
395
|
-
}}
|
|
396
|
-
/>
|
|
397
|
-
)}
|
|
398
|
-
</ReqoreMenuSection>
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
);
|
|
402
|
-
|
|
403
|
-
export const TemplateDropdownSelector = memo(
|
|
404
|
-
({
|
|
405
|
-
onItemSelect,
|
|
406
|
-
onRemoveClick,
|
|
407
|
-
items,
|
|
408
|
-
templates,
|
|
409
|
-
allowCustomValues,
|
|
410
|
-
hasOnlyAllowedValues,
|
|
411
|
-
value,
|
|
412
|
-
size,
|
|
413
|
-
...rest
|
|
414
|
-
}: ITemplateDropdownSelectorProps) => {
|
|
415
|
-
/* The LAST hop before Reqore, which is the only place a drawn description
|
|
416
|
-
may be made: `filteredTemplates` upstream is a `JSON.stringify` memo key,
|
|
417
|
-
and an element in it throws on its own circular owner. */
|
|
418
|
-
const renderMarkdown = useMarkdownRenderer();
|
|
419
|
-
const shownItems = useMemo(
|
|
420
|
-
() => renderTemplateItemDescriptions(templateItemsToShow(items), renderMarkdown),
|
|
421
|
-
[items, renderMarkdown]
|
|
422
|
-
);
|
|
423
|
-
|
|
424
|
-
// One resolver for every surface that names a reference — the picker chip
|
|
425
|
-
// here, the read-only tag, and the compact row's expression summary. The
|
|
426
|
-
// row and this editor must agree: a reference that reads as its path when
|
|
427
|
-
// the row is closed cannot read as `$data:{…}` the moment it is opened.
|
|
428
|
-
const resolved = describeTemplateReference(templates, value);
|
|
429
|
-
const template = resolved.item;
|
|
430
|
-
const label = resolved.label || rest.label || 'Select Template';
|
|
431
|
-
const leftIconProps = useMemo(
|
|
432
|
-
(): IReqoreButtonProps['leftIconProps'] => ({
|
|
433
|
-
image: template?.metadata?.image,
|
|
434
|
-
icon: 'ExchangeDollarLine',
|
|
435
|
-
}),
|
|
436
|
-
[template]
|
|
437
|
-
);
|
|
438
|
-
// SEAM (reqraft): the IDE resolves the template's app/action via
|
|
439
|
-
// `useGetAppActionData` and renders the action's display name as a badge
|
|
440
|
-
// here — the app catalogue is IDE-only, so the badge is dropped.
|
|
441
|
-
|
|
442
|
-
return (
|
|
443
|
-
<ReqoreControlGroup vertical fluid>
|
|
444
|
-
{hasOnlyAllowedValues && (
|
|
445
|
-
<ReqoreMessage intent='warning' size='small' opaque={false}>
|
|
446
|
-
This field has pre-defined allowed values, make sure the template you select is
|
|
447
|
-
compatible with those
|
|
448
|
-
</ReqoreMessage>
|
|
449
|
-
)}
|
|
450
|
-
<ReqoreControlGroup stack>
|
|
451
|
-
<ReqoreDropdown
|
|
452
|
-
className='template-selector'
|
|
453
|
-
customTheme={TemplatesListProps.listCustomTheme}
|
|
454
|
-
minimal
|
|
455
|
-
compact
|
|
456
|
-
onItemSelect={onItemSelect}
|
|
457
|
-
items={shownItems}
|
|
458
|
-
label={label}
|
|
459
|
-
leftIconProps={leftIconProps}
|
|
460
|
-
caretPosition='right'
|
|
461
|
-
filterable
|
|
462
|
-
size={size}
|
|
463
|
-
{...TemplatesListProps}
|
|
464
|
-
/>
|
|
465
|
-
{allowCustomValues || value ?
|
|
466
|
-
<ReqoreButton
|
|
467
|
-
customTheme={TemplatesListProps.listCustomTheme}
|
|
468
|
-
fixed
|
|
469
|
-
icon='CloseLine'
|
|
470
|
-
tooltip='Remove template value'
|
|
471
|
-
minimal
|
|
472
|
-
className='template-remove'
|
|
473
|
-
compact
|
|
474
|
-
size={size}
|
|
475
|
-
onClick={onRemoveClick}
|
|
476
|
-
/>
|
|
477
|
-
: null}
|
|
478
|
-
</ReqoreControlGroup>
|
|
479
|
-
</ReqoreControlGroup>
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
);
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* `ui_type`s whose OWN editor renders templates as chips inline.
|
|
486
|
-
*
|
|
487
|
-
* For these the template SELECTOR must not take over: it replaces a control the
|
|
488
|
-
* author can type in with one they can only pick from. A Qorus test assertion's
|
|
489
|
-
* `Value` is the case this was written for — the IDE's own `auto.tsx` already
|
|
490
|
-
* renders it as template rich text (type freely, references become chips), and
|
|
491
|
-
* the same field reached through this form engine offered a dropdown and no way
|
|
492
|
-
* to type at all.
|
|
493
|
-
*
|
|
494
|
-
* `richtext` is reqraft's own; a consumer adds its types through the
|
|
495
|
-
* `templateAwareUiTypes` prop, exactly as it adds `rendererOnlyUiTypes`.
|
|
496
|
-
*/
|
|
497
|
-
export const BuiltInTemplateAwareUiTypes = ['richtext'];
|
|
498
|
-
|
|
499
|
-
export const isTemplateAwareUiType = (uiType?: string, extra?: string[]): boolean =>
|
|
500
|
-
!!uiType && [...BuiltInTemplateAwareUiTypes, ...(extra ?? [])].includes(uiType);
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* One entry of the "set a value of this type" menu an untyped field offers.
|
|
504
|
-
*
|
|
505
|
-
* `onClick` is typed by what the caller actually invokes it with — the chosen
|
|
506
|
-
* value and a reset callback — rather than as `Function`, which accepts a class
|
|
507
|
-
* declaration as readily as a handler and gives no help at the call site.
|
|
508
|
-
*/
|
|
509
|
-
interface IUntypedFieldMenuItem {
|
|
510
|
-
label?: unknown;
|
|
511
|
-
description?: unknown;
|
|
512
|
-
isDivider?: boolean;
|
|
513
|
-
onClick?: (value: unknown, reset: () => void) => void;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
const TemplateFieldImpl = memo(
|
|
517
|
-
({
|
|
518
|
-
rowMenu,
|
|
519
|
-
value,
|
|
520
|
-
name,
|
|
521
|
-
onChange,
|
|
522
|
-
component: Comp = Auto,
|
|
523
|
-
templates,
|
|
524
|
-
interfaceContext, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
525
|
-
allowTemplates = true,
|
|
526
|
-
allowFunctions,
|
|
527
|
-
allowTextExpressions,
|
|
528
|
-
extraActions,
|
|
529
|
-
componentOverrides,
|
|
530
|
-
allowCustomValues = true,
|
|
531
|
-
filterTemplatesByType = true,
|
|
532
|
-
filterTemplatesFunc,
|
|
533
|
-
componentFromType,
|
|
534
|
-
isFunction,
|
|
535
|
-
isDefaultFunction,
|
|
536
|
-
isDefaultTemplate,
|
|
537
|
-
returnType,
|
|
538
|
-
level,
|
|
539
|
-
className,
|
|
540
|
-
menuItems,
|
|
541
|
-
menuActions,
|
|
542
|
-
menuTrailingItems,
|
|
543
|
-
reorder,
|
|
544
|
-
label,
|
|
545
|
-
...rest
|
|
546
|
-
}: ITemplateFieldProps & { rowMenu?: IRowMenuRegistration }) => {
|
|
547
|
-
const qorusTypes = useQorusTypes();
|
|
548
|
-
const functions = useExpressions({
|
|
549
|
-
allow: !!allowFunctions,
|
|
550
|
-
expressionsUrl: rest.expressions_url,
|
|
551
|
-
extraExpressions: rest.expressions,
|
|
552
|
-
});
|
|
553
|
-
const type = rest.ui_type || rest.type || rest.defaultType;
|
|
554
|
-
|
|
555
|
-
/* The type an EXPRESSION must return, and is stored with, is a DATA type.
|
|
556
|
-
`type` above deliberately prefers `ui_type`, because that is what decides
|
|
557
|
-
which editor to render — but a ui_type says how a value is EDITED, not
|
|
558
|
-
what it is. The IDE's reference fields carry `ui_type: 'test-reference'`
|
|
559
|
-
(a rich-text editor that turns `$.` paths into chips), and feeding that
|
|
560
|
-
to the expression builder asked it for an expression RETURNING
|
|
561
|
-
`test-reference`: no expression returns one, so every choice was refused
|
|
562
|
-
with *"the expected return type is test-reference"*, and the ui_type was
|
|
563
|
-
then stored on the saved expression as its declared type.
|
|
564
|
-
|
|
565
|
-
The declared data type is the constraint; the ui_type is only a fallback
|
|
566
|
-
for a field that declares no type at all. */
|
|
567
|
-
const expressionDataType = rest.type || rest.defaultType || rest.ui_type;
|
|
568
|
-
|
|
569
|
-
const filteredTemplates = useMemo<IReqoreFormTemplates>(():
|
|
570
|
-
IReqoreFormTemplates | undefined => {
|
|
571
|
-
if (!allowTemplates) {
|
|
572
|
-
return undefined;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
let result: IReqoreFormTemplates = templates;
|
|
576
|
-
|
|
577
|
-
if (filterTemplatesByType) {
|
|
578
|
-
result = templatesFilterFunc(templates, type, !!rest.arg_schema);
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
if (filterTemplatesFunc) {
|
|
582
|
-
result = filterTemplatesFunc(result);
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
/* A lone category is opened, once, HERE — where this control resolves the
|
|
586
|
-
templates every one of its pickers then reads: the "Select Template"
|
|
587
|
-
dropdown, the in-editor `$` list, the numeric field's focus dropdown and
|
|
588
|
-
the expression builder's argument picker. Applying it per picker meant
|
|
589
|
-
each new one had to remember, and the ones that forgot made the author
|
|
590
|
-
click through a header naming the only category on offer to reach the
|
|
591
|
-
only values on offer.
|
|
592
|
-
|
|
593
|
-
LAST, after both filters. `filterTemplatesFunc` is given the grouped
|
|
594
|
-
shape on purpose — the Qog expression builder filters top-level items by
|
|
595
|
-
`metadata.dataRole`, which is a property of the CATEGORY — so flattening
|
|
596
|
-
before it would hand it values and quietly change what it keeps. This
|
|
597
|
-
only changes what is finally shown. */
|
|
598
|
-
return { ...result, items: templateItemsToShow(result?.items) };
|
|
599
|
-
}, [
|
|
600
|
-
JSON.stringify(templates),
|
|
601
|
-
type,
|
|
602
|
-
allowTemplates,
|
|
603
|
-
filterTemplatesByType,
|
|
604
|
-
JSON.stringify(rest.arg_schema),
|
|
605
|
-
filterTemplatesFunc,
|
|
606
|
-
]);
|
|
607
|
-
|
|
608
|
-
// An `any`-typed field has no editor of its own until a concrete type is
|
|
609
|
-
// chosen, so it opened on the TYPE PICKER: before an author could say what
|
|
610
|
-
// they meant, they had to answer a question about storage — "is this a Text
|
|
611
|
-
// or a Number?" — that they often cannot answer, because the value they
|
|
612
|
-
// want is a reference to something else whose type is not theirs to pick.
|
|
613
|
-
//
|
|
614
|
-
// So an untyped field that accepts templates now opens on the template
|
|
615
|
-
// selector, which is the answer most of them want, and "Set Custom Value"
|
|
616
|
-
// in the ⋮ menu is the way to a literal of a chosen type. That is the
|
|
617
|
-
// reverse of the old default, and it is the right way round: choosing a
|
|
618
|
-
// template is picking from a list, choosing a literal is a decision.
|
|
619
|
-
//
|
|
620
|
-
// Only while the field is EMPTY. A field already holding a literal must
|
|
621
|
-
// open showing that literal — flipping to the template view would hide a
|
|
622
|
-
// value the author put there and make it look lost.
|
|
623
|
-
//
|
|
624
|
-
// A field that may hold a custom value opens there whether or not templates
|
|
625
|
-
// are on offer, and whether or not they have ARRIVED: template mode gives it
|
|
626
|
-
// a typable editor, which offers the list once there is one. Waiting for the
|
|
627
|
-
// list decided the landing from data that is async — on a cold load the
|
|
628
|
-
// type-filtered list did not exist at mount, so the field fell to the type
|
|
629
|
-
// picker and stayed there. A pick-only field (no custom values) is in
|
|
630
|
-
// template mode regardless, by the `!allowCustomValues` term.
|
|
631
|
-
const typeIsAnyLike = isUntypedOptionType(type);
|
|
632
|
-
/* An EMPTY field, for the purpose of offering the template selector.
|
|
633
|
-
|
|
634
|
-
`null` is deliberately not empty. It is the DPQL null literal — a value
|
|
635
|
-
an author writes to say "this is nothing", and the only way to assert
|
|
636
|
-
that a call returned no value. Counted as emptiness here, an argument
|
|
637
|
-
holding it was treated as a field the author had just cleared: with a
|
|
638
|
-
type of `any` and templates on offer, the selector-restore effect below
|
|
639
|
-
flipped the field into template mode with a null template value, and
|
|
640
|
-
that reported the field as cleared — so writing `null` in the Text tab
|
|
641
|
-
and switching to Visual silently erased it, leaving `{type: "any"}` in
|
|
642
|
-
the draft and the message "Value for argument 1 ("any") is invalid:
|
|
643
|
-
Value is empty".
|
|
644
|
-
|
|
645
|
-
`undefined` is the cleared state; `null` is a value. Same rule as
|
|
646
|
-
`expressions/argumentPresence`, which states it canonically. */
|
|
647
|
-
const isEmptyValue = value === undefined || value === '';
|
|
648
|
-
const hasTemplatesOnOffer = !!size(filteredTemplates?.items);
|
|
649
|
-
/* The field's own editor already renders templates inline, so the selector
|
|
650
|
-
is not merely unnecessary here — it is a downgrade, swapping a typable
|
|
651
|
-
control for a pick-only one. Derived rather than folded into the state
|
|
652
|
-
below so every `setIsTemplate` path keeps working untouched; they simply
|
|
653
|
-
stop having anything to say for these fields. */
|
|
654
|
-
const editorHandlesTemplates =
|
|
655
|
-
!!allowTemplates && isTemplateAwareUiType(type as string, (rest as any).templateAwareUiTypes);
|
|
656
|
-
|
|
657
|
-
const hasOnlyAllowedValues = useMemo(
|
|
658
|
-
() => !!size(rest.allowed_values) && !rest.allowed_values_creatable,
|
|
659
|
-
[rest.allowed_values, rest.allowed_values_creatable]
|
|
660
|
-
);
|
|
661
|
-
|
|
662
|
-
/** Where this field lands when it is empty: an untyped one in template mode — see above. */
|
|
663
|
-
const emptyLandsOnTemplates =
|
|
664
|
-
typeIsAnyLike && (hasTemplatesOnOffer || (!!allowCustomValues && !hasOnlyAllowedValues));
|
|
665
|
-
const opensOnTemplates = isEmptyValue && emptyLandsOnTemplates;
|
|
666
|
-
|
|
667
|
-
const [isTemplateState, setIsTemplate] = useState<boolean>(
|
|
668
|
-
(isDefaultTemplate || isValueTemplate(value) || !allowCustomValues || opensOnTemplates) &&
|
|
669
|
-
allowTemplates
|
|
670
|
-
);
|
|
671
|
-
|
|
672
|
-
const isTemplate = editorHandlesTemplates ? false : isTemplateState;
|
|
673
|
-
const [internalIsFunction, setInternalIsFunction] = useState<boolean>(
|
|
674
|
-
!!isDefaultFunction && !!allowFunctions
|
|
675
|
-
);
|
|
676
|
-
const [templateValue, setTemplateValue] = useState<string | null>(value);
|
|
677
|
-
|
|
678
|
-
// Typed text that turned out to be an expression the author may accept.
|
|
679
|
-
const [dpqlOffer, setDpqlOffer] = useState<{ text: string; expression: any } | null>(null);
|
|
680
|
-
// The literal this field held before typed text switched it into
|
|
681
|
-
// expression mode — kept so the switch is undoable, and so the editor
|
|
682
|
-
// opens on the Text view the author was already writing in.
|
|
683
|
-
const [expressionFromText, setExpressionFromText] = useState<string | null>(null);
|
|
684
|
-
// Texts the author has said no to. Without this, dismissing an offer (or
|
|
685
|
-
// undoing a switch) would re-detect the same text on the next render and
|
|
686
|
-
// ask again forever.
|
|
687
|
-
const declinedTexts = useRef<Set<string>>(new Set());
|
|
688
|
-
const detectTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
689
|
-
const probeDpql = useDpqlProbe();
|
|
690
|
-
|
|
691
|
-
const effectiveIsFunction = isFunction || internalIsFunction;
|
|
692
|
-
|
|
693
|
-
useWhyDidYouUpdate(`Template field ${name}`, {
|
|
694
|
-
name,
|
|
695
|
-
onChange,
|
|
696
|
-
value,
|
|
697
|
-
...rest,
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
useEffect(() => {
|
|
701
|
-
if (isTemplate && isValueTemplate(value)) {
|
|
702
|
-
setTemplateValue(value);
|
|
703
|
-
}
|
|
704
|
-
}, [JSON.stringify(value)]);
|
|
705
|
-
|
|
706
|
-
/* Clearing an untyped field returns it to the template selector, which is
|
|
707
|
-
where mounting it empty already lands.
|
|
708
|
-
|
|
709
|
-
The rule above that opens an `any`-like field on the template selector is
|
|
710
|
-
a `useState` INITIALISER, so it only ever ran on mount. Clearing a value
|
|
711
|
-
in place does not remount anything, so the field fell through to the TYPE
|
|
712
|
-
picker and demanded `string`/`int`/`hash` before it would let the author
|
|
713
|
-
name a value they had already captured -- the very question that rule
|
|
714
|
-
exists to stop asking. Reloading the page fixed it, which is the tell:
|
|
715
|
-
same field, same empty value, different landing, because only one of the
|
|
716
|
-
two paths ran the rule.
|
|
717
|
-
|
|
718
|
-
Watched as a TRANSITION from a value to no value, not as "the value is
|
|
719
|
-
empty": an author who picks `Set Custom Value` on an empty field is
|
|
720
|
-
asking for the type picker, and re-asserting the template view on every
|
|
721
|
-
render while the field sat empty would take it away again immediately. */
|
|
722
|
-
const hadValue = useRef(!isEmptyValue);
|
|
723
|
-
/* A clear is REMEMBERED rather than acted on in the same render.
|
|
724
|
-
|
|
725
|
-
While the field holds a value its resolved type is that VALUE's type — a
|
|
726
|
-
reference reads as `test-reference`, not `auto` — and clearing reverts it
|
|
727
|
-
to the schema's `auto` one render LATER than the value empties. Acting
|
|
728
|
-
only on the transition therefore ran while `typeIsAnyLike` was still
|
|
729
|
-
false and did nothing, and by the time the type settled the transition
|
|
730
|
-
had passed. Measured in the live IDE at the moment of the clear:
|
|
731
|
-
`{ wasCleared: true, typeIsAnyLike: false, type: "test-reference",
|
|
732
|
-
hasTemplatesOnOffer: true }`, then `typeIsAnyLike: true` on the very next
|
|
733
|
-
render with `wasCleared` already false. */
|
|
734
|
-
const restoreSelectorWhenSettled = useRef(false);
|
|
735
|
-
/** Set by the template control's own `×`, which is an author saying "not a
|
|
736
|
-
* template" — that clear must not be answered with the selector again. */
|
|
737
|
-
const suppressSelectorRestore = useRef(false);
|
|
738
|
-
|
|
739
|
-
useEffect(() => {
|
|
740
|
-
if (hadValue.current && isEmptyValue) {
|
|
741
|
-
restoreSelectorWhenSettled.current = !suppressSelectorRestore.current;
|
|
742
|
-
suppressSelectorRestore.current = false;
|
|
743
|
-
}
|
|
744
|
-
if (!isEmptyValue) {
|
|
745
|
-
// A value arrived: whatever the author did, they are not sitting on an
|
|
746
|
-
// empty field waiting to be offered the list.
|
|
747
|
-
restoreSelectorWhenSettled.current = false;
|
|
748
|
-
}
|
|
749
|
-
hadValue.current = !isEmptyValue;
|
|
750
|
-
|
|
751
|
-
if (
|
|
752
|
-
restoreSelectorWhenSettled.current &&
|
|
753
|
-
opensOnTemplates &&
|
|
754
|
-
allowTemplates &&
|
|
755
|
-
!effectiveIsFunction
|
|
756
|
-
) {
|
|
757
|
-
restoreSelectorWhenSettled.current = false;
|
|
758
|
-
setTemplateValue(null);
|
|
759
|
-
setIsTemplate(true);
|
|
760
|
-
}
|
|
761
|
-
}, [isEmptyValue, opensOnTemplates, allowTemplates, effectiveIsFunction]);
|
|
762
|
-
|
|
763
|
-
useEffect(() => {
|
|
764
|
-
if (allowCustomValues && isTemplate && value && !isValueTemplate(value)) {
|
|
765
|
-
setIsTemplate(false);
|
|
766
|
-
}
|
|
767
|
-
}, [allowCustomValues]);
|
|
768
|
-
|
|
769
|
-
useEffect(() => {
|
|
770
|
-
if (!isTemplate && isValueTemplate(value) && allowTemplates) {
|
|
771
|
-
// In auto mode, leave user-typed dollar-strings alone ('$foo: hello'
|
|
772
|
-
// passes the loose check) — but a string that IS one well-formed token
|
|
773
|
-
// ($data:{…}, $config:item) must still flip into template mode, or an
|
|
774
|
-
// arg whose value hydrates after mount is stuck rendering raw text.
|
|
775
|
-
if (
|
|
776
|
-
type === 'auto' &&
|
|
777
|
-
getTypeFromValue(value) === 'string' &&
|
|
778
|
-
!isCompleteTemplateToken(value)
|
|
779
|
-
) {
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// A template reference with an OPERATOR on it (`$local:count + 1`) is
|
|
784
|
-
// an expression, not a template. The loose check above passes it —
|
|
785
|
-
// it starts with `$` and has a colon — so without this every such
|
|
786
|
-
// string was swallowed into template mode, where the arithmetic is
|
|
787
|
-
// dead text and no affordance can reach it. A token standing alone
|
|
788
|
-
// (`$local:count`, `$data:{1.field}`) has no operator and still
|
|
789
|
-
// flips, which is the case template mode is for.
|
|
790
|
-
if (!isCompleteTemplateToken(value) && mightBeDpqlExpression(value)) {
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
setIsTemplate(true);
|
|
795
|
-
setTemplateValue(value);
|
|
796
|
-
}
|
|
797
|
-
}, [JSON.stringify(value), allowTemplates]);
|
|
798
|
-
|
|
799
|
-
// When template key or template value change run the onChange function
|
|
800
|
-
useUpdateEffect(() => {
|
|
801
|
-
if (templateValue) {
|
|
802
|
-
onChange?.(name, templateValue, type as TQorusType, effectiveIsFunction);
|
|
803
|
-
}
|
|
804
|
-
}, [JSON.stringify(templateValue)]);
|
|
805
|
-
|
|
806
|
-
// an editor that takes templates into its own text has no template mode to switch to: "Use Template"
|
|
807
|
-
// there emptied the field and showed nothing in its place
|
|
808
|
-
const showTemplateToggle =
|
|
809
|
-
allowCustomValues && allowTemplates && !rest.arg_schema && !editorHandlesTemplates;
|
|
810
|
-
|
|
811
|
-
// Only a BRACED context ref (`$data:{…}` — machine-written, nobody types
|
|
812
|
-
// one) renders as the picker chip (named via `resolveTemplateLabel`)
|
|
813
|
-
// rather than as its raw text in a string editor. Plain word-path tokens
|
|
814
|
-
// (`$local:id`) are typeable, so per the build #123 review they keep the
|
|
815
|
-
// input that offers templates while typing. Mixed text-and-token strings
|
|
816
|
-
// keep the string editor too; the chip-in-editor treatment arrives with
|
|
817
|
-
// the rich-text string mode.
|
|
818
|
-
const templateValueIsBracedToken = isBracedTemplateToken(templateValue);
|
|
819
|
-
|
|
820
|
-
/* An UNTYPED field can be typed into as well as picked from.
|
|
821
|
-
|
|
822
|
-
Template mode has a typable editor whenever the field's type can hold
|
|
823
|
-
arbitrary text, and `any`/`auto` can — it is the type that has not been
|
|
824
|
-
narrowed yet, not a type that excludes text. Restricting this to
|
|
825
|
-
`string` meant an empty untyped field opened on template mode with no
|
|
826
|
-
editor to offer, so it fell through to the pick-only "Select Template"
|
|
827
|
-
dropdown: a control that can only choose from a list, on exactly the
|
|
828
|
-
fields where an author most often needs to write something the list
|
|
829
|
-
cannot hold — a deeper walk, a literal, or an expression.
|
|
830
|
-
|
|
831
|
-
Reported against a Qorus assertion's Expected Value, and it was never
|
|
832
|
-
specific to that field: every empty untyped field with templates on
|
|
833
|
-
offer got the same downgrade. The editor still offers the same templates
|
|
834
|
-
on focus, so nothing is lost by being able to type as well. */
|
|
835
|
-
const templateSupportsCustomValues =
|
|
836
|
-
allowCustomValues && (type === 'string' || typeIsAnyLike) && !hasOnlyAllowedValues;
|
|
837
|
-
const showTemplatesDropdown =
|
|
838
|
-
allowTemplates && (!allowCustomValues || (isTemplate && !templateSupportsCustomValues));
|
|
839
|
-
const hasOnlyExpressions = !allowCustomValues && !allowTemplates && allowFunctions;
|
|
840
|
-
// True when some input control renders besides the ⋮ menu. When nothing
|
|
841
|
-
// does (an empty `any` field: custom values are disallowed and the value's
|
|
842
|
-
// type is picked FROM the menu), the menu trigger is the field's only
|
|
843
|
-
// affordance and gets a label — a bare ⋮ alone reads as a broken editor.
|
|
844
|
-
const hasInputAffordance =
|
|
845
|
-
(!isTemplate && allowCustomValues) ||
|
|
846
|
-
(isTemplate && templateSupportsCustomValues) ||
|
|
847
|
-
showTemplatesDropdown;
|
|
848
|
-
|
|
849
|
-
const Component = componentFromType ? ComponentMap[type] : Comp;
|
|
850
|
-
// Only a ComponentMap component gets `type`: it is ours and CONSUMES the
|
|
851
|
-
// prop (the long-string field needs it to know whether it holds one line)
|
|
852
|
-
// rather than spreading it onto the DOM. A caller-supplied `Comp` is someone
|
|
853
|
-
// else's, which is why `type` was kept off this call in the first place.
|
|
854
|
-
const componentTypeProp = componentFromType ? { type } : {};
|
|
855
|
-
const fieldAriaLabel = rest['aria-label'] ?? label ?? rest.display_name ?? name;
|
|
856
|
-
|
|
857
|
-
const handleTemplateFieldChange = useCallback(
|
|
858
|
-
(_name: string, val: string) => {
|
|
859
|
-
if (!val) {
|
|
860
|
-
/* Emptying the text leaves the field where an empty field lands. For
|
|
861
|
-
an untyped field that is THIS editor: switching to custom mode here
|
|
862
|
-
mounted a different editor in its place, so deleting the last
|
|
863
|
-
character lost the cursor. */
|
|
864
|
-
if (!(emptyLandsOnTemplates && allowTemplates)) {
|
|
865
|
-
setIsTemplate(false);
|
|
866
|
-
}
|
|
867
|
-
setTemplateValue(null);
|
|
868
|
-
onChange(name, undefined);
|
|
869
|
-
} else {
|
|
870
|
-
setTemplateValue(val);
|
|
871
|
-
}
|
|
872
|
-
},
|
|
873
|
-
[name, onChange, emptyLandsOnTemplates, allowTemplates]
|
|
874
|
-
);
|
|
875
|
-
|
|
876
|
-
const handleTemplateTextChange = useCallback(
|
|
877
|
-
(val: unknown) => handleTemplateFieldChange(name, typeof val === 'string' ? val : ''),
|
|
878
|
-
[handleTemplateFieldChange, name]
|
|
879
|
-
);
|
|
880
|
-
|
|
881
|
-
const handleSelectTemplateFromList = useCallback(
|
|
882
|
-
// If the field has allowed values and supports templates, we do not want to overwrite the field type with the template type
|
|
883
|
-
(item) => {
|
|
884
|
-
// If the template type is richtext, we need to wrap the template value in the richtext template format
|
|
885
|
-
const value =
|
|
886
|
-
item.badge === 'richtext' ?
|
|
887
|
-
([
|
|
888
|
-
{
|
|
889
|
-
type: 'paragraph',
|
|
890
|
-
/* The empty text nodes on either side are load-bearing. A
|
|
891
|
-
chip is an inline VOID: it holds no text of its own, so the
|
|
892
|
-
only places a cursor can go are the text nodes AROUND it.
|
|
893
|
-
Slate treats that as an invariant and repairs it during
|
|
894
|
-
normalisation, which runs on edits but NOT on a document
|
|
895
|
-
handed in whole as a controlled value — which is what this
|
|
896
|
-
is. Without them the picked template renders as a chip that
|
|
897
|
-
cannot be typed after, so it can never be extended by hand. */
|
|
898
|
-
children: [
|
|
899
|
-
{ text: '' },
|
|
900
|
-
{
|
|
901
|
-
children: [{ text: '' }],
|
|
902
|
-
label: item.label,
|
|
903
|
-
type: 'tag',
|
|
904
|
-
value: item.value,
|
|
905
|
-
metadata: item.metadata,
|
|
906
|
-
},
|
|
907
|
-
{ text: '' },
|
|
908
|
-
],
|
|
909
|
-
},
|
|
910
|
-
] as IReqoreRichTextEditorProps['value'])
|
|
911
|
-
: item.value;
|
|
912
|
-
|
|
913
|
-
onChange(
|
|
914
|
-
name,
|
|
915
|
-
value,
|
|
916
|
-
hasOnlyAllowedValues ? (type as TQorusType) : (item.badge as TQorusType)
|
|
917
|
-
);
|
|
918
|
-
},
|
|
919
|
-
[name, onChange]
|
|
920
|
-
);
|
|
921
|
-
|
|
922
|
-
// SEAM (reqraft): the IDE computes `canSaveValue` here and renders a
|
|
923
|
-
// `SaveValueButton` in the controls menu — the saved-values storage is
|
|
924
|
-
// IDE-only, so the menu item is dropped (`allowSaving` is inert).
|
|
925
|
-
|
|
926
|
-
const handleRemoveTemplateClick = useCallback(() => {
|
|
927
|
-
/* This is the `×` ON the template control, and it means "I do not want a
|
|
928
|
-
template here" — on a field whose menu offers no `Set Custom Value` it
|
|
929
|
-
is the ONLY way to reach a literal. So it still drops to the custom
|
|
930
|
-
value editor, and it tells the empty-field rule below to keep its hands
|
|
931
|
-
off this particular clear: that rule watches the value going away, and
|
|
932
|
-
this handler clears the value too, so without the flag it would send
|
|
933
|
-
the author straight back to the selector they just dismissed. */
|
|
934
|
-
if (allowCustomValues) {
|
|
935
|
-
suppressSelectorRestore.current = true;
|
|
936
|
-
setIsTemplate(false);
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
setTemplateValue(null);
|
|
940
|
-
onChange?.(name, undefined);
|
|
941
|
-
}, [allowCustomValues, name, onChange]);
|
|
942
|
-
|
|
943
|
-
const handleSelectFunctionChange = useCallback(() => {
|
|
944
|
-
setInternalIsFunction(true);
|
|
945
|
-
setIsTemplate(false);
|
|
946
|
-
setTemplateValue(null);
|
|
947
|
-
|
|
948
|
-
let firstArg: IExpression;
|
|
949
|
-
|
|
950
|
-
if (type !== 'bool' && value !== undefined && value !== rest.default_value) {
|
|
951
|
-
firstArg = {
|
|
952
|
-
type: type as TQorusType,
|
|
953
|
-
value,
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
onChange?.(
|
|
958
|
-
name,
|
|
959
|
-
{
|
|
960
|
-
args: [firstArg],
|
|
961
|
-
},
|
|
962
|
-
undefined,
|
|
963
|
-
true
|
|
964
|
-
);
|
|
965
|
-
}, [
|
|
966
|
-
JSON.stringify(functions.expressions),
|
|
967
|
-
JSON.stringify(qorusTypes.value),
|
|
968
|
-
name,
|
|
969
|
-
onChange,
|
|
970
|
-
type,
|
|
971
|
-
value,
|
|
972
|
-
]);
|
|
973
|
-
|
|
974
|
-
/* Leaving template mode from the ⋮ — the counterpart of "Use Template".
|
|
975
|
-
Template mode's editor has no `×` of its own, so without this the author
|
|
976
|
-
who switched to a template had no way back and no menu to ask with. */
|
|
977
|
-
const handleUseCustomValueClick = useCallback(() => {
|
|
978
|
-
setIsTemplate(false);
|
|
979
|
-
/* A reference cannot stay in the custom editor: the field reads it as a
|
|
980
|
-
template again and switches straight back. Anything else is text the
|
|
981
|
-
author wrote, and it survives the switch. */
|
|
982
|
-
if (isValueTemplate(value as string) || isCompleteTemplateToken(templateValue)) {
|
|
983
|
-
/* Only where the value is actually cleared. The flag is read by the
|
|
984
|
-
"emptied" effect, which never runs when the text survives — setting
|
|
985
|
-
it unconditionally left it armed to swallow the NEXT genuine clear's
|
|
986
|
-
selector restore. */
|
|
987
|
-
suppressSelectorRestore.current = true;
|
|
988
|
-
setTemplateValue(null);
|
|
989
|
-
onChange?.(name, undefined);
|
|
990
|
-
}
|
|
991
|
-
}, [name, onChange, value, templateValue]);
|
|
992
|
-
|
|
993
|
-
const handleTemplateToggleClick = useCallback(() => {
|
|
994
|
-
setInternalIsFunction(false);
|
|
995
|
-
onChange(name, undefined, undefined, false);
|
|
996
|
-
setTemplateValue(null);
|
|
997
|
-
setIsTemplate(true);
|
|
998
|
-
}, [onChange, name]);
|
|
999
|
-
|
|
1000
|
-
const handleExpressionChange = useCallback(
|
|
1001
|
-
(expressionValue: IExpression | undefined, remove: boolean) => {
|
|
1002
|
-
if (remove) {
|
|
1003
|
-
setInternalIsFunction(false);
|
|
1004
|
-
// The expression is gone, so there is no longer a switch to undo.
|
|
1005
|
-
setExpressionFromText(null);
|
|
1006
|
-
}
|
|
1007
|
-
onChange(name, expressionValue?.value, expressionDataType as TQorusType, !remove);
|
|
1008
|
-
},
|
|
1009
|
-
[name, onChange, expressionDataType, value]
|
|
1010
|
-
);
|
|
1011
|
-
|
|
1012
|
-
// ─── Text typed into a plain field that is really a DPQL expression ───
|
|
1013
|
-
//
|
|
1014
|
-
// A field that accepts expressions still gets DPQL TYPED into it, in the
|
|
1015
|
-
// ordinary editor, by an author who never opened the expression view.
|
|
1016
|
-
// What happens then depends on the field's own type, and the asymmetry is
|
|
1017
|
-
// deliberate: text that could stand as a literal here is only ever
|
|
1018
|
-
// OFFERED, because silently rewriting the string `a + b` into a
|
|
1019
|
-
// concatenation would destroy a value the author meant. Text that could
|
|
1020
|
-
// NOT be a literal here was already an error the moment it was typed, so
|
|
1021
|
-
// switching costs nothing and explains the error.
|
|
1022
|
-
//
|
|
1023
|
-
// The server decides whether the text is an expression at all — see
|
|
1024
|
-
// `helpers/dpqlDetection` for why a successful parse alone means nothing.
|
|
1025
|
-
const validationField = useMemo(
|
|
1026
|
-
() => ({
|
|
1027
|
-
validation_regex: rest.validation_regex,
|
|
1028
|
-
has_to_be_valid_identifier: rest.has_to_be_valid_identifier,
|
|
1029
|
-
has_to_have_value: rest.has_to_have_value,
|
|
1030
|
-
rules: rest.rules,
|
|
1031
|
-
arg_schema: rest.arg_schema,
|
|
1032
|
-
}),
|
|
1033
|
-
[
|
|
1034
|
-
rest.validation_regex,
|
|
1035
|
-
rest.has_to_be_valid_identifier,
|
|
1036
|
-
rest.has_to_have_value,
|
|
1037
|
-
JSON.stringify(rest.rules),
|
|
1038
|
-
JSON.stringify(rest.arg_schema),
|
|
1039
|
-
]
|
|
1040
|
-
);
|
|
1041
|
-
|
|
1042
|
-
const enterExpressionFromText = useCallback(
|
|
1043
|
-
(text: string, expression: any) => {
|
|
1044
|
-
setDpqlOffer(null);
|
|
1045
|
-
setExpressionFromText(text);
|
|
1046
|
-
setInternalIsFunction(true);
|
|
1047
|
-
setIsTemplate(false);
|
|
1048
|
-
setTemplateValue(null);
|
|
1049
|
-
// `dpql/parse` answers with the field-ready envelope
|
|
1050
|
-
// (`{is_expression, value}`); this field stores the inner AST and
|
|
1051
|
-
// signals the flag through `onChange`'s fourth argument, exactly as
|
|
1052
|
-
// `handleExpressionChange` does.
|
|
1053
|
-
onChange?.(name, expression?.value ?? expression, expressionDataType as TQorusType, true);
|
|
1054
|
-
},
|
|
1055
|
-
[name, onChange, expressionDataType]
|
|
1056
|
-
);
|
|
1057
|
-
|
|
1058
|
-
const undoExpressionFromText = useCallback(() => {
|
|
1059
|
-
if (expressionFromText === null) {
|
|
1060
|
-
return;
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
declinedTexts.current.add(expressionFromText);
|
|
1064
|
-
setInternalIsFunction(false);
|
|
1065
|
-
setExpressionFromText(null);
|
|
1066
|
-
onChange?.(name, expressionFromText, type as TQorusType, false);
|
|
1067
|
-
}, [expressionFromText, name, onChange, type]);
|
|
1068
|
-
|
|
1069
|
-
const declineDpqlOffer = useCallback(() => {
|
|
1070
|
-
if (dpqlOffer) {
|
|
1071
|
-
declinedTexts.current.add(dpqlOffer.text);
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
setDpqlOffer(null);
|
|
1075
|
-
}, [dpqlOffer]);
|
|
1076
|
-
|
|
1077
|
-
const acceptDpqlOffer = useCallback(() => {
|
|
1078
|
-
if (dpqlOffer) {
|
|
1079
|
-
enterExpressionFromText(dpqlOffer.text, dpqlOffer.expression);
|
|
1080
|
-
}
|
|
1081
|
-
}, [dpqlOffer, enterExpressionFromText]);
|
|
1082
|
-
|
|
1083
|
-
// Held in a ref so the debounce below does not depend on it. `onChange`
|
|
1084
|
-
// comes from the host form and can be a fresh function on any render;
|
|
1085
|
-
// with the callback in the effect's deps, a re-render caused by a
|
|
1086
|
-
// DIFFERENT field would restart this field's timer, and a form the
|
|
1087
|
-
// author is typing in re-renders constantly.
|
|
1088
|
-
const enterExpressionRef = useRef(enterExpressionFromText);
|
|
1089
|
-
useEffect(() => {
|
|
1090
|
-
enterExpressionRef.current = enterExpressionFromText;
|
|
1091
|
-
}, [enterExpressionFromText]);
|
|
1092
|
-
|
|
1093
|
-
// Detection only runs on a field that could hold an expression and is
|
|
1094
|
-
// currently showing a plain editor — never on a read-only field, a
|
|
1095
|
-
// fixed-value list, or one already in template or expression mode.
|
|
1096
|
-
const canDetectDpql =
|
|
1097
|
-
!!allowFunctions &&
|
|
1098
|
-
!!allowTextExpressions &&
|
|
1099
|
-
!effectiveIsFunction &&
|
|
1100
|
-
!isTemplate &&
|
|
1101
|
-
!hasOnlyAllowedValues &&
|
|
1102
|
-
!rest.readonly &&
|
|
1103
|
-
!rest.readOnly &&
|
|
1104
|
-
!rest.disabled;
|
|
1105
|
-
|
|
1106
|
-
useEffect(() => {
|
|
1107
|
-
if (detectTimer.current) {
|
|
1108
|
-
clearTimeout(detectTimer.current);
|
|
1109
|
-
detectTimer.current = null;
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
/* A richtext field is still text. It hands its value back as a Slate
|
|
1113
|
-
DOCUMENT rather than a flattened string — deliberately, so a chosen
|
|
1114
|
-
reference cannot fuse with text typed beside it — and reading only
|
|
1115
|
-
`typeof value === 'string'` here silently switched detection off for
|
|
1116
|
-
every one of them the moment the field changed shape. A test
|
|
1117
|
-
assertion's Value is exactly that field, and `1 + 2` typed into it
|
|
1118
|
-
stopped being offered as an expression.
|
|
1119
|
-
|
|
1120
|
-
`richtextToString` flattens a tag to its raw value, so a document
|
|
1121
|
-
holding only a chosen reference reads as `$.result` — no operator, so
|
|
1122
|
-
`mightBeDpqlExpression` rejects it below and the server is never
|
|
1123
|
-
asked. */
|
|
1124
|
-
const text =
|
|
1125
|
-
typeof value === 'string' ? value
|
|
1126
|
-
: Array.isArray(value) ? richtextToString(value as never)
|
|
1127
|
-
: undefined;
|
|
1128
|
-
|
|
1129
|
-
if (
|
|
1130
|
-
!canDetectDpql ||
|
|
1131
|
-
!text ||
|
|
1132
|
-
declinedTexts.current.has(text) ||
|
|
1133
|
-
!mightBeDpqlExpression(text)
|
|
1134
|
-
) {
|
|
1135
|
-
setDpqlOffer(null);
|
|
1136
|
-
return undefined;
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
let cancelled = false;
|
|
1140
|
-
|
|
1141
|
-
detectTimer.current = setTimeout(() => {
|
|
1142
|
-
detectTimer.current = null;
|
|
1143
|
-
|
|
1144
|
-
void probeDpql(text)
|
|
1145
|
-
.then((parsed) => {
|
|
1146
|
-
if (cancelled) {
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
const outcome = classifyTypedText({ text, type, field: validationField, parsed });
|
|
1151
|
-
|
|
1152
|
-
if (outcome === 'switch') {
|
|
1153
|
-
enterExpressionRef.current(text, parsed.expression);
|
|
1154
|
-
} else if (outcome === 'offer') {
|
|
1155
|
-
setDpqlOffer({ text, expression: parsed.expression });
|
|
1156
|
-
} else {
|
|
1157
|
-
setDpqlOffer(null);
|
|
1158
|
-
}
|
|
1159
|
-
})
|
|
1160
|
-
.catch(() => {
|
|
1161
|
-
// Detection is an offer of help, never a reason for a field to
|
|
1162
|
-
// break: an unreachable instance or a classifier that threw leaves
|
|
1163
|
-
// the author's text exactly where they put it.
|
|
1164
|
-
if (!cancelled) {
|
|
1165
|
-
setDpqlOffer(null);
|
|
1166
|
-
}
|
|
1167
|
-
});
|
|
1168
|
-
}, DPQL_DETECT_DEBOUNCE_MS);
|
|
1169
|
-
|
|
1170
|
-
return () => {
|
|
1171
|
-
cancelled = true;
|
|
1172
|
-
|
|
1173
|
-
if (detectTimer.current) {
|
|
1174
|
-
clearTimeout(detectTimer.current);
|
|
1175
|
-
detectTimer.current = null;
|
|
1176
|
-
}
|
|
1177
|
-
};
|
|
1178
|
-
}, [value, canDetectDpql, type, validationField, probeDpql]);
|
|
1179
|
-
|
|
1180
|
-
const canOfferExpression =
|
|
1181
|
-
allowFunctions && !hasOnlyAllowedValues && !rest.readonly && !internalIsFunction;
|
|
1182
|
-
const canOfferTemplate = showTemplateToggle && !isTemplate;
|
|
1183
|
-
/* The way back out, published on the same terms the field's own ⋮ draws it.
|
|
1184
|
-
A field inside a form ROW draws no menu of its own — it publishes into
|
|
1185
|
-
the row's — so leaving this out of the published list meant template mode
|
|
1186
|
-
was a one-way door on the surface most options are edited from. */
|
|
1187
|
-
const canOfferCustomValue = showTemplateToggle && isTemplate && templateSupportsCustomValues;
|
|
1188
|
-
|
|
1189
|
-
const publishedItems = useMemo(
|
|
1190
|
-
() => [
|
|
1191
|
-
...(canOfferExpression && !functions.loading
|
|
1192
|
-
? [
|
|
1193
|
-
{
|
|
1194
|
-
label: 'Use Expression',
|
|
1195
|
-
icon: 'Functions' as const,
|
|
1196
|
-
tooltip: 'Run a function on this value',
|
|
1197
|
-
onClick: handleSelectFunctionChange,
|
|
1198
|
-
},
|
|
1199
|
-
]
|
|
1200
|
-
: []),
|
|
1201
|
-
...(canOfferTemplate
|
|
1202
|
-
? [
|
|
1203
|
-
{
|
|
1204
|
-
label: 'Use Template',
|
|
1205
|
-
icon: 'MoneyDollarCircleLine' as const,
|
|
1206
|
-
tooltip: 'Use a template',
|
|
1207
|
-
onClick: handleTemplateToggleClick,
|
|
1208
|
-
},
|
|
1209
|
-
]
|
|
1210
|
-
: []),
|
|
1211
|
-
...(canOfferCustomValue
|
|
1212
|
-
? [
|
|
1213
|
-
{
|
|
1214
|
-
label: 'Use Custom Value',
|
|
1215
|
-
icon: 'EditLine' as const,
|
|
1216
|
-
tooltip: 'Write the value here instead of choosing a template',
|
|
1217
|
-
onClick: handleUseCustomValueClick,
|
|
1218
|
-
},
|
|
1219
|
-
]
|
|
1220
|
-
: []),
|
|
1221
|
-
/* The "set a value of this type" choices an untyped field offers.
|
|
1222
|
-
Dividers are dropped: they grouped items in a menu this field drew
|
|
1223
|
-
itself, and in the row's shared menu they would divide other
|
|
1224
|
-
people's. */
|
|
1225
|
-
...((menuItems ?? []) as IUntypedFieldMenuItem[])
|
|
1226
|
-
.filter((item) => !('isDivider' in item))
|
|
1227
|
-
.map((item) => ({
|
|
1228
|
-
label: item.label as string,
|
|
1229
|
-
description: item.description as string | undefined,
|
|
1230
|
-
onClick: () =>
|
|
1231
|
-
item.onClick?.(undefined, () => {
|
|
1232
|
-
setIsTemplate(false);
|
|
1233
|
-
setTemplateValue(null);
|
|
1234
|
-
}),
|
|
1235
|
-
})),
|
|
1236
|
-
],
|
|
1237
|
-
[
|
|
1238
|
-
canOfferExpression,
|
|
1239
|
-
functions.loading,
|
|
1240
|
-
canOfferTemplate,
|
|
1241
|
-
canOfferCustomValue,
|
|
1242
|
-
menuItems,
|
|
1243
|
-
handleSelectFunctionChange,
|
|
1244
|
-
handleTemplateToggleClick,
|
|
1245
|
-
handleUseCustomValueClick,
|
|
1246
|
-
]
|
|
1247
|
-
);
|
|
1248
|
-
|
|
1249
|
-
/* Keyed on WHICH items are offered, never on the items: they carry
|
|
1250
|
-
handlers, so they are a new array every render and a row comparing them
|
|
1251
|
-
by value would loop. */
|
|
1252
|
-
const publishedKey = [
|
|
1253
|
-
canOfferExpression && !functions.loading ? 'expression' : '',
|
|
1254
|
-
canOfferTemplate ? 'template' : '',
|
|
1255
|
-
canOfferCustomValue ? 'custom-value' : '',
|
|
1256
|
-
`custom:${((menuItems ?? []) as { label?: unknown }[]).map((item) => String(item.label ?? '')).join('|')}`,
|
|
1257
|
-
].join(',');
|
|
1258
|
-
|
|
1259
|
-
useRowMenuPublisher(rowMenu, publishedKey, publishedItems as never);
|
|
1260
|
-
|
|
1261
|
-
const renderControls = useCallback(() => {
|
|
1262
|
-
const showFunctionsDropdown =
|
|
1263
|
-
allowFunctions && !hasOnlyAllowedValues && !rest.readonly && !internalIsFunction;
|
|
1264
|
-
const showTemplatesButton = showTemplateToggle && !isTemplate;
|
|
1265
|
-
// The way back out of template mode, where the editor draws no `×`.
|
|
1266
|
-
const showCustomValueButton = showTemplateToggle && isTemplate && templateSupportsCustomValues;
|
|
1267
|
-
// The "Set value" label promises a way to set one — reorder rows alone don't.
|
|
1268
|
-
const hasValueRows =
|
|
1269
|
-
showFunctionsDropdown || showTemplatesButton || showCustomValueButton || size(menuItems) > 0;
|
|
1270
|
-
|
|
1271
|
-
/* A lone group opens itself. Two of the menu's groups are collapsed
|
|
1272
|
-
sections, so a menu holding nothing but one of them asked for a click
|
|
1273
|
-
to reach the only thing on offer — on an untyped field, "Set Custom
|
|
1274
|
-
Value" hiding the type rows behind it. Expanded, it still names what
|
|
1275
|
-
its rows are and can still be collapsed. The same rule the template
|
|
1276
|
-
list follows for a lone category, and the row menu already publishes
|
|
1277
|
-
these rows flat. */
|
|
1278
|
-
const loneSectionStartsExpanded =
|
|
1279
|
-
[
|
|
1280
|
-
showFunctionsDropdown,
|
|
1281
|
-
showTemplatesButton,
|
|
1282
|
-
showCustomValueButton,
|
|
1283
|
-
size(menuActions?.items) > 0,
|
|
1284
|
-
size(menuItems) > 0,
|
|
1285
|
-
].filter(Boolean).length === 1;
|
|
1286
|
-
|
|
1287
|
-
/* ONE menu per control. Where this field sits in a form ROW, the row
|
|
1288
|
-
already renders a ⋮ of its own, and drawing a second one beside it
|
|
1289
|
-
put two menus of slightly different widths on the same control —
|
|
1290
|
-
with the type choices an `any` field offers hidden in the narrower
|
|
1291
|
-
one. The items are published to the row instead (see
|
|
1292
|
-
`rowMenuContext`); outside a row there is nothing to publish into,
|
|
1293
|
-
so the field goes on drawing its own. */
|
|
1294
|
-
if (rowMenu) {
|
|
1295
|
-
return null;
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
if (hasOnlyExpressions) {
|
|
1299
|
-
return (
|
|
1300
|
-
showFunctionsDropdown ?
|
|
1301
|
-
functions.loading ?
|
|
1302
|
-
<ReqoreSkeleton size={rest.size} />
|
|
1303
|
-
: <ReqoreButton
|
|
1304
|
-
compact
|
|
1305
|
-
minimal
|
|
1306
|
-
label='Create New Expression'
|
|
1307
|
-
className='function-selector'
|
|
1308
|
-
icon='Functions'
|
|
1309
|
-
tooltip='This field only accepts expressions'
|
|
1310
|
-
onClick={() => {
|
|
1311
|
-
setIsTemplate(false);
|
|
1312
|
-
setTemplateValue(null);
|
|
1313
|
-
onChange?.(
|
|
1314
|
-
name,
|
|
1315
|
-
{
|
|
1316
|
-
args: [],
|
|
1317
|
-
},
|
|
1318
|
-
undefined,
|
|
1319
|
-
true
|
|
1320
|
-
);
|
|
1321
|
-
}}
|
|
1322
|
-
/>
|
|
1323
|
-
: null
|
|
1324
|
-
);
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
if (hasValueRows || size(menuActions?.items) > 0 || size(menuTrailingItems) > 0) {
|
|
1328
|
-
return (
|
|
1329
|
-
<ReqorePopover
|
|
1330
|
-
component={ReqoreButton}
|
|
1331
|
-
closeOnTargetClick
|
|
1332
|
-
closeOnInsideClick={false}
|
|
1333
|
-
isReqoreComponent
|
|
1334
|
-
noWrapper
|
|
1335
|
-
noArrow
|
|
1336
|
-
placement='bottom-end'
|
|
1337
|
-
componentProps={
|
|
1338
|
-
{
|
|
1339
|
-
icon: 'More2Fill',
|
|
1340
|
-
className: 'template-more',
|
|
1341
|
-
compact: true,
|
|
1342
|
-
transparent: true,
|
|
1343
|
-
size: rest.size,
|
|
1344
|
-
fixed: true,
|
|
1345
|
-
/* Centre the trailing menu in its flex line so it lines up
|
|
1346
|
-
with sibling action buttons (reqore alignSelf; replaces a
|
|
1347
|
-
reqraft `align-self !important` override of this button).
|
|
1348
|
-
|
|
1349
|
-
Centring is only right beside a ONE-LINE editor. The
|
|
1350
|
-
expression shell is a toolbar with an editor, a type message
|
|
1351
|
-
and a preview stacked under it, so centring put this menu
|
|
1352
|
-
somewhere down the side of that block — level with nothing,
|
|
1353
|
-
over the editor, and a long way from the Undo it belongs
|
|
1354
|
-
beside. There it goes to the top, which is where the shell's
|
|
1355
|
-
own toolbar is. */
|
|
1356
|
-
alignSelf: effectiveIsFunction ? 'flex-start' : 'center',
|
|
1357
|
-
label: hasInputAffordance || !hasValueRows ? undefined : 'Set value',
|
|
1358
|
-
style:
|
|
1359
|
-
hasInputAffordance ?
|
|
1360
|
-
{
|
|
1361
|
-
paddingLeft: 0,
|
|
1362
|
-
paddingRight: 0,
|
|
1363
|
-
minWidth: '10px',
|
|
1364
|
-
}
|
|
1365
|
-
: undefined,
|
|
1366
|
-
effect: {
|
|
1367
|
-
gradient: {
|
|
1368
|
-
direction: 'to bottom right',
|
|
1369
|
-
colors: {
|
|
1370
|
-
0: '#444444',
|
|
1371
|
-
40: '#161616',
|
|
1372
|
-
60: '#161616',
|
|
1373
|
-
100: '#444444',
|
|
1374
|
-
},
|
|
1375
|
-
},
|
|
1376
|
-
},
|
|
1377
|
-
} as IReqoreButtonProps
|
|
1378
|
-
}
|
|
1379
|
-
handler='click'
|
|
1380
|
-
content={
|
|
1381
|
-
<ReqoreMenu size={rest.size} maxHeight='400px' style={{ overflow: 'auto' }}>
|
|
1382
|
-
{showFunctionsDropdown ?
|
|
1383
|
-
functions.loading ?
|
|
1384
|
-
<ReqoreSkeleton size={rest.size} />
|
|
1385
|
-
: <ReqoreButton
|
|
1386
|
-
compact
|
|
1387
|
-
transparent
|
|
1388
|
-
label='Use Expression'
|
|
1389
|
-
className='function-selector'
|
|
1390
|
-
icon='Functions'
|
|
1391
|
-
tooltip='Run a function on this value'
|
|
1392
|
-
onClick={handleSelectFunctionChange}
|
|
1393
|
-
/>
|
|
1394
|
-
|
|
1395
|
-
: null}
|
|
1396
|
-
|
|
1397
|
-
{showTemplatesButton ?
|
|
1398
|
-
<ReqoreButton
|
|
1399
|
-
transparent
|
|
1400
|
-
icon='MoneyDollarCircleLine'
|
|
1401
|
-
className='template-toggle'
|
|
1402
|
-
tooltip={'Use a template'}
|
|
1403
|
-
compact
|
|
1404
|
-
size={rest.size}
|
|
1405
|
-
onClick={handleTemplateToggleClick}
|
|
1406
|
-
>
|
|
1407
|
-
{' '}
|
|
1408
|
-
Use Template{' '}
|
|
1409
|
-
</ReqoreButton>
|
|
1410
|
-
: null}
|
|
1411
|
-
|
|
1412
|
-
{showCustomValueButton ?
|
|
1413
|
-
<ReqoreButton
|
|
1414
|
-
transparent
|
|
1415
|
-
icon='EditLine'
|
|
1416
|
-
className='template-custom-value'
|
|
1417
|
-
tooltip='Write the value here instead of choosing a template'
|
|
1418
|
-
compact
|
|
1419
|
-
size={rest.size}
|
|
1420
|
-
onClick={handleUseCustomValueClick}
|
|
1421
|
-
>
|
|
1422
|
-
{' '}
|
|
1423
|
-
Use Custom Value{' '}
|
|
1424
|
-
</ReqoreButton>
|
|
1425
|
-
: null}
|
|
1426
|
-
|
|
1427
|
-
{size(menuActions?.items) > 0 ?
|
|
1428
|
-
<MenuActionsSection
|
|
1429
|
-
actions={menuActions}
|
|
1430
|
-
size={rest.size}
|
|
1431
|
-
startExpanded={loneSectionStartsExpanded}
|
|
1432
|
-
/>
|
|
1433
|
-
: null}
|
|
1434
|
-
|
|
1435
|
-
{size(menuItems) > 0 ?
|
|
1436
|
-
<CustomMenuItems
|
|
1437
|
-
items={menuItems}
|
|
1438
|
-
setIsTemplate={setIsTemplate}
|
|
1439
|
-
setTemplateValue={setTemplateValue}
|
|
1440
|
-
startExpanded={loneSectionStartsExpanded}
|
|
1441
|
-
/>
|
|
1442
|
-
: null}
|
|
1443
|
-
|
|
1444
|
-
{size(menuTrailingItems) > 0 ?
|
|
1445
|
-
<MenuTrailingItems items={menuTrailingItems} size={rest.size} />
|
|
1446
|
-
: null}
|
|
1447
|
-
</ReqoreMenu>
|
|
1448
|
-
}
|
|
1449
|
-
/>
|
|
1450
|
-
);
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
return null;
|
|
1454
|
-
}, [
|
|
1455
|
-
allowFunctions,
|
|
1456
|
-
functions.expressions,
|
|
1457
|
-
handleSelectFunctionChange,
|
|
1458
|
-
handleTemplateToggleClick,
|
|
1459
|
-
handleUseCustomValueClick,
|
|
1460
|
-
hasOnlyAllowedValues,
|
|
1461
|
-
isTemplate,
|
|
1462
|
-
rest.readonly,
|
|
1463
|
-
rest.size,
|
|
1464
|
-
showTemplateToggle,
|
|
1465
|
-
// reaches the menu through `templateSupportsCustomValues`
|
|
1466
|
-
allowCustomValues,
|
|
1467
|
-
hasOnlyExpressions,
|
|
1468
|
-
type,
|
|
1469
|
-
value,
|
|
1470
|
-
menuItems,
|
|
1471
|
-
menuActions,
|
|
1472
|
-
menuTrailingItems,
|
|
1473
|
-
internalIsFunction,
|
|
1474
|
-
effectiveIsFunction,
|
|
1475
|
-
hasInputAffordance,
|
|
1476
|
-
// the row decides whether this field draws a menu at all
|
|
1477
|
-
rowMenu,
|
|
1478
|
-
]);
|
|
1479
|
-
|
|
1480
|
-
// When the type is a list, and it has an element type - that element type is different
|
|
1481
|
-
// from the field type, so we need to send down the full templates object
|
|
1482
|
-
// and the actual rendered field will filter it's own templates
|
|
1483
|
-
// This is a special case only for lists with element types
|
|
1484
|
-
/* `undefined` when nothing is on offer, rather than a list with no items:
|
|
1485
|
-
an editor given a list draws the control that opens it, so a field whose
|
|
1486
|
-
templates were all filtered out by type opened an EMPTY menu. */
|
|
1487
|
-
const componentTemplates = useMemo(() => {
|
|
1488
|
-
if (type === 'list' && (rest.ui_element_type || rest.element_type)) {
|
|
1489
|
-
return templates;
|
|
1490
|
-
}
|
|
1491
|
-
return size(filteredTemplates?.items) ?
|
|
1492
|
-
{
|
|
1493
|
-
...filteredTemplates,
|
|
1494
|
-
...TemplatesListProps,
|
|
1495
|
-
}
|
|
1496
|
-
: undefined;
|
|
1497
|
-
}, [
|
|
1498
|
-
JSON.stringify(filteredTemplates),
|
|
1499
|
-
// the list-with-element-type branch hands this back untouched
|
|
1500
|
-
templates,
|
|
1501
|
-
rest.ui_element_type,
|
|
1502
|
-
rest.element_type,
|
|
1503
|
-
type,
|
|
1504
|
-
]);
|
|
1505
|
-
|
|
1506
|
-
if (effectiveIsFunction && !hasOnlyAllowedValues) {
|
|
1507
|
-
// SEAM (reqraft): `allowTextExpressions` swaps the IDE's bare builder
|
|
1508
|
-
// for the ExpressionField shell (Visual = the same builder, Text = the
|
|
1509
|
-
// DPQL editor). `handleExpressionChange` serves both — the shell emits
|
|
1510
|
-
// the identical `({ is_expression, value }, remove)` contract.
|
|
1511
|
-
if (allowTextExpressions) {
|
|
1512
|
-
return (
|
|
1513
|
-
<ReqoreControlGroup>
|
|
1514
|
-
<ReqoreErrorBoundary>
|
|
1515
|
-
<ExpressionField
|
|
1516
|
-
value={{
|
|
1517
|
-
is_expression: true,
|
|
1518
|
-
value,
|
|
1519
|
-
}}
|
|
1520
|
-
// The host's per-ui_type editors reach this field through the
|
|
1521
|
-
// rest-spread; the expression shell needs them explicitly or the
|
|
1522
|
-
// builder's operands render "Unknown type!" for any consumer
|
|
1523
|
-
// ui_type (an assertion's `test-reference` Value, for one).
|
|
1524
|
-
componentOverrides={componentOverrides}
|
|
1525
|
-
localTemplates={templates}
|
|
1526
|
-
type={type as string}
|
|
1527
|
-
returnType={(returnType || expressionDataType) as any}
|
|
1528
|
-
onChange={handleExpressionChange}
|
|
1529
|
-
readOnly={rest.readOnly || rest.disabled}
|
|
1530
|
-
expressions={rest.expressions}
|
|
1531
|
-
expressionsUrl={rest.expressions_url}
|
|
1532
|
-
// the record's fields for the Text view, from the field's schema (`dpql_fields`)
|
|
1533
|
-
fields={rest.dpql_fields}
|
|
1534
|
-
serverHandled={rest.server_expression_handling}
|
|
1535
|
-
extraActions={extraActions}
|
|
1536
|
-
size={rest.size}
|
|
1537
|
-
// An author who typed the expression as text is already
|
|
1538
|
-
// writing in that language — dropping them into the visual
|
|
1539
|
-
// builder would make them find their own sentence again.
|
|
1540
|
-
defaultMode={expressionFromText !== null ? 'text' : 'visual'}
|
|
1541
|
-
reorder={reorder}
|
|
1542
|
-
/>
|
|
1543
|
-
</ReqoreErrorBoundary>
|
|
1544
|
-
{expressionFromText !== null ?
|
|
1545
|
-
<ReqoreButton
|
|
1546
|
-
fixed
|
|
1547
|
-
compact
|
|
1548
|
-
minimal
|
|
1549
|
-
icon='ArrowGoBackLine'
|
|
1550
|
-
// No `intent` with `minimal`: a Reqore intent is a FILL, and
|
|
1551
|
-
// `muted` as TEXT is 1.3:1 on the app surface.
|
|
1552
|
-
size={rest.size}
|
|
1553
|
-
className='dpql-detected-undo'
|
|
1554
|
-
tooltip={`Keep "${expressionFromText}" as plain text instead`}
|
|
1555
|
-
onClick={undoExpressionFromText}
|
|
1556
|
-
>
|
|
1557
|
-
Undo
|
|
1558
|
-
</ReqoreButton>
|
|
1559
|
-
: null}
|
|
1560
|
-
{renderControls()}
|
|
1561
|
-
</ReqoreControlGroup>
|
|
1562
|
-
);
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
return (
|
|
1566
|
-
<ReqoreControlGroup>
|
|
1567
|
-
<ReqoreErrorBoundary>
|
|
1568
|
-
<ExpressionBuilder
|
|
1569
|
-
value={{
|
|
1570
|
-
is_expression: true,
|
|
1571
|
-
value,
|
|
1572
|
-
}}
|
|
1573
|
-
componentOverrides={componentOverrides}
|
|
1574
|
-
localTemplates={templates}
|
|
1575
|
-
level={level}
|
|
1576
|
-
type={type as string}
|
|
1577
|
-
returnType={(returnType || expressionDataType) as any}
|
|
1578
|
-
onChange={handleExpressionChange}
|
|
1579
|
-
readOnly={rest.readOnly || rest.disabled}
|
|
1580
|
-
expressions={rest.expressions}
|
|
1581
|
-
expressionsUrl={rest.expressions_url}
|
|
1582
|
-
serverHandled={rest.server_expression_handling}
|
|
1583
|
-
extraActions={extraActions}
|
|
1584
|
-
reorder={reorder}
|
|
1585
|
-
/>
|
|
1586
|
-
</ReqoreErrorBoundary>
|
|
1587
|
-
{renderControls()}
|
|
1588
|
-
</ReqoreControlGroup>
|
|
1589
|
-
);
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
if (rest.disabled) {
|
|
1593
|
-
if (isTemplate) {
|
|
1594
|
-
// SEAM (reqraft): the IDE renders a bare `<ReqoreTag label={templateValue}/>`
|
|
1595
|
-
// here; reqraft upgrades the read-only template to a proper picker chip —
|
|
1596
|
-
// the $-dollar icon + resolved display name + app image, coloured by the
|
|
1597
|
-
// IDE's intent scheme. Shared with the compact read-first row.
|
|
1598
|
-
return <ReadOnlyTemplateTag value={templateValue} templates={templates} size={rest.size} />;
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
return (
|
|
1602
|
-
<Comp
|
|
1603
|
-
value={value}
|
|
1604
|
-
onChange={onChange}
|
|
1605
|
-
name={name}
|
|
1606
|
-
{...rest}
|
|
1607
|
-
componentOverrides={componentOverrides}
|
|
1608
|
-
/>
|
|
1609
|
-
);
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
return (
|
|
1613
|
-
<ReqoreControlGroup
|
|
1614
|
-
fluid={rest.fluid}
|
|
1615
|
-
fixed={rest.fixed}
|
|
1616
|
-
size={rest.size}
|
|
1617
|
-
{...rest}
|
|
1618
|
-
stack={false}
|
|
1619
|
-
verticalAlign='flex-start'
|
|
1620
|
-
>
|
|
1621
|
-
{!isTemplate && allowCustomValues ?
|
|
1622
|
-
<Component
|
|
1623
|
-
value={value}
|
|
1624
|
-
allowTemplates={allowTemplates}
|
|
1625
|
-
onChange={onChange}
|
|
1626
|
-
name={name}
|
|
1627
|
-
level={level}
|
|
1628
|
-
{...rest}
|
|
1629
|
-
componentOverrides={componentOverrides}
|
|
1630
|
-
{...componentTypeProp}
|
|
1631
|
-
aria-label={fieldAriaLabel}
|
|
1632
|
-
className={`${className} template-selector`}
|
|
1633
|
-
templates={componentTemplates}
|
|
1634
|
-
/>
|
|
1635
|
-
: null}
|
|
1636
|
-
|
|
1637
|
-
{/* Template mode's editor for a value that can also be typed: each
|
|
1638
|
-
reference in it is a chip named as the catalogue names it, while the
|
|
1639
|
-
field still stores the plain string. A textarea spelled a chosen
|
|
1640
|
-
template `$local:name` wherever it was edited — in the Visual
|
|
1641
|
-
builder's operands, in every string field that takes templates. */}
|
|
1642
|
-
{isTemplate && templateSupportsCustomValues && !templateValueIsBracedToken ?
|
|
1643
|
-
<RichTextFormField
|
|
1644
|
-
className='template-selector'
|
|
1645
|
-
valueFormat='text'
|
|
1646
|
-
singleLine={isSingleLineStringType('string')}
|
|
1647
|
-
value={typeof templateValue === 'string' ? templateValue : ''}
|
|
1648
|
-
templates={filteredTemplates}
|
|
1649
|
-
allowTemplates
|
|
1650
|
-
onChange={handleTemplateTextChange}
|
|
1651
|
-
{...rest}
|
|
1652
|
-
aria-label={fieldAriaLabel}
|
|
1653
|
-
/>
|
|
1654
|
-
: null}
|
|
1655
|
-
|
|
1656
|
-
{dpqlOffer ?
|
|
1657
|
-
<ReqoreControlGroup fixed stack size={rest.size}>
|
|
1658
|
-
<ReqoreButton
|
|
1659
|
-
compact
|
|
1660
|
-
icon='Functions'
|
|
1661
|
-
intent='info'
|
|
1662
|
-
className='dpql-detected-offer'
|
|
1663
|
-
tooltip={`"${dpqlOffer.text}" reads as an expression. It is also valid text here, so nothing has been changed — use it as an expression?`}
|
|
1664
|
-
onClick={acceptDpqlOffer}
|
|
1665
|
-
>
|
|
1666
|
-
Use as expression
|
|
1667
|
-
</ReqoreButton>
|
|
1668
|
-
<ReqoreButton
|
|
1669
|
-
compact
|
|
1670
|
-
icon='CloseLine'
|
|
1671
|
-
intent='info'
|
|
1672
|
-
className='dpql-detected-dismiss'
|
|
1673
|
-
tooltip='Keep it as plain text'
|
|
1674
|
-
onClick={declineDpqlOffer}
|
|
1675
|
-
/>
|
|
1676
|
-
</ReqoreControlGroup>
|
|
1677
|
-
: null}
|
|
1678
|
-
|
|
1679
|
-
{(
|
|
1680
|
-
showTemplatesDropdown ||
|
|
1681
|
-
(isTemplate && templateSupportsCustomValues && templateValueIsBracedToken)
|
|
1682
|
-
) ?
|
|
1683
|
-
<TemplateDropdownSelector
|
|
1684
|
-
allowCustomValues={allowCustomValues}
|
|
1685
|
-
templates={templates}
|
|
1686
|
-
value={templateValue}
|
|
1687
|
-
items={filteredTemplates?.items}
|
|
1688
|
-
onItemSelect={handleSelectTemplateFromList}
|
|
1689
|
-
onRemoveClick={handleRemoveTemplateClick}
|
|
1690
|
-
size={rest.size}
|
|
1691
|
-
label={label}
|
|
1692
|
-
hasOnlyAllowedValues={hasOnlyAllowedValues}
|
|
1693
|
-
/>
|
|
1694
|
-
: null}
|
|
1695
|
-
|
|
1696
|
-
{renderControls()}
|
|
1697
|
-
</ReqoreControlGroup>
|
|
1698
|
-
);
|
|
1699
|
-
}
|
|
1700
|
-
);
|
|
1701
|
-
|
|
1702
|
-
/**
|
|
1703
|
-
* The row channel belongs to the row's OWN editor: this field. It is read here
|
|
1704
|
-
* and hidden from everything this field renders, so a field nested inside it —
|
|
1705
|
-
* an expression operand, a list item — keeps drawing its own menu instead of
|
|
1706
|
-
* publishing actions into a row menu that cannot say which value they act on.
|
|
1707
|
-
* `undefined` outside a row, where this field draws its own menu too.
|
|
1708
|
-
*/
|
|
1709
|
-
export const TemplateField = memo((props: ITemplateFieldProps) => {
|
|
1710
|
-
const rowMenu = useRowMenu();
|
|
1711
|
-
|
|
1712
|
-
return (
|
|
1713
|
-
<RowMenuContext.Provider value={undefined}>
|
|
1714
|
-
<TemplateFieldImpl {...props} rowMenu={rowMenu} />
|
|
1715
|
-
</RowMenuContext.Provider>
|
|
1716
|
-
);
|
|
1717
|
-
});
|