@simitgroup/simpleapp-generator 1.6.4-c-alpha → 1.6.4-d-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 (65) 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 +8 -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 +8 -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 +53 -39
  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.service.ts.eta +5 -0
  43. package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +3 -3
  44. package/templates/nest/src/simpleapp/types/index.ts._eta +14 -0
  45. package/templates/nuxt/app.vue.eta +9 -7
  46. package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +7 -14
  47. package/templates/nuxt/components/list/ListView.vue.eta +97 -111
  48. package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +102 -42
  49. package/templates/nuxt/components/search/SearchBox.vue._eta +371 -0
  50. package/templates/nuxt/components/search/SearchBoxBefore.vue._eta +11 -0
  51. package/templates/nuxt/components/search/SearchBoxProduct.vue._eta +26 -0
  52. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +24 -3
  53. package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +1 -0
  54. package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +10 -5
  55. package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +4 -3
  56. package/templates/nuxt/components/user/UserTenantPicker.vue.eta +18 -16
  57. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +6 -49
  58. package/templates/nuxt/composables/stringHelper.generate.ts.eta +2 -2
  59. package/templates/nuxt/middleware/30.acl.global.ts.eta +6 -5
  60. package/templates/nuxt/pages/[xorg]/pickgroup.vue._eta +28 -27
  61. package/templates/nuxt/pages/picktenant.vue._eta +3 -3
  62. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +49 -29
  63. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +7 -1
  64. package/templates/nuxt/types/others.ts.eta +7 -1
  65. package/tsconfig.tsbuildinfo +1 -1
@@ -28,21 +28,22 @@ export const Default<%=modelname%> = (uuid:string)=>{
28
28
  <%}else if(key=='doctype'){ %>
29
29
  doctype : '<%=it.doctype.toUpperCase()%>',
30
30
  <% } else if(typeof field.default !='undefined' && field.type=='string'){%>
31
- <%=key%> : '<%= field.default %>',
32
- <%} else if(typeof field.default !='undefined'){%>
33
- <%=key%> : <%= field.default %>,
31
+ <%=key%> : '<%= field.default %>',
32
+ <%} else if(typeof field.default !='undefined' && JSON.stringify(field.default)=='{}'){%>
33
+ // <%=key%> : <%~ JSON.stringify(field.default) %>,
34
+ <%} else if(typeof field.default !='undefined'){%>
35
+ <%=key%> : <%= field.default %>,
34
36
  <%} else if(field.type=='boolean' ){%>
35
37
  <%=key%> :false ,
36
38
  <%} else if(typeof field=='string'){%>
37
39
  <%=key%> : Default<%= field %>(''),
38
40
  <%} else if(field.type=='string'){%>
39
41
  <%=key%> : '<%= field.default %>',
40
-
41
42
  <%} else if(Array.isArray(field) && ['string','integer','number','boolean'].includes(field[0])) {%>
42
43
  <%=key%> : <<%=field[0]%>[]>[], //typeof field == array <%~JSON.stringify(field)%>
43
44
  <%} else if(Array.isArray(field)) {%>
44
45
  <%=key%> : [Default<%=field[0]%>(crypto.randomUUID())], //typeof field == array <%~JSON.stringify(field)%>
45
- <%} else {%>
46
+ <%} else {%>
46
47
  <%=key%> : <%=field.default%>, //else <%= typeof field %>
47
48
  <%}%>
48
49
  <%})%>
@@ -27,6 +27,8 @@ export const Default<%=modelname%> = (uuid:string)=>{
27
27
  orgId : getUserProfile()?.orgId,
28
28
  <%}else if(key=='branchId'){ %>
29
29
  branchId : getUserProfile()?.branchId,
30
+ <%} else if(typeof field.default !='undefined' && JSON.stringify(field.default)=='{}'){%>
31
+ //<%=key%> : <%~ JSON.stringify(field.default) %>,
30
32
  <% } else if(typeof field.default !='undefined' && field.type=='string'){%>
31
33
  <%=key%> : '<%= field.default %>',
32
34
  <%} else if(typeof field.default !='undefined'){%>
@@ -300,10 +300,5 @@ export class <%= it.typename%>Client extends SimpleAppClient<openapi.<%= it.type
300
300
  <%}%>
