@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.
Files changed (161) hide show
  1. package/README.md +6 -5
  2. package/dist/buildinschemas/branch.d.ts.map +1 -1
  3. package/dist/buildinschemas/branch.js +1 -2
  4. package/dist/buildinschemas/branch.js.map +1 -1
  5. package/dist/buildinschemas/changehistories.d.ts +3 -0
  6. package/dist/buildinschemas/changehistories.d.ts.map +1 -0
  7. package/dist/buildinschemas/changehistories.js +36 -0
  8. package/dist/buildinschemas/changehistories.js.map +1 -0
  9. package/dist/buildinschemas/index.d.ts +1 -0
  10. package/dist/buildinschemas/index.d.ts.map +1 -1
  11. package/dist/buildinschemas/index.js +3 -1
  12. package/dist/buildinschemas/index.js.map +1 -1
  13. package/dist/buildinschemas/organization.js +2 -2
  14. package/dist/buildinschemas/organization.js.map +1 -1
  15. package/dist/buildinschemas/user.d.ts.map +1 -1
  16. package/dist/buildinschemas/user.js +5 -1
  17. package/dist/buildinschemas/user.js.map +1 -1
  18. package/dist/buildinschemas/webhook.d.ts +3 -0
  19. package/dist/buildinschemas/webhook.d.ts.map +1 -0
  20. package/dist/buildinschemas/webhook.js +33 -0
  21. package/dist/buildinschemas/webhook.js.map +1 -0
  22. package/dist/framework.d.ts.map +1 -1
  23. package/dist/framework.js +3 -2
  24. package/dist/framework.js.map +1 -1
  25. package/dist/generate.js +30 -11
  26. package/dist/generate.js.map +1 -1
  27. package/dist/index.js +4 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/processors/jsonschemabuilder.d.ts.map +1 -1
  30. package/dist/processors/jsonschemabuilder.js +10 -2
  31. package/dist/processors/jsonschemabuilder.js.map +1 -1
  32. package/dist/type.d.ts +2 -0
  33. package/dist/type.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/src/buildinschemas/branch.ts +1 -2
  36. package/src/buildinschemas/changehistories.ts +33 -0
  37. package/src/buildinschemas/index.ts +2 -1
  38. package/src/buildinschemas/organization.ts +2 -2
  39. package/src/buildinschemas/user.ts +5 -1
  40. package/src/buildinschemas/webhook.ts +31 -0
  41. package/src/framework.ts +3 -2
  42. package/src/generate.ts +35 -15
  43. package/src/index.ts +8 -3
  44. package/src/processors/jsonschemabuilder.ts +10 -2
  45. package/src/type.ts +2 -0
  46. package/templates/basic/nest/controller.ts.eta +23 -2
  47. package/templates/basic/nest/model.ts.eta +9 -1
  48. package/templates/basic/nest/resolver.ts.eta +2 -2
  49. package/templates/basic/nuxt/pages.[id].vue.eta +7 -7
  50. package/templates/basic/nuxt/pages.form.vue.eta +3 -6
  51. package/templates/basic/nuxt/pages.landing.vue.eta +2 -21
  52. package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +8 -1
  53. package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +2 -0
  54. package/templates/nest/src/simpleapp/generate/commons/dicts/documents.ts.eta +9 -2
  55. package/templates/nest/src/simpleapp/generate/commons/docnogenerator.service.ts.eta +36 -30
  56. package/templates/nest/src/simpleapp/generate/commons/roles/roles.enum.ts.eta +5 -10
  57. package/templates/nest/src/simpleapp/generate/commons/roles/roles.group.ts.eta +1 -0
  58. package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +50 -0
  59. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +13 -3
  60. package/templates/nest/src/simpleapp/generate/controllers/simpleapp.controller.ts.eta +9 -1
  61. package/templates/nest/src/simpleapp/generate/processors/branch.processor.ts.eta +12 -6
  62. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +128 -14
  63. package/templates/nest/src/simpleapp/generate/types/schema.type.ts.eta +3 -1
  64. package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +1 -0
  65. package/templates/nest/src/simpleapp/profile/profile.controller.ts.eta +19 -0
  66. package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +30 -8
  67. package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +2 -1
  68. package/templates/nuxt/{app.vue._eta → app.vue.eta} +3 -1
  69. package/templates/nuxt/assets/css/calendar.css._eta +3 -0
  70. package/templates/nuxt/assets/css/style.css._eta +1 -1
  71. package/templates/nuxt/assets/images/unknown.png.eta +0 -0
  72. package/templates/nuxt/assets/primevue/passthrough.ts._eta +6 -1
  73. package/templates/nuxt/components/button/ButtonAction.vue._eta +49 -7
  74. package/templates/nuxt/components/button/ButtonDanger.vue._eta +11 -3
  75. package/templates/nuxt/components/button/ButtonDefault.vue._eta +11 -3
  76. package/templates/nuxt/components/button/ButtonPrimary.vue._eta +9 -3
  77. package/templates/nuxt/components/button/ButtonSecondary.vue._eta +33 -0
  78. package/templates/nuxt/components/button/ButtonText.vue._eta +9 -5
  79. package/templates/nuxt/components/button/ButtonWarning.vue._eta +11 -3
  80. package/templates/nuxt/components/calendar/CalendarInput.vue.eta +17 -14
  81. package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +33 -16
  82. package/templates/nuxt/components/chart/card.vue._eta +1 -1
  83. package/templates/nuxt/components/debug/DebugDocumentData.vue.eta +36 -26
  84. package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +62 -22
  85. package/templates/nuxt/components/form/FormBranch.vue._eta +52 -5
  86. package/templates/nuxt/components/form/FormDocnoformat.vue.eta +14 -10
  87. package/templates/nuxt/components/form/FormUser.vue._eta +1 -1
  88. package/templates/nuxt/components/form/user/FormUserPermission.vue.eta +77 -59
  89. package/templates/nuxt/components/header/HeaderSelectBranch.vue.eta +42 -35
  90. package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +30 -0
  91. package/templates/nuxt/components/image/ImageOrganization.vue.eta.vue +7 -5
  92. package/templates/nuxt/components/image/ImageToBase64Uploader.vue.eta.vue +67 -50
  93. package/templates/nuxt/components/list/ListDocument.vue.eta +10 -5
  94. package/templates/nuxt/components/list/ListDocumentTable.vue.eta +21 -13
  95. package/templates/nuxt/components/list/ListMessages.vue.eta +1 -1
  96. package/templates/nuxt/components/list/ListView.vue.eta +94 -56
  97. package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +11 -4
  98. package/templates/nuxt/components/overlay/OverlaySideBarCrud.vue.eta +17 -6
  99. package/templates/nuxt/components/overlay/OverlayViewer.vue.eta +16 -6
  100. package/templates/nuxt/components/page/PageDocList.vue.eta +108 -31
  101. package/templates/nuxt/components/renderer/RendererDate.vue.eta +8 -2
  102. package/templates/nuxt/components/renderer/RendererDateTime.vue.eta +7 -1
  103. package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +56 -0
  104. package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +9 -8
  105. package/templates/nuxt/components/renderer/RendererLink.vue.eta +7 -4
  106. package/templates/nuxt/components/renderer/RendererMoney.vue.eta +25 -17
  107. package/templates/nuxt/components/renderer/RendererTime.vue.eta +7 -1
  108. package/templates/nuxt/components/renderer/RendererViewer.vue.eta +19 -9
  109. package/templates/nuxt/components/select/SelectTemplate.vue.eta +76 -38
  110. package/templates/nuxt/components/session/SessionBlock.vue.eta +44 -46
  111. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +61 -24
  112. package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +64 -0
  113. package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +26 -14
  114. package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +8 -8
  115. package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +1 -1
  116. package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +128 -33
  117. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +89 -168
  118. package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +43 -40
  119. package/templates/nuxt/components/simpleApp/SimpleAppUserPicker.vue.eta +387 -0
  120. package/templates/nuxt/components/text/TextDocStatus.vue._eta +22 -0
  121. package/templates/nuxt/components/user/UserButtonCreateTenant.vue._eta +13 -15
  122. package/templates/nuxt/components/user/UserButtonPermissionInfo.vue.eta +127 -93
  123. package/templates/nuxt/components/user/UserTenantPicker.vue.eta +1 -1
  124. package/templates/nuxt/composables/confirm.generate.ts.eta +19 -0
  125. package/templates/nuxt/composables/date.generate.ts.eta +106 -8
  126. package/templates/nuxt/composables/getDocument.generate.ts.eta +8 -6
  127. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +58 -10
  128. package/templates/nuxt/composables/getUserStore.generate.ts.eta +37 -5
  129. package/templates/nuxt/composables/goTo.generate.ts.eta +14 -1
  130. package/templates/nuxt/composables/graphquery.generate.ts.eta +20 -2
  131. package/templates/nuxt/composables/recently.generate.ts.eta +16 -0
  132. package/templates/nuxt/composables/roles.generate.ts.eta +8 -13
  133. package/templates/nuxt/composables/stringHelper.generate.ts.eta +54 -1
  134. package/templates/nuxt/composables/sysmessage.generate.ts.eta +1 -1
  135. package/templates/nuxt/pages/[xorg]/docnoformat.vue.eta +1 -1
  136. package/templates/nuxt/pages/[xorg]/mobile/docnoformat/{index.vue.eta → index.vue.etaxxx} +1 -1
  137. package/templates/nuxt/pages/[xorg]/mobile/user/{index.vue.eta → index.vue.etaxxx} +1 -1
  138. package/templates/nuxt/pages/[xorg]/{organization.vue.eta → organization.vue._eta} +39 -10
  139. package/templates/nuxt/pages/[xorg]/profile.vue.eta +1 -1
  140. package/templates/nuxt/pages/[xorg]/user.vue.eta +13 -10
  141. package/templates/nuxt/pages/login.vue._eta +4 -1
  142. package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +4 -0
  143. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +45 -26
  144. package/templates/nuxt/plugins/70.recently.ts.eta +55 -0
  145. package/templates/nuxt/providers/my-provider.ts.eta +22 -0
  146. package/templates/nuxt/server/api/[xorg]/{[...].ts.eta → [...].ts._eta} +47 -21
  147. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +44 -3
  148. package/templates/nuxt/types/events.ts.eta +3 -2
  149. package/templates/nuxt/types/others.ts.eta +11 -1
  150. package/templates/nuxt/types/schema.ts.eta +3 -1
  151. package/templates/nuxt/types/simpleappinput.ts.eta +1 -1
  152. package/templates/nuxt/types/user.ts.eta +8 -7
  153. package/templates/project/jsonschemas/branch.json._eta +1 -0
  154. package/templates/project/jsonschemas/invoice.json._eta +4 -3
  155. package/templates/project/jsonschemas/organization.json._eta +2 -2
  156. package/templates/project/lang/default._json +5 -1
  157. package/tsconfig.tsbuildinfo +1 -1
  158. package/templates/nuxt/components/image/ImageAvatar.vue.eta.vue +0 -38
  159. /package/templates/nuxt/pages/[xorg]/mobile/{index.vue._eta → index.vue._etaxxx} +0 -0
  160. /package/templates/nuxt/pages/[xorg]/mobile/organization/{[id].vue._eta → [id].vue._etaxxx} +0 -0
  161. /package/templates/nuxt/pages/[xorg]/mobile/{pickgroup.vue._eta → pickgroup.vue._etaxxx} +0 -0
