@simitgroup/simpleapp-generator 1.0.64 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/buildinschemas/user.d.ts.map +1 -1
  2. package/dist/buildinschemas/user.js +0 -1
  3. package/dist/buildinschemas/user.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/buildinschemas/user.ts +1 -2
  6. package/templates/basic/nuxt/pages.landing.vue.eta +1 -1
  7. package/templates/basic/nuxt/pages.new.vue.eta +52 -68
  8. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +0 -1
  9. package/templates/nuxt/assets/css/style.css._eta +29 -1
  10. package/templates/nuxt/assets/primevue/passthrough.ts._eta +8 -2
  11. package/templates/nuxt/components/debug/DebugDocumentData.vue.eta +8 -4
  12. package/templates/nuxt/components/event/EventNotification.vue.eta +13 -9
  13. package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +31 -44
  14. package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +12 -11
  15. package/templates/nuxt/components/simpleApp/SimpleAppForm.vue.eta +5 -4
  16. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +288 -0
  17. package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +4 -52
  18. package/templates/nuxt/components/simpleApp/{SimpleAppAutocomplete.vue.eta → pending/SimpleAppAutocomplete.vue} +1 -2
  19. package/templates/nuxt/components/simpleApp/pending/SimpleAppDocumentNo.vue +90 -0
  20. package/templates/nuxt/components/simpleApp/pending/SimpleAppInputTable.vue +83 -0
  21. package/templates/nuxt/components/simpleApp/{SimpleAppText.vue.eta → pending/SimpleAppText.vue} +0 -2
  22. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +32 -1
  23. package/templates/nuxt/layouts/default.vue.eta +1 -1
  24. package/templates/nuxt/layouts/documentlist.vue.eta +4 -4
  25. package/templates/nuxt/layouts/sidelist.vue.eta +1 -1
  26. package/templates/nuxt/layouts/sidelistcrud.vue.eta +1 -1
  27. package/templates/nuxt/nuxt.config.ts.eta +0 -1
  28. package/templates/nuxt/pages/[xorg]/docnoformat/[doctype]/new.vue.eta +96 -90
  29. package/templates/nuxt/pages/[xorg]/organization/[id]/branches/new.vue +3 -3
  30. package/templates/nuxt/pages/[xorg]/organization/new.vue.eta +24 -18
  31. package/templates/nuxt/pages/[xorg]/organization.vue.eta +32 -17
  32. package/templates/nuxt/pages/[xorg]/user/index.vue.eta +40 -35
  33. package/templates/nuxt/pages/[xorg]/user.vue.eta +10 -8
  34. package/templates/nuxt/pages/index.vue._eta +2 -2
  35. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +4 -1
  36. package/templates/nuxt/types/index.ts.eta +2 -1
  37. package/templates/nuxt/types/simpleappinput.ts.eta +39 -0
  38. package/templates/project/jsonschemas/category.json._eta +3 -3
  39. package/templates/project/jsonschemas/customer.json._eta +3 -3
  40. package/templates/project/jsonschemas/invoice.json._eta +3 -3
  41. package/templates/project/jsonschemas/product.json._eta +3 -3
  42. package/tsconfig.tsbuildinfo +1 -1
  43. package/templates/nuxt/composables/getAutocomplete.generate.ts.eta +0 -32
  44. /package/templates/nuxt/components/{ListView.vue.eta → list/ListView.vue.eta} +0 -0
  45. /package/templates/nuxt/components/simpleApp/{SimpleAppAutocompletemulti.vue.eta → pending/SimpleAppAutocompletemulti.vue} +0 -0
  46. /package/templates/nuxt/components/simpleApp/{SimpleAppCalendar.vue.eta → pending/SimpleAppCalendar.vue} +0 -0
  47. /package/templates/nuxt/components/simpleApp/{SimpleAppCheckbox.vue.eta → pending/SimpleAppCheckbox.vue} +0 -0
  48. /package/templates/nuxt/components/simpleApp/{SimpleAppChip.vue.eta → pending/SimpleAppChip.vue} +0 -0
  49. /package/templates/nuxt/components/simpleApp/{SimpleAppColor.vue.eta → pending/SimpleAppColor.vue} +0 -0
  50. /package/templates/nuxt/components/simpleApp/{SimpleAppDynamicInput.vue.eta → pending/SimpleAppDynamicInput.vue} +0 -0
  51. /package/templates/nuxt/components/simpleApp/{SimpleAppEditor.vue.eta → pending/SimpleAppEditor.vue} +0 -0
  52. /package/templates/nuxt/components/simpleApp/{SimpleAppList.vue.eta → pending/SimpleAppList.vue} +0 -0
  53. /package/templates/nuxt/components/simpleApp/{SimpleAppListmulti.vue.eta → pending/SimpleAppListmulti.vue} +0 -0
  54. /package/templates/nuxt/components/simpleApp/{SimpleAppNumber.vue.eta → pending/SimpleAppNumber.vue} +0 -0
  55. /package/templates/nuxt/components/simpleApp/{SimpleAppPassword.vue.eta → pending/SimpleAppPassword.vue} +0 -0
  56. /package/templates/nuxt/components/simpleApp/{SimpleAppRadio.vue.eta → pending/SimpleAppRadio.vue} +0 -0
  57. /package/templates/nuxt/components/simpleApp/{SimpleAppRating.vue.eta → pending/SimpleAppRating.vue} +0 -0
  58. /package/templates/nuxt/components/simpleApp/{SimpleAppSelect.vue.eta → pending/SimpleAppSelect.vue} +0 -0
  59. /package/templates/nuxt/components/simpleApp/{SimpleAppSelectmulti.vue.eta → pending/SimpleAppSelectmulti.vue} +0 -0
  60. /package/templates/nuxt/components/simpleApp/{SimpleAppSlider.vue.eta → pending/SimpleAppSlider.vue} +0 -0
  61. /package/templates/nuxt/components/simpleApp/{SimpleAppSwitch.vue.eta → pending/SimpleAppSwitch.vue} +0 -0
  62. /package/templates/nuxt/components/simpleApp/{SimpleAppTextarea.vue.eta → pending/SimpleAppTextarea.vue} +0 -0
  63. /package/templates/nuxt/components/simpleApp/{SimpleAppValue.vue.eta → pending/SimpleAppValue.vue} +0 -0
  64. /package/templates/nuxt/components/simpleApp/{helper.ts.eta → pending/helper.ts-backup} +0 -0
  65. /package/templates/nuxt/components/simpleApp/{type.ts.eta → pending/type.ts-backup} +0 -0
  66. /package/templates/nuxt/components/{CrudNestedDoc.vue.eta → suspended/CrudNestedDoc.vue.eta} +0 -0
  67. /package/templates/nuxt/components/{CrudSimple.vue.eta → suspended/CrudSimple.vue.eta} +0 -0
  68. /package/templates/nuxt/components/{Menus.vue.eta → suspended/Menus.vue.eta} +0 -0
  69. /package/templates/nuxt/components/{Spinner.vue.eta → suspended/Spinner.vue.eta} +0 -0
  70. /package/templates/nuxt/components/{DocumentDatatable.vue.eta → table/TableDocuments.vue.eta} +0 -0
  71. /package/templates/nuxt/components/{ButtonCreateTenant.vue.eta → user/UserButtonCreateTenant.vue.eta} +0 -0
  72. /package/templates/nuxt/components/{ButtonPermissionInfo.vue.eta → user/UserButtonPermissionInfo.vue.eta} +0 -0
  73. /package/templates/nuxt/components/{Invitation.vue.eta → user/UserInvitation.vue.eta} +0 -0
  74. /package/templates/nuxt/components/{UserProfileListItem.vue.eta → user/UserProfileListItem.vue.eta} +0 -0
  75. /package/templates/nuxt/components/{TenantPicker.vue.eta → user/UserTenantPicker.vue.eta} +0 -0
