@simitgroup/simpleapp-generator 1.3.3-alpha → 1.3.4-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/framework.js +2 -2
- package/dist/framework.js.map +1 -1
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +7 -11
- package/dist/generate.js.map +1 -1
- package/dist/processors/jsonschemabuilder.d.ts.map +1 -1
- package/dist/processors/jsonschemabuilder.js +8 -0
- package/dist/processors/jsonschemabuilder.js.map +1 -1
- package/package.json +1 -1
- package/src/framework.ts +2 -2
- package/src/generate.ts +15 -12
- package/src/processors/jsonschemabuilder.ts +12 -1
- package/templates/basic/nest/controller.ts.eta +16 -5
- package/templates/basic/nuxt/component.select.vue.eta +35 -0
- package/templates/basic/nuxt/pages.form.vue.eta +5 -8
- package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +3 -1
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +10 -9
- package/templates/nest/src/simpleapp/generate/controllers/simpleapp.controller.ts.eta +2 -2
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +38 -38
- package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +14 -9
- package/templates/nuxt/assets/css/style.css._eta +39 -3
- package/templates/nuxt/assets/primevue/passthrough.ts._eta +17 -12
- package/templates/nuxt/components/button/ButtonAction.vue._eta +19 -0
- package/templates/nuxt/components/button/ButtonDanger.vue._eta +13 -6
- package/templates/nuxt/components/button/ButtonDefault.vue._eta +13 -6
- package/templates/nuxt/components/button/ButtonMultiple.vue._eta +9 -7
- package/templates/nuxt/components/button/ButtonPrimary.vue._eta +13 -6
- package/templates/nuxt/components/button/ButtonText.vue._eta +16 -7
- package/templates/nuxt/components/button/ButtonWarning.vue._eta +13 -6
- package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +83 -69
- package/templates/nuxt/components/chart/card.vue._eta +32 -0
- package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +44 -21
- package/templates/nuxt/components/event/EventNotification.vue._eta +119 -107
- package/templates/nuxt/components/header/button/HeaderButtonProfile.vue.eta +129 -75
- package/templates/nuxt/components/list/ListView.vue.eta +44 -13
- package/templates/nuxt/components/mobile/MobileToolbar.vue.eta +6 -5
- package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +35 -37
- package/templates/nuxt/components/overlay/OverlaySideBarCrud.vue.eta +3 -4
- package/templates/nuxt/components/renderer/RendererDate.vue.eta +3 -2
- package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +38 -34
- package/templates/nuxt/components/select/SelectTemplate.vue.eta +79 -0
- package/templates/nuxt/components/select/readme.md +1 -0
- package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +181 -35
- package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +70 -0
- package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +77 -73
- package/templates/nuxt/components/simpleApp/SimpleAppForm.vue.eta +113 -111
- package/templates/nuxt/components/simpleApp/{SimpleAppFormToolBar.vue.eta → SimpleAppFormToolBar.vue._eta} +125 -61
- package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +116 -42
- package/templates/nuxt/components/text/TextPrimary.vue._eta +13 -0
- package/templates/nuxt/components/user/UserButtonCreateTenant.vue._eta +68 -0
- package/templates/nuxt/components/user/UserTenantPicker.vue.eta +81 -70
- package/templates/nuxt/composables/date.generate.ts.eta +2 -0
- package/templates/nuxt/composables/getDocument.generate.ts.eta +35 -2
- package/templates/nuxt/composables/getOpenApi.generate.ts.eta +5 -1
- package/templates/nuxt/composables/refreshDocumentList.generate.ts.eta +2 -1
- package/templates/nuxt/lang/en.ts.eta +3 -1
- package/templates/nuxt/nuxt.config.ts._eta +3 -0
- package/templates/nuxt/pages/index.vue._eta +10 -56
- package/templates/nuxt/pages/picktenant.vue._eta +19 -0
- package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +10 -2
- package/templates/nuxt/server/api/[xorg]/[...].ts.eta +9 -10
- package/templates/nuxt/types/calendar.ts.eta +2 -0
- package/templates/nuxt/types/events.ts.eta +3 -1
- package/templates/nuxt/types/simpleappinput.ts.eta +1 -0
- package/templates/project/lang/default._json +5 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nuxt/components/user/UserButtonCreateTenant.vue.eta +0 -103
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
<span
|
|
8
8
|
class="pi pi-times rounded-full bg-slate-500 p-1 cursor-pointer text-xs"
|
|
9
9
|
@click="clear"
|
|
10
|
-
></span>
|
|
10
|
+
></span>
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
13
|
<AutoComplete
|
|
14
|
+
v-if="!isMobile()"
|
|
14
15
|
class="w-full"
|
|
15
16
|
v-model="modelValue"
|
|
16
17
|
ref="autocompleteinput"
|
|
@@ -53,6 +54,76 @@
|
|
|
53
54
|
</template>
|
|
54
55
|
<!-- </slot> -->
|
|
55
56
|
</AutoComplete>
|
|
57
|
+
<div v-else>
|
|
58
|
+
<InputGroup class="w-full flex flex-row">
|
|
59
|
+
<InputText
|
|
60
|
+
:value="modelValue?.label"
|
|
61
|
+
@focus="showAutocompleteDialog(false)"
|
|
62
|
+
:placeholder="placeholdertxt"
|
|
63
|
+
class="rounded-r-none"
|
|
64
|
+
></InputText>
|
|
65
|
+
<InputGroupAddon
|
|
66
|
+
@click="showAutocompleteDialog(true)"
|
|
67
|
+
v-ripple
|
|
68
|
+
class="bg bg-primary-600 dark:bg-primary-700 text-white rounded-r-lg p-3"
|
|
69
|
+
>
|
|
70
|
+
<i :class="`pi ${modelValue ? 'pi-link' : 'pi-angle-down'}`"></i>
|
|
71
|
+
</InputGroupAddon>
|
|
72
|
+
</InputGroup>
|
|
73
|
+
|
|
74
|
+
<OverlaySideBarCrud
|
|
75
|
+
v-model="mobileVisible"
|
|
76
|
+
closeEventName="autocompleteoverlay"
|
|
77
|
+
>
|
|
78
|
+
<template v-if="mobileListMode == 'list'">
|
|
79
|
+
<mobile-toolbar>
|
|
80
|
+
<template #start>
|
|
81
|
+
<ButtonText @click="mobileVisible = false">
|
|
82
|
+
<i class="pi pi-times"></i>
|
|
83
|
+
</ButtonText>
|
|
84
|
+
</template>
|
|
85
|
+
<template #center>
|
|
86
|
+
<TextTitle>{{ t(docname) }}</TextTitle>
|
|
87
|
+
</template>
|
|
88
|
+
<template #end>
|
|
89
|
+
<div></div>
|
|
90
|
+
<!-- <ButtonText @click="openViewer(false)">
|
|
91
|
+
<i class="pi pi-plus"></i>
|
|
92
|
+
</ButtonText> -->
|
|
93
|
+
</template>
|
|
94
|
+
</mobile-toolbar>
|
|
95
|
+
<div class="h-16"></div>
|
|
96
|
+
<ListView
|
|
97
|
+
:list="list"
|
|
98
|
+
:withFilter="true"
|
|
99
|
+
:defaultFilterValue="defaultFilterValue"
|
|
100
|
+
idField="_id"
|
|
101
|
+
titleField="code"
|
|
102
|
+
subTitleField="label"
|
|
103
|
+
#default="{ item, index }"
|
|
104
|
+
@click="onClickInMobile"
|
|
105
|
+
>
|
|
106
|
+
<div class="flex flex-row justify-end">
|
|
107
|
+
<div class="flex-1">{{ item.label }}</div>
|
|
108
|
+
<div>{{ item.code }}</div>
|
|
109
|
+
</div>
|
|
110
|
+
</ListView>
|
|
111
|
+
</template>
|
|
112
|
+
<template v-else>
|
|
113
|
+
<component
|
|
114
|
+
:is="
|
|
115
|
+
defineAsyncComponent(
|
|
116
|
+
getDocument(setting.fieldsetting['x-foreignkey']).viewer,
|
|
117
|
+
)
|
|
118
|
+
"
|
|
119
|
+
@after="
|
|
120
|
+
async (eventType: FormCrudEvent, data: any, result: any) =>
|
|
121
|
+
await afterRenderMobileForm(eventType, data)
|
|
122
|
+
"
|
|
123
|
+
/>
|
|
124
|
+
</template>
|
|
125
|
+
</OverlaySideBarCrud>
|
|
126
|
+
</div>
|
|
56
127
|
</div>
|
|
57
128
|
<div
|
|
58
129
|
v-else
|
|
@@ -76,9 +147,19 @@
|
|
|
76
147
|
*/
|
|
77
148
|
import { isNull } from "lodash";
|
|
78
149
|
import jsonpath from "jsonpath";
|
|
79
|
-
import {
|
|
80
|
-
|
|
81
|
-
|
|
150
|
+
import {
|
|
151
|
+
AutoCompleteDropdownClickEvent,
|
|
152
|
+
AutoCompleteProps,
|
|
153
|
+
} from "primevue/autocomplete";
|
|
154
|
+
import {
|
|
155
|
+
autocompletetype,
|
|
156
|
+
ForeignKey,
|
|
157
|
+
FormCrudEvent,
|
|
158
|
+
SchemaConfig,
|
|
159
|
+
SchemaType,
|
|
160
|
+
} from "~/types";
|
|
161
|
+
const mobileVisible = ref(false);
|
|
162
|
+
const autocompleteinput = ref<autocompletetype | undefined>();
|
|
82
163
|
const { $event } = useNuxtApp();
|
|
83
164
|
const list = ref<any[]>([]);
|
|
84
165
|
const props = withDefaults(
|
|
@@ -87,9 +168,11 @@ const props = withDefaults(
|
|
|
87
168
|
allowAddNew?: boolean;
|
|
88
169
|
showNull?: boolean;
|
|
89
170
|
readonly?: boolean;
|
|
90
|
-
placeholder?:string;
|
|
91
|
-
hidelabel?:boolean;
|
|
171
|
+
placeholder?: string;
|
|
172
|
+
hidelabel?: boolean;
|
|
92
173
|
inputId: string;
|
|
174
|
+
componentProps?: AutoCompleteProps;
|
|
175
|
+
autocompleteFilter?: any;
|
|
93
176
|
pt?: any;
|
|
94
177
|
}>(),
|
|
95
178
|
{
|
|
@@ -97,7 +180,8 @@ const props = withDefaults(
|
|
|
97
180
|
showNull: true,
|
|
98
181
|
},
|
|
99
182
|
);
|
|
100
|
-
|
|
183
|
+
const mobileListMode = ref("list");
|
|
184
|
+
const defaultFilterValue = ref("");
|
|
101
185
|
const path = "$" + props.setting.instancepath;
|
|
102
186
|
const modifiedpath = path.replaceAll("/", ".");
|
|
103
187
|
const queryresult = jsonpath.query(props.setting.defaultValue, modifiedpath)[0];
|
|
@@ -106,18 +190,22 @@ const schema: SchemaType = <SchemaType>remotedoc?.docClass.getSchema();
|
|
|
106
190
|
const labelfield = schema["x-simpleapp-config"].documentTitle as string;
|
|
107
191
|
const codefield = schema["x-simpleapp-config"].uniqueKey as string;
|
|
108
192
|
const docname = props.setting.fieldsetting["x-foreignkey"];
|
|
109
|
-
const placeholdertxt = computed(()=> props.placeholder ?? t(docname)
|
|
110
|
-
const emptyautocomplete = computed((): autocompletetype => queryresult);
|
|
193
|
+
const placeholdertxt = computed(() => props.placeholder ?? t(docname));
|
|
194
|
+
const emptyautocomplete = computed(() => undefined); //((): autocompletetype => queryresult);
|
|
111
195
|
const cancelShowList = ref(false);
|
|
112
|
-
const autocompleteitem = ref<autocompletetype|undefined>(
|
|
113
|
-
|
|
196
|
+
const autocompleteitem = ref<autocompletetype | undefined>(
|
|
197
|
+
emptyautocomplete.value,
|
|
198
|
+
);
|
|
199
|
+
const modelValue = defineModel<autocompletetype | undefined>({
|
|
200
|
+
required: true,
|
|
201
|
+
});
|
|
114
202
|
if (modelValue.value && modelValue.value._id) {
|
|
115
203
|
autocompleteitem.value = { ...modelValue.value };
|
|
116
204
|
}
|
|
117
205
|
//clear auto complete auto set value = empty
|
|
118
206
|
const clear = () => {
|
|
119
|
-
autocompleteitem.value = undefined
|
|
120
|
-
modelValue.value = undefined
|
|
207
|
+
autocompleteitem.value = undefined;
|
|
208
|
+
modelValue.value = undefined;
|
|
121
209
|
};
|
|
122
210
|
|
|
123
211
|
//if record picked, click button show record info instead
|
|
@@ -140,13 +228,30 @@ const onBlurAutocomplete = () => {
|
|
|
140
228
|
}
|
|
141
229
|
};
|
|
142
230
|
|
|
231
|
+
const showAutocompleteDialog = (isbutton: boolean) => {
|
|
232
|
+
mobileListMode.value='list'
|
|
233
|
+
if (modelValue.value && isbutton) {
|
|
234
|
+
openViewer(false);
|
|
235
|
+
} else {
|
|
236
|
+
// if(!modelValue.value && !isbutton ){
|
|
237
|
+
mobileVisible.value = true;
|
|
238
|
+
defaultFilterValue.value =
|
|
239
|
+
modelValue.value && modelValue.value?._id ? modelValue.value.label : "";
|
|
240
|
+
getListFromAutocompleteApi({ query: "" });
|
|
241
|
+
}
|
|
242
|
+
};
|
|
143
243
|
//obtain remote data
|
|
144
244
|
const getListFromAutocompleteApi = (event: any) => {
|
|
145
|
-
const keyword = event
|
|
245
|
+
const keyword = event?.query ?? "";
|
|
246
|
+
const defaultfilter: any = schema.properties["active"]
|
|
247
|
+
? { active: true }
|
|
248
|
+
: {};
|
|
249
|
+
const morefilter = props.autocompleteFilter ?? defaultfilter;
|
|
146
250
|
const targetDocument = props.setting.fieldsetting["x-foreignkey"];
|
|
147
251
|
getDocumentApi(targetDocument)
|
|
148
|
-
.autoComplete(keyword)
|
|
252
|
+
.autoComplete(keyword, morefilter)
|
|
149
253
|
.then((res: any) => {
|
|
254
|
+
console.log("Run autocomplete?");
|
|
150
255
|
list.value = res.data;
|
|
151
256
|
|
|
152
257
|
if (props.allowAddNew) {
|
|
@@ -161,16 +266,20 @@ const getListFromAutocompleteApi = (event: any) => {
|
|
|
161
266
|
//on select
|
|
162
267
|
const pickAutoComplete = (event: any) => {
|
|
163
268
|
if (event.value._id === "") {
|
|
164
|
-
modelValue.value = emptyautocomplete.value;
|
|
165
|
-
autocompleteitem.value = emptyautocomplete.value;
|
|
269
|
+
modelValue.value = undefined; //emptyautocomplete.value;
|
|
270
|
+
autocompleteitem.value = undefined; //emptyautocomplete.value;
|
|
166
271
|
} else if (event.value._id === "new") {
|
|
167
|
-
modelValue.value = emptyautocomplete.value;
|
|
168
|
-
autocompleteitem.value = emptyautocomplete.value;
|
|
169
|
-
|
|
272
|
+
modelValue.value = undefined; // emptyautocomplete.value;
|
|
273
|
+
autocompleteitem.value = undefined; //emptyautocomplete.value;
|
|
274
|
+
if (isMobile()) {
|
|
275
|
+
mobileListMode.value = "form";
|
|
276
|
+
return;
|
|
277
|
+
} else openViewer(false);
|
|
170
278
|
} else if (typeof event.value.query == "undefined") {
|
|
171
279
|
modelValue.value = event.value;
|
|
172
280
|
autocompleteitem.value = event.value;
|
|
173
281
|
}
|
|
282
|
+
mobileVisible.value = false;
|
|
174
283
|
};
|
|
175
284
|
|
|
176
285
|
const emits = defineEmits([
|
|
@@ -191,7 +300,7 @@ const setFocus = (ev: any) => {
|
|
|
191
300
|
|
|
192
301
|
//pop up records
|
|
193
302
|
const openViewer = (readonly: boolean) => {
|
|
194
|
-
if (remotedoc) {
|
|
303
|
+
if (remotedoc) {
|
|
195
304
|
$event("ViewRecord", {
|
|
196
305
|
_id: modelValue.value?._id as string,
|
|
197
306
|
eventId: randomUUID(),
|
|
@@ -203,24 +312,61 @@ const openViewer = (readonly: boolean) => {
|
|
|
203
312
|
documentName: docname,
|
|
204
313
|
|
|
205
314
|
//after create, auto copy value into auto complete
|
|
206
|
-
after: (eventType:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
315
|
+
after: async (eventType: FormCrudEvent, data: any) => {
|
|
316
|
+
if (
|
|
317
|
+
eventType == FormCrudEvent.create ||
|
|
318
|
+
eventType == FormCrudEvent.update
|
|
319
|
+
) {
|
|
320
|
+
autocompleteitem.value = {
|
|
321
|
+
_id: data._id,
|
|
322
|
+
code: data[codefield],
|
|
323
|
+
label: data[labelfield],
|
|
324
|
+
};
|
|
325
|
+
if (schema["x-simpleapp-config"].additionalAutoCompleteFields) {
|
|
326
|
+
const addfields =
|
|
327
|
+
schema["x-simpleapp-config"].additionalAutoCompleteFields;
|
|
328
|
+
for (let i = 0; i < addfields.length; i++) {
|
|
329
|
+
const fieldname = addfields[i] as string;
|
|
330
|
+
autocompleteitem.value[fieldname] = data[fieldname];
|
|
331
|
+
}
|
|
218
332
|
}
|
|
333
|
+
modelValue.value = { ...autocompleteitem.value };
|
|
334
|
+
emitChanges();
|
|
219
335
|
}
|
|
220
|
-
modelValue.value = { ...autocompleteitem.value };
|
|
221
|
-
emitChanges();
|
|
222
336
|
},
|
|
223
337
|
});
|
|
224
338
|
}
|
|
225
339
|
};
|
|
340
|
+
|
|
341
|
+
const onClickInMobile = (id: string, item: ForeignKey) => {
|
|
342
|
+
pickAutoComplete({ value: item });
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const afterRenderMobileForm = async (
|
|
346
|
+
eventType: FormCrudEvent,
|
|
347
|
+
data: any,
|
|
348
|
+
result: any,
|
|
349
|
+
) => {
|
|
350
|
+
console.log("afterRenderMobileForm", eventType);
|
|
351
|
+
if (eventType == FormCrudEvent.create || eventType == FormCrudEvent.update) {
|
|
352
|
+
autocompleteitem.value = {
|
|
353
|
+
_id: data._id,
|
|
354
|
+
code: data[codefield],
|
|
355
|
+
label: data[labelfield],
|
|
356
|
+
};
|
|
357
|
+
if (schema["x-simpleapp-config"].additionalAutoCompleteFields) {
|
|
358
|
+
const addfields =
|
|
359
|
+
schema["x-simpleapp-config"].additionalAutoCompleteFields;
|
|
360
|
+
for (let i = 0; i < addfields.length; i++) {
|
|
361
|
+
const fieldname = addfields[i] as string;
|
|
362
|
+
autocompleteitem.value[fieldname] = data[fieldname];
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
modelValue.value = { ...autocompleteitem.value };
|
|
366
|
+
emitChanges();
|
|
367
|
+
mobileVisible.value = false;
|
|
368
|
+
} else if (eventType == FormCrudEvent.exit) {
|
|
369
|
+
mobileVisible.value = false;
|
|
370
|
+
}
|
|
371
|
+
};
|
|
226
372
|
</script>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-col">
|
|
3
|
+
<div class="flex flex-row">
|
|
4
|
+
<div class="p-2 flex-1">
|
|
5
|
+
<TextTitle v-if="title">{{ title }}</TextTitle>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="pr-2">
|
|
8
|
+
<ButtonDefault v-if="!readOnly" @click="addRow"
|
|
9
|
+
><i class="pi pi-plus"></i
|
|
10
|
+
></ButtonDefault>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
<ListView
|
|
14
|
+
class="p-2 dark:bg-slate-900 bg-slate-200 rounded-lg"
|
|
15
|
+
:list="list"
|
|
16
|
+
#default="{ index, item }"
|
|
17
|
+
@click="showRow"
|
|
18
|
+
>
|
|
19
|
+
<slot name="listbody" :item="item" :index="index">
|
|
20
|
+
<div class="flex flex-row">item {{ item._id }}</div>
|
|
21
|
+
</slot>
|
|
22
|
+
</ListView>
|
|
23
|
+
|
|
24
|
+
<Dialog v-model:visible="showDialog" modal :header="t('editDetails')">
|
|
25
|
+
<div class="flex flex-col p-2 gap-4">
|
|
26
|
+
<slot name="popupbody" :index="rowIndex" :item="list[rowIndex]">
|
|
27
|
+
row {{ rowIndex }} define SimpleAppInputs here
|
|
28
|
+
</slot>
|
|
29
|
+
</div>
|
|
30
|
+
<template #footer>
|
|
31
|
+
<div v-if="!readOnly" class="flex flex-row gap-2 w-full">
|
|
32
|
+
<ButtonDanger @click="deleteItem">{{ t("delete") }}</ButtonDanger>
|
|
33
|
+
<ButtonPrimary @click="updateItem">{{ t("ok") }}</ButtonPrimary>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
</Dialog>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
<script setup lang="ts" generic="T extends { [key: string]: any }">
|
|
40
|
+
/**
|
|
41
|
+
* This file was automatically generated by simpleapp generator. Every
|
|
42
|
+
* MODIFICATION OVERRIDE BY GENERATEOR
|
|
43
|
+
* last change 2024-03-01
|
|
44
|
+
* Author: Ks Tan
|
|
45
|
+
*/
|
|
46
|
+
const showDialog = ref(false);
|
|
47
|
+
const rowIndex = ref(0);
|
|
48
|
+
const emits = defineEmits(["addrow", "deleteitem", "itemupdated"]);
|
|
49
|
+
const props = defineProps<{ list: T[]; title?: string; readOnly?: boolean }>();
|
|
50
|
+
|
|
51
|
+
const showRow = (index: number, item: T) => {
|
|
52
|
+
showDialog.value = true;
|
|
53
|
+
rowIndex.value = index;
|
|
54
|
+
};
|
|
55
|
+
const deleteItem = () => {
|
|
56
|
+
showDialog.value = false;
|
|
57
|
+
props.list.splice(rowIndex.value, 1);
|
|
58
|
+
emits("deleteitem");
|
|
59
|
+
};
|
|
60
|
+
const updateItem = () => {
|
|
61
|
+
showDialog.value = false;
|
|
62
|
+
emits("itemupdated", rowIndex.value);
|
|
63
|
+
};
|
|
64
|
+
const addRow = (event:MouseEvent) =>{
|
|
65
|
+
|
|
66
|
+
emits('addrow', MouseEvent)
|
|
67
|
+
const lineno = props.list.length -1
|
|
68
|
+
showRow(lineno, props.list[lineno])
|
|
69
|
+
}
|
|
70
|
+
</script>
|
|
@@ -1,37 +1,43 @@
|
|
|
1
|
-
|
|
2
1
|
<template>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
2
|
+
<div class="flex flex-row w-full">
|
|
3
|
+
<InputText
|
|
4
|
+
@focus="setFocus"
|
|
5
|
+
:readonly="readonly"
|
|
6
|
+
v-model="modelValue"
|
|
7
|
+
:placeholder="placeholder"
|
|
8
|
+
:pt="pt"
|
|
9
|
+
:class="
|
|
10
|
+
!pt
|
|
11
|
+
? 'flex-1 w-full rounded-lg ' +
|
|
12
|
+
(props.readonly ? '' : 'rounded-tr-none rounded-br-none')
|
|
13
|
+
: ''
|
|
14
|
+
"
|
|
15
|
+
/>
|
|
16
|
+
<span class="" v-if="!readonly">
|
|
17
|
+
<button v-ripple
|
|
18
|
+
type="button"
|
|
19
|
+
@click="toggle"
|
|
20
|
+
tabindex="-1"
|
|
21
|
+
class="'btn btn-primary p-3 dark:border-blue-900/40 rounded-lg rounded-tl-none rounded-bl-none"
|
|
22
|
+
>
|
|
23
|
+
<i class="pi pi-angle-down"></i>
|
|
24
|
+
</button>
|
|
25
|
+
<OverlayPanel ref="op" class="p-4">
|
|
26
|
+
<div class="m-4">
|
|
27
|
+
<ul>
|
|
28
|
+
<li v-for="docno in docFormatlist" class="hover-list-primary p-2">
|
|
29
|
+
<a class="" @click="chooseFormat(docno)">
|
|
30
|
+
<span class="pi pi-hashtag mr-2"></span>
|
|
31
|
+
<span class="">{{ docno.docNoFormatName }}</span>
|
|
32
|
+
<span class="text text-green-600">{{ docno.sample }}</span>
|
|
33
|
+
</a>
|
|
34
|
+
</li>
|
|
35
|
+
</ul>
|
|
33
36
|
</div>
|
|
34
|
-
|
|
37
|
+
</OverlayPanel>
|
|
38
|
+
</span>
|
|
39
|
+
<!-- {{ Object.getOwnPropertyNames(setting) }} -->
|
|
40
|
+
</div>
|
|
35
41
|
</template>
|
|
36
42
|
<script lang="ts" setup>
|
|
37
43
|
/**
|
|
@@ -40,52 +46,50 @@
|
|
|
40
46
|
* last change 2023-10-28
|
|
41
47
|
* Author: Ks Tan
|
|
42
48
|
*/
|
|
43
|
-
import {ForeignKey} from
|
|
44
|
-
import OverlayPanel from
|
|
45
|
-
import InputText from
|
|
46
|
-
import {DocNoFormat} from "~/types"
|
|
49
|
+
import { ForeignKey } from "~/types";
|
|
50
|
+
import OverlayPanel from "primevue/overlaypanel";
|
|
51
|
+
import InputText from "primevue/inputtext";
|
|
52
|
+
import { DocNoFormat } from "~/types";
|
|
47
53
|
const props = defineProps<{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}>()
|
|
54
|
+
setting: any;
|
|
55
|
+
readonly?: boolean;
|
|
56
|
+
pt?: any;
|
|
57
|
+
}>();
|
|
52
58
|
const op = ref();
|
|
53
|
-
const placeholder = ref(
|
|
54
|
-
const docFormatlist = ref()
|
|
55
|
-
const modelValue = defineModel<string>({required:true})
|
|
56
|
-
const docNoFormat = props.setting.document.getReactiveData().value.docNoFormat
|
|
57
|
-
const emits = defineEmits([
|
|
58
|
-
|
|
59
|
-
const documenttype = props.setting.document.doctype
|
|
60
|
-
|
|
61
|
-
const toggle = async (event:any) => {
|
|
62
|
-
op.value.toggle(event);
|
|
63
|
-
}
|
|
59
|
+
const placeholder = ref("");
|
|
60
|
+
const docFormatlist = ref();
|
|
61
|
+
const modelValue = defineModel<string>({ required: true });
|
|
62
|
+
const docNoFormat = props.setting.document.getReactiveData().value.docNoFormat;
|
|
63
|
+
const emits = defineEmits(["update:docNoFormat"]);
|
|
64
64
|
|
|
65
|
-
const
|
|
66
|
-
placeholder.value = item.sample
|
|
67
|
-
const f = item
|
|
68
|
-
docNoFormat.value = { _id : f._id, label : f.docNoFormatName}
|
|
69
|
-
op.value.toggle();
|
|
70
|
-
emits('update:docNoFormat',item)
|
|
71
|
-
}
|
|
65
|
+
const documenttype = props.setting.document.doctype;
|
|
72
66
|
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const f = docFormatlist.value[0]
|
|
77
|
-
docNoFormat.value = { _id : f._id, label : f.docNoFormatName}
|
|
78
|
-
placeholder.value = docFormatlist.value[0].sample
|
|
79
|
-
}
|
|
80
|
-
}
|
|
67
|
+
const toggle = async (event: any) => {
|
|
68
|
+
op.value.toggle(event);
|
|
69
|
+
};
|
|
81
70
|
|
|
71
|
+
const chooseFormat = (item: any) => {
|
|
72
|
+
placeholder.value = item.sample;
|
|
73
|
+
const f = item;
|
|
74
|
+
docNoFormat.value = { _id: f._id, label: f.docNoFormatName };
|
|
75
|
+
op.value.toggle();
|
|
76
|
+
emits("update:docNoFormat", item);
|
|
77
|
+
};
|
|
82
78
|
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
const loadDocFormats = async () => {
|
|
80
|
+
docFormatlist.value = await getDocFormats(documenttype);
|
|
81
|
+
if (docFormatlist.value.length > 0) {
|
|
82
|
+
const f = docFormatlist.value[0];
|
|
83
|
+
docNoFormat.value = { _id: f._id, label: f.docNoFormatName };
|
|
84
|
+
placeholder.value = docFormatlist.value[0].sample;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
const setFocus = (ev: any) => {
|
|
89
|
+
if (!isMobile()) ev.target.select();
|
|
90
|
+
};
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
onMounted(() => {
|
|
93
|
+
loadDocFormats();
|
|
94
|
+
});
|
|
95
|
+
</script>
|