@simitgroup/simpleapp-generator 1.6.4-e-alpha → 1.6.4-f-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 (36) hide show
  1. package/dist/buildinschemas/index.d.ts +0 -1
  2. package/dist/buildinschemas/index.d.ts.map +1 -1
  3. package/dist/buildinschemas/index.js +1 -3
  4. package/dist/buildinschemas/index.js.map +1 -1
  5. package/dist/buildinschemas/systemmessage.js +3 -3
  6. package/dist/buildinschemas/systemmessage.js.map +1 -1
  7. package/dist/buildinschemas/user.d.ts.map +1 -1
  8. package/dist/buildinschemas/user.js +7 -0
  9. package/dist/buildinschemas/user.js.map +1 -1
  10. package/dist/buildinschemas/webhook.d.ts.map +1 -1
  11. package/dist/buildinschemas/webhook.js +20 -5
  12. package/dist/buildinschemas/webhook.js.map +1 -1
  13. package/package.json +1 -1
  14. package/src/buildinschemas/index.ts +0 -1
  15. package/src/buildinschemas/systemmessage.ts +3 -3
  16. package/src/buildinschemas/user.ts +7 -0
  17. package/src/buildinschemas/webhook.ts +21 -7
  18. package/templates/nest/.env._eta +5 -0
  19. package/templates/nest/src/simpleapp/generate/commons/audittrail.service.ts.eta +31 -26
  20. package/templates/nest/src/simpleapp/generate/commons/dicts/documents.ts.eta +2 -1
  21. package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +161 -29
  22. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +4 -6
  23. package/templates/nest/src/simpleapp/generate/processors/webhook.processor.ts.eta +224 -0
  24. package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +113 -110
  25. package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +47 -13
  26. package/templates/nuxt/components/image/ImageToBase64Uploader.vue.eta.vue +5 -5
  27. package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +8 -5
  28. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +25 -18
  29. package/templates/nuxt/composables/stringHelper.generate.ts.eta +13 -9
  30. package/templates/nuxt/pages/profile.vue.eta +3 -1
  31. package/templates/nuxt/server/api/profile/[...].ts.eta +11 -2
  32. package/templates/nuxt/simpleapp/generate/commons/documents.ts.eta +3 -1
  33. package/templates/nuxt/types/others.ts.eta +1 -0
  34. package/templates/nuxt/types/simpleappinput.ts.eta +2 -1
  35. package/tsconfig.tsbuildinfo +1 -1
  36. package/src/buildinschemas/webhookhistory.ts +0 -42
