@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.
Files changed (152) hide show
  1. package/dist/buildinschemas/branch.d.ts.map +1 -1
  2. package/dist/buildinschemas/branch.js +1 -0
  3. package/dist/buildinschemas/branch.js.map +1 -1
  4. package/dist/buildinschemas/changehistories.d.ts +3 -0
  5. package/dist/buildinschemas/changehistories.d.ts.map +1 -0
  6. package/dist/buildinschemas/changehistories.js +36 -0
  7. package/dist/buildinschemas/changehistories.js.map +1 -0
  8. package/dist/buildinschemas/index.d.ts +1 -0
  9. package/dist/buildinschemas/index.d.ts.map +1 -1
  10. package/dist/buildinschemas/index.js +3 -1
  11. package/dist/buildinschemas/index.js.map +1 -1
  12. package/dist/buildinschemas/organization.js +2 -2
  13. package/dist/buildinschemas/organization.js.map +1 -1
  14. package/dist/buildinschemas/user.d.ts.map +1 -1
  15. package/dist/buildinschemas/user.js +5 -1
  16. package/dist/buildinschemas/user.js.map +1 -1
  17. package/dist/buildinschemas/webhook.d.ts +3 -0
  18. package/dist/buildinschemas/webhook.d.ts.map +1 -0
  19. package/dist/buildinschemas/webhook.js +33 -0
  20. package/dist/buildinschemas/webhook.js.map +1 -0
  21. package/dist/framework.d.ts.map +1 -1
  22. package/dist/framework.js +3 -2
  23. package/dist/framework.js.map +1 -1
  24. package/dist/generate.js +30 -11
  25. package/dist/generate.js.map +1 -1
  26. package/dist/processors/jsonschemabuilder.d.ts.map +1 -1
  27. package/dist/processors/jsonschemabuilder.js +10 -2
  28. package/dist/processors/jsonschemabuilder.js.map +1 -1
  29. package/dist/type.d.ts +2 -0
  30. package/dist/type.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/src/buildinschemas/branch.ts +1 -0
  33. package/src/buildinschemas/changehistories.ts +33 -0
  34. package/src/buildinschemas/index.ts +2 -1
  35. package/src/buildinschemas/organization.ts +2 -2
  36. package/src/buildinschemas/user.ts +5 -1
  37. package/src/buildinschemas/webhook.ts +31 -0
  38. package/src/framework.ts +3 -2
  39. package/src/generate.ts +35 -15
  40. package/src/processors/jsonschemabuilder.ts +10 -2
  41. package/src/type.ts +2 -0
  42. package/templates/basic/nest/controller.ts.eta +24 -3
  43. package/templates/basic/nest/model.ts.eta +9 -1
  44. package/templates/basic/nest/resolver.ts.eta +2 -2
  45. package/templates/basic/nuxt/pages.[id].vue.eta +7 -7
  46. package/templates/basic/nuxt/pages.form.vue.eta +1 -4
  47. package/templates/basic/nuxt/pages.landing.vue.eta +1 -20
  48. package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +8 -1
  49. package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +2 -0
  50. package/templates/nest/src/simpleapp/generate/commons/dicts/documents.ts.eta +9 -2
  51. package/templates/nest/src/simpleapp/generate/commons/docnogenerator.service.ts.eta +21 -8
  52. package/templates/nest/src/simpleapp/generate/commons/roles/roles.enum.ts.eta +5 -10
  53. package/templates/nest/src/simpleapp/generate/commons/roles/roles.group.ts.eta +1 -0
  54. package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +50 -0
  55. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +22 -8
  56. package/templates/nest/src/simpleapp/generate/controllers/simpleapp.controller.ts.eta +9 -1
  57. package/templates/nest/src/simpleapp/generate/processors/branch.processor.ts.eta +12 -6
  58. package/templates/nest/src/simpleapp/generate/processors/org.processor.ts.eta +7 -12
  59. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +133 -28
  60. package/templates/nest/src/simpleapp/generate/types/schema.type.ts.eta +3 -1
  61. package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +1 -0
  62. package/templates/nest/src/simpleapp/profile/profile.controller.ts.eta +19 -0
  63. package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +33 -8
  64. package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +15 -9
  65. package/templates/nuxt/assets/css/calendar.css._eta +3 -0
  66. package/templates/nuxt/assets/css/style.css._eta +1 -1
  67. package/templates/nuxt/assets/images/unknown.png.eta +0 -0
  68. package/templates/nuxt/assets/primevue/passthrough.ts._eta +6 -1
  69. package/templates/nuxt/components/button/ButtonAction.vue._eta +40 -39
  70. package/templates/nuxt/components/button/ButtonDanger.vue._eta +11 -3
  71. package/templates/nuxt/components/button/ButtonDefault.vue._eta +11 -3
  72. package/templates/nuxt/components/button/ButtonPrimary.vue._eta +9 -3
  73. package/templates/nuxt/components/button/ButtonSecondary.vue._eta +33 -0
  74. package/templates/nuxt/components/button/ButtonText.vue._eta +9 -5
  75. package/templates/nuxt/components/button/ButtonWarning.vue._eta +11 -3
  76. package/templates/nuxt/components/calendar/CalendarInput.vue.eta +4 -3
  77. package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +76 -52
  78. package/templates/nuxt/components/chart/card.vue._eta +1 -1
  79. package/templates/nuxt/components/debug/DebugDocumentData.vue.eta +36 -26
  80. package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +35 -13
  81. package/templates/nuxt/components/form/FormBranch.vue._eta +52 -5
  82. package/templates/nuxt/components/form/FormDocnoformat.vue.eta +14 -10
  83. package/templates/nuxt/components/form/FormUser.vue._eta +2 -4
  84. package/templates/nuxt/components/form/user/FormUserPermission.vue.eta +77 -59
  85. package/templates/nuxt/components/header/HeaderSelectBranch.vue.eta +42 -35
  86. package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +30 -0
  87. package/templates/nuxt/components/image/ImageOrganization.vue.eta.vue +34 -14
  88. package/templates/nuxt/components/image/ImageToBase64Uploader.vue.eta.vue +67 -50
  89. package/templates/nuxt/components/list/ListDocumentTable.vue.eta +20 -12
  90. package/templates/nuxt/components/list/ListView.vue.eta +64 -35
  91. package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +5 -4
  92. package/templates/nuxt/components/overlay/OverlayViewer.vue.eta +8 -8
  93. package/templates/nuxt/components/page/PageDocList.vue.eta +36 -13
  94. package/templates/nuxt/components/renderer/RendererDate.vue.eta +8 -2
  95. package/templates/nuxt/components/renderer/RendererDateTime.vue.eta +7 -1
  96. package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +56 -0
  97. package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +14 -8
  98. package/templates/nuxt/components/renderer/RendererLink.vue.eta +7 -4
  99. package/templates/nuxt/components/renderer/RendererMoney.vue.eta +25 -17
  100. package/templates/nuxt/components/renderer/RendererTime.vue.eta +7 -1
  101. package/templates/nuxt/components/renderer/RendererViewer.vue.eta +19 -9
  102. package/templates/nuxt/components/select/SelectTemplate.vue.eta +53 -22
  103. package/templates/nuxt/components/session/SessionBlock.vue.eta +44 -46
  104. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +25 -16
  105. package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +60 -0
  106. package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +16 -8
  107. package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +8 -8
  108. package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +1 -1
  109. package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +114 -38
  110. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +89 -168
  111. package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +44 -40
  112. package/templates/nuxt/components/simpleApp/SimpleAppUserPicker.vue.eta +387 -0
  113. package/templates/nuxt/components/text/TextDocStatus.vue._eta +22 -0
  114. package/templates/nuxt/components/user/UserButtonCreateTenant.vue._eta +13 -15
  115. package/templates/nuxt/components/user/UserButtonPermissionInfo.vue.eta +138 -95
  116. package/templates/nuxt/components/user/UserInvitation.vue.eta +53 -45
  117. package/templates/nuxt/components/user/UserTenantPicker.vue.eta +32 -71
  118. package/templates/nuxt/composables/date.generate.ts.eta +105 -8
  119. package/templates/nuxt/composables/getDocument.generate.ts.eta +8 -6
  120. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +58 -10
  121. package/templates/nuxt/composables/getUserStore.generate.ts.eta +39 -6
  122. package/templates/nuxt/composables/goTo.generate.ts.eta +14 -1
  123. package/templates/nuxt/composables/graphquery.generate.ts.eta +20 -2
  124. package/templates/nuxt/composables/recently.generate.ts.eta +16 -0
  125. package/templates/nuxt/composables/roles.generate.ts.eta +9 -13
  126. package/templates/nuxt/composables/stringHelper.generate.ts.eta +52 -0
  127. package/templates/nuxt/composables/sysmessage.generate.ts.eta +1 -1
  128. package/templates/nuxt/error.vue._eta +4 -2
  129. package/templates/nuxt/pages/[xorg]/{organization.vue.eta → organization.vue._eta} +38 -9
  130. package/templates/nuxt/pages/[xorg]/user.vue.eta +12 -9
  131. package/templates/nuxt/pages/login.vue._eta +4 -1
  132. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +54 -26
  133. package/templates/nuxt/plugins/70.recently.ts.eta +55 -0
  134. package/templates/nuxt/providers/my-provider.ts.eta +22 -0
  135. package/templates/nuxt/server/api/[xorg]/{[...].ts.eta → [...].ts._eta} +47 -21
  136. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +44 -3
  137. package/templates/nuxt/types/events.ts.eta +3 -2
  138. package/templates/nuxt/types/others.ts.eta +11 -1
  139. package/templates/nuxt/types/schema.ts.eta +3 -1
  140. package/templates/nuxt/types/simpleappinput.ts.eta +1 -1
  141. package/templates/nuxt/types/user.ts.eta +8 -7
  142. package/templates/project/jsonschemas/branch.json._eta +1 -0
  143. package/templates/project/jsonschemas/invoice.json._eta +4 -3
  144. package/templates/project/jsonschemas/organization.json._eta +2 -2
  145. package/templates/project/lang/default._json +6 -2
  146. package/tsconfig.tsbuildinfo +1 -1
  147. package/templates/nuxt/components/image/ImageAvatar.vue.eta.vue +0 -38
  148. /package/templates/nuxt/pages/[xorg]/mobile/docnoformat/{index.vue.eta → index.vue.etaxxx} +0 -0
  149. /package/templates/nuxt/pages/[xorg]/mobile/{index.vue._eta → index.vue._etaxxx} +0 -0
  150. /package/templates/nuxt/pages/[xorg]/mobile/organization/{[id].vue._eta → [id].vue._etaxxx} +0 -0
  151. /package/templates/nuxt/pages/[xorg]/mobile/{pickgroup.vue._eta → pickgroup.vue._etaxxx} +0 -0
  152. /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-20 h-20 place-content-center"
