@simitgroup/simpleapp-generator 1.6.3-alpha → 1.6.4-b-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/buildinschemas/branch.d.ts.map +1 -1
- package/dist/buildinschemas/branch.js +1 -0
- 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/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 -0
- 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/processors/jsonschemabuilder.ts +10 -2
- package/src/type.ts +2 -0
- package/templates/basic/nest/controller.ts.eta +24 -3
- 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 +1 -4
- package/templates/basic/nuxt/pages.landing.vue.eta +1 -20
- 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 +21 -8
- 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 +22 -8
- 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/org.processor.ts.eta +7 -12
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +133 -28
- 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 +33 -8
- package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +15 -9
- 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 +40 -39
- 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 +4 -3
- package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +76 -52
- 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 +35 -13
- 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 +2 -4
- 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 +34 -14
- package/templates/nuxt/components/image/ImageToBase64Uploader.vue.eta.vue +67 -50
- package/templates/nuxt/components/list/ListDocumentTable.vue.eta +20 -12
- package/templates/nuxt/components/list/ListView.vue.eta +64 -35
- package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +5 -4
- package/templates/nuxt/components/overlay/OverlayViewer.vue.eta +8 -8
- package/templates/nuxt/components/page/PageDocList.vue.eta +36 -13
- 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 +14 -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 +53 -22
- package/templates/nuxt/components/session/SessionBlock.vue.eta +44 -46
- package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +25 -16
- package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +60 -0
- package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +16 -8
- 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 +114 -38
- package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +89 -168
- package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +44 -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 +138 -95
- package/templates/nuxt/components/user/UserInvitation.vue.eta +53 -45
- package/templates/nuxt/components/user/UserTenantPicker.vue.eta +32 -71
- package/templates/nuxt/composables/date.generate.ts.eta +105 -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 +39 -6
- 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 +9 -13
- package/templates/nuxt/composables/stringHelper.generate.ts.eta +52 -0
- package/templates/nuxt/composables/sysmessage.generate.ts.eta +1 -1
- package/templates/nuxt/error.vue._eta +4 -2
- package/templates/nuxt/pages/[xorg]/{organization.vue.eta → organization.vue._eta} +38 -9
- package/templates/nuxt/pages/[xorg]/user.vue.eta +12 -9
- package/templates/nuxt/pages/login.vue._eta +4 -1
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +54 -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 +6 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nuxt/components/image/ImageAvatar.vue.eta.vue +0 -38
- /package/templates/nuxt/pages/[xorg]/mobile/docnoformat/{index.vue.eta → index.vue.etaxxx} +0 -0
- /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
- /package/templates/nuxt/pages/[xorg]/mobile/user/{index.vue.eta → index.vue.etaxxx} +0 -0
|
@@ -2,39 +2,59 @@
|
|
|
2
2
|
<ImageToBase64Uploader
|
|
3
3
|
v-if="changable"
|
|
4
4
|
#default
|
|
5
|
-
class="w
|
|
5
|
+
:class="`w-${sizenumber} h-${sizenumber} place-content-center bg-white`"
|
|
6
6
|
@image-uploaded="handleBase64"
|
|
7
7
|
>
|
|
8
|
-
<
|
|
8
|
+
<NuxtImg
|
|
9
|
+
class="w-full h-full"
|
|
10
|
+
:key="imageKey"
|
|
11
|
+
provider="myProvider"
|
|
12
|
+
:src="imagepath"
|
|
13
|
+
/>
|
|
9
14
|
</ImageToBase64Uploader>
|
|
10
|
-
<div
|
|
11
|
-
|
|
15
|
+
<div
|
|
16
|
+
v-else
|
|
17
|
+
:class="`inline-block border rounded-lg w-${sizenumber} h-${sizenumber} bg-white`"
|
|
18
|
+
>
|
|
19
|
+
<NuxtImg class="w-full h-full" provider="myProvider" :src="imagepath" />
|
|
12
20
|
</div>
|
|
13
21
|
</template>
|
|
14
22
|
<script lang="ts" setup>
|
|
15
23
|
// import {KeyValue} from ''
|
|
16
24
|
const props = defineProps<{
|
|
17
|
-
changable
|
|
25
|
+
changable?: boolean;
|
|
26
|
+
orgRecordId?: string;
|
|
27
|
+
size: number;
|
|
18
28
|
}>();
|
|
29
|
+
const imageKey = ref(0);
|
|
30
|
+
const orgRecordId = computed(
|
|
31
|
+
() => props.orgRecordId ?? getUserProfile()?.orgRecordId,
|
|
32
|
+
);
|
|
33
|
+
const xorgpath= getCurrentXorg() ? `${getCurrentXorg()}/` : 'MC0wLTA/'
|
|
34
|
+
|
|
35
|
+
const imagepath = `${xorgpath}images/organization/${
|
|
36
|
+
orgRecordId.value
|
|
37
|
+
}`;
|
|
38
|
+
const sizenumber = props.size ?? 16;
|
|
19
39
|
const imageData = ref("");
|
|
40
|
+
watch(
|
|
41
|
+
() => props.orgRecordId,
|
|
42
|
+
() => imageKey.value++,
|
|
43
|
+
);
|
|
20
44
|
const handleBase64 = async (data: string) => {
|
|
21
45
|
const keyvalue = {
|
|
22
|
-
key: "
|
|
46
|
+
key: "org-" + props.orgRecordId,
|
|
23
47
|
value: data,
|
|
24
48
|
};
|
|
25
|
-
|
|
49
|
+
console.log("upload logo ", data);
|
|
26
50
|
const uploadok = await useNuxtApp()
|
|
27
51
|
.$OrganizationDoc()
|
|
28
52
|
.getApi()
|
|
29
53
|
.runUploadlogo(keyvalue);
|
|
30
54
|
if (uploadok) {
|
|
31
|
-
|
|
55
|
+
const realpath = `/api/${imagepath}`;
|
|
56
|
+
await fetch(realpath, { cache: "reload", credentials: "include" });
|
|
57
|
+
imageKey.value++;
|
|
32
58
|
}
|
|
33
59
|
};
|
|
34
|
-
const loadLogo = async () => {
|
|
35
|
-
await refreshOrgLogo();
|
|
36
|
-
imageData.value = getOrgLogo();
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
onMounted(async () => await loadLogo());
|
|
40
60
|
</script>
|
|
@@ -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;
|
|
@@ -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
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,30 +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
|
-
<InputGroupAddon
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
>
|
|
15
27
|
</InputGroupAddon>
|
|
16
28
|
<InputText
|
|
17
29
|
:placeholder="t('searchKeyword')"
|
|
18
30
|
v-model="searchvalue"
|
|
19
|
-
class="w-full dark:text-white text-sm"
|
|
20
31
|
type="search"
|
|
32
|
+
:pt="{ root: { class: 'p-1' } }"
|
|
21
33
|
ref="listviewfilter"
|
|
22
34
|
/>
|
|
23
|
-
<InputGroupAddon
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
+
>
|
|
45
|
+
|
|
27
46
|
</InputGroupAddon>
|
|
47
|
+
<slot name="inputAddOn"></slot>
|
|
28
48
|
</InputGroup>
|
|
29
49
|
</div>
|
|
30
50
|
|
|
@@ -90,10 +110,14 @@
|
|
|
90
110
|
</div>
|
|
91
111
|
</div>
|
|
92
112
|
|
|
93
|
-
<Dialog
|
|
113
|
+
<Dialog
|
|
114
|
+
v-model:visible="visibleMoreFilter"
|
|
115
|
+
:header="t('filter')"
|
|
116
|
+
:pt="{ root: { class: 'w-1/3' } }"
|
|
117
|
+
>
|
|
94
118
|
<slot name="filter"> define filter in #filter </slot>
|
|
95
119
|
<template #footer>
|
|
96
|
-
<div class="flex flex-row">
|
|
120
|
+
<div class="flex flex-row gap-4">
|
|
97
121
|
<ButtonDefault @click="clearFilter" class="flex flex-row p-2">
|
|
98
122
|
<i class="pi pi-times mr-1" />
|
|
99
123
|
<span class="mr-1">{{ t("clear") }}</span>
|
|
@@ -123,11 +147,13 @@ const props = withDefaults(
|
|
|
123
147
|
defineProps<{
|
|
124
148
|
list: T[];
|
|
125
149
|
url?: string;
|
|
150
|
+
urlsuffix?: string;
|
|
151
|
+
header?: string;
|
|
126
152
|
titleField?: string;
|
|
127
153
|
idField?: string;
|
|
128
154
|
subTitleField?: string;
|
|
129
155
|
withFilter?: boolean;
|
|
130
|
-
filter?:
|
|
156
|
+
filter?: { [key: string]: any };
|
|
131
157
|
withAddNew?: boolean;
|
|
132
158
|
showIndex?: boolean;
|
|
133
159
|
showClickEffect?: boolean;
|
|
@@ -147,9 +173,14 @@ const clickRow = (item: ListItem) => {
|
|
|
147
173
|
// selecteditem.value = item.code
|
|
148
174
|
};
|
|
149
175
|
const getUrl = (item: any) => {
|
|
176
|
+
const urlsuffix =
|
|
177
|
+
props.urlsuffix === undefined || props.urlsuffix == ""
|
|
178
|
+
? ""
|
|
179
|
+
: "/" + props.urlsuffix;
|
|
150
180
|
if (props.url && props.idField) {
|
|
151
|
-
if (_.last(props.url) == "/")
|
|
152
|
-
|
|
181
|
+
if (_.last(props.url) == "/")
|
|
182
|
+
return `${props.url}${item[props.idField]}${urlsuffix}`;
|
|
183
|
+
else return `${props.url}/${item[props.idField]}${urlsuffix}`;
|
|
153
184
|
} else return undefined;
|
|
154
185
|
// :to="url ? `${url}/${item[idField]}` : undefined"
|
|
155
186
|
};
|
|
@@ -159,22 +190,20 @@ const filterlist = computed(() => {
|
|
|
159
190
|
return [];
|
|
160
191
|
}
|
|
161
192
|
if (props.list !== undefined) {
|
|
162
|
-
const searchstr = searchvalue.value.toLowerCase()
|
|
163
|
-
|
|
193
|
+
const searchstr = searchvalue.value.toLowerCase();
|
|
194
|
+
|
|
164
195
|
newlist = props.list.filter((item: T) => {
|
|
165
|
-
let res = false
|
|
166
|
-
if(searchstr.length==0) return true
|
|
167
|
-
if(props.titleField && item[props.titleField]){
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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;
|
|
172
206
|
|
|
173
|
-
if(props.subTitleField && item[props.subTitleField])
|
|
174
|
-
res = item[props.subTitleField].toLowerCase()
|
|
175
|
-
.includes(searchstr)
|
|
176
|
-
if(res) return true
|
|
177
|
-
|
|
178
207
|
return false;
|
|
179
208
|
});
|
|
180
209
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Sidebar
|
|
3
|
-
:position="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
8
|
:dismissable="dismissable"
|
|
9
|
+
:pt="{root:{class:'w-2/3 border-0 border-l border-l-gray-500'}}"
|
|
9
10
|
#container
|
|
10
11
|
>
|
|
11
|
-
<div class="overflow-y-scroll
|
|
12
|
-
<MobileToolbar class="
|
|
12
|
+
<div class="overflow-y-scroll">
|
|
13
|
+
<MobileToolbar class="">
|
|
13
14
|
<template #start>
|
|
14
15
|
<slot name="headerLeft"></slot>
|
|
15
16
|
</template>
|
|
@@ -37,7 +38,7 @@ const showDialog = defineModel<boolean>({ required: true });
|
|
|
37
38
|
const props = defineProps<{
|
|
38
39
|
closeEventName: string;
|
|
39
40
|
dismissable?: boolean;
|
|
40
|
-
position?:
|
|
41
|
+
position?: "right" | "full" | "left" | "top" | "bottom" | undefined;
|
|
41
42
|
}>();
|
|
42
43
|
// const position = ref(props?.position ?? 'right')
|
|
43
44
|
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
<Dialog
|
|
3
3
|
v-if="showDialog"
|
|
4
4
|
v-model:visible="showDialog"
|
|
5
|
-
|
|
6
5
|
maximizable
|
|
7
6
|
:dismissable="false"
|
|
8
7
|
:show-close-icon="false"
|
|
9
8
|
:closeOnEscape="false"
|
|
10
9
|
:modal="true"
|
|
11
|
-
:pt="{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
:pt="{
|
|
11
|
+
root: { class: 'w-11/12 border top-0' },
|
|
12
|
+
mask: {
|
|
13
|
+
style: 'backdrop-filter: blur(2px);background-color: red;',
|
|
14
|
+
},
|
|
15
|
+
}"
|
|
15
16
|
>
|
|
16
17
|
<template #header>
|
|
17
|
-
<slot name="header">{{t(title)}}</slot>
|
|
18
|
+
<slot name="header">{{ t(title) }}</slot>
|
|
18
19
|
</template>
|
|
19
|
-
<div class="overflow-y-scroll
|
|
20
|
+
<div class="overflow-y-scroll bodycolorclass">
|
|
20
21
|
<slot name="default"></slot>
|
|
21
22
|
</div>
|
|
22
23
|
</Dialog>
|
|
@@ -32,5 +33,4 @@ const showDialog = defineModel<boolean>({ required: true });
|
|
|
32
33
|
useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
|
|
33
34
|
if (closeEventName == "viewer") showDialog.value = false;
|
|
34
35
|
});
|
|
35
|
-
|
|
36
36
|
</script>
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
</div>
|
|
9
9
|
<div>
|
|
10
10
|
<ButtonText
|
|
11
|
+
v-if="allowAction('create')"
|
|
11
12
|
@click="goTo(doc.getDocName(), 'new')"
|
|
12
13
|
class="pi pi-plus"
|
|
13
14
|
></ButtonText>
|
|
@@ -36,12 +37,13 @@
|
|
|
36
37
|
>
|
|
37
38
|
<template #toolbar>
|
|
38
39
|
<div class="w-full text-left">
|
|
39
|
-
<ButtonPrimary
|
|
40
|
-
class="pi pi-plus"
|
|
40
|
+
<ButtonPrimary
|
|
41
41
|
@click="newData"
|
|
42
42
|
v-tooltip="t('new')"
|
|
43
|
-
v-if="canPerform(resourcename, 'create')"
|
|
44
|
-
|
|
43
|
+
v-if="allowAction('create') && canPerform(resourcename, 'create')"
|
|
44
|
+
>
|
|
45
|
+
<i class="pi pi-plus"></i>
|
|
46
|
+
</ButtonPrimary>
|
|
45
47
|
</div>
|
|
46
48
|
</template>
|
|
47
49
|
<template #default>
|
|
@@ -65,6 +67,14 @@
|
|
|
65
67
|
:fields="[col]"
|
|
66
68
|
>
|
|
67
69
|
</RendererLink>
|
|
70
|
+
<TextMain v-else-if="col == 'documentStatus'">{{
|
|
71
|
+
t(data[col])
|
|
72
|
+
}}</TextMain>
|
|
73
|
+
<RendererMoney
|
|
74
|
+
v-else-if="schemacols[col]['format'] == 'money'"
|
|
75
|
+
v-model="data[col]"
|
|
76
|
+
>
|
|
77
|
+
</RendererMoney>
|
|
68
78
|
<span v-else-if="typeof schemacols[col].enum != 'undefined'">
|
|
69
79
|
{{ t(data[col]) }}
|
|
70
80
|
</span>
|
|
@@ -78,6 +88,12 @@
|
|
|
78
88
|
>
|
|
79
89
|
{{ data[col]?.label ?? data[col]?.code ?? data[col] }}
|
|
80
90
|
</RendererForeignKey>
|
|
91
|
+
<span v-else-if="schemacols[col].format == 'date'">
|
|
92
|
+
<RendererDate v-model="data[col]" />
|
|
93
|
+
</span>
|
|
94
|
+
<span v-else-if="schemacols[col].format == 'datetime'">
|
|
95
|
+
<RendererDateTime v-model="data[col]" />
|
|
96
|
+
</span>
|
|
81
97
|
<span v-else-if="data[col]?.label !== undefined">{{
|
|
82
98
|
data[col].label
|
|
83
99
|
}}</span>
|
|
@@ -105,15 +121,15 @@
|
|
|
105
121
|
}}</TextTitle>
|
|
106
122
|
</template>
|
|
107
123
|
<template #headerRight>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
<i v-if="sidebarposition=='
|
|
124
|
+
<ButtonText
|
|
125
|
+
@click="
|
|
126
|
+
sidebarposition =
|
|
127
|
+
sidebarposition == 'right' ? (sidebarposition = 'full') : 'right'
|
|
128
|
+
"
|
|
129
|
+
>
|
|
130
|
+
<i v-if="sidebarposition == 'right'" class="pi pi-window-maximize" />
|
|
131
|
+
<i v-if="sidebarposition == 'full'" class="pi pi-window-minimize" />
|
|
115
132
|
</ButtonText>
|
|
116
|
-
|
|
117
133
|
</template>
|
|
118
134
|
|
|
119
135
|
<div class="p-2">
|
|
@@ -135,7 +151,7 @@ import { ref } from "vue";
|
|
|
135
151
|
import _ from "lodash";
|
|
136
152
|
import { SearchBody } from "~/types";
|
|
137
153
|
import { SimpleAppClient } from "~/simpleapp/generate/clients/SimpleAppClient";
|
|
138
|
-
const sidebarposition = ref(
|
|
154
|
+
const sidebarposition = ref("right");
|
|
139
155
|
const props = defineProps<{
|
|
140
156
|
document: SimpleAppClient<any, any>;
|
|
141
157
|
data: T;
|
|
@@ -143,6 +159,7 @@ const props = defineProps<{
|
|
|
143
159
|
columns: string[];
|
|
144
160
|
mobileColumns?: string[];
|
|
145
161
|
sorts?: string[][];
|
|
162
|
+
availableActions?:string[]
|
|
146
163
|
}>();
|
|
147
164
|
const maxcolumns = 16;
|
|
148
165
|
const emits = defineEmits(["selectRow"]);
|
|
@@ -164,6 +181,12 @@ const recordlist = ref<T[]>();
|
|
|
164
181
|
const uniqueKey = doc.getSchema()["x-simpleapp-config"].uniqueKey;
|
|
165
182
|
const documentTitle = doc.getSchema()["x-simpleapp-config"].documentTitle;
|
|
166
183
|
const schemacols = doc.getSchema().properties;
|
|
184
|
+
const allowAction = (actname:string)=>{
|
|
185
|
+
if(props.availableActions === undefined) return true
|
|
186
|
+
else if(Array.isArray(props.availableActions) && props.availableActions.length>0 && !props.availableActions.includes(actname))
|
|
187
|
+
return false
|
|
188
|
+
else return true
|
|
189
|
+
}
|
|
167
190
|
const getCssClass = (col: string) => {
|
|
168
191
|
if (schemacols[col]?.type == "number") return "text-right";
|
|
169
192
|
else if (schemacols[col]?.type == "boolean")
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<span v-if="modelValue">
|
|
2
|
+
<span v-if="modelValue">
|
|
3
|
+
{{ dateRenderToDateStr(modelValue) }}
|
|
4
|
+
</span>
|
|
5
|
+
<span v-else-if="value">
|
|
6
|
+
{{ dateRenderToDateStr(value) }}
|
|
7
|
+
</span>
|
|
3
8
|
<span v-else>-</span>
|
|
4
9
|
</template>
|
|
5
10
|
<script lang="ts" setup>
|
|
@@ -9,5 +14,6 @@
|
|
|
9
14
|
* last change 2024-02-04
|
|
10
15
|
* author: Ks Tan
|
|
11
16
|
*/
|
|
12
|
-
const modelValue = defineModel<Date|string>()
|
|
17
|
+
const modelValue = defineModel<Date | string>();
|
|
18
|
+
const props = defineProps<{ value?: Date | string }>();
|
|
13
19
|
</script>
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<span v-if="modelValue">
|
|
2
|
+
<span v-if="modelValue">
|
|
3
|
+
{{ dateRenderToDateTimeStr(modelValue) }}
|
|
4
|
+
</span>
|
|
5
|
+
<span v-else-if="value">
|
|
6
|
+
{{ dateRenderToDateTimeStr(value) }}
|
|
7
|
+
</span>
|
|
3
8
|
<span v-else>-</span>
|
|
4
9
|
</template>
|
|
5
10
|
<script lang="ts" setup>
|
|
@@ -10,4 +15,5 @@
|
|
|
10
15
|
* author: Ks Tan
|
|
11
16
|
*/
|
|
12
17
|
const modelValue = defineModel<Date | string>();
|
|
18
|
+
const props = defineProps<{value:Date|string}>()
|
|
13
19
|
</script>
|