@simitgroup/simpleapp-generator 1.6.2-alpha → 1.6.3-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/README.md +6 -5
- package/dist/buildinschemas/branch.d.ts.map +1 -1
- package/dist/buildinschemas/branch.js +0 -2
- package/dist/buildinschemas/branch.js.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/buildinschemas/branch.ts +0 -2
- package/src/index.ts +8 -3
- package/templates/basic/nuxt/pages.form.vue.eta +2 -2
- package/templates/basic/nuxt/pages.landing.vue.eta +1 -1
- package/templates/nest/src/simpleapp/generate/commons/docnogenerator.service.ts.eta +36 -30
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +16 -3
- package/templates/nuxt/{app.vue._eta → app.vue.eta} +3 -1
- package/templates/nuxt/components/button/ButtonAction.vue._eta +49 -8
- package/templates/nuxt/components/calendar/CalendarInput.vue.eta +16 -14
- package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +30 -13
- package/templates/nuxt/components/list/ListDocument.vue.eta +10 -5
- package/templates/nuxt/components/list/ListDocumentTable.vue.eta +2 -2
- package/templates/nuxt/components/list/ListMessages.vue.eta +1 -1
- package/templates/nuxt/components/list/ListView.vue.eta +61 -52
- package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +10 -4
- package/templates/nuxt/components/overlay/OverlaySideBarCrud.vue.eta +17 -6
- package/templates/nuxt/components/overlay/OverlayViewer.vue.eta +16 -6
- package/templates/nuxt/components/page/PageDocList.vue.eta +81 -27
- package/templates/nuxt/components/select/SelectTemplate.vue.eta +43 -31
- package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +45 -17
- package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +15 -11
- package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +71 -20
- package/templates/nuxt/composables/confirm.generate.ts.eta +19 -0
- package/templates/nuxt/composables/date.generate.ts.eta +1 -0
- package/templates/nuxt/composables/stringHelper.generate.ts.eta +2 -1
- package/templates/nuxt/pages/[xorg]/docnoformat.vue.eta +1 -1
- package/templates/nuxt/pages/[xorg]/mobile/docnoformat/index.vue.eta +1 -1
- package/templates/nuxt/pages/[xorg]/mobile/user/index.vue.eta +1 -1
- package/templates/nuxt/pages/[xorg]/organization.vue.eta +1 -1
- package/templates/nuxt/pages/[xorg]/profile.vue.eta +1 -1
- package/templates/nuxt/pages/[xorg]/user.vue.eta +1 -1
- package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +4 -0
- package/templates/project/lang/default._json +4 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -2,27 +2,29 @@
|
|
|
2
2
|
<div class="relative">
|
|
3
3
|
<div v-if="withFilter" class="flex flex-row p-2">
|
|
4
4
|
<InputGroup>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
<InputGroupAddon v-if="filter">
|
|
6
|
+
<ButtonText
|
|
7
|
+
@click="showMoreFilter"
|
|
8
|
+
v-if="Object.keys(filter) == 0"
|
|
9
|
+
>
|
|
10
|
+
<i class="pi pi-filter"></i>
|
|
11
|
+
</ButtonText>
|
|
12
|
+
<ButtonWarning @click="showMoreFilter" v-else>
|
|
13
|
+
<i class="pi pi-filter"></i>
|
|
14
|
+
</ButtonWarning>
|
|
15
|
+
</InputGroupAddon>
|
|
16
|
+
<InputText
|
|
17
|
+
:placeholder="t('searchKeyword')"
|
|
18
|
+
v-model="searchvalue"
|
|
19
|
+
class="w-full dark:text-white text-sm"
|
|
20
|
+
type="search"
|
|
21
|
+
ref="listviewfilter"
|
|
22
|
+
/>
|
|
23
|
+
<InputGroupAddon v-if="withAddNew">
|
|
24
|
+
<ButtonPrimary @click="emits('add')">
|
|
25
|
+
<i class="pi pi-plus"></i>
|
|
26
|
+
</ButtonPrimary>
|
|
27
|
+
</InputGroupAddon>
|
|
26
28
|
</InputGroup>
|
|
27
29
|
</div>
|
|
28
30
|
|
|
@@ -54,7 +56,7 @@
|
|
|
54
56
|
<span>{{ item[titleField][0] }}</span>
|
|
55
57
|
</div>
|
|
56
58
|
<div
|
|
57
|
-
@click="onClick(index, item)"
|
|
59
|
+
@click="onClick(index, item, $event)"
|
|
58
60
|
:class="`border-l-none border-r-none listview-item dark:border-t-gray-700 ${
|
|
59
61
|
index > 0 ? 'border-t-2' : ''
|
|
60
62
|
}`"
|
|
@@ -88,18 +90,17 @@
|
|
|
88
90
|
</div>
|
|
89
91
|
</div>
|
|
90
92
|
|
|
91
|
-
|
|
92
93
|
<Dialog v-model:visible="visibleMoreFilter" :header="t('filter')">
|
|
93
|
-
<slot name="filter">
|
|
94
|
-
define filter in #filter
|
|
95
|
-
</slot>
|
|
94
|
+
<slot name="filter"> define filter in #filter </slot>
|
|
96
95
|
<template #footer>
|
|
97
96
|
<div class="flex flex-row">
|
|
98
97
|
<ButtonDefault @click="clearFilter" class="flex flex-row p-2">
|
|
99
|
-
<i class="pi pi-times mr-1"/>
|
|
98
|
+
<i class="pi pi-times mr-1" />
|
|
99
|
+
<span class="mr-1">{{ t("clear") }}</span>
|
|
100
100
|
</ButtonDefault>
|
|
101
|
-
<ButtonPrimary
|
|
102
|
-
<i class="pi pi-filter mr-1"/>
|
|
101
|
+
<ButtonPrimary @click="runFilter" class="flex flex-row p-2">
|
|
102
|
+
<i class="pi pi-filter mr-1" />
|
|
103
|
+
<span class="mr-1">{{ t("ok") }}</span>
|
|
103
104
|
</ButtonPrimary>
|
|
104
105
|
</div>
|
|
105
106
|
</template>
|
|
@@ -116,7 +117,7 @@
|
|
|
116
117
|
import { ref } from "vue";
|
|
117
118
|
import { ListItem } from "~/types/listview";
|
|
118
119
|
import _ from "lodash";
|
|
119
|
-
const visibleMoreFilter = ref(false)
|
|
120
|
+
const visibleMoreFilter = ref(false);
|
|
120
121
|
const listviewfilter = ref();
|
|
121
122
|
const props = withDefaults(
|
|
122
123
|
defineProps<{
|
|
@@ -126,7 +127,7 @@ const props = withDefaults(
|
|
|
126
127
|
idField?: string;
|
|
127
128
|
subTitleField?: string;
|
|
128
129
|
withFilter?: boolean;
|
|
129
|
-
filter?:Object;
|
|
130
|
+
filter?: Object;
|
|
130
131
|
withAddNew?: boolean;
|
|
131
132
|
showIndex?: boolean;
|
|
132
133
|
showClickEffect?: boolean;
|
|
@@ -138,7 +139,7 @@ const props = withDefaults(
|
|
|
138
139
|
const letters = ref<string[]>([]);
|
|
139
140
|
let lastchar = "";
|
|
140
141
|
|
|
141
|
-
const emits = defineEmits(["add", "runFilter", "clearFilter","click"]);
|
|
142
|
+
const emits = defineEmits(["add", "runFilter", "clearFilter", "click"]);
|
|
142
143
|
const searchvalue = ref("");
|
|
143
144
|
const selecteditem = ref("");
|
|
144
145
|
const clickRow = (item: ListItem) => {
|
|
@@ -158,15 +159,23 @@ const filterlist = computed(() => {
|
|
|
158
159
|
return [];
|
|
159
160
|
}
|
|
160
161
|
if (props.list !== undefined) {
|
|
162
|
+
const searchstr = searchvalue.value.toLowerCase()
|
|
163
|
+
|
|
161
164
|
newlist = props.list.filter((item: T) => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
let res = false
|
|
166
|
+
if(searchstr.length==0) return true
|
|
167
|
+
if(props.titleField && item[props.titleField]){
|
|
168
|
+
res = item[props.titleField].toLowerCase()
|
|
169
|
+
.includes(searchstr)
|
|
170
|
+
}
|
|
171
|
+
if(res) return true
|
|
172
|
+
|
|
173
|
+
if(props.subTitleField && item[props.subTitleField])
|
|
174
|
+
res = item[props.subTitleField].toLowerCase()
|
|
175
|
+
.includes(searchstr)
|
|
176
|
+
if(res) return true
|
|
177
|
+
|
|
178
|
+
return false;
|
|
170
179
|
});
|
|
171
180
|
}
|
|
172
181
|
|
|
@@ -198,21 +207,21 @@ const showCategoryBar = (letter: string) => {
|
|
|
198
207
|
}
|
|
199
208
|
};
|
|
200
209
|
|
|
201
|
-
const onClick = (index: number, data: T) => {
|
|
202
|
-
emits("click", index, data);
|
|
210
|
+
const onClick = (index: number, data: T, event: Event | MouseEvent) => {
|
|
211
|
+
emits("click", index, data, event);
|
|
203
212
|
};
|
|
204
213
|
|
|
205
|
-
const showMoreFilter = ()=>{
|
|
206
|
-
visibleMoreFilter.value=true
|
|
207
|
-
}
|
|
208
|
-
const clearFilter = () =>{
|
|
209
|
-
visibleMoreFilter.value = false
|
|
210
|
-
emits(
|
|
211
|
-
}
|
|
214
|
+
const showMoreFilter = () => {
|
|
215
|
+
visibleMoreFilter.value = true;
|
|
216
|
+
};
|
|
217
|
+
const clearFilter = () => {
|
|
218
|
+
visibleMoreFilter.value = false;
|
|
219
|
+
emits("clearFilter");
|
|
220
|
+
};
|
|
212
221
|
const runFilter = () => {
|
|
213
|
-
visibleMoreFilter.value = false
|
|
214
|
-
emits(
|
|
215
|
-
}
|
|
222
|
+
visibleMoreFilter.value = false;
|
|
223
|
+
emits("runFilter");
|
|
224
|
+
};
|
|
216
225
|
onMounted(() => {
|
|
217
226
|
// if(props.withFilter) listviewfilter.value.$el.focus()
|
|
218
227
|
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Sidebar
|
|
3
|
-
position="right"
|
|
3
|
+
:position="position??'right'"
|
|
4
4
|
v-if="showDialog"
|
|
5
5
|
v-model:visible="showDialog"
|
|
6
6
|
modal
|
|
7
7
|
:show-close-icon="false"
|
|
8
|
+
:dismissable="dismissable"
|
|
8
9
|
#container
|
|
9
10
|
>
|
|
10
|
-
<div class="overflow-y-scroll">
|
|
11
|
+
<div class="overflow-y-scroll border-l-2">
|
|
11
12
|
<MobileToolbar class="bg-gray-800 text-white">
|
|
12
13
|
<template #start>
|
|
13
14
|
<slot name="headerLeft"></slot>
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
<slot name="headerRight"></slot>
|
|
20
21
|
</template>
|
|
21
22
|
</MobileToolbar>
|
|
22
|
-
<div >
|
|
23
|
+
<div class="p-2">
|
|
23
24
|
<slot name="default"></slot>
|
|
24
25
|
</div>
|
|
25
26
|
</div>
|
|
@@ -33,7 +34,12 @@
|
|
|
33
34
|
* Author: Ks Tan
|
|
34
35
|
*/
|
|
35
36
|
const showDialog = defineModel<boolean>({ required: true });
|
|
36
|
-
const props = defineProps<{
|
|
37
|
+
const props = defineProps<{
|
|
38
|
+
closeEventName: string;
|
|
39
|
+
dismissable?: boolean;
|
|
40
|
+
position?:string
|
|
41
|
+
}>();
|
|
42
|
+
// const position = ref(props?.position ?? 'right')
|
|
37
43
|
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
38
44
|
if (props.closeEventName == closeEventName) {
|
|
39
45
|
showDialog.value = false;
|
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
position="right"
|
|
4
4
|
v-if="showDialog"
|
|
5
5
|
v-model:visible="showDialog"
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
:dismissable="dismissable"
|
|
7
|
+
modal
|
|
8
8
|
#container
|
|
9
|
-
>
|
|
10
|
-
<div class="
|
|
11
|
-
<
|
|
9
|
+
>
|
|
10
|
+
<div class="border-l-2 pl-2">
|
|
11
|
+
<div class="flex flex-row justify-end p-2" v-if="title">
|
|
12
|
+
<TextTitle class="dark:text-white line-clamp-2 flex-1">{{title}}</TextTitle>
|
|
13
|
+
<ButtonText @click="showDialog=false"><i class="pi pi-times" /></ButtonText>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="overflow-y-scroll">
|
|
16
|
+
<slot name="default"></slot>
|
|
17
|
+
</div>
|
|
12
18
|
</div>
|
|
13
19
|
</Sidebar>
|
|
14
20
|
</template>
|
|
@@ -20,7 +26,12 @@
|
|
|
20
26
|
* Author: Ks Tan
|
|
21
27
|
*/
|
|
22
28
|
const showDialog = defineModel<boolean>({ required: true });
|
|
23
|
-
const props = defineProps<{
|
|
29
|
+
const props = defineProps<{
|
|
30
|
+
closeEventName: string
|
|
31
|
+
title?:string
|
|
32
|
+
dismissable?:boolean
|
|
33
|
+
|
|
34
|
+
}>();
|
|
24
35
|
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
25
36
|
if (props.closeEventName == closeEventName) {
|
|
26
37
|
showDialog.value = false;
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
position="bottom"
|
|
2
|
+
<Dialog
|
|
4
3
|
v-if="showDialog"
|
|
5
4
|
v-model:visible="showDialog"
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
maximizable
|
|
7
|
+
:dismissable="false"
|
|
7
8
|
:show-close-icon="false"
|
|
8
|
-
|
|
9
|
+
:closeOnEscape="false"
|
|
10
|
+
:modal="true"
|
|
11
|
+
:pt="{root:{class:'w-11/12 border top-0'}, mask: {
|
|
12
|
+
style: 'backdrop-filter: blur(2px);background-color: red;'
|
|
13
|
+
}}"
|
|
14
|
+
|
|
9
15
|
>
|
|
10
|
-
<
|
|
16
|
+
<template #header>
|
|
17
|
+
<slot name="header">{{t(title)}}</slot>
|
|
18
|
+
</template>
|
|
19
|
+
<div class="overflow-y-scroll bg-white">
|
|
11
20
|
<slot name="default"></slot>
|
|
12
21
|
</div>
|
|
13
|
-
</
|
|
22
|
+
</Dialog>
|
|
14
23
|
</template>
|
|
15
24
|
<script lang="ts" setup>
|
|
16
25
|
/**
|
|
@@ -23,4 +32,5 @@ const showDialog = defineModel<boolean>({ required: true });
|
|
|
23
32
|
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
24
33
|
if (closeEventName == "viewer") showDialog.value = false;
|
|
25
34
|
});
|
|
35
|
+
|
|
26
36
|
</script>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<title v-if="!id">{{ t(doc.getDocName()) }}</title>
|
|
3
|
+
|
|
3
4
|
<div v-if="isMobile()" class="w-full">
|
|
4
5
|
<div class="p-2 flex flex-row justify-end place-items-center h-14">
|
|
5
6
|
<div class="flex-1">
|
|
6
|
-
<
|
|
7
|
+
<TextMain>{{ t(doc.getDocName()) }}</TextMain>
|
|
7
8
|
</div>
|
|
8
9
|
<div>
|
|
9
10
|
<ButtonText
|
|
@@ -45,37 +46,82 @@
|
|
|
45
46
|
</template>
|
|
46
47
|
<template #default>
|
|
47
48
|
<slot name="dataTableColumns">
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class="min-w-[5rem]"
|
|
52
|
-
#body="{ index, data }"
|
|
49
|
+
<!-- :sortable="schemacols[col] && schemacols[col].type!='object'" -->
|
|
50
|
+
<template
|
|
51
|
+
v-for="col in columns.filter((item, index) => index < maxcolumns)"
|
|
53
52
|
>
|
|
54
|
-
<
|
|
55
|
-
v-if="
|
|
56
|
-
:
|
|
57
|
-
|
|
58
|
-
:
|
|
53
|
+
<Column
|
|
54
|
+
v-if="schemacols[col]"
|
|
55
|
+
:header="t(col)"
|
|
56
|
+
sortable
|
|
57
|
+
:field="schemacols[col]['x-foreignkey'] ? col + '.label' : col"
|
|
58
|
+
:class="`min-w-[5rem] ${getCssClass(col)}`"
|
|
59
|
+
#body="{ index, data }"
|
|
59
60
|
>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
<RendererLink
|
|
62
|
+
v-if="uniqueKey === col || documentTitle === col"
|
|
63
|
+
:value="data"
|
|
64
|
+
:setting="{ path: resourcename.toLocaleLowerCase() }"
|
|
65
|
+
:fields="[col]"
|
|
66
|
+
>
|
|
67
|
+
</RendererLink>
|
|
68
|
+
<span v-else-if="typeof schemacols[col].enum != 'undefined'">
|
|
69
|
+
{{ t(data[col]) }}
|
|
70
|
+
</span>
|
|
71
|
+
<span v-else-if="schemacols[col].type == 'boolean'">
|
|
72
|
+
<RendererBoolean v-model="data[col]" />
|
|
73
|
+
</span>
|
|
74
|
+
<RendererForeignKey
|
|
75
|
+
v-else-if="schemacols[col]['x-foreignkey']"
|
|
76
|
+
v-model="data[col]"
|
|
77
|
+
:setting="{ collection: schemacols[col]['x-foreignkey'] }"
|
|
78
|
+
>
|
|
79
|
+
{{ data[col]?.label ?? data[col]?.code ?? data[col] }}
|
|
80
|
+
</RendererForeignKey>
|
|
81
|
+
<span v-else-if="data[col]?.label !== undefined">{{
|
|
82
|
+
data[col].label
|
|
83
|
+
}}</span>
|
|
84
|
+
<span v-else>{{ data[col] }}</span>
|
|
85
|
+
</Column>
|
|
86
|
+
</template>
|
|
67
87
|
</slot>
|
|
68
88
|
</template>
|
|
69
89
|
</ListDocumentTable>
|
|
70
90
|
</div>
|
|
71
|
-
<
|
|
91
|
+
<OverlayPanelWithToolBar
|
|
72
92
|
v-model="showDialog"
|
|
73
93
|
:closeEventName="doc.getDocName()"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
:dismissable="false"
|
|
95
|
+
:position="sidebarposition"
|
|
96
|
+
>
|
|
97
|
+
<template #headerLeft>
|
|
98
|
+
<ButtonText @click="showDialog = false">
|
|
99
|
+
<i class="pi pi-times"></i>
|
|
100
|
+
</ButtonText>
|
|
101
|
+
</template>
|
|
102
|
+
<template #headerCenter>
|
|
103
|
+
<TextTitle class="text-center text-white">{{
|
|
104
|
+
t(doc.getDocName())
|
|
105
|
+
}}</TextTitle>
|
|
106
|
+
</template>
|
|
107
|
+
<template #headerRight>
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
<ButtonText @click="sidebarposition = sidebarposition == 'right' ? sidebarposition='full': 'right'">
|
|
113
|
+
<i v-if="sidebarposition=='right'" class="pi pi-window-maximize"/>
|
|
114
|
+
<i v-if="sidebarposition=='full'" class="pi pi-window-minimize"/>
|
|
115
|
+
</ButtonText>
|
|
116
|
+
|
|
117
|
+
</template>
|
|
118
|
+
|
|
119
|
+
<div class="p-2">
|
|
120
|
+
<slot name="default">
|
|
121
|
+
<NuxtPage :_id="id"></NuxtPage>
|
|
122
|
+
</slot>
|
|
123
|
+
</div>
|
|
124
|
+
</OverlayPanelWithToolBar>
|
|
79
125
|
</template>
|
|
80
126
|
|
|
81
127
|
<script setup lang="ts" generic="T extends { [key: string]: any }">
|
|
@@ -89,14 +135,16 @@ import { ref } from "vue";
|
|
|
89
135
|
import _ from "lodash";
|
|
90
136
|
import { SearchBody } from "~/types";
|
|
91
137
|
import { SimpleAppClient } from "~/simpleapp/generate/clients/SimpleAppClient";
|
|
138
|
+
const sidebarposition = ref('right')
|
|
92
139
|
const props = defineProps<{
|
|
93
140
|
document: SimpleAppClient<any, any>;
|
|
94
141
|
data: T;
|
|
142
|
+
dismissable?: boolean;
|
|
95
143
|
columns: string[];
|
|
96
144
|
mobileColumns?: string[];
|
|
97
145
|
sorts?: string[][];
|
|
98
146
|
}>();
|
|
99
|
-
|
|
147
|
+
const maxcolumns = 16;
|
|
100
148
|
const emits = defineEmits(["selectRow"]);
|
|
101
149
|
const id = computed(() => getPathPara("id"));
|
|
102
150
|
const resourcename = ref(_.upperFirst(props.document.getDocName()));
|
|
@@ -115,7 +163,13 @@ const { $event, $listen } = useNuxtApp();
|
|
|
115
163
|
const recordlist = ref<T[]>();
|
|
116
164
|
const uniqueKey = doc.getSchema()["x-simpleapp-config"].uniqueKey;
|
|
117
165
|
const documentTitle = doc.getSchema()["x-simpleapp-config"].documentTitle;
|
|
118
|
-
|
|
166
|
+
const schemacols = doc.getSchema().properties;
|
|
167
|
+
const getCssClass = (col: string) => {
|
|
168
|
+
if (schemacols[col]?.type == "number") return "text-right";
|
|
169
|
+
else if (schemacols[col]?.type == "boolean")
|
|
170
|
+
return "text-center place-items-center";
|
|
171
|
+
else return "text-left";
|
|
172
|
+
};
|
|
119
173
|
const refresh = () => {
|
|
120
174
|
const searchbody: SearchBody = {
|
|
121
175
|
fields: props.columns,
|
|
@@ -154,7 +208,7 @@ watch(showDialog, () => {
|
|
|
154
208
|
watch(
|
|
155
209
|
() => useRoute().path,
|
|
156
210
|
async () => {
|
|
157
|
-
if(!isMobile()){
|
|
211
|
+
if (!isMobile()) {
|
|
158
212
|
if (getPathPara("id")) {
|
|
159
213
|
showDialog.value = true;
|
|
160
214
|
} else {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div class="flex flex-row
|
|
3
|
+
<div class="flex flex-row">
|
|
4
4
|
<label v-if="!hideLabel" :for="fieldid" class="pt-2">
|
|
5
|
-
|
|
5
|
+
{{ t(documentName) }}
|
|
6
6
|
</label>
|
|
7
|
-
<ButtonText
|
|
8
|
-
|
|
7
|
+
<ButtonText
|
|
8
|
+
v-if="allowAddNew"
|
|
9
|
+
@click="addnew"
|
|
10
|
+
class="text-xs text-blue-600"
|
|
11
|
+
>
|
|
12
|
+
<span>{{ t("new") }}</span>
|
|
9
13
|
</ButtonText>
|
|
10
14
|
</div>
|
|
11
15
|
<MultiSelect
|
|
@@ -20,7 +24,6 @@
|
|
|
20
24
|
:placeholder="placeholder"
|
|
21
25
|
/>
|
|
22
26
|
<Dropdown
|
|
23
|
-
|
|
24
27
|
:input-id="fieldid"
|
|
25
28
|
v-else
|
|
26
29
|
@update:modelValue="change"
|
|
@@ -40,20 +43,25 @@
|
|
|
40
43
|
* Author: Ks Tan
|
|
41
44
|
*/
|
|
42
45
|
import Dropdown from "primevue/dropdown";
|
|
43
|
-
|
|
46
|
+
|
|
47
|
+
import { ForeignKey,SimpleAppDocuments, FormCrudEvent } from "~/types";
|
|
44
48
|
const emits = defineEmits(["change"]);
|
|
45
|
-
|
|
46
|
-
const list = ref<ForeignKey[]>([]);
|
|
47
|
-
const fieldid = randomUUID()
|
|
49
|
+
|
|
48
50
|
const props = defineProps<{
|
|
49
|
-
documentName:
|
|
51
|
+
documentName: SimpleAppDocuments;
|
|
50
52
|
placeholder?: string;
|
|
51
53
|
showNull?: boolean;
|
|
52
54
|
allowAddNew?: boolean;
|
|
53
55
|
filter?: any;
|
|
54
56
|
multiple?: boolean;
|
|
55
|
-
hideLabel?:boolean
|
|
57
|
+
hideLabel?: boolean;
|
|
56
58
|
}>();
|
|
59
|
+
// const initvalue = props.multiple==true ? [] : ''
|
|
60
|
+
const modelValue = defineModel<string | string[]>();
|
|
61
|
+
|
|
62
|
+
const list = ref<ForeignKey[]>([]);
|
|
63
|
+
const fieldid = randomUUID();
|
|
64
|
+
|
|
57
65
|
const options = ref<
|
|
58
66
|
{
|
|
59
67
|
value: string;
|
|
@@ -79,30 +87,34 @@ onMounted(async () => {
|
|
|
79
87
|
});
|
|
80
88
|
const getItem = (id: string) => list.value?.find((item) => item._id == id);
|
|
81
89
|
|
|
82
|
-
const change = (id: string) => {
|
|
90
|
+
const change = (id: string|string[]) => {
|
|
83
91
|
const selectedItem = getItem(id);
|
|
84
92
|
emits("change", id, selectedItem);
|
|
85
|
-
|
|
86
93
|
};
|
|
87
94
|
|
|
88
|
-
const addnew=()=>{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
modelValue.value =
|
|
101
|
-
|
|
95
|
+
const addnew = () => {
|
|
96
|
+
const doc = getDocument(props.documentName )?.docClass;
|
|
97
|
+
if (doc) {
|
|
98
|
+
const tmpdata = doc?.getReactiveData();
|
|
99
|
+
type DataType = typeof tmpdata.value;
|
|
100
|
+
onScreenAddDocument<DataType>(
|
|
101
|
+
props.documentName ,
|
|
102
|
+
undefined,
|
|
103
|
+
async (eventType: FormCrudEvent, data: DataType) => {
|
|
104
|
+
if (eventType == FormCrudEvent.create) {
|
|
105
|
+
await getListOptions();
|
|
106
|
+
if(props.multiple) {
|
|
107
|
+
if(modelValue.value===undefined) modelValue.value=[data._id]
|
|
108
|
+
else if(Array.isArray(modelValue.value))
|
|
109
|
+
modelValue.value.push(data._id);
|
|
110
|
+
|
|
111
|
+
|
|
102
112
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
else modelValue.value = data._id;
|
|
114
|
+
emits("change", data._id, getItem(data._id));
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
);
|
|
106
118
|
}
|
|
107
|
-
}
|
|
119
|
+
};
|
|
108
120
|
</script>
|
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
v-if="readonly"
|
|
4
|
+
class="p-3 border rounded-lg border-gray-300 dark:border-blue-900/40"
|
|
5
|
+
>
|
|
6
|
+
<button
|
|
7
|
+
:readonly="readonly"
|
|
8
|
+
class="cursor-pointer text-primary-600 dark:text-primary-400"
|
|
9
|
+
tabindex="0"
|
|
10
|
+
@click="openViewer(true)"
|
|
11
|
+
>{{ modelValue && modelValue.label ? modelValue.label : "-" }}</button
|
|
12
|
+
>
|
|
13
|
+
</div>
|
|
14
|
+
<div
|
|
15
|
+
v-else-if="modelValue !== undefined"
|
|
16
|
+
class="p-3 border rounded-lg border-gray-300 dark:border-blue-900/40 relative"
|
|
17
|
+
>
|
|
18
|
+
<button
|
|
19
|
+
ref="autocompleteinput"
|
|
20
|
+
readonly
|
|
21
|
+
class="cursor-pointer text-primary-600 dark:text-primary-400"
|
|
22
|
+
|
|
23
|
+
@click="openViewer(true)"
|
|
24
|
+
>{{ modelValue && modelValue.label ? modelValue.label : "-" }}</button>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
class="absolute h-full top-0 right-0 text-right text-white z-10 align-middle p-3"
|
|
28
|
+
>
|
|
29
|
+
<button
|
|
30
|
+
class="pi pi-times rounded-full bg-slate-500 p-1 cursor-pointer text-xs"
|
|
31
|
+
@click="clear" tabindex="0"
|
|
32
|
+
|
|
33
|
+
></button>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div v-else class="relative">
|
|
3
37
|
<div
|
|
4
|
-
class="absolute h-full top-0 right-10 text-right
|
|
38
|
+
class="absolute h-full top-0 right-10 text-right text-white z-10 align-middle p-3"
|
|
5
39
|
v-if="modelValue?._id"
|
|
6
40
|
>
|
|
7
41
|
<span
|
|
@@ -24,14 +58,15 @@
|
|
|
24
58
|
:dropdown="true"
|
|
25
59
|
@clear="clear"
|
|
26
60
|
:dropdown-mode="'current'"
|
|
61
|
+
:readonly="readonly"
|
|
27
62
|
:pt="pt"
|
|
28
63
|
:delay="500"
|
|
29
64
|
:disabled="readonly"
|
|
65
|
+
@click="clickAutocomplete"
|
|
30
66
|
:suggestions="list"
|
|
31
67
|
@blur="onBlurAutocomplete"
|
|
32
68
|
:inputId="inputId"
|
|
33
69
|
:path="setting.instancepath"
|
|
34
|
-
:readonly="readonly"
|
|
35
70
|
>
|
|
36
71
|
<template #header>
|
|
37
72
|
<slot name="header">
|
|
@@ -46,7 +81,7 @@
|
|
|
46
81
|
</template>
|
|
47
82
|
<template #option="{ index, option }">
|
|
48
83
|
<slot name="option" :index="index" :option="option">
|
|
49
|
-
<div class="flex flex-row text-white">
|
|
84
|
+
<div class="flex flex-row dark:text-white">
|
|
50
85
|
<div class="w w-1/3">{{ option.code }}</div>
|
|
51
86
|
<div class="w w-2/3">{{ option.label }}</div>
|
|
52
87
|
</div>
|
|
@@ -91,7 +126,7 @@
|
|
|
91
126
|
<i class="pi pi-plus"></i>
|
|
92
127
|
</ButtonText> -->
|
|
93
128
|
</template>
|
|
94
|
-
</mobile-toolbar>
|
|
129
|
+
</mobile-toolbar>
|
|
95
130
|
<ListView
|
|
96
131
|
:list="list"
|
|
97
132
|
:withFilter="true"
|
|
@@ -124,18 +159,6 @@
|
|
|
124
159
|
</OverlaySideBarCrud>
|
|
125
160
|
</div>
|
|
126
161
|
</div>
|
|
127
|
-
<div
|
|
128
|
-
v-else
|
|
129
|
-
class="p-3 border rounded-lg border-gray-300 dark:border-blue-900/40"
|
|
130
|
-
>
|
|
131
|
-
<span
|
|
132
|
-
:readonly="readonly"
|
|
133
|
-
class="cursor-pointer text-primary-600 dark:text-primary-400"
|
|
134
|
-
tabindex="0"
|
|
135
|
-
@click="openViewer(true)"
|
|
136
|
-
>{{ modelValue && modelValue.label ? modelValue.label : "-" }}</span
|
|
137
|
-
>
|
|
138
|
-
</div>
|
|
139
162
|
</template>
|
|
140
163
|
<script setup lang="ts">
|
|
141
164
|
/**
|
|
@@ -368,4 +391,9 @@ const afterRenderMobileForm = async (
|
|
|
368
391
|
mobileVisible.value = false;
|
|
369
392
|
}
|
|
370
393
|
};
|
|
394
|
+
|
|
395
|
+
const clickAutocomplete = (a, b) => {
|
|
396
|
+
console.log("clickAutocomplete", a, b);
|
|
397
|
+
return false;
|
|
398
|
+
};
|
|
371
399
|
</script>
|