5
+ :class="`w-${sizenumber} h-${sizenumber} place-content-center bg-white`"
6
6
  @image-uploaded="handleBase64"
7
7
  >
8
- <Image :src="imageData"></Image>
8
+ <NuxtImg
9
+ class="w-full h-full"
10
+ :key="imageKey"
11
+ provider="myProvider"
12
+ :src="imagepath"
13
+ />
9
14
  </ImageToBase64Uploader>
10
- <div v-else class="inline-block border rounded-lg w-20 h-20">
11
- <Image :src="imageData"></Image>
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: boolean;
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: "organizationLogo",
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
- await loadLogo();
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
- <button
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
- <slot name="default">
8
- <Image v-if="selectedBase64Img" :src="selectedBase64Img" />
9
- <i v-else class="pi pi-upload text-3xl"></i>
10
- </slot>
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
- <Dialog
13
- v-model:visible="dialogVisible"
14
- header="Image Upload"
15
- :pt="{ root: { class: 'w-4/5' } }"
16
- >
17
- <div class="upload-container">
18
- <input
19
- type="file"
20
- ref="fileInput"
21
- accept="image/*"
22
- @change="handleImageUpload"
23
- />
24
- <div id="preview" v-if="scaledImage" class="w-7/8">
25
- <Cropper
26
- ref="cropperInstance"
27
- :src="scaledImage"
28
- :stencil-props="{ aspectRatio: 1 }"
29
- :options="cropperOptions"
30
- @change="changeChropper"
31
- />
32
- <!-- :maxWidth="50"
33
- :maxHeight="50" -->
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
- </div>
36
- <template #footer>
37
- <div class="flex flex-row gap-4">
38
- <ButtonWarning @click="dialogVisible = false">{{
39
- t("cancel")
40
- }}</ButtonWarning>
41
- <ButtonPrimary @click="confirm">{{ t("confirm") }}</ButtonPrimary>
42
- </div>
43
- </template>
44
- </Dialog>
45
- </button>
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 = 800; // Set your desired maximum width
83
- const maxHeight = 600; // Set your desired maximum height
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
- <span class="p-input-icon-left flex-1">
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
- </span>
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
- <slot name="default">
51
- <Column header="undefineColumns"></Column>
52
- </slot>
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 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>
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 v-if="withAddNew">
24
- <ButtonPrimary @click="emits('add')">
25
- <i class="pi pi-plus"></i>
26
- </ButtonPrimary>
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 v-model:visible="visibleMoreFilter" :header="t('filter')">
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?: Object;
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) == "/") return `${props.url}${item[props.idField]}`;
152
- else return `${props.url}/${item[props.idField]}`;
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
- res = item[props.titleField].toLowerCase()
169
- .includes(searchstr)
170
- }
171
- if(res) return true
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 border-l-2">
12
- <MobileToolbar class="bg-gray-800 text-white">
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?:string
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="{root:{class:'w-11/12 border top-0'}, mask: {
12
- style: 'backdrop-filter: blur(2px);background-color: red;'
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 bg-white">
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
- ></ButtonPrimary>
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
- <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"/>
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('right')
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">{{ toUTCDate(modelValue) }}</span>
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">{{ toUTCDateTime(modelValue) }}</span>
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>