@@ -0,0 +1,224 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR
4
+ * last change 2024-02-23
5
+ * Author: Ks Tan
6
+ */
7
+ import { UserContext } from '../commons/user.context';
8
+ import * as sharelibs from '../sharelibs';
9
+ import { Injectable, InternalServerErrorException, } from '@nestjs/common';
10
+ import { InjectModel } from '@nestjs/mongoose';
11
+ import * as jsonpath from 'jsonpath';
12
+ import { Model } from 'mongoose';
13
+ import { WebhookJsonSchema } from '../jsonschemas/webhook.jsonschema';
14
+ import { SimpleAppService } from './simpleapp.processor';
15
+ import * as types from '../types';
16
+ import { DocNumberFormatGenerator } from '../commons/docnogenerator.service';
17
+ import {
18
+ WebhookBasicAuth,
19
+ WebhookHeaders,
20
+ Webhook,
21
+ } from '../types/webhook.type';
22
+ import {
23
+ DefaultWebhookBasicAuth,
24
+ DefaultWebhookHeaders,
25
+ DefaultWebhook,
26
+ } from '../defaults/webhook.default';
27
+
28
+ @Injectable()
29
+ export class WebhookProcessor extends SimpleAppService<Webhook> {
30
+ protected documentIdentityCode = 'title';
31
+ protected documentIdentityLabel = 'title';
32
+ private webhookApiKey = process.env.WEBHOOK_SERVER_APIKEY
33
+ private webhookAppId=process.env.WEBHOOK_SERVER_APP_ID
34
+ private webhookurl = process.env.WEBHOOK_SERVER_URL;
35
+ private webhookprefix = process.env.PROJECT_CODE+'.'
36
+ private webhooksubscribtionurl = `${process.env.WEBHOOK_SERVER_URL}/subscriptions/`;
37
+
38
+ protected hooks: types.WebhookHooks = {
39
+ beforeCreate: async (appuser: UserContext, data: types.Webhook) =>
40
+ this.beforeCreate(appuser, data),
41
+ beforeUpdate: async (
42
+ appuser: UserContext,
43
+ id: string,
44
+ prevdata: types.Webhook,
45
+ newdata: types.Webhook,
46
+ ) => this.beforeUpdate(appuser, id, prevdata, newdata),
47
+ afterDelete: async (
48
+ appuser: UserContext,
49
+ result: types.DeleteResultType<types.Webhook>,
50
+ id: string,
51
+ ) => this.afterDelete(appuser, result, id),
52
+ };
53
+
54
+
55
+ protected foreignkeys = {};
56
+ constructor(mydoc: Model<Webhook>) {
57
+ super('WEBHOOK', 'webhook', mydoc, types.IsolationType.tenant);
58
+ this.setSchema(WebhookJsonSchema);
59
+ this.setData(DefaultWebhook(crypto.randomUUID()));
60
+ }
61
+
62
+ reCalculateValue(data: Webhook) {
63
+ //console.log('trigger new recalculate')
64
+ const $data = data;
65
+ const jsopbj = new jsonpath['JSONPath']();
66
+ }
67
+
68
+ async beforeCreate(appuser: UserContext, data: types.Webhook) {
69
+ const createResult = await this.addRemoteWebhook(appuser, data);
70
+ if (!createResult['subscription_id'])
71
+ throw new InternalServerErrorException(
72
+ 'syncronize webhook server failed',
73
+ );
74
+ data.serverSubscriptionId = createResult.subscription_id;
75
+ data.serverSubscriptionSecret = createResult.secret;
76
+ // throw new BadRequestException("fail purposely")
77
+ }
78
+
79
+ async beforeUpdate(
80
+ appuser: UserContext,
81
+ id: string,
82
+ prevdata: types.Webhook,
83
+ newdata: types.Webhook,
84
+ ) {
85
+
86
+ if(!prevdata.serverSubscriptionId){
87
+ const createResult = await this.addRemoteWebhook(appuser, newdata);
88
+ if (!createResult['subscription_id'])
89
+ throw new InternalServerErrorException(
90
+ 'syncronize webhook server failed',
91
+ );
92
+ newdata.serverSubscriptionId = createResult.subscription_id;
93
+ newdata.serverSubscriptionSecret = createResult.secret;
94
+ }else{
95
+ await this.updateRemoteWebhook(appuser,newdata)
96
+ }
97
+ }
98
+
99
+ async afterDelete(
100
+ appuser: UserContext,
101
+ result: types.DeleteResultType<types.Webhook>,
102
+ id: string,
103
+ ) {
104
+ await this.removeRemoteWebhook(appuser,result,id)
105
+ }
106
+
107
+ async removeRemoteWebhook(
108
+ appuser: UserContext,
109
+ result: types.DeleteResultType<types.Webhook>,
110
+ id: string,
111
+ ){
112
+ const options = {
113
+ method: 'DELETE',
114
+ headers: {Authorization: this.webhookApiKey}
115
+ };
116
+
117
+
118
+ const subscriptionId=result.data.serverSubscriptionId
119
+ if(!subscriptionId)return
120
+
121
+ try{
122
+ const res = await fetch(
123
+ `${this.webhooksubscribtionurl}/${subscriptionId}?application_id=${this.webhookAppId}`,
124
+ options)
125
+ }catch(e){
126
+ throw new InternalServerErrorException(e)
127
+ }
128
+
129
+ }
130
+ async addRemoteWebhook(appuser: UserContext, data: types.Webhook) {
131
+ const headers = {};
132
+ data.headers.forEach((h) => {
133
+ headers[h.name] = h.value;
134
+ });
135
+
136
+ const options = {
137
+ method: 'POST',
138
+ headers: {
139
+ Authorization: this.webhookApiKey,
140
+ accept: 'application/json',
141
+ 'content-type': 'application/json',
142
+ },
143
+ body: JSON.stringify({
144
+ application_id: this.webhookAppId,
145
+ description: data.title,
146
+ metadata: {
147
+ tenantId: data.tenantId.toString(),
148
+ creator: appuser.getUname(),
149
+ },
150
+ is_enabled: data.active,
151
+ event_types: data.eventTypes.map(
152
+ (item) => this.webhookprefix + item,
153
+ ),
154
+ label_key: 'tenantId',
155
+ label_value: data.tenantId.toString(),
156
+ target: {
157
+ headers: headers,
158
+ type: 'http',
159
+ method: data.requestMethod.toUpperCase(),
160
+ url: data.url,
161
+ },
162
+ }),
163
+ };
164
+ try {
165
+ const res = await fetch(this.webhooksubscribtionurl, options);
166
+ return await res.json();
167
+ if (res.status >= 300) {
168
+ this.logger.error(res.statusText, 'create webhook failed');
169
+ throw new InternalServerErrorException('create webhook failed');
170
+ }
171
+ } catch (e) {
172
+ throw new InternalServerErrorException(e);
173
+ }
174
+ }
175
+
176
+ async updateRemoteWebhook(appuser: UserContext, data: types.Webhook) {
177
+ const headers = {};
178
+ data.headers.forEach((h) => {
179
+ headers[h.name] = h.value;
180
+ });
181
+
182
+ const options = {
183
+ method: 'PUT',
184
+ headers: {
185
+ Authorization: this.webhookApiKey,
186
+ accept: 'application/json',
187
+ 'content-type': 'application/json',
188
+ },
189
+ body: JSON.stringify({
190
+ application_id: this.webhookAppId,
191
+ description: data.title,
192
+ metadata: {
193
+ tenantId: data.tenantId.toString(),
194
+ creator: appuser.getUname(),
195
+ },
196
+ is_enabled: data.active,
197
+ event_types: data.eventTypes.map(
198
+ (item) => this.webhookprefix + item,
199
+ ),
200
+ label_key: 'tenantId',
201
+ label_value: data.tenantId.toString(),
202
+ target: {
203
+ headers: headers,
204
+ type: 'http',
205
+ method: data.requestMethod.toUpperCase(),
206
+ url: data.url,
207
+ },
208
+ }),
209
+ };
210
+ try {
211
+ const subscriptionId = data.serverSubscriptionId
212
+ const res = await fetch(`${this.webhooksubscribtionurl}/${subscriptionId}`, options);
213
+ return await res.json();
214
+ if (res.status >= 300) {
215
+ this.logger.error(res.statusText, 'updateRemoteWebhook webhook failed');
216
+ throw new InternalServerErrorException('update webhook failed');
217
+ }
218
+ } catch (e) {
219
+ throw new InternalServerErrorException(e);
220
+ }
221
+ }
222
+
223
+ /***************************** additional execute *****************************************/
224
+ }
@@ -1,129 +1,132 @@
1
- <template>
2
- <ClientOnly>
3
- <VueCal
4
- :id="id"
5
- class="w-full"
6
- hide-view-selector
7
- click-to-navigate
8
- :time="false"
9
- today-button
10
- active-view="month"
11
- :disable-views="['week', 'day']"
12
- :selected-date="selectedDate"
13
- events-count-on-year-view
14
- @view-change="viewChange"
15
- :events="allevents"
16
- @cell-focus="chooseDate"
17
- xsmall
18
- >
19
- <template #today-button>
20
- <!-- Using Vuetify (but we prefer Wave UI 🤘) -->
21
- <div @click="chooseDate(new Date(), true)">{{ t("today") }}</div>
22
- </template>
23
- <template #cell-content="{ cell, events }">
24
- <div>
25
- <div>
26
- <s
27
- v-if="isHoliday(cell.formattedDate)"
28
- v-tooltip="getHolidayName(new Date(cell.formattedDate))"
29
- class="text text-red-400 dark:text-red-400 font-bold"
30
- >{{ cell.content }}</s
31
- >
32
- <div v-else-if="isOffDay(cell)" class="text-gray-400">
33
- <s v-tooltip="t('offDay')">{{ cell.content }}</s>
34
- </div>
35
- <span v-else>{{ cell.content }} </span>
36
- </div>
1
+ <template>
2
+ <Calendar
3
+ v-model="selectedDate"
4
+ inline
5
+ @update:modelValue="chooseDate"
6
+ :pt="{root:{class:'w-full'}}"
7
+ @month-change="viewChange"
8
+ @year-change="viewChange"
9
+ class="smallcalendar">
10
+ <template #footer>
11
+ <div class="p-2 flex flex-row justify-between">
12
+ <ButtonPrimary @click="goToday()">{{ t('today') }}</ButtonPrimary>
13
+ <TextSubsubtitle class="text-right"
14
+ >{{ items.length }} {{ t("records") }}</TextSubsubtitle>
37
15
 
