@simitgroup/simpleapp-generator 1.6.2-alpha → 1.6.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/README.md +6 -5
- package/dist/buildinschemas/branch.d.ts.map +1 -1
- package/dist/buildinschemas/branch.js +1 -2
- package/dist/buildinschemas/branch.js.map +1 -1
- package/dist/buildinschemas/changehistories.d.ts +3 -0
- package/dist/buildinschemas/changehistories.d.ts.map +1 -0
- package/dist/buildinschemas/changehistories.js +36 -0
- package/dist/buildinschemas/changehistories.js.map +1 -0
- package/dist/buildinschemas/index.d.ts +1 -0
- package/dist/buildinschemas/index.d.ts.map +1 -1
- package/dist/buildinschemas/index.js +3 -1
- package/dist/buildinschemas/index.js.map +1 -1
- package/dist/buildinschemas/organization.js +2 -2
- package/dist/buildinschemas/organization.js.map +1 -1
- package/dist/buildinschemas/user.d.ts.map +1 -1
- package/dist/buildinschemas/user.js +5 -1
- package/dist/buildinschemas/user.js.map +1 -1
- package/dist/buildinschemas/webhook.d.ts +3 -0
- package/dist/buildinschemas/webhook.d.ts.map +1 -0
- package/dist/buildinschemas/webhook.js +33 -0
- package/dist/buildinschemas/webhook.js.map +1 -0
- package/dist/framework.d.ts.map +1 -1
- package/dist/framework.js +3 -2
- package/dist/framework.js.map +1 -1
- package/dist/generate.js +30 -11
- package/dist/generate.js.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/processors/jsonschemabuilder.d.ts.map +1 -1
- package/dist/processors/jsonschemabuilder.js +10 -2
- package/dist/processors/jsonschemabuilder.js.map +1 -1
- package/dist/type.d.ts +2 -0
- package/dist/type.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/buildinschemas/branch.ts +1 -2
- package/src/buildinschemas/changehistories.ts +33 -0
- package/src/buildinschemas/index.ts +2 -1
- package/src/buildinschemas/organization.ts +2 -2
- package/src/buildinschemas/user.ts +5 -1
- package/src/buildinschemas/webhook.ts +31 -0
- package/src/framework.ts +3 -2
- package/src/generate.ts +35 -15
- package/src/index.ts +8 -3
- package/src/processors/jsonschemabuilder.ts +10 -2
- package/src/type.ts +2 -0
- package/templates/basic/nest/controller.ts.eta +23 -2
- package/templates/basic/nest/model.ts.eta +9 -1
- package/templates/basic/nest/resolver.ts.eta +2 -2
- package/templates/basic/nuxt/pages.[id].vue.eta +7 -7
- package/templates/basic/nuxt/pages.form.vue.eta +3 -6
- package/templates/basic/nuxt/pages.landing.vue.eta +2 -21
- package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +8 -1
- package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +2 -0
- package/templates/nest/src/simpleapp/generate/commons/dicts/documents.ts.eta +9 -2
- package/templates/nest/src/simpleapp/generate/commons/docnogenerator.service.ts.eta +36 -30
- package/templates/nest/src/simpleapp/generate/commons/roles/roles.enum.ts.eta +5 -10
- package/templates/nest/src/simpleapp/generate/commons/roles/roles.group.ts.eta +1 -0
- package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +50 -0
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +13 -3
- package/templates/nest/src/simpleapp/generate/controllers/simpleapp.controller.ts.eta +9 -1
- package/templates/nest/src/simpleapp/generate/processors/branch.processor.ts.eta +12 -6
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +128 -14
- package/templates/nest/src/simpleapp/generate/types/schema.type.ts.eta +3 -1
- package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +1 -0
- package/templates/nest/src/simpleapp/profile/profile.controller.ts.eta +19 -0
- package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +30 -8
- package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +2 -1
- package/templates/nuxt/{app.vue._eta → app.vue.eta} +3 -1
- package/templates/nuxt/assets/css/calendar.css._eta +3 -0
- package/templates/nuxt/assets/css/style.css._eta +1 -1
- package/templates/nuxt/assets/images/unknown.png.eta +0 -0
- package/templates/nuxt/assets/primevue/passthrough.ts._eta +6 -1
- package/templates/nuxt/components/button/ButtonAction.vue._eta +49 -7
- package/templates/nuxt/components/button/ButtonDanger.vue._eta +11 -3
- package/templates/nuxt/components/button/ButtonDefault.vue._eta +11 -3
- package/templates/nuxt/components/button/ButtonPrimary.vue._eta +9 -3
- package/templates/nuxt/components/button/ButtonSecondary.vue._eta +33 -0
- package/templates/nuxt/components/button/ButtonText.vue._eta +9 -5
- package/templates/nuxt/components/button/ButtonWarning.vue._eta +11 -3
- package/templates/nuxt/components/calendar/CalendarInput.vue.eta +17 -14
- package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +33 -16
- package/templates/nuxt/components/chart/card.vue._eta +1 -1
- package/templates/nuxt/components/debug/DebugDocumentData.vue.eta +36 -26
- package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +62 -22
- package/templates/nuxt/components/form/FormBranch.vue._eta +52 -5
- package/templates/nuxt/components/form/FormDocnoformat.vue.eta +14 -10
- package/templates/nuxt/components/form/FormUser.vue._eta +1 -1
- package/templates/nuxt/components/form/user/FormUserPermission.vue.eta +77 -59
- package/templates/nuxt/components/header/HeaderSelectBranch.vue.eta +42 -35
- package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +30 -0
- package/templates/nuxt/components/image/ImageOrganization.vue.eta.vue +7 -5
- package/templates/nuxt/components/image/ImageToBase64Uploader.vue.eta.vue +67 -50
- package/templates/nuxt/components/list/ListDocument.vue.eta +10 -5
- package/templates/nuxt/components/list/ListDocumentTable.vue.eta +21 -13
- package/templates/nuxt/components/list/ListMessages.vue.eta +1 -1
- package/templates/nuxt/components/list/ListView.vue.eta +94 -56
- package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +11 -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 +108 -31
- package/templates/nuxt/components/renderer/RendererDate.vue.eta +8 -2
- package/templates/nuxt/components/renderer/RendererDateTime.vue.eta +7 -1
- package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +56 -0
- package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +9 -8
- package/templates/nuxt/components/renderer/RendererLink.vue.eta +7 -4
- package/templates/nuxt/components/renderer/RendererMoney.vue.eta +25 -17
- package/templates/nuxt/components/renderer/RendererTime.vue.eta +7 -1
- package/templates/nuxt/components/renderer/RendererViewer.vue.eta +19 -9
- package/templates/nuxt/components/select/SelectTemplate.vue.eta +76 -38
- package/templates/nuxt/components/session/SessionBlock.vue.eta +44 -46
- package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +61 -24
- package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +64 -0
- package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +26 -14
- package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +8 -8
- package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +1 -1
- package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +128 -33
- package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +89 -168
- package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +43 -40
- package/templates/nuxt/components/simpleApp/SimpleAppUserPicker.vue.eta +387 -0
- package/templates/nuxt/components/text/TextDocStatus.vue._eta +22 -0
- package/templates/nuxt/components/user/UserButtonCreateTenant.vue._eta +13 -15
- package/templates/nuxt/components/user/UserButtonPermissionInfo.vue.eta +127 -93
- package/templates/nuxt/components/user/UserTenantPicker.vue.eta +1 -1
- package/templates/nuxt/composables/confirm.generate.ts.eta +19 -0
- package/templates/nuxt/composables/date.generate.ts.eta +106 -8
- package/templates/nuxt/composables/getDocument.generate.ts.eta +8 -6
- package/templates/nuxt/composables/getOpenApi.generate.ts.eta +58 -10
- package/templates/nuxt/composables/getUserStore.generate.ts.eta +37 -5
- package/templates/nuxt/composables/goTo.generate.ts.eta +14 -1
- package/templates/nuxt/composables/graphquery.generate.ts.eta +20 -2
- package/templates/nuxt/composables/recently.generate.ts.eta +16 -0
- package/templates/nuxt/composables/roles.generate.ts.eta +8 -13
- package/templates/nuxt/composables/stringHelper.generate.ts.eta +54 -1
- package/templates/nuxt/composables/sysmessage.generate.ts.eta +1 -1
- package/templates/nuxt/pages/[xorg]/docnoformat.vue.eta +1 -1
- package/templates/nuxt/pages/[xorg]/mobile/docnoformat/{index.vue.eta → index.vue.etaxxx} +1 -1
- package/templates/nuxt/pages/[xorg]/mobile/user/{index.vue.eta → index.vue.etaxxx} +1 -1
- package/templates/nuxt/pages/[xorg]/{organization.vue.eta → organization.vue._eta} +39 -10
- package/templates/nuxt/pages/[xorg]/profile.vue.eta +1 -1
- package/templates/nuxt/pages/[xorg]/user.vue.eta +13 -10
- package/templates/nuxt/pages/login.vue._eta +4 -1
- package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +4 -0
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +45 -26
- package/templates/nuxt/plugins/70.recently.ts.eta +55 -0
- package/templates/nuxt/providers/my-provider.ts.eta +22 -0
- package/templates/nuxt/server/api/[xorg]/{[...].ts.eta → [...].ts._eta} +47 -21
- package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +44 -3
- package/templates/nuxt/types/events.ts.eta +3 -2
- package/templates/nuxt/types/others.ts.eta +11 -1
- package/templates/nuxt/types/schema.ts.eta +3 -1
- package/templates/nuxt/types/simpleappinput.ts.eta +1 -1
- package/templates/nuxt/types/user.ts.eta +8 -7
- package/templates/project/jsonschemas/branch.json._eta +1 -0
- package/templates/project/jsonschemas/invoice.json._eta +4 -3
- package/templates/project/jsonschemas/organization.json._eta +2 -2
- package/templates/project/lang/default._json +5 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nuxt/components/image/ImageAvatar.vue.eta.vue +0 -38
- /package/templates/nuxt/pages/[xorg]/mobile/{index.vue._eta → index.vue._etaxxx} +0 -0
- /package/templates/nuxt/pages/[xorg]/mobile/organization/{[id].vue._eta → [id].vue._etaxxx} +0 -0
- /package/templates/nuxt/pages/[xorg]/mobile/{pickgroup.vue._eta → pickgroup.vue._etaxxx} +0 -0
|
@@ -1,73 +1,90 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<div
|
|
3
3
|
@click="openUploadDialog"
|
|
4
4
|
:title="selectedBase64Img"
|
|
5
|
-
class="place-content-center image-to-base64-uploader rounded-lg border block"
|
|
5
|
+
class="vvv place-content-center image-to-base64-uploader rounded-lg border block"
|
|
6
6
|
>
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
<ClientOnly>
|
|
8
|
+
<slot name="default">
|
|
9
|
+
<Image v-if="selectedBase64Img" :src="selectedBase64Img" />
|
|
10
|
+
<i v-else class="pi pi-upload text-3xl"></i>
|
|
11
|
+
</slot>
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
13
|
+
<Dialog
|
|
14
|
+
v-if="dialogVisible"
|
|
15
|
+
v-model:visible="dialogVisible"
|
|
16
|
+
header="Image Upload"
|
|
17
|
+
:pt="{ root: { class: 'w-4/5' } }"
|
|
18
|
+
>
|
|
19
|
+
<div class="w-full grid grid-cols-2 gap-2">
|
|
20
|
+
<div class="w-7/8 border rounded p-4">
|
|
21
|
+
<TabView lazy>
|
|
22
|
+
<TabPanel :header="t('upload')">
|
|
23
|
+
<div class="upload-container">
|
|
24
|
+
<input
|
|
25
|
+
type="file"
|
|
26
|
+
ref="fileInput"
|
|
27
|
+
accept="image/*"
|
|
28
|
+
@change="handleImageUpload"
|
|
29
|
+
/>
|
|
30
|
+
</div>
|
|
31
|
+
</TabPanel>
|
|
32
|
+
<TabPanel :header="t('webcam')">
|
|
33
|
+
<div class="webcam-container h h-1/6">
|
|
34
|
+
<WebCamUI :fullscreenState="false" @photoTaken="photoTaken" />
|
|
35
|
+
</div>
|
|
36
|
+
</TabPanel>
|
|
37
|
+
</TabView>
|
|
38
|
+
</div>
|
|
39
|
+
<div id="preview" class="w-7/8 border rounded p-4">
|
|
40
|
+
<Cropper
|
|
41
|
+
v-if="scaledImage"
|
|
42
|
+
ref="cropperInstance"
|
|
43
|
+
:src="scaledImage"
|
|
44
|
+
:stencil-props="{ aspectRatio: 1 }"
|
|
45
|
+
:options="cropperOptions"
|
|
46
|
+
@change="changeChropper"
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
34
49
|
</div>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
|
|
51
|
+
<template #footer>
|
|
52
|
+
<div class="flex flex-row gap-4">
|
|
53
|
+
<ButtonDefault @click="dialogVisible = false">{{
|
|
54
|
+
t("cancel")
|
|
55
|
+
}}</ButtonDefault>
|
|
56
|
+
<ButtonPrimary @click="confirm">{{ t("confirm") }}</ButtonPrimary>
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
59
|
+
</Dialog>
|
|
60
|
+
</ClientOnly>
|
|
61
|
+
</div>
|
|
46
62
|
</template>
|
|
47
63
|
|
|
48
64
|
<script setup lang="ts">
|
|
49
|
-
/**
|
|
50
|
-
* This file was automatically generated by simpleapp generator during initialization.
|
|
51
|
-
* IT IS NOT CHANGABLE
|
|
52
|
-
* last change 2024-04-06
|
|
53
|
-
* author: Ks Tan
|
|
54
|
-
*/
|
|
55
65
|
// Assuming the Dialog component and Cropper component are globally available or imported in a parent component
|
|
56
|
-
import { defineEmits } from "vue";
|
|
66
|
+
// import { defineEmits } from "vue";
|
|
67
|
+
import { WebCamUI } from "vue-camera-lib";
|
|
68
|
+
import VueCameraLib from "vue-camera-lib";
|
|
69
|
+
|
|
57
70
|
// import Cropper from 'cropperjs'; // Assuming CropperJS is installed using a package manager
|
|
58
71
|
import { Cropper } from "vue-advanced-cropper";
|
|
59
72
|
import "vue-advanced-cropper/dist/style.css";
|
|
73
|
+
|
|
60
74
|
const selectedBase64Img = ref("");
|
|
61
75
|
const cropedBase64Img = ref("");
|
|
62
76
|
const dialogVisible = ref(false);
|
|
63
77
|
const previewImage = ref<string | null>(null);
|
|
64
78
|
const scaledImage = ref<string | null>(null);
|
|
65
|
-
const image = ref<string | null>(null);
|
|
66
|
-
|
|
79
|
+
// const image = ref<string | null>(null);
|
|
67
80
|
const emit = defineEmits<{
|
|
68
81
|
(event: "image-uploaded", imageData: string): void;
|
|
69
82
|
}>();
|
|
70
83
|
|
|
84
|
+
// Use camera reference to call functions
|
|
85
|
+
const photoTaken = (data: any) => {
|
|
86
|
+
scaledImage.value = data.image_data_url;
|
|
87
|
+
};
|
|
71
88
|
const openUploadDialog = () => {
|
|
72
89
|
dialogVisible.value = true;
|
|
73
90
|
};
|
|
@@ -79,8 +96,8 @@ const handleImageUpload = (event) => {
|
|
|
79
96
|
reader.onload = (e) => {
|
|
80
97
|
const img = new Image();
|
|
81
98
|
img.onload = () => {
|
|
82
|
-
const maxWidth =
|
|
83
|
-
const maxHeight =
|
|
99
|
+
const maxWidth = 400; // Set your desired maximum width
|
|
100
|
+
const maxHeight = 300; // Set your desired maximum height
|
|
84
101
|
const scale = Math.min(maxWidth / img.width, maxHeight / img.height);
|
|
85
102
|
const scaledWidth = img.width * scale;
|
|
86
103
|
const scaledHeight = img.height * scale;
|
|
@@ -6,10 +6,15 @@
|
|
|
6
6
|
:sub-title-field="uniqueKey"
|
|
7
7
|
#default="{ item, index }"
|
|
8
8
|
>
|
|
9
|
-
<div
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
<div
|
|
10
|
+
class="cursor-pointer flex flex-row gap-2"
|
|
11
|
+
@click="emits('click', item)"
|
|
12
|
+
>
|
|
13
|
+
<slot name="default" :index="index" :item="item">
|
|
14
|
+
<TextMain class="flex-1">{{
|
|
15
|
+
item[documentTitle as keyof typeof item]
|
|
16
|
+
}}</TextMain>
|
|
17
|
+
<TextSubsubtitle>{{ item[uniqueKey as keyof typeof item] }}</TextSubsubtitle>
|
|
13
18
|
</slot>
|
|
14
19
|
</div>
|
|
15
20
|
</ListView>
|
|
@@ -24,7 +29,7 @@
|
|
|
24
29
|
import { SearchBody } from "~/types";
|
|
25
30
|
const emits = defineEmits(["click"]);
|
|
26
31
|
const props = defineProps<{
|
|
27
|
-
recordlist: T[];
|
|
32
|
+
recordlist: T[];
|
|
28
33
|
uniqueKey?: string;
|
|
29
34
|
documentTitle?: string;
|
|
30
35
|
}>();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<DataTable
|
|
3
|
+
ref="documentlisttable"
|
|
3
4
|
v-bind="$attrs"
|
|
4
5
|
stripedRows
|
|
5
6
|
dataKey="_id"
|
|
@@ -29,15 +30,17 @@
|
|
|
29
30
|
</h1>
|
|
30
31
|
</slot>
|
|
31
32
|
</div>
|
|
32
|
-
<
|
|
33
|
-
<
|
|
33
|
+
<div class="p-input-icon-left gap-2 flex flex-row">
|
|
34
|
+
<ButtonPrimary @click="exportData">
|
|
35
|
+
<i class="pi pi-external-link"/>
|
|
36
|
+
</ButtonPrimary>
|
|
34
37
|
<InputText
|
|
35
38
|
type="search"
|
|
36
39
|
v-model="filters['global'].value"
|
|
37
|
-
class="text-
|
|
40
|
+
class="w-full dark:text-white text-sm"
|
|
38
41
|
placeholder="Keyword Search"
|
|
39
42
|
/>
|
|
40
|
-
</
|
|
43
|
+
</div>
|
|
41
44
|
</div>
|
|
42
45
|
</template>
|
|
43
46
|
<!-- no data found -->
|
|
@@ -46,10 +49,10 @@
|
|
|
46
49
|
<div class="text-3xl text-gray-400 pi pi-exclamation-circle"></div>
|
|
47
50
|
<div class="text-3xl text-gray-400">{{ t("noDataFound") }}</div>
|
|
48
51
|
</div>
|
|
49
|
-
</template>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
</template>
|
|
53
|
+
<slot name="default">
|
|
54
|
+
<Column header="undefineColumns"></Column>
|
|
55
|
+
</slot>
|
|
53
56
|
</DataTable>
|
|
54
57
|
</template>
|
|
55
58
|
<script setup lang="ts" generic="T">
|
|
@@ -65,18 +68,23 @@ import DataTable from "primevue/datatable";
|
|
|
65
68
|
import Column from "primevue/column";
|
|
66
69
|
import renderComponent from "~/components/renderer";
|
|
67
70
|
import { emit } from "process";
|
|
71
|
+
import ButtonPrimary from "../button/ButtonPrimary.vue";
|
|
72
|
+
const documentlisttable = ref()
|
|
68
73
|
const props = defineProps<{
|
|
69
|
-
value: T[]
|
|
70
|
-
title: string
|
|
71
|
-
columns: string[]
|
|
72
|
-
uniqueKey: string
|
|
73
|
-
documentTitle: string
|
|
74
|
+
value: T[];
|
|
75
|
+
title: string;
|
|
76
|
+
columns: string[];
|
|
77
|
+
uniqueKey: string;
|
|
78
|
+
documentTitle: string;
|
|
74
79
|
}>();
|
|
75
80
|
const emits = defineEmits(["selectRow"]);
|
|
76
81
|
const clickRow = (eventdata: any) => {
|
|
77
82
|
emits("selectRow", eventdata.data);
|
|
78
83
|
};
|
|
79
84
|
|
|
85
|
+
const exportData = ()=>{
|
|
86
|
+
documentlisttable.value.exportCSV()
|
|
87
|
+
}
|
|
80
88
|
const filters = ref({
|
|
81
89
|
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
|
82
90
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<Sidebar v-model:visible="messagesvisible" :header="t('messages')">
|
|
3
|
+
<Sidebar v-model:visible="messagesvisible" position="right" :header="t('messages')">
|
|
4
4
|
<ListView :list="list" #default="{ item, index }" @click="openMessage">
|
|
5
5
|
<div class="flex flex-col">
|
|
6
6
|
<TextBold v-if="!item.read">{{ item.messageTitle }}</TextBold>
|
|
@@ -1,28 +1,50 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative">
|
|
3
|
+
<div v-if="header">
|
|
4
|
+
<slot name="header">
|
|
5
|
+
<TextMain class="text-gray-800 pl-2 pt-2">{{ header }}</TextMain>
|
|
6
|
+
</slot>
|
|
7
|
+
<hr class="mt-2" />
|
|
8
|
+
</div>
|
|
3
9
|
<div v-if="withFilter" class="flex flex-row p-2">
|
|
4
|
-
<InputGroup>
|
|
5
|
-
|
|
10
|
+
<InputGroup :pt="{ root: { class: 'p-0' } }">
|
|
11
|
+
<InputGroupAddon
|
|
12
|
+
v-if="filter !== undefined && Object.keys(filter).length > 0"
|
|
13
|
+
:pt="{
|
|
14
|
+
root: {
|
|
15
|
+
class:
|
|
16
|
+
'p-0 pi pi-filter cursor-pointer bg-warning-400 text-white p-3',
|
|
17
|
+
},
|
|
18
|
+
}"
|
|
19
|
+
@click="showMoreFilter"
|
|
20
|
+
>
|
|
21
|
+
</InputGroupAddon>
|
|
22
|
+
<InputGroupAddon
|
|
23
|
+
v-else
|
|
24
|
+
:pt="{ root: { class: 'p-0 pi pi-filter cursor-pointer p-3' } }"
|
|
25
|
+
@click="showMoreFilter"
|
|
26
|
+
>
|
|
27
|
+
</InputGroupAddon>
|
|
28
|
+
<InputText
|
|
29
|
+
:placeholder="t('searchKeyword')"
|
|
30
|
+
v-model="searchvalue"
|
|
31
|
+
type="search"
|
|
32
|
+
:pt="{ root: { class: 'p-1' } }"
|
|
33
|
+
ref="listviewfilter"
|
|
34
|
+
/>
|
|
35
|
+
<InputGroupAddon
|
|
36
|
+
:pt="{
|
|
37
|
+
root: {
|
|
38
|
+
class:
|
|
39
|
+
'p-0 cursor-pointer bg-primary-400 pi pi-plus p-3 text-white',
|
|
40
|
+
},
|
|
41
|
+
}"
|
|
42
|
+
v-if="withAddNew"
|
|
43
|
+
@click="emits('add')"
|
|
44
|
+
>
|
|
6
45
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
</ButtonDefault>
|
|
10
|
-
<ButtonWarning @click="showMoreFilter" v-else>
|
|
11
|
-
<i class="pi pi-filter"></i>
|
|
12
|
-
</ButtonWarning>
|
|
13
|
-
</InputGroupAddon>
|
|
14
|
-
<InputText
|
|
15
|
-
:placeholder="t('searchKeyword')"
|
|
16
|
-
v-model="searchvalue"
|
|
17
|
-
class="w-full dark:text-white text-sm "
|
|
18
|
-
type="search"
|
|
19
|
-
ref="listviewfilter"
|
|
20
|
-
/>
|
|
21
|
-
<InputGroupAddon v-if="withAddNew">
|
|
22
|
-
<ButtonPrimary @click="emits('add')">
|
|
23
|
-
<i class="pi pi-plus"></i>
|
|
24
|
-
</ButtonPrimary>
|
|
25
|
-
</InputGroupAddon>
|
|
46
|
+
</InputGroupAddon>
|
|
47
|
+
<slot name="inputAddOn"></slot>
|
|
26
48
|
</InputGroup>
|
|
27
49
|
</div>
|
|
28
50
|
|
|
@@ -54,7 +76,7 @@
|
|
|
54
76
|
<span>{{ item[titleField][0] }}</span>
|
|
55
77
|
</div>
|
|
56
78
|
<div
|
|
57
|
-
@click="onClick(index, item)"
|
|
79
|
+
@click="onClick(index, item, $event)"
|
|
58
80
|
:class="`border-l-none border-r-none listview-item dark:border-t-gray-700 ${
|
|
59
81
|
index > 0 ? 'border-t-2' : ''
|
|
60
82
|
}`"
|
|
@@ -88,18 +110,21 @@
|
|
|
88
110
|
</div>
|
|
89
111
|
</div>
|
|
90
112
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
113
|
+
<Dialog
|
|
114
|
+
v-model:visible="visibleMoreFilter"
|
|
115
|
+
:header="t('filter')"
|
|
116
|
+
:pt="{ root: { class: 'w-1/3' } }"
|
|
117
|
+
>
|
|
118
|
+
<slot name="filter"> define filter in #filter </slot>
|
|
96
119
|
<template #footer>
|
|
97
|
-
<div class="flex flex-row">
|
|
120
|
+
<div class="flex flex-row gap-4">
|
|
98
121
|
<ButtonDefault @click="clearFilter" class="flex flex-row p-2">
|
|
99
|
-
<i class="pi pi-times mr-1"/>
|
|
122
|
+
<i class="pi pi-times mr-1" />
|
|
123
|
+
<span class="mr-1">{{ t("clear") }}</span>
|
|
100
124
|
</ButtonDefault>
|
|
101
|
-
<ButtonPrimary
|
|
102
|
-
<i class="pi pi-filter mr-1"/>
|
|
125
|
+
<ButtonPrimary @click="runFilter" class="flex flex-row p-2">
|
|
126
|
+
<i class="pi pi-filter mr-1" />
|
|
127
|
+
<span class="mr-1">{{ t("ok") }}</span>
|
|
103
128
|
</ButtonPrimary>
|
|
104
129
|
</div>
|
|
105
130
|
</template>
|
|
@@ -116,17 +141,19 @@
|
|
|
116
141
|
import { ref } from "vue";
|
|
117
142
|
import { ListItem } from "~/types/listview";
|
|
118
143
|
import _ from "lodash";
|
|
119
|
-
const visibleMoreFilter = ref(false)
|
|
144
|
+
const visibleMoreFilter = ref(false);
|
|
120
145
|
const listviewfilter = ref();
|
|
121
146
|
const props = withDefaults(
|
|
122
147
|
defineProps<{
|
|
123
148
|
list: T[];
|
|
124
149
|
url?: string;
|
|
150
|
+
urlsuffix?: string;
|
|
151
|
+
header?: string;
|
|
125
152
|
titleField?: string;
|
|
126
153
|
idField?: string;
|
|
127
154
|
subTitleField?: string;
|
|
128
155
|
withFilter?: boolean;
|
|
129
|
-
filter?:
|
|
156
|
+
filter?: { [key: string]: any };
|
|
130
157
|
withAddNew?: boolean;
|
|
131
158
|
showIndex?: boolean;
|
|
132
159
|
showClickEffect?: boolean;
|
|
@@ -138,7 +165,7 @@ const props = withDefaults(
|
|
|
138
165
|
const letters = ref<string[]>([]);
|
|
139
166
|
let lastchar = "";
|
|
140
167
|
|
|
141
|
-
const emits = defineEmits(["add", "runFilter", "clearFilter","click"]);
|
|
168
|
+
const emits = defineEmits(["add", "runFilter", "clearFilter", "click"]);
|
|
142
169
|
const searchvalue = ref("");
|
|
143
170
|
const selecteditem = ref("");
|
|
144
171
|
const clickRow = (item: ListItem) => {
|
|
@@ -146,9 +173,14 @@ const clickRow = (item: ListItem) => {
|
|
|
146
173
|
// selecteditem.value = item.code
|
|
147
174
|
};
|
|
148
175
|
const getUrl = (item: any) => {
|
|
176
|
+
const urlsuffix =
|
|
177
|
+
props.urlsuffix === undefined || props.urlsuffix == ""
|
|
178
|
+
? ""
|
|
179
|
+
: "/" + props.urlsuffix;
|
|
149
180
|
if (props.url && props.idField) {
|
|
150
|
-
if (_.last(props.url) == "/")
|
|
151
|
-
|
|
181
|
+
if (_.last(props.url) == "/")
|
|
182
|
+
return `${props.url}${item[props.idField]}${urlsuffix}`;
|
|
183
|
+
else return `${props.url}/${item[props.idField]}${urlsuffix}`;
|
|
152
184
|
} else return undefined;
|
|
153
185
|
// :to="url ? `${url}/${item[idField]}` : undefined"
|
|
154
186
|
};
|
|
@@ -158,15 +190,21 @@ const filterlist = computed(() => {
|
|
|
158
190
|
return [];
|
|
159
191
|
}
|
|
160
192
|
if (props.list !== undefined) {
|
|
193
|
+
const searchstr = searchvalue.value.toLowerCase();
|
|
194
|
+
|
|
161
195
|
newlist = props.list.filter((item: T) => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
)
|
|
196
|
+
let res = false;
|
|
197
|
+
if (searchstr.length == 0) return true;
|
|
198
|
+
if (props.titleField && item[props.titleField]) {
|
|
199
|
+
res = item[props.titleField].toLowerCase().includes(searchstr);
|
|
200
|
+
}
|
|
201
|
+
if (res) return true;
|
|
202
|
+
|
|
203
|
+
if (props.subTitleField && item[props.subTitleField])
|
|
204
|
+
res = item[props.subTitleField].toLowerCase().includes(searchstr);
|
|
205
|
+
if (res) return true;
|
|
206
|
+
|
|
207
|
+
return false;
|
|
170
208
|
});
|
|
171
209
|
}
|
|
172
210
|
|
|
@@ -198,21 +236,21 @@ const showCategoryBar = (letter: string) => {
|
|
|
198
236
|
}
|
|
199
237
|
};
|
|
200
238
|
|
|
201
|
-
const onClick = (index: number, data: T) => {
|
|
202
|
-
emits("click", index, data);
|
|
239
|
+
const onClick = (index: number, data: T, event: Event | MouseEvent) => {
|
|
240
|
+
emits("click", index, data, event);
|
|
203
241
|
};
|
|
204
242
|
|
|
205
|
-
const showMoreFilter = ()=>{
|
|
206
|
-
visibleMoreFilter.value=true
|
|
207
|
-
}
|
|
208
|
-
const clearFilter = () =>{
|
|
209
|
-
visibleMoreFilter.value = false
|
|
210
|
-
emits(
|
|
211
|
-
}
|
|
243
|
+
const showMoreFilter = () => {
|
|
244
|
+
visibleMoreFilter.value = true;
|
|
245
|
+
};
|
|
246
|
+
const clearFilter = () => {
|
|
247
|
+
visibleMoreFilter.value = false;
|
|
248
|
+
emits("clearFilter");
|
|
249
|
+
};
|
|
212
250
|
const runFilter = () => {
|
|
213
|
-
visibleMoreFilter.value = false
|
|
214
|
-
emits(
|
|
215
|
-
}
|
|
251
|
+
visibleMoreFilter.value = false;
|
|
252
|
+
emits("runFilter");
|
|
253
|
+
};
|
|
216
254
|
onMounted(() => {
|
|
217
255
|
// if(props.withFilter) listviewfilter.value.$el.focus()
|
|
218
256
|
});
|
|
@@ -1,14 +1,16 @@
|
|
|
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"
|
|
9
|
+
:pt="{root:{class:'w-2/3 border-0 border-l border-l-gray-500'}}"
|
|
8
10
|
#container
|
|
9
11
|
>
|
|
10
12
|
<div class="overflow-y-scroll">
|
|
11
|
-
<MobileToolbar class="
|
|
13
|
+
<MobileToolbar class="">
|
|
12
14
|
<template #start>
|
|
13
15
|
<slot name="headerLeft"></slot>
|
|
14
16
|
</template>
|
|
@@ -19,7 +21,7 @@
|
|
|
19
21
|
<slot name="headerRight"></slot>
|
|
20
22
|
</template>
|
|
21
23
|
</MobileToolbar>
|
|
22
|
-
<div >
|
|
24
|
+
<div class="p-2">
|
|
23
25
|
<slot name="default"></slot>
|
|
24
26
|
</div>
|
|
25
27
|
</div>
|
|
@@ -33,7 +35,12 @@
|
|
|
33
35
|
* Author: Ks Tan
|
|
34
36
|
*/
|
|
35
37
|
const showDialog = defineModel<boolean>({ required: true });
|
|
36
|
-
const props = defineProps<{
|
|
38
|
+
const props = defineProps<{
|
|
39
|
+
closeEventName: string;
|
|
40
|
+
dismissable?: boolean;
|
|
41
|
+
position?: "right" | "full" | "left" | "top" | "bottom" | undefined;
|
|
42
|
+
}>();
|
|
43
|
+
// const position = ref(props?.position ?? 'right')
|
|
37
44
|
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
38
45
|
if (props.closeEventName == closeEventName) {
|
|
39
46
|
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,26 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
position="bottom"
|
|
2
|
+
<Dialog
|
|
4
3
|
v-if="showDialog"
|
|
5
4
|
v-model:visible="showDialog"
|
|
6
|
-
|
|
5
|
+
maximizable
|
|
6
|
+
:dismissable="false"
|
|
7
7
|
:show-close-icon="false"
|
|
8
|
-
|
|
8
|
+
:closeOnEscape="false"
|
|
9
|
+
:modal="true"
|
|
10
|
+
:pt="{
|
|
11
|
+
root: { class: 'w-11/12 border top-0' },
|
|
12
|
+
mask: {
|
|
13
|
+
style: 'backdrop-filter: blur(2px);background-color: red;',
|
|
14
|
+
},
|
|
15
|
+
}"
|
|
9
16
|
>
|
|
10
|
-
<
|
|
17
|
+
<template #header>
|
|
18
|
+
<slot name="header">{{ t(title) }}</slot>
|
|
19
|
+
</template>
|
|
20
|
+
<div class="overflow-y-scroll bodycolorclass">
|
|
11
21
|
<slot name="default"></slot>
|
|
12
22
|
</div>
|
|
13
|
-
</
|
|
23
|
+
</Dialog>
|
|
14
24
|
</template>
|
|
15
25
|
<script lang="ts" setup>
|
|
16
26
|
/**
|