@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
@@ -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,6 +219,7 @@ export class UserContext {
191
219
 
192
220
  if (this.tenantId > 0) {
193
221
  pipeline.push(joinpermission);
222
+ pipeline.push({ $unwind: '$permissions' });
194
223
  }
195
224
  // console.log("obtainProfileFromDbobtainProfileFromDb ",pipeline)
196
225
  // const users = await usermodel.find(filter)
@@ -207,11 +236,11 @@ export class UserContext {
207
236
 
208
237
  //console.log(userinfo)
209
238
  if (this.tenantId > 0) {
210
- const myperm = userinfo.permissions[0];
239
+ const myperm = userinfo.permissions;
211
240
 
212
241
  if (myperm && myperm.groups) {
213
242
  userinfo.groups = myperm.groups;
214
- userinfo.roles = [] as Role[];
243
+ userinfo.roles = [Role.Everyone, Role.User] as Role[];
215
244
  for (let g = 0; g < userinfo.groups.length; g++) {
216
245
  const roles: Role[] = rolegroups[userinfo.groups[g]]();
217
246
  for (let r = 0; r < roles.length; r++) {
@@ -220,16 +249,17 @@ export class UserContext {
220
249
  }
221
250
  }
222
251
 
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;
252
+ userinfo.branchRecordId = myperm.currentbranch._id;
253
+ userinfo.branchCode = myperm.currentbranch.branchCode;
254
+ userinfo.branchName = myperm.currentbranch.branchName;
255
+ userinfo.orgRecordId = myperm.currentorg._id;
256
+ userinfo.orgCode = myperm.currentorg.orgCode;
257
+ userinfo.orgName = myperm.currentorg.orgName;
258
+ userinfo.timeZone = myperm.currentorg.timeZone;
259
+ userinfo.currency = myperm.currentorg.currency;
260
+ userinfo.country = myperm.currentorg.country;
261
+ userinfo.offsetMinute = myperm.currentorg.offsetMinute;
262
+ userinfo.clientSetting = myperm.currentTenant.clientSetting;
233
263
  }
234
264
  } else {
235
265
  userinfo.groups = [];
@@ -239,16 +269,6 @@ export class UserContext {
239
269
 
240
270
  const dblastactivity = userinfo.lastActivity ?? '2000-01-01T00:00:00Z';
241
271
  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
272
  return userinfo;
253
273
  } else {
254
274
  return undefined;
@@ -287,6 +307,7 @@ export class UserContext {
287
307
  this.orgRecordId = userinfo['orgRecordId'] ?? '';
288
308
  this.branchRecordId = userinfo['branchRecordId'] ?? '';
289
309
  this.groups = userinfo['groups'] ?? [];
310
+ this.clientSetting = userinfo['clientSetting'] ?? {};
290
311
  this.roles = userinfo['roles'] ?? [Role.Everyone, Role.User];
291
312
  this.moreProps = this.setMoreProps(userinfo);
292
313
  } else {
@@ -586,15 +607,6 @@ export class UserContext {
586
607
  },
587
608
  } as PipelineStage;
588
609
 
589
- const getTenantData: PipelineStage = {
590
- $lookup: {
591
- from: 'tenant',
592
- localField: 'tenantId',
593
- foreignField: 'tenantId',
594
- as: 'tenant',
595
- },
596
- };
597
-
598
610
  const permission: PipelineStage = {
599
611
  $lookup: {
600
612
  from: 'permission',
@@ -610,7 +622,7 @@ export class UserContext {
610
622
  as: 'org',
611
623
  },
612
624
  },
613
- {$unwind:'$org'},
625
+ { $unwind: '$org' },
614
626
  {
615
627
  $lookup: {
616
628
  from: 'branch',
@@ -619,18 +631,25 @@ export class UserContext {
619
631
  as: 'branch',
620
632
  },
621
633
  },
622
- {$unwind:'$branch'},
634
+ { $unwind: '$branch' },
623
635
  ],
624
636
  },
625
637
  };
626
638
 
627
639
  const pipelines: PipelineStage[] = [
628
- filteruser,
629
- getTenantData,
640
+ { $match: { uid: this.uid, tenantId: { $gt: 0 } } },
641
+ {
642
+ $lookup: {
643
+ from: 'tenant',
644
+ localField: 'tenantId',
645
+ foreignField: 'tenantId',
646
+ as: 'tenant',
647
+ },
648
+ },
630
649
  permission,
631
650
  ];
632
651
  // const users=[]
633
- this.logger.warn(pipelines, 'pipelines');
652
+ // this.logger.warn(pipelines, 'pipelines');
634
653
  const users = await this.usermodel.aggregate(pipelines);
635
654
 
636
655
  if (users) {
@@ -650,7 +669,7 @@ export class UserContext {
650
669
  orgId: item.orgId,
651
670
  branchId: item.branchId,
652
671
  groups: item.groups,
653
- orgRecordId:item.org._id,
672
+ orgRecordId: item.org._id,
654
673
  orgCode: item.org.orgCode,
655
674
  orgName: item.org.orgName,
656
675
  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) {