@ramathibodi/nuxt-commons 0.1.73 → 0.1.75

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 (111) hide show
  1. package/README.md +115 -96
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +1 -0
  4. package/dist/runtime/components/Alert.vue +58 -54
  5. package/dist/runtime/components/BarcodeReader.vue +130 -122
  6. package/dist/runtime/components/ExportCSV.vue +110 -102
  7. package/dist/runtime/components/FileBtn.vue +79 -67
  8. package/dist/runtime/components/ImportCSV.vue +151 -139
  9. package/dist/runtime/components/MrzReader.vue +168 -0
  10. package/dist/runtime/components/SplitterPanel.vue +67 -59
  11. package/dist/runtime/components/TabsGroup.vue +39 -31
  12. package/dist/runtime/components/TextBarcode.vue +66 -54
  13. package/dist/runtime/components/device/IdCardButton.vue +95 -83
  14. package/dist/runtime/components/device/IdCardWebSocket.vue +207 -195
  15. package/dist/runtime/components/device/Scanner.vue +350 -338
  16. package/dist/runtime/components/dialog/Confirm.vue +112 -100
  17. package/dist/runtime/components/dialog/Host.vue +88 -84
  18. package/dist/runtime/components/dialog/Index.vue +84 -72
  19. package/dist/runtime/components/dialog/Loading.vue +51 -39
  20. package/dist/runtime/components/dialog/default/Confirm.vue +112 -100
  21. package/dist/runtime/components/dialog/default/Loading.vue +60 -48
  22. package/dist/runtime/components/dialog/default/Notify.vue +82 -70
  23. package/dist/runtime/components/dialog/default/Printing.vue +46 -34
  24. package/dist/runtime/components/dialog/default/VerifyUser.vue +144 -132
  25. package/dist/runtime/components/document/Form.vue +50 -42
  26. package/dist/runtime/components/document/TemplateBuilder.vue +536 -524
  27. package/dist/runtime/components/form/ActionPad.vue +156 -144
  28. package/dist/runtime/components/form/Birthdate.vue +116 -104
  29. package/dist/runtime/components/form/CheckboxGroup.vue +99 -87
  30. package/dist/runtime/components/form/CodeEditor.vue +45 -37
  31. package/dist/runtime/components/form/Date.vue +270 -258
  32. package/dist/runtime/components/form/DateTime.vue +220 -208
  33. package/dist/runtime/components/form/Dialog.vue +178 -166
  34. package/dist/runtime/components/form/EditPad.vue +157 -145
  35. package/dist/runtime/components/form/File.vue +295 -283
  36. package/dist/runtime/components/form/Hidden.vue +44 -32
  37. package/dist/runtime/components/form/Iterator.vue +538 -526
  38. package/dist/runtime/components/form/Login.vue +143 -131
  39. package/dist/runtime/components/form/Pad.vue +399 -387
  40. package/dist/runtime/components/form/SignPad.vue +226 -218
  41. package/dist/runtime/components/form/System.vue +34 -26
  42. package/dist/runtime/components/form/Table.vue +391 -379
  43. package/dist/runtime/components/form/TableData.vue +236 -224
  44. package/dist/runtime/components/form/Time.vue +177 -165
  45. package/dist/runtime/components/form/images/Capture.vue +245 -237
  46. package/dist/runtime/components/form/images/Edit.vue +133 -121
  47. package/dist/runtime/components/form/images/Field.vue +331 -320
  48. package/dist/runtime/components/form/images/Pad.vue +54 -42
  49. package/dist/runtime/components/label/Date.vue +37 -29
  50. package/dist/runtime/components/label/DateAgo.vue +102 -94
  51. package/dist/runtime/components/label/DateCount.vue +152 -144
  52. package/dist/runtime/components/label/Field.vue +111 -103
  53. package/dist/runtime/components/label/FormatMoney.vue +37 -29
  54. package/dist/runtime/components/label/Mask.vue +46 -38
  55. package/dist/runtime/components/label/Object.vue +21 -13
  56. package/dist/runtime/components/master/Autocomplete.vue +89 -81
  57. package/dist/runtime/components/master/Combobox.vue +88 -80
  58. package/dist/runtime/components/master/RadioGroup.vue +90 -78
  59. package/dist/runtime/components/master/Select.vue +70 -62
  60. package/dist/runtime/components/master/label.vue +55 -47
  61. package/dist/runtime/components/model/Autocomplete.vue +91 -79
  62. package/dist/runtime/components/model/Combobox.vue +90 -78
  63. package/dist/runtime/components/model/Pad.vue +114 -102
  64. package/dist/runtime/components/model/Select.vue +78 -72
  65. package/dist/runtime/components/model/Table.vue +370 -358
  66. package/dist/runtime/components/model/iterator.vue +497 -489
  67. package/dist/runtime/components/model/label.vue +58 -50
  68. package/dist/runtime/components/pdf/Print.vue +75 -63
  69. package/dist/runtime/components/pdf/View.vue +146 -134
  70. package/dist/runtime/composables/alert.d.ts +4 -0
  71. package/dist/runtime/composables/api.d.ts +4 -0
  72. package/dist/runtime/composables/dialog.d.ts +1 -1
  73. package/dist/runtime/composables/document/templateFormHidden.d.ts +4 -0
  74. package/dist/runtime/composables/graphql.d.ts +1 -1
  75. package/dist/runtime/composables/graphqlModel.d.ts +9 -9
  76. package/dist/runtime/composables/graphqlModelItem.d.ts +7 -7
  77. package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
  78. package/dist/runtime/composables/localStorageModel.d.ts +4 -0
  79. package/dist/runtime/composables/lookupList.d.ts +4 -0
  80. package/dist/runtime/composables/menu.d.ts +4 -0
  81. package/dist/runtime/composables/useMrzReader.d.ts +48 -0
  82. package/dist/runtime/composables/useMrzReader.js +423 -0
  83. package/dist/runtime/composables/useTesseract.d.ts +16 -0
  84. package/dist/runtime/composables/useTesseract.js +45 -0
  85. package/dist/runtime/composables/userPermission.d.ts +1 -1
  86. package/dist/runtime/labs/Calendar.vue +99 -99
  87. package/dist/runtime/labs/form/EditMobile.vue +152 -152
  88. package/dist/runtime/labs/form/TextFieldMask.vue +43 -43
  89. package/dist/runtime/plugins/clientConfig.d.ts +1 -1
  90. package/dist/runtime/plugins/default.d.ts +1 -1
  91. package/dist/runtime/plugins/dialogManager.d.ts +1 -1
  92. package/dist/runtime/plugins/permission.d.ts +1 -1
  93. package/dist/runtime/types/alert.d.ts +11 -11
  94. package/dist/runtime/types/clientConfig.d.ts +13 -13
  95. package/dist/runtime/types/dialogManager.d.ts +35 -35
  96. package/dist/runtime/types/formDialog.d.ts +5 -5
  97. package/dist/runtime/types/graphqlOperation.d.ts +23 -23
  98. package/dist/runtime/types/menu.d.ts +31 -31
  99. package/dist/runtime/types/modules.d.ts +7 -7
  100. package/dist/runtime/types/permission.d.ts +13 -13
  101. package/dist/runtime/utils/asset.d.ts +2 -0
  102. package/dist/runtime/utils/asset.js +49 -0
  103. package/package.json +131 -122
  104. package/scripts/enrich-vue-docs-from-ai.mjs +197 -0
  105. package/scripts/generate-ai-summary.mjs +321 -0
  106. package/scripts/generate-composables-md.mjs +129 -0
  107. package/scripts/postInstall.cjs +70 -70
  108. package/templates/.codegen/codegen.ts +32 -32
  109. package/templates/.codegen/plugin-schema-object.js +161 -161
  110. package/templates/public/tesseract/mrz.traineddata.gz +0 -0
  111. package/templates/public/tesseract/ocrb.traineddata.gz +0 -0
