@simitgroup/simpleapp-generator 1.6.4-c-alpha → 1.6.4-e-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 (66) hide show
  1. package/dist/buildinschemas/documentevent.d.ts +3 -0
  2. package/dist/buildinschemas/documentevent.d.ts.map +1 -0
  3. package/dist/buildinschemas/documentevent.js +38 -0
  4. package/dist/buildinschemas/documentevent.js.map +1 -0
  5. package/dist/buildinschemas/index.d.ts +2 -0
  6. package/dist/buildinschemas/index.d.ts.map +1 -1
  7. package/dist/buildinschemas/index.js +5 -1
  8. package/dist/buildinschemas/index.js.map +1 -1
  9. package/dist/buildinschemas/tenant.d.ts.map +1 -1
  10. package/dist/buildinschemas/tenant.js +9 -0
  11. package/dist/buildinschemas/tenant.js.map +1 -1
  12. package/dist/buildinschemas/webhook.d.ts.map +1 -1
  13. package/dist/buildinschemas/webhook.js +21 -3
  14. package/dist/buildinschemas/webhook.js.map +1 -1
  15. package/dist/buildinschemas/webhookhistory.d.ts +3 -0
  16. package/dist/buildinschemas/webhookhistory.d.ts.map +1 -0
  17. package/dist/buildinschemas/webhookhistory.js +44 -0
  18. package/dist/buildinschemas/webhookhistory.js.map +1 -0
  19. package/dist/framework.js +1 -1
  20. package/dist/framework.js.map +1 -1
  21. package/dist/generate.js +1 -1
  22. package/dist/generate.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/buildinschemas/documentevent.ts +36 -0
  25. package/src/buildinschemas/index.ts +3 -1
  26. package/src/buildinschemas/tenant.ts +9 -0
  27. package/src/buildinschemas/webhook.ts +22 -3
  28. package/src/buildinschemas/webhookhistory.ts +42 -0
  29. package/src/framework.ts +1 -1
  30. package/src/generate.ts +1 -1
  31. package/templates/basic/nest/apischema.ts.eta +6 -2
  32. package/templates/basic/nest/controller.ts.eta +4 -3
  33. package/templates/basic/nest/default.ts.eta +6 -5
  34. package/templates/basic/nuxt/default.ts.eta +2 -0
  35. package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +1 -6
  36. package/templates/nest/src/simpleapp/apischemas/index.ts._eta +17 -0
  37. package/templates/nest/src/simpleapp/generate/commons/audittrail.service.ts.eta +37 -7
  38. package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +39 -20
  39. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +60 -41
  40. package/templates/nest/src/simpleapp/generate/controllers/simpleapp.controller.ts.eta +3 -3
  41. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +100 -34
  42. package/templates/nest/src/simpleapp/profile/profile.controller.ts.eta +16 -8
  43. package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +7 -0
  44. package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +3 -3
  45. package/templates/nest/src/simpleapp/types/index.ts._eta +14 -0
  46. package/templates/nuxt/app.vue.eta +9 -7
  47. package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +7 -14
  48. package/templates/nuxt/components/list/ListView.vue.eta +97 -111
  49. package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +102 -42
  50. package/templates/nuxt/components/search/SearchBox.vue._eta +371 -0
  51. package/templates/nuxt/components/search/SearchBoxBefore.vue._eta +11 -0
  52. package/templates/nuxt/components/search/SearchBoxProduct.vue._eta +26 -0
  53. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +24 -3
  54. package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +1 -0
  55. package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +10 -5
  56. package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +4 -3
  57. package/templates/nuxt/components/user/UserTenantPicker.vue.eta +18 -16
  58. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +6 -49
  59. package/templates/nuxt/composables/stringHelper.generate.ts.eta +2 -2
  60. package/templates/nuxt/middleware/30.acl.global.ts.eta +6 -5
  61. package/templates/nuxt/pages/[xorg]/pickgroup.vue._eta +28 -27
  62. package/templates/nuxt/pages/picktenant.vue._eta +3 -3
  63. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +49 -29
  64. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +7 -1
  65. package/templates/nuxt/types/others.ts.eta +7 -1
  66. package/tsconfig.tsbuildinfo +1 -1