@@ -5,10 +5,10 @@
5
5
  </form>
6
6
  </template>
7
7
  <script setup lang="ts" >
8
- import type {SimpleAppFieldSetting} from './type'
9
- import { SimpleAppClient } from '../simpleapp/generate/clients/SimpleAppClient'
8
+ // import type {SimpleAppFieldSetting} from '/types'
9
+ import { SimpleAppClient } from '~/simpleapp/generate/clients/SimpleAppClient'
10
10
  import type { JSONSchema7,JSONSchema7Definition } from 'json-schema';
11
-
11
+ import _ from 'lodash'
12
12
  const props = defineProps<{
13
13
  title?:string,
14
14
  document: SimpleAppClient<any,any>
@@ -28,6 +28,7 @@ import type { JSONSchema7,JSONSchema7Definition } from 'json-schema';
28
28
 
29
29
  return {
30
30
  path: path,
31
+ key: _.last(path.split('/')),
31
32
  instancepath: getInstancePath(schema,path),
32
33
  fieldsetting: fieldsetting,
33
34
  modelObject: data,
@@ -37,7 +38,7 @@ import type { JSONSchema7,JSONSchema7Definition } from 'json-schema';
37
38
  isrequired: getIsRequired(schema,path),
38
39
  errors: props.document.getErrors(),
39
40
  readonly: props.readonly
40
- } as SimpleAppFieldSetting
41
+ } //as SimpleAppFieldSetting
41
42
  }