@@ -1,524 +1,536 @@
1
- <script lang="ts" setup>
2
- import {computed, ref, watch} from 'vue'
3
- import * as prettier from 'prettier'
4
- import prettierPluginHtml from 'prettier/plugins/html'
5
- import {useDocumentTemplate, validationRulesRegex,optionStringToChoiceObject} from '../../composables/document/template'
6
- import {autoActionHeader,templateToHeader} from "../../composables/document/templateFormTable";
7
- import {cloneDeep} from "lodash-es";
8
- import VueJsonPretty from 'vue-json-pretty';
9
- import 'vue-json-pretty/lib/styles.css';
10
- import {safeParseJSONDeep} from "../../utils/object";
11
-
12
- interface Props {
13
- title?: string
14
- disableAdvanceMode?: boolean
15
- }
16
-
17
- const props = withDefaults(defineProps<Props>(), {
18
- title: "Document Template",
19
- disableAdvanceMode: false,
20
- })
21
-
22
- const emit = defineEmits(['update:modelValue'])
23
- const modelValue = defineModel<string|Record<string, any>[]>()
24
-
25
- const advanceModeCode = ref<string>()
26
- const isAdvanceMode = computed(() => {
27
- return modelValue.value && ((typeof modelValue.value === "string") && !isValidJsonArrayOfObjects(modelValue.value))
28
- })
29
-
30
- const templateItems = ref<Record<string, any>[]>([])
31
-
32
- const headers = ref([
33
- { title: '',
34
- key: 'operation',
35
- width: '120px',
36
- },
37
- {
38
- title: 'Rec No.',
39
- key: 'recNo',
40
- },
41
- {
42
- title: 'Input Type',
43
- key: 'inputType',
44
- },
45
- {
46
- title: 'Width',
47
- key: 'width',
48
- },
49
- {
50
- title: 'Input Label',
51
- key: 'inputLabel',
52
- },
53
- {
54
- title: 'Variable Name',
55
- key: 'variableName',
56
- },
57
- {
58
- title: 'Configuration',
59
- key: 'configuration',
60
- },
61
- {
62
- title: 'Action',
63
- key: 'action',
64
- width: '120px',
65
- },
66
- ])
67
-
68
- const formTableHeaders = ref([
69
- {
70
- title: 'Title',
71
- key: 'title',
72
- },
73
- {
74
- title: 'Key',
75
- key: 'key',
76
- },
77
- {
78
- title: 'Width',
79
- key: 'width',
80
- },
81
- {
82
- title: 'Action',
83
- key: 'action',
84
- width: '120px',
85
- },
86
- ])
87
-
88
- const choiceHeaders = ref([
89
- {
90
- title: 'Label',
91
- key: 'label',
92
- },
93
- {
94
- title: 'Value',
95
- key: 'value',
96
- },
97
- {
98
- title: 'Action',
99
- key: 'action',
100
- width: '120px',
101
- },
102
- ])
103
-
104
-
105
- function isValidJsonArrayOfObjects(str: string | undefined) {
106
- try {
107
- const parsed = JSON.parse(str as string)
108
- return Array.isArray(parsed) && parsed.every(item => typeof item === 'object' && item !== null && !Array.isArray(item))
109
- }
110
- catch (e) {
111
- return false
112
- }
113
- }
114
-
115
- watch(templateItems, (newValue) => {
116
- if (!isAdvanceMode.value) modelValue.value = JSON.stringify(newValue)
117
- }, { deep: true })
118
-
119
- watch(modelValue, (newValue) => {
120
- if (typeof newValue === "string" && isValidJsonArrayOfObjects(newValue)) templateItems.value = JSON.parse(newValue as string)
121
- else if (typeof newValue === "string") advanceModeCode.value = newValue
122
- else if (newValue) templateItems.value = cloneDeep(newValue)
123
- }, { deep: true, immediate: true })
124
-
125
- watch(advanceModeCode, (newValue)=>{
126
- if (isAdvanceMode.value) modelValue.value = newValue
127
- })
128
-
129
- async function convertToAdvanceMode() {
130
- if (!isAdvanceMode.value) {
131
- modelValue.value = await prettier.format(useDocumentTemplate(templateItems.value).replaceAll('>', '>\n'), { parser: 'html', plugins: [prettierPluginHtml] })
132
- }
133
- }
134
- const inputTypeChoice = ref([
135
- { label: 'Text Field', value: 'VTextField' },
136
- { label: 'Text Area', value: 'VTextarea' },
137
- { label: 'Text Date Picker', value: 'FormDate' },
138
- { label: 'Text Time Picker', value: 'FormTime' },
139
- { label: 'Text Date & Time Picker', value: 'FormDateTime' },
140
- { label: 'Select Dropdown', value: 'VSelect' },
141
- { label: 'Select Combobox', value: 'VCombobox' },
142
- { label: 'Autocomplete', value: 'VAutocomplete' },
143
- { label: 'Autocomplete from Master', value: 'MasterAutocomplete' },
144
- { label: 'Radio Buttons', value: 'VRadio' },
145
- { label: 'Radio Buttons Inline', value: 'VRadioInline' },
146
- { label: 'Checkbox', value: 'VCheckbox' },
147
- { label: 'Checkbox Group', value: 'FormCheckboxGroup' },
148
- { label: 'Switch', value: 'VSwitch' },
149
- { label: 'File Upload', value: 'FormFile' },
150
- { label: 'Signature Pad', value: 'FormSignPad' },
151
- { label: 'Table', value: 'FormTable' },
152
- { label: 'Table Data', value: 'FormTableData' },
153
- { label: '[Decoration] Header', value: 'Header' },
154
- { label: '[Decoration] Separator', value: 'Separator' },
155
- { label: '[Advanced] Hidden Field', value: 'FormHidden' },
156
- { label: '[Advanced] Inherit Form', value: 'DocumentForm' },
157
- { label: '[Advanced] Custom Code', value: 'CustomCode' },
158
- ]);
159
-
160
- const requireOption = ref(['VSelect', 'VAutocomplete', 'VCombobox', 'VRadio', 'VRadioInline', 'MasterAutocomplete','FormTable','FormTableData','DocumentForm','FormCheckboxGroup'])
161
- const notRequireVariable = ref(['Header', 'Separator', 'CustomCode','DocumentForm'])
162
- const notRequireLabel = ref(['Separator', 'CustomCode', 'FormFile', 'FormHidden','DocumentForm'])
163
- const notRequireWidth = ref(['Separator', 'FormHidden','DocumentForm'])
164
- const notRequireOptions = ref(['Separator','CustomCode', 'FormFile'])
165
- const notRequireRules = ref(['Separator','Header','CustomCode','FormHidden','DocumentForm'])
166
- const notRequireInputAttributes = ref(['CustomCode','Header','DocumentForm'])
167
- const notRequireColumnAttributes = ref(['Separator', 'FormHidden','DocumentForm'])
168
- const notRequireAdvancedSetting = ref(['Separator','CustomCode'])
169
- const notRequireClassAndStyle = ref(['FormHidden'])
170
-
171
- const hasSpecificOption = ref(['FormHidden','FormTable','FormTableData'])
172
-
173
- const choiceOption = ref(['VRadio', 'VRadioInline','VSelect', 'VAutocomplete', 'VCombobox','FormCheckboxGroup'])
174
- const inputOptionsLabel = ref<Record<string,string>>({
175
- 'MasterAutocomplete' : "Group Key",
176
- 'Header' : "Class",
177
- 'DocumentForm': "Template Code",
178
- })
179
-
180
- const ruleOptions = (inputType: string) => (value: any) => {
181
- if (choiceOption.value.includes(inputType) && !(/^[^'",]+(,[^'",]+)*$/.test(value))) return 'Invalid options format'
182
-
183
- return true
184
- }
185
- </script>
186
-
187
- <template>
188
- <FormTable
189
- v-if="!isAdvanceMode"
190
- v-model="templateItems"
191
- :headers="headers"
192
- :title="props.title"
193
- >
194
- <template #toolbarItems>
195
- <VBtn
196
- color="primary"
197
- variant="flat"
198
- @click="convertToAdvanceMode()"
199
- v-if="!disableAdvanceMode"
200
- >
201
- Convert To Advance
202
- </VBtn>
203
- </template>
204
- <template #item.recNo="{internalItem}">
205
- {{ internalItem.index }}
206
- </template>
207
- <template #form="{ data, rules }">
208
- <v-container fluid>
209
- <v-row dense>
210
- <v-col cols="3">
211
- <v-combobox
212
- v-model="data.inputType"
213
- label="Input Type"
214
- :items="inputTypeChoice"
215
- item-title="label"
216
- item-value="value"
217
- :return-object="false"
218
- :rules="[rules.require()]"
219
- />
220
- </v-col>
221
- <v-col cols="1" v-if="!notRequireWidth.includes(data.inputType)">
222
- <v-text-field
223
- v-model="data.width"
224
- label="Width"
225
- :rules="[rules.require()]"
226
- type="number"
227
- />
228
- <form-hidden v-model="data.inputOptions" :item-value="data.inputType" :hook="(_result: any,model: any,newValue: any,oldValue: any)=>{return (newValue && oldValue) ? undefined : model}"></form-hidden>
229
- </v-col>
230
- <v-col cols="4" v-if="!notRequireLabel.includes(data.inputType)">
231
- <v-text-field
232
- v-model="data.inputLabel"
233
- label="Input Label"
234
- :rules="[rules.require()]"
235
- />
236
- </v-col>
237
- <v-col cols="4" v-if="!notRequireVariable.includes(data.inputType)">
238
- <v-text-field
239
- v-model="data.variableName"
240
- label="Variable Name"
241
- :rules="[rules.require()]"
242
- />
243
- </v-col>
244
- <v-col
245
- v-if="!notRequireOptions.includes(data.inputType)"
246
- cols="12"
247
- >
248
- <form-pad v-model="data.inputOptions" v-if="data.inputType=='FormTable'">
249
- <template #default="{data: optionData}">
250
- <v-row dense>
251
- <v-col cols="12">
252
- <form-table v-model="optionData.headers" :headers="formTableHeaders" title="Headers">
253
- <template #form="{data: headerData,rules}">
254
- <v-container fluid>
255
- <v-row dense>
256
- <v-col cols="6"><v-text-field v-model="headerData.title" label="Title"></v-text-field></v-col>
257
- <v-col cols="3"><v-text-field v-model="headerData.key" label="Key" :rules="[rules.require()]"></v-text-field></v-col>
258
- <v-col cols="3"><v-text-field v-model="headerData.width" label="Width"></v-text-field></v-col>
259
- </v-row>
260
- <v-row dense>
261
- <v-col cols="12"><v-textarea v-model="headerData.template" label="Item Template"></v-textarea></v-col>
262
- </v-row>
263
- </v-container>
264
- </template>
265
- </form-table>
266
- </v-col>
267
- <v-col cols="12">
268
- <document-template-builder v-model="optionData.formTemplate" title="Form Template"></document-template-builder>
269
- </v-col>
270
- </v-row>
271
- </template>
272
- </form-pad>
273
- <form-pad v-model="data.inputOptions" v-if="data.inputType=='FormTableData'">
274
- <template #default="{data: optionData}">
275
- <v-row dense>
276
- <v-col cols="12">
277
- <tabs-group>
278
- <template #tabs>
279
- <v-tab value="itemTemplate">Item Template</v-tab>
280
- <v-tab value="dataTemplate">Data Template</v-tab>
281
- <v-tab value="header">Header</v-tab>
282
- </template>
283
- <template #items>
284
- <v-tabs-window-item value="itemTemplate">
285
- <document-template-builder v-model="optionData.itemTemplate" title="Item Template" disable-advance-mode></document-template-builder>
286
- </v-tabs-window-item>
287
- <v-tabs-window-item value="dataTemplate">
288
- <document-template-builder v-model="optionData.dataTemplate" title="Data Template" disable-advance-mode></document-template-builder>
289
- </v-tabs-window-item>
290
- <v-tabs-window-item value="header">
291
- <form-table v-model="optionData.headers" :headers="formTableHeaders" title="Headers">
292
- <template #form="{data: headerData,rules}">
293
- <v-container fluid>
294
- <v-row dense>
295
- <v-col cols="6"><v-text-field v-model="headerData.title" label="Title"></v-text-field></v-col>
296
- <v-col cols="3"><v-text-field v-model="headerData.key" label="Key" :rules="[rules.require()]"></v-text-field></v-col>
297
- <v-col cols="3"><v-text-field v-model="headerData.width" label="Width"></v-text-field></v-col>
298
- </v-row>
299
- <v-row dense>
300
- <v-col cols="12"><v-text-field v-model="headerData.value" label="Value"></v-text-field></v-col>
301
- <v-col cols="12"><v-textarea v-model="headerData.template" label="Item Template"></v-textarea></v-col>
302
- </v-row>
303
- </v-container>
304
- </template>
305
- </form-table>
306
- </v-tabs-window-item>
307
- </template>
308
- </tabs-group>
309
- </v-col>
310
- <v-col cols="12">
311
- <form-table v-model="optionData.items" :headers="(optionData.headers && optionData.headers.length>0) ? autoActionHeader(optionData.headers) : autoActionHeader(templateToHeader(optionData.itemTemplate))" title="Items">
312
- <template #form="{data}">
313
- <form-pad :model-value="data" :template="optionData.itemTemplate"></form-pad>
314
- </template>
315
- </form-table>
316
- </v-col>
317
- <v-col cols="12">
318
- <v-row dense>
319
- <v-col cols="4">
320
- <v-radio-group v-model="optionData.disableApplyToAll" inline>
321
- <template #prepend>
322
- <span class="opacity-60"> Disable Apply to All</span>
323
- </template>
324
- <v-radio label="No" value="false" hide-details> </v-radio>
325
- <v-radio label="Yes" value="true" hide-details> </v-radio>
326
- <v-radio label="Partial" value="partial" hide-details> </v-radio>
327
- </v-radio-group>
328
- </v-col>
329
- <v-col cols="8">
330
- <VTextField
331
- variant="underlined"
332
- v-model="optionData.disableApplyToAllPartial"
333
- label="Disable Apply To All Column"
334
- v-if="optionData.disableApplyToAll=='partial'"
335
- >
336
- </VTextField>
337
- </v-col>
338
- </v-row>
339
- </v-col>
340
- </v-row>
341
- </template>
342
- </form-pad>
343
- <form-pad v-model="data.inputOptions" v-if="data.inputType=='FormHidden'">
344
- <template #default="{data: optionData}">
345
- <v-row dense>
346
- <v-col cols="12">
347
- <v-text-field
348
- v-model="optionData.hook"
349
- label="Hook"
350
- />
351
- </v-col>
352
- <v-col cols="12">
353
- <v-text-field
354
- v-model="optionData.itemValue"
355
- label="Item Value"
356
- />
357
- </v-col>
358
- </v-row>
359
- </template>
360
- </form-pad>
361
- <form-table v-model="data.inputOptions" :headers="choiceHeaders" title="Choices" v-if="choiceOption.includes(data.inputType) && (!data.inputOptions || typeof data.inputOptions === 'object')">
362
- <template #form="{data: optionData,rules}">
363
- <v-container fluid>
364
- <v-row dense>
365
- <v-col cols="6"><v-text-field v-model="optionData.label" label="Label"></v-text-field></v-col>
366
- <v-col cols="6"><v-text-field v-model="optionData.value" label="Value" :rules="[rules.require()]"></v-text-field></v-col>
367
- </v-row>
368
- </v-container>
369
- </template>
370
- </form-table>
371
- <form-hidden v-model="data.inputOptions" :itemValue="data.inputOptions" :hook="(option: any)=>optionStringToChoiceObject(option)" v-if="choiceOption.includes(data.inputType) && data.inputOptions && typeof data.inputOptions === 'string'"></form-hidden>
372
- <v-textarea
373
- v-model="data.inputOptions"
374
- :label="inputOptionsLabel[data.inputType] || 'Input Options'"
375
- auto-grow
376
- :rules="[rules.requireIf(requireOption.includes(data.inputType)), ruleOptions(data.inputType)]"
377
- v-if="!hasSpecificOption.includes(data.inputType) && !choiceOption.includes(data.inputType)"
378
- />
379
- </v-col>
380
-
381
- <v-col
382
- v-if="data.inputType=='CustomCode'"
383
- cols="12"
384
- >
385
- <FormCodeEditor
386
- v-model="data.inputCustomCode"
387
- label="Custom Code"
388
- :rules="[rules.require()]"
389
- />
390
- </v-col>
391
- </v-row>
392
- <v-row dense>
393
- <v-col>
394
- <v-expansion-panels>
395
- <v-expansion-panel v-if="!notRequireRules.includes(data.inputType)">
396
- <v-expansion-panel-title collapse-icon="mdi mdi-minus" expand-icon="mdi mdi-plus" class="font-weight-bold">Validations</v-expansion-panel-title>
397
- <v-expansion-panel-text>
398
- <v-container fluid>
399
- <v-row dense>
400
- <v-col cols="12">
401
- <v-text-field
402
- v-model="data.validationRules"
403
- label="Validation Rules"
404
- :rules="[rules.regex(validationRulesRegex)]"
405
- />
406
- <b>Available rules :</b> require, requireIf(condition), requireTrue, requireTrueIf(condition), numeric, range(min,max), integer, unique, length(length), lengthGreater(length), lengthLess(length), telephone, email, regex(regex), idcard, DateFuture, DatetimeFuture, DateHappen, DatetimeHappen, DateAfter(date), DateBefore(Date), DateEqual(date)
407
- </v-col>
408
- </v-row>
409
- </v-container>
410
- </v-expansion-panel-text>
411
- </v-expansion-panel>
412
- <v-expansion-panel v-if="!notRequireAdvancedSetting.includes(data.inputType)">
413
- <v-expansion-panel-title collapse-icon="mdi mdi-minus" expand-icon="mdi mdi-plus" class="font-weight-bold">Advanced settings</v-expansion-panel-title>
414
- <v-expansion-panel-text>
415
- <v-container fluid>
416
- <v-row dense>
417
- <v-col cols="12" md="6" v-if="!notRequireInputAttributes.includes(data.inputType)">
418
- <v-text-field
419
- v-model="data.inputAttributes"
420
- label="Input Attributes"
421
- />
422
- </v-col>
423
- <v-col cols="12" md="6" v-if="!notRequireColumnAttributes.includes(data.inputType)">
424
- <v-text-field
425
- v-model="data.columnAttributes"
426
- label="Column Attributes"
427
- />
428
- </v-col>
429
- <v-col cols="12" md="6">
430
- <v-text-field
431
- v-model="data.conditionalDisplay"
432
- label="Conditional Display"
433
- />
434
- </v-col>
435
- <v-col cols="12" md="6">
436
- <v-text-field
437
- v-model="data.computedValue"
438
- label="Computed Value"
439
- />
440
- </v-col>
441
- <v-col cols="12" md="6">
442
- <v-text-field
443
- v-model="data.retrievedValue"
444
- label="Retrieved Value"
445
- />
446
- </v-col>
447
- </v-row>
448
- </v-container>
449
- </v-expansion-panel-text>
450
- </v-expansion-panel>
451
- <v-expansion-panel v-if="!notRequireClassAndStyle.includes(data.inputType)">
452
- <v-expansion-panel-title collapse-icon="mdi mdi-minus" expand-icon="mdi mdi-plus" class="font-weight-bold">Class and Styles</v-expansion-panel-title>
453
- <v-expansion-panel-text>
454
- <v-container fluid>
455
- <v-row dense>
456
- <v-col cols="12">
457
- <v-text-field
458
- v-model="data.customClass"
459
- label="Custom Class"
460
- />
461
- </v-col>
462
- <v-col cols="12">
463
- <v-text-field
464
- v-model="data.customStyle"
465
- label="Custom Styles"
466
- />
467
- </v-col>
468
- </v-row>
469
- </v-container>
470
- </v-expansion-panel-text>
471
- </v-expansion-panel>
472
- </v-expansion-panels>
473
- </v-col>
474
- </v-row>
475
- </v-container>
476
- </template>
477
- <template #item.configuration="props">
478
- <v-sheet
479
- elevation="1"
480
- max-height="250"
481
- class="overflow-y-auto my-1 pa-2"
482
- v-if="props.item.inputType=='CustomCode'
483
- || props.item.validationRules
484
- || props.item.inputOptions
485
- || props.item.inputAttributes
486
- || props.item.columnAttributes
487
- || props.item.conditionalDisplay
488
- || props.item.computedValue
489
- || props.item.retrievedValue"
490
- >
491
- <template v-if="props.item.inputType=='CustomCode'">
492
- <b>Custom Code :</b><br>
493
- <span style="white-space: pre-line">{{ props.item.inputCustomCode }}</span>
494
- </template>
495
- <template v-if="props.item.validationRules">
496
- <b>Validation Rules :</b> {{ props.item.validationRules }}<br>
497
- </template>
498
- <template v-if="props.item.inputOptions">
499
- <b>Input Options :</b>
500
- <vue-json-pretty :data="safeParseJSONDeep(props.item.inputOptions)" />
501
- </template>
502
- <template v-if="props.item.inputAttributes">
503
- <b>Input Attributes :</b> {{ props.item.inputAttributes }}<br>
504
- </template>
505
- <template v-if="props.item.columnAttributes">
506
- <b>Column Attributes :</b> {{ props.item.columnAttributes }}<br>
507
- </template>
508
- <template v-if="props.item.conditionalDisplay">
509
- <b>Conditional Display :</b> {{ props.item.conditionalDisplay }}<br>
510
- </template>
511
- <template v-if="props.item.computedValue">
512
- <b>Computed Value :</b> {{ props.item.computedValue }}<br>
513
- </template>
514
- <template v-if="props.item.retrievedValue">
515
- <b>Retrieved Value :</b> {{ props.item.retrievedValue }}<br>
516
- </template>
517
- </v-sheet>
518
- </template>
519
- </FormTable>
520
- <FormCodeEditor
521
- v-else
522
- v-model="advanceModeCode"
523
- />
524
- </template>
1
+ <script lang="ts" setup>
2
+ /**
3
+ * DocumentTemplateBuilder supports document-template rendering and synchronizes template-defined field behavior with runtime data.
4
+ * This doc block is consumed by vue-docgen for generated API documentation.
5
+ */
6
+ import {computed, ref, watch} from 'vue'
7
+ import * as prettier from 'prettier'
8
+ import prettierPluginHtml from 'prettier/plugins/html'
9
+ import {useDocumentTemplate, validationRulesRegex,optionStringToChoiceObject} from '../../composables/document/template'
10
+ import {autoActionHeader,templateToHeader} from "../../composables/document/templateFormTable";
11
+ import {cloneDeep} from "lodash-es";
12
+ import VueJsonPretty from 'vue-json-pretty';
13
+ import 'vue-json-pretty/lib/styles.css';
14
+ import {safeParseJSONDeep} from "../../utils/object";
15
+
16
+ interface Props {
17
+ title?: string // Title text displayed in the component header or dialog.
18
+ disableAdvanceMode?: boolean // Disables advanced editor mode toggles and actions.
19
+ }
20
+
21
+ /**
22
+ * Public props accepted by DocumentTemplateBuilder.
23
+ * Document each prop field with intent, defaults, and side effects for clear generated docs.
24
+ */
25
+ const props = withDefaults(defineProps<Props>(), {
26
+ title: "Document Template",
27
+ disableAdvanceMode: false,
28
+ })
29
+
30
+ /**
31
+ * Custom events emitted by DocumentTemplateBuilder.
32
+ * Parents can listen to these events to react to user actions and internal state changes.
33
+ */
34
+ const emit = defineEmits(['update:modelValue'])
35
+ const modelValue = defineModel<string|Record<string, any>[]>()
36
+
37
+ const advanceModeCode = ref<string>()
38
+ const isAdvanceMode = computed(() => {
39
+ return modelValue.value && ((typeof modelValue.value === "string") && !isValidJsonArrayOfObjects(modelValue.value))
40
+ })
41
+
42
+ const templateItems = ref<Record<string, any>[]>([])
43
+
44
+ const headers = ref([
45
+ { title: '',
46
+ key: 'operation',
47
+ width: '120px',
48
+ },
49
+ {
50
+ title: 'Rec No.',
51
+ key: 'recNo',
52
+ },
53
+ {
54
+ title: 'Input Type',
55
+ key: 'inputType',
56
+ },
57
+ {
58
+ title: 'Width',
59
+ key: 'width',
60
+ },
61
+ {
62
+ title: 'Input Label',
63
+ key: 'inputLabel',
64
+ },
65
+ {
66
+ title: 'Variable Name',
67
+ key: 'variableName',
68
+ },
69
+ {
70
+ title: 'Configuration',
71
+ key: 'configuration',
72
+ },
73
+ {
74
+ title: 'Action',
75
+ key: 'action',
76
+ width: '120px',
77
+ },
78
+ ])
79
+
80
+ const formTableHeaders = ref([
81
+ {
82
+ title: 'Title',
83
+ key: 'title',
84
+ },
85
+ {
86
+ title: 'Key',
87
+ key: 'key',
88
+ },
89
+ {
90
+ title: 'Width',
91
+ key: 'width',
92
+ },
93
+ {
94
+ title: 'Action',
95
+ key: 'action',
96
+ width: '120px',
97
+ },
98
+ ])
99
+
100
+ const choiceHeaders = ref([
101
+ {
102
+ title: 'Label',
103
+ key: 'label',
104
+ },
105
+ {
106
+ title: 'Value',
107
+ key: 'value',
108
+ },
109
+ {
110
+ title: 'Action',
111
+ key: 'action',
112
+ width: '120px',
113
+ },
114
+ ])
115
+
116
+
117
+ function isValidJsonArrayOfObjects(str: string | undefined) {
118
+ try {
119
+ const parsed = JSON.parse(str as string)
120
+ return Array.isArray(parsed) && parsed.every(item => typeof item === 'object' && item !== null && !Array.isArray(item))
121
+ }
122
+ catch (e) {
123
+ return false
124
+ }
125
+ }
126
+
127
+ watch(templateItems, (newValue) => {
128
+ if (!isAdvanceMode.value) modelValue.value = JSON.stringify(newValue)
129
+ }, { deep: true })
130
+
131
+ watch(modelValue, (newValue) => {
132
+ if (typeof newValue === "string" && isValidJsonArrayOfObjects(newValue)) templateItems.value = JSON.parse(newValue as string)
133
+ else if (typeof newValue === "string") advanceModeCode.value = newValue
134
+ else if (newValue) templateItems.value = cloneDeep(newValue)
135
+ }, { deep: true, immediate: true })
136
+
137
+ watch(advanceModeCode, (newValue)=>{
138
+ if (isAdvanceMode.value) modelValue.value = newValue
139
+ })
140
+
141
+ async function convertToAdvanceMode() {
142
+ if (!isAdvanceMode.value) {
143
+ modelValue.value = await prettier.format(useDocumentTemplate(templateItems.value).replaceAll('>', '>\n'), { parser: 'html', plugins: [prettierPluginHtml] })
144
+ }
145
+ }
146
+ const inputTypeChoice = ref([
147
+ { label: 'Text Field', value: 'VTextField' },
148
+ { label: 'Text Area', value: 'VTextarea' },
149
+ { label: 'Text Date Picker', value: 'FormDate' },
150
+ { label: 'Text Time Picker', value: 'FormTime' },
151
+ { label: 'Text Date & Time Picker', value: 'FormDateTime' },
152
+ { label: 'Select Dropdown', value: 'VSelect' },
153
+ { label: 'Select Combobox', value: 'VCombobox' },
154
+ { label: 'Autocomplete', value: 'VAutocomplete' },
155
+ { label: 'Autocomplete from Master', value: 'MasterAutocomplete' },
156
+ { label: 'Radio Buttons', value: 'VRadio' },
157
+ { label: 'Radio Buttons Inline', value: 'VRadioInline' },
158
+ { label: 'Checkbox', value: 'VCheckbox' },
159
+ { label: 'Checkbox Group', value: 'FormCheckboxGroup' },
160
+ { label: 'Switch', value: 'VSwitch' },
161
+ { label: 'File Upload', value: 'FormFile' },
162
+ { label: 'Signature Pad', value: 'FormSignPad' },
163
+ { label: 'Table', value: 'FormTable' },
164
+ { label: 'Table Data', value: 'FormTableData' },
165
+ { label: '[Decoration] Header', value: 'Header' },
166
+ { label: '[Decoration] Separator', value: 'Separator' },
167
+ { label: '[Advanced] Hidden Field', value: 'FormHidden' },
168
+ { label: '[Advanced] Inherit Form', value: 'DocumentForm' },
169
+ { label: '[Advanced] Custom Code', value: 'CustomCode' },
170
+ ]);
171
+
172
+ const requireOption = ref(['VSelect', 'VAutocomplete', 'VCombobox', 'VRadio', 'VRadioInline', 'MasterAutocomplete','FormTable','FormTableData','DocumentForm','FormCheckboxGroup'])
173
+ const notRequireVariable = ref(['Header', 'Separator', 'CustomCode','DocumentForm'])
174
+ const notRequireLabel = ref(['Separator', 'CustomCode', 'FormFile', 'FormHidden','DocumentForm'])
175
+ const notRequireWidth = ref(['Separator', 'FormHidden','DocumentForm'])
176
+ const notRequireOptions = ref(['Separator','CustomCode', 'FormFile'])
177
+ const notRequireRules = ref(['Separator','Header','CustomCode','FormHidden','DocumentForm'])
178
+ const notRequireInputAttributes = ref(['CustomCode','Header','DocumentForm'])
179
+ const notRequireColumnAttributes = ref(['Separator', 'FormHidden','DocumentForm'])
180
+ const notRequireAdvancedSetting = ref(['Separator','CustomCode'])
181
+ const notRequireClassAndStyle = ref(['FormHidden'])
182
+
183
+ const hasSpecificOption = ref(['FormHidden','FormTable','FormTableData'])
184
+
185
+ const choiceOption = ref(['VRadio', 'VRadioInline','VSelect', 'VAutocomplete', 'VCombobox','FormCheckboxGroup'])
186
+ const inputOptionsLabel = ref<Record<string,string>>({
187
+ 'MasterAutocomplete' : "Group Key",
188
+ 'Header' : "Class",
189
+ 'DocumentForm': "Template Code",
190
+ })
191
+
192
+ const ruleOptions = (inputType: string) => (value: any) => {
193
+ if (choiceOption.value.includes(inputType) && !(/^[^'",]+(,[^'",]+)*$/.test(value))) return 'Invalid options format'
194
+
195
+ return true
196
+ }
197
+ </script>
198
+
199
+ <template>
200
+ <FormTable
201
+ v-if="!isAdvanceMode"
202
+ v-model="templateItems"
203
+ :headers="headers"
204
+ :title="props.title"
205
+ >
206
+ <template #toolbarItems>
207
+ <VBtn
208
+ color="primary"
209
+ variant="flat"
210
+ @click="convertToAdvanceMode()"
211
+ v-if="!disableAdvanceMode"
212
+ >
213
+ Convert To Advance
214
+ </VBtn>
215
+ </template>
216
+ <template #item.recNo="{internalItem}">
217
+ {{ internalItem.index }}
218
+ </template>
219
+ <template #form="{ data, rules }">
220
+ <v-container fluid>
221
+ <v-row dense>
222
+ <v-col cols="3">
223
+ <v-combobox
224
+ v-model="data.inputType"
225
+ label="Input Type"
226
+ :items="inputTypeChoice"
227
+ item-title="label"
228
+ item-value="value"
229
+ :return-object="false"
230
+ :rules="[rules.require()]"
231
+ />
232
+ </v-col>
233
+ <v-col cols="1" v-if="!notRequireWidth.includes(data.inputType)">
234
+ <v-text-field
235
+ v-model="data.width"
236
+ label="Width"
237
+ :rules="[rules.require()]"
238
+ type="number"
239
+ />
240
+ <form-hidden v-model="data.inputOptions" :item-value="data.inputType" :hook="(_result: any,model: any,newValue: any,oldValue: any)=>{return (newValue && oldValue) ? undefined : model}"></form-hidden>
241
+ </v-col>
242
+ <v-col cols="4" v-if="!notRequireLabel.includes(data.inputType)">
243
+ <v-text-field
244
+ v-model="data.inputLabel"
245
+ label="Input Label"
246
+ :rules="[rules.require()]"
247
+ />
248
+ </v-col>
249
+ <v-col cols="4" v-if="!notRequireVariable.includes(data.inputType)">
250
+ <v-text-field
251
+ v-model="data.variableName"
252
+ label="Variable Name"
253
+ :rules="[rules.require()]"
254
+ />
255
+ </v-col>
256
+ <v-col
257
+ v-if="!notRequireOptions.includes(data.inputType)"
258
+ cols="12"
259
+ >
260
+ <form-pad v-model="data.inputOptions" v-if="data.inputType=='FormTable'">
261
+ <template #default="{data: optionData}">
262
+ <v-row dense>
263
+ <v-col cols="12">
264
+ <form-table v-model="optionData.headers" :headers="formTableHeaders" title="Headers">
265
+ <template #form="{data: headerData,rules}">
266
+ <v-container fluid>
267
+ <v-row dense>
268
+ <v-col cols="6"><v-text-field v-model="headerData.title" label="Title"></v-text-field></v-col>
269
+ <v-col cols="3"><v-text-field v-model="headerData.key" label="Key" :rules="[rules.require()]"></v-text-field></v-col>
270
+ <v-col cols="3"><v-text-field v-model="headerData.width" label="Width"></v-text-field></v-col>
271
+ </v-row>
272
+ <v-row dense>
273
+ <v-col cols="12"><v-textarea v-model="headerData.template" label="Item Template"></v-textarea></v-col>
274
+ </v-row>
275
+ </v-container>
276
+ </template>
277
+ </form-table>
278
+ </v-col>
279
+ <v-col cols="12">
280
+ <document-template-builder v-model="optionData.formTemplate" title="Form Template"></document-template-builder>
281
+ </v-col>
282
+ </v-row>
283
+ </template>
284
+ </form-pad>
285
+ <form-pad v-model="data.inputOptions" v-if="data.inputType=='FormTableData'">
286
+ <template #default="{data: optionData}">
287
+ <v-row dense>
288
+ <v-col cols="12">
289
+ <tabs-group>
290
+ <template #tabs>
291
+ <v-tab value="itemTemplate">Item Template</v-tab>
292
+ <v-tab value="dataTemplate">Data Template</v-tab>
293
+ <v-tab value="header">Header</v-tab>
294
+ </template>
295
+ <template #items>
296
+ <v-tabs-window-item value="itemTemplate">
297
+ <document-template-builder v-model="optionData.itemTemplate" title="Item Template" disable-advance-mode></document-template-builder>
298
+ </v-tabs-window-item>
299
+ <v-tabs-window-item value="dataTemplate">
300
+ <document-template-builder v-model="optionData.dataTemplate" title="Data Template" disable-advance-mode></document-template-builder>
301
+ </v-tabs-window-item>
302
+ <v-tabs-window-item value="header">
303
+ <form-table v-model="optionData.headers" :headers="formTableHeaders" title="Headers">
304
+ <template #form="{data: headerData,rules}">
305
+ <v-container fluid>
306
+ <v-row dense>
307
+ <v-col cols="6"><v-text-field v-model="headerData.title" label="Title"></v-text-field></v-col>
308
+ <v-col cols="3"><v-text-field v-model="headerData.key" label="Key" :rules="[rules.require()]"></v-text-field></v-col>
309
+ <v-col cols="3"><v-text-field v-model="headerData.width" label="Width"></v-text-field></v-col>
310
+ </v-row>
311
+ <v-row dense>
312
+ <v-col cols="12"><v-text-field v-model="headerData.value" label="Value"></v-text-field></v-col>
313
+ <v-col cols="12"><v-textarea v-model="headerData.template" label="Item Template"></v-textarea></v-col>
314
+ </v-row>
315
+ </v-container>
316
+ </template>
317
+ </form-table>
318
+ </v-tabs-window-item>
319
+ </template>
320
+ </tabs-group>
321
+ </v-col>
322
+ <v-col cols="12">
323
+ <form-table v-model="optionData.items" :headers="(optionData.headers && optionData.headers.length>0) ? autoActionHeader(optionData.headers) : autoActionHeader(templateToHeader(optionData.itemTemplate))" title="Items">
324
+ <template #form="{data}">
325
+ <form-pad :model-value="data" :template="optionData.itemTemplate"></form-pad>
326
+ </template>
327
+ </form-table>
328
+ </v-col>
329
+ <v-col cols="12">
330
+ <v-row dense>
331
+ <v-col cols="4">
332
+ <v-radio-group v-model="optionData.disableApplyToAll" inline>
333
+ <template #prepend>
334
+ <span class="opacity-60"> Disable Apply to All</span>
335
+ </template>
336
+ <v-radio label="No" value="false" hide-details> </v-radio>
337
+ <v-radio label="Yes" value="true" hide-details> </v-radio>
338
+ <v-radio label="Partial" value="partial" hide-details> </v-radio>
339
+ </v-radio-group>
340
+ </v-col>
341
+ <v-col cols="8">
342
+ <VTextField
343
+ variant="underlined"
344
+ v-model="optionData.disableApplyToAllPartial"
345
+ label="Disable Apply To All Column"
346
+ v-if="optionData.disableApplyToAll=='partial'"
347
+ >
348
+ </VTextField>
349
+ </v-col>
350
+ </v-row>
351
+ </v-col>
352
+ </v-row>
353
+ </template>
354
+ </form-pad>
355
+ <form-pad v-model="data.inputOptions" v-if="data.inputType=='FormHidden'">
356
+ <template #default="{data: optionData}">
357
+ <v-row dense>
358
+ <v-col cols="12">
359
+ <v-text-field
360
+ v-model="optionData.hook"
361
+ label="Hook"
362
+ />
363
+ </v-col>
364
+ <v-col cols="12">
365
+ <v-text-field
366
+ v-model="optionData.itemValue"
367
+ label="Item Value"
368
+ />
369
+ </v-col>
370
+ </v-row>
371
+ </template>
372
+ </form-pad>
373
+ <form-table v-model="data.inputOptions" :headers="choiceHeaders" title="Choices" v-if="choiceOption.includes(data.inputType) && (!data.inputOptions || typeof data.inputOptions === 'object')">
374
+ <template #form="{data: optionData,rules}">
375
+ <v-container fluid>
376
+ <v-row dense>
377
+ <v-col cols="6"><v-text-field v-model="optionData.label" label="Label"></v-text-field></v-col>
378
+ <v-col cols="6"><v-text-field v-model="optionData.value" label="Value" :rules="[rules.require()]"></v-text-field></v-col>
379
+ </v-row>
380
+ </v-container>
381
+ </template>
382
+ </form-table>
383
+ <form-hidden v-model="data.inputOptions" :itemValue="data.inputOptions" :hook="(option: any)=>optionStringToChoiceObject(option)" v-if="choiceOption.includes(data.inputType) && data.inputOptions && typeof data.inputOptions === 'string'"></form-hidden>
384
+ <v-textarea
385
+ v-model="data.inputOptions"
386
+ :label="inputOptionsLabel[data.inputType] || 'Input Options'"
387
+ auto-grow
388
+ :rules="[rules.requireIf(requireOption.includes(data.inputType)), ruleOptions(data.inputType)]"
389
+ v-if="!hasSpecificOption.includes(data.inputType) && !choiceOption.includes(data.inputType)"
390
+ />
391
+ </v-col>
392
+
393
+ <v-col
394
+ v-if="data.inputType=='CustomCode'"
395
+ cols="12"
396
+ >
397
+ <FormCodeEditor
398
+ v-model="data.inputCustomCode"
399
+ label="Custom Code"
400
+ :rules="[rules.require()]"
401
+ />
402
+ </v-col>
403
+ </v-row>
404
+ <v-row dense>
405
+ <v-col>
406
+ <v-expansion-panels>
407
+ <v-expansion-panel v-if="!notRequireRules.includes(data.inputType)">
408
+ <v-expansion-panel-title collapse-icon="mdi mdi-minus" expand-icon="mdi mdi-plus" class="font-weight-bold">Validations</v-expansion-panel-title>
409
+ <v-expansion-panel-text>
410
+ <v-container fluid>
411
+ <v-row dense>
412
+ <v-col cols="12">
413
+ <v-text-field
414
+ v-model="data.validationRules"
415
+ label="Validation Rules"
416
+ :rules="[rules.regex(validationRulesRegex)]"
417
+ />
418
+ <b>Available rules :</b> require, requireIf(condition), requireTrue, requireTrueIf(condition), numeric, range(min,max), integer, unique, length(length), lengthGreater(length), lengthLess(length), telephone, email, regex(regex), idcard, DateFuture, DatetimeFuture, DateHappen, DatetimeHappen, DateAfter(date), DateBefore(Date), DateEqual(date)
419
+ </v-col>
420
+ </v-row>
421
+ </v-container>
422
+ </v-expansion-panel-text>
423
+ </v-expansion-panel>
424
+ <v-expansion-panel v-if="!notRequireAdvancedSetting.includes(data.inputType)">
425
+ <v-expansion-panel-title collapse-icon="mdi mdi-minus" expand-icon="mdi mdi-plus" class="font-weight-bold">Advanced settings</v-expansion-panel-title>
426
+ <v-expansion-panel-text>
427
+ <v-container fluid>
428
+ <v-row dense>
429
+ <v-col cols="12" md="6" v-if="!notRequireInputAttributes.includes(data.inputType)">
430
+ <v-text-field
431
+ v-model="data.inputAttributes"
432
+ label="Input Attributes"
433
+ />
434
+ </v-col>
435
+ <v-col cols="12" md="6" v-if="!notRequireColumnAttributes.includes(data.inputType)">
436
+ <v-text-field
437
+ v-model="data.columnAttributes"
438
+ label="Column Attributes"
439
+ />
440
+ </v-col>
441
+ <v-col cols="12" md="6">
442
+ <v-text-field
443
+ v-model="data.conditionalDisplay"
444
+ label="Conditional Display"
445
+ />
446
+ </v-col>
447
+ <v-col cols="12" md="6">
448
+ <v-text-field
449
+ v-model="data.computedValue"
450
+ label="Computed Value"
451
+ />
452
+ </v-col>
453
+ <v-col cols="12" md="6">
454
+ <v-text-field
455
+ v-model="data.retrievedValue"
456
+ label="Retrieved Value"
457
+ />
458
+ </v-col>
459
+ </v-row>
460
+ </v-container>
461
+ </v-expansion-panel-text>
462
+ </v-expansion-panel>
463
+ <v-expansion-panel v-if="!notRequireClassAndStyle.includes(data.inputType)">
464
+ <v-expansion-panel-title collapse-icon="mdi mdi-minus" expand-icon="mdi mdi-plus" class="font-weight-bold">Class and Styles</v-expansion-panel-title>
465
+ <v-expansion-panel-text>
466
+ <v-container fluid>
467
+ <v-row dense>
468
+ <v-col cols="12">
469
+ <v-text-field
470
+ v-model="data.customClass"
471
+ label="Custom Class"
472
+ />
473
+ </v-col>
474
+ <v-col cols="12">
475
+ <v-text-field
476
+ v-model="data.customStyle"
477
+ label="Custom Styles"
478
+ />
479
+ </v-col>
480
+ </v-row>
481
+ </v-container>
482
+ </v-expansion-panel-text>
483
+ </v-expansion-panel>
484
+ </v-expansion-panels>
485
+ </v-col>
486
+ </v-row>
487
+ </v-container>
488
+ </template>
489
+ <template #item.configuration="props">
490
+ <v-sheet
491
+ elevation="1"
492
+ max-height="250"
493
+ class="overflow-y-auto my-1 pa-2"
494
+ v-if="props.item.inputType=='CustomCode'
495
+ || props.item.validationRules
496
+ || props.item.inputOptions
497
+ || props.item.inputAttributes
498
+ || props.item.columnAttributes
499
+ || props.item.conditionalDisplay
500
+ || props.item.computedValue
501
+ || props.item.retrievedValue"
502
+ >
503
+ <template v-if="props.item.inputType=='CustomCode'">
504
+ <b>Custom Code :</b><br>
505
+ <span style="white-space: pre-line">{{ props.item.inputCustomCode }}</span>
506
+ </template>
507
+ <template v-if="props.item.validationRules">
508
+ <b>Validation Rules :</b> {{ props.item.validationRules }}<br>
509
+ </template>
510
+ <template v-if="props.item.inputOptions">
511
+ <b>Input Options :</b>
512
+ <vue-json-pretty :data="safeParseJSONDeep(props.item.inputOptions)" />
513
+ </template>
514
+ <template v-if="props.item.inputAttributes">
515
+ <b>Input Attributes :</b> {{ props.item.inputAttributes }}<br>
516
+ </template>
517
+ <template v-if="props.item.columnAttributes">
518
+ <b>Column Attributes :</b> {{ props.item.columnAttributes }}<br>
519
+ </template>
520
+ <template v-if="props.item.conditionalDisplay">
521
+ <b>Conditional Display :</b> {{ props.item.conditionalDisplay }}<br>
522
+ </template>
523
+ <template v-if="props.item.computedValue">
524
+ <b>Computed Value :</b> {{ props.item.computedValue }}<br>
525
+ </template>
526
+ <template v-if="props.item.retrievedValue">
527
+ <b>Retrieved Value :</b> {{ props.item.retrievedValue }}<br>
528
+ </template>
529
+ </v-sheet>
530
+ </template>
531
+ </FormTable>
532
+ <FormCodeEditor
533
+ v-else
534
+ v-model="advanceModeCode"
535
+ />
536
+ </template>