@simitgroup/simpleapp-generator 1.3.3-alpha → 1.3.5-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 +17 -6
- 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/.gitignore.eta +6 -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 +43 -7
- package/templates/nuxt/assets/primevue/passthrough.ts._eta +26 -15
- 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/HeaderButtonMenuPicker.vue._eta +46 -38
- package/templates/nuxt/components/header/button/HeaderButtonProfile.vue.eta +131 -75
- package/templates/nuxt/components/list/ListView.vue.eta +44 -13
- package/templates/nuxt/components/mobile/MobileToolbar.vue.eta +13 -8
- 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/SimpleAppFieldContainer.vue.eta +20 -7
- package/templates/nuxt/components/simpleApp/SimpleAppForm.vue.eta +113 -111
- package/templates/nuxt/components/simpleApp/{SimpleAppFormToolBar.vue.eta → SimpleAppFormToolBar.vue._eta} +126 -65
- package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +117 -43
- package/templates/nuxt/components/text/TextPrimary.vue._eta +13 -0
- package/templates/nuxt/components/user/UserButtonCreateTenant.vue._eta +64 -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 +14 -2
- package/templates/nuxt/lang/en.ts.eta +3 -1
- package/templates/nuxt/nuxt.config.ts._eta +3 -0
- package/templates/nuxt/pages/[xorg]/organization.vue.eta +80 -61
- 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 +150 -63
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nuxt/components/user/UserButtonCreateTenant.vue.eta +0 -103
|
@@ -1,41 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-if="isMobile()" class="w-full">
|
|
3
|
-
<MobileToolbar class="
|
|
2
|
+
<div v-if="isMobile()" class="w-full">
|
|
3
|
+
<MobileToolbar class="bg-gray-800 text-white">
|
|
4
4
|
<template #start>
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
<slot name="start" :menu="menu">
|
|
6
|
+
<ButtonText class="text-xl" @click="callClose"
|
|
7
|
+
><i class="pi pi-times"></i
|
|
8
|
+
></ButtonText>
|
|
9
|
+
</slot>
|
|
8
10
|
</template>
|
|
9
11
|
<template #center>
|
|
10
|
-
<
|
|
12
|
+
<slot name="center" :menu="menu">
|
|
13
|
+
<TextTitle class="text-white line-clamp-2">{{ title }}</TextTitle>
|
|
14
|
+
</slot>
|
|
11
15
|
</template>
|
|
12
16
|
<template #end>
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
>
|
|
31
|
-
<i class="pi pi-save"></i>
|
|
32
|
-
</ButtonText>
|
|
33
|
-
|
|
34
|
-
<ContextMenu ref="menu" :model="menus as MenuItem[]" />
|
|
35
|
-
</div>
|
|
17
|
+
<slot name="end" :menu="menu">
|
|
18
|
+
<div class="flex flex-row w-full">
|
|
19
|
+
<ButtonText
|
|
20
|
+
class="text-xl"
|
|
21
|
+
@click="emitEvent(menus[0], $event)"
|
|
22
|
+
v-if="isShow"
|
|
23
|
+
v-tooltip="menus[0].label"
|
|
24
|
+
>
|
|
25
|
+
<i :class="menus[0].icon"></i>
|
|
26
|
+
</ButtonText>
|
|
27
|
+
|
|
28
|
+
<ButtonText class="text-xl" @click="toggleMenu" v-if="isShow">
|
|
29
|
+
<i class="pi pi-ellipsis-v"></i>
|
|
30
|
+
</ButtonText>
|
|
31
|
+
</div>
|
|
32
|
+
</slot>
|
|
33
|
+
<ContextMenu ref="menu" :model="menus as MenuItem[]" />
|
|
36
34
|
</template>
|
|
37
|
-
</MobileToolbar>
|
|
38
|
-
<div class="h-14"></div>
|
|
35
|
+
</MobileToolbar>
|
|
39
36
|
<ConfirmDialog></ConfirmDialog>
|
|
40
37
|
</div>
|
|
41
38
|
<div v-else class="simpleapp-tool-bar">
|
|
@@ -43,63 +40,87 @@
|
|
|
43
40
|
<template #start>
|
|
44
41
|
<div v-for="(menu, index) in menus" :key="index">
|
|
45
42
|
<div v-if="menu.label && menu.type == 'crud'">
|
|
46
|
-
<
|
|
47
|
-
menu
|
|
48
|
-
|
|
43
|
+
<ButtonAction
|
|
44
|
+
@click="emitEvent(menu, $event)"
|
|
45
|
+
:action-name="menu.action"
|
|
46
|
+
>{{ menu.label }}</ButtonAction
|
|
47
|
+
>
|
|
49
48
|
</div>
|
|
50
49
|
</div>
|
|
51
50
|
</template>
|
|
52
51
|
<template #center>
|
|
52
|
+
<TextTitle class="text-white line-clamp-2">{{ title }}</TextTitle>
|
|
53
|
+
</template>
|
|
54
|
+
<template #end>
|
|
53
55
|
<div v-for="(menu, index) in menus" :key="index">
|
|
54
56
|
<div v-if="menu.label && menu.type == 'docstatus'">
|
|
55
|
-
<
|
|
56
|
-
menu
|
|
57
|
-
|
|
57
|
+
<ButtonAction
|
|
58
|
+
@click="emitEvent(menu, $event)"
|
|
59
|
+
:action-name="menu.action"
|
|
60
|
+
>{{ menu.label }}</ButtonAction
|
|
61
|
+
>
|
|
58
62
|
</div>
|
|
59
63
|
</div>
|
|
60
64
|
</template>
|
|
61
|
-
<template #end> </template>
|
|
62
65
|
</Toolbar>
|
|
63
|
-
|
|
64
66
|
<ConfirmPopup></ConfirmPopup>
|
|
65
67
|
</div>
|
|
66
68
|
</template>
|
|
67
69
|
<script setup lang="ts">
|
|
68
70
|
/**
|
|
69
|
-
* This file was automatically generated by simpleapp generator.
|
|
70
|
-
*
|
|
71
|
-
* last change
|
|
72
|
-
*
|
|
71
|
+
* This file was automatically generated by simpleapp generator during initialization. It is changable.
|
|
72
|
+
* --remove-this-line-to-prevent-override--
|
|
73
|
+
* last change 2024-02-22
|
|
74
|
+
* author: Ks Tan
|
|
73
75
|
*/
|
|
76
|
+
|
|
74
77
|
import { SimpleAppClient } from "~/simpleapp/generate/clients/SimpleAppClient";
|
|
75
78
|
import { useConfirm } from "primevue/useconfirm";
|
|
76
79
|
import { FormActions, FormCrudEvent, FormMenu } from "~/types";
|
|
77
80
|
import { MenuItem } from "primevue/menuitem";
|
|
81
|
+
import { MenuItemCommandEvent } from "primevue/menuitem";
|
|
78
82
|
const confirm = useConfirm();
|
|
79
83
|
const emits = defineEmits(["on", "close"]);
|
|
80
84
|
const props = defineProps<{
|
|
81
85
|
document: SimpleAppClient<any, any>;
|
|
82
86
|
disableaction?: string[];
|
|
83
87
|
}>();
|
|
84
|
-
const createData = async () => {
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
const createData = async () => {
|
|
89
|
+
try {
|
|
90
|
+
return await doc.create();
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.debug("validation error:", e);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const updateData = async () => {
|
|
96
|
+
try {
|
|
97
|
+
return await doc.update();
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.debug("validation error:", e);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const deleteData = async () => {
|
|
103
|
+
try {
|
|
104
|
+
return await doc.delete();
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.debug("validation error:", e);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
87
109
|
|
|
88
110
|
const doc = props.document;
|
|
89
111
|
const data = doc.getReactiveData();
|
|
90
112
|
type Datatype = keyof typeof data.value;
|
|
91
113
|
const config = doc.getSchema()["x-simpleapp-config"];
|
|
92
|
-
const titlefield = (config.
|
|
93
|
-
const title =
|
|
114
|
+
const titlefield = (config.uniqueKey ?? config.documentTitle) as Datatype;
|
|
115
|
+
const title = computed(() =>
|
|
94
116
|
data.value[titlefield as Datatype]
|
|
95
117
|
? data.value[titlefield as Datatype]
|
|
96
118
|
: t(doc.getDocName()),
|
|
97
119
|
);
|
|
120
|
+
|
|
98
121
|
const menu = ref();
|
|
99
122
|
const menus = computed(() =>
|
|
100
|
-
[...getActions(),
|
|
101
|
-
showMenuButton(item),
|
|
102
|
-
),
|
|
123
|
+
[...getActions(), ...getDocActions()].filter((item) => showMenuButton(item)),
|
|
103
124
|
);
|
|
104
125
|
|
|
105
126
|
const isShow = computed(
|
|
@@ -109,23 +130,22 @@ const toggleMenu = (event: MouseEvent) => {
|
|
|
109
130
|
menu.value.toggle(event);
|
|
110
131
|
};
|
|
111
132
|
|
|
112
|
-
const callClose = (e: MouseEvent) => {
|
|
133
|
+
const callClose = (e: MouseEvent) => {
|
|
113
134
|
useNuxtApp().$event("CloseDialog", doc.getDocName());
|
|
114
135
|
emitEvent({ action: "exit", type: "menu", label: "" }, e);
|
|
115
136
|
// async (menu: FormMenu, clickEvent: MouseEvent)
|
|
116
137
|
};
|
|
117
|
-
const emitMobileEvent = (itemevent: {
|
|
118
|
-
item: any;
|
|
119
|
-
originalEvent: MouseEvent;
|
|
120
|
-
}) => {
|
|
138
|
+
const emitMobileEvent = (itemevent: MenuItemCommandEvent) => {
|
|
121
139
|
const actionname: string = itemevent.item.action;
|
|
122
140
|
const event = itemevent.originalEvent;
|
|
123
|
-
emitEvent({ action: actionname, type: "crud", label: "" }, event);
|
|
141
|
+
// emitEvent({ action: actionname, type: "crud", label: "" }, event);
|
|
142
|
+
emitEvent(itemevent.item, event);
|
|
124
143
|
};
|
|
125
144
|
|
|
126
145
|
const getActions = () => {
|
|
127
146
|
const actions = doc.getActions();
|
|
128
147
|
const crudmenus: any[] = [];
|
|
148
|
+
|
|
129
149
|
// Object.keys(actions).forEach((key)=>{ //crud, api, docstatus
|
|
130
150
|
actions["crud"].forEach((item) => {
|
|
131
151
|
if (props.disableaction && props.disableaction.includes(item)) {
|
|
@@ -135,6 +155,7 @@ const getActions = () => {
|
|
|
135
155
|
action: item,
|
|
136
156
|
label: t(item),
|
|
137
157
|
type: "crud",
|
|
158
|
+
icon: getActionIcon(item),
|
|
138
159
|
command: emitMobileEvent,
|
|
139
160
|
});
|
|
140
161
|
}
|
|
@@ -161,9 +182,10 @@ const emitEvent = async (menu: FormMenu, clickEvent: MouseEvent) => {
|
|
|
161
182
|
if (await createData()) emits("on", FormCrudEvent.create);
|
|
162
183
|
} else if (menu.action == "update") {
|
|
163
184
|
if (await updateData()) emits("on", FormCrudEvent.update);
|
|
164
|
-
} else if (menu.type == "
|
|
185
|
+
} else if (menu.type == "docstatus") {
|
|
165
186
|
emits("on", FormCrudEvent.setDocStatus, menu.action);
|
|
166
|
-
else if (menu.action == FormCrudEvent.exit)
|
|
187
|
+
} else if (menu.action == FormCrudEvent.exit)
|
|
188
|
+
emits("on", FormCrudEvent.exit);
|
|
167
189
|
}
|
|
168
190
|
};
|
|
169
191
|
|
|
@@ -183,21 +205,60 @@ const getDocActions = () => {
|
|
|
183
205
|
action: item,
|
|
184
206
|
label: statusNames[item],
|
|
185
207
|
type: "docstatus",
|
|
208
|
+
icon: getActionIcon(item),
|
|
209
|
+
command: emitMobileEvent,
|
|
186
210
|
})) ?? [];
|
|
187
211
|
}
|
|
188
212
|
return docactionmenus;
|
|
189
213
|
};
|
|
190
214
|
const showMenuButton = (menu: FormMenu) => {
|
|
191
215
|
if (menu.separator) return true;
|
|
192
|
-
|
|
193
|
-
|
|
216
|
+
|
|
217
|
+
//all document status cannot direct apply regardless new or draft
|
|
218
|
+
if (menu.type == "docstatus") return true;
|
|
219
|
+
|
|
220
|
+
// afterward, new document only acces create action
|
|
194
221
|
if (doc.isNew() && menu.action == "create") return true;
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
222
|
+
if (doc.isNew() && menu.action != "create") return false;
|
|
223
|
+
|
|
224
|
+
//start from here, readonly document all action not allow
|
|
225
|
+
if (doc.isReadOnly()) return false;
|
|
198
226
|
|
|
199
|
-
|
|
227
|
+
//edit draft document, only create not allow
|
|
228
|
+
if (!doc.isNew() && menu.action == "create") return false;
|
|
229
|
+
if (!doc.isNew() && menu.action != "create") return true;
|
|
200
230
|
|
|
201
231
|
return false;
|
|
202
232
|
};
|
|
233
|
+
|
|
234
|
+
const getActionIcon = (actionName: string) => {
|
|
235
|
+
let icon = "";
|
|
236
|
+
switch (actionName) {
|
|
237
|
+
case "create":
|
|
238
|
+
icon = "pi-save";
|
|
239
|
+
break;
|
|
240
|
+
case "update":
|
|
241
|
+
icon = "pi-save";
|
|
242
|
+
break;
|
|
243
|
+
case "delete":
|
|
244
|
+
icon = "pi-trash";
|
|
245
|
+
break;
|
|
246
|
+
case "confirm":
|
|
247
|
+
icon = "pi-check";
|
|
248
|
+
break;
|
|
249
|
+
case "void":
|
|
250
|
+
icon = "pi-ban";
|
|
251
|
+
break;
|
|
252
|
+
case "print":
|
|
253
|
+
icon = "pi-print";
|
|
254
|
+
break;
|
|
255
|
+
case "draft":
|
|
256
|
+
icon = "pi-pencil";
|
|
257
|
+
break;
|
|
258
|
+
default:
|
|
259
|
+
icon = "pi-question-circle";
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
return `pi ${icon}`;
|
|
263
|
+
};
|
|
203
264
|
</script>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
:instancepath="instancepath"
|
|
11
11
|
:error="error"
|
|
12
12
|
#default="slotprops"
|
|
13
|
+
:resetcount="resetcount"
|
|
13
14
|
>
|
|
14
15
|
<Checkbox
|
|
15
16
|
v-if="inputType == SimpleAppInputType.checkbox"
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
v-model="modelValue"
|
|
21
22
|
:binary="true"
|
|
22
23
|
v-bind="componentProps as CheckboxProps"
|
|
24
|
+
@change="onChange"
|
|
23
25
|
/>
|
|
24
26
|
<InputSwitch
|
|
25
27
|
v-else-if="inputType == SimpleAppInputType.switch"
|
|
@@ -30,8 +32,9 @@
|
|
|
30
32
|
v-model="modelValue as boolean"
|
|
31
33
|
:binary="true"
|
|
32
34
|
v-bind="componentProps as InputSwitchProps"
|
|
35
|
+
@change="onChange"
|
|
33
36
|
/>
|
|
34
|
-
|
|
37
|
+
<!--
|
|
35
38
|
<InputText
|
|
36
39
|
type="date"
|
|
37
40
|
:pt="pt"
|
|
@@ -43,19 +46,24 @@
|
|
|
43
46
|
:readonly="isReadonly"
|
|
44
47
|
:placeholder="placeholder"
|
|
45
48
|
v-bind="componentProps as InputTextProps"
|
|
46
|
-
/>
|
|
49
|
+
/> -->
|
|
47
50
|
<!-- calendar component -->
|
|
48
51
|
<Calendar
|
|
49
52
|
type="date"
|
|
50
53
|
:pt="pt"
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
v-else-if="
|
|
55
|
+
SimpleAppInputType.calendar == inputType ||
|
|
56
|
+
inputType == SimpleAppInputType.date
|
|
57
|
+
"
|
|
53
58
|
:inputId="slotprops.uuid"
|
|
54
59
|
:path="setting.instancepath"
|
|
55
60
|
v-model="datevalue"
|
|
56
61
|
@update:modelValue="updateDate"
|
|
62
|
+
:touchUI="isMobile()"
|
|
63
|
+
showButtonBar
|
|
57
64
|
:readonly="isReadonly"
|
|
58
65
|
:placeholder="placeholder"
|
|
66
|
+
:date-format="getDateFormat()"
|
|
59
67
|
v-bind="componentProps as CalendarProps"
|
|
60
68
|
/>
|
|
61
69
|
|
|
@@ -69,7 +77,7 @@
|
|
|
69
77
|
@update:modelValue="updateTime"
|
|
70
78
|
:inputId="slotprops.uuid"
|
|
71
79
|
:path="setting.instancepath"
|
|
72
|
-
v-model="
|
|
80
|
+
v-model="timevalue"
|
|
73
81
|
:readonly="isReadonly"
|
|
74
82
|
:placeholder="placeholder"
|
|
75
83
|
v-bind="componentProps as CalendarProps"
|
|
@@ -90,6 +98,7 @@
|
|
|
90
98
|
optionValue="value"
|
|
91
99
|
:placeholder="placeholder"
|
|
92
100
|
v-bind="componentProps as ListboxProps"
|
|
101
|
+
@change="onChange"
|
|
93
102
|
/>
|
|
94
103
|
|
|
95
104
|
<Dropdown
|
|
@@ -106,6 +115,7 @@
|
|
|
106
115
|
optionValue="value"
|
|
107
116
|
:placeholder="placeholder"
|
|
108
117
|
v-bind="componentProps"
|
|
118
|
+
@change="onChange"
|
|
109
119
|
/>
|
|
110
120
|
|
|
111
121
|
<!-- radio component -->
|
|
@@ -118,6 +128,7 @@
|
|
|
118
128
|
name="smaple"
|
|
119
129
|
:value="item.value"
|
|
120
130
|
:readonly="isReadonly"
|
|
131
|
+
@change="onChange"
|
|
121
132
|
/>
|
|
122
133
|
{{ " " }}
|
|
123
134
|
<label :for="setting.key + '-' + index"> {{ item.label }} </label>
|
|
@@ -136,6 +147,8 @@
|
|
|
136
147
|
:path="setting.instancepath"
|
|
137
148
|
:readonly="isReadonly"
|
|
138
149
|
:placeholder="placeholder"
|
|
150
|
+
:autocompleteFilter="autocompleteFilter"
|
|
151
|
+
@change="onChange"
|
|
139
152
|
/>
|
|
140
153
|
<!-- v-bind:attributes="componentProps" -->
|
|
141
154
|
<!-- document no input-->
|
|
@@ -149,6 +162,7 @@
|
|
|
149
162
|
:pt="pt"
|
|
150
163
|
:path="setting.instancepath"
|
|
151
164
|
v-bind="componentProps as any"
|
|
165
|
+
@change="onChange"
|
|
152
166
|
/>
|
|
153
167
|
<!-- use componentProps as any at the moment, no ideal yet, and for compatibility -->
|
|
154
168
|
|
|
@@ -163,6 +177,7 @@
|
|
|
163
177
|
class="flex flex-col"
|
|
164
178
|
:inputId="slotprops.uuid"
|
|
165
179
|
:path="setting.instancepath"
|
|
180
|
+
@change="onChange"
|
|
166
181
|
:placeholder="placeholder"
|
|
167
182
|
v-bind="componentProps as PasswordProps"
|
|
168
183
|
/>
|
|
@@ -176,6 +191,7 @@
|
|
|
176
191
|
:readonly="isReadonly"
|
|
177
192
|
:inputId="slotprops.uuid"
|
|
178
193
|
:path="setting.instancepath"
|
|
194
|
+
@change="onChange"
|
|
179
195
|
v-bind="componentProps as RatingProps"
|
|
180
196
|
/>
|
|
181
197
|
|
|
@@ -189,10 +205,11 @@
|
|
|
189
205
|
:inputId="slotprops.uuid"
|
|
190
206
|
:path="setting.instancepath"
|
|
191
207
|
:placeholder="placeholder"
|
|
208
|
+
@update:modelValue="onChange"
|
|
192
209
|
v-bind="componentProps as ChipsProps"
|
|
193
210
|
/>
|
|
194
211
|
<!-- simple component -->
|
|
195
|
-
|
|
212
|
+
|
|
196
213
|
<InputNumber
|
|
197
214
|
v-else-if="inputType == SimpleAppInputType.number"
|
|
198
215
|
:type="type"
|
|
@@ -202,10 +219,27 @@
|
|
|
202
219
|
:pt="pt"
|
|
203
220
|
:class="!pt ? 'w-full flex flex-col' : ''"
|
|
204
221
|
:inputId="slotprops.uuid"
|
|
222
|
+
@update:modelValue="onChange"
|
|
205
223
|
:path="setting.instancepath"
|
|
206
224
|
v-bind="componentProps as InputNumber"
|
|
207
225
|
:placeholder="placeholder"
|
|
208
226
|
/>
|
|
227
|
+
<InputNumber
|
|
228
|
+
v-else-if="inputType == SimpleAppInputType.money"
|
|
229
|
+
:type="type"
|
|
230
|
+
v-model="modelValue as number"
|
|
231
|
+
@focus="setFocus"
|
|
232
|
+
:max-fraction-digits="2"
|
|
233
|
+
:min-fraction-digits="2"
|
|
234
|
+
:readonly="isReadonly"
|
|
235
|
+
:pt="pt"
|
|
236
|
+
:class="!pt ? 'w-full flex flex-col' : ''"
|
|
237
|
+
:inputId="slotprops.uuid"
|
|
238
|
+
:path="setting.instancepath"
|
|
239
|
+
@change="onChange"
|
|
240
|
+
v-bind="componentProps as InputNumber"
|
|
241
|
+
:placeholder="placeholder"
|
|
242
|
+
/>
|
|
209
243
|
<Textarea
|
|
210
244
|
v-else-if="inputType == SimpleAppInputType.textarea"
|
|
211
245
|
v-model="modelValue as string"
|
|
@@ -216,6 +250,7 @@
|
|
|
216
250
|
class="w-full flex flex-col"
|
|
217
251
|
:inputId="slotprops.uuid"
|
|
218
252
|
:path="setting.instancepath"
|
|
253
|
+
@change="onChange"
|
|
219
254
|
:placeholder="placeholder"
|
|
220
255
|
v-bind="componentProps as TextareaProps"
|
|
221
256
|
/>
|
|
@@ -229,11 +264,12 @@
|
|
|
229
264
|
:type="type"
|
|
230
265
|
class="w-full flex flex-col"
|
|
231
266
|
:inputId="slotprops.uuid"
|
|
267
|
+
@change="onChange"
|
|
232
268
|
:path="setting.instancepath"
|
|
233
269
|
:placeholder="placeholder"
|
|
234
270
|
v-bind="componentProps as InputTextProps"
|
|
235
271
|
/>
|
|
236
|
-
<!-- component require special treatment -->
|
|
272
|
+
<!-- component require special treatment -->
|
|
237
273
|
</SimpleAppFieldContainer>
|
|
238
274
|
</template>
|
|
239
275
|
|
|
@@ -264,12 +300,13 @@ import Rating, { RatingProps } from "primevue/rating";
|
|
|
264
300
|
import Slider, { SliderProps } from "primevue/slider";
|
|
265
301
|
import Textarea, { TextareaProps } from "primevue/textarea";
|
|
266
302
|
import { SimpleAppInputType } from "~/types";
|
|
267
|
-
|
|
303
|
+
const resetcount = ref(0)
|
|
268
304
|
const instancepath = ref("");
|
|
269
305
|
const modelValue = defineModel({ required: true });
|
|
270
|
-
const datevalue = ref("");
|
|
271
|
-
const timevalue = ref<Date>();
|
|
272
306
|
|
|
307
|
+
const datevalue = ref<Date>();
|
|
308
|
+
const timevalue = ref<Date>();
|
|
309
|
+
let watchOnChange = 0;
|
|
273
310
|
const props = withDefaults(
|
|
274
311
|
defineProps<{
|
|
275
312
|
inputType: SimpleAppInputType;
|
|
@@ -284,6 +321,7 @@ const props = withDefaults(
|
|
|
284
321
|
autofocus?: boolean;
|
|
285
322
|
pt?: any;
|
|
286
323
|
placeholder?: string;
|
|
324
|
+
autocompleteFilter?: any;
|
|
287
325
|
componentProps?:
|
|
288
326
|
| InputNumberProps
|
|
289
327
|
| InputSwitchProps
|
|
@@ -296,45 +334,55 @@ const props = withDefaults(
|
|
|
296
334
|
{ type: "text" },
|
|
297
335
|
);
|
|
298
336
|
|
|
299
|
-
const pt =ref(props.pt)
|
|
337
|
+
const pt = ref(props.pt);
|
|
300
338
|
|
|
301
339
|
if (props.inputType == SimpleAppInputType.date && modelValue.value) {
|
|
302
|
-
datevalue.value =
|
|
340
|
+
datevalue.value = stringToDate(<string>modelValue.value); //.format("YYYY-MM-DD");
|
|
303
341
|
} else {
|
|
304
|
-
datevalue.value =
|
|
342
|
+
datevalue.value = undefined;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (props.inputType == SimpleAppInputType.time) {
|
|
346
|
+
if (modelValue.value) {
|
|
347
|
+
timevalue.value = stringToDate(
|
|
348
|
+
(today() + "T" + modelValue.value) as string,
|
|
349
|
+
); //.format("YYYY-MM-DD");
|
|
350
|
+
} else {
|
|
351
|
+
timevalue.value = undefined;
|
|
352
|
+
}
|
|
305
353
|
}
|
|
306
354
|
|
|
307
355
|
if (props?.instancepath) instancepath.value = props.instancepath;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
356
|
+
else if (props.setting?.instancepath)
|
|
357
|
+
instancepath.value = props.setting.instancepath;
|
|
358
|
+
else instancepath.value = "/unknown";
|
|
311
359
|
|
|
312
360
|
watch(props.setting.errors, (newvalue, oldvalue) => {
|
|
313
|
-
let errmsg =
|
|
361
|
+
let errmsg = "";
|
|
314
362
|
if (newvalue[instancepath.value]) {
|
|
315
|
-
const errlist: any[] = newvalue[instancepath.value];
|
|
363
|
+
const errlist: any[] = newvalue[instancepath.value];
|
|
316
364
|
for (let i = 0; i < errlist.length; i++) {
|
|
317
365
|
errmsg += errlist[i].message + ",";
|
|
318
|
-
}
|
|
366
|
+
}
|
|
319
367
|
} else {
|
|
320
|
-
errmsg = "";
|
|
368
|
+
errmsg = "";
|
|
321
369
|
}
|
|
322
|
-
if(errmsg!=
|
|
323
|
-
const errorstyle = { style:
|
|
324
|
-
if(!pt.value)pt.value = {}
|
|
370
|
+
if (errmsg != "") {
|
|
371
|
+
const errorstyle = { style: "border-color: lightcoral; color:lightcoral " };
|
|
372
|
+
if (!pt.value) pt.value = {};
|
|
325
373
|
|
|
326
|
-
if(props.inputType == SimpleAppInputType.text)
|
|
327
|
-
|
|
328
|
-
else
|
|
329
|
-
|
|
374
|
+
if (props.inputType == SimpleAppInputType.text)
|
|
375
|
+
pt.value = { root: errorstyle };
|
|
376
|
+
else if (props.inputType == SimpleAppInputType.autocomplete)
|
|
377
|
+
pt.value = { input: errorstyle };
|
|
378
|
+
else if (props.inputType == SimpleAppInputType.number)
|
|
379
|
+
pt.value = { input: { root: errorstyle } };
|
|
380
|
+
else pt.value = { root: errorstyle, input: { root: errorstyle } };
|
|
330
381
|
//some component still not working
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
pt.value=props.pt
|
|
382
|
+
} else {
|
|
383
|
+
pt.value = props.pt;
|
|
334
384
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
})
|
|
385
|
+
});
|
|
338
386
|
const isReadonly = computed(() => {
|
|
339
387
|
if (props.readonly) {
|
|
340
388
|
return props.readonly;
|
|
@@ -344,15 +392,18 @@ const isReadonly = computed(() => {
|
|
|
344
392
|
return false;
|
|
345
393
|
}
|
|
346
394
|
});
|
|
347
|
-
const updateTime = () => {
|
|
348
|
-
|
|
395
|
+
const updateTime = (value: Date) => {
|
|
396
|
+
value.setSeconds(0);
|
|
397
|
+
modelValue.value = dateToTimeString(value);
|
|
398
|
+
onChange();
|
|
349
399
|
};
|
|
350
400
|
const updateDate = (value: any) => {
|
|
351
401
|
if (value) {
|
|
352
|
-
modelValue.value =
|
|
402
|
+
modelValue.value = dateToString(value);
|
|
353
403
|
} else {
|
|
354
404
|
modelValue.value = "";
|
|
355
405
|
}
|
|
406
|
+
onChange();
|
|
356
407
|
};
|
|
357
408
|
|
|
358
409
|
const setFocus = (ev: any) => {
|
|
@@ -380,6 +431,10 @@ const emits = defineEmits([
|
|
|
380
431
|
"update:docNoFormat",
|
|
381
432
|
]);
|
|
382
433
|
|
|
434
|
+
const getDateFormat = () => {
|
|
435
|
+
return getPrimevueCalendarDateFormat();
|
|
436
|
+
};
|
|
437
|
+
|
|
383
438
|
watch(modelValue, (newvalue: any) => {
|
|
384
439
|
if (
|
|
385
440
|
[SimpleAppInputType.date, SimpleAppInputType.calendar].includes(
|
|
@@ -387,14 +442,19 @@ watch(modelValue, (newvalue: any) => {
|
|
|
387
442
|
)
|
|
388
443
|
) {
|
|
389
444
|
if (modelValue.value) {
|
|
390
|
-
datevalue.value =
|
|
445
|
+
datevalue.value = stringToDate(modelValue.value as string);
|
|
446
|
+
} else {
|
|
447
|
+
timevalue.value = undefined;
|
|
448
|
+
}
|
|
449
|
+
} else if (props.inputType == SimpleAppInputType.time) {
|
|
450
|
+
if (modelValue.value) {
|
|
451
|
+
timevalue.value = stringToDate(
|
|
452
|
+
(today() + "T" + modelValue.value) as string,
|
|
453
|
+
);
|
|
391
454
|
} else {
|
|
392
|
-
|
|
455
|
+
timevalue.value = undefined;
|
|
393
456
|
}
|
|
394
457
|
}
|
|
395
|
-
|
|
396
|
-
emits("change", modelValue.value);
|
|
397
|
-
emits("update:modelValue", modelValue.value);
|
|
398
458
|
});
|
|
399
459
|
onMounted(() => {
|
|
400
460
|
if (
|
|
@@ -403,13 +463,27 @@ onMounted(() => {
|
|
|
403
463
|
)
|
|
404
464
|
) {
|
|
405
465
|
if (modelValue.value) {
|
|
406
|
-
datevalue.value =
|
|
466
|
+
datevalue.value = stringToDate(modelValue.value as string);
|
|
467
|
+
} else {
|
|
468
|
+
datevalue.value = undefined;
|
|
469
|
+
}
|
|
470
|
+
} else if (props.inputType == SimpleAppInputType.time) {
|
|
471
|
+
if (modelValue.value) {
|
|
472
|
+
timevalue.value = stringToDate(
|
|
473
|
+
(today() + "T" + modelValue.value) as string,
|
|
474
|
+
);
|
|
407
475
|
} else {
|
|
408
|
-
|
|
476
|
+
timevalue.value = undefined;
|
|
409
477
|
}
|
|
410
478
|
}
|
|
411
479
|
});
|
|
412
480
|
|
|
481
|
+
const onChange = () => {
|
|
482
|
+
pt.value=undefined
|
|
483
|
+
resetcount.value++
|
|
484
|
+
emits("change", modelValue.value);
|
|
485
|
+
};
|
|
486
|
+
|
|
413
487
|
/************ start autocomplete only ***************/
|
|
414
488
|
|
|
415
489
|
/************ end autocomplete only ***************/
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="text-base text-primary-600 dark:text-primary-500">
|
|
3
|
+
<slot name="default"></slot>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
<script setup lang="ts">
|
|
7
|
+
/**
|
|
8
|
+
* This file was automatically generated by simpleapp generator during initialization. It is changable.
|
|
9
|
+
* --remove-this-line-to-prevent-override--
|
|
10
|
+
* last change 2024-02-22
|
|
11
|
+
* author: Ks Tan
|
|
12
|
+
*/
|
|
13
|
+
</script>
|