42
43
 
43
44
  // "schemaPath": "#/properties/email/format",
@@ -0,0 +1,288 @@
1
+ <template>
2
+ <SimpleAppFieldContainer :hidelabel="hidelabel" v-model="modelValue"
3
+ :label="label" :description="description"
4
+ :setting="setting" :instancepath="instancepath" :error="error" #default="slotprops">
5
+ <!-- binary input -->
6
+ <component :is="inputComponent" :readonly="isReadonly" :pt="pt"
7
+ v-if="[SimpleAppInputType.checkbox,SimpleAppInputType.switch ].includes(inputType)"
8
+ :inputId="slotprops.uuid" :path="setting.instancepath"
9
+ v-model="modelValue" :binary="true"/>
10
+
11
+ <!-- date component -->
12
+ <component :is="inputComponent" type="date" :pt="pt"
13
+ v-else-if="inputType == SimpleAppInputType.date"
14
+ :inputId="slotprops.uuid" :path="setting.instancepath"
15
+ v-model="datevalue" @update:modelValue="updateDate" :readonly="isReadonly"/>
16
+ <!-- calendar component -->
17
+ <component :is="inputComponent" type="date" :pt="pt" class="flex flex-col"
18
+ v-else-if="SimpleAppInputType.calendar==inputType"
19
+ :inputId="slotprops.uuid" :path="setting.instancepath"
20
+ v-model="datevalue" @update:modelValue="updateDate" :readonly="isReadonly"/>
21
+
22
+ <!-- select/list component -->
23
+ <component :is="inputComponent" v-model="modelValue" :pt="pt"
24
+ v-else-if="[SimpleAppInputType.select,SimpleAppInputType.list].includes(inputType)"
25
+ :inputId="slotprops.uuid" :path="setting.instancepath"
26
+ :readonly="isReadonly"
27
+ :options="getListOptions()" optionLabel="label" optionValue="value"/>
28
+
29
+ <!-- radio component -->
30
+ <div v-else-if="inputType == SimpleAppInputType.radio" >
31
+ <div v-for="(item,index) in getListOptions()">
32
+ <component :pt="pt" :is="inputComponent" v-model="modelValue"
33
+ :inputId="setting.key+'-'+index" name="smaple" :value="item.value"
34
+ :readonly="isReadonly"
35
+ /> {{ ' ' }}
36
+ <label :for="setting.key+'-'+index"> {{ item.label }} </label>
37
+ </div>
38
+ </div>
39
+
40
+ <!-- autocomplete -->
41
+ <AutoComplete :is="inputComponent" v-model="modelValue"
42
+ v-else-if="inputType==SimpleAppInputType.autocomplete"
43
+ forceSelection optionLabel="label" :dropdown="true"
44
+ @item-select="pickAutoComplete"
45
+ @complete="getListFromAutocompleteApi"
46
+
47
+ :pt="{
48
+ root:{class:'rounded-lg flex flex-row'},
49
+ input:{class:'w-full font-sans text-gray-600 dark:text-white/80 bg-white dark:bg-gray-900 border border-gray-300 dark:border-blue-900/40 rounded-lg rounded-tr-none rounded-br-none transition-colors duration-200 appearance-none hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)] text-base'},
50
+ loadingIcon:{class:'hidden'},
51
+ dropdownbutton: {
52
+ root:' bg-primary-600 hover:bg-primary-400 text-white rounded flex flex-row p-3 rounded-tl-none rounded-bl-none '
53
+ }
54
+ }"
55
+ :disabled="isReadonly"
56
+ :suggestions="list"
57
+ @blur="onBlurAutocomplete"
58
+ :inputId="slotprops.uuid" :path="setting.instancepath"
59
+ :readonly="isReadonly"
60
+ />
61
+
62
+ <!-- document no input-->
63
+ <SimpleAppDocumentNo v-else-if="inputType == SimpleAppInputType.documentno"
64
+ :setting="setting" v-model="modelValue" :inputId="slotprops.uuid"
65
+ :readonly="isReadonly" @update:docNoFormat="triggerDocNoFormatChange"
66
+ :path="setting.instancepath"/>
67
+
68
+
69
+ <!-- password -->
70
+ <component :is="inputComponent"
71
+ v-else-if="inputType == SimpleAppInputType.password"
72
+ :type="type" v-model="modelValue" :pt="pt"
73
+ :readonly="isReadonly" class="flex flex-col"
74
+ :inputId="slotprops.uuid" :path="setting.instancepath"/>
75
+
76
+ <!-- rating -->
77
+ <Rating v-else-if="inputType == SimpleAppInputType.rating"
78
+ :is="inputComponent" :type="type" v-model="modelValue" :pt="pt"
79
+ :readonly="isReadonly"
80
+ :inputId="slotprops.uuid" :path="setting.instancepath"/>
81
+
82
+ <!-- chip -->
83
+ <component v-else-if="inputType == SimpleAppInputType.chip"
84
+ :is="inputComponent" :type="type" v-model="modelValue"
85
+ :pt="pt"
86
+ :disabled="isReadonly"
87
+
88
+
89
+ :inputId="slotprops.uuid" :path="setting.instancepath"/>
90
+ <!-- simple component -->
91
+ <component v-else :is="inputComponent" :type="type" v-model="modelValue" :pt="pt"
92
+ :readonly="isReadonly"
93
+ class="w-full flex flex-col"
94
+ :inputId="slotprops.uuid" :path="setting.instancepath"/>
95
+
96
+
97
+ <!-- component require special treatment -->
98
+
99
+ </SimpleAppFieldContainer>
100
+ </template>
101
+
102
+ <script lang="ts" setup>
103
+ import { isNull, pick } from 'lodash';
104
+ import {autocompletetype} from '~/types'
105
+ import moment from 'moment'
106
+ import AutoComplete from 'primevue/autocomplete';
107
+ import Calendar from 'primevue/calendar';
108
+ import Checkbox from 'primevue/checkbox';
109
+ import Chips from 'primevue/chips';
110
+ import SimpleAppDocumentNo from './SimpleAppDocumentNo.vue';
111
+ import Dropdown from 'primevue/dropdown';
112
+ import InputNumber from 'primevue/inputnumber';
113
+ import InputSwitch from 'primevue/inputswitch';
114
+ import InputText from 'primevue/inputtext';
115
+ import Listbox from 'primevue/listbox';
116
+ import MultiSelect from 'primevue/multiselect';
117
+ import Password from 'primevue/password';
118
+ import RadioButton from 'primevue/radiobutton';
119
+ import Rating from 'primevue/rating';
120
+ import Slider from 'primevue/slider';
121
+ import Textarea from 'primevue/textarea';
122
+ import {SimpleAppInputType} from '~/types'
123
+
124
+ let inputComponent :Component
125
+ const emptyautocomplete =():autocompletetype=> ({_id:'',label:''})
126
+ const autocompleteitem = ref<autocompletetype>(emptyautocomplete())
127
+ const datevalue = ref('')
128
+ const modelValue = defineModel()
129
+ const list = ref([])
130
+ const props = withDefaults( defineProps<{
131
+ inputType:SimpleAppInputType,
132
+ label?:string,
133
+ description?:string,
134
+ error?:string,
135
+ setting:any,
136
+ type?:string,
137
+ instancepath?:string,
138
+ hidelabel?: boolean
139
+ readonly?: boolean
140
+ pt?:any
141
+ }>(),{type:'text'})
142
+
143
+
144
+ switch(props.inputType){
145
+ case SimpleAppInputType.text:
146
+ inputComponent = InputText
147
+ break;
148
+ case SimpleAppInputType.textarea:
149
+ inputComponent = Textarea
150
+ break;
151
+ case SimpleAppInputType.number:
152
+ inputComponent = InputNumber
153
+ break
154
+ case SimpleAppInputType.date:
155
+ inputComponent = InputText
156
+ break;
157
+ case SimpleAppInputType.calendar:
158
+ inputComponent = Calendar
159
+ break;
160
+ case SimpleAppInputType.autocomplete:
161
+ inputComponent = AutoComplete
162
+ break;
163
+ case SimpleAppInputType.autocompletemultiple: //*
164
+ inputComponent = AutoComplete
165
+ break;
166
+ case SimpleAppInputType.selectmultiple: //*
167
+ inputComponent = MultiSelect
168
+ break;
169
+ case SimpleAppInputType.listmultiple: //*
170
+ break;
171
+ case SimpleAppInputType.radio: //*
172
+ inputComponent = RadioButton
173
+ break;
174
+ case SimpleAppInputType.select: //*
175
+ inputComponent = Dropdown
176
+ break;
177
+ case SimpleAppInputType.list: //*
178
+ inputComponent = Listbox
179
+ break;
180
+ case SimpleAppInputType.chip: //*
181
+ inputComponent = Chips
182
+ break;
183
+ case SimpleAppInputType.checkbox:
184
+ inputComponent = Checkbox
185
+ break;
186
+ case SimpleAppInputType.switch:
187
+ inputComponent = InputSwitch
188
+ break;
189
+ case SimpleAppInputType.documentno: //*
190
+ break;
191
+ case SimpleAppInputType.password:
192
+ inputComponent = Password
193
+ break;
194
+ case SimpleAppInputType.rating:
195
+ inputComponent = Rating
196
+ break;
197
+ case SimpleAppInputType.slider:
198
+ inputComponent = Slider
199
+ break;
200
+
201
+ }
202
+ const isReadonly = computed(()=>{
203
+ if(props.readonly){
204
+ return props.readonly
205
+ }else if(props.setting.readonly){
206
+ return props.setting.readonly
207
+ }else{
208
+ return false
209
+ }
210
+ })
211
+
212
+ const updateDate = (value:any)=>{
213
+ modelValue.value = moment(value).toISOString()
214
+ }
215
+
216
+
217
+ const getListOptions = () =>{
218
+
219
+ const options = []
220
+ if(props.setting.fieldsetting.enum){
221
+ for(let i=0;i<props.setting.fieldsetting.enum.length;i++){
222
+ const v = props.setting.fieldsetting.enum[i]
223
+ options.push({value:v, label: camelCaseToWords(v)})
224
+ }
225
+
226
+
227
+ }
228
+ return options
229
+ }
230
+
231
+
232
+ const emits = defineEmits(['change','update:modelValue','update:docNoFormat'])
233
+
234
+ watch(modelValue ,(newvalue:any)=>{
235
+
236
+ if([SimpleAppInputType.date,SimpleAppInputType.calendar].includes(props.inputType)){
237
+ datevalue.value = moment(modelValue.value as string ).format('YYYY-MM-DD')
238
+ }else if(props.inputType==SimpleAppInputType.autocomplete){
239
+ modelValue.value=autocompleteitem.value
240
+ }
241
+
242
+ emits('change',modelValue.value)
243
+ emits('update:modelValue',modelValue.value)
244
+ })
245
+
246
+
247
+ /************ start autocomplete only ***************/
248
+ const onBlurAutocomplete = ()=>{
249
+
250
+ if( autocompleteitem.value === null){
251
+ autocompleteitem.value = emptyautocomplete()
252
+ }
253
+ if(isNull(modelValue.value )){
254
+ modelValue.value = autocompleteitem.value
255
+ }
256
+ else if(typeof modelValue.value =='object'){
257
+
258
+ }else{
259
+ modelValue.value = autocompleteitem.value
260
+ }
261
+
262
+ }
263
+ const getListFromAutocompleteApi = (event:any)=>{
264
+ const keyword = event.query??''
265
+ //props.setting.document.getDocType()
266
+ const targetDocument = props.setting.fieldsetting['x-foreignkey']
267
+ getDocumentApi(targetDocument).autoComplete(keyword).then((res:any)=>{
268
+ list.value = res.data
269
+ })
270
+ }
271
+ const pickAutoComplete = (event:any)=>{
272
+ if(typeof event.value.query == 'undefined'){
273
+ modelValue.value=event.value
274
+ autocompleteitem.value = event.value
275
+ }
276
+ }
277
+ /************ end autocomplete only ***************/
278
+
279
+
280
+
281
+
282
+
283
+ const triggerDocNoFormatChange=(formatdata:any)=>{
284
+ emits('update:docNoFormat',formatdata)
285
+ }
286
+ </script>
287
+ <style scoped>
288
+ </style>
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
  </template>
