@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
|
@@ -5,85 +5,139 @@
|
|
|
5
5
|
* last change 2023-10-28
|
|
6
6
|
* Author: Ks Tan
|
|
7
7
|
*/
|
|
8
|
-
import Avatar from
|
|
9
|
-
import Dropdown from
|
|
10
|
-
import OverlayPanel from
|
|
11
|
-
import {ref} from
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const { locale,setLocale,locales } = useI18n()
|
|
15
|
-
const colorMode = useColorMode()
|
|
16
|
-
const modelValue = defineModel<boolean>()
|
|
17
|
-
const mylocale = ref(locale)
|
|
18
|
-
const colors = [{value:'light', name:t('light')},{value:'dark', name:t('dark')}]
|
|
19
|
-
|
|
20
|
-
const toProfile = ()=>{
|
|
21
|
-
modelValue.value=false
|
|
22
|
-
|
|
23
|
-
if(getCurrentXorg()){
|
|
24
|
-
navigateTo(`/${getCurrentXorg()}/profile`)
|
|
25
|
-
}else{
|
|
26
|
-
navigateTo(`/profile`)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
const saveLocale=async (v:string)=>{
|
|
31
|
-
await setLocale(v)
|
|
32
|
-
}
|
|
33
|
-
|
|
8
|
+
import Avatar from "primevue/avatar";
|
|
9
|
+
import Dropdown from "primevue/dropdown";
|
|
10
|
+
import OverlayPanel from "primevue/overlaypanel";
|
|
11
|
+
import { ref } from "vue";
|
|
34
12
|
|
|
13
|
+
const { locale, setLocale, locales } = useI18n();
|
|
14
|
+
const colorMode = useColorMode();
|
|
15
|
+
const modelValue = defineModel<boolean>();
|
|
16
|
+
const mylocale = ref(locale);
|
|
17
|
+
const colors = [
|
|
18
|
+
{ value: "light", name: t("light") },
|
|
19
|
+
{ value: "dark", name: t("dark") },
|
|
20
|
+
];
|
|
21
|
+
const goTenantPicker = () => {
|
|
22
|
+
modelValue.value = false;
|
|
23
|
+
navigateTo("/picktenant");
|
|
24
|
+
};
|
|
25
|
+
const toProfile = () => {
|
|
26
|
+
modelValue.value = false;
|
|
35
27
|
|
|
28
|
+
if (getCurrentXorg()) {
|
|
29
|
+
navigateTo(`/${getCurrentXorg()}/profile`);
|
|
30
|
+
} else {
|
|
31
|
+
navigateTo(`/profile`);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const saveLocale = async (v: string) => {
|
|
35
|
+
await setLocale(v);
|
|
36
|
+
};
|
|
36
37
|
</script>
|
|
37
38
|
|
|
38
|
-
<template>
|
|
39
|
-
|
|
39
|
+
<template>
|
|
40
|
+
<!-- <div class="bg-cover bg-center rounded-md p-3 cursor-pointer profile-button" @click="toggle">
|
|
40
41
|
<i class="pi pi-user dark:text-white"></i> -->
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
42
|
+
<!-- <img :src="getAvatarLink(<string>getProfileEmail(),32)" alt="" class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow" /> -->
|
|
43
|
+
<!-- </div> -->
|
|
44
|
+
|
|
45
|
+
<Dialog
|
|
46
|
+
appendTo="body"
|
|
47
|
+
ref="userprofileoverlay"
|
|
48
|
+
v-model:visible="modelValue"
|
|
49
|
+
close-on-escape
|
|
50
|
+
:header="t('profile')"
|
|
51
|
+
>
|
|
52
|
+
<!-- <div> -->
|
|
53
|
+
<!-- <div class="py-2 transition duration-150 ease-in-out z-10 absolute top-0 right-0 bottom-0 left-0" id="modal"> -->
|
|
54
|
+
<div class="p-4">
|
|
55
|
+
<!-- <div class="relative p-4 md:p-8 bg-white dark:bg-gray-800 shadow-md rounded border border-gray-400"> -->
|
|
56
|
+
<div
|
|
57
|
+
class="w-full flex items-center justify-start text-gray-600 dark:text-gray-400 mb-5"
|
|
58
|
+
>
|
|
59
|
+
<div class="w-12 h-12 bg-cover bg-center rounded-md">
|
|
60
|
+
<img
|
|
61
|
+
:src="getAvatarLink(<string>getProfileEmail(), 32)"
|
|
62
|
+
alt=""
|
|
63
|
+
class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow"
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="flex flex-col">
|
|
67
|
+
<h1
|
|
68
|
+
class="text-left text-gray-800 dark:text-gray-100 font-lg font-bold tracking-normal leading-tight ml-2"
|
|
69
|
+
>
|
|
70
|
+
{{ getUserProfile()?.fullName }}
|
|
71
|
+
</h1>
|
|
72
|
+
<p
|
|
73
|
+
class="text-gray-400 dark:text-gray-100 font-normal text-base tracking-normal ml-2 mr-4"
|
|
74
|
+
>
|
|
75
|
+
{{ getUserProfile()?.group }}
|
|
76
|
+
</p>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="pt-2 pb-2">
|
|
80
|
+
<TextTitle>{{ getUserProfile()?.branchName }}</TextTitle>
|
|
81
|
+
<TextPrimary @click="goTenantPicker">{{
|
|
82
|
+
t("switchDatabase")
|
|
83
|
+
}} </TextPrimary>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="col-span-full">
|
|
86
|
+
<label
|
|
87
|
+
for="pick-lang"
|
|
88
|
+
class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300"
|
|
89
|
+
>{{ t("language") }}</label
|
|
90
|
+
>
|
|
91
|
+
<div class="mt-2">
|
|
92
|
+
<Dropdown
|
|
93
|
+
inputId="pick-lang"
|
|
94
|
+
@update:model-value="saveLocale"
|
|
95
|
+
v-model="mylocale"
|
|
96
|
+
option-value="code"
|
|
97
|
+
option-label="name"
|
|
98
|
+
:options="locales"
|
|
99
|
+
>
|
|
100
|
+
</Dropdown>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<div class="mt-3 col-span-full">
|
|
104
|
+
<label
|
|
105
|
+
for="pick-theme"
|
|
106
|
+
class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300"
|
|
107
|
+
>{{ t("theme") }}</label
|
|
108
|
+
>
|
|
109
|
+
<div class="mt-2">
|
|
110
|
+
<h1>Color mode: {{ $colorMode.value }}</h1>
|
|
111
|
+
|
|
112
|
+
<Dropdown
|
|
113
|
+
inputId="pick-theme"
|
|
114
|
+
v-model="colorMode.preference"
|
|
115
|
+
option-value="value"
|
|
116
|
+
option-label="name"
|
|
117
|
+
:options="colors"
|
|
118
|
+
>
|
|
119
|
+
</Dropdown>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
70
122
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
123
|
+
<div class="mt-3 flex items-center justify-start w-full">
|
|
124
|
+
<button
|
|
125
|
+
class="focus:outline-none transition duration-150 ease-in-out hover:bg-gray-600 bg-gray-700 rounded text-white px-8 py-2 text-sm"
|
|
126
|
+
@click="toProfile"
|
|
127
|
+
>
|
|
128
|
+
{{ t("profile") }}
|
|
129
|
+
</button>
|
|
130
|
+
<button
|
|
131
|
+
class="focus:outline-none ml-3 bg-warning-100 dark:bg-warning-700 dark:border-warning-700 dark:hover:bg-warning-600 transition duration-150 text-gray-600 dark:text-white ease-in-out hover:border-gray-400 hover:bg-gray-300 border rounded px-8 py-2 text-sm"
|
|
132
|
+
@click="logout()"
|
|
133
|
+
>
|
|
134
|
+
{{ t("logout") }}
|
|
135
|
+
</button>
|
|
136
|
+
</div>
|
|
137
|
+
<!-- </div> -->
|
|
138
|
+
</div>
|
|
139
|
+
<!-- </div> -->
|
|
76
140
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<button class="focus:outline-none ml-3 bg-warning-100 dark:bg-warning-700 dark:border-warning-700 dark:hover:bg-warning-600 transition duration-150 text-gray-600 dark:text-white ease-in-out hover:border-gray-400 hover:bg-gray-300 border rounded px-8 py-2 text-sm" @click="logout()">{{ t('logout') }}</button>
|
|
81
|
-
</div>
|
|
82
|
-
<!-- </div> -->
|
|
83
|
-
</div>
|
|
84
|
-
<!-- </div> -->
|
|
85
|
-
|
|
86
|
-
<!-- </div> -->
|
|
87
|
-
</Dialog>
|
|
88
|
-
|
|
89
|
-
</template>
|
|
141
|
+
<!-- </div> -->
|
|
142
|
+
</Dialog>
|
|
143
|
+
</template>
|
|
@@ -2,19 +2,25 @@
|
|
|
2
2
|
<div class="relative">
|
|
3
3
|
<div v-if="withFilter" class="flex flex-row">
|
|
4
4
|
<InputText
|
|
5
|
-
placeholder="
|
|
5
|
+
:placeholder="t('searchKeyword')"
|
|
6
6
|
v-model="searchvalue"
|
|
7
7
|
class="w-full dark:text-white"
|
|
8
8
|
type="search"
|
|
9
|
+
ref="listviewfilter"
|
|
9
10
|
/>
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
<template v-if="withAddNew">
|
|
12
|
+
<ButtonText v-if="isMobile()" @click="emits('add')"
|
|
13
|
+
><i class="pi pi-plus"></i
|
|
14
|
+
></ButtonText>
|
|
15
|
+
<ButtonPrimary v-else @click="emits('add')"
|
|
16
|
+
><i class="pi pi-plus"></i
|
|
17
|
+
></ButtonPrimary>
|
|
18
|
+
</template>
|
|
13
19
|
</div>
|
|
14
20
|
|
|
15
21
|
<div
|
|
16
22
|
v-if="showIndex"
|
|
17
|
-
class="flex flex-col fixed left-1 top-1/5 gap-2
|
|
23
|
+
class="flex flex-col fixed left-1 top-1/5 gap-2 z-10 rounded border bg-white dark:bg-black opacity-90"
|
|
18
24
|
>
|
|
19
25
|
<NuxtLink
|
|
20
26
|
class="text-primary-600 dark:text-primary-400 text-lg p-2"
|
|
@@ -28,7 +34,9 @@
|
|
|
28
34
|
<div>
|
|
29
35
|
<div v-for="(item, index) in filterlist">
|
|
30
36
|
<!-- :class="isMobile() ? '' : 'overflow overflow-y-scroll overflow-auto '" -->
|
|
31
|
-
<div
|
|
37
|
+
<div
|
|
38
|
+
:id="titleField && item[titleField] && item[titleField][0]"
|
|
39
|
+
></div>
|
|
32
40
|
<div
|
|
33
41
|
class="w-full bg-gray-400 dark:bg-gray-500 p-1 pl-2 top-0 sticky opacity-90"
|
|
34
42
|
v-if="
|
|
@@ -37,8 +45,16 @@
|
|
|
37
45
|
>
|
|
38
46
|
<span>{{ item[titleField][0] }}</span>
|
|
39
47
|
</div>
|
|
40
|
-
<div
|
|
41
|
-
|
|
48
|
+
<div
|
|
49
|
+
@click="onClick(index, item)"
|
|
50
|
+
:class="`border-l-none border-r-none listview-item dark:border-t-gray-700 ${
|
|
51
|
+
index > 0 ? 'border-t-2' : ''
|
|
52
|
+
}`"
|
|
53
|
+
>
|
|
54
|
+
<NuxtLink :to="getUrl(item)"
|
|
55
|
+
|
|
56
|
+
class="p-2"
|
|
57
|
+
>
|
|
42
58
|
<slot name="default" :item="item" :index="index">
|
|
43
59
|
<div class="flex flex-row">
|
|
44
60
|
<div class="flex-1 mr-2 dark:text-white">
|
|
@@ -55,9 +71,7 @@
|
|
|
55
71
|
</div>
|
|
56
72
|
</div>
|
|
57
73
|
<div v-else>
|
|
58
|
-
<div
|
|
59
|
-
class="w-full h-20 p-2 border-l-none border-r-none "
|
|
60
|
-
>
|
|
74
|
+
<div class="w-full h-20 p-2 border-l-none border-r-none">
|
|
61
75
|
<slot name="nodata">
|
|
62
76
|
<div class="border-round border-1 surface-border p-4 surface-card">
|
|
63
77
|
{{ t("noDataFound") }}
|
|
@@ -76,6 +90,8 @@
|
|
|
76
90
|
*/
|
|
77
91
|
import { ref } from "vue";
|
|
78
92
|
import { ListItem } from "~/types/listview";
|
|
93
|
+
import _ from 'lodash'
|
|
94
|
+
const listviewfilter = ref();
|
|
79
95
|
const props = withDefaults(
|
|
80
96
|
defineProps<{
|
|
81
97
|
list: T[];
|
|
@@ -94,13 +110,21 @@ const props = withDefaults(
|
|
|
94
110
|
const letters = ref<string[]>([]);
|
|
95
111
|
let lastchar = "";
|
|
96
112
|
|
|
97
|
-
const emits = defineEmits(["add"]);
|
|
113
|
+
const emits = defineEmits(["add", "click"]);
|
|
98
114
|
const searchvalue = ref("");
|
|
99
115
|
const selecteditem = ref("");
|
|
100
116
|
const clickRow = (item: ListItem) => {
|
|
101
117
|
// emit('clickitem',item)
|
|
102
118
|
// selecteditem.value = item.code
|
|
103
119
|
};
|
|
120
|
+
const getUrl = (item:any)=>{
|
|
121
|
+
if(props.url && props.idField) {
|
|
122
|
+
if(_.last(props.url)=='/') return `${props.url}${item[props.idField]}`
|
|
123
|
+
else return `${props.url}/${item[props.idField]}`
|
|
124
|
+
}
|
|
125
|
+
else return undefined
|
|
126
|
+
// :to="url ? `${url}/${item[idField]}` : undefined"
|
|
127
|
+
}
|
|
104
128
|
const filterlist = computed(() => {
|
|
105
129
|
let newlist: T[] = [];
|
|
106
130
|
if (!Array.isArray(props.list)) {
|
|
@@ -122,7 +146,6 @@ const filterlist = computed(() => {
|
|
|
122
146
|
return newlist;
|
|
123
147
|
});
|
|
124
148
|
|
|
125
|
-
|
|
126
149
|
const allLetters = computed(() => {
|
|
127
150
|
if (props.titleField && props.list) {
|
|
128
151
|
return props.list
|
|
@@ -147,4 +170,12 @@ const showCategoryBar = (letter: string) => {
|
|
|
147
170
|
return false;
|
|
148
171
|
}
|
|
149
172
|
};
|
|
173
|
+
|
|
174
|
+
const onClick = (index: number, data: T) => {
|
|
175
|
+
emits("click", index, data);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
onMounted(() => {
|
|
179
|
+
// if(props.withFilter) listviewfilter.value.$el.focus()
|
|
180
|
+
});
|
|
150
181
|
</script>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
class="w-full dark:bg-gray-800 z-20 justify justify-between absolute h h-14 flex flex-row place-items-center opacity-90 dark:text-white"
|
|
3
4
|
>
|
|
4
|
-
<div class="
|
|
5
|
-
<div class="
|
|
6
|
-
<div class="
|
|
5
|
+
<div class="text-left"><slot name="start"></slot></div>
|
|
6
|
+
<div class="flex-1 text-center line-clamp-2"><slot name="center"></slot></div>
|
|
7
|
+
<div class=" text-right"><slot name="end"></slot></div>
|
|
7
8
|
</div>
|
|
8
9
|
</template>
|
|
9
10
|
<script setup lang="ts">
|
|
@@ -13,4 +14,4 @@
|
|
|
13
14
|
* last change 2023-10-28
|
|
14
15
|
* Author: Ks Tan
|
|
15
16
|
*/
|
|
16
|
-
</script>
|
|
17
|
+
</script>
|
|
@@ -1,44 +1,42 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
</div>
|
|
2
|
+
<Sidebar
|
|
3
|
+
position="right"
|
|
4
|
+
v-if="showDialog"
|
|
5
|
+
v-model:visible="showDialog"
|
|
6
|
+
modal
|
|
7
|
+
:show-close-icon="false"
|
|
8
|
+
#container
|
|
9
|
+
>
|
|
10
|
+
<div class="overflow-y-scroll">
|
|
11
|
+
<MobileToolbar class="bg-gray-800 text-white">
|
|
12
|
+
<template #start>
|
|
13
|
+
<slot name="headerLeft"></slot>
|
|
14
|
+
</template>
|
|
15
|
+
<template #center>
|
|
16
|
+
<slot name="headerCenter"></slot>
|
|
17
|
+
</template>
|
|
18
|
+
<template #end>
|
|
19
|
+
<slot name="headerRight"></slot>
|
|
20
|
+
</template>
|
|
21
|
+
</MobileToolbar>
|
|
22
|
+
<div class="mt-14">
|
|
23
|
+
<slot name="default"></slot>
|
|
25
24
|
</div>
|
|
26
|
-
</
|
|
27
|
-
</
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
</div>
|
|
26
|
+
</Sidebar>
|
|
27
|
+
</template>
|
|
28
|
+
<script lang="ts" setup>
|
|
29
|
+
/**
|
|
30
30
|
* This file was automatically generated by simpleapp generator. Every
|
|
31
31
|
* MODIFICATION OVERRIDE BY GENERATEOR
|
|
32
32
|
* last change 2023-10-28
|
|
33
33
|
* Author: Ks Tan
|
|
34
34
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</script>
|
|
44
|
-
|
|
35
|
+
const showDialog = defineModel<boolean>({ required: true });
|
|
36
|
+
const props = defineProps<{ closeEventName: string }>();
|
|
37
|
+
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
38
|
+
if (props.closeEventName == closeEventName) {
|
|
39
|
+
showDialog.value = false;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
</script>
|
|
@@ -22,9 +22,8 @@
|
|
|
22
22
|
const showDialog = defineModel<boolean>({ required: true });
|
|
23
23
|
const props = defineProps<{ closeEventName: string }>();
|
|
24
24
|
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
25
|
-
if (props.closeEventName == closeEventName){
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if (props.closeEventName == closeEventName) {
|
|
26
|
+
showDialog.value = false;
|
|
27
|
+
}
|
|
28
28
|
});
|
|
29
|
-
|
|
30
29
|
</script>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<span>{{ toLocalDate(
|
|
2
|
+
<span v-if="modelValue">{{ toLocalDate(modelValue) }}</span>
|
|
3
|
+
<span v-else>-</span>
|
|
3
4
|
</template>
|
|
4
5
|
<script lang="ts" setup>
|
|
5
6
|
/**
|
|
@@ -8,5 +9,5 @@
|
|
|
8
9
|
* last change 2024-02-04
|
|
9
10
|
* author: Ks Tan
|
|
10
11
|
*/
|
|
11
|
-
const
|
|
12
|
+
const modelValue = defineModel<Date|string>()
|
|
12
13
|
</script>
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<span
|
|
3
|
+
v-if="setting?.collection"
|
|
4
|
+
@click="viewRecord"
|
|
5
|
+
class="text-primary-700 hover:text-primary-500 dark:text-primary-400 cursor-pointer"
|
|
6
|
+
>
|
|
7
|
+
<slot>
|
|
8
|
+
{{ displayText }}
|
|
9
|
+
</slot>
|
|
10
|
+
|
|
11
|
+
</span>
|
|
12
|
+
<span v-else>{{ displayText }}</span>
|
|
6
13
|
</template>
|
|
7
14
|
<script setup lang="ts">
|
|
8
15
|
/**
|
|
@@ -11,35 +18,32 @@
|
|
|
11
18
|
* last change 2024-02-04
|
|
12
19
|
* author: Ks Tan
|
|
13
20
|
*/
|
|
14
|
-
import { ForeignKey } from
|
|
15
|
-
|
|
21
|
+
import { ForeignKey } from "~/types";
|
|
16
22
|
|
|
17
|
-
type SettingProp = {collection:string
|
|
18
|
-
const modelValue = defineModel<ForeignKey>()
|
|
19
|
-
const props = defineProps<{setting:SettingProp}>()
|
|
20
|
-
const displayText = computed(()=>{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
27
|
-
const {$event} = useNuxtApp()
|
|
28
|
-
const viewer=ref()
|
|
23
|
+
type SettingProp = { collection: string; displayField?: string };
|
|
24
|
+
const modelValue = defineModel<ForeignKey>();
|
|
25
|
+
const props = defineProps<{ setting: SettingProp }>();
|
|
26
|
+
const displayText = computed(() => {
|
|
27
|
+
const s = props.setting;
|
|
28
|
+
if (!modelValue.value) return undefined;
|
|
29
|
+
else if (!s.collection) return modelValue.value;
|
|
30
|
+
else if (s.displayField) return modelValue.value[s.displayField];
|
|
31
|
+
else return modelValue.value.label;
|
|
32
|
+
});
|
|
33
|
+
const { $event } = useNuxtApp();
|
|
34
|
+
const viewer = ref();
|
|
29
35
|
const viewRecord = () => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
|
|
33
|
-
//getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
|
|
34
|
-
$event('ViewRecord',{
|
|
35
|
-
_id: modelValue.value?._id as string,
|
|
36
|
-
label: modelValue.value?.label as string,
|
|
37
|
-
eventId: randomUUID(),
|
|
38
|
-
documentName: props.setting.collection,
|
|
39
|
-
viewer: viewer.value,
|
|
40
|
-
readonly:true
|
|
41
|
-
|
|
42
|
-
})
|
|
36
|
+
viewer.value = getDocument(props.setting.collection)?.viewer;
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
// getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
|
|
39
|
+
//getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
|
|
40
|
+
$event("ViewRecord", {
|
|
41
|
+
_id: modelValue.value?._id as string,
|
|
42
|
+
label: modelValue.value?.label as string,
|
|
43
|
+
eventId: randomUUID(),
|
|
44
|
+
documentName: props.setting.collection,
|
|
45
|
+
viewer: viewer.value,
|
|
46
|
+
readonly: true,
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
</script>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Dropdown
|
|
3
|
+
@update:modelValue="change"
|
|
4
|
+
v-model="modelValue"
|
|
5
|
+
:options="options"
|
|
6
|
+
optionLabel="label"
|
|
7
|
+
optionValue="value"
|
|
8
|
+
:placeholder="placeholder"
|
|
9
|
+
/>
|
|
10
|
+
</template>
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
/**
|
|
13
|
+
* This file was automatically generated by simpleapp generator. Every
|
|
14
|
+
* MODIFICATION OVERRIDE BY GENERATEOR
|
|
15
|
+
* last change 2024-02-26
|
|
16
|
+
* Author: Ks Tan
|
|
17
|
+
*/
|
|
18
|
+
import Dropdown from "primevue/dropdown";
|
|
19
|
+
import { ForeignKey, FormCrudEvent } from "~/types";
|
|
20
|
+
const emits = defineEmits(["change"]);
|
|
21
|
+
const modelValue = defineModel<string>();
|
|
22
|
+
const list = ref<ForeignKey[]>([]);
|
|
23
|
+
|
|
24
|
+
const props = defineProps<{
|
|
25
|
+
documentName: string;
|
|
26
|
+
placeholder?: string;
|
|
27
|
+
showNull?: boolean;
|
|
28
|
+
allowAddNew?: boolean;
|
|
29
|
+
filter?: any
|
|
30
|
+
}>();
|
|
31
|
+
const options = ref<
|
|
32
|
+
{
|
|
33
|
+
value: string;
|
|
34
|
+
label: string;
|
|
35
|
+
}[]
|
|
36
|
+
>([]);
|
|
37
|
+
const getListOptions = async () => {
|
|
38
|
+
const filter = props.filter ?? {}
|
|
39
|
+
const res = await getDocumentApi(props.documentName).autoComplete("", filter);
|
|
40
|
+
list.value = res.data as ForeignKey[];
|
|
41
|
+
if (props.allowAddNew)
|
|
42
|
+
list.value.unshift({ _id: "new", code: "", label: t("addNew") });
|
|
43
|
+
if (props.showNull)
|
|
44
|
+
list.value.unshift({ _id: "", code: "", label: t("null") });
|
|
45
|
+
options.value = list.value.map((item) => ({
|
|
46
|
+
value: item._id,
|
|
47
|
+
label: item.label,
|
|
48
|
+
}));
|
|
49
|
+
};
|
|
50
|
+
onMounted(async () => {
|
|
51
|
+
await getListOptions();
|
|
52
|
+
if (modelValue.value) change(modelValue.value);
|
|
53
|
+
});
|
|
54
|
+
const getItem = (id: string) => list.value?.find((item) => item._id == id);
|
|
55
|
+
|
|
56
|
+
const change = (id: string) => {
|
|
57
|
+
const selectedItem = getItem(id);
|
|
58
|
+
if (selectedItem?._id == "new") {
|
|
59
|
+
const doc = getDocument(props.documentName)?.docClass;
|
|
60
|
+
if (doc) {
|
|
61
|
+
const tmpdata = doc?.getReactiveData();
|
|
62
|
+
type DataType = typeof tmpdata.value;
|
|
63
|
+
onScreenAddDocument<DataType>(
|
|
64
|
+
props.documentName,
|
|
65
|
+
undefined,
|
|
66
|
+
async (eventType: FormCrudEvent, data: DataType) => {
|
|
67
|
+
if (eventType == FormCrudEvent.create) {
|
|
68
|
+
await getListOptions();
|
|
69
|
+
modelValue.value = data._id;
|
|
70
|
+
emits("change", data._id, getItem(data._id));
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
emits("change", id, selectedItem);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
</script>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
all static select filter
|