38
- <div>
39
- <slot name="default" :cell="cell" :events="events">
16
+ </div>
17
+ </template>
18
+ <template #date="{date}">
19
+ <div class="flex flex-col text-center" >
20
+ <s v-if="isHoliday(date)" class="text-red-600">
21
+ {{ date.day }}
22
+ </s>
23
+ <span v-else-if="isOffDay(date)" class="text-gray-400">
24
+ {{ date.day }}
25
+ </span>
26
+ <template v-else>
27
+ {{ date.day }}
28
+ </template>
40
29
  <Badge
41
- v-if="events.length > 0"
42
- @contextmenu="
43
- (mouseevent) => onRightClickDate(mouseevent, cell)
44
- "
45
- severity="info"
46
- :value="events.length"
30
+ v-if="getEventQty(date) > 0"
31
+ severity="info"
32
+ :value="getEventQty(date)"
47
33
  />
48
- </slot>
49
34
  </div>
50
- </div>
51
35
  </template>
52
- </VueCal>
53
- </ClientOnly>
36
+ </Calendar>
54
37
  </template>
55
- <script lang="ts" setup generic="T">
56
- /**
57
- * This file was automatically generated by simpleapp generator during initialization.
58
- * IT IS NOT CHANGABLE
59
- * last change 2024-02-22
60
- * author: Ks Tan
61
- */
62
- //, { Event, SplitDaysAttributes }
63
- import VueCal from "vue-cal";
64
- import "vue-cal/dist/vuecal.css";
38
+ <script setup lang="ts" generic="T">
39
+ import { CalendarDateSlotOptions,CalendarMonthChangeEvent } from "primevue/calendar";
40
+
65
41
  import {
66
- CalEventType,
67
- CalRightClickEvent,
68
- OffDay,
69
- CalViewChange,
42
+ CalEventType,
43
+ CalRightClickEvent,
44
+ OffDay,
45
+ CalViewChange,
70
46
  } from "~/types";