10
10
  <slot>
11
- <!-- <template> -->
11
+
12
12
 
13
13
  <Column class="text-center" header="undefine columns">
14
14
  <template #body>
@@ -18,30 +18,11 @@
18
18
  </Column>
19
19
 
20
20
 
21
- <!-- </template> -->
22
21
 
23
- </slot>
24
22
 
25
-
26
-
27
-
28
-
29
-
30
-
23
+ </slot>
31
24
 
32
-
33
-
34
25
 
35
- <!-- <Column v-for="(col,index) in columns" :field="col.field" :style="col.style" :header="camelCaseToWords(col.title??'')">
36
- <template #body="{ data, field,index }">
37
- <SimpleAppDynamicInput v-if="modelValue" :instancepath="getInstancePath(index,field)" :setting="getChildFieldSetting(field)" v-model="modelValue[index][field]" :getAutocomplete="getAutocomplete" :hidelabel="true" />
38
- </template>
39
- </Column>
40
- <Column v-if="!readonly">
41
- <template #body="{data,field,index}">
42
- <Button class="simpleapp-inputtable-delrow button-danger" @click="deleteRow(index)" type="button">X</Button>
43
- </template>
44
- </Column> -->
45
26
  </DataTable>
46
27
  </template>
47
28
  <script setup lang="ts">
