@simitgroup/simpleapp-generator 1.6.4-alpha → 1.6.4-c-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.
- package/package.json +1 -1
- package/templates/basic/nest/controller.ts.eta +1 -1
- package/templates/basic/nuxt/pages.viewer.vue.eta +1 -0
- package/templates/nest/src/simpleapp/generate/commons/docnogenerator.service.ts.eta +21 -8
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +9 -5
- package/templates/nest/src/simpleapp/generate/processors/org.processor.ts.eta +7 -12
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +17 -13
- package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +14 -11
- package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +13 -8
- package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +54 -47
- package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +10 -11
- package/templates/nuxt/components/form/FormUser.vue._eta +2 -4
- package/templates/nuxt/components/image/ImageOrganization.vue.eta.vue +34 -16
- package/templates/nuxt/components/renderer/RendererDate.vue.eta +1 -1
- package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +10 -5
- package/templates/nuxt/components/select/SelectTemplate.vue.eta +27 -22
- package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +2 -2
- package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +37 -41
- package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +57 -25
- package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +11 -10
- package/templates/nuxt/components/user/UserButtonPermissionInfo.vue.eta +17 -8
- package/templates/nuxt/components/user/UserInvitation.vue.eta +53 -45
- package/templates/nuxt/components/user/UserTenantPicker.vue.eta +31 -70
- package/templates/nuxt/composables/getUserStore.generate.ts.eta +3 -2
- package/templates/nuxt/composables/roles.generate.ts.eta +1 -0
- package/templates/nuxt/error.vue._eta +4 -2
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +12 -3
- package/templates/nuxt/server/api/profile/[...].ts.eta +44 -1
- package/templates/project/lang/default._json +4 -1
package/package.json
CHANGED
|
@@ -345,7 +345,7 @@ export class <%= it.typename %>Controller extends SimpleAppAbstractController<
|
|
|
345
345
|
|
|
346
346
|
<% if(simpleappconfig?.printFormats){%>
|
|
347
347
|
@Get(':id/print/:formatid')
|
|
348
|
-
@Roles(Role.SuperAdmin, Role.SuperUser, Role.<%= `${it.typename}
|
|
348
|
+
@Roles(Role.SuperAdmin, Role.SuperUser, Role.<%= `${it.typename}_access`%>)
|
|
349
349
|
@ApiResponse({
|
|
350
350
|
status: 200,
|
|
351
351
|
description: 'return base64 pdf string',
|
|
@@ -9,16 +9,25 @@ import { InjectModel } from '@nestjs/mongoose';
|
|
|
9
9
|
import { Model } from 'mongoose';
|
|
10
10
|
import { DocNumberFormatResult } from '../types';
|
|
11
11
|
import { Docnoformat } from '../types/docno.type';
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
Injectable,
|
|
14
|
+
InternalServerErrorException,
|
|
15
|
+
BadRequestException,
|
|
16
|
+
} from '@nestjs/common';
|
|
13
17
|
// import moment from 'moment';
|
|
14
|
-
import dayjs from 'dayjs'
|
|
18
|
+
import dayjs from 'dayjs';
|
|
15
19
|
import { ForeignKey } from '../types';
|
|
16
20
|
|
|
17
21
|
export class DocNumberFormatGenerator {
|
|
18
|
-
constructor(
|
|
22
|
+
constructor(
|
|
23
|
+
@InjectModel('Docnoformat') private docformat: Model<Docnoformat>,
|
|
24
|
+
) {}
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
async generateNextNumberFromDocument(
|
|
27
|
+
appuser: UserContext,
|
|
28
|
+
docType: string,
|
|
29
|
+
data: any,
|
|
30
|
+
) {
|
|
22
31
|
let formatId = '';
|
|
23
32
|
if (data.docNoFormat && data.docNoFormat._id) {
|
|
24
33
|
formatId = data.docNoFormat._id;
|
|
@@ -32,14 +41,18 @@ export class DocNumberFormatGenerator {
|
|
|
32
41
|
return docnoobj.result;
|
|
33
42
|
}
|
|
34
43
|
|
|
35
|
-
generateNextNo = async (
|
|
44
|
+
generateNextNo = async (
|
|
45
|
+
appuser: UserContext,
|
|
46
|
+
doctype: string,
|
|
47
|
+
id: string = '',
|
|
48
|
+
) => {
|
|
36
49
|
doctype = doctype.toUpperCase();
|
|
37
50
|
let filter = { docNoType: doctype };
|
|
38
51
|
if (id) {
|
|
39
52
|
filter['_id'] = id;
|
|
40
53
|
}
|
|
41
54
|
Object.assign(filter, appuser.getBranchFilter());
|
|
42
|
-
const result = await this.docformat.find(filter);
|
|
55
|
+
const result = await this.docformat.find(filter).session(appuser.getDBSession());
|
|
43
56
|
//search(appuser, filter);
|
|
44
57
|
if (result && result.length > 0) {
|
|
45
58
|
const d: Docnoformat = result[0];
|
|
@@ -98,7 +111,7 @@ export class DocNumberFormatGenerator {
|
|
|
98
111
|
for (let d = 0; d < datepattern.length; d++) {
|
|
99
112
|
const dpattern = datepattern[d];
|
|
100
113
|
const date = new Date();
|
|
101
|
-
const formatteddate =dayjs().format(
|
|
114
|
+
const formatteddate = dayjs().format(
|
|
102
115
|
dpattern.replace('{', '').replace('}', ''),
|
|
103
116
|
);
|
|
104
117
|
newvalue = newvalue.replace(dpattern, formatteddate);
|
|
@@ -90,6 +90,7 @@ export class UserContext {
|
|
|
90
90
|
getFullname = () => this.fullname;
|
|
91
91
|
getTenantId = () => this.tenantId;
|
|
92
92
|
getOrgId = () => this.orgId;
|
|
93
|
+
getOrgRecordId = () => this.orgRecordId;
|
|
93
94
|
getBranchId = () => this.branchId;
|
|
94
95
|
getBranchCode = () => this.branchCode;
|
|
95
96
|
getEmail = () => this.email;
|
|
@@ -609,6 +610,7 @@ export class UserContext {
|
|
|
609
610
|
as: 'org',
|
|
610
611
|
},
|
|
611
612
|
},
|
|
613
|
+
{$unwind:'$org'},
|
|
612
614
|
{
|
|
613
615
|
$lookup: {
|
|
614
616
|
from: 'branch',
|
|
@@ -617,6 +619,7 @@ export class UserContext {
|
|
|
617
619
|
as: 'branch',
|
|
618
620
|
},
|
|
619
621
|
},
|
|
622
|
+
{$unwind:'$branch'},
|
|
620
623
|
],
|
|
621
624
|
},
|
|
622
625
|
};
|
|
@@ -639,7 +642,7 @@ export class UserContext {
|
|
|
639
642
|
activeusers.forEach((u) => {
|
|
640
643
|
const permissions = u.permissions
|
|
641
644
|
.filter((item: any) => {
|
|
642
|
-
return item.org
|
|
645
|
+
return item.org.active && item.branch.active;
|
|
643
646
|
})
|
|
644
647
|
.map((item: any) => {
|
|
645
648
|
return {
|
|
@@ -647,10 +650,11 @@ export class UserContext {
|
|
|
647
650
|
orgId: item.orgId,
|
|
648
651
|
branchId: item.branchId,
|
|
649
652
|
groups: item.groups,
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
653
|
+
orgRecordId:item.org._id,
|
|
654
|
+
orgCode: item.org.orgCode,
|
|
655
|
+
orgName: item.org.orgName,
|
|
656
|
+
branchCode: item.branch.branchCode,
|
|
657
|
+
branchName: item.branch.branchName,
|
|
654
658
|
xOrg: this.generateXorg(u.tenantId, item.orgId, item.branchId),
|
|
655
659
|
};
|
|
656
660
|
});
|
|
@@ -32,8 +32,6 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
32
32
|
protected documentIdentityLabel = 'orgName';
|
|
33
33
|
protected strictIsolation = false;
|
|
34
34
|
protected foreignkeys = {};
|
|
35
|
-
protected defaultlogo =
|
|
36
|
-
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=';
|
|
37
35
|
protected hooks: OrganizationHooks = {
|
|
38
36
|
beforeCreate: async (appuser: UserContext, data: Organization) =>
|
|
39
37
|
await this.orgBeforeCreate(appuser, data),
|
|
@@ -65,23 +63,22 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
65
63
|
async runGetlogo(appuser: UserContext) {
|
|
66
64
|
const logo = await this.searchLogo(appuser);
|
|
67
65
|
if (logo) return logo.value;
|
|
68
|
-
else return
|
|
66
|
+
else return ''
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
async searchLogo(appuser: UserContext) {
|
|
72
70
|
const keyvaluepair = await this.kvpairService.search(appuser, {
|
|
73
|
-
key: '
|
|
71
|
+
key: 'org-'+appuser.getOrgRecordId(),
|
|
74
72
|
});
|
|
75
73
|
if (keyvaluepair && keyvaluepair.length > 0) return keyvaluepair[0];
|
|
76
74
|
else return null;
|
|
77
75
|
}
|
|
78
|
-
async runUploadlogo(appuser: UserContext, data: KeyValue) {
|
|
79
|
-
// this.setDefaultLogo(data.value);
|
|
76
|
+
async runUploadlogo(appuser: UserContext, data: KeyValue) {
|
|
80
77
|
const key = data.key;
|
|
81
78
|
|
|
82
79
|
let kvdata: Keyvaluepair = await this.searchLogo(appuser);
|
|
83
80
|
if (kvdata) {
|
|
84
|
-
kvdata.value=data.value
|
|
81
|
+
kvdata.value = data.value;
|
|
85
82
|
const res = await this.kvpairService.findIdThenUpdate(
|
|
86
83
|
appuser,
|
|
87
84
|
kvdata._id,
|
|
@@ -95,7 +92,7 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
95
92
|
} else {
|
|
96
93
|
kvdata = {
|
|
97
94
|
_id: crypto.randomUUID(),
|
|
98
|
-
key: '
|
|
95
|
+
key: 'org-'+appuser.getOrgRecordId(),
|
|
99
96
|
value: data.value,
|
|
100
97
|
};
|
|
101
98
|
const res = await this.kvpairService.create(appuser, kvdata);
|
|
@@ -106,10 +103,8 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
|
|
109
|
-
return
|
|
106
|
+
return ''
|
|
110
107
|
}
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
this.defaultlogo = data;
|
|
114
|
-
}
|
|
109
|
+
|
|
115
110
|
}
|
|
@@ -230,7 +230,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
230
230
|
this.polishIsolationFilter(isolationFilter);
|
|
231
231
|
|
|
232
232
|
Object.assign(pipeline[0]['$match'], isolationFilter);
|
|
233
|
-
|
|
233
|
+
this.logger.verbose(pipeline, `${this.documentName} aggregate:`);
|
|
234
234
|
return await this.doc.aggregate(pipeline, {
|
|
235
235
|
session: appuser.getDBSession(),
|
|
236
236
|
});
|
|
@@ -576,20 +576,24 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
576
576
|
// };
|
|
577
577
|
|
|
578
578
|
findIdThenUpdate = async (appuser: UserContext, id: string, data: T) => {
|
|
579
|
-
|
|
580
|
-
|
|
579
|
+
|
|
580
|
+
try {
|
|
581
581
|
//version exists, need ensure different only 1
|
|
582
|
-
|
|
583
|
-
throw new
|
|
584
|
-
`You submit older version data "v${data.__v}"" but latest version = "v${existingdata.__v}"`,
|
|
585
|
-
);
|
|
586
|
-
}
|
|
582
|
+
const existingdata = await this.findById(appuser, id);
|
|
583
|
+
if(!existingdata) throw new NotFoundException(`${this.documentName} findIdThenUpdate: _id:${id} not found`, 'not found');
|
|
587
584
|
|
|
585
|
+
this.logger.debug("update id:"+id,this.documentName+' findIdThenUpdate')
|
|
586
|
+
if (typeof data.__v == 'number' && data.__v != existingdata.__v) {
|
|
587
|
+
throw new BadRequestException(
|
|
588
|
+
`You submit older version data "v${data.__v}"" but latest version = "v${existingdata.__v}"`,
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
this.logger.debug("warn1",existingdata)
|
|
588
592
|
data.__v = existingdata.__v + 1;
|
|
589
|
-
if (!existingdata) {
|
|
590
|
-
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
+
// if (!existingdata) {
|
|
594
|
+
// throw new NotFoundException(`${id} not found`, 'not found');
|
|
595
|
+
// }
|
|
596
|
+
this.logger.debug("warn2")
|
|
593
597
|
if (this.hooks.beforeUpdate)
|
|
594
598
|
await this.hooks.beforeUpdate(appuser, id, data, existingdata);
|
|
595
599
|
|
|
@@ -611,7 +615,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
|
611
615
|
this.polishIsolationFilter(isolationFilter);
|
|
612
616
|
isolationFilter['_id'] = id;
|
|
613
617
|
this.applyNestedDateTime(appuser, data, 'update');
|
|
614
|
-
|
|
618
|
+
|
|
615
619
|
const result = await this.doc.findOneAndReplace(isolationFilter, data, {
|
|
616
620
|
session: dbsession,
|
|
617
621
|
new: true,
|
|
@@ -124,6 +124,7 @@ export class ProfileService {
|
|
|
124
124
|
orgName: tenantName,
|
|
125
125
|
active: true,
|
|
126
126
|
orgCode: 'HQ',
|
|
127
|
+
registrationNo: '000000',
|
|
127
128
|
timeZone: timeZone,
|
|
128
129
|
offsetMinute: utcOffset,
|
|
129
130
|
currency: currencyCode,
|
|
@@ -143,6 +144,13 @@ export class ProfileService {
|
|
|
143
144
|
branchId: 1,
|
|
144
145
|
branchCode: 'HQ',
|
|
145
146
|
branchName: tenantName,
|
|
147
|
+
street1: '11,my street 1',
|
|
148
|
+
street2: 'my street 2',
|
|
149
|
+
postcode: '11111',
|
|
150
|
+
city: 'my city',
|
|
151
|
+
tel: '99999999999',
|
|
152
|
+
email: 'change-email@email.com',
|
|
153
|
+
region: 'my region',
|
|
146
154
|
country: countryName,
|
|
147
155
|
active: true,
|
|
148
156
|
orgId: orgResult.orgId,
|
|
@@ -246,22 +254,17 @@ export class ProfileService {
|
|
|
246
254
|
return 'OK';
|
|
247
255
|
}
|
|
248
256
|
|
|
249
|
-
|
|
250
|
-
async runTourComplete(appuser: UserContext, guideName: string) {
|
|
257
|
+
async runTourComplete(appuser: UserContext, guideName: string) {
|
|
251
258
|
if (!guideName || guideName == '')
|
|
252
259
|
throw new BadRequestException('undefine guideName');
|
|
253
260
|
|
|
254
|
-
const user = await this.usersvc.findById(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if(!Array.isArray(user.completedTours)){
|
|
259
|
-
user.completedTours=[]
|
|
260
|
-
}
|
|
261
|
+
const user = await this.usersvc.findById(appuser, appuser.getId());
|
|
262
|
+
if (!Array.isArray(user.completedTours)) {
|
|
263
|
+
user.completedTours = [];
|
|
264
|
+
}
|
|
261
265
|
|
|
262
266
|
if (!user.completedTours.includes(guideName)) {
|
|
263
|
-
|
|
264
|
-
user.completedTours.push(guideName);
|
|
267
|
+
user.completedTours.push(guideName);
|
|
265
268
|
const res = await this.usersvc.findIdThenUpdate(appuser, user._id, user);
|
|
266
269
|
}
|
|
267
270
|
|
|
@@ -22,11 +22,11 @@ import { <%= obj.docname %>MongoSchema } from './generate/models/<%= obj.doctype
|
|
|
22
22
|
<%}%>
|
|
23
23
|
import { ProfileController } from './profile/profile.controller';
|
|
24
24
|
import { ProfileService } from './profile/profile.service';
|
|
25
|
-
import { WorkflowController } from './generate/workflow/workflow.controller';
|
|
26
|
-
import { WorkflowDelegate } from './generate/workflow/workflow.delegate';
|
|
27
|
-
import { WorkflowConfig } from './generate/workflow/workflow.config';
|
|
28
|
-
import { WorkflowService } from './generate/workflow/workflow.service';
|
|
29
|
-
import { WorkflowUserService } from './generate/workflow/workflow.userservice';
|
|
25
|
+
//import { WorkflowController } from './generate/workflow/workflow.controller';
|
|
26
|
+
//import { WorkflowDelegate } from './generate/workflow/workflow.delegate';
|
|
27
|
+
//import { WorkflowConfig } from './generate/workflow/workflow.config';
|
|
28
|
+
//import { WorkflowService } from './generate/workflow/workflow.service';
|
|
29
|
+
//import { WorkflowUserService } from './generate/workflow/workflow.userservice';
|
|
30
30
|
import { SimpleAppRobotUserService } from './generate/commons/robotuser.service';
|
|
31
31
|
<%for(let i=0; i<it.allbpmn.length;i++){%>
|
|
32
32
|
<%let bpmn = it.allbpmn[i]%>
|
|
@@ -50,14 +50,17 @@ import { <%=capitalizeFirstLetter(bpmn)%>ListenerService } from 'src/simpleapp/w
|
|
|
50
50
|
<%}%>
|
|
51
51
|
]),
|
|
52
52
|
],
|
|
53
|
-
controllers: [<% for(let i=0;i<it.modules.length; i++){ %><%= it.modules[i].docname %>Controller,<%}%> ProfileController,
|
|
53
|
+
controllers: [<% for(let i=0;i<it.modules.length; i++){ %><%= it.modules[i].docname %>Controller,<%}%> ProfileController,
|
|
54
|
+
//WorkflowController
|
|
55
|
+
],
|
|
54
56
|
providers: [
|
|
55
57
|
SimpleAppRobotUserService,
|
|
56
58
|
RunWebhookService,
|
|
57
59
|
AuditTrail,DocNumberFormatGenerator,<% for(let i=0;i<it.modules.length; i++){ %>
|
|
58
60
|
<%= it.modules[i].docname %>Service,
|
|
59
61
|
<%= it.modules[i].docname %>Resolver,
|
|
60
|
-
<%}%> ProfileService,
|
|
62
|
+
<%}%> ProfileService,
|
|
63
|
+
//WorkflowDelegate,WorkflowConfig,WorkflowService,WorkflowUserService,
|
|
61
64
|
<%for(let i=0; i<it.allbpmn.length;i++){%>
|
|
62
65
|
<%let bpmn = it.allbpmn[i]%>
|
|
63
66
|
<%=capitalizeFirstLetter(bpmn)%>ListenerService,
|
|
@@ -66,6 +69,8 @@ import { <%=capitalizeFirstLetter(bpmn)%>ListenerService } from 'src/simpleapp/w
|
|
|
66
69
|
exports:[SimpleAppRobotUserService,AuditTrail,DocNumberFormatGenerator,<% for(let i=0;i<it.modules.length; i++){ %>
|
|
67
70
|
<%= it.modules[i].docname %>Service,
|
|
68
71
|
<%= it.modules[i].docname %>Resolver,
|
|
69
|
-
<%}%> ProfileService,
|
|
72
|
+
<%}%> ProfileService,
|
|
73
|
+
//WorkflowDelegate,WorkflowConfig,WorkflowService,WorkflowUserService,
|
|
74
|
+
UserResolverService,]
|
|
70
75
|
})
|
|
71
76
|
export class GenerateModule {}
|
|
@@ -1,51 +1,56 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<ClientOnly>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<div>
|
|
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 }">
|
|
25
24
|
<div>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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>
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
<div>
|
|
39
|
+
<slot name="default" :cell="cell" :events="events">
|
|
40
|
+
<Badge
|
|
41
|
+
v-if="events.length > 0"
|
|
42
|
+
@contextmenu="
|
|
43
|
+
(mouseevent) => onRightClickDate(mouseevent, cell)
|
|
44
|
+
"
|
|
45
|
+
severity="info"
|
|
46
|
+
:value="events.length"
|
|
47
|
+
/>
|
|
48
|
+
</slot>
|
|
49
|
+
</div>
|
|
44
50
|
</div>
|
|
45
|
-
</
|
|
46
|
-
</
|
|
47
|
-
</
|
|
48
|
-
</ClientOnly>
|
|
51
|
+
</template>
|
|
52
|
+
</VueCal>
|
|
53
|
+
</ClientOnly>
|
|
49
54
|
</template>
|
|
50
55
|
<script lang="ts" setup generic="T">
|
|
51
56
|
/**
|
|
@@ -70,7 +75,7 @@ const props = defineProps<{
|
|
|
70
75
|
holidays: OffDay[];
|
|
71
76
|
}>();
|
|
72
77
|
const offdays = ref<string[]>([]);
|
|
73
|
-
const emits = defineEmits(["chooseDate", "rightClick"]);
|
|
78
|
+
const emits = defineEmits(["chooseDate", "rightClick","viewChange"]);
|
|
74
79
|
// const allholidays = computed(() => props.holidays.map((item) => item.date));
|
|
75
80
|
const selectedDate = defineModel<Date>({ required: true });
|
|
76
81
|
const getHolidayName = (date: Date) =>
|
|
@@ -93,6 +98,7 @@ const allevents = computed(() => {
|
|
|
93
98
|
});
|
|
94
99
|
const viewChange = (event: CalViewChange) => {
|
|
95
100
|
viewStatus.value = event;
|
|
101
|
+
emits('viewChange',event)
|
|
96
102
|
};
|
|
97
103
|
|
|
98
104
|
const isHoliday = (datestr: string) => {
|
|
@@ -101,8 +107,9 @@ const isHoliday = (datestr: string) => {
|
|
|
101
107
|
);
|
|
102
108
|
};
|
|
103
109
|
const isOffDay = (cell: any) => {
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
const dayname: string = new Date(cell.formattedDate)
|
|
111
|
+
.toLocaleString("en", { weekday: "short" })
|
|
112
|
+
.toLowerCase();
|
|
106
113
|
if (offdays.value.includes(dayname)) return true;
|
|
107
114
|
else return false;
|
|
108
115
|
};
|
|
@@ -65,10 +65,10 @@ const after = (
|
|
|
65
65
|
) => {
|
|
66
66
|
if (v.after) {
|
|
67
67
|
v.after(eventType, data, visible);
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
//only after mount consider no remove tab
|
|
70
|
-
if (eventType == "mount") return
|
|
71
|
-
|
|
70
|
+
if (eventType == "mount") return;
|
|
71
|
+
else if(eventType=='setDocStatus') return;
|
|
72
72
|
deleteTab();
|
|
73
73
|
}
|
|
74
74
|
};
|
|
@@ -81,21 +81,20 @@ onKeyStroke("Escape", (e) => {
|
|
|
81
81
|
const deleteTab = () => {
|
|
82
82
|
const keys = Object.keys(allview.value);
|
|
83
83
|
const lastkey = keys[keys.length - 1];
|
|
84
|
-
console.log("Trigger delete tab")
|
|
84
|
+
// console.log("Trigger delete tab");
|
|
85
85
|
if (keys.length == 1) {
|
|
86
86
|
const callback = allview.value[lastkey]?.after;
|
|
87
87
|
if (typeof callback == "function") {
|
|
88
88
|
callback(FormCrudEvent.exit, undefined, visible);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
if(autodeletetab.value){
|
|
91
|
+
if (autodeletetab.value) {
|
|
92
92
|
delete allview.value[lastkey];
|
|
93
93
|
visible.value = false;
|
|
94
|
-
useNuxtApp().$event("CloseDialog", "viewer");
|
|
94
|
+
useNuxtApp().$event("CloseDialog", "viewer");
|
|
95
95
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
console.log("Trigger delete tab2")
|
|
96
|
+
} else {
|
|
97
|
+
// console.log("Trigger delete tab2");
|
|
99
98
|
delete allview.value[lastkey];
|
|
100
99
|
}
|
|
101
100
|
};
|
|
@@ -103,7 +102,7 @@ const deleteTab = () => {
|
|
|
103
102
|
$listen("ViewRecord", (setting) => {
|
|
104
103
|
visible.value = true;
|
|
105
104
|
if (setting["autoclose"] != undefined) {
|
|
106
|
-
autodeletetab.value = setting["autoclose"] ==0 ? false : true;
|
|
105
|
+
autodeletetab.value = setting["autoclose"] == 0 ? false : true;
|
|
107
106
|
}
|
|
108
107
|
allview.value[setting.eventId] = setting;
|
|
109
108
|
});
|
|
@@ -127,7 +126,7 @@ $listen("CloseDialog", (documentName: string) => {
|
|
|
127
126
|
//
|
|
128
127
|
const clearView = () => {
|
|
129
128
|
const firstId = Object.keys(allview.value)[0];
|
|
130
|
-
console.log("clear view", allview.value);
|
|
129
|
+
// console.log("clear view", allview.value);
|
|
131
130
|
const callback = allview.value[firstId]?.after;
|
|
132
131
|
if (typeof callback == "function") {
|
|
133
132
|
callback(FormCrudEvent.exit, undefined, visible);
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
<title v-if="id">{{ data.fullName ?? data.email }}</title>
|
|
8
8
|
<TabView lazy>
|
|
9
9
|
<TabPanel :header="t('profile')">
|
|
10
|
-
<div
|
|
11
|
-
class="grid grid-cols-1 lg:grid-cols-2 gap-4 p-2"
|
|
12
|
-
>
|
|
10
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 p-2">
|
|
13
11
|
<SimpleAppInput
|
|
14
12
|
:input-type="SimpleAppInputType.text"
|
|
15
13
|
:setting="o.getField('#/properties/fullName')"
|
|
@@ -37,7 +35,7 @@
|
|
|
37
35
|
/>
|
|
38
36
|
</div>
|
|
39
37
|
|
|
40
|
-
<DebugDocumentData v-model="data" :label="doc.getDocName()" />
|
|
38
|
+
<!-- <DebugDocumentData v-model="data" :label="doc.getDocName()" /> -->
|
|
41
39
|
</TabPanel>
|
|
42
40
|
<TabPanel :header="t('permission')">
|
|
43
41
|
<!-- <UserButtonPermissionInfo></UserButtonPermissionInfo> -->
|
|
@@ -2,41 +2,59 @@
|
|
|
2
2
|
<ImageToBase64Uploader
|
|
3
3
|
v-if="changable"
|
|
4
4
|
#default
|
|
5
|
-
class="w
|
|
5
|
+
:class="`w-${sizenumber} h-${sizenumber} place-content-center bg-white`"
|
|
6
6
|
@image-uploaded="handleBase64"
|
|
7
7
|
>
|
|
8
|
-
<
|
|
9
|
-
|
|
8
|
+
<NuxtImg
|
|
9
|
+
class="w-full h-full"
|
|
10
|
+
:key="imageKey"
|
|
11
|
+
provider="myProvider"
|
|
12
|
+
:src="imagepath"
|
|
13
|
+
/>
|
|
10
14
|
</ImageToBase64Uploader>
|
|
11
|
-
<div
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
<div
|
|
16
|
+
v-else
|
|
17
|
+
:class="`inline-block border rounded-lg w-${sizenumber} h-${sizenumber} bg-white`"
|
|
18
|
+
>
|
|
19
|
+
<NuxtImg class="w-full h-full" provider="myProvider" :src="imagepath" />
|
|
14
20
|
</div>
|
|
15
21
|
</template>
|
|
16
22
|
<script lang="ts" setup>
|
|
17
23
|
// import {KeyValue} from ''
|
|
18
24
|
const props = defineProps<{
|
|
19
|
-
changable
|
|
25
|
+
changable?: boolean;
|
|
26
|
+
orgRecordId?: string;
|
|
27
|
+
size: number;
|
|
20
28
|
}>();
|
|
29
|
+
const imageKey = ref(0);
|
|
30
|
+
const orgRecordId = computed(
|
|
31
|
+
() => props.orgRecordId ?? getUserProfile()?.orgRecordId,
|
|
32
|
+
);
|
|
33
|
+
const xorgpath= getCurrentXorg() ? `${getCurrentXorg()}/` : 'MC0wLTA/'
|
|
34
|
+
|
|
35
|
+
const imagepath = `${xorgpath}images/organization/${
|
|
36
|
+
orgRecordId.value
|
|
37
|
+
}`;
|
|
38
|
+
const sizenumber = props.size ?? 16;
|
|
21
39
|
const imageData = ref("");
|
|
40
|
+
watch(
|
|
41
|
+
() => props.orgRecordId,
|
|
42
|
+
() => imageKey.value++,
|
|
43
|
+
);
|
|
22
44
|
const handleBase64 = async (data: string) => {
|
|
23
45
|
const keyvalue = {
|
|
24
|
-
key: "
|
|
46
|
+
key: "org-" + props.orgRecordId,
|
|
25
47
|
value: data,
|
|
26
48
|
};
|
|
27
|
-
|
|
49
|
+
console.log("upload logo ", data);
|
|
28
50
|
const uploadok = await useNuxtApp()
|
|
29
51
|
.$OrganizationDoc()
|
|
30
52
|
.getApi()
|
|
31
53
|
.runUploadlogo(keyvalue);
|
|
32
54
|
if (uploadok) {
|
|
33
|
-
|
|
55
|
+
const realpath = `/api/${imagepath}`;
|
|
56
|
+
await fetch(realpath, { cache: "reload", credentials: "include" });
|
|
57
|
+
imageKey.value++;
|
|
34
58
|
}
|
|
35
59
|
};
|
|
36
|
-
const loadLogo = async () => {
|
|
37
|
-
await refreshOrgLogo();
|
|
38
|
-
imageData.value = getOrgLogo();
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
onMounted(async () => await loadLogo());
|
|
42
60
|
</script>
|