@ramathibodi/nuxt-commons 0.1.74 → 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 (96) hide show
  1. package/README.md +115 -115
  2. package/dist/module.json +1 -1
  3. package/dist/runtime/components/Alert.vue +58 -58
  4. package/dist/runtime/components/BarcodeReader.vue +130 -130
  5. package/dist/runtime/components/ExportCSV.vue +110 -110
  6. package/dist/runtime/components/FileBtn.vue +79 -79
  7. package/dist/runtime/components/ImportCSV.vue +151 -151
  8. package/dist/runtime/components/MrzReader.vue +168 -168
  9. package/dist/runtime/components/SplitterPanel.vue +67 -67
  10. package/dist/runtime/components/TabsGroup.vue +39 -39
  11. package/dist/runtime/components/TextBarcode.vue +66 -66
  12. package/dist/runtime/components/device/IdCardButton.vue +95 -95
  13. package/dist/runtime/components/device/IdCardWebSocket.vue +207 -207
  14. package/dist/runtime/components/device/Scanner.vue +350 -350
  15. package/dist/runtime/components/dialog/Confirm.vue +112 -112
  16. package/dist/runtime/components/dialog/Host.vue +88 -88
  17. package/dist/runtime/components/dialog/Index.vue +84 -84
  18. package/dist/runtime/components/dialog/Loading.vue +51 -51
  19. package/dist/runtime/components/dialog/default/Confirm.vue +112 -112
  20. package/dist/runtime/components/dialog/default/Loading.vue +60 -60
  21. package/dist/runtime/components/dialog/default/Notify.vue +82 -82
  22. package/dist/runtime/components/dialog/default/Printing.vue +46 -46
  23. package/dist/runtime/components/dialog/default/VerifyUser.vue +144 -144
  24. package/dist/runtime/components/document/Form.vue +50 -50
  25. package/dist/runtime/components/document/TemplateBuilder.vue +536 -536
  26. package/dist/runtime/components/form/ActionPad.vue +156 -156
  27. package/dist/runtime/components/form/Birthdate.vue +116 -116
  28. package/dist/runtime/components/form/CheckboxGroup.vue +99 -99
  29. package/dist/runtime/components/form/CodeEditor.vue +45 -45
  30. package/dist/runtime/components/form/Date.vue +270 -270
  31. package/dist/runtime/components/form/DateTime.vue +220 -220
  32. package/dist/runtime/components/form/Dialog.vue +178 -178
  33. package/dist/runtime/components/form/EditPad.vue +157 -157
  34. package/dist/runtime/components/form/File.vue +295 -295
  35. package/dist/runtime/components/form/Hidden.vue +44 -44
  36. package/dist/runtime/components/form/Iterator.vue +538 -538
  37. package/dist/runtime/components/form/Login.vue +143 -143
  38. package/dist/runtime/components/form/Pad.vue +399 -399
  39. package/dist/runtime/components/form/SignPad.vue +226 -226
  40. package/dist/runtime/components/form/System.vue +34 -34
  41. package/dist/runtime/components/form/Table.vue +391 -391
  42. package/dist/runtime/components/form/TableData.vue +236 -236
  43. package/dist/runtime/components/form/Time.vue +177 -177
  44. package/dist/runtime/components/form/images/Capture.vue +245 -245
  45. package/dist/runtime/components/form/images/Edit.vue +133 -133
  46. package/dist/runtime/components/form/images/Field.vue +331 -331
  47. package/dist/runtime/components/form/images/Pad.vue +54 -54
  48. package/dist/runtime/components/label/Date.vue +37 -37
  49. package/dist/runtime/components/label/DateAgo.vue +102 -102
  50. package/dist/runtime/components/label/DateCount.vue +152 -152
  51. package/dist/runtime/components/label/Field.vue +111 -111
  52. package/dist/runtime/components/label/FormatMoney.vue +37 -37
  53. package/dist/runtime/components/label/Mask.vue +46 -46
  54. package/dist/runtime/components/label/Object.vue +21 -21
  55. package/dist/runtime/components/master/Autocomplete.vue +89 -89
  56. package/dist/runtime/components/master/Combobox.vue +88 -88
  57. package/dist/runtime/components/master/RadioGroup.vue +90 -90
  58. package/dist/runtime/components/master/Select.vue +70 -70
  59. package/dist/runtime/components/master/label.vue +55 -55
  60. package/dist/runtime/components/model/Autocomplete.vue +91 -91
  61. package/dist/runtime/components/model/Combobox.vue +90 -90
  62. package/dist/runtime/components/model/Pad.vue +114 -114
  63. package/dist/runtime/components/model/Select.vue +78 -84
  64. package/dist/runtime/components/model/Table.vue +370 -370
  65. package/dist/runtime/components/model/iterator.vue +497 -497
  66. package/dist/runtime/components/model/label.vue +58 -58
  67. package/dist/runtime/components/pdf/Print.vue +75 -75
  68. package/dist/runtime/components/pdf/View.vue +146 -146
  69. package/dist/runtime/composables/dialog.d.ts +1 -1
  70. package/dist/runtime/composables/graphql.d.ts +1 -1
  71. package/dist/runtime/composables/graphqlModel.d.ts +9 -9
  72. package/dist/runtime/composables/graphqlModelItem.d.ts +7 -7
  73. package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
  74. package/dist/runtime/composables/userPermission.d.ts +1 -1
  75. package/dist/runtime/labs/Calendar.vue +99 -99
  76. package/dist/runtime/labs/form/EditMobile.vue +152 -152
  77. package/dist/runtime/labs/form/TextFieldMask.vue +43 -43
  78. package/dist/runtime/plugins/clientConfig.d.ts +1 -1
  79. package/dist/runtime/plugins/default.d.ts +1 -1
  80. package/dist/runtime/plugins/dialogManager.d.ts +1 -1
  81. package/dist/runtime/plugins/permission.d.ts +1 -1
  82. package/dist/runtime/types/alert.d.ts +11 -11
  83. package/dist/runtime/types/clientConfig.d.ts +13 -13
  84. package/dist/runtime/types/dialogManager.d.ts +35 -35
  85. package/dist/runtime/types/formDialog.d.ts +5 -5
  86. package/dist/runtime/types/graphqlOperation.d.ts +23 -23
  87. package/dist/runtime/types/menu.d.ts +31 -31
  88. package/dist/runtime/types/modules.d.ts +7 -7
  89. package/dist/runtime/types/permission.d.ts +13 -13
  90. package/package.json +131 -131
  91. package/scripts/enrich-vue-docs-from-ai.mjs +197 -197
  92. package/scripts/generate-ai-summary.mjs +321 -321
  93. package/scripts/generate-composables-md.mjs +129 -129
  94. package/scripts/postInstall.cjs +70 -70
  95. package/templates/.codegen/codegen.ts +32 -32
  96. package/templates/.codegen/plugin-schema-object.js +161 -161
@@ -1,536 +1,536 @@
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>
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>