71
- const viewStatus = ref<CalViewChange>();
47
+
72
48
  const props = defineProps<{
73
- id: string;
74
- items: CalEventType<T>[];
75
- holidays: OffDay[];
49
+ id: string;
50
+ items: CalEventType<T>[];
51
+ holidays: OffDay[];
76
52
  }>();
77
- const offdays = ref<string[]>([]);
78
- const emits = defineEmits(["chooseDate", "rightClick","viewChange"]);
79
- // const allholidays = computed(() => props.holidays.map((item) => item.date));
53
+ const emits = defineEmits(["chooseDate", "viewChange"]);
54
+
55
+
80
56
  const selectedDate = defineModel<Date>({ required: true });
81
- const getHolidayName = (date: Date) =>
82
- props.holidays.find((item) => item.date.getTime() == date.getTime())?.title;
83
- const allevents = computed(() => {
84
- const list = props.items.map((item) => {
85
- if (item.start instanceof Date)
86
- item.start = item.start.format("YYYY-MM-DD HH:mm");
87
- else if (typeof item.start == "string") {
88
- item.start = item.start.substring(0, 16).replace("T", " ");
89
- }
90
- if (item.end instanceof Date)
91
- item.end = item.end.format("YYYY-MM-DD HH:mm");
92
- else if (typeof item.end == "string") {
93
- item.end = item.end.substring(0, 16).replace("T", " ");
94
- }
95
- return item;
96
- });
97
- return list;
98
- });
99
- const viewChange = (event: CalViewChange) => {
100
- viewStatus.value = event;
101
- emits('viewChange',event)
102
- };
57
+ const offdays = ref<string[]>([]);
58
+ type DateType = {
59
+ day: number
60
+ month : number
61
+ otherMonth: boolean
62
+ selectable : boolean
63
+ today : boolean
64
+ year: number
65
+ }
103
66
 