@@ -1,15 +1,23 @@
1
- <template>
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>
9
- <div v-if="withFilter" class="flex flex-row p-2">
10
- <InputGroup :pt="{ root: { class: 'p-0' } }">
11
- <InputGroupAddon
12
- v-if="filter !== undefined && Object.keys(filter).length > 0"
1
+ <template>
2
+ <Listbox
3
+ ref="listview"
4
+ :options="filterlist"
5
+ v-model="selectedItem"
6
+ :optionLabel="titleField"
7
+ :filter="withFilter"
8
+ :optionValue="idField"
9
+
10
+ :filterFields="filterFields"
11
+ :pt="{filterContainer:{class:'p-inputgroup'}}"
12
+ >
13
+ <template #empty>
14
+ <slot name="nodata">
15
+ <NodataLarge/>
16
+ </slot>
17
+ </template>
18
+ <template #filtericon="sss">
19
+ <!-- <i class="pi pi-refresh"/> -->
20
+ <InputGroupAddon v-if="filter !== undefined && Object.keys(filter).length > 0"
13
21
  :pt="{
14
22
  root: {
15
23
  class:
@@ -18,20 +26,15 @@
18
26
  }"
19
27
  @click="showMoreFilter"
20
28
  >
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
- />
29
+ </InputGroupAddon>
30
+ <InputGroupAddon
31
+ v-else-if="filter !== undefined"
32
+ :pt="{ root: { class: 'p-0 pi pi-filter cursor-pointer p-3' } }"
33
+ @click="showMoreFilter"
34
+ >
35
+ </InputGroupAddon>
36
+ <slot name="filterInputGroupAddon"></slot>
37
+
35
38
  <InputGroupAddon
36
39
  :pt="{
