@flyanra/vue-core 0.3.0 → 1.0.0

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.
Files changed (118) hide show
  1. package/dist/types/components/basic/fly-button/FlyButton.types.d.ts +2 -3
  2. package/dist/types/components/basic/typography/FlyCollapseTitleRenderer.vue.d.ts +16 -0
  3. package/dist/types/components/feedback/tooltip/FlyInfoTooltip.vue.d.ts +36 -0
  4. package/dist/types/components/feedback/tooltip/FlyTooltip.vue.d.ts +1 -0
  5. package/dist/types/components/form/form.utils.d.ts +11 -0
  6. package/dist/types/components/form/index.d.ts +5 -0
  7. package/dist/types/components/form/input-renderers/boolean/FlyBoolean.types.d.ts +14 -0
  8. package/dist/types/components/form/input-renderers/boolean/FlyBoolean.vue.d.ts +15 -0
  9. package/dist/types/components/form/input-renderers/date-time/FlyDateTime.types.d.ts +20 -0
  10. package/dist/types/components/form/input-renderers/date-time/FlyDateTime.vue.d.ts +19 -0
  11. package/dist/types/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.vue.d.ts +19 -0
  12. package/dist/types/components/form/input-renderers/form-item-renderer/index.d.ts +3 -0
  13. package/dist/types/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.types.d.ts +2 -0
  14. package/dist/types/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.utils.d.ts +21 -0
  15. package/dist/types/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.vue.d.ts +17 -0
  16. package/dist/types/components/form/input-renderers/form-schema-renderer/UseFormSchemaRenderer.d.ts +25 -0
  17. package/dist/types/components/form/input-renderers/form-schema.types.d.ts +77 -0
  18. package/dist/types/components/form/input-renderers/input-renderer/FlyInputRenderer.vue.d.ts +18 -0
  19. package/dist/types/components/form/input-renderers/input-renderer/index.d.ts +3 -0
  20. package/dist/types/components/form/input-renderers/input-renderer.types.d.ts +30 -0
  21. package/dist/types/components/form/input-renderers/input-renderer.utils.d.ts +2 -0
  22. package/dist/types/components/form/input-renderers/number/FlyNumber.types.d.ts +13 -0
  23. package/dist/types/components/form/input-renderers/number/FlyNumber.utils.d.ts +1 -0
  24. package/dist/types/components/form/input-renderers/number/FlyNumber.vue.d.ts +19 -0
  25. package/dist/types/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.types.d.ts +13 -0
  26. package/dist/types/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.vue.d.ts +20 -0
  27. package/dist/types/components/form/input-renderers/select/FlySelect.types.d.ts +22 -0
  28. package/dist/types/components/form/input-renderers/select/FlySelect.utils.d.ts +2 -0
  29. package/dist/types/components/form/input-renderers/select/FlySelect.vue.d.ts +19 -0
  30. package/dist/types/components/form/input-renderers/text/FlyText.types.d.ts +18 -0
  31. package/dist/types/components/form/input-renderers/text/FlyText.vue.d.ts +19 -0
  32. package/dist/types/components/form/input-renderers/value-unit/FlyValueUnit.types.d.ts +23 -0
  33. package/dist/types/components/form/input-renderers/value-unit/FlyValueUnit.vue.d.ts +19 -0
  34. package/dist/types/components/form/input-validators.d.ts +12 -0
  35. package/dist/types/components/general/fly-icon-v2/FlyIconV2.types.d.ts +5 -0
  36. package/dist/types/components/general/fly-icon-v2/FlyIconV2.vue.d.ts +4 -0
  37. package/dist/types/components/general/fly-icon-v2/index.d.ts +4 -0
  38. package/dist/types/components/general/index.d.ts +2 -0
  39. package/dist/types/components/index.d.ts +1 -4
  40. package/dist/types/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.types.d.ts +2 -2
  41. package/dist/types/components/navigation/menu/fly-sidebar/FlySidebar.types.d.ts +2 -2
  42. package/dist/types/composables/UseLocaleInjector.d.ts +8 -0
  43. package/dist/types/composables/index.d.ts +1 -0
  44. package/dist/types/utils/pure-functions.d.ts +1 -0
  45. package/dist/types/utils/validators.d.ts +8 -0
  46. package/package.json +26 -8
  47. package/src/components/basic/fly-button/FlyButton.types.ts +2 -3
  48. package/src/components/basic/fly-button/FlyButton.vue +4 -6
  49. package/src/components/basic/typography/FlyCollapseTitleRenderer.vue +46 -0
  50. package/src/components/feedback/tooltip/FlyInfoTooltip.vue +49 -0
  51. package/src/components/feedback/tooltip/FlyTooltip.element.scss +1 -1
  52. package/src/components/feedback/tooltip/FlyTooltip.vue +1 -0
  53. package/src/components/form/form.utils.ts +72 -0
  54. package/src/components/form/index.ts +6 -0
  55. package/src/components/form/input-renderers/boolean/FlyBoolean.scss +1 -0
  56. package/src/components/form/input-renderers/boolean/FlyBoolean.types.ts +16 -0
  57. package/src/components/form/input-renderers/boolean/FlyBoolean.vue +48 -0
  58. package/src/components/form/input-renderers/date-time/FlyDateTime.scss +1 -0
  59. package/src/components/form/input-renderers/date-time/FlyDateTime.types.ts +21 -0
  60. package/src/components/form/input-renderers/date-time/FlyDateTime.vue +85 -0
  61. package/src/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.scss +4 -0
  62. package/src/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.vue +48 -0
  63. package/src/components/form/input-renderers/form-item-renderer/index.ts +4 -0
  64. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.types.ts +3 -0
  65. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.utils.ts +221 -0
  66. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.vue +75 -0
  67. package/src/components/form/input-renderers/form-schema-renderer/UseFormSchemaRenderer.ts +97 -0
  68. package/src/components/form/input-renderers/form-schema.types.ts +95 -0
  69. package/src/components/form/input-renderers/input-renderer/FlyInputRenderer.vue +49 -0
  70. package/src/components/form/input-renderers/input-renderer/index.ts +4 -0
  71. package/src/components/form/input-renderers/input-renderer.types.ts +49 -0
  72. package/src/components/form/input-renderers/input-renderer.utils.ts +18 -0
  73. package/src/components/form/input-renderers/number/FlyNumber.scss +1 -0
  74. package/src/components/form/input-renderers/number/FlyNumber.types.ts +13 -0
  75. package/src/components/form/input-renderers/number/FlyNumber.utils.ts +6 -0
  76. package/src/components/form/input-renderers/number/FlyNumber.vue +64 -0
  77. package/src/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.types.ts +15 -0
  78. package/src/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.vue +99 -0
  79. package/src/components/form/input-renderers/select/FlySelect.scss +1 -0
  80. package/src/components/form/input-renderers/select/FlySelect.types.ts +25 -0
  81. package/src/components/form/input-renderers/select/FlySelect.utils.ts +37 -0
  82. package/src/components/form/input-renderers/select/FlySelect.vue +48 -0
  83. package/src/components/form/input-renderers/text/FlyText.scss +1 -0
  84. package/src/components/form/input-renderers/text/FlyText.types.ts +20 -0
  85. package/src/components/form/input-renderers/text/FlyText.vue +70 -0
  86. package/src/components/form/input-renderers/value-unit/FlyValueUnit.scss +2 -0
  87. package/src/components/form/input-renderers/value-unit/FlyValueUnit.types.ts +28 -0
  88. package/src/components/form/input-renderers/value-unit/FlyValueUnit.vue +102 -0
  89. package/src/components/form/input-validators.ts +99 -0
  90. package/src/components/general/fly-icon-v2/FlyIconV2.types.ts +6 -0
  91. package/src/components/general/fly-icon-v2/FlyIconV2.vue +17 -0
  92. package/src/components/general/fly-icon-v2/index.ts +6 -0
  93. package/src/components/general/index.ts +3 -0
  94. package/src/components/index.ts +2 -6
  95. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.types.ts +2 -2
  96. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebarItem.vue +2 -2
  97. package/src/components/navigation/menu/fly-sidebar/FlySidebar.types.ts +2 -2
  98. package/src/components/navigation/menu/fly-sidebar/FlySidebar.vue +5 -4
  99. package/src/components/navigation/menu/fly-sidebar/FlySidebarNode.vue +3 -3
  100. package/src/styles/element/mixins/collapse.scss +2 -2
  101. package/src/styles/element/overrides/date-time.scss +11 -0
  102. package/src/styles/element/overrides/form.scss +26 -12
  103. package/src/styles/element/overrides/message-box.scss +2 -0
  104. package/src/styles/element/overrides/radio.scss +2 -0
  105. package/src/styles/element/overrides/select.scss +9 -0
  106. package/dist/types/components/AppButton/AppButton.types.d.ts +0 -8
  107. package/dist/types/components/AppButton/AppButton.vue.d.ts +0 -20
  108. package/dist/types/components/AppButton/index.d.ts +0 -4
  109. package/dist/types/components/AppCard/AppCard.types.d.ts +0 -5
  110. package/dist/types/components/AppCard/AppCard.vue.d.ts +0 -17
  111. package/dist/types/components/AppCard/index.d.ts +0 -4
  112. package/src/components/AppButton/AppButton.element.scss +0 -2
  113. package/src/components/AppButton/AppButton.types.ts +0 -10
  114. package/src/components/AppButton/AppButton.vue +0 -65
  115. package/src/components/AppButton/index.ts +0 -6
  116. package/src/components/AppCard/AppCard.types.ts +0 -5
  117. package/src/components/AppCard/AppCard.vue +0 -58
  118. package/src/components/AppCard/index.ts +0 -6