301
301
  /***************************** end document status code*****************************************/
302
302
 
303
- <%if(it.jsonschema['x-simpleapp-config']['search']!==undefined){%>
304
- async runFullTextSearh(keyword:string) {
305
- const response = await this.docapi.runFullTextSearch(keyword)
306
- return response.data
307
- }
308
- <%}%>
303
+
309
304
  }
@@ -67,3 +67,20 @@ export class UserPermission {
67
67
  @ApiProperty({ type: 'string', required: true, format: 'uuid', default: '' })
68
68
  userId: string;
69
69
  }
70
+
71
+ @ObjectType()
72
+ export class TextSearchBody{
73
+ @Field()
74
+ @ApiProperty({ type: String })
75
+ keyword:string
76
+ @Field(()=>[String])
77
+ @ApiProperty({ type: ()=>[String] })
78
+ fields?:string[]
79
+ @Field(()=>[[String]])
80
+ @ApiProperty({ type: ()=>[[String]], })
81
+ sorts?:string[][]
82
+ @Field()
83
+ @ApiProperty({ type: Object })
84
+
85
+ lookup?: Record<string,string>
86
+ }
@@ -4,14 +4,44 @@
4
4
  * last change 2023-10-28
5
5
  * Author: Ks Tan
6
6
  */
7
- import { Injectable } from "@nestjs/common";
7
+ import { InjectModel } from '@nestjs/mongoose';
8
+ import { Injectable } from '@nestjs/common';
9
+ import { UserContext } from '../commons/user.context';
10
+ import { Model } from 'mongoose';
11
+ import * as types from 'src/simpleapp/generate/types';
8
12
 
9
13
  @Injectable()
10
14
  export class AuditTrail {
11
- constructor(){
12
- }
13
15
 
14
- addEvent(data:any){
15
- console.log("Add event into db:",data)
16
- }
17
- }
16
+ constructor( @InjectModel('Documentevent') private doc: Model<types.Documentevent>) {}
17
+
18
+
19
+
20
+ // addEvent(data: any) {
21
+ // console.log('Add event into db:', data);
22
+ // }
23
+ async addEvent(appuser:UserContext,documentName:string,id:string,eventType:string,data:any){
24
+
25
+
26
+
27
+ const eventdata:types.Documentevent = {
28
+ _id:crypto.randomUUID(),
29
+ documentName:documentName,
30
+ documentId:id,
31
+ eventType:eventType,
32
+ eventdata:data
33
+ }
34
+ Object.assign(eventdata, appuser.getCreateFilter());
35
+ console.log('add event',documentName,id,eventType)
36
+ console.log('Add event into db:', eventdata);
37
+ const newdoc = new this.doc(eventdata);
38
+ const dbsession = appuser.getDBSession();
39
+ const result = await newdoc.save({ session: dbsession });
40
+
41
+
42
+ }
43
+
44
+ async addManyEvents(appuser:UserContext,documentName:string,eventType:string,data:any[]){
45
+ console.log('add many event',documentName,eventType)
46
+ }
47
+ }
@@ -7,18 +7,28 @@ import {
7
7
  } from '@nestjs/common';
8
8
  import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
9
9
  import { UserContext } from './user.context';
10
- import { WebhookService } from 'src/simpleapp/services/webhook.service';
10
+ import {
11
+ Webhook,
12
+ WebhookService,
13
+ } from 'src/simpleapp/services/webhook.service';
14
+ import {
15
+ Webhookhistory,
16
+ WebhookhistoryService,
17
+ } from 'src/simpleapp/services/webhookhistory.service';
11
18
  @Injectable()