37
40
  root: {
@@ -42,73 +45,53 @@
42
45
  v-if="withAddNew"
43
46
  @click="emits('add')"
44
47
  >
45
-
46
48
  </InputGroupAddon>
47
- <slot name="inputAddOn"></slot>
48
- </InputGroup>
49
- </div>
50
-
51
- <div
52
- v-if="showIndex"
53
- class="flex flex-col fixed left-1 top-1/5 gap-2 z-10 rounded border bg-white dark:bg-black opacity-90"
54
- >
55
- <NuxtLink
56
- class="text-primary-600 dark:text-primary-400 text-lg p-2"
57
- :url="'#' + l"
58
- v-for="l in allLetters"
59
- >{{ l }}</NuxtLink
60
- >
61
- </div>
49
+ </template>
50
+
51
+ <template #header="{options,value}">
52
+ <div>
53
+ <slot name="header">
54
+ <TextMain class="text-gray-800 pl-2 pt-2">{{ header }}</TextMain>
55
+ </slot>
56
+ <hr class="mt-2" />
57
+ </div>
58
+ </template>
62
59
 
63
- <div v-if="filterlist && filterlist.length > 0">
64
- <div>
65
- <div v-for="(item, index) in filterlist">
66
- <!-- :class="isMobile() ? '' : 'overflow overflow-y-scroll overflow-auto '" -->
67
- <div
68
- :id="titleField && item[titleField] && item[titleField][0]"
69
- ></div>
70
- <div
71
- class="w-full bg-gray-400 dark:bg-gray-500 p-1 pl-2 top-0 sticky opacity-90"
72
- v-if="
73
- showIndex && titleField && showCategoryBar(item[titleField][0])
74
- "
75
- >
76
- <span>{{ item[titleField][0] }}</span>
77
- </div>
60
+ <template #option="{option,index}">
61
+ <div
62
+ :id="titleField && option[titleField] && option[titleField][0]"
63
+ ></div>
64
+ <div
65
+ class="w-full bg-gray-400 dark:bg-gray-500 p-1 pl-2 top-0 sticky opacity-90"
66
+ v-if="
67
+ showIndex && titleField && showCategoryBar(option[titleField][0])
68
+ "
69
+ >
70
+ <span>{{ option[titleField][0] }}</span>
71
+ </div>
72
+ <div class="border-l-none border-r-none listview-item">
73
+ <!-- :to="getUrl(option)" -->
78
74
  <div
79
- @click="onClick(index, item, $event)"
80
- :class="`border-l-none border-r-none listview-item dark:border-t-gray-700 ${
81
- index > 0 ? 'border-t-2' : ''
82
- }`"
75
+
76
+ :class="`p-2 ${showClickEffect ? 'listlink' : ''}`"
83
77
  >
84
- <NuxtLink
85
- :to="getUrl(item)"
86
- :class="`p-2 ${showClickEffect ? 'listlink' : ''}`"
87
- >
88
- <slot name="default" :item="item" :index="index">
89
- <div class="flex flex-row">
90
- <div class="flex-1 mr-2 dark:text-white">
91
- {{ item[titleField ?? ""] }}
92
- </div>
93
- <div class="text-right dark:text-gray-400 text-gray-600">
94
- {{ item[subTitleField ?? ""] }}
95
- </div>
78
+ <slot name="default" :item="option" :index="index">
79
+ <div class="flex flex-row">
80
+ <div class="flex-1 mr-2 dark:text-white">
81
+ {{ option[titleField ?? ""] }}
96
82
  </div>
97
- </slot>
98
- </NuxtLink>
83
+ <div class="text-right dark:text-gray-400 text-gray-600">
84
+ {{ option[subTitleField ?? ""] }}
85
+ </div>
86
+ </div>
87
+ </slot>
99
88
  </div>
100
89
  </div>
101
- </div>
102
- </div>
103
- <div v-else>
104
- <div class="w-full h-20 p-2 border-l-none border-r-none">
105
- <slot name="nodata">
106
- <div class="border-round border-1 surface-border p-4 surface-card">
107
- {{ t("noDataFound") }}
108
- </div>
109
- </slot>
110
- </div>
111
- </div>
90
+ </template>
91
+ </Listbox>
92
+
93
+
94
+
112
95
 
113
96
  <Dialog
114
97
  v-model:visible="visibleMoreFilter"
@@ -129,7 +112,7 @@
129
112
  </div>
130
113
  </template>
131
114
  </Dialog>
132
- </div>
115
+
133
116
  </template>
134
117
  <script setup lang="ts" generic="T extends { [key: string]: any }">
135
118
  /**
@@ -141,8 +124,10 @@
141
124
  import { ref } from "vue";
142
125
  import { ListItem } from "~/types/listview";
143
126
  import _ from "lodash";
127
+ const listview = ref(null)
144
128
  const visibleMoreFilter = ref(false);
145
129
  const listviewfilter = ref();
130
+ const selectedItem = ref('')
146
131
  const props = withDefaults(
147
132
  defineProps<{
148
133
  list: T[];
@@ -150,40 +135,31 @@ const props = withDefaults(
150
135
  urlsuffix?: string;
151
136
  header?: string;
152
137
  titleField?: string;
153
- idField?: string;
138
+ idField: string;
154
139
  subTitleField?: string;
155
140
  withFilter?: boolean;
156
141
  filter?: { [key: string]: any };
157
142
  withAddNew?: boolean;
158
143
  showIndex?: boolean;
159
144
  showClickEffect?: boolean;
145
+
160
146
  }>(),
161
147
  {
162
148
  idField: "_id",
163
149
  },
164
150
  );
151
+ const filterFields=computed(()=>{
152
+ const fields:string[] = []
153
+ if(props.titleField) fields.push(props.titleField)
154
+ if(props.subTitleField) fields.push(props.subTitleField)
155
+ return fields
156
+ })
165
157
  const letters = ref<string[]>([]);
166
158
  let lastchar = "";
167
159
 
168
160
  const emits = defineEmits(["add", "runFilter", "clearFilter", "click"]);
169
161
  const searchvalue = ref("");
170
- const selecteditem = ref("");
171
- const clickRow = (item: ListItem) => {
172
- // emit('clickitem',item)
173
- // selecteditem.value = item.code
174
- };
175
- const getUrl = (item: any) => {
176
- const urlsuffix =
177
- props.urlsuffix === undefined || props.urlsuffix == ""
178
- ? ""
179
- : "/" + props.urlsuffix;
180
- if (props.url && props.idField) {
181
- if (_.last(props.url) == "/")
182
- return `${props.url}${item[props.idField]}${urlsuffix}`;
183
- else return `${props.url}/${item[props.idField]}${urlsuffix}`;
184
- } else return undefined;
185
- // :to="url ? `${url}/${item[idField]}` : undefined"
186
- };
162
+
187
163
  const filterlist = computed(() => {
188
164
  let newlist: T[] = [];
189
165
  if (!Array.isArray(props.list)) {
@@ -236,9 +212,6 @@ const showCategoryBar = (letter: string) => {
236
212
  }
237
213
  };
238
214
 
239
- const onClick = (index: number, data: T, event: Event | MouseEvent) => {
240
- emits("click", index, data, event);
241
- };
242
215
 
243
216
  const showMoreFilter = () => {
244
217
  visibleMoreFilter.value = true;
@@ -251,7 +224,20 @@ const runFilter = () => {
251
224
  visibleMoreFilter.value = false;
252
225
  emits("runFilter");
253
226
  };
254
- onMounted(() => {
255
- // if(props.withFilter) listviewfilter.value.$el.focus()
256
- });
227
+
228
+ watch(selectedItem,(newvalue)=>{
229
+ if(newvalue){
230
+ emits("click",newvalue);
231
+ if(props.url){
232
+ navigateTo(props.url+'/'+newvalue)
233
+ }
234
+
235
+ }
236
+ })
237
+
238
+ function setFocus(){
239
+ const listbodyid = listview.value?.$el?.id
240
+ document.querySelector(`#${listbodyid} .p-listbox-list`)?.focus()
241
+ }
242
+ defineExpose({setFocus})
257
243
  </script>