@@ -0,0 +1,221 @@
1
+ import type { FormItemRule } from 'element-plus'
2
+
3
+ import { checkInputRange } from '../../../../utils/validators'
4
+ import {
5
+ checkInputRangeValidator,
6
+ requiredField,
7
+ requiredFieldArray,
8
+ requiredFieldNumber,
9
+ requiredFieldNumberSelect,
10
+ requiredFieldValueUnit
11
+ } from '../../input-validators'
12
+ import type {
13
+ T_FormSchemaLookupData,
14
+ T_InputSchema,
15
+ T_InputSchemaSelect,
16
+ T_InputSchemaValueUnit
17
+ } from '../form-schema.types'
18
+ import type { T_InputRendererBase } from '../input-renderer.types'
19
+ import type { T_InputSelectOption } from '../select/FlySelect.types'
20
+
21
+ export function getValidatorsFromInputFields(fields: T_InputRendererBase[]) {
22
+ const validators = fields.reduce(
23
+ (p, c) => {
24
+ if (c.validations) {
25
+ p[c.key] = c.validations
26
+ }
27
+ return p
28
+ },
29
+ {} as Record<string, FormItemRule[]>
30
+ )
31
+
32
+ return validators
33
+ }
34
+
35
+ export function generateInputFromFormSchema(
36
+ field: T_InputSchema,
37
+ lookupData?: T_FormSchemaLookupData
38
+ ) {
39
+ switch (field.type) {
40
+ case 'text': {
41
+ const selectInput: T_InputRendererBase = {
42
+ label: field.label,
43
+ type: field.type,
44
+ key: field.unique_key,
45
+ attrs: {
46
+ maxlength: field.config?.maxLength,
47
+ minlength: field.config?.minLength,
48
+ showWordLimit: true,
49
+ type: field.config?.type || field.type,
50
+ rows: field.config?.rows
51
+ },
52
+ placeholder: field.placeholder,
53
+ tooltip: field.tooltip,
54
+ validations: generateFormRule(field)
55
+ }
56
+
57
+ return selectInput
58
+ }
59
+ case 'select': {
60
+ const selectInput: T_InputRendererBase = {
61
+ label: field.label,
62
+ type: field.type,
63
+ key: field.unique_key,
64
+ attrs: {
65
+ multiple: field.config.multiple
66
+ },
67
+ placeholder: field.placeholder,
68
+ tooltip: field.tooltip,
69
+ validations: generateFormRule(field),
70
+ config: {
71
+ options: generateSelectOptionsFromSchema(field, lookupData)
72
+ }
73
+ }
74
+
75
+ return selectInput
76
+ }
77
+ case 'valueUnit': {
78
+ const selectInput: T_InputRendererBase = {
79
+ label: field.label,
80
+ type: field.type,
81
+ key: field.unique_key,
82
+ attrs: {},
83
+ placeholder: field.placeholder,
84
+ tooltip: field.tooltip,
85
+ validations: generateFormRule(field),
86
+ config: {
87
+ options: generateSelectOptionsFromSchema(field, lookupData)
88
+ }
89
+ }
90
+
91
+ return selectInput
92
+ }
93
+ case 'number': {
94
+ const selectInput: T_InputRendererBase = {
95
+ label: field.label,
96
+ type: field.type,
97
+ key: field.unique_key,
98
+ attrs: {},
99
+ placeholder: field.placeholder,
100
+ tooltip: field.tooltip,
101
+ validations: generateFormRule(field)
102
+ }
103
+
104
+ return selectInput
105
+ }
106
+ case 'boolean': {
107
+ const selectInput: T_InputRendererBase = {
108
+ label: field.label,
109
+ type: field.type,
110
+ key: field.unique_key,
111
+ attrs: {
112
+ activeText: field.config?.activeText,
113
+ inactiveText: field.config?.inactiveText
114
+ },
115
+ placeholder: field.placeholder,
116
+ tooltip: field.tooltip,
117
+ validations: generateFormRule(field)
118
+ }
119
+
120
+ return selectInput
121
+ }
122
+ case 'dateTime': {
123
+ const selectInput: T_InputRendererBase = {
124
+ label: field.label,
125
+ type: field.type,
126
+ key: field.unique_key,
127
+ placeholder: field.placeholder,
128
+ tooltip: field.tooltip,
129
+ validations: generateFormRule(field),
130
+ config: {
131
+ inputType: field.config?.inputType
132
+ }
133
+ }
134
+
135
+ return selectInput
136
+ }
137
+ default:
138
+ break
139
+ }
140
+ }
141
+
142
+ export function generateFormRule(field: T_InputSchema): FormItemRule[] {
143
+ const validations = field.validation
144
+ const rules: FormItemRule[] = []
145
+
146
+ if (validations?.required) {
147
+ switch (field.type) {
148
+ case 'text': {
149
+ rules.push(requiredField(field.label, 'blur', true))
150
+
151
+ if (field.validation?.minLength || field.validation?.maxLength) {
152
+ rules.push(
153
+ checkInputRangeValidator(
154
+ checkInputRange(
155
+ field.label,
156
+ {
157
+ min: field.validation?.minLength,
158
+ max: field.validation?.maxLength
159
+ },
160
+ undefined,
161
+ undefined
162
+ ),
163
+ 'blur'
164
+ )
165
+ )
166
+ }
167
+
168
+ break
169
+ }
170
+
171
+ case 'dateTime': {
172
+ rules.push(requiredField(field.label, 'blur', true))
173
+ break
174
+ }
175
+
176
+ case 'number': {
177
+ rules.push(requiredFieldNumber(field.label, 'change'))
178
+ break
179
+ }
180
+
181
+ case 'select': {
182
+ if (field.config.multiple) {
183
+ rules.push(requiredFieldArray(field.label, 'change', true))
184
+ } else {
185
+ rules.push(requiredField(field.label, 'change', true))
186
+ }
187
+ break
188
+ }
189
+
190
+ case 'valueUnit': {
191
+ if (field.config.valueType === 'text') {
192
+ rules.push(
193
+ requiredFieldValueUnit(field.label, 'change', undefined, undefined, {
194
+ valueType: 'text'
195
+ })
196
+ )
197
+ } else {
198
+ rules.push(requiredFieldNumberSelect(field.label, 'change', true))
199
+ }
200
+ }
201
+ }
202
+ }
203
+
204
+ return rules
205
+ }
206
+
207
+ export function generateSelectOptionsFromSchema(
208
+ field: T_InputSchemaSelect | T_InputSchemaValueUnit,
209
+ lookupData?: T_FormSchemaLookupData
210
+ ): T_InputSelectOption[] {
211
+ const optionsArr = field.config?.options
212
+ if (optionsArr) return optionsArr
213
+
214
+ if (!lookupData) return []
215
+ const lookupId = field.config.options_config_Lookup_id
216
+ if (!lookupId) return []
217
+
218
+ const record = lookupData[lookupId]
219
+
220
+ return record ? (record as T_InputSelectOption[]) : []
221
+ }
@@ -0,0 +1,75 @@
1
+ <template>
2
+ <div class="fly-form-schema-renderer">
3
+ <el-form
4
+ ref="formRef"
5
+ :rules="dynamicValidators"
6
+ :model="formProxy"
7
+ label-position="top"
8
+ status-icon
9
+ :disabled="disabled"
10
+ @submit.prevent
11
+ >
12
+ <div class="fly-form-schema-renderer__form-holder">
13
+ <div
14
+ v-for="(input, i) in generatedForm?.inputs"
15
+ :key="i"
16
+ :style="{
17
+ gridColumn: `span ${getSpan(input)} / span ${getSpan(input)}`
18
+ }"
19
+ >
20
+ <FlyFormItemRenderer v-model="formProxy[input.key]" :input="input" />
21
+ </div>
22
+ </div>
23
+ </el-form>
24
+ </div>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { ref } from 'vue'
29
+
30
+ import { ElForm, type FormInstance } from 'element-plus'
31
+
32
+ import '../../../../styles/element/overrides/form.scss'
33
+ import FlyFormItemRenderer from '../form-item-renderer/FlyFormItemRenderer.vue'
34
+ import type { T_InputRendererBase } from '../input-renderer.types'
35
+
36
+ import {
37
+ type T_FormSchemaRendererEmits,
38
+ type T_FormSchemaRendererProps,
39
+ UseFormSchemaRenderer
40
+ } from './UseFormSchemaRenderer'
41
+
42
+ const emit = defineEmits<T_FormSchemaRendererEmits>()
43
+
44
+ const props = defineProps<
45
+ T_FormSchemaRendererProps & {
46
+ /**
47
+ * Column span within a 12 column grid
48
+ */
49
+ columnSpan?: number
50
+ }
51
+ >()
52
+
53
+ const formRef = ref<FormInstance>()
54
+
55
+ const dynamicConfigFormComp = UseFormSchemaRenderer({ formRef, props, emit })
56
+ const { dynamicValidators, formProxy, generatedForm } = dynamicConfigFormComp
57
+
58
+ function getSpan(input?: T_InputRendererBase) {
59
+ return input?.columnSpan || props.columnSpan || 4
60
+ }
61
+
62
+ defineExpose({
63
+ validateForm: dynamicConfigFormComp.validateForm
64
+ })
65
+ </script>
66
+
67
+ <style lang="scss" scoped>
68
+ .fly-form-schema-renderer {
69
+ &__form-holder {
70
+ display: grid;
71
+ grid-template-columns: repeat(12, minmax(0, 1fr));
72
+ gap: 0.5rem;
73
+ }
74
+ }
75
+ </style>
@@ -0,0 +1,97 @@
1
+ import { type Ref, computed, ref, watch } from 'vue'
2
+
3
+ import type { FormInstance } from 'element-plus'
4
+
5
+ import { defaultsDeep } from 'lodash-es'
6
+
7
+ import { genericFormValidator } from '../../form.utils'
8
+ import type { T_FormSchemaLookupData, T_InputSchema } from '../form-schema.types'
9
+ import type { T_FormSchemaRendererConfig, T_InputRendererBase } from '../input-renderer.types'
10
+
11
+ import {
12
+ generateInputFromFormSchema,
13
+ getValidatorsFromInputFields
14
+ } from './FlyFormSchemaRenderer.utils'
15
+
16
+ export type T_FormSchemaRendererProps = {
17
+ formConfig: T_InputSchema[]
18
+ lookupData?: T_FormSchemaLookupData
19
+ modelValue?: Record<string, unknown>
20
+ disabled?: boolean
21
+ }
22
+
23
+ export type T_FormSchemaRendererEmits = {
24
+ (e: 'update:modelValue', value: T_FormSchemaRendererProps['modelValue']): void
25
+ }
26
+
27
+ type ConfigFormCompArgs = {
28
+ formRef: Ref<FormInstance | undefined>
29
+ props: T_FormSchemaRendererProps
30
+ emit: T_FormSchemaRendererEmits
31
+ }
32
+
33
+ export function UseFormSchemaRenderer(args: ConfigFormCompArgs) {
34
+ const fallbackForm = {}
35
+
36
+ const formProxy = computed<Record<string, unknown>>({
37
+ get: () => args.props.modelValue || fallbackForm,
38
+ set: (val) => args.emit('update:modelValue', val)
39
+ })
40
+
41
+ const generatedForm = ref<T_FormSchemaRendererConfig>()
42
+ const dynamicFormGenerated = ref(false)
43
+
44
+ const dynamicValidators = computed(() => {
45
+ const validators =
46
+ generatedForm.value && getValidatorsFromInputFields(generatedForm.value.inputs)
47
+
48
+ return validators || {}
49
+ })
50
+
51
+ async function validateForm() {
52
+ return args.formRef.value && genericFormValidator(args.formRef.value)
53
+ }
54
+
55
+ function generateDynamicForm() {
56
+ try {
57
+ if (dynamicFormGenerated.value) return
58
+
59
+ const inputs: T_InputRendererBase[] = []
60
+ const baseForm: T_FormSchemaRendererConfig['baseForm'] = {}
61
+
62
+ args.props.formConfig.forEach((f) => {
63
+ const i = generateInputFromFormSchema(f, args.props.lookupData)
64
+ if (i) {
65
+ inputs.push(i)
66
+ baseForm[i.key] = f.default_value
67
+ }
68
+ })
69
+
70
+ dynamicFormGenerated.value = true
71
+
72
+ defaultsDeep(args.props.modelValue, baseForm)
73
+
74
+ generatedForm.value = { inputs, baseForm }
75
+ } catch (error) {
76
+ console.error(error)
77
+ }
78
+ }
79
+
80
+ watch(
81
+ () => args.props.formConfig,
82
+ () => {
83
+ dynamicFormGenerated.value = false
84
+ generateDynamicForm()
85
+ },
86
+ {
87
+ immediate: true
88
+ }
89
+ )
90
+
91
+ return {
92
+ dynamicValidators,
93
+ formProxy,
94
+ generatedForm,
95
+ validateForm
96
+ }
97
+ }
@@ -0,0 +1,95 @@
1
+ import type { T_DateInputTypes } from './date-time/FlyDateTime.types'
2
+ import type { T_InputSelectOption } from './select/FlySelect.types'
3
+ import type { T_ValueUnitValue } from './value-unit/FlyValueUnit.types'
4
+
5
+ export type T_FormSchemaLookupData = Record<string, Array<unknown>>
6
+
7
+ export type T_InputSchema =
8
+ | T_InputSchemaText
9
+ | T_InputSchemaNumber
10
+ | T_InputSchemaBoolean
11
+ | T_InputSchemaSelect
12
+ | T_InputSchemaValueUnit
13
+ | T_InputSchemaDateTime
14
+
15
+ type T_FieldValidationBase = {
16
+ required?: boolean
17
+ }
18
+
19
+ type T_InputSchemaBase<ValidationRules = object> = {
20
+ unique_key: string
21
+ label: string
22
+ tooltip?: string
23
+ placeholder?: string
24
+ validation?: T_FieldValidationBase & ValidationRules
25
+ }
26
+
27
+ export type T_InputSchemaText = T_InputSchemaBase<{
28
+ minLength?: number
29
+ maxLength?: number
30
+ }> & {
31
+ type: 'text'
32
+ default_value?: string
33
+ config?: {
34
+ maxLength?: number
35
+ minLength?: number
36
+ type?: string
37
+ rows?: number
38
+ }
39
+ }
40
+
41
+ export type T_InputSchemaNumber = T_InputSchemaBase<{
42
+ minLength?: number
43
+ maxLength?: number
44
+ }> & {
45
+ type: 'number'
46
+ default_value?: number
47
+ config?: {
48
+ minLength?: number
49
+ maxLength?: number
50
+ }
51
+ }
52
+
53
+ export type T_InputSchemaBoolean = T_InputSchemaBase & {
54
+ type: 'boolean'
55
+ default_value?: boolean
56
+ config?: {
57
+ activeText?: string
58
+ inactiveText?: string
59
+ }
60
+ }
61
+
62
+ type T_SelectOptions =
63
+ | {
64
+ options_config_Lookup_id: string
65
+ options?: never
66
+ }
67
+ | {
68
+ options?: T_InputSelectOption[]
69
+ options_config_Lookup_id?: never
70
+ }
71
+ type T_SelectBase<M extends boolean | undefined> = T_InputSchemaBase & {
72
+ type: 'select'
73
+ config: T_SelectOptions & {
74
+ multiple?: M
75
+ }
76
+ default_value?: M extends true ? (string | number)[] : string | number
77
+ }
78
+
79
+ export type T_InputSchemaSelect = T_SelectBase<true> | T_SelectBase<false | undefined>
80
+
81
+ export type T_InputSchemaValueUnit = T_InputSchemaBase & {
82
+ type: 'valueUnit'
83
+ config: T_SelectOptions & {
84
+ valueType?: 'text' | 'number'
85
+ }
86
+ default_value?: T_ValueUnitValue
87
+ }
88
+
89
+ export type T_InputSchemaDateTime = T_InputSchemaBase & {
90
+ type: 'dateTime'
91
+ default_value?: string | [string | string]
92
+ config?: {
93
+ inputType: T_DateInputTypes
94
+ }
95
+ }
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <div style="width: 100%">
3
+ <component
4
+ :is="map[input.type]"
5
+ :model-value="modelValue"
6
+ :input="input"
7
+ @change="(v: unknown) => emit('change', v)"
8
+ @update:model-value="(v: unknown) => emit('update:modelValue', v)"
9
+ @blur="emit('blur')"
10
+ @focus="emit('focus')"
11
+ />
12
+ </div>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import FlyBoolean from '../boolean/FlyBoolean.vue'
17
+ import FlyDateTime from '../date-time/FlyDateTime.vue'
18
+ import type {
19
+ T_DynamicInputComponent,
20
+ T_InputRendererBase,
21
+ T_InputTypes
22
+ } from '../input-renderer.types'
23
+ import FlyNumber from '../number/FlyNumber.vue'
24
+ import FlySelect from '../select/FlySelect.vue'
25
+ import FlyText from '../text/FlyText.vue'
26
+ import FlyValueUnit from '../value-unit/FlyValueUnit.vue'
27
+
28
+ const emit = defineEmits<{
29
+ (e: 'update:modelValue', v: unknown): void
30
+ (e: 'change', v: unknown): void
31
+ (e: 'blur'): void
32
+ (e: 'focus'): void
33
+ }>()
34
+
35
+ defineProps<{
36
+ modelValue?: unknown
37
+ input: T_InputRendererBase
38
+ }>()
39
+
40
+ const map: Record<T_InputTypes, T_DynamicInputComponent> = {
41
+ text: FlyText,
42
+ textarea: FlyText,
43
+ number: FlyNumber,
44
+ valueUnit: FlyValueUnit,
45
+ select: FlySelect,
46
+ boolean: FlyBoolean,
47
+ dateTime: FlyDateTime
48
+ }
49
+ </script>
@@ -0,0 +1,4 @@
1
+ import FlyInputRenderer from './FlyInputRenderer.vue'
2
+
3
+ export default FlyInputRenderer
4
+ export { FlyInputRenderer }
@@ -0,0 +1,49 @@
1
+ import type { Component } from 'vue'
2
+
3
+ import type { FormItemRule } from 'element-plus'
4
+
5
+ import type { T_InputBoolean, T_InputBooleanBase } from './boolean/FlyBoolean.types'
6
+ import type { T_InputDateTime, T_InputDateTimeBase } from './date-time/FlyDateTime.types'
7
+ import type { T_InputNumber, T_InputNumberBase } from './number/FlyNumber.types'
8
+ import type { T_InputSelect, T_InputSelectBase } from './select/FlySelect.types'
9
+ import type { T_InputText, T_InputTextBase } from './text/FlyText.types'
10
+ import type { T_InputValueUnit, T_InputValueUnitBase } from './value-unit/FlyValueUnit.types'
11
+
12
+ export type T_DynamicInputPropsBase = {
13
+ key: string
14
+ prop?: string // for form validation. falls back to key
15
+ label: string
16
+ tooltip?: string
17
+ columnSpan?: number
18
+ validations?: FormItemRule[]
19
+ }
20
+
21
+ export type T_InputRendererBase = T_DynamicInputPropsBase & T_SupportedInputTypeBase
22
+
23
+ export type T_SupportedInputTypeBase =
24
+ | T_InputTextBase
25
+ | T_InputBooleanBase
26
+ | T_InputDateTimeBase
27
+ | T_InputNumberBase
28
+ | T_InputSelectBase
29
+ | T_InputValueUnitBase
30
+
31
+ export type T_SupportedInputType =
32
+ | T_InputText
33
+ | T_InputNumber
34
+ | T_InputValueUnit
35
+ | T_InputSelect
36
+ | T_InputBoolean
37
+ | T_InputDateTime
38
+
39
+ export type T_InputTypes = T_SupportedInputTypeBase['type']
40
+
41
+ export type T_DynamicInputComponent = Component<{
42
+ modelValue?: unknown
43
+ input?: T_SupportedInputType
44
+ }>
45
+
46
+ export type T_FormSchemaRendererConfig = {
47
+ inputs: T_InputRendererBase[]
48
+ baseForm: { [K: string]: unknown }
49
+ }
@@ -0,0 +1,18 @@
1
+ import { isNil } from 'lodash-es'
2
+
3
+ import type { T_InputTypes } from './input-renderer.types'
4
+
5
+ export function getInputDisplayValue(v: unknown, inputType: T_InputTypes) {
6
+ switch (inputType) {
7
+ case 'number':
8
+ if (isNil(v)) return ''
9
+ return Number(v)
10
+
11
+ case 'text':
12
+ default:
13
+ if (isNil(v)) {
14
+ return ''
15
+ }
16
+ return String(v)
17
+ }
18
+ }
@@ -0,0 +1 @@
1
+ @use 'element-plus/theme-chalk/src/input.scss';
@@ -0,0 +1,13 @@
1
+ export type T_InputTextValues = string | number | undefined
2
+
3
+ export type T_InputNumberBase = T_InputNumber & {
4
+ type: 'number'
5
+ }
6
+
7
+ export type T_InputNumber = {
8
+ placeholder?: string
9
+ /**
10
+ * Attrs are passed directly to the input element as props
11
+ */
12
+ attrs?: { [K: string]: unknown }
13
+ }
@@ -0,0 +1,6 @@
1
+ export function displayToNumber(v: unknown): number | undefined {
2
+ if (v === '' || v === undefined || v === undefined) return undefined
3
+
4
+ const n = Number(v)
5
+ return Number.isNaN(n) ? undefined : n
6
+ }
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <el-input
3
+ v-model.number="inputProxy"
4
+ style="width: 100%"
5
+ type="number"
6
+ v-bind="input?.attrs"
7
+ :placeholder="input?.placeholder"
8
+ @change="(val) => emit('change', displayToNumber(val))"
9
+ @blur="() => emit('blur')"
10
+ @focus="() => emit('focus')"
11
+ >
12
+ </el-input>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { computed, watch } from 'vue'
17
+
18
+ import { ElInput } from 'element-plus'
19
+
20
+ import { getInputDisplayValue } from '../input-renderer.utils'
21
+
22
+ import './FlyNumber.scss'
23
+ import type { T_InputNumber, T_InputTextValues } from './FlyNumber.types'
24
+ import { displayToNumber } from './FlyNumber.utils'
25
+
26
+ const emit = defineEmits<{
27
+ (e: 'update:modelValue', v: T_InputTextValues): void
28
+ (e: 'change', v: T_InputTextValues): void
29
+ (e: 'blur'): void
30
+ (e: 'focus'): void
31
+ }>()
32
+
33
+ const props = defineProps<{
34
+ modelValue?: unknown
35
+ input?: T_InputNumber
36
+ }>()
37
+
38
+ const inputProxy = computed({
39
+ get: () => {
40
+ return getInputDisplayValue(props.modelValue, 'number')
41
+ },
42
+ set: (v) => {
43
+ const parsed = displayToNumber(v)
44
+
45
+ emit('update:modelValue', parsed)
46
+ emit('change', parsed)
47
+ }
48
+ })
49
+
50
+ watch(
51
+ () => props.modelValue,
52
+ () => {
53
+ const parsed = displayToNumber(props.modelValue)
54
+
55
+ if (parsed !== props.modelValue) {
56
+ emit('update:modelValue', parsed)
57
+ emit('change', parsed)
58
+ }
59
+ },
60
+ {
61
+ immediate: true
62
+ }
63
+ )
64
+ </script>