zet-lib 3.3.3 → 3.3.5
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/lib/Form.js +3 -1
- package/lib/views/zgenerator/routerApp.ejs +359 -359
- package/lib/zAppRouter.js +15 -1
- package/lib/zRoute.js +20 -16
- package/lib/zapp.js +2 -0
- package/package.json +1 -1
package/lib/Form.js
CHANGED
|
@@ -508,7 +508,9 @@ Form.field = (obj) => {
|
|
|
508
508
|
});
|
|
509
509
|
value = value || [];
|
|
510
510
|
value.map((item, index) => {
|
|
511
|
-
|
|
511
|
+
if (obj.dataObject && item in obj.dataObject) {
|
|
512
|
+
leftButtons += `<li><button class="btn btn-primary boxy" type="button">${obj.dataObject[item]}<input type="hidden" name='${obj.name}[]' value="${item}"></button></li>`;
|
|
513
|
+
}
|
|
512
514
|
});
|
|
513
515
|
|
|
514
516
|
displayForm += `<div id="dragdrop_${obj.id}" class="row contentfields">
|
|
@@ -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/zAppRouter.js
CHANGED
|
@@ -628,10 +628,24 @@ router.get("/session/:id", access, async (req, res) => {
|
|
|
628
628
|
// Ubah layout backend (per user / personalized: tiap user punya preferensi sendiri)
|
|
629
629
|
router.get("/layout_changes/:layout", access, async (req, res) => {
|
|
630
630
|
const selectedLayout = String(req.params.layout || "").replace(/\.ejs$/i, "");
|
|
631
|
-
|
|
631
|
+
// Prioritaskan redirect dari query param (lebih reliable daripada Referer header)
|
|
632
|
+
let backURL = req.query.redirect;
|
|
633
|
+
if (!(backURL && typeof backURL === "string" && backURL.startsWith("/") && !backURL.startsWith("//"))) {
|
|
634
|
+
backURL = req.header("Referer") || "/";
|
|
635
|
+
}
|
|
632
636
|
try {
|
|
633
637
|
if (req.session && req.session.user) {
|
|
634
638
|
req.session.user.layout = selectedLayout;
|
|
639
|
+
// Simpan ke database agar preferensi layout tetap setelah logout/login
|
|
640
|
+
try {
|
|
641
|
+
await connection.update({
|
|
642
|
+
table: "zuser",
|
|
643
|
+
data: { layout: selectedLayout },
|
|
644
|
+
where: { id: res.locals.userId },
|
|
645
|
+
});
|
|
646
|
+
} catch (dbErr) {
|
|
647
|
+
debug(req, res, dbErr);
|
|
648
|
+
}
|
|
635
649
|
}
|
|
636
650
|
res.locals.layout = selectedLayout;
|
|
637
651
|
} catch (err) {
|
package/lib/zRoute.js
CHANGED
|
@@ -5321,22 +5321,26 @@ zRoute.updateSQL = async (req, res, table, data, whereData) => {
|
|
|
5321
5321
|
data: data,
|
|
5322
5322
|
});
|
|
5323
5323
|
//save to history
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5324
|
+
try {
|
|
5325
|
+
connection.insert({
|
|
5326
|
+
table: "zhistory",
|
|
5327
|
+
data: {
|
|
5328
|
+
module_id: result.id,
|
|
5329
|
+
module: MYMODEL.table,
|
|
5330
|
+
data_1: JSON.stringify(result),
|
|
5331
|
+
data_2: JSON.stringify(myresult),
|
|
5332
|
+
data_1_date: result.updated_at,
|
|
5333
|
+
data_2_date: data.updated_at,
|
|
5334
|
+
created_by: userId,
|
|
5335
|
+
updated_by: userId,
|
|
5336
|
+
created_at: Util.now(),
|
|
5337
|
+
updated_at: Util.now(),
|
|
5338
|
+
company_id: res.locals.companyId,
|
|
5339
|
+
},
|
|
5340
|
+
});
|
|
5341
|
+
} catch (e) {
|
|
5342
|
+
console.log(e)
|
|
5343
|
+
}
|
|
5340
5344
|
zRoute.modelsCacheRenew(table, res.locals.companyId);
|
|
5341
5345
|
return myresult;
|
|
5342
5346
|
} else {
|
package/lib/zapp.js
CHANGED
|
@@ -68,6 +68,8 @@ module.exports = (req, res, next) => {
|
|
|
68
68
|
}
|
|
69
69
|
// Default layout jika user belum pilih; tiap user bisa punya layout berbeda
|
|
70
70
|
res.locals.layout = res.locals.layout || "admin";
|
|
71
|
+
// Sinkronkan ke global.layout agar route yang pakai variabel layout (tanpa res.locals) dapat preferensi user
|
|
72
|
+
global.layout = res.locals.layout;
|
|
71
73
|
global.COMPANY_ID = res.locals.companyId;
|
|
72
74
|
global.USER_ID = res.locals.userId;
|
|
73
75
|
res.locals.LANGUAGE = global.LANGUAGE;
|