@morscherlab/mint-sdk 1.0.0-rc.4 → 1.0.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/components/AppTopBar.navigation.test.d.ts +1 -0
- package/dist/__tests__/components/DoseCalculatorVolumeField.test.d.ts +1 -0
- package/dist/__tests__/components/PlateMapEditorToolbarInternal.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.controls.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.navigation.test.d.ts +1 -0
- package/dist/__tests__/components/PluginWorkspaceView.shell.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStep.presentation.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStepEditor.state.test.d.ts +1 -0
- package/dist/__tests__/components/ProtocolStepParameterField.test.d.ts +1 -0
- package/dist/__tests__/components/ReagentList.presentation.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.colors.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.drag.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.groups.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelector.selection.test.d.ts +1 -0
- package/dist/__tests__/components/SampleSelectorSampleRow.test.d.ts +1 -0
- package/dist/__tests__/components/ScheduleCalendar.test.d.ts +1 -0
- package/dist/__tests__/components/SettingsModal.schema.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.colors.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.conditions.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.geometry.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.interaction.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.legend.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.rendering.test.d.ts +1 -0
- package/dist/__tests__/components/WellPlate.sampleDrop.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/classify.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/columns.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/compose.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/cooccurrence.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/fingerprint.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/integration.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/template.test.d.ts +1 -0
- package/dist/__tests__/composables/autoGroup/tokenize.test.d.ts +1 -0
- package/dist/__tests__/composables/useAutoGroupInputSources.test.d.ts +1 -0
- package/dist/__tests__/composables/useScheduleCalendarLayout.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsComponents.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsExports.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsParsing.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +1 -0
- package/dist/__tests__/docs/extractDocsTheme.test.d.ts +1 -0
- package/dist/components/AppSidebar.vue.d.ts +9 -6
- package/dist/components/AppTopBar.navigation.d.ts +11 -0
- package/dist/components/BaseButton.vue.d.ts +1 -1
- package/dist/components/BaseCheckbox.vue.d.ts +7 -2
- package/dist/components/BaseInput.vue.d.ts +2 -2
- package/dist/components/BasePill.vue.d.ts +2 -2
- package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
- package/dist/components/BaseSelect.vue.d.ts +1 -1
- package/dist/components/BaseSlider.vue.d.ts +2 -2
- package/dist/components/BaseTextarea.vue.d.ts +2 -2
- package/dist/components/BaseToggle.vue.d.ts +7 -2
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -1
- package/dist/components/CollapsibleCard.vue.d.ts +9 -0
- package/dist/components/ColorSlider.vue.d.ts +2 -2
- package/dist/components/ConcentrationInput.vue.d.ts +2 -2
- package/dist/components/ControlWorkspaceView.vue.d.ts +4 -4
- package/dist/components/DatePicker.vue.d.ts +1 -1
- package/dist/components/DateTimePicker.vue.d.ts +2 -2
- package/dist/components/DoseCalculatorVolumeField.vue.d.ts +15 -0
- package/dist/components/DoseDesignWorkspaceView.vue.d.ts +2 -2
- package/dist/components/DropdownButton.vue.d.ts +1 -1
- package/dist/components/FileUploader.vue.d.ts +2 -2
- package/dist/components/FormulaInput.vue.d.ts +2 -2
- package/dist/components/IconButton.vue.d.ts +1 -1
- package/dist/components/LoadingSpinner.vue.d.ts +1 -1
- package/dist/components/MoleculeInput.vue.d.ts +2 -2
- package/dist/components/MultiSelect.vue.d.ts +1 -1
- package/dist/components/NumberInput.vue.d.ts +1 -1
- package/dist/components/PlateMapEditor.vue.d.ts +6 -6
- package/dist/components/PluginWorkspaceView.controls.d.ts +28 -0
- package/dist/components/PluginWorkspaceView.navigation.d.ts +29 -0
- package/dist/components/PluginWorkspaceView.props.d.ts +151 -0
- package/dist/components/PluginWorkspaceView.shell.d.ts +19 -0
- package/dist/components/PluginWorkspaceView.vue.d.ts +51 -196
- package/dist/components/ProgressBar.vue.d.ts +1 -1
- package/dist/components/ProtocolStep.presentation.d.ts +4 -0
- package/dist/components/ProtocolStepEditor.state.d.ts +18 -0
- package/dist/components/ProtocolStepParameterField.vue.d.ts +12 -0
- package/dist/components/ReagentList.presentation.d.ts +16 -0
- package/dist/components/ResourceCard.vue.d.ts +1 -1
- package/dist/components/SampleSelector.colors.d.ts +13 -0
- package/dist/components/SampleSelector.drag.d.ts +24 -0
- package/dist/components/SampleSelector.groups.d.ts +15 -0
- package/dist/components/SampleSelector.selection.d.ts +26 -0
- package/dist/components/SampleSelector.vue.d.ts +4 -1
- package/dist/components/SampleSelectorSampleRow.vue.d.ts +21 -0
- package/dist/components/SegmentedControl.vue.d.ts +1 -1
- package/dist/components/SequenceInput.vue.d.ts +2 -2
- package/dist/components/SequenceProgressBar.vue.d.ts +1 -1
- package/dist/components/SettingsModal.schema.d.ts +9 -0
- package/dist/components/StatusIndicator.vue.d.ts +1 -1
- package/dist/components/TagsInput.vue.d.ts +2 -2
- package/dist/components/TimePicker.vue.d.ts +2 -2
- package/dist/components/TimeRangeInput.vue.d.ts +1 -1
- package/dist/components/UnitInput.vue.d.ts +2 -2
- package/dist/components/WellPlate.colors.d.ts +9 -0
- package/dist/components/WellPlate.conditions.d.ts +26 -0
- package/dist/components/WellPlate.geometry.d.ts +23 -0
- package/dist/components/WellPlate.interaction.d.ts +71 -0
- package/dist/components/WellPlate.legend.d.ts +2 -0
- package/dist/components/WellPlate.rendering.d.ts +24 -0
- package/dist/components/WellPlate.sampleDrop.d.ts +8 -0
- package/dist/components/WellPlate.vue.d.ts +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/internal/ActionItemInternal.vue.d.ts +1 -1
- package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +28 -0
- package/dist/{components-DafPc4rM.js → components-Blx4MG--.js} +4073 -4222
- package/dist/components-Blx4MG--.js.map +1 -0
- package/dist/composables/autoGroup/classKey.d.ts +4 -0
- package/dist/composables/autoGroup/classify.d.ts +28 -0
- package/dist/composables/autoGroup/colors.d.ts +2 -0
- package/dist/composables/autoGroup/columns.d.ts +10 -0
- package/dist/composables/autoGroup/compose.d.ts +8 -0
- package/dist/composables/autoGroup/cooccurrence.d.ts +2 -0
- package/dist/composables/autoGroup/csv-shim.d.ts +2 -0
- package/dist/composables/autoGroup/fingerprint.d.ts +3 -0
- package/dist/composables/autoGroup/index.d.ts +16 -0
- package/dist/composables/autoGroup/replicatePreGroup.d.ts +38 -0
- package/dist/composables/autoGroup/template.d.ts +15 -0
- package/dist/composables/autoGroup/tokenize.d.ts +8 -0
- package/dist/composables/autoGroupConstants.d.ts +1 -0
- package/dist/composables/autoGroupGrouping.d.ts +3 -0
- package/dist/composables/controlComponentBindings.d.ts +1 -1
- package/dist/composables/controlSchemaAdapters.d.ts +1 -1
- package/dist/composables/controlSchemaDoseDesign.d.ts +11 -0
- package/dist/composables/controlSchemaLayout.d.ts +1 -1
- package/dist/composables/controlSchemaModel.d.ts +5 -0
- package/dist/composables/controlSchemaNormalize.d.ts +1 -1
- package/dist/composables/controlSchemaTypes.d.ts +311 -0
- package/dist/composables/controlWorkspaceOptions.d.ts +1 -1
- package/dist/composables/formBuilderSchema.d.ts +18 -0
- package/dist/composables/index.js +3 -3
- package/dist/composables/pluginEndpointBuilder.d.ts +13 -0
- package/dist/composables/protocolTemplateCatalog.d.ts +26 -0
- package/dist/composables/useAutoGroup.d.ts +61 -74
- package/dist/composables/useAutoGroupInputSources.d.ts +32 -0
- package/dist/composables/useBioTemplateControls.d.ts +1 -1
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +1 -1
- package/dist/composables/useBioTemplateWorkspace.d.ts +1 -1
- package/dist/composables/useControlSchema.d.ts +4 -316
- package/dist/composables/useControlWorkspace.d.ts +1 -1
- package/dist/composables/useForm.d.ts +2 -33
- package/dist/composables/useFormBuilder.d.ts +2 -9
- package/dist/composables/useFormValidation.d.ts +34 -0
- package/dist/composables/usePluginClient.d.ts +1 -4
- package/dist/composables/useProtocolTemplates.d.ts +2 -24
- package/dist/composables/useScheduleCalendarLayout.d.ts +49 -0
- package/dist/{composables-BMkPQhVK.js → composables-CHDjDIQT.js} +33 -31
- package/dist/composables-CHDjDIQT.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/install.js +2 -2
- package/dist/styles.css +1432 -660
- package/dist/templates/controlSchemaTypes.d.ts +1 -1
- package/dist/templates/index.js +1 -1
- package/dist/templates/templateAdapterTypes.d.ts +48 -0
- package/dist/templates/templateCreateOptions.d.ts +165 -0
- package/dist/templates/templateQpcrTypes.d.ts +42 -0
- package/dist/templates/types.d.ts +5 -250
- package/dist/{templates-bUAWMn5L.js → templates-DSbHJC4v.js} +1536 -297
- package/dist/templates-DSbHJC4v.js.map +1 -0
- package/dist/types/auto-group.d.ts +79 -9
- package/dist/types/componentLabTypes.d.ts +161 -0
- package/dist/types/componentWorkflowTypes.d.ts +150 -0
- package/dist/types/components.d.ts +14 -311
- package/dist/types/form-builder.d.ts +3 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/{useProtocolTemplates-QZtHFFH2.js → useProtocolTemplates-BbPOYPzO.js} +1220 -454
- package/dist/useProtocolTemplates-BbPOYPzO.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/components/AppSidebar.test.ts +67 -0
- package/src/__tests__/components/AppTopBar.navigation.test.ts +70 -0
- package/src/__tests__/components/CollapsibleCard.test.ts +47 -0
- package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +53 -0
- package/src/__tests__/components/FormBuilder.test.ts +57 -0
- package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +54 -0
- package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +156 -0
- package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +102 -0
- package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +43 -0
- package/src/__tests__/components/ProtocolStep.presentation.test.ts +31 -0
- package/src/__tests__/components/ProtocolStepEditor.state.test.ts +165 -0
- package/src/__tests__/components/ProtocolStepParameterField.test.ts +44 -0
- package/src/__tests__/components/ReagentList.presentation.test.ts +68 -0
- package/src/__tests__/components/SampleSelector.colors.test.ts +49 -0
- package/src/__tests__/components/SampleSelector.drag.test.ts +100 -0
- package/src/__tests__/components/SampleSelector.groups.test.ts +81 -0
- package/src/__tests__/components/SampleSelector.selection.test.ts +70 -0
- package/src/__tests__/components/SampleSelector.test.ts +32 -0
- package/src/__tests__/components/SampleSelectorSampleRow.test.ts +37 -0
- package/src/__tests__/components/ScheduleCalendar.test.ts +44 -0
- package/src/__tests__/components/SettingsModal.schema.test.ts +97 -0
- package/src/__tests__/components/WellPlate.colors.test.ts +28 -0
- package/src/__tests__/components/WellPlate.conditions.test.ts +68 -0
- package/src/__tests__/components/WellPlate.geometry.test.ts +54 -0
- package/src/__tests__/components/WellPlate.interaction.test.ts +171 -0
- package/src/__tests__/components/WellPlate.legend.test.ts +13 -0
- package/src/__tests__/components/WellPlate.rendering.test.ts +122 -0
- package/src/__tests__/components/WellPlate.sampleDrop.test.ts +70 -0
- package/src/__tests__/composables/autoGroup/classify.test.ts +107 -0
- package/src/__tests__/composables/autoGroup/columns.test.ts +135 -0
- package/src/__tests__/composables/autoGroup/compose.test.ts +227 -0
- package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +91 -0
- package/src/__tests__/composables/autoGroup/fingerprint.test.ts +50 -0
- package/src/__tests__/composables/autoGroup/integration.test.ts +79 -0
- package/src/__tests__/composables/autoGroup/template.test.ts +70 -0
- package/src/__tests__/composables/autoGroup/tokenize.test.ts +33 -0
- package/src/__tests__/composables/useAutoGroup.test.ts +129 -625
- package/src/__tests__/composables/useAutoGroupInputSources.test.ts +107 -0
- package/src/__tests__/composables/useControlSchema.test.ts +23 -0
- package/src/__tests__/composables/useScheduleCalendarLayout.test.ts +89 -0
- package/src/__tests__/docs/extractDocsComponents.test.ts +142 -0
- package/src/__tests__/docs/extractDocsExports.test.ts +77 -0
- package/src/__tests__/docs/extractDocsParsing.test.ts +69 -0
- package/src/__tests__/docs/extractDocsTemplates.test.ts +54 -0
- package/src/__tests__/docs/extractDocsTheme.test.ts +89 -0
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +1 -1
- package/src/__tests__/fixtures/auto-group/mixed-lc-ms-batch.txt +187 -0
- package/src/components/AppSidebar.story.vue +79 -6
- package/src/components/AppSidebar.vue +74 -6
- package/src/components/AppTopBar.navigation.ts +62 -0
- package/src/components/AppTopBar.vue +17 -44
- package/src/components/AutoGroupModal.story.vue +50 -0
- package/src/components/AutoGroupModal.vue +441 -158
- package/src/components/BaseCheckbox.story.vue +27 -0
- package/src/components/BaseCheckbox.vue +63 -1
- package/src/components/BaseToggle.story.vue +27 -0
- package/src/components/BaseToggle.vue +66 -1
- package/src/components/CollapsibleCard.vue +123 -45
- package/src/components/ControlWorkspaceView.vue +2 -6
- package/src/components/DoseCalculator.vue +13 -73
- package/src/components/DoseCalculatorVolumeField.vue +61 -0
- package/src/components/ExperimentTimeline.vue +6 -31
- package/src/components/FormBuilder.story.vue +13 -0
- package/src/components/FormBuilder.vue +2 -7
- package/src/components/PlateMapEditor.vue +32 -106
- package/src/components/PluginWorkspaceView.controls.ts +182 -0
- package/src/components/PluginWorkspaceView.navigation.ts +106 -0
- package/src/components/PluginWorkspaceView.props.ts +174 -0
- package/src/components/PluginWorkspaceView.shell.ts +67 -0
- package/src/components/PluginWorkspaceView.vue +88 -404
- package/src/components/ProtocolStep.presentation.ts +31 -0
- package/src/components/ProtocolStepEditor.state.ts +104 -0
- package/src/components/ProtocolStepEditor.vue +48 -179
- package/src/components/ProtocolStepParameterField.vue +134 -0
- package/src/components/ReagentList.presentation.ts +105 -0
- package/src/components/ReagentList.vue +16 -79
- package/src/components/SampleSelector.colors.ts +43 -0
- package/src/components/SampleSelector.drag.ts +164 -0
- package/src/components/SampleSelector.groups.ts +109 -0
- package/src/components/SampleSelector.selection.ts +103 -0
- package/src/components/SampleSelector.vue +82 -349
- package/src/components/SampleSelectorSampleRow.vue +64 -0
- package/src/components/ScheduleCalendar.vue +44 -199
- package/src/components/SettingsModal.schema.ts +71 -0
- package/src/components/SettingsModal.vue +16 -46
- package/src/components/WellPlate.colors.ts +56 -0
- package/src/components/WellPlate.conditions.ts +100 -0
- package/src/components/WellPlate.geometry.ts +91 -0
- package/src/components/WellPlate.interaction.ts +272 -0
- package/src/components/WellPlate.legend.ts +8 -0
- package/src/components/WellPlate.rendering.ts +105 -0
- package/src/components/WellPlate.sampleDrop.ts +73 -0
- package/src/components/WellPlate.vue +102 -550
- package/src/components/internal/FormFieldRendererInternal.vue +23 -5
- package/src/components/internal/PlateMapEditorToolbarInternal.vue +128 -0
- package/src/composables/autoGroup/classKey.ts +5 -0
- package/src/composables/autoGroup/classify.ts +205 -0
- package/src/composables/autoGroup/colors.ts +6 -0
- package/src/composables/autoGroup/columns.ts +226 -0
- package/src/composables/autoGroup/compose.ts +156 -0
- package/src/composables/autoGroup/cooccurrence.ts +46 -0
- package/src/composables/autoGroup/csv-shim.ts +44 -0
- package/src/composables/autoGroup/fingerprint.ts +49 -0
- package/src/composables/autoGroup/index.ts +20 -0
- package/src/composables/autoGroup/replicatePreGroup.ts +90 -0
- package/src/composables/autoGroup/template.ts +126 -0
- package/src/composables/autoGroup/tokenize.ts +41 -0
- package/src/composables/autoGroup/vocab.json +67 -0
- package/src/composables/autoGroupConstants.ts +4 -0
- package/src/composables/autoGroupGrouping.ts +148 -0
- package/src/composables/controlComponentBindings.ts +1 -1
- package/src/composables/controlSchemaAdapters.ts +4 -1
- package/src/composables/controlSchemaDoseDesign.ts +215 -0
- package/src/composables/controlSchemaFormFields.ts +4 -1
- package/src/composables/controlSchemaLayout.ts +1 -1
- package/src/composables/controlSchemaModel.ts +163 -0
- package/src/composables/controlSchemaNormalize.ts +1 -1
- package/src/composables/controlSchemaTypes.ts +372 -0
- package/src/composables/controlWorkspaceOptions.ts +1 -1
- package/src/composables/formBuilderSchema.ts +153 -0
- package/src/composables/pluginEndpointBuilder.ts +203 -0
- package/src/composables/protocolTemplateCatalog.ts +325 -0
- package/src/composables/useAutoGroup.ts +395 -549
- package/src/composables/useAutoGroupInputSources.ts +147 -0
- package/src/composables/useBioTemplateControls.ts +1 -1
- package/src/composables/useBioTemplatePresetWorkspace.ts +1 -1
- package/src/composables/useBioTemplateWorkspace.ts +1 -1
- package/src/composables/useControlSchema.ts +21 -692
- package/src/composables/useControlWorkspace.ts +7 -13
- package/src/composables/useForm.ts +5 -187
- package/src/composables/useFormBuilder.ts +11 -153
- package/src/composables/useFormValidation.ts +154 -0
- package/src/composables/usePluginClient.ts +10 -193
- package/src/composables/useProtocolTemplates.ts +10 -328
- package/src/composables/useScheduleCalendarLayout.ts +287 -0
- package/src/styles/components/app-sidebar.css +134 -6
- package/src/styles/components/auto-group-modal.css +248 -310
- package/src/styles/components/checkbox.css +87 -0
- package/src/styles/components/collapsible-card.css +154 -14
- package/src/styles/components/toggle.css +80 -0
- package/src/templates/controlSchemaTypes.ts +1 -1
- package/src/templates/templateAdapterTypes.ts +58 -0
- package/src/templates/templateCreateOptions.ts +208 -0
- package/src/templates/templateQpcrTypes.ts +48 -0
- package/src/templates/types.ts +79 -275
- package/src/types/auto-group.ts +107 -9
- package/src/types/componentLabTypes.ts +235 -0
- package/src/types/componentWorkflowTypes.ts +190 -0
- package/src/types/components.ts +95 -424
- package/src/types/form-builder.ts +3 -0
- package/src/types/index.ts +2 -0
- package/dist/components-DafPc4rM.js.map +0 -1
- package/dist/composables-BMkPQhVK.js.map +0 -1
- package/dist/templates-bUAWMn5L.js.map +0 -1
- package/dist/useProtocolTemplates-QZtHFFH2.js.map +0 -1
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ComputedRef,
|
|
3
|
+
Ref,
|
|
4
|
+
} from 'vue'
|
|
5
|
+
import type {
|
|
6
|
+
PillNavItem,
|
|
7
|
+
SidebarBadgeTone,
|
|
8
|
+
SidebarToolSection,
|
|
9
|
+
SidebarToolSectionAction,
|
|
10
|
+
SelectOption,
|
|
11
|
+
SettingsModalSchema,
|
|
12
|
+
TopBarSettingsConfig,
|
|
13
|
+
} from '../types'
|
|
14
|
+
import type { AccessPolicy, AccessAudienceInput } from '../permissions'
|
|
15
|
+
import type {
|
|
16
|
+
FieldCondition,
|
|
17
|
+
FieldValidation,
|
|
18
|
+
FormFieldSchema,
|
|
19
|
+
FormFieldType,
|
|
20
|
+
FormSchema,
|
|
21
|
+
FormSectionSchema,
|
|
22
|
+
} from '../types/form-builder'
|
|
23
|
+
import type { WellConcentration } from './useDoseCalculator'
|
|
24
|
+
|
|
25
|
+
export type ControlOptionValue = string | number | boolean
|
|
26
|
+
export type ControlOption = ControlOptionValue | SelectOption<unknown>
|
|
27
|
+
export type ControlPrimitive = string | number | boolean
|
|
28
|
+
export type ControlShorthand = ControlPrimitive | readonly ControlOption[]
|
|
29
|
+
export type ControlInput = ControlDefinition | ControlShorthand
|
|
30
|
+
|
|
31
|
+
export interface ControlSectionConfig {
|
|
32
|
+
id?: string
|
|
33
|
+
label?: string
|
|
34
|
+
title?: string
|
|
35
|
+
description?: string
|
|
36
|
+
subtitle?: string
|
|
37
|
+
icon?: string | string[]
|
|
38
|
+
iconColor?: string
|
|
39
|
+
iconBg?: string
|
|
40
|
+
badge?: string | number
|
|
41
|
+
badgeTone?: SidebarBadgeTone
|
|
42
|
+
actions?: SidebarToolSectionAction[]
|
|
43
|
+
columns?: 1 | 2 | 3
|
|
44
|
+
condition?: FieldCondition
|
|
45
|
+
access?: AccessPolicy
|
|
46
|
+
visibleFor?: AccessAudienceInput
|
|
47
|
+
requiresAdmin?: boolean
|
|
48
|
+
permissions?: readonly string[]
|
|
49
|
+
anyPermissions?: readonly string[]
|
|
50
|
+
defaultOpen?: boolean
|
|
51
|
+
showToggle?: boolean
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ControlViewConfig {
|
|
55
|
+
label?: string
|
|
56
|
+
icon?: string
|
|
57
|
+
to?: string
|
|
58
|
+
href?: string
|
|
59
|
+
disabled?: boolean
|
|
60
|
+
children?: PillNavItem['children']
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ControlSidebarConfig extends Omit<ControlSectionConfig, 'id' | 'title' | 'description' | 'columns'> {
|
|
64
|
+
enabled?: boolean
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface ControlDefinition {
|
|
68
|
+
type?: FormFieldType
|
|
69
|
+
label?: string
|
|
70
|
+
default?: unknown
|
|
71
|
+
defaultValue?: unknown
|
|
72
|
+
placeholder?: string
|
|
73
|
+
hint?: string
|
|
74
|
+
icon?: string | string[]
|
|
75
|
+
iconColor?: string
|
|
76
|
+
iconBg?: string
|
|
77
|
+
size?: 'sm' | 'md' | 'lg'
|
|
78
|
+
disabled?: boolean
|
|
79
|
+
readonly?: boolean
|
|
80
|
+
required?: boolean | string
|
|
81
|
+
min?: number | { value: number; message: string }
|
|
82
|
+
max?: number | { value: number; message: string }
|
|
83
|
+
minLength?: number | { value: number; message: string }
|
|
84
|
+
maxLength?: number | { value: number; message: string }
|
|
85
|
+
email?: boolean | string
|
|
86
|
+
pattern?: string | { value: string; message: string }
|
|
87
|
+
validation?: FieldValidation
|
|
88
|
+
condition?: FieldCondition
|
|
89
|
+
access?: AccessPolicy
|
|
90
|
+
visibleFor?: AccessAudienceInput
|
|
91
|
+
requiresAdmin?: boolean
|
|
92
|
+
permissions?: readonly string[]
|
|
93
|
+
anyPermissions?: readonly string[]
|
|
94
|
+
options?: readonly ControlOption[]
|
|
95
|
+
section?: string
|
|
96
|
+
sectionLabel?: string
|
|
97
|
+
sectionDescription?: string
|
|
98
|
+
sectionSubtitle?: string
|
|
99
|
+
view?: string
|
|
100
|
+
order?: number
|
|
101
|
+
colSpan?: number
|
|
102
|
+
props?: Record<string, unknown>
|
|
103
|
+
sidebar?: boolean | ControlSidebarConfig
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type ControlSchema = Record<string, ControlInput>
|
|
107
|
+
export type ControlFormSchema = Extract<FormSchema, { sections: FormSectionSchema[] }>
|
|
108
|
+
|
|
109
|
+
export interface ControlSchemaOptions {
|
|
110
|
+
view?: string
|
|
111
|
+
views?: Record<string, ControlViewConfig>
|
|
112
|
+
section?: string
|
|
113
|
+
sectionLabel?: string
|
|
114
|
+
sections?: Record<string, ControlSectionConfig>
|
|
115
|
+
columns?: 1 | 2 | 3
|
|
116
|
+
submitLabel?: string
|
|
117
|
+
cancelLabel?: string
|
|
118
|
+
showCancel?: boolean
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface ControlWorkspaceOptions extends ControlSchemaOptions {
|
|
122
|
+
initialValues?: Record<string, unknown>
|
|
123
|
+
topBarSettings?: Omit<TopBarSettingsConfig, 'schema' | 'controls' | 'controlOptions' | 'values'>
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ControlModelSectionConfig extends ControlSectionConfig {
|
|
127
|
+
controls: ControlSchema
|
|
128
|
+
sidebar?: boolean | ControlSidebarConfig
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface ControlModelViewConfig extends ControlViewConfig {
|
|
132
|
+
controls?: ControlSchema
|
|
133
|
+
section?: string
|
|
134
|
+
sectionLabel?: string
|
|
135
|
+
sectionDescription?: string
|
|
136
|
+
sections?: Record<string, ControlModelSectionConfig>
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface ControlModel extends Omit<ControlWorkspaceOptions, 'sections' | 'views'> {
|
|
140
|
+
controls?: ControlSchema
|
|
141
|
+
sections?: Record<string, ControlModelSectionConfig>
|
|
142
|
+
views?: Record<string, ControlModelViewConfig>
|
|
143
|
+
/** Optional SDK component bindings returned with generated component props for custom workspace slots. */
|
|
144
|
+
componentBindings?: ControlComponentBindingsConfig
|
|
145
|
+
/** Alias for componentBindings in raw control models. */
|
|
146
|
+
components?: ControlComponentBindingsConfig
|
|
147
|
+
/** Optional ControlWorkspaceView componentProps mapping returned with the generated controls/options. */
|
|
148
|
+
componentProps?: ControlComponentPropsMap
|
|
149
|
+
/** Optional named componentProps mappings returned for multiple SDK components. */
|
|
150
|
+
componentPropsById?: ControlComponentPropsByIdMap
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface ControlModelBinding {
|
|
154
|
+
controls: ControlSchema
|
|
155
|
+
controlOptions: ControlWorkspaceOptions
|
|
156
|
+
componentBindings?: ControlComponentBindingsConfig
|
|
157
|
+
componentProps?: ControlComponentPropsMap
|
|
158
|
+
componentPropsById?: ControlComponentPropsByIdMap
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface ControlSidebarBinding {
|
|
162
|
+
panels: Record<string, SidebarToolSection[]>
|
|
163
|
+
forms: Record<string, ControlFormSchema>
|
|
164
|
+
viewIds: string[]
|
|
165
|
+
viewItems: PillNavItem[]
|
|
166
|
+
defaultView: string
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface ControlFormBinding {
|
|
170
|
+
schema: ControlFormSchema
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface ControlSettingsBinding {
|
|
174
|
+
schema: SettingsModalSchema
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface ControlTopBarSettingsBinding {
|
|
178
|
+
showSettings: true
|
|
179
|
+
settingsConfig: TopBarSettingsConfig
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface ControlWorkspaceFormBinding extends ControlFormBinding {
|
|
183
|
+
modelValue: Record<string, unknown>
|
|
184
|
+
'onUpdate:modelValue': (values: Record<string, unknown>) => void
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface ControlWorkspaceSidebarBinding extends ControlSidebarBinding {
|
|
188
|
+
activeView: string
|
|
189
|
+
modelValue: Record<string, unknown>
|
|
190
|
+
'onUpdate:modelValue': (values: Record<string, unknown>) => void
|
|
191
|
+
values: Record<string, unknown>
|
|
192
|
+
'onUpdate:values': (values: Record<string, unknown>) => void
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface ControlWorkspaceTopBarSettingsBinding extends ControlTopBarSettingsBinding {
|
|
196
|
+
onSettingsValuesChange: (values: Record<string, unknown>) => void
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface ControlWorkspacePillNavBinding {
|
|
200
|
+
items: PillNavItem[]
|
|
201
|
+
currentItemId: string
|
|
202
|
+
onSelect: (item: PillNavItem) => void
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface ControlWorkspaceTopBarBinding extends ControlWorkspaceTopBarSettingsBinding {
|
|
206
|
+
pillNav: PillNavItem[]
|
|
207
|
+
currentPillId: string
|
|
208
|
+
onPillSelect: (item: PillNavItem) => void
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export type ControlWorkspaceAppTopBarPillBinding = ControlWorkspaceTopBarBinding
|
|
212
|
+
|
|
213
|
+
export interface ControlWorkspaceComponentBindings {
|
|
214
|
+
form: ControlWorkspaceFormBinding
|
|
215
|
+
sidebar: ControlWorkspaceSidebarBinding
|
|
216
|
+
topBar: ComputedRef<ControlWorkspaceTopBarBinding>
|
|
217
|
+
topBarSettings: ControlWorkspaceTopBarSettingsBinding
|
|
218
|
+
pillNav: ControlWorkspacePillNavBinding
|
|
219
|
+
componentBindings: ComputedRef<ControlComponentBinding[]>
|
|
220
|
+
componentBindingsById: ComputedRef<ControlComponentBindingsById>
|
|
221
|
+
componentProps: ComputedRef<Record<string, unknown>>
|
|
222
|
+
componentPropsById: ComputedRef<Record<string, Record<string, unknown>>>
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export type ControlComponentPropSource<TValues extends Record<string, unknown> = Record<string, unknown>> =
|
|
226
|
+
| (keyof TValues & string)
|
|
227
|
+
| ((values: TValues) => unknown)
|
|
228
|
+
|
|
229
|
+
export type ControlComponentPropsMap<TValues extends Record<string, unknown> = Record<string, unknown>> =
|
|
230
|
+
| readonly (keyof TValues & string)[]
|
|
231
|
+
| Record<string, ControlComponentPropSource<TValues>>
|
|
232
|
+
|
|
233
|
+
export type ControlComponentPropsByIdMap<TValues extends Record<string, unknown> = Record<string, unknown>> =
|
|
234
|
+
Record<string, ControlComponentPropsMap<TValues>>
|
|
235
|
+
|
|
236
|
+
export interface ControlComponentBindingConfig<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
237
|
+
id?: string
|
|
238
|
+
component: string
|
|
239
|
+
props?: ControlComponentPropsMap<TValues>
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface ControlComponentBindingRecordConfig<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
243
|
+
component: string
|
|
244
|
+
props?: ControlComponentPropsMap<TValues>
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export type ControlComponentBindingsConfig<TValues extends Record<string, unknown> = Record<string, unknown>> =
|
|
248
|
+
| readonly ControlComponentBindingConfig<TValues>[]
|
|
249
|
+
| Record<string, ControlComponentBindingRecordConfig<TValues>>
|
|
250
|
+
|
|
251
|
+
export interface ControlComponentBinding {
|
|
252
|
+
id: string
|
|
253
|
+
component: string
|
|
254
|
+
props: Record<string, unknown>
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export type ControlComponentBindingsById = Record<string, ControlComponentBinding>
|
|
258
|
+
|
|
259
|
+
export interface WellPlateControlPropsOptions<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
260
|
+
selectedWells?: ControlComponentPropSource<TValues>
|
|
261
|
+
format?: ControlComponentPropSource<TValues>
|
|
262
|
+
wells?: ControlComponentPropSource<TValues>
|
|
263
|
+
disabled?: ControlComponentPropSource<TValues>
|
|
264
|
+
readonly?: ControlComponentPropSource<TValues>
|
|
265
|
+
showLegend?: ControlComponentPropSource<TValues>
|
|
266
|
+
showSampleTypeIndicator?: ControlComponentPropSource<TValues>
|
|
267
|
+
/** Listener for WellPlate v-model updates. Set false to keep generated props one-way. */
|
|
268
|
+
onUpdateModelValue?: ((values: TValues) => (wellIds: string[]) => void) | false
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface DoseCalculatorControlPropsOptions<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
272
|
+
mode?: ControlComponentPropSource<TValues>
|
|
273
|
+
targetWells?: ControlComponentPropSource<TValues>
|
|
274
|
+
/** Control value key used by the default apply-to-wells handler. */
|
|
275
|
+
wells?: ControlComponentPropSource<TValues>
|
|
276
|
+
disabled?: ControlComponentPropSource<TValues>
|
|
277
|
+
molecularWeight?: ControlComponentPropSource<TValues>
|
|
278
|
+
/** Listener for DoseCalculator apply-to-wells. Set false to keep generated props one-way. */
|
|
279
|
+
onApplyToWells?: ((values: TValues) => (results: WellConcentration[]) => void) | false
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface WellPlateDoseControlPropsOptions<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
283
|
+
plateId?: string
|
|
284
|
+
doseId?: string
|
|
285
|
+
plate?: WellPlateControlPropsOptions<TValues>
|
|
286
|
+
dose?: DoseCalculatorControlPropsOptions<TValues>
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export interface DoseDesignControlModelOptions {
|
|
290
|
+
viewId?: string
|
|
291
|
+
viewLabel?: string
|
|
292
|
+
sectionId?: string
|
|
293
|
+
sectionLabel?: string
|
|
294
|
+
sectionDescription?: string
|
|
295
|
+
selectedWells?: readonly string[]
|
|
296
|
+
plateFormat?: number
|
|
297
|
+
plateFormats?: readonly number[]
|
|
298
|
+
doseMode?: 'serial' | 'dilution' | 'conversion'
|
|
299
|
+
doseModes?: readonly ('serial' | 'dilution' | 'conversion')[]
|
|
300
|
+
disabled?: boolean
|
|
301
|
+
includeMolecularWeight?: boolean
|
|
302
|
+
molecularWeight?: number
|
|
303
|
+
componentProps?: WellPlateDoseControlPropsOptions
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export interface UseControlSchemaReturn<TControls extends ControlSchema> {
|
|
307
|
+
controls: TControls
|
|
308
|
+
fields: FormFieldSchema[]
|
|
309
|
+
formSchema: ControlFormSchema
|
|
310
|
+
form: ControlFormBinding
|
|
311
|
+
settingsSchema: SettingsModalSchema
|
|
312
|
+
settings: ControlSettingsBinding
|
|
313
|
+
topBarSettingsConfig: TopBarSettingsConfig
|
|
314
|
+
topBarSettings: ControlTopBarSettingsBinding
|
|
315
|
+
sidebarPanels: Record<string, SidebarToolSection[]>
|
|
316
|
+
viewIds: string[]
|
|
317
|
+
viewItems: PillNavItem[]
|
|
318
|
+
defaultView: string
|
|
319
|
+
sectionSchemas: Record<string, ControlFormSchema>
|
|
320
|
+
sidebar: ControlSidebarBinding
|
|
321
|
+
initialValues: ControlValues<TControls>
|
|
322
|
+
sectionSchema: (sectionId: string) => ControlFormSchema
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export interface UseControlWorkspaceReturn<TControls extends ControlSchema>
|
|
326
|
+
extends Omit<UseControlSchemaReturn<TControls>, 'form' | 'sidebar' | 'topBarSettings'> {
|
|
327
|
+
schema: UseControlSchemaReturn<TControls>
|
|
328
|
+
values: ControlValues<TControls> & Record<string, unknown>
|
|
329
|
+
activeView: Ref<string>
|
|
330
|
+
form: ControlWorkspaceFormBinding
|
|
331
|
+
sidebar: ControlWorkspaceSidebarBinding
|
|
332
|
+
topBar: ComputedRef<ControlWorkspaceTopBarBinding>
|
|
333
|
+
pillNav: ControlWorkspacePillNavBinding
|
|
334
|
+
topBarSettings: ControlWorkspaceTopBarSettingsBinding
|
|
335
|
+
bindings: ControlWorkspaceComponentBindings
|
|
336
|
+
componentBindings: ComputedRef<ControlComponentBinding[]>
|
|
337
|
+
componentBindingsById: ComputedRef<ControlComponentBindingsById>
|
|
338
|
+
componentProps: ComputedRef<Record<string, unknown>>
|
|
339
|
+
componentPropsById: ComputedRef<Record<string, Record<string, unknown>>>
|
|
340
|
+
setActiveView: (viewId: string) => void
|
|
341
|
+
setValues: (values: Record<string, unknown>) => void
|
|
342
|
+
resetValues: (values?: Record<string, unknown>) => void
|
|
343
|
+
getComponentProps: (
|
|
344
|
+
mapping?: ControlComponentPropsMap<ControlValues<TControls> & Record<string, unknown>>
|
|
345
|
+
) => Record<string, unknown>
|
|
346
|
+
getComponentPropsById: (
|
|
347
|
+
mappings?: ControlComponentPropsByIdMap<ControlValues<TControls> & Record<string, unknown>>
|
|
348
|
+
) => Record<string, Record<string, unknown>>
|
|
349
|
+
getComponentBindings: (
|
|
350
|
+
bindings?: ControlComponentBindingsConfig<ControlValues<TControls> & Record<string, unknown>>
|
|
351
|
+
) => ControlComponentBinding[]
|
|
352
|
+
getComponentBindingsById: (
|
|
353
|
+
bindings?: ControlComponentBindingsConfig<ControlValues<TControls> & Record<string, unknown>>
|
|
354
|
+
) => ControlComponentBindingsById
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export type ControlValues<TControls extends ControlSchema> = {
|
|
358
|
+
[K in keyof TControls]: ControlValue<TControls[K]>
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
type ControlValue<TControl> =
|
|
362
|
+
TControl extends { default: infer TDefault }
|
|
363
|
+
? TDefault
|
|
364
|
+
: TControl extends { defaultValue: infer TDefaultValue }
|
|
365
|
+
? TDefaultValue
|
|
366
|
+
: TControl extends readonly [infer First, ...unknown[]]
|
|
367
|
+
? OptionValue<First>
|
|
368
|
+
: TControl extends ControlPrimitive
|
|
369
|
+
? TControl
|
|
370
|
+
: unknown
|
|
371
|
+
|
|
372
|
+
type OptionValue<TOption> = TOption extends SelectOption<infer TValue> ? TValue : TOption
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { getTypeDefault } from './formBuilderRegistry'
|
|
2
|
+
import type { FieldRules } from './useForm'
|
|
3
|
+
import type {
|
|
4
|
+
FieldCondition,
|
|
5
|
+
FieldValidation,
|
|
6
|
+
FormEnhancements,
|
|
7
|
+
FormFieldSchema,
|
|
8
|
+
FormSchema,
|
|
9
|
+
FormSectionSchema,
|
|
10
|
+
} from '../types/form-builder'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Evaluate a JSON-serializable field condition against the current form data.
|
|
14
|
+
*
|
|
15
|
+
* Supports logical operators (`and`, `or`, `not`) and comparison operators
|
|
16
|
+
* (`eq`, `neq`, `gt`, `lt`, `gte`, `lte`, `in`, `notIn`, `truthy`, `falsy`,
|
|
17
|
+
* `contains`). Returns `true` if the condition passes.
|
|
18
|
+
*/
|
|
19
|
+
export function evaluateCondition(
|
|
20
|
+
condition: FieldCondition,
|
|
21
|
+
data: Record<string, unknown>,
|
|
22
|
+
): boolean {
|
|
23
|
+
if ('and' in condition) {
|
|
24
|
+
return condition.and.every((c) => evaluateCondition(c, data))
|
|
25
|
+
}
|
|
26
|
+
if ('or' in condition) {
|
|
27
|
+
return condition.or.some((c) => evaluateCondition(c, data))
|
|
28
|
+
}
|
|
29
|
+
if ('not' in condition) {
|
|
30
|
+
return !evaluateCondition(condition.not, data)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const value = data[condition.field]
|
|
34
|
+
|
|
35
|
+
if ('eq' in condition) return value === condition.eq
|
|
36
|
+
if ('neq' in condition) return value !== condition.neq
|
|
37
|
+
if ('gt' in condition) return typeof value === 'number' && value > condition.gt
|
|
38
|
+
if ('lt' in condition) return typeof value === 'number' && value < condition.lt
|
|
39
|
+
if ('gte' in condition) return typeof value === 'number' && value >= condition.gte
|
|
40
|
+
if ('lte' in condition) return typeof value === 'number' && value <= condition.lte
|
|
41
|
+
if ('in' in condition) return condition.in.includes(value)
|
|
42
|
+
if ('notIn' in condition) return !condition.notIn.includes(value)
|
|
43
|
+
if ('truthy' in condition) return !!value
|
|
44
|
+
if ('falsy' in condition) return !value
|
|
45
|
+
if ('contains' in condition) {
|
|
46
|
+
if (typeof value === 'string') return value.includes(condition.contains)
|
|
47
|
+
if (Array.isArray(value)) return value.includes(condition.contains)
|
|
48
|
+
return false
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return true
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Return all sections across steps (wizard) or directly from a flat schema. */
|
|
55
|
+
export function collectSections(schema: FormSchema): FormSectionSchema[] {
|
|
56
|
+
return schema.steps ? schema.steps.flatMap((step) => step.sections) : schema.sections
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Return all field schemas in schema order, flattening sections and steps. */
|
|
60
|
+
export function flattenFields(schema: FormSchema): FormFieldSchema[] {
|
|
61
|
+
return collectSections(schema).flatMap((section) => section.fields)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Convert a JSON-safe `FieldValidation` descriptor to a runtime `FieldRules` object. */
|
|
65
|
+
function convertValidation(v: FieldValidation): FieldRules {
|
|
66
|
+
const rules: FieldRules = {}
|
|
67
|
+
|
|
68
|
+
if (v.required !== undefined) rules.required = v.required
|
|
69
|
+
if (v.minLength !== undefined) rules.minLength = v.minLength
|
|
70
|
+
if (v.maxLength !== undefined) rules.maxLength = v.maxLength
|
|
71
|
+
if (v.min !== undefined) rules.min = v.min
|
|
72
|
+
if (v.max !== undefined) rules.max = v.max
|
|
73
|
+
if (v.email !== undefined) rules.email = v.email
|
|
74
|
+
|
|
75
|
+
if (v.pattern !== undefined) {
|
|
76
|
+
rules.pattern =
|
|
77
|
+
typeof v.pattern === 'string'
|
|
78
|
+
? new RegExp(v.pattern)
|
|
79
|
+
: { value: new RegExp(v.pattern.value), message: v.pattern.message }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return rules
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function buildInitialValues<T extends Record<string, unknown>>(
|
|
86
|
+
fields: readonly FormFieldSchema[],
|
|
87
|
+
initialData?: Partial<T>,
|
|
88
|
+
): Record<string, unknown> {
|
|
89
|
+
const initialValues = {} as Record<string, unknown>
|
|
90
|
+
|
|
91
|
+
for (const field of fields) {
|
|
92
|
+
const key = field.name
|
|
93
|
+
if (initialData && hasOwnKey(initialData, key)) {
|
|
94
|
+
initialValues[key] = (initialData as Record<string, unknown>)[key]
|
|
95
|
+
} else if (field.defaultValue !== undefined) {
|
|
96
|
+
initialValues[key] = field.defaultValue
|
|
97
|
+
} else {
|
|
98
|
+
initialValues[key] = getTypeDefault(field.type)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return initialValues
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function buildRules<T extends Record<string, unknown>>(
|
|
106
|
+
fields: readonly FormFieldSchema[],
|
|
107
|
+
enhancements?: FormEnhancements<T>,
|
|
108
|
+
): Partial<Record<string, FieldRules>> {
|
|
109
|
+
const rules: Partial<Record<string, FieldRules>> = {}
|
|
110
|
+
|
|
111
|
+
for (const field of fields) {
|
|
112
|
+
const base: FieldRules = field.validation ? convertValidation(field.validation) : {}
|
|
113
|
+
const enhancement = enhancements?.fields?.[field.name as keyof T]
|
|
114
|
+
|
|
115
|
+
const customValidators: Array<(
|
|
116
|
+
value: unknown,
|
|
117
|
+
formData: Record<string, unknown>,
|
|
118
|
+
) => string | undefined | null> = []
|
|
119
|
+
|
|
120
|
+
if (enhancement?.validate) {
|
|
121
|
+
const fn = enhancement.validate
|
|
122
|
+
customValidators.push((value, formData) => fn(value, formData as T))
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (customValidators.length > 0) {
|
|
126
|
+
base.custom = customValidators
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (Object.keys(base).length > 0) {
|
|
130
|
+
rules[field.name] = base
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return rules
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function replaceArray<T>(target: T[], values: readonly T[]): void {
|
|
138
|
+
target.splice(0, target.length, ...values)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function replaceRecord<TValue>(
|
|
142
|
+
target: Partial<Record<string, TValue>>,
|
|
143
|
+
source: Partial<Record<string, TValue>>,
|
|
144
|
+
): void {
|
|
145
|
+
for (const key of Object.keys(target)) {
|
|
146
|
+
delete target[key]
|
|
147
|
+
}
|
|
148
|
+
Object.assign(target, source)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function hasOwnKey(source: object, key: string): boolean {
|
|
152
|
+
return Object.prototype.hasOwnProperty.call(source, key)
|
|
153
|
+
}
|