104
- const isHoliday = (datestr: string) => {
105
- return props.holidays.find(
106
- (item) => item.date.format("YYYY-MM-DD") == datestr,
107
- );
108
- };
109
- const isOffDay = (cell: any) => {
110
- const dayname: string = new Date(cell.formattedDate)
111
- .toLocaleString("en", { weekday: "short" })
112
- .toLowerCase();
113
- if (offdays.value.includes(dayname)) return true;
114
- else return false;
115
- };
116
- const chooseDate = (date1: Date, force?: boolean) => {
117
- if (force || !viewStatus.value || viewStatus.value.view == "month") {
118
- selectedDate.value = date1;
119
- emits("chooseDate", date1);
67
+ const disableDays=computed(()=>{
68
+ return offdays.value.map(item=>{
69
+ if(item=='sun')return 0
70
+ else if(item=='mon')return 1
71
+ else if(item=='tue')return 2
72
+ else if(item=='wed')return 3
73
+ else if(item=='thu')return 4
74
+ else if(item=='fri')return 5
75
+ else if(item=='sat')return 6
76
+ })
77
+ })
78
+
79
+ function isHoliday(date:CalendarDateSlotOptions){
80
+
81
+ for(let i = 0 ; i<props.holidays.length;i++){
82
+ const item = props.holidays[i]
83
+ const currenyday = getDayJs()(item.date).date()
84
+ const currentmonth = getDayJs()(item.date).month()
85
+ const currentyear = getDayJs()(item.date).year()
86
+ if(currenyday==date.day && currentmonth==date.month && currentyear==date.year){
87
+ return true
88
+ }
120
89
  }
90
+ return false
91
+ }
92
+ function goToday(){
93
+ selectedDate.value= new Date(today())
94
+ chooseDate(new Date(today()))
95
+ }
96
+ function chooseDate(date: string | string[] | Date | Date[] | undefined){
97
+ emits('chooseDate',date)
98
+ }
99
+
100
+ const isOffDay = (date:CalendarDateSlotOptions) => {
101
+ const dayname: string = new Date(date.year,date.month, date.day)
102
+
103
+ .toLocaleString("en", { weekday: "short" })
104
+ .toLowerCase();
105
+ if (offdays.value.includes(dayname)) return true;
106
+ else return false;
121
107
  };
122
- const onRightClickDate = (e: MouseEvent, cell: CalRightClickEvent) => {
123
- emits("rightClick", e, cell);
108
+
109
+ const getEventQty = (date:CalendarDateSlotOptions)=>{
110
+ const checkdate = dateToISOWithoutConvert(new Date(date.year,date.month, date.day)).substring(0,10)
111
+ const recordlength = props.items.filter(item=>item.start==checkdate).length
112
+ return recordlength
113
+ }
114
+ const viewChange = (event: CalendarMonthChangeEvent) => {
115
+ emits("viewChange", event);
124
116
  };
125
117
 
118
+
126
119
  onMounted(() => {
127
- offdays.value = getCurrentBranch()?.branch.offdays ?? [];
120
+ offdays.value = getCurrentBranch()?.branch.offdays ?? [];
128
121
  });
129
122
  </script>
123
+ <style >
124
+ .smallcalendar td {
125
+ height: 3rem;
126
+ border: solid 1px #ccc;
127
+ }
128
+ .smallcalendar .p-datepicker table td > span {
129
+ widows: initial !important;
130
+ height: initial !important;
131
+ }
132
+ </style>
@@ -1,23 +1,57 @@
1
1
  <template>
2
- <div :class="`inline-block border rounded-lg w-${size} h-${size} bg-white`">
3
- <Avatar
4
- :image="getAvatarLink(<string>id, size*3)"
5
- shape="circle"
2
+ <ImageToBase64Uploader
3
+ v-if="changable"
4
+ #default
5
+ :class="`w-${sizenumber} h-${sizenumber} place-content-center bg-white`"
6
+ @image-uploaded="handleBase64"
7
+ >
8
+ <NuxtImg
6
9
  class="w-full h-full"
10
+ :key="imageKey"
11
+ :src="imagepath"
7
12
  />
8
-
9
-
13
+ </ImageToBase64Uploader>
14
+ <div
15
+ v-else
16
+ :class="`inline-block border rounded-lg w-${sizenumber} h-${sizenumber} bg-white text-black`"
17
+ >
18
+ <NuxtImg class="w-full h-full" :src="imagepath" />
10
19
  </div>
11
20
  </template>
12
21
  <script lang="ts" setup>
13
- /**
14
- * This file was automatically generated by simpleapp generator during initialization.
15
- * --remove-this-line-to-prevent-override--
16
- * last change 2024-04-06
17
- * author: Ks Tan
18
- */
22
+ // import {KeyValue} from ''
19
23
  const props = defineProps<{
20
- id?: string;
24
+ changable?: boolean;
25
+ uid?: string;
21
26
  size: number;
22
27
  }>();
28
+ const imageKey = ref(0);
29
+ const uid = computed(
30
+ () => props.uid ?? getUserProfile()?.uid,
31
+ );
32
+ // const xorgpath = getCurrentXorg() ? `${getCurrentXorg()}/` : "MC0wLTA/";
33
+
34
+ const sizenumber = props.size ?? 16;
35
+ const imagepath = getAvatarByUid(uid.value,sizenumber) //`${xorgpath}images/organization/${orgRecordId.value}`;
36
+ const imageData = ref("");
37
+ watch(
38
+ uid,
39
+ () => imageKey.value++,
40
+ );
41
+ const handleBase64 = async (data: string) => {
42
+ // const keyvalue = {
43
+ // key: "org-" + props.orgRecordId,
44
+ // value: data,
45
+ // };
46
+ // console.log("upload logo ", data);
47
+ // const uploadok = await useNuxtApp()
48
+ // .$OrganizationDoc()
49
+ // .getApi()
50
+ // .runUploadlogo(keyvalue);
51
+ // if (uploadok) {
52
+ // const realpath = `/api/${imagepath}`;
53
+ // await fetch(realpath, { cache: "reload", credentials: "include" });
54
+ // imageKey.value++;
55
+ // }
56
+ };
23
57
  </script>
@@ -2,7 +2,7 @@
2
2
  <div
3
3
  @click="openUploadDialog"
4
4
  :title="selectedBase64Img"
5
- class="vvv place-content-center image-to-base64-uploader rounded-lg border block"
5
+ class="place-content-center image-to-base64-uploader rounded-lg border block"
6
6
  >
7
7
  <ClientOnly>
8
8
  <slot name="default">
@@ -11,10 +11,10 @@
11
11
  </slot>
12
12
 
13
13
  <Dialog
14
- v-if="dialogVisible"
14
+ v-if="dialogVisible" modal
15
15
  v-model:visible="dialogVisible"
16
16
  header="Image Upload"
17
- :pt="{ root: { class: 'w-4/5' } }"
17
+ :pt="{ root: { class: 'w-11/12' } }"
18
18
  >
19
19
  <div class="w-full grid grid-cols-2 gap-2">
20
20
  <div class="w-7/8 border rounded p-4">
@@ -96,8 +96,8 @@ const handleImageUpload = (event) => {
96
96
  reader.onload = (e) => {
97
97
  const img = new Image();
98
98
  img.onload = () => {
99
- const maxWidth = 400; // Set your desired maximum width
100
- const maxHeight = 300; // Set your desired maximum height
99
+ const maxWidth = 800; // Set your desired maximum width
100
+ const maxHeight = 600; // Set your desired maximum height
101
101
  const scale = Math.min(maxWidth / img.width, maxHeight / img.height);
102
102
  const scaledWidth = img.width * scale;
103
103
  const scaledHeight = img.height * scale;
@@ -1,16 +1,19 @@
1
1
  <template>
2
2
  <div
3
- class="flex flex-row text-xs cursor-pointer justify-end "
3
+ class="flex flex-row text-xs cursor-pointer justify-end"
4
4
  v-if="data?.updated && data?.updated != ''"
5
5
  @click="viewHistories"
6
6
  >
7
- <ImageAvatar
7
+ <ImageAvatar
8
8
  v-if="data?.updatedBy"
9
9
  :id="data.updatedBy"
10
- :size="8"
10
+ :size="36"
11
11
  ></ImageAvatar>
12
12
  <div class="flex flex-col flex-1">
13
- <TextDocStatus v-if="data?.documentStatus" :docStatus="data?.documentStatus" />
13
+ <TextDocStatus
14
+ v-if="data?.documentStatus"
15
+ :docStatus="data?.documentStatus"
16
+ />
14
17
  <!-- <TextSubsubtitle class="text-gray-400 italic"
15
18
  >{{ t("updated") }}:</TextSubsubtitle
16
19
  > -->
@@ -26,7 +29,7 @@
26
29
  <Timeline :value="events" class="w-full md:w-20rem">
27
30
  <template #opposite="{ item }">
28
31
  <div class="flex flex-row">
29
- <ImageAvatar :email="item.email" :id="item.uid" :size="12" />
32
+ <ImageAvatar :email="item.email" :id="item.uid" />
30
33
  <div class="flex flex-col">
31
34
  <span>{{ item.fullName }}</span>
32
35
  <RendererDateAge