@@ -1,56 +1,116 @@
1
1
  <template>
2
- <div class="flex flex-row text-xs cursor-pointer"
3
- v-if="data?.updated && data?.updated !=''" @click="viewHistories">
4
- <ImageAvatar v-if="data?.updatedBy" :id="data.updatedBy" :size="12"></ImageAvatar>
5
- <div class="flex flex-col p-2">
6
- <TextDocStatus v-if="data?.docStatus" :docStatus="data?.docStatus" />
7
- <TextSubsubtitle class=" text-gray-400 italic">{{ t('updated') }}:</TextSubsubtitle>
8
- <RendererDateTime :value="data?.updated" class="text-gray-400 italic"/>
2
+ <div
3
+ class="flex flex-row text-xs cursor-pointer justify-end "
4
+ v-if="data?.updated && data?.updated != ''"
5
+ @click="viewHistories"
6
+ >
7
+ <ImageAvatar
8
+ v-if="data?.updatedBy"
9
+ :id="data.updatedBy"
10
+ :size="8"
11
+ ></ImageAvatar>
12
+ <div class="flex flex-col flex-1">
13
+ <TextDocStatus v-if="data?.documentStatus" :docStatus="data?.documentStatus" />
14
+ <!-- <TextSubsubtitle class="text-gray-400 italic"
15
+ >{{ t("updated") }}:</TextSubsubtitle
16
+ > -->
17
+ <RendererDateAge :value="data?.updated" class="text-gray-400 italic" />
9
18
  </div>
10
-
11
19
 
12
- <Dialog v-model:visible="visibleHistories" modal
13
- :header="t('histories')" :pt="{root:{class:'w-1/4'}}">
20
+ <Dialog
21
+ v-model:visible="visibleHistories"
22
+ modal
23
+ :header="t(documentName) + ' ' + t('histories')"
24
+ :pt="{ root: { class: 'w-1/3' } }"
25
+ >
14
26
  <Timeline :value="events" class="w-full md:w-20rem">
15
- <template #opposite="slotProps">
16
- <RendererDateTime class="italic text-gray-400 text-xs" :value="slotProps.item.date"/>
27
+ <template #opposite="{ item }">
28
+ <div class="flex flex-row">
29
+ <ImageAvatar :email="item.email" :id="item.uid" :size="12" />
30
+ <div class="flex flex-col">
31
+ <span>{{ item.fullName }}</span>
32
+ <RendererDateAge
33
+ class="italic text-gray-400 text-xs whitespace-nowrap"
34
+ :value="item.eventDate"
35
+ />
36
+ </div>
37
+ </div>
17
38
  </template>