@@ -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;
@@ -6,10 +6,15 @@
6
6
  :sub-title-field="uniqueKey"
7
7
  #default="{ item, index }"
8
8
  >
9
- <div class="cursor-pointer flex flex-row gap-2" @click="emits('click', item)">
10
- <slot name="default" :index="index" :item="item">
11
- <TextTitle class="flex-1">{{ item[(documentTitle as keyof typeof item) ] }}</TextTitle>
12
- <TextSubtitle >{{ item[uniqueKey as keyof typeof item] }}</TextSubtitle>
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
- <span class="p-input-icon-left flex-1">
33
- <i class="pi pi-search mt-4 ml-2 text-gray-400 absolute" />
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-right"
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,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
- <InputGroupAddon v-if="filter">
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
- <ButtonDefault @click="showMoreFilter" v-if="Object.keys(filter)==0">
8
- <i class="pi pi-filter"></i>
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
- <Dialog v-model:visible="visibleMoreFilter" :header="t('filter')">
93
- <slot name="filter">
94
- define filter in #filter
95
- </slot>
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"/> <span class="mr-1">{{t('clear')}}</span>
122
+ <i class="pi pi-times mr-1" />
123
+ <span class="mr-1">{{ t("clear") }}</span>
100
124
  </ButtonDefault>