12
19
  export class RunWebhookService {
13
- public constructor(private webhookService: WebhookService) {}
20
+ public constructor(
21
+ private webhookService: WebhookService,
22
+ private webhookhistoryService: WebhookhistoryService,
23
+ ) {}
14
24
  @OnEvent('webhook')
15
- async runWebhook(
25
+ async loadWebhook(
16
26
  appuser: UserContext,
17
27
  documentName: string,
18
28
  actionName: string,
19
29
  data?: any,
20
30
  ) {
21
- let subscribeall=false
31
+ let subscribeall = false;
22
32
  const webhooks = await this.webhookService.search(appuser, {
23
33
  documentName: documentName,
24
34
  active: true,
@@ -26,25 +36,34 @@ export class RunWebhookService {
26
36
  if (webhooks.length == 0) return;
27
37
 
28
38
  const webhook = webhooks[0];
29
- let subscribes:string[] = []
30
- if(webhook.setting=='' || webhook.setting===undefined){
31
- subscribeall=true
32
- }else{
33
- subscribes= JSON.parse(webhook.setting)
39
+ let subscribes: string[] = [];
40
+ if (webhook.setting == '' || webhook.setting === undefined) {
41
+ subscribeall = true;
42
+ } else {
43
+ subscribes = JSON.parse(webhook.setting);
34
44
  }
35
45
 
36
- if(subscribes.includes(actionName)){
37
- const webhookurl = webhook.url;
38
- const secretkey = webhook.secret;
39
- const req = await fetch(webhookurl, {
40
- method: 'POST',
41
- headers: { 'x-apiKey': secretkey },
42
- body: JSON.stringify(data),
43
- });
44
- const statusCode = req.status
45
- const body = req.body
46
+ if (subscribeall || subscribes.includes(actionName)) {
47
+ await this.runWebHook(appuser, webhook, data);
48
+ }
49
+ }
46
50
 
51
+ async runWebHook(appuser: UserContext, webhook: Webhook, data: any) {
52
+ const webhookurl = webhook.url;
53
+ const headers = { 'x-from': process.env.PROJECT_NAME };
54
+ if (Array.isArray(webhook.headers)) {
55
+ webhook.headers.forEach((h) => {
56
+ headers[h.name] = h.value;
57
+ });
47
58
  }
48
-
59
+ const options = {
60
+ method: webhook.requestMethod,
61
+ body: JSON.stringify(data),
62
+ headers: headers,
63
+ };
64
+
65
+ const req = await fetch(webhookurl, options);
66
+ const statusCode = req.status;
67
+ const body = req.body;
49
68
  }
50
69
  }
@@ -26,8 +26,13 @@ import { UserService } from './../../services/user.service';
26
26
  import { InjectModel } from '@nestjs/mongoose';
27
27
  const Base64URL = require('@darkwolf/base64url');
28
28
  import { UserMongoSchema } from './../models/user.model';
29
- import { User } from './../types/user.type';
30
- import { Permission } from './../types/perm.type';
29
+ // import { User } from './../types/user.type';
30
+ import {
31
+ TenantClientSetting,
32
+ Permission,
33
+ User,
34
+ } from 'src/simpleapp/generate/types';
35
+ // import { Permission } from './../types/perm.type';
31
36
  import {
32
37
  ProfileUserBranch,
33
38
  ProfileUserInvites,
@@ -67,6 +72,11 @@ export class UserContext {
67
72
  protected invites: any[] = []; //User + field tenant:Tenant[]
68
73
  protected roles: string[] = [];
69
74
  protected moreProps: any[] = [];
75
+ protected clientSetting: TenantClientSetting = {
76
+ auditTrail: false,
77
+ support: false,
78
+ webhook: false,
79
+ };
70
80
  private dbsession: ClientSession;
71
81
  protected modifiedRecords: ModifiedRecords = {
72
82
  createds: {},
@@ -92,6 +102,7 @@ export class UserContext {
92
102
  getOrgId = () => this.orgId;
93
103
  getOrgRecordId = () => this.orgRecordId;
94
104
  getBranchId = () => this.branchId;
105
+ getClientSetting = () => this.clientSetting;
95
106
  getBranchCode = () => this.branchCode;
96
107
  getEmail = () => this.email;
97
108
  getTimeZone = () => this.timeZone;
@@ -103,10 +114,10 @@ export class UserContext {
103
114
  getRoles = () => this.roles;
104
115
  getModifieds = () => this.modifiedRecords;
105
116
  getBranches = (): ProfileUserBranch[] => {
106
- this.branches;
117
+ // this.branches;
107
118
  const data: ProfileUserBranch[] = [];
108
119
 
109
- if (this.branches) {
120
+ if (Array.isArray(this.branches)) {
110
121
  for (let i = 0; i < this.branches.length; i++) {
111
122
  const b = this.branches[i];
112
123
  data.push({
@@ -175,6 +186,9 @@ export class UserContext {
175
186
  as: 'currentbranch',
176
187
  },
177
188
  },
189
+ {
190
+ $unwind: '$currentbranch',
191
+ },
178
192
  {
179
193
  $lookup: {
180
194
  from: 'organization',
@@ -183,6 +197,20 @@ export class UserContext {
183
197
  as: 'currentorg',
184
198
  },
185
199
  },
200
+ {
201
+ $unwind: '$currentorg',
202
+ },
203
+ {
204
+ $lookup: {
205
+ from: 'tenant',
206
+ localField: 'tenantId',
207
+ foreignField: 'tenantId',
208
+ as: 'currentTenant',
209
+ },
210
+ },
211
+ {
212
+ $unwind: '$currentTenant',
213
+ }
186
214
  ],
187
215
  },
188
216
  };
@@ -191,10 +219,12 @@ export class UserContext {
191
219
 
192
220
  if (this.tenantId > 0) {
193
221
  pipeline.push(joinpermission);
222
+ pipeline.push({$unwind:'$permissions'})
223
+
194
224
  }
195
225
  // console.log("obtainProfileFromDbobtainProfileFromDb ",pipeline)
196
226
  // const users = await usermodel.find(filter)
197
- const users = await this.usermodel.aggregate(pipeline);
227
+ const users = await this.usermodel.aggregate(pipeline);
198
228
  this.logger.verbose(
199
229
  `aggregate user profile from database`,
200
230
  'obtainProfileFromDb',
@@ -207,7 +237,7 @@ export class UserContext {
207
237
 
208
238
  //console.log(userinfo)
209
239
  if (this.tenantId > 0) {
210
- const myperm = userinfo.permissions[0];
240
+ const myperm = userinfo.permissions;
211
241
 
212
242
  if (myperm && myperm.groups) {
213
243
  userinfo.groups = myperm.groups;
@@ -220,16 +250,17 @@ export class UserContext {
220
250
  }
221
251
  }
222
252
 
223
- userinfo.branchRecordId = myperm.currentbranch[0]._id;
224
- userinfo.branchCode = myperm.currentbranch[0].branchCode;
225
- userinfo.branchName = myperm.currentbranch[0].branchName;
226
- userinfo.orgRecordId = myperm.currentorg[0]._id;
227
- userinfo.orgCode = myperm.currentorg[0].orgCode;
228
- userinfo.orgName = myperm.currentorg[0].orgName;
229
- userinfo.timeZone = myperm.currentorg[0].timeZone;
230
- userinfo.currency = myperm.currentorg[0].currency;
231
- userinfo.country = myperm.currentorg[0].country;
232
- userinfo.offsetMinute = myperm.currentorg[0].offsetMinute;
253
+ userinfo.branchRecordId = myperm.currentbranch._id;
254
+ userinfo.branchCode = myperm.currentbranch.branchCode;
255
+ userinfo.branchName = myperm.currentbranch.branchName;
256
+ userinfo.orgRecordId = myperm.currentorg._id;
257
+ userinfo.orgCode = myperm.currentorg.orgCode;
258
+ userinfo.orgName = myperm.currentorg.orgName;
259
+ userinfo.timeZone = myperm.currentorg.timeZone;
260
+ userinfo.currency = myperm.currentorg.currency;
261
+ userinfo.country = myperm.currentorg.country;
262
+ userinfo.offsetMinute = myperm.currentorg.offsetMinute;
263
+ userinfo.clientSetting = myperm.currentTenant.clientSetting;
233
264
  }
234
265
  } else {
235
266
  userinfo.groups = [];
@@ -239,16 +270,6 @@ export class UserContext {
239
270
 
240
271
  const dblastactivity = userinfo.lastActivity ?? '2000-01-01T00:00:00Z';
241
272
  const lastvisit = new Date(dblastactivity).getTime() ?? 0;
242
- // if(currentitme - lastvisit)
243
-
244
- //update last activtity dont too frequent
245
- //if(!dblastactivity || currentitme - lastvisit > 5000 ){
246
- // const newusermodel = await this.usermodel.findById(userinfo._id)
247
- // newusermodel.lastActivity= this.lastActivity
248
- // const result = await newusermodel.save()
249
- //}
250
-
251
- // const result = await this.usermodel.findOneAndUpdate({_id: userinfo._id},{lastActivity: new Date().toISOString})
252
273
  return userinfo;
253
274
  } else {
254
275
  return undefined;
@@ -287,6 +308,7 @@ export class UserContext {
287
308
  this.orgRecordId = userinfo['orgRecordId'] ?? '';
288
309
  this.branchRecordId = userinfo['branchRecordId'] ?? '';
289
310
  this.groups = userinfo['groups'] ?? [];
311
+ this.clientSetting = userinfo['clientSetting'] ?? {};
290
312
  this.roles = userinfo['roles'] ?? [Role.Everyone, Role.User];
291
313
  this.moreProps = this.setMoreProps(userinfo);
292
314
  } else {
@@ -586,14 +608,6 @@ export class UserContext {
586
608
  },
587
609
  } as PipelineStage;
588
610
 
589
- const getTenantData: PipelineStage = {
590
- $lookup: {
591
- from: 'tenant',
592
- localField: 'tenantId',
593
- foreignField: 'tenantId',
594
- as: 'tenant',
595
- },
596
- };
597
611
 
598
612
  const permission: PipelineStage = {
599
613
  $lookup: {
@@ -610,7 +624,7 @@ export class UserContext {
610
624
  as: 'org',
611
625
  },
612
626
  },
613
- {$unwind:'$org'},
627
+ { $unwind: '$org' },
614
628
  {
615
629
  $lookup: {
616
630
  from: 'branch',
@@ -619,14 +633,14 @@ export class UserContext {
619
633
  as: 'branch',
620
634
  },
621
635
  },
622
- {$unwind:'$branch'},
636
+ { $unwind: '$branch' },
623
637
  ],
624
638
  },
625
639
  };
626
640
 
627
641
  const pipelines: PipelineStage[] = [
628
- filteruser,
629
- getTenantData,
642
+ { $match: { uid: this.uid, tenantId: { $gt: 0 }}},
643
+ { $lookup: { from: 'tenant', localField: 'tenantId', foreignField: 'tenantId',as: 'tenant'}},
630
644
  permission,
631
645
  ];
632
646
  // const users=[]
@@ -650,7 +664,7 @@ export class UserContext {
650
664
  orgId: item.orgId,
651
665
  branchId: item.branchId,
652
666
  groups: item.groups,
653
- orgRecordId:item.org._id,
667
+ orgRecordId: item.org._id,
654
668
  orgCode: item.org.orgCode,
655
669
  orgName: item.org.orgName,
656
670
  branchCode: item.branch.branchCode,
@@ -16,7 +16,7 @@ import {
16
16
  } from '@nestjs/common';
17
17
  // import { ApiTags, ApiBody, ApiResponse, ApiOperation } from '@nestjs/swagger';
18
18
  import { UserContext } from '../commons/user.context';
19
- import { SearchBody } from '../types';
19
+ import { SearchBody,TextSearchBody } from '../types';
20
20
  const doctype = 'person'.toUpperCase();
21
21
  type ServiceType = {
22
22
  list: Function;
@@ -51,10 +51,10 @@ export class SimpleAppAbstractController<
51
51
  async _list(appuser: UserContext) {
52
52
  return this.service.list(appuser);
53
53
  }
54
- async _fulltextsearch(appuser: UserContext, keyword: string) {
54
+ async _fulltextsearch(appuser: UserContext, body:TextSearchBody) {
55
55
  return this.service.fullTextSearch(
56
56
  appuser,
57
- keyword
57
+ body
58
58
  );
59
59
  }
60
60
  async _search(appuser: UserContext, searchObject: SearchBody) {