@@ -49,13 +30,11 @@
49
30
  import {ref} from 'vue'
50
31
  import DataTable from 'primevue/datatable';
51
32
  import Column from 'primevue/column';
52
- import {camelCaseToWords} from './helper'
53
- import type {InputTableColumn} from './type'
33
+
54
34
  const props = defineProps<{
55
35
  // columns:InputTableColumn[],
56
36
  setting:any,
57
- getField:Function,
58
- getAutocomplete:Function, readonly?:boolean
37
+ getField:Function,
59
38
  }>()
60
39
 
61
40
 
@@ -63,33 +42,6 @@ const props = defineProps<{
63
42
  const modelValue = defineModel<any[]>()
64
43
 
65
44
 
66
- const fieldsetting = props.setting.fieldsetting
67
-
68
- const readonly = ref(false)
69
- if(props.setting.readonly!==undefined ){
70
- readonly.value = props.setting.readonly
71
- }
72
- if(props.readonly!==undefined ){
73
- readonly.value = props.readonly
74
- }
75
- // const columns = ref(props.columns)
76
- // for(let i=0;i<props.columns.length;i++){
77
- // if(columns.value[i].title ===undefined){
78
- // columns.value[i].title=columns.value[i].field
79
- // }
80
- // }
81
- const getChildFieldSetting=(field:string)=>{
82
- return props.getField(`${props.setting.path}/items/properties/${field}`)
83
- }
84
- const getInstancePath=(index:number,field:string)=>{
85
- return `${props.setting.instancepath}/${index}/${field}`
86
- }
87
-
88
- const deleteRow=(index: number)=>{
89
- if(modelValue.value){
90
- modelValue.value.splice(index,1)
91
- }
92
- }
93
45
  const addNew = () => {
94
46
  const field = props.setting.path.split('/').at(-1)
95
47
  props.setting.document[`add${field}`]()
@@ -115,8 +115,7 @@ const onblur = ()=>{
115
115
  selecteditem.value={...modelValue.value}
116
116
  if(typeof selecteditem.value[labelfield]=='undefined'){
117
117
  selecteditem.value[labelfield]=''
118
- }
119
- // console.log("selecteditem.value",selecteditem.value)
118
+ }
120
119
  }
121
120
  const capitalizeFirstLetter = (str: string) => {
122
121
  const res = str == '' ? '' : str.slice(0, 1).toUpperCase() + str.slice(1);
@@ -0,0 +1,90 @@
1
+
2
+ <template>
3
+ <FieldContainer :hidelabel="hidelabel" v-model="modelValue" :label="label" :description="description" :setting="setting" :instancepath="instancepath" :error="error" #default="slotprops">
4
+ <div class="p-inputgroup ">
5
+ <InputText class="simpleapp-inputfield"
6
+ :inputId="slotprops.uuid"
7
+ v-model="modelValue"
8
+ :placeholder="placeholder"
9
+ :path="setting.instancepath"
10
+ :pt="{input:{class:'text-right w-full'}}"
11
+ />
12
+ <span class="p-inputgroup-addon p p-0">
13
+ <Button class="pi pi-angle-down" type="button" @click="toggle"></Button>
14
+
15
+ <OverlayPanel ref="op">
16
+ <ul>
17
+ <li v-for="docno in docFormatlist" class="hover-list-primary " >
18
+ <a class="flex-row p-2 mt-4" @click="chooseFormat(docno)">
19
+ <span class="pi pi-hashtag mr-2"></span>
20
+ <span class="">{{docno.docNoFormatName}}</span>
21
+ <span class="ml-2 text text-green-600">{{docno.sample}}</span>
22
+ </a>
23
+ </li>
24
+ </ul>
25
+ </OverlayPanel>
26
+ </span>
27
+ <!-- {{ Object.getOwnPropertyNames(setting) }} -->
28
+ </div>
29
+ </FieldContainer>
30
+ </template>
31
+ <script lang="ts" setup>
32
+ import {ForeignKey} from '~/types'
33
+ import OverlayPanel from 'primevue/overlaypanel';
34
+ import {computed,watch,ref} from 'vue'
35
+ import InputText from 'primevue/inputtext';
36
+ import FieldContainer from './SimpleAppFieldContainer.vue'
37
+ import {DocNoFormat} from "~/types"
38
+ const selectedformat = ref()
39
+ const op = ref();
40
+ const placeholder = ref('')
41
+ const docFormatlist = ref()
42
+ const modelValue = defineModel<string>()
43
+ const docNoFormat = defineModel<ForeignKey>('docNoFormat')
44
+ // const emit = defineEmits(['update:docNoFormat'])
45
+
46
+ const props = withDefaults(defineProps<{
47
+ // docNoFormat:object,
48
+ // docFormatlist?:DocNoFormat[]
49
+ label?:string,
50
+ description?:string,
51
+ setting:any
52
+ error?:string,
53
+ instancepath?:string,
54
+ hidelabel?:boolean,
55
+
56
+ }>(),{
57
+ hidelabel:false
58
+ })
59
+ const documenttype = props.setting.document.doctype
60
+
61
+
62
+ const toggle = async (event:any) => {
63
+ op.value.toggle(event);
64
+
65
+
66
+ }
67
+
68
+ const chooseFormat = (item:any) =>{
69
+ placeholder.value = item.sample
70
+ const f = item
71
+ docNoFormat.value = { _id : f._id, label : f.docNoFormatName}
72
+ op.value.toggle();
73
+ }
74
+
75
+ const loadDocFormats = async () =>{
76
+ docFormatlist.value= await getDocFormats(documenttype)
77
+ if(docFormatlist.value.length>0){
78
+ const f = docFormatlist.value[0]
79
+ docNoFormat.value = { _id : f._id, label : f.docNoFormatName}
80
+ placeholder.value = docFormatlist.value[0].sample
81
+
82
+ }
83
+ }
84
+
85
+
86
+ onMounted(()=>{
87
+ loadDocFormats()
88
+
89
+ })
90
+ </script>
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <DataTable v-bind="$attrs" stripedRows resizableColumns
3
+ class="simpleapp-datatable p-datatable-sm" :value="modelValue">
4
+ <template #empty> <div class="text-center">No record found.</div> </template>
5
+ <template #header >
6
+ <div>
7
+ <Button icon="pi pi-plus" @click="addNew()" class="simpleapp-datatable-add btn-primary" type="button">Add</Button>
8
+ </div>
9
+ </template>
10
+ <slot>
11
+ <!-- <template> -->
12
+
13
+ <Column class="text-center" header="undefine columns">
14
+ <template #body>
15
+ <div class="text-center">Missing {{ '<Column></Column>' }}</div>
16
+ </template>
17
+
18
+ </Column>
19
+
20
+
21
+ <!-- </template> -->
22
+
23
+ </slot>
24
+ </DataTable>
25
+ </template>
26
+ <script setup lang="ts">
27
+
28
+ import {ref} from 'vue'
29
+ import DataTable from 'primevue/datatable';
30
+ import Column from 'primevue/column';
31
+ import {camelCaseToWords} from './helper'
32
+ import type {InputTableColumn} from './type'
33
+ const props = defineProps<{
34
+ // columns:InputTableColumn[],
35
+ setting:any,
36
+ getField:Function,
37
+ getAutocomplete:Function, readonly?:boolean
38
+ }>()
39
+
40
+
41
+ //{path: '#/properties/details', instancepath: '/details', fieldsetting: {…}, modelObject: Proxy(Object), apiObj: INVApi, …}
42
+ const modelValue = defineModel<any[]>()
43
+
44
+
45
+ const fieldsetting = props.setting.fieldsetting
46
+
47
+ const readonly = ref(false)
48
+ if(props.setting.readonly!==undefined ){
49
+ readonly.value = props.setting.readonly
50
+ }
51
+ if(props.readonly!==undefined ){
52
+ readonly.value = props.readonly
53
+ }
54
+ // const columns = ref(props.columns)
55
+ // for(let i=0;i<props.columns.length;i++){
56
+ // if(columns.value[i].title ===undefined){
57
+ // columns.value[i].title=columns.value[i].field
58
+ // }
59
+ // }
60
+ const getChildFieldSetting=(field:string)=>{
61
+ return props.getField(`${props.setting.path}/items/properties/${field}`)
62
+ }
63
+ const getInstancePath=(index:number,field:string)=>{
64
+ return `${props.setting.instancepath}/${index}/${field}`
65
+ }
66
+
67
+ const deleteRow=(index: number)=>{
68
+ if(modelValue.value){
69
+ modelValue.value.splice(index,1)
70
+ }
71
+ }
72
+ const addNew = () => {
73
+ const field = props.setting.path.split('/').at(-1)
74
+ props.setting.document[`add${field}`]()
75
+ }
76
+ /**
77
+ * 1. support array with field to label
78
+ * 2. auto add edit button
79
+ * 3. option readonly or not readonly
80
+ * 4.
81
+ */
82
+
83
+ </script>
@@ -1,8 +1,6 @@
1
1
 
2
2
  <template>
3
3
  <FieldContainer :hidelabel="hidelabel" v-model="modelValue" :label="label" :description="description" :setting="setting" :instancepath="instancepath" :error="error" #default="slotprops">
4
-
5
-
6
4
  <InputText v-if="slotprops.error"
7
5
  class="simpleapp-inputfield simpleapp-invalid-input"
8
6
  :id="slotprops.uuid"
@@ -1,6 +1,37 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator during initialization.
3
+ * DO NOT MODIFY IT BY HAND.
4
+ * last change 2023-09-09
5
+ * author: Ks Tan
6
+ */
7
+
1
8
  import * as o from "../simpleapp/generate/openapi";
2
9
  import axios from 'axios'
10
+ export const getDocumentApi = (apiname: string): any => {
11
+ //const { csrf } = useCsrf()
12
+ //axios.defaults.headers.common = {"CSRF-TOKEN": csrf};
13
+ const route = useRoute();
3
14
 
4
- export const getApi=()=>{
15
+ const config: o.Configuration = {
16
+ basePath: `${useRuntimeConfig().public.APP_URL}/api/${route.params.xorg}`,
17
+ isJsonMime: () => true,
18
+ };
19
+ const docsOpenapi: any = {
20
+ <% for(let i=0;i<it.modules.length; i++){ %>
21
+ '<%=it.modules[i].docname.toLowerCase()%>': new o.<%=it.modules[i].doctype.toUpperCase()%>Api(config),
22
+ <%}%>
23
+ };
24
+ if (!docsOpenapi[apiname]) {
25
+ console.error(
26
+ `api for '${apiname}' does not exists, most probably define wrong x-foreignkey`,
27
+ );
28
+ return undefined;
29
+ } else {
30
+ return docsOpenapi[apiname];
31
+ }
32
+ };
33
+
34
+
35
+ export const getAllApi=()=>{
5
36
  return o
6
37
  }
@@ -4,7 +4,7 @@
4
4
  <template>
5
5
  <div>
6
6
  <HeaderBar />
7
- <Invitation/>
7
+ <UserInvitation/>
8
8
  <slot></slot>
9
9
  </div>
10
10
  </template>
@@ -148,8 +148,8 @@ watch(()=> useRoute().meta ,(newvalue,oldvalue)=>{
148
148
  <div>
149
149
 
150
150
  <HeaderBar />
151
- <Invitation/>
152
- <DocumentDatatable :value="recordlist" :columns="tablecolumns" :title="String(useRoute().meta.name)">
151
+ <UserInvitation/>
152
+ <TableDocuments :value="recordlist" :columns="tablecolumns" :title="String(useRoute().meta.name)">
153
153
  <template #toolbar>
154
154
  <div class="w-full text-left">
155
155
  <slot>
@@ -162,10 +162,10 @@ watch(()=> useRoute().meta ,(newvalue,oldvalue)=>{
162
162
  </template>
163
163
  <Column header=" ">
164
164
  <template #body="{index,data}">
165
- <Button @click="goTo(String(useRoute().meta.documentName),data._id)" icon="pi pi-pencil" class="bg-primary-600 hover:bg-primary-400 text-white" >Edit</Button>
165
+ <Button @click="goTo(String(useRoute().meta.documentName),data._id)" icon="pi pi-pencil" class="btn btn-primary" >Edit</Button>
166
166
  </template>
167
167
  </Column>
168
- </DocumentDatatable>
168
+ </TableDocuments>
169
169
  <!--
170
170
  <DebugDocumentData v-model="data"/>
171
171
  -->