zet-lib 5.0.3 → 6.0.1
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/README.md +49 -0
- package/lib/index.js +84 -62
- package/lib/views/generatorjs.ejs +0 -12
- package/lib/views/zgenerator/routerApp.ejs +359 -359
- package/lib/zGeneratorRouter.js +3 -83
- package/lib/zPage.js +1 -9
- package/lib/zRoleRouter.js +0 -2
- package/lib/zRoute.js +1 -3
- package/package.json +11 -16
package/README.md
CHANGED
|
@@ -13,3 +13,52 @@ Installation
|
|
|
13
13
|
------------
|
|
14
14
|
|
|
15
15
|
npm install zet-lib
|
|
16
|
+
|
|
17
|
+
Safe installation
|
|
18
|
+
-----------------
|
|
19
|
+
|
|
20
|
+
`zet-lib` includes some optional heavy features, such as browser/PDF automation and image processing.
|
|
21
|
+
If your app only needs the core helpers (database, cache, utilities, routers, mail, etc), a normal install is enough:
|
|
22
|
+
|
|
23
|
+
npm install zet-lib
|
|
24
|
+
|
|
25
|
+
If you want to avoid browser downloads in CI/CD or server environments:
|
|
26
|
+
|
|
27
|
+
PUPPETEER_SKIP_DOWNLOAD=1 npm install zet-lib
|
|
28
|
+
|
|
29
|
+
Optional features
|
|
30
|
+
-----------------
|
|
31
|
+
|
|
32
|
+
- `puppeteer`
|
|
33
|
+
- Used for browser/PDF style features.
|
|
34
|
+
- Starting from `zet-lib@6`, it is treated as optional during install.
|
|
35
|
+
- If you use a feature that needs Puppeteer and it is not installed, `zet-lib` will throw a clear error message.
|
|
36
|
+
- To install it explicitly:
|
|
37
|
+
|
|
38
|
+
npm install puppeteer
|
|
39
|
+
|
|
40
|
+
- `sharp`
|
|
41
|
+
- Used for image processing/compression features.
|
|
42
|
+
- It is optional because some environments do not need it or may have native install constraints.
|
|
43
|
+
- To install it explicitly:
|
|
44
|
+
|
|
45
|
+
npm install --include=optional sharp
|
|
46
|
+
|
|
47
|
+
Performance note
|
|
48
|
+
----------------
|
|
49
|
+
|
|
50
|
+
`zet-lib` lazily loads its exports. This means `require("zet-lib")` will not immediately load all heavy modules.
|
|
51
|
+
Only the feature you access will load its underlying dependency tree.
|
|
52
|
+
|
|
53
|
+
Examples
|
|
54
|
+
--------
|
|
55
|
+
|
|
56
|
+
Use only core utilities:
|
|
57
|
+
|
|
58
|
+
const { Util, connection } = require("zet-lib");
|
|
59
|
+
|
|
60
|
+
Use Puppeteer-powered features:
|
|
61
|
+
|
|
62
|
+
const { puppeteer } = require("zet-lib");
|
|
63
|
+
|
|
64
|
+
// Make sure puppeteer is installed in your project first.
|
package/lib/index.js
CHANGED
|
@@ -1,73 +1,95 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Util: require("./Util"),
|
|
7
|
-
myCache: require("./cache"),
|
|
8
|
-
connection: require("./connection"),
|
|
9
|
-
zDataTable: require("./zdataTable"),
|
|
10
|
-
zDebug: require("./debug"),
|
|
11
|
-
zForm: require("./Form"),
|
|
12
|
-
io: require("./io"),
|
|
13
|
-
zMail: require("./Mail"),
|
|
14
|
-
moduleLib: require("./moduleLib"),
|
|
15
|
-
Model: require("./Model"),
|
|
16
|
-
zApp: require("./zapp"),
|
|
17
|
-
zAppRouter: require("./zAppRouter"),
|
|
18
|
-
zComponent: require("./zComponent"),
|
|
19
|
-
zFn: require("./zFn"),
|
|
20
|
-
zFunction: require("./zFunction"),
|
|
21
|
-
zMenuRouter: require("./zMenuRouter"),
|
|
22
|
-
zGeneratorRouter: require("./zGeneratorRouter"),
|
|
23
|
-
zViewGenerator: require("./zViewGenerator"),
|
|
24
|
-
zReport: require("./zReport"),
|
|
25
|
-
zRoute: require("./zRoute"),
|
|
26
|
-
zRole: require("./zRole"),
|
|
27
|
-
zRoleRouter: require("./zRoleRouter"),
|
|
28
|
-
zPage: require("./zPage"),
|
|
29
|
-
zTester: require("./zTester"),
|
|
30
|
-
zCache: require("./zCache"),
|
|
31
|
-
zDropbox: require("./zDropbox"),
|
|
32
|
-
csrf: require("./csrf")
|
|
33
|
-
};
|
|
3
|
+
function lazyRequire(modulePath) {
|
|
4
|
+
return () => require(modulePath);
|
|
5
|
+
}
|
|
34
6
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
7
|
+
function optionalRequire(moduleName, installHint) {
|
|
8
|
+
return () => {
|
|
9
|
+
try {
|
|
10
|
+
return require(moduleName);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
if (error && error.code === "MODULE_NOT_FOUND") {
|
|
13
|
+
const message =
|
|
14
|
+
installHint ||
|
|
15
|
+
`Optional dependency "${moduleName}" is not installed. Install it to use this feature.`;
|
|
16
|
+
const wrapped = new Error(message);
|
|
17
|
+
wrapped.code = "MODULE_NOT_FOUND";
|
|
18
|
+
wrapped.cause = error;
|
|
19
|
+
throw wrapped;
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const exportsMap = {
|
|
27
|
+
access: lazyRequire("./access"),
|
|
28
|
+
Util: lazyRequire("./Util"),
|
|
29
|
+
myCache: lazyRequire("./cache"),
|
|
30
|
+
connection: lazyRequire("./connection"),
|
|
31
|
+
zDataTable: lazyRequire("./zdataTable"),
|
|
32
|
+
zDebug: lazyRequire("./debug"),
|
|
33
|
+
zForm: lazyRequire("./Form"),
|
|
34
|
+
io: lazyRequire("./io"),
|
|
35
|
+
zMail: lazyRequire("./Mail"),
|
|
36
|
+
moduleLib: lazyRequire("./moduleLib"),
|
|
37
|
+
Model: lazyRequire("./Model"),
|
|
38
|
+
zApp: lazyRequire("./zapp"),
|
|
39
|
+
zAppRouter: lazyRequire("./zAppRouter"),
|
|
40
|
+
zComponent: lazyRequire("./zComponent"),
|
|
41
|
+
zFn: lazyRequire("./zFn"),
|
|
42
|
+
zFunction: lazyRequire("./zFunction"),
|
|
43
|
+
zMenuRouter: lazyRequire("./zMenuRouter"),
|
|
44
|
+
zGeneratorRouter: lazyRequire("./zGeneratorRouter"),
|
|
45
|
+
zViewGenerator: lazyRequire("./zViewGenerator"),
|
|
46
|
+
zReport: lazyRequire("./zReport"),
|
|
47
|
+
zRoute: lazyRequire("./zRoute"),
|
|
48
|
+
zRole: lazyRequire("./zRole"),
|
|
49
|
+
zRoleRouter: lazyRequire("./zRoleRouter"),
|
|
50
|
+
zPage: lazyRequire("./zPage"),
|
|
51
|
+
zTester: lazyRequire("./zTester"),
|
|
52
|
+
zCache: lazyRequire("./zCache"),
|
|
53
|
+
zDropbox: lazyRequire("./zDropbox"),
|
|
54
|
+
csrf: lazyRequire("./csrf"),
|
|
55
|
+
puppeteer: optionalRequire(
|
|
56
|
+
"puppeteer",
|
|
57
|
+
'Optional dependency "puppeteer" is not installed. Install it with `npm install --include=optional zet-lib` or `npm install puppeteer` to use browser/PDF features.'
|
|
58
|
+
),
|
|
59
|
+
moment: lazyRequire("moment"),
|
|
60
|
+
ejs: lazyRequire("ejs"),
|
|
61
|
+
axios: lazyRequire("axios"),
|
|
62
|
+
Excel: lazyRequire("exceljsremake"),
|
|
63
|
+
pm2: () => {
|
|
53
64
|
try {
|
|
54
65
|
return require("pm2");
|
|
55
66
|
} catch (e) {
|
|
56
67
|
return null;
|
|
57
68
|
}
|
|
58
69
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return require("read-excel-file/node");
|
|
64
|
-
},
|
|
65
|
-
get JSZip() {
|
|
66
|
-
return require("jszip");
|
|
67
|
-
},
|
|
68
|
-
get pg() {
|
|
69
|
-
return require("pg");
|
|
70
|
-
}
|
|
70
|
+
nodemailer: lazyRequire("nodemailer"),
|
|
71
|
+
readXlsxFile: lazyRequire("read-excel-file/node"),
|
|
72
|
+
JSZip: lazyRequire("jszip"),
|
|
73
|
+
pg: lazyRequire("pg")
|
|
71
74
|
};
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
const exported = {};
|
|
77
|
+
|
|
78
|
+
for (const [key, resolver] of Object.entries(exportsMap)) {
|
|
79
|
+
Object.defineProperty(exported, key, {
|
|
80
|
+
enumerable: true,
|
|
81
|
+
configurable: true,
|
|
82
|
+
get() {
|
|
83
|
+
const value = resolver();
|
|
84
|
+
Object.defineProperty(exported, key, {
|
|
85
|
+
value,
|
|
86
|
+
enumerable: true,
|
|
87
|
+
configurable: true,
|
|
88
|
+
writable: false
|
|
89
|
+
});
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = exported;
|
|
@@ -516,18 +516,6 @@
|
|
|
516
516
|
}
|
|
517
517
|
})
|
|
518
518
|
|
|
519
|
-
$('.btn-minify').on('click', function () {
|
|
520
|
-
if (window.confirm('Minify all views in one line make your website faster ?')) {
|
|
521
|
-
ajaxPost('/<%- routeName%>/minify', {}, function (data) {
|
|
522
|
-
if (data.status == 0) {
|
|
523
|
-
toastr.error(data.message, data.title)
|
|
524
|
-
} else {
|
|
525
|
-
toastr.success(data.title, data.message)
|
|
526
|
-
}
|
|
527
|
-
})
|
|
528
|
-
}
|
|
529
|
-
})
|
|
530
|
-
|
|
531
519
|
$('.btn-generate-assets').on('click', function () {
|
|
532
520
|
if (window.confirm('Replace javascript assets with this one ?')) {
|
|
533
521
|
ajaxPost('/<%- routeName%>/generate-assets', {}, function (data) {
|
|
@@ -1,359 +1,359 @@
|
|
|
1
|
-
const router = require('express').Router();
|
|
2
|
-
const {csrf} = require('zet-lib');
|
|
3
|
-
const csrfProtection = csrf({cookie: true});
|
|
4
|
-
const {Util, access, connection, moduleLib, zDebug, zRoute, zRole, zDataTable, zForm} = require('zet-lib');
|
|
5
|
-
const MYMODEL = require('./../models/[[[TABLE_NAME]]]');
|
|
6
|
-
|
|
7
|
-
router.get('/', async (req, res) => {
|
|
8
|
-
await zRoute.attributeData(res, MYMODEL);
|
|
9
|
-
let dataTable = new zDataTable(res.locals);
|
|
10
|
-
dataTable.filterMODEL = await zRoute.dataTableFilterSync(req,res, MYMODEL, res.locals.gridFilter);
|
|
11
|
-
const levels = zRole.myLevel(req, res, MYMODEL.table);
|
|
12
|
-
dataTable.levels = levels;
|
|
13
|
-
res.render(`layouts/${layout}`, {
|
|
14
|
-
dataTable: dataTable,
|
|
15
|
-
levels : levels,
|
|
16
|
-
titleHeader: `<strong class="text text-info">${MYMODEL.title}</strong>`,
|
|
17
|
-
breadcrumb : zForm.breadcrumbIndex(),
|
|
18
|
-
myModal : zForm.modal({
|
|
19
|
-
attributeData: res.locals.attributeData,
|
|
20
|
-
visibles: res.locals.visibles,
|
|
21
|
-
invisibles: res.locals.invisibles,
|
|
22
|
-
routeName: MYMODEL.table,
|
|
23
|
-
}, LANGUAGE),
|
|
24
|
-
renderHead: `${MYMODEL.routeName}/indexcss.ejs`,
|
|
25
|
-
renderBody: `${MYMODEL.routeName}/index.ejs`,
|
|
26
|
-
renderEnd: `${MYMODEL.routeName}/indexjs.ejs`
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
router.post('/list', async (req, res) => {
|
|
31
|
-
const data = await zRoute.listData(req, res, MYMODEL, zRole);
|
|
32
|
-
res.json(data);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
router.get('/create', csrfProtection, async(req, res) => {
|
|
36
|
-
let data = MYMODEL.datas;
|
|
37
|
-
const zForms = await zRoute.formsFieldSync(req, res, MYMODEL, data);
|
|
38
|
-
res.render(`layouts/${layout}`, {
|
|
39
|
-
data: data,
|
|
40
|
-
zForms: zForms,
|
|
41
|
-
titleHeader: `${LANGUAGE['form_create']} : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
42
|
-
csrfToken: req.csrfToken(),
|
|
43
|
-
breadcrumb : zForm.breadcrumbCreate(MYMODEL.routeName),
|
|
44
|
-
renderBody: `${MYMODEL.routeName}/create.ejs`,
|
|
45
|
-
renderEnd: `${MYMODEL.routeName}/createjs.ejs`
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
router.post('/create', csrfProtection, async (req, res) => {
|
|
50
|
-
let json = Util.jsonSuccess(LANGUAGE['data_saved']);
|
|
51
|
-
try {
|
|
52
|
-
let data = zRoute.post(req,res, MYMODEL)[MYMODEL.routeName];
|
|
53
|
-
const validator = zRoute.validator(data, MYMODEL);
|
|
54
|
-
if(validator.status == 0) return res.json(validator.message);
|
|
55
|
-
const result = await zRoute.insertSQL(req, res, MYMODEL.table, data);
|
|
56
|
-
json.data=result;
|
|
57
|
-
} catch (err) {
|
|
58
|
-
if(Object.hasOwn(err,"sqlMessage")){
|
|
59
|
-
json = Util.flashError(err.sqlMessage);
|
|
60
|
-
} else {
|
|
61
|
-
json = Util.flashError(err.toString());
|
|
62
|
-
}
|
|
63
|
-
zDebug(req, res, err);
|
|
64
|
-
}
|
|
65
|
-
res.json(json);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
router.get('/update/:id', csrfProtection, async (req, res) => {
|
|
69
|
-
const id = parseInt(req.params.id);
|
|
70
|
-
const results = await connection.results({
|
|
71
|
-
select:zRoute.selectData(MYMODEL),
|
|
72
|
-
table: MYMODEL.table,
|
|
73
|
-
where: {
|
|
74
|
-
id: id,
|
|
75
|
-
company_id: res.locals.companyId
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
if (results.length == 0) {
|
|
79
|
-
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
80
|
-
return res.redirect('/' + MYMODEL.routeName);
|
|
81
|
-
}
|
|
82
|
-
let data = results[0];
|
|
83
|
-
const zForms = await zRoute.formsFieldSync(req, res, MYMODEL, data);
|
|
84
|
-
res.render(`layouts/${layout}`, {
|
|
85
|
-
data: data,
|
|
86
|
-
zForms: zForms,
|
|
87
|
-
titleHeader: `${LANGUAGE['form_update']} : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
88
|
-
csrfToken: req.csrfToken(),
|
|
89
|
-
breadcrumb : zForm.breadcrumbUpdate(MYMODEL.routeName, id),
|
|
90
|
-
renderBody: `${MYMODEL.routeName}/update.ejs`,
|
|
91
|
-
renderEnd: `${MYMODEL.routeName}/updatejs.ejs`,
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
router.post('/update/:id', csrfProtection, async (req, res) => {
|
|
96
|
-
let json = Util.jsonSuccess(LANGUAGE['data_saved']);
|
|
97
|
-
try {
|
|
98
|
-
const id = parseInt(req.params.id);
|
|
99
|
-
let data = zRoute.post(req,res, MYMODEL)[MYMODEL.routeName];
|
|
100
|
-
const validator = zRoute.validator(data, MYMODEL);
|
|
101
|
-
if(validator.status == 0) return res.json(validator.message);
|
|
102
|
-
const result = await zRoute.updateSQL(req, res,MYMODEL.table, data, {id:id});
|
|
103
|
-
json.data=result;
|
|
104
|
-
} catch (err) {
|
|
105
|
-
console.log(err)
|
|
106
|
-
if(Object.hasOwn(err,"sqlMessage")){
|
|
107
|
-
json = Util.flashError(err.sqlMessage);
|
|
108
|
-
} else {
|
|
109
|
-
json = Util.flashError(err.toString());
|
|
110
|
-
}
|
|
111
|
-
zDebug(req, res, err)
|
|
112
|
-
}
|
|
113
|
-
res.json(json);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
router.delete('/delete', async (req, res) => {
|
|
117
|
-
const id = req.body.id;
|
|
118
|
-
let json = Util.jsonSuccess(LANGUAGE['data_delete']);
|
|
119
|
-
try {
|
|
120
|
-
await zRoute.deleteSQL(MYMODEL.table, id, res.locals.companyId);
|
|
121
|
-
} catch (err) {
|
|
122
|
-
json = Util.flashError(err.toString());
|
|
123
|
-
zDebug(req, res, err)
|
|
124
|
-
}
|
|
125
|
-
res.json(json);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
router.get('/view/:id', async (req, res) => {
|
|
129
|
-
await zRoute.attributeData(res, MYMODEL);
|
|
130
|
-
const id = req.params.id;
|
|
131
|
-
let data = {};
|
|
132
|
-
let zForms = {};
|
|
133
|
-
try {
|
|
134
|
-
const results = await connection.results({select:zRoute.selectData(MYMODEL),table:MYMODEL.table,where:{id:id}});
|
|
135
|
-
if (results.length == 0) {
|
|
136
|
-
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
137
|
-
return res.redirect('/' + MYMODEL.routeName);
|
|
138
|
-
}
|
|
139
|
-
data = results[0];
|
|
140
|
-
zForms = await zRoute.viewFormsSync(req, res, MYMODEL, data);
|
|
141
|
-
} catch (err){
|
|
142
|
-
zDebug(req, res, err);
|
|
143
|
-
res.send("Err");
|
|
144
|
-
}
|
|
145
|
-
res.render(`layouts/${layout}`, {
|
|
146
|
-
data: data,
|
|
147
|
-
Util:Util,
|
|
148
|
-
zForms:zForms,
|
|
149
|
-
titleHeader: `View : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
150
|
-
breadcrumb : zForm.breadcrumbView(MYMODEL.routeName),
|
|
151
|
-
levels: zRole.myLevel(req, res, MYMODEL.table),
|
|
152
|
-
renderBody: `${MYMODEL.routeName}/view.ejs`
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
router.get('/excel-query', async (req,res) => {
|
|
157
|
-
await zRoute.excelQuery(req, res, MYMODEL);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
router.get('/excel', async (req, res) => {
|
|
161
|
-
const fields = MYMODEL.keysExcel;
|
|
162
|
-
const results = await connection.results({
|
|
163
|
-
table: MYMODEL.table,
|
|
164
|
-
where: {company_id: res.locals.companyId},
|
|
165
|
-
orderBy: ['id', 'DESC']
|
|
166
|
-
});
|
|
167
|
-
await zRoute.excel(req, res, MYMODEL, fields, results);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
router.get('/sample', async (req, res) => {
|
|
171
|
-
let fields = [];
|
|
172
|
-
for (let i = 0; i < MYMODEL.keysExcel.length; i++) {
|
|
173
|
-
if (!Util.in_array(MYMODEL.keysExcel[i], Util.nots)) {
|
|
174
|
-
fields.push(MYMODEL.keysExcel[i]);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
const results = await connection.results({
|
|
178
|
-
table:MYMODEL.table,
|
|
179
|
-
where:{
|
|
180
|
-
company_id:res.locals.companyId
|
|
181
|
-
},
|
|
182
|
-
orderBy:["id","desc"], limit:10
|
|
183
|
-
});
|
|
184
|
-
let callback=(result,field)=> {
|
|
185
|
-
return MYMODEL.widgets[field] && MYMODEL.widgets[field].name == 'datepicker' ? Util.dateSql(result[field]) : result[field];
|
|
186
|
-
};
|
|
187
|
-
await zRoute.excel(req, res, MYMODEL, fields, results, callback);
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
router.get('/import',csrfProtection, async (req, res) => {
|
|
191
|
-
const room = res.locals.token;
|
|
192
|
-
res.render(`layouts/${layout}`, {
|
|
193
|
-
room: room,
|
|
194
|
-
titleHeader: `Import / Upload data : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
195
|
-
csrfToken: req.csrfToken(),
|
|
196
|
-
breadcrumb : zForm.breadcrumbImport(MYMODEL.routeName),
|
|
197
|
-
renderBody: `${MYMODEL.routeName}/import.ejs`,
|
|
198
|
-
renderEnd: `${MYMODEL.routeName}/importjs.ejs`
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
router.post('/import', async(req, res) => {
|
|
204
|
-
res.json(await zRoute.import(req,res,MYMODEL));
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
router.get('/approval/:id', async (req, res) => {
|
|
208
|
-
await zRoute.attributeData(res, MYMODEL);
|
|
209
|
-
const id = req.params.id;
|
|
210
|
-
let data = {};
|
|
211
|
-
let data2 = {};
|
|
212
|
-
let zForms = {};
|
|
213
|
-
let zForms2 = {};
|
|
214
|
-
let result = {};
|
|
215
|
-
try {
|
|
216
|
-
result = await connection.result({table: MYMODEL.table, where: {id: id}});
|
|
217
|
-
if (!result.id) {
|
|
218
|
-
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
219
|
-
return res.redirect('/' + MYMODEL.routeName);
|
|
220
|
-
}
|
|
221
|
-
data=result;
|
|
222
|
-
moduleLib.editor(req, res);
|
|
223
|
-
zForms = await zRoute.viewFormsSync(req, res, MYMODEL, result);
|
|
224
|
-
const contentScript = `$("#submit_draft").on("click", function () {$("#status").val(1);ajaxPost("/zzapproval",$("#form-group").serializeArray(), function (data) {
|
|
225
|
-
if (data.status == 0) {
|
|
226
|
-
toastr.error(data.message, data.title);
|
|
227
|
-
} else {
|
|
228
|
-
toastr.success(data.title, data.message);
|
|
229
|
-
}
|
|
230
|
-
});});
|
|
231
|
-
$("#submit").on("click", function () {
|
|
232
|
-
$('[name="zapprovals[status]"]').val(2);
|
|
233
|
-
ajaxPost("/zzapproval",$("#form-group").serializeArray(), function (data) {
|
|
234
|
-
if (data.status == 0) {
|
|
235
|
-
toastr.error(data.message, data.title);
|
|
236
|
-
} else {
|
|
237
|
-
toastr.success(data.title, data.message);
|
|
238
|
-
location.href = "";
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
`;
|
|
243
|
-
await moduleLib.addScript(req, res, contentScript);
|
|
244
|
-
const MODEL_APROVALS = require("./../models/zapprovals");
|
|
245
|
-
const rows = await connection.results({
|
|
246
|
-
table: "zapprovals",
|
|
247
|
-
where: {table: MYMODEL.table, company_id: res.locals.companyId, id_data: id}
|
|
248
|
-
});
|
|
249
|
-
if (rows.length) {
|
|
250
|
-
data2 = rows[0];
|
|
251
|
-
} else {
|
|
252
|
-
let obj = {};
|
|
253
|
-
obj.token = Util.uuid();
|
|
254
|
-
obj.status = 1;
|
|
255
|
-
obj.table = MYMODEL.table;
|
|
256
|
-
obj.company_id = res.locals.companyId;
|
|
257
|
-
obj.id_data = id;
|
|
258
|
-
obj.created_by = res.locals.userId;
|
|
259
|
-
obj.updated_by = res.locals.userId;
|
|
260
|
-
obj.created_at = Util.now();
|
|
261
|
-
let zfields = await connection.result({table: "zfields", where: {table: MYMODEL.table}});
|
|
262
|
-
let jsonApproval = zfields.approval_json || {}
|
|
263
|
-
obj.template = jsonApproval.content || {}
|
|
264
|
-
let title = jsonApproval.title;
|
|
265
|
-
if (title) {
|
|
266
|
-
let titleData = title;
|
|
267
|
-
for (var key in data) {
|
|
268
|
-
titleData = Util.replaceAll(titleData, "{{" + key + "}}", data[key])
|
|
269
|
-
}
|
|
270
|
-
obj.title = titleData
|
|
271
|
-
}
|
|
272
|
-
if (jsonApproval.hasOwnProperty("approvers")) {
|
|
273
|
-
obj.approvers = JSON.stringify(jsonApproval.approvers);
|
|
274
|
-
obj.knowings = JSON.stringify(jsonApproval.knowings);
|
|
275
|
-
obj.type = 1;
|
|
276
|
-
}
|
|
277
|
-
//insert default data
|
|
278
|
-
await connection.insert({table: "zapprovals", data: obj});
|
|
279
|
-
data2 = obj;
|
|
280
|
-
}
|
|
281
|
-
zForms2 = await zRoute.formsFieldSync(req, res, MODEL_APROVALS, data2);
|
|
282
|
-
} catch (err) {
|
|
283
|
-
zDebug(req, res, err);
|
|
284
|
-
res.send("Err");
|
|
285
|
-
}
|
|
286
|
-
res.render(`layouts/${layout}`, {
|
|
287
|
-
zForms: zForms,
|
|
288
|
-
zForms2: zForms2,
|
|
289
|
-
data: result,
|
|
290
|
-
result:result,
|
|
291
|
-
data2: data2,
|
|
292
|
-
Util: Util,
|
|
293
|
-
levels: zRole.myLevel(req, res, MYMODEL.table),
|
|
294
|
-
breadcrumb : zForm.breadcrumbApproval(MYMODEL.routeName, id),
|
|
295
|
-
renderBody: `${MYMODEL.routeName}/approval.ejs`
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
router.get('/preview/:token', async (req, res) => {
|
|
300
|
-
let token = req.params.token;
|
|
301
|
-
let data = {}, data2 = {};
|
|
302
|
-
let template = "";
|
|
303
|
-
let footers = "";
|
|
304
|
-
try {
|
|
305
|
-
let zfields = await connection.result({table: "zfields", where: {table: MYMODEL.table}});
|
|
306
|
-
let jsonApproval = zfields.approval_json || {}
|
|
307
|
-
let mytemplate = jsonApproval.content || {}
|
|
308
|
-
let results = await connection.results({table: "zapprovals", where: {token: token}});
|
|
309
|
-
if (results.length == 0) {
|
|
310
|
-
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
311
|
-
return res.redirect('/' + MYMODEL.routeName);
|
|
312
|
-
}
|
|
313
|
-
if(results[0].status == 1){
|
|
314
|
-
await connection.update({
|
|
315
|
-
table : "zapprovals",
|
|
316
|
-
data: {
|
|
317
|
-
template : mytemplate
|
|
318
|
-
},
|
|
319
|
-
where : {
|
|
320
|
-
token:token
|
|
321
|
-
}
|
|
322
|
-
})
|
|
323
|
-
results = await connection.results({table: "zapprovals", where: {token: token}});
|
|
324
|
-
}
|
|
325
|
-
let MYMODEL2 = require("./../models/zapprovals")
|
|
326
|
-
data = await zRoute.viewTable(req, res, MYMODEL2, results[0], true);
|
|
327
|
-
let row = await connection.result({table: results[0].table, where: {id: results[0].id_data}});
|
|
328
|
-
data2 = await zRoute.viewTable(req, res, MYMODEL, row, true);
|
|
329
|
-
template = data.template;
|
|
330
|
-
let title = data.title || ""
|
|
331
|
-
for (var key in data2) {
|
|
332
|
-
template = Util.replaceAll(template, "{{" + key + "}}", data2[key])
|
|
333
|
-
title = Util.replaceAll(title, "{{" + key + "}}", data2[key])
|
|
334
|
-
}
|
|
335
|
-
data.title = title;
|
|
336
|
-
var details = await connection.results({table: "zapprovals_details", where: {title_id: results[0].id}});
|
|
337
|
-
if (details.length) {
|
|
338
|
-
footers = await zRoute.approversFooter(details);
|
|
339
|
-
}
|
|
340
|
-
} catch (err) {
|
|
341
|
-
zDebug(req, res, err);
|
|
342
|
-
res.send("Err");
|
|
343
|
-
}
|
|
344
|
-
res.render(`layouts/blank`, {
|
|
345
|
-
template: template,
|
|
346
|
-
data: data,
|
|
347
|
-
footers: footers,
|
|
348
|
-
Util: Util,
|
|
349
|
-
details: details,
|
|
350
|
-
renderBody: 'index/zapprovals_preview.ejs'
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
router.post('/grid', access, zRoute.postGrid);
|
|
355
|
-
router.post('/reload', access, zRoute.postGridReload);
|
|
356
|
-
router.post('/chains', access, zRoute.chains);
|
|
357
|
-
router.post('/get_attributes',access, zRoute.getAttributes);
|
|
358
|
-
|
|
359
|
-
module.exports = router;
|
|
1
|
+
const router = require('express').Router();
|
|
2
|
+
const {csrf} = require('zet-lib');
|
|
3
|
+
const csrfProtection = csrf({cookie: true});
|
|
4
|
+
const {Util, access, connection, moduleLib, zDebug, zRoute, zRole, zDataTable, zForm} = require('zet-lib');
|
|
5
|
+
const MYMODEL = require('./../models/[[[TABLE_NAME]]]');
|
|
6
|
+
|
|
7
|
+
router.get('/', async (req, res) => {
|
|
8
|
+
await zRoute.attributeData(res, MYMODEL);
|
|
9
|
+
let dataTable = new zDataTable(res.locals);
|
|
10
|
+
dataTable.filterMODEL = await zRoute.dataTableFilterSync(req,res, MYMODEL, res.locals.gridFilter);
|
|
11
|
+
const levels = zRole.myLevel(req, res, MYMODEL.table);
|
|
12
|
+
dataTable.levels = levels;
|
|
13
|
+
res.render(`layouts/${layout}`, {
|
|
14
|
+
dataTable: dataTable,
|
|
15
|
+
levels : levels,
|
|
16
|
+
titleHeader: `<strong class="text text-info">${MYMODEL.title}</strong>`,
|
|
17
|
+
breadcrumb : zForm.breadcrumbIndex(),
|
|
18
|
+
myModal : zForm.modal({
|
|
19
|
+
attributeData: res.locals.attributeData,
|
|
20
|
+
visibles: res.locals.visibles,
|
|
21
|
+
invisibles: res.locals.invisibles,
|
|
22
|
+
routeName: MYMODEL.table,
|
|
23
|
+
}, LANGUAGE),
|
|
24
|
+
renderHead: `${MYMODEL.routeName}/indexcss.ejs`,
|
|
25
|
+
renderBody: `${MYMODEL.routeName}/index.ejs`,
|
|
26
|
+
renderEnd: `${MYMODEL.routeName}/indexjs.ejs`
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
router.post('/list', async (req, res) => {
|
|
31
|
+
const data = await zRoute.listData(req, res, MYMODEL, zRole);
|
|
32
|
+
res.json(data);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
router.get('/create', csrfProtection, async(req, res) => {
|
|
36
|
+
let data = MYMODEL.datas;
|
|
37
|
+
const zForms = await zRoute.formsFieldSync(req, res, MYMODEL, data);
|
|
38
|
+
res.render(`layouts/${layout}`, {
|
|
39
|
+
data: data,
|
|
40
|
+
zForms: zForms,
|
|
41
|
+
titleHeader: `${LANGUAGE['form_create']} : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
42
|
+
csrfToken: req.csrfToken(),
|
|
43
|
+
breadcrumb : zForm.breadcrumbCreate(MYMODEL.routeName),
|
|
44
|
+
renderBody: `${MYMODEL.routeName}/create.ejs`,
|
|
45
|
+
renderEnd: `${MYMODEL.routeName}/createjs.ejs`
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
router.post('/create', csrfProtection, async (req, res) => {
|
|
50
|
+
let json = Util.jsonSuccess(LANGUAGE['data_saved']);
|
|
51
|
+
try {
|
|
52
|
+
let data = zRoute.post(req,res, MYMODEL)[MYMODEL.routeName];
|
|
53
|
+
const validator = zRoute.validator(data, MYMODEL);
|
|
54
|
+
if(validator.status == 0) return res.json(validator.message);
|
|
55
|
+
const result = await zRoute.insertSQL(req, res, MYMODEL.table, data);
|
|
56
|
+
json.data=result;
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if(Object.hasOwn(err,"sqlMessage")){
|
|
59
|
+
json = Util.flashError(err.sqlMessage);
|
|
60
|
+
} else {
|
|
61
|
+
json = Util.flashError(err.toString());
|
|
62
|
+
}
|
|
63
|
+
zDebug(req, res, err);
|
|
64
|
+
}
|
|
65
|
+
res.json(json);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
router.get('/update/:id', csrfProtection, async (req, res) => {
|
|
69
|
+
const id = parseInt(req.params.id);
|
|
70
|
+
const results = await connection.results({
|
|
71
|
+
select:zRoute.selectData(MYMODEL),
|
|
72
|
+
table: MYMODEL.table,
|
|
73
|
+
where: {
|
|
74
|
+
id: id,
|
|
75
|
+
company_id: res.locals.companyId
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
if (results.length == 0) {
|
|
79
|
+
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
80
|
+
return res.redirect('/' + MYMODEL.routeName);
|
|
81
|
+
}
|
|
82
|
+
let data = results[0];
|
|
83
|
+
const zForms = await zRoute.formsFieldSync(req, res, MYMODEL, data);
|
|
84
|
+
res.render(`layouts/${layout}`, {
|
|
85
|
+
data: data,
|
|
86
|
+
zForms: zForms,
|
|
87
|
+
titleHeader: `${LANGUAGE['form_update']} : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
88
|
+
csrfToken: req.csrfToken(),
|
|
89
|
+
breadcrumb : zForm.breadcrumbUpdate(MYMODEL.routeName, id),
|
|
90
|
+
renderBody: `${MYMODEL.routeName}/update.ejs`,
|
|
91
|
+
renderEnd: `${MYMODEL.routeName}/updatejs.ejs`,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
router.post('/update/:id', csrfProtection, async (req, res) => {
|
|
96
|
+
let json = Util.jsonSuccess(LANGUAGE['data_saved']);
|
|
97
|
+
try {
|
|
98
|
+
const id = parseInt(req.params.id);
|
|
99
|
+
let data = zRoute.post(req,res, MYMODEL)[MYMODEL.routeName];
|
|
100
|
+
const validator = zRoute.validator(data, MYMODEL);
|
|
101
|
+
if(validator.status == 0) return res.json(validator.message);
|
|
102
|
+
const result = await zRoute.updateSQL(req, res,MYMODEL.table, data, {id:id});
|
|
103
|
+
json.data=result;
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.log(err)
|
|
106
|
+
if(Object.hasOwn(err,"sqlMessage")){
|
|
107
|
+
json = Util.flashError(err.sqlMessage);
|
|
108
|
+
} else {
|
|
109
|
+
json = Util.flashError(err.toString());
|
|
110
|
+
}
|
|
111
|
+
zDebug(req, res, err)
|
|
112
|
+
}
|
|
113
|
+
res.json(json);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
router.delete('/delete', async (req, res) => {
|
|
117
|
+
const id = req.body.id;
|
|
118
|
+
let json = Util.jsonSuccess(LANGUAGE['data_delete']);
|
|
119
|
+
try {
|
|
120
|
+
await zRoute.deleteSQL(MYMODEL.table, id, res.locals.companyId);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
json = Util.flashError(err.toString());
|
|
123
|
+
zDebug(req, res, err)
|
|
124
|
+
}
|
|
125
|
+
res.json(json);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
router.get('/view/:id', async (req, res) => {
|
|
129
|
+
await zRoute.attributeData(res, MYMODEL);
|
|
130
|
+
const id = req.params.id;
|
|
131
|
+
let data = {};
|
|
132
|
+
let zForms = {};
|
|
133
|
+
try {
|
|
134
|
+
const results = await connection.results({select:zRoute.selectData(MYMODEL),table:MYMODEL.table,where:{id:id}});
|
|
135
|
+
if (results.length == 0) {
|
|
136
|
+
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
137
|
+
return res.redirect('/' + MYMODEL.routeName);
|
|
138
|
+
}
|
|
139
|
+
data = results[0];
|
|
140
|
+
zForms = await zRoute.viewFormsSync(req, res, MYMODEL, data);
|
|
141
|
+
} catch (err){
|
|
142
|
+
zDebug(req, res, err);
|
|
143
|
+
res.send("Err");
|
|
144
|
+
}
|
|
145
|
+
res.render(`layouts/${layout}`, {
|
|
146
|
+
data: data,
|
|
147
|
+
Util:Util,
|
|
148
|
+
zForms:zForms,
|
|
149
|
+
titleHeader: `View : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
150
|
+
breadcrumb : zForm.breadcrumbView(MYMODEL.routeName),
|
|
151
|
+
levels: zRole.myLevel(req, res, MYMODEL.table),
|
|
152
|
+
renderBody: `${MYMODEL.routeName}/view.ejs`
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
router.get('/excel-query', async (req,res) => {
|
|
157
|
+
await zRoute.excelQuery(req, res, MYMODEL);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
router.get('/excel', async (req, res) => {
|
|
161
|
+
const fields = MYMODEL.keysExcel;
|
|
162
|
+
const results = await connection.results({
|
|
163
|
+
table: MYMODEL.table,
|
|
164
|
+
where: {company_id: res.locals.companyId},
|
|
165
|
+
orderBy: ['id', 'DESC']
|
|
166
|
+
});
|
|
167
|
+
await zRoute.excel(req, res, MYMODEL, fields, results);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
router.get('/sample', async (req, res) => {
|
|
171
|
+
let fields = [];
|
|
172
|
+
for (let i = 0; i < MYMODEL.keysExcel.length; i++) {
|
|
173
|
+
if (!Util.in_array(MYMODEL.keysExcel[i], Util.nots)) {
|
|
174
|
+
fields.push(MYMODEL.keysExcel[i]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const results = await connection.results({
|
|
178
|
+
table:MYMODEL.table,
|
|
179
|
+
where:{
|
|
180
|
+
company_id:res.locals.companyId
|
|
181
|
+
},
|
|
182
|
+
orderBy:["id","desc"], limit:10
|
|
183
|
+
});
|
|
184
|
+
let callback=(result,field)=> {
|
|
185
|
+
return MYMODEL.widgets[field] && MYMODEL.widgets[field].name == 'datepicker' ? Util.dateSql(result[field]) : result[field];
|
|
186
|
+
};
|
|
187
|
+
await zRoute.excel(req, res, MYMODEL, fields, results, callback);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
router.get('/import',csrfProtection, async (req, res) => {
|
|
191
|
+
const room = res.locals.token;
|
|
192
|
+
res.render(`layouts/${layout}`, {
|
|
193
|
+
room: room,
|
|
194
|
+
titleHeader: `Import / Upload data : <strong><a href="/${MYMODEL.routeName}">${MYMODEL.title}</a></strong>`,
|
|
195
|
+
csrfToken: req.csrfToken(),
|
|
196
|
+
breadcrumb : zForm.breadcrumbImport(MYMODEL.routeName),
|
|
197
|
+
renderBody: `${MYMODEL.routeName}/import.ejs`,
|
|
198
|
+
renderEnd: `${MYMODEL.routeName}/importjs.ejs`
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
router.post('/import', async(req, res) => {
|
|
204
|
+
res.json(await zRoute.import(req,res,MYMODEL));
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
router.get('/approval/:id', async (req, res) => {
|
|
208
|
+
await zRoute.attributeData(res, MYMODEL);
|
|
209
|
+
const id = req.params.id;
|
|
210
|
+
let data = {};
|
|
211
|
+
let data2 = {};
|
|
212
|
+
let zForms = {};
|
|
213
|
+
let zForms2 = {};
|
|
214
|
+
let result = {};
|
|
215
|
+
try {
|
|
216
|
+
result = await connection.result({table: MYMODEL.table, where: {id: id}});
|
|
217
|
+
if (!result.id) {
|
|
218
|
+
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
219
|
+
return res.redirect('/' + MYMODEL.routeName);
|
|
220
|
+
}
|
|
221
|
+
data=result;
|
|
222
|
+
moduleLib.editor(req, res);
|
|
223
|
+
zForms = await zRoute.viewFormsSync(req, res, MYMODEL, result);
|
|
224
|
+
const contentScript = `$("#submit_draft").on("click", function () {$("#status").val(1);ajaxPost("/zzapproval",$("#form-group").serializeArray(), function (data) {
|
|
225
|
+
if (data.status == 0) {
|
|
226
|
+
toastr.error(data.message, data.title);
|
|
227
|
+
} else {
|
|
228
|
+
toastr.success(data.title, data.message);
|
|
229
|
+
}
|
|
230
|
+
});});
|
|
231
|
+
$("#submit").on("click", function () {
|
|
232
|
+
$('[name="zapprovals[status]"]').val(2);
|
|
233
|
+
ajaxPost("/zzapproval",$("#form-group").serializeArray(), function (data) {
|
|
234
|
+
if (data.status == 0) {
|
|
235
|
+
toastr.error(data.message, data.title);
|
|
236
|
+
} else {
|
|
237
|
+
toastr.success(data.title, data.message);
|
|
238
|
+
location.href = "";
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
`;
|
|
243
|
+
await moduleLib.addScript(req, res, contentScript);
|
|
244
|
+
const MODEL_APROVALS = require("./../models/zapprovals");
|
|
245
|
+
const rows = await connection.results({
|
|
246
|
+
table: "zapprovals",
|
|
247
|
+
where: {table: MYMODEL.table, company_id: res.locals.companyId, id_data: id}
|
|
248
|
+
});
|
|
249
|
+
if (rows.length) {
|
|
250
|
+
data2 = rows[0];
|
|
251
|
+
} else {
|
|
252
|
+
let obj = {};
|
|
253
|
+
obj.token = Util.uuid();
|
|
254
|
+
obj.status = 1;
|
|
255
|
+
obj.table = MYMODEL.table;
|
|
256
|
+
obj.company_id = res.locals.companyId;
|
|
257
|
+
obj.id_data = id;
|
|
258
|
+
obj.created_by = res.locals.userId;
|
|
259
|
+
obj.updated_by = res.locals.userId;
|
|
260
|
+
obj.created_at = Util.now();
|
|
261
|
+
let zfields = await connection.result({table: "zfields", where: {table: MYMODEL.table}});
|
|
262
|
+
let jsonApproval = zfields.approval_json || {}
|
|
263
|
+
obj.template = jsonApproval.content || {}
|
|
264
|
+
let title = jsonApproval.title;
|
|
265
|
+
if (title) {
|
|
266
|
+
let titleData = title;
|
|
267
|
+
for (var key in data) {
|
|
268
|
+
titleData = Util.replaceAll(titleData, "{{" + key + "}}", data[key])
|
|
269
|
+
}
|
|
270
|
+
obj.title = titleData
|
|
271
|
+
}
|
|
272
|
+
if (jsonApproval.hasOwnProperty("approvers")) {
|
|
273
|
+
obj.approvers = JSON.stringify(jsonApproval.approvers);
|
|
274
|
+
obj.knowings = JSON.stringify(jsonApproval.knowings);
|
|
275
|
+
obj.type = 1;
|
|
276
|
+
}
|
|
277
|
+
//insert default data
|
|
278
|
+
await connection.insert({table: "zapprovals", data: obj});
|
|
279
|
+
data2 = obj;
|
|
280
|
+
}
|
|
281
|
+
zForms2 = await zRoute.formsFieldSync(req, res, MODEL_APROVALS, data2);
|
|
282
|
+
} catch (err) {
|
|
283
|
+
zDebug(req, res, err);
|
|
284
|
+
res.send("Err");
|
|
285
|
+
}
|
|
286
|
+
res.render(`layouts/${layout}`, {
|
|
287
|
+
zForms: zForms,
|
|
288
|
+
zForms2: zForms2,
|
|
289
|
+
data: result,
|
|
290
|
+
result:result,
|
|
291
|
+
data2: data2,
|
|
292
|
+
Util: Util,
|
|
293
|
+
levels: zRole.myLevel(req, res, MYMODEL.table),
|
|
294
|
+
breadcrumb : zForm.breadcrumbApproval(MYMODEL.routeName, id),
|
|
295
|
+
renderBody: `${MYMODEL.routeName}/approval.ejs`
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
router.get('/preview/:token', async (req, res) => {
|
|
300
|
+
let token = req.params.token;
|
|
301
|
+
let data = {}, data2 = {};
|
|
302
|
+
let template = "";
|
|
303
|
+
let footers = "";
|
|
304
|
+
try {
|
|
305
|
+
let zfields = await connection.result({table: "zfields", where: {table: MYMODEL.table}});
|
|
306
|
+
let jsonApproval = zfields.approval_json || {}
|
|
307
|
+
let mytemplate = jsonApproval.content || {}
|
|
308
|
+
let results = await connection.results({table: "zapprovals", where: {token: token}});
|
|
309
|
+
if (results.length == 0) {
|
|
310
|
+
req.session.sessionFlash = Util.flashError(LANGUAGE['data_not_found']);
|
|
311
|
+
return res.redirect('/' + MYMODEL.routeName);
|
|
312
|
+
}
|
|
313
|
+
if(results[0].status == 1){
|
|
314
|
+
await connection.update({
|
|
315
|
+
table : "zapprovals",
|
|
316
|
+
data: {
|
|
317
|
+
template : mytemplate
|
|
318
|
+
},
|
|
319
|
+
where : {
|
|
320
|
+
token:token
|
|
321
|
+
}
|
|
322
|
+
})
|
|
323
|
+
results = await connection.results({table: "zapprovals", where: {token: token}});
|
|
324
|
+
}
|
|
325
|
+
let MYMODEL2 = require("./../models/zapprovals")
|
|
326
|
+
data = await zRoute.viewTable(req, res, MYMODEL2, results[0], true);
|
|
327
|
+
let row = await connection.result({table: results[0].table, where: {id: results[0].id_data}});
|
|
328
|
+
data2 = await zRoute.viewTable(req, res, MYMODEL, row, true);
|
|
329
|
+
template = data.template;
|
|
330
|
+
let title = data.title || ""
|
|
331
|
+
for (var key in data2) {
|
|
332
|
+
template = Util.replaceAll(template, "{{" + key + "}}", data2[key])
|
|
333
|
+
title = Util.replaceAll(title, "{{" + key + "}}", data2[key])
|
|
334
|
+
}
|
|
335
|
+
data.title = title;
|
|
336
|
+
var details = await connection.results({table: "zapprovals_details", where: {title_id: results[0].id}});
|
|
337
|
+
if (details.length) {
|
|
338
|
+
footers = await zRoute.approversFooter(details);
|
|
339
|
+
}
|
|
340
|
+
} catch (err) {
|
|
341
|
+
zDebug(req, res, err);
|
|
342
|
+
res.send("Err");
|
|
343
|
+
}
|
|
344
|
+
res.render(`layouts/blank`, {
|
|
345
|
+
template: template,
|
|
346
|
+
data: data,
|
|
347
|
+
footers: footers,
|
|
348
|
+
Util: Util,
|
|
349
|
+
details: details,
|
|
350
|
+
renderBody: 'index/zapprovals_preview.ejs'
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
router.post('/grid', access, zRoute.postGrid);
|
|
355
|
+
router.post('/reload', access, zRoute.postGridReload);
|
|
356
|
+
router.post('/chains', access, zRoute.chains);
|
|
357
|
+
router.post('/get_attributes',access, zRoute.getAttributes);
|
|
358
|
+
|
|
359
|
+
module.exports = router;
|
package/lib/zGeneratorRouter.js
CHANGED
|
@@ -5,8 +5,6 @@ const csrfProtection = csrf({ cookie: true });
|
|
|
5
5
|
const fs = require("fs-extra");
|
|
6
6
|
const axios = require("axios");
|
|
7
7
|
const getPm2 = require("./optionalPm2");
|
|
8
|
-
const uglifyJS = require("uglify-js");
|
|
9
|
-
const { minify } = require("html-minifier-terser");
|
|
10
8
|
const zRoute = require("./zRoute");
|
|
11
9
|
const connection = require("./connection");
|
|
12
10
|
const Util = require("./Util");
|
|
@@ -614,22 +612,10 @@ const generate = async (req, res) => {
|
|
|
614
612
|
if (!fs.existsSync(DIR_VIEW)) {
|
|
615
613
|
fs.mkdirSync(DIR_VIEW);
|
|
616
614
|
}
|
|
617
|
-
let compilesJS = ["createjs.ejs", "updatejs.ejs", "importjs.ejs"];
|
|
618
615
|
if (!dummy) {
|
|
619
616
|
for (const q in filesKey) {
|
|
620
617
|
console.log(q);
|
|
621
|
-
|
|
622
|
-
fs.writeFileSync(path.join(DIR_VIEW, q), filesKey[q]);
|
|
623
|
-
} else {
|
|
624
|
-
fs.writeFileSync(
|
|
625
|
-
path.join(DIR_VIEW, q),
|
|
626
|
-
await minify(filesKey[q], {
|
|
627
|
-
minifyJS: true,
|
|
628
|
-
minifyCSS: true,
|
|
629
|
-
collapseWhitespace: true,
|
|
630
|
-
})
|
|
631
|
-
);
|
|
632
|
-
}
|
|
618
|
+
fs.writeFileSync(path.join(DIR_VIEW, q), filesKey[q]);
|
|
633
619
|
console.log(`The files views of ${q} is saved!`);
|
|
634
620
|
}
|
|
635
621
|
}
|
|
@@ -657,17 +643,11 @@ const generate = async (req, res) => {
|
|
|
657
643
|
let relations = await zRoute.relations(req, res, MYMODEL.table);
|
|
658
644
|
//add script
|
|
659
645
|
let jsObj = zRoute.generateJS(req, res, MYMODEL, relations);
|
|
660
|
-
//minify script
|
|
661
|
-
let script = uglifyJS.minify(jsObj.script);
|
|
662
|
-
if (script.error) {
|
|
663
|
-
console.log(jsObj.script);
|
|
664
|
-
throw script.error;
|
|
665
|
-
}
|
|
666
646
|
let time = new Date().getTime();
|
|
667
647
|
Util.deleteAllFiles(path_script);
|
|
668
648
|
Util.deleteAllFiles(path_head);
|
|
669
649
|
Util.deleteAllFiles(path_end);
|
|
670
|
-
Util.writeFile(path.join(path_script, `${time}.js`), script
|
|
650
|
+
Util.writeFile(path.join(path_script, `${time}.js`), jsObj.script);
|
|
671
651
|
Util.writeFile(path.join(path_head, "head.txt"), jsObj.head);
|
|
672
652
|
Util.writeFile(path.join(path_end, "end.txt"), jsObj.end);
|
|
673
653
|
}
|
|
@@ -1589,10 +1569,7 @@ router.post("/generate-assets", async (req, res) => {
|
|
|
1589
1569
|
Util.deleteAllFiles(path_end);
|
|
1590
1570
|
Util.deleteAllFiles(path_script);
|
|
1591
1571
|
|
|
1592
|
-
|
|
1593
|
-
let script = uglifyJS.minify(jsObj.script);
|
|
1594
|
-
if (script.error) throw script.error;
|
|
1595
|
-
Util.writeFile(path.join(path_script, `${time}.js`), script.code);
|
|
1572
|
+
Util.writeFile(path.join(path_script, `${time}.js`), jsObj.script);
|
|
1596
1573
|
Util.writeFile(path.join(path_head, "head.txt"), jsObj.head);
|
|
1597
1574
|
Util.writeFile(path.join(path_end, "end.txt"), jsObj.end);
|
|
1598
1575
|
}
|
|
@@ -1602,63 +1579,6 @@ router.post("/generate-assets", async (req, res) => {
|
|
|
1602
1579
|
res.json(notifObj);
|
|
1603
1580
|
});
|
|
1604
1581
|
|
|
1605
|
-
router.post("/minify", async (req, res) => {
|
|
1606
|
-
let notifyObj = Util.jsonSuccess("Success to cached");
|
|
1607
|
-
try {
|
|
1608
|
-
notifyObj = await viewsMini();
|
|
1609
|
-
} catch (e) {
|
|
1610
|
-
console.log(e);
|
|
1611
|
-
notifyObj = Util.flashError(e.toString());
|
|
1612
|
-
}
|
|
1613
|
-
res.json(notifyObj);
|
|
1614
|
-
});
|
|
1615
|
-
|
|
1616
|
-
const viewsMini = async () => {
|
|
1617
|
-
let notifyObj = Util.jsonSuccess("Success");
|
|
1618
|
-
const viewDir = path.join(dirRoot, "views");
|
|
1619
|
-
const layoutsDir = path.join(dirRoot, "views", "layouts");
|
|
1620
|
-
let item;
|
|
1621
|
-
try {
|
|
1622
|
-
let views = Util.getAllFiles(viewDir);
|
|
1623
|
-
let options = {
|
|
1624
|
-
minifyJS: true,
|
|
1625
|
-
minifyCSS: true,
|
|
1626
|
-
collapseWhitespace: true,
|
|
1627
|
-
};
|
|
1628
|
-
const notViewDir = ["zgenerator", "layouts", "index", "zindex"];
|
|
1629
|
-
for (const dir of views) {
|
|
1630
|
-
console.log("dir :", dir);
|
|
1631
|
-
if (!Util.in_array(dir, notViewDir)) {
|
|
1632
|
-
let files = Util.getAllFiles(path.join(viewDir, dir));
|
|
1633
|
-
//console.log(files);
|
|
1634
|
-
for (item of files) {
|
|
1635
|
-
if (item.includes(".ejs")) {
|
|
1636
|
-
let filename = path.join(viewDir, dir, item);
|
|
1637
|
-
let content = Util.readFile(filename);
|
|
1638
|
-
let contentChange = await minify(content, options);
|
|
1639
|
-
fs.writeFileSync(filename, contentChange);
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
let layouts = Util.getAllFiles(layoutsDir);
|
|
1646
|
-
for (item of layouts) {
|
|
1647
|
-
if (item.includes(".ejs")) {
|
|
1648
|
-
let filename = path.join(layoutsDir, item);
|
|
1649
|
-
let content = Util.readFile(filename);
|
|
1650
|
-
let contentChange = await minify(content, options);
|
|
1651
|
-
fs.writeFileSync(filename, contentChange);
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
} catch (e) {
|
|
1655
|
-
notifyObj = Util.flashError(
|
|
1656
|
-
`error in item : ${item} , error str :${e.toString()}`
|
|
1657
|
-
);
|
|
1658
|
-
}
|
|
1659
|
-
return notifyObj;
|
|
1660
|
-
};
|
|
1661
|
-
|
|
1662
1582
|
router.post("/load-joins", async (req, res) => {
|
|
1663
1583
|
let jsonNotif = Util.jsonSuccess("Success");
|
|
1664
1584
|
let html = "";
|
package/lib/zPage.js
CHANGED
|
@@ -8,7 +8,6 @@ const nodemailer = require('nodemailer');
|
|
|
8
8
|
const qs = require('qs');
|
|
9
9
|
const moment = require('moment');
|
|
10
10
|
const getPm2 = require('./optionalPm2');
|
|
11
|
-
const { minify } = require('html-minifier-terser');
|
|
12
11
|
const connection = require('./connection');
|
|
13
12
|
const Util = require('./Util');
|
|
14
13
|
const myCache = require('./cache');
|
|
@@ -159,14 +158,7 @@ zpage.createRoute = (obj, token, layoutObj) => {
|
|
|
159
158
|
zpage.buildLayout = async (obj) => {
|
|
160
159
|
let name = Util.toName(obj.name);
|
|
161
160
|
if (obj.active) {
|
|
162
|
-
|
|
163
|
-
removeComments:true,
|
|
164
|
-
minifyJS:true,
|
|
165
|
-
minifyCSS:true,
|
|
166
|
-
collapseWhitespace: true
|
|
167
|
-
});
|
|
168
|
-
console.log(path.join(dirRoot, "views", "layouts", name + ".ejs"));
|
|
169
|
-
fs.writeFileSync(path.join(dirRoot, "views", "layouts", name + ".ejs"), html, 'utf-8');
|
|
161
|
+
fs.writeFileSync(path.join(dirRoot, "views", "layouts", name + ".ejs"), obj.code, 'utf-8');
|
|
170
162
|
if (process.env.NODE_ENV === "production") {
|
|
171
163
|
setTimeout(function () {
|
|
172
164
|
const pm2 = getPm2()
|
package/lib/zRoleRouter.js
CHANGED
|
@@ -2,9 +2,7 @@ const express = require('express')
|
|
|
2
2
|
const router = express.Router()
|
|
3
3
|
// setup route middlewares
|
|
4
4
|
const csrf = require('./csrf')
|
|
5
|
-
const bodyParser = require('body-parser')
|
|
6
5
|
const path = require('path')
|
|
7
|
-
const parseForm = bodyParser.urlencoded({ extended: true })
|
|
8
6
|
const csrfProtection = csrf({ cookie: true })
|
|
9
7
|
const getPm2 = require('./optionalPm2')
|
|
10
8
|
const env = process.env.NODE_ENV || 'development'
|
package/lib/zRoute.js
CHANGED
|
@@ -8,7 +8,6 @@ const qs = require("qs");
|
|
|
8
8
|
//for generate PDF
|
|
9
9
|
const puppeteer = require("puppeteer");
|
|
10
10
|
const ejs = require("ejs");
|
|
11
|
-
const uglifyJS = require("uglify-js");
|
|
12
11
|
const Excel = require("exceljsremake");
|
|
13
12
|
const fs = require("fs-extra");
|
|
14
13
|
const Util = require("./Util");
|
|
@@ -4123,8 +4122,7 @@ zRoute.moduleLib = (req, res, MYMODEL, relations, zForms = "", data = {}) => {
|
|
|
4123
4122
|
let time = new Date().getTime();
|
|
4124
4123
|
Util.deleteAllFiles(path_head);
|
|
4125
4124
|
Util.deleteAllFiles(path_end);
|
|
4126
|
-
|
|
4127
|
-
Util.writeFile(path.join(path_script, `${time}.js`), uglifyJS.minify(jsObj.script));
|
|
4125
|
+
Util.writeFile(path.join(path_script, `${time}.js`), jsObj.script);
|
|
4128
4126
|
Util.writeFile(path.join(path_head, "head.txt"), jsObj.head);
|
|
4129
4127
|
Util.writeFile(path.join(path_end, "end.txt"), jsObj.end);
|
|
4130
4128
|
end += `<script src="/runtime/script/${table}/${time}.js"></script>`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zet-lib",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "zet is a library that part of zet generator.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18"
|
|
@@ -21,41 +21,36 @@
|
|
|
21
21
|
"!lib/**/__tests__/"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"test": "npm run lint && npm run unit",
|
|
27
|
-
"unit": "nyc node test.js"
|
|
24
|
+
"test": "npm run unit",
|
|
25
|
+
"unit": "node -e \"console.log('No automated tests are configured for this repo yet.')\""
|
|
28
26
|
},
|
|
29
27
|
"sideEffects": false,
|
|
30
28
|
"dependencies": {
|
|
31
|
-
"axios": "^1.
|
|
29
|
+
"axios": "^1.18.1",
|
|
32
30
|
"dotenv": "^16.5.0",
|
|
33
31
|
"dropbox": "^10.34.0",
|
|
34
|
-
"ejs": "^
|
|
35
|
-
"exceljsremake": "^0.1.
|
|
32
|
+
"ejs": "^6.0.1",
|
|
33
|
+
"exceljsremake": "^0.1.5",
|
|
36
34
|
"express-zip": "^3.0.0",
|
|
37
35
|
"fs-extra": "^11.3.4",
|
|
38
|
-
"html-minifier-terser": "^7.2.0",
|
|
39
36
|
"isomorphic-fetch": "^3.0.0",
|
|
40
37
|
"js-sha256": "^0.11.1",
|
|
41
38
|
"jszip": "^3.10.1",
|
|
42
39
|
"moment": "^2.30.1",
|
|
43
40
|
"node-cache": "^5.1.2",
|
|
44
|
-
"nodemailer": "^
|
|
41
|
+
"nodemailer": "^9.0.3",
|
|
45
42
|
"pg": "^8.16.3",
|
|
46
|
-
"puppeteer": "^24.40.0",
|
|
47
43
|
"qs": "^6.14.0",
|
|
48
44
|
"randomstring": "^1.3.1",
|
|
49
45
|
"read-excel-file": "^5.8.0",
|
|
50
|
-
"socket.io": "^4.8.3"
|
|
51
|
-
"uglify-js": "^3.19.3"
|
|
46
|
+
"socket.io": "^4.8.3"
|
|
52
47
|
},
|
|
53
48
|
"optionalDependencies": {
|
|
54
|
-
"
|
|
49
|
+
"puppeteer": "^25.1.0",
|
|
50
|
+
"sharp": "^0.35.3"
|
|
55
51
|
},
|
|
56
52
|
"devDependencies": {
|
|
57
|
-
"nyc": "^18.0.0"
|
|
58
|
-
"standard": "^17.1.2"
|
|
53
|
+
"nyc": "^18.0.0"
|
|
59
54
|
},
|
|
60
55
|
"overrides": {
|
|
61
56
|
"istanbul-lib-processinfo": {
|