18
- <template #content="slotProps">
39
+ <template #content="{ item }">
19
40
  <div>
20
- <div>{{ slotProps.item.status }}</div>
21
- </div>
22
-
41
+ <div>{{ item.status }}</div>
42
+ </div>
23
43
  </template>
24
- </Timeline>
44
+ </Timeline>
25
45
  </Dialog>
26
46
  </div>
27
-
28
47
  </template>
29
48
  <script lang="ts" setup>
30
- import TextSubsubtitle from '../text/TextSubsubtitle.vue';
31
- import RendererDateTime from './RendererDateTime.vue';
32
- const visibleHistories = ref(false)
33
- const props=defineProps<{data:any}>()
34
- const events = computed(()=>{
35
- const list = [{ status: t('created'), date: props.data.created },]
36
-
37
- if(props.data.updated != props.data.created){
38
- list.push({ status: t('paidFeature'), date:''})
39
- list.push( { status: t('lastUpdate'), date: props.data.updated })
40
- }
41
- return list
42
- })
43
- const severity = computed(()=>{
44
- const stat = props.data.docStatus
45
- if(props.data.docStatus=='confirm') return "success"
46
- else if(props.data.docStatus=='void') return "danger"
47
- else if(props.data.docStatus=='draft') return "secondary"
48
- else return "warning"
49
- })
50
-
49
+ import TextSubsubtitle from "../text/TextSubsubtitle.vue";
50
+ import RendererDateTime from "./RendererDateTime.vue";
51
+ import { Documentevent, User } from "~/simpleapp/generate/openapi";
52
+ const eventDoc = useNuxtApp().$DocumenteventDoc();
53
+ const visibleHistories = ref(false);
54
+ const props = defineProps<{ data: any; documentName: string }>();
55
+ type EventHistory = {
56
+ status: string;
57
+ eventDate: string;
58
+ uid?: string;
59
+ fullName?: string;
60
+ email?: string;
61
+ };
62
+ const events = ref<EventHistory[]>([]);
63
+ const getEvents = async () => {
64
+ const simplelog = [
65
+ {
66
+ status: t("created"),
67
+ eventDate: props.data.created,
68
+ uid: props.data.createdBy,
69
+ },
70
+ ];
71
+ if (props.data.updated != props.data.created) {
72
+ simplelog.push({
73
+ status: t("lastUpdate"),
74
+ eventDate: props.data.updated,
75
+ uid: props.data.updatedBy,
76
+ });
77
+ }
51
78
 
52
- const viewHistories = () =>{
53
- visibleHistories.value=true
54
- console.log("histories")
79
+ // events.value=[];
80
+ // console.log("Renderer getEvents histories");
81
+ const list: (Documentevent & { _user: User })[] = await eventDoc.search({
82
+ filter: {
83
+ documentName: props.documentName,
84
+ documentId: props.data._id,
85
+ },
86
+ fields: ["created", "createdBy", "eventType"],
87
+ sorts: [["created", "asc"]],
88
+ lookup: { "user.uid": "createdBy" },
89
+ });
90
+ if (list.length > 0) {
91
+ events.value = list.map((item) => ({
92
+ _id: <string>item._id,
93
+ status: t(<string>item.eventType),
94
+ eventDate: <string>item.created,
95
+ uid: <string>item.createdBy,
96
+ fullName: <string>item._user.fullName,
97
+ email: <string>item._user.email,
98
+ }));
99
+ } else {
100
+ events.value = simplelog;
55
101
  }
102
+ };
103
+ const severity = computed(() => {
104
+ const stat = props.data.docStatus;
105
+ if (props.data.docStatus == "confirm") return "success";
106
+ else if (props.data.docStatus == "void") return "danger";
107
+ else if (props.data.docStatus == "draft") return "secondary";
108
+ else return "warning";
109
+ });
110
+
111
+ const viewHistories = async () => {
112
+ visibleHistories.value = true;
113
+ await getEvents();
114
+ // console.log("histories");
115
+ };
56
116
  </script>