101
- <ButtonPrimary @click="runFilter" class="flex flex-row p-2">
102
- <i class="pi pi-filter mr-1"/> <span class="mr-1">{{t('ok')}}</span>
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?:Object;
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) == "/") return `${props.url}${item[props.idField]}`;
151
- 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}`;
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
- return (
163
- String(item[props.titleField ?? ""])
164
- .toLowerCase()
165
- .includes(searchvalue.value.toLowerCase()) ||
166
- String(item[props.subTitleField ?? ""])
167
- .toLowerCase()
168
- .includes(searchvalue.value.toLowerCase())
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('clearFilter')
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('runFilter')
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="bg-gray-800 text-white">
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<{ closeEventName: string }>();
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
- modal
7
- :show-close-icon="false"
6
+ :dismissable="dismissable"
7
+ modal
8
8
  #container
9
- >
10
- <div class="overflow-y-scroll">
11
- <slot name="default"></slot>
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<{ closeEventName: string }>();
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
- <Sidebar
3
- position="bottom"
2
+ <Dialog
4
3
  v-if="showDialog"
5
4
  v-model:visible="showDialog"
6
- modal
5
+ maximizable
6
+ :dismissable="false"
7
7
  :show-close-icon="false"
8
- #container
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
- <div class="overflow-y-scroll">
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
- </Sidebar>
23
+ </Dialog>
14
24
  </template>
15
25
  <script lang="ts" setup>
16
26
  /**