zet-lib 1.0.23 → 1.0.24
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/index.js +1 -0
- package/lib/languages/lang_id.js +1 -1
- package/lib/views/generator.ejs +533 -0
- package/lib/views/generator_layout.ejs +267 -0
- package/lib/views/generatorjs.ejs +811 -0
- package/lib/zGeneratorRouter.js +1249 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1249 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const csrf = require('csurf');
|
|
4
|
+
const csrfProtection = csrf({cookie: true});
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
const axios = require('axios');
|
|
7
|
+
const pm2 = require('pm2');
|
|
8
|
+
const uglifyJS = require("uglify-js");
|
|
9
|
+
const {minify} = require('html-minifier-terser');
|
|
10
|
+
const zRoute = require('./zRoute');
|
|
11
|
+
const connection = require('./connection');
|
|
12
|
+
const Util = require('./Util');
|
|
13
|
+
const moduleLib = require('./moduleLib');
|
|
14
|
+
|
|
15
|
+
const nots = ['index','uploads','js','css','log','generator','zmenu','zgenerator','zfields','zrole','zfunction','zgrid','zgrid_default', 'zuser','zreport','zpage','zlayout','zerror','zuser_company','zconfig'];
|
|
16
|
+
const nots = [];
|
|
17
|
+
const generatorUrl = 'https://appmaker.monster';
|
|
18
|
+
//const generatorUrl = 'http://localhost:3000';
|
|
19
|
+
|
|
20
|
+
router.get('/', csrfProtection, async (req, res) => {
|
|
21
|
+
let table = req.query.table || "", route = "", jsonData = {}, zForms = {}, relations = {},
|
|
22
|
+
approvalDatas = {is_approval: false};
|
|
23
|
+
let datas = await axios.post(`${generatorUrl}/api/generator/index`, {
|
|
24
|
+
results: await zfields(),
|
|
25
|
+
fields: await connection.query(connection.showFullFields(table)),
|
|
26
|
+
table: table
|
|
27
|
+
});
|
|
28
|
+
const MYMODELS = myCache.get('MYMODELS');
|
|
29
|
+
zForms.obj = {};
|
|
30
|
+
jsonData = datas.data;
|
|
31
|
+
let sorting = "";
|
|
32
|
+
if (table) {
|
|
33
|
+
let contentScript = `var ZFIELDS = ${JSON.stringify(jsonData.rows, null, 2)};`
|
|
34
|
+
moduleLib.addScript(req, res, contentScript);
|
|
35
|
+
moduleLib.editor(req, res);
|
|
36
|
+
let MYMODEL_APPROVERS = MYMODELS['zapprovals'];
|
|
37
|
+
let zfieldData = await connection.result({
|
|
38
|
+
table: "zfields",
|
|
39
|
+
where: {
|
|
40
|
+
table: table
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
sorting = JSON.stringify(zfieldData.sorting);
|
|
44
|
+
approvalDatas = MYMODEL_APPROVERS.datas;
|
|
45
|
+
if (zfieldData) {
|
|
46
|
+
let approvalJSON = zfieldData.approval_json || {};
|
|
47
|
+
approvalDatas.is_approval = zfieldData.is_approval || false;
|
|
48
|
+
approvalDatas.title = approvalJSON.title || "";
|
|
49
|
+
approvalDatas.type = approvalJSON.type || 1;
|
|
50
|
+
approvalDatas.approvers = approvalJSON.approvers ? approvalJSON.approvers : [];
|
|
51
|
+
approvalDatas.knowings = approvalJSON.knowings || [];
|
|
52
|
+
approvalDatas.template = approvalJSON.content || "";
|
|
53
|
+
zForms = await zRoute.formsFieldSync(req, res, MYMODEL_APPROVERS, approvalDatas);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const jsonDatas = jsonData.datas;
|
|
58
|
+
const lock = nots.includes(table) ? 1 : 0;
|
|
59
|
+
const jsonDatasJson = jsonDatas.hasOwnProperty('json') && jsonDatas.json ? jsonDatas.json : {};
|
|
60
|
+
const checkDummy = Object.prototype.hasOwnProperty.call(jsonDatasJson, 'dummy') && jsonDatasJson.dummy ? 'checked' : '';
|
|
61
|
+
const renderData = {
|
|
62
|
+
datas: jsonDatas,
|
|
63
|
+
table: table,
|
|
64
|
+
rows: jsonData.rows,
|
|
65
|
+
checkDummy: checkDummy,
|
|
66
|
+
csrfToken: req.csrfToken(),
|
|
67
|
+
route: jsonData.route,
|
|
68
|
+
selects: jsonData.selects,
|
|
69
|
+
zForms: zForms,
|
|
70
|
+
relations: relations,
|
|
71
|
+
approvalDatas: approvalDatas,
|
|
72
|
+
sorting: sorting,
|
|
73
|
+
lock: lock,
|
|
74
|
+
routeName:res.locals.routeName,
|
|
75
|
+
bodyHTML : Util.readFile(`./views/generator.ejs`),
|
|
76
|
+
endHTML : Util.readFile(`./views/generatorjs.ejs`)
|
|
77
|
+
//renderBody: "zgenerator/index.ejs",
|
|
78
|
+
//renderEnd: "zgenerator/indexjs.ejs"
|
|
79
|
+
};
|
|
80
|
+
let dataRender = zRoute.renderHTML(renderData);
|
|
81
|
+
|
|
82
|
+
res.render('layout/generator',dataRender);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
router.post('/fields', async (req, res) => {
|
|
86
|
+
try {
|
|
87
|
+
let body = req.body;
|
|
88
|
+
let table = body.table || "";
|
|
89
|
+
let result = {}, fields = {}, rowsFields = [];
|
|
90
|
+
if (table) {
|
|
91
|
+
result = await connection.result({table: 'zfields', where: {table: table}});
|
|
92
|
+
fields = await connection.query(connection.showFullFields(table));
|
|
93
|
+
rowsFields = await connection.query(connection.describeTable(table))
|
|
94
|
+
}
|
|
95
|
+
let objData = {
|
|
96
|
+
result: result,
|
|
97
|
+
fields: fields,
|
|
98
|
+
rowsFields: rowsFields,
|
|
99
|
+
table: table
|
|
100
|
+
};
|
|
101
|
+
let datas = await axios.post(`${generatorUrl}/api/generator/modal`, objData);
|
|
102
|
+
res.json(datas.data)
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.log(e);
|
|
105
|
+
res.json(e.toString())
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
Create new Module/Table
|
|
111
|
+
*/
|
|
112
|
+
router.post("/", csrfProtection, async (req, res) => {
|
|
113
|
+
try {
|
|
114
|
+
let results = await axios.post(`${generatorUrl}/api/generator/create`, req.body);
|
|
115
|
+
let datas = results.data;
|
|
116
|
+
if (datas.status == 0) {
|
|
117
|
+
res.json(datas)
|
|
118
|
+
} else {
|
|
119
|
+
if (nots.includes(datas.post.table)) {
|
|
120
|
+
return res.json(Util.flashError("Table is locked"));
|
|
121
|
+
}
|
|
122
|
+
await connection.insert({
|
|
123
|
+
table: "zfields",
|
|
124
|
+
data: datas.post
|
|
125
|
+
});
|
|
126
|
+
await connection.query(datas.sql);
|
|
127
|
+
res.json(datas);
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
res.json(Util.flashError(err.toString()));
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
router.post("/reset", async (req, res) => {
|
|
135
|
+
try {
|
|
136
|
+
let json = Util.jsonSuccess("Reset Success");
|
|
137
|
+
let table = req.body.table;
|
|
138
|
+
if (nots.includes(table)) {
|
|
139
|
+
return res.json(Util.flashError("Table is locked"));
|
|
140
|
+
}
|
|
141
|
+
if (table) {
|
|
142
|
+
let results = await axios.post(`${generatorUrl}/api/generator/reset`, req.body);
|
|
143
|
+
let datas = results.data;
|
|
144
|
+
await connection.update({
|
|
145
|
+
table: "zfields",
|
|
146
|
+
data: datas,
|
|
147
|
+
where: {
|
|
148
|
+
table: table
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
json = Util.flashError("error");
|
|
153
|
+
}
|
|
154
|
+
res.json(json)
|
|
155
|
+
} catch (e) {
|
|
156
|
+
console.log(e.toString())
|
|
157
|
+
json = Util.flashError("error");
|
|
158
|
+
res.json(json)
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
router.post('/tabs', async (req, res) => {
|
|
163
|
+
let json = {status: 0, title: 'error', url: ''}
|
|
164
|
+
let body = req.body;
|
|
165
|
+
let table = body.table || "";
|
|
166
|
+
let title = body.title || "";
|
|
167
|
+
let tabs = body.tabs || [];
|
|
168
|
+
if (table == "") {
|
|
169
|
+
json.title = "table is empty";
|
|
170
|
+
return res.send(json)
|
|
171
|
+
}
|
|
172
|
+
if (title == "") {
|
|
173
|
+
json.title = "title is empty";
|
|
174
|
+
return res.send(json)
|
|
175
|
+
}
|
|
176
|
+
if (nots.includes(table)) {
|
|
177
|
+
return res.json(Util.flashError("Table is locked"));
|
|
178
|
+
}
|
|
179
|
+
let post = {};
|
|
180
|
+
post.table = table;
|
|
181
|
+
post.tabs = JSON.stringify(tabs);
|
|
182
|
+
post.name = title;
|
|
183
|
+
if (body.hasOwnProperty('json')) {
|
|
184
|
+
post.json = JSON.stringify(body.json);
|
|
185
|
+
} else {
|
|
186
|
+
post.json = JSON.stringify({dummy: 0});
|
|
187
|
+
}
|
|
188
|
+
let results = await connection.results({
|
|
189
|
+
table: "zfields",
|
|
190
|
+
where: {
|
|
191
|
+
table: table
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
if (results.length == 0) {
|
|
195
|
+
await connection.insert({table: "zfields", data: post})
|
|
196
|
+
} else {
|
|
197
|
+
await connection.update({table: "zfields", where: {id: results[0].id}, data: post});
|
|
198
|
+
}
|
|
199
|
+
json.status = 1;
|
|
200
|
+
json.url = '/generator?table=' + table;
|
|
201
|
+
res.send(json)
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
//after drag and drop then save
|
|
206
|
+
// and generate
|
|
207
|
+
router.post("/save_and_generate", csrfProtection, async (req, res) => {
|
|
208
|
+
try {
|
|
209
|
+
if (nots.includes(req.body.table)) {
|
|
210
|
+
return res.json(Util.flashError("Table is locked"));
|
|
211
|
+
}
|
|
212
|
+
const json = await generate(req, res);
|
|
213
|
+
res.json(json);
|
|
214
|
+
} catch (e) {
|
|
215
|
+
console.log(e);
|
|
216
|
+
res.status(400).json({message: e.toString()})
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const generate = async (req, res) => {
|
|
221
|
+
const body = req.body;
|
|
222
|
+
const table = body.table;
|
|
223
|
+
const MYMODELS = myCache.get('MYMODELS');
|
|
224
|
+
let MYMODEL = {};
|
|
225
|
+
let chains = [];
|
|
226
|
+
let datas;
|
|
227
|
+
let results;
|
|
228
|
+
let dummy = false;
|
|
229
|
+
//save data into table zfields
|
|
230
|
+
//console.log(JSON.stringify(body.others))
|
|
231
|
+
const others = body.others;
|
|
232
|
+
//return;
|
|
233
|
+
await saveToZFields(body);
|
|
234
|
+
|
|
235
|
+
let exist = await connection.query(connection.describeTable(table));
|
|
236
|
+
if (exist.length) {
|
|
237
|
+
body.rows = await connection.results({table: "zfields", where: {table: table}});
|
|
238
|
+
body.checks = await connection.query(`SELECT 'public.${table}'::regclass`);
|
|
239
|
+
} else {
|
|
240
|
+
let sql = `
|
|
241
|
+
CREATE TABLE ${table} (
|
|
242
|
+
id BIGSERIAL PRIMARY KEY,
|
|
243
|
+
company_id BIGINT NOT NULL,
|
|
244
|
+
updated_by BIGINT DEFAULT NULL,
|
|
245
|
+
created_by BIGINT DEFAULT NULL,
|
|
246
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
247
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
248
|
+
CONSTRAINT fk_${table}_company_id FOREIGN KEY (company_id) REFERENCES zcompany (id)
|
|
249
|
+
);`;
|
|
250
|
+
await connection.query(sql);
|
|
251
|
+
body.checks = await connection.query(`SELECT 'public.${table}'::regclass`);
|
|
252
|
+
body.rows = await connection.results({table: "zfields", where: {table: table}});
|
|
253
|
+
}
|
|
254
|
+
body.others = others;
|
|
255
|
+
results = await axios.post(`${generatorUrl}/api/generator/properties`, body);
|
|
256
|
+
datas = results.data;
|
|
257
|
+
if (datas.create_table.hasOwnProperty("sql")) {
|
|
258
|
+
await connection.query(datas.create_table.sql);
|
|
259
|
+
return generate(body);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let result = await connection.update({
|
|
263
|
+
table: 'zfields',
|
|
264
|
+
data: datas.updateFields.post,
|
|
265
|
+
where: {
|
|
266
|
+
id: datas.updateFields.id
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
let properties = result.properties;
|
|
271
|
+
//update if any chains
|
|
272
|
+
for (let key in properties) {
|
|
273
|
+
//override
|
|
274
|
+
properties[key].values.required = properties[key].values.required ? true : false;
|
|
275
|
+
properties[key].values.unique = properties[key].values.unique ? true : false;
|
|
276
|
+
var isChain = properties[key].values.isChain ? true : false;
|
|
277
|
+
properties[key].values.isChain = isChain;
|
|
278
|
+
if (isChain) {
|
|
279
|
+
chains.push(key)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (chains.length && chains.length < 2) {
|
|
283
|
+
return Util.flashError("Chains min 2 fields number...");
|
|
284
|
+
}
|
|
285
|
+
if (chains.length) {
|
|
286
|
+
let prop = chainings(table, chains);
|
|
287
|
+
for (const key in prop) {
|
|
288
|
+
if (prop[key].hasOwnProperty("chains")) {
|
|
289
|
+
chains = Object.keys(prop[key].chains);
|
|
290
|
+
if (chains.length) {
|
|
291
|
+
properties[key].values.chains = prop[key].chains;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
//update properties
|
|
297
|
+
result = await connection.update({
|
|
298
|
+
table: "zfields",
|
|
299
|
+
data: {
|
|
300
|
+
properties: JSON.stringify(properties)
|
|
301
|
+
},
|
|
302
|
+
where: {
|
|
303
|
+
table: table
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
//end chains
|
|
307
|
+
|
|
308
|
+
//generate file models routes views
|
|
309
|
+
body.columns = await connection.query(connection.describeTable(table));
|
|
310
|
+
body.constraintList = await connection.query(connection.constraintList(table));
|
|
311
|
+
body.result = result;
|
|
312
|
+
results = await axios.post(`${generatorUrl}/api/generator/generate`, body);
|
|
313
|
+
datas = results.data;
|
|
314
|
+
let files = datas.files;
|
|
315
|
+
for (let key in files) {
|
|
316
|
+
let filesKey = files[key];
|
|
317
|
+
if (key == "model") {
|
|
318
|
+
if (filesKey.hasOwnProperty("sql")) {
|
|
319
|
+
const sql = filesKey.sql || [];
|
|
320
|
+
for (let i = 0; i < sql.length; i++) {
|
|
321
|
+
console.log(i + "sql : " + sql[i])
|
|
322
|
+
await connection.query(sql[i]);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (filesKey.hasOwnProperty("alter")) {
|
|
326
|
+
const alter = filesKey.alter || [];
|
|
327
|
+
for (let i = 0; i < alter.length; i++) {
|
|
328
|
+
console.log(alter[i])
|
|
329
|
+
await connection.query(alter[i]);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (filesKey.hasOwnProperty("index")) {
|
|
333
|
+
const index = filesKey.index || [];
|
|
334
|
+
for (let i = 0; i < index.length; i++) {
|
|
335
|
+
console.log(index[i])
|
|
336
|
+
await connection.query(index[i]);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (filesKey.hasOwnProperty("fk")) {
|
|
340
|
+
let fk = filesKey.fk || [];
|
|
341
|
+
for (let i = 0; i < fk.length; i++) {
|
|
342
|
+
console.log(fk[i])
|
|
343
|
+
await connection.query(fk[i]);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (filesKey.hasOwnProperty("defaultValue")) {
|
|
347
|
+
const defaultValue = filesKey.defaultValue || [];
|
|
348
|
+
for (let i = 0; i < defaultValue.length; i++) {
|
|
349
|
+
console.log(defaultValue[i])
|
|
350
|
+
await connection.query(defaultValue[i]);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
//console.log(JSON.stringify(filesKey.modelObj))
|
|
354
|
+
//check if has chains here
|
|
355
|
+
MYMODEL = filesKey.modelObj;
|
|
356
|
+
|
|
357
|
+
//delete/clean zgrid after changes
|
|
358
|
+
await connection.delete({
|
|
359
|
+
table: "zgrid",
|
|
360
|
+
where: {
|
|
361
|
+
route_name: table
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
await connection.delete({
|
|
365
|
+
table: 'zgrid_default',
|
|
366
|
+
where: {
|
|
367
|
+
table: table
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
//insert into zgrid default
|
|
371
|
+
let datagrid = {
|
|
372
|
+
company_id: 1,
|
|
373
|
+
updated_by: 1,
|
|
374
|
+
created_by: 1,
|
|
375
|
+
created_at: Util.now(),
|
|
376
|
+
updated_at: Util.now()
|
|
377
|
+
};
|
|
378
|
+
datagrid.table = table;
|
|
379
|
+
datagrid.visibles = JSON.stringify(MYMODEL.grids.visibles);
|
|
380
|
+
datagrid.invisibles = JSON.stringify(MYMODEL.grids.invisibles);
|
|
381
|
+
datagrid.fields = JSON.stringify([...MYMODEL.grids.visibles, ...MYMODEL.grids.invisibles]);
|
|
382
|
+
await connection.insert({
|
|
383
|
+
table: 'zgrid_default',
|
|
384
|
+
data: datagrid
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
fs.writeFileSync(`${dirRoot}/models/${filesKey.filename}`, filesKey.content);
|
|
388
|
+
console.log(`The file model of ${filesKey.filename} is saved!`);
|
|
389
|
+
|
|
390
|
+
let widgets = MYMODEL.widgets;
|
|
391
|
+
let objChains = {}
|
|
392
|
+
let chainsTable = [];
|
|
393
|
+
let isChain = false;
|
|
394
|
+
for (let key in widgets) {
|
|
395
|
+
let hasChains = widgets[key].hasOwnProperty("isChain") ? widgets[key].isChain : false;
|
|
396
|
+
if (hasChains) {
|
|
397
|
+
isChain = true;
|
|
398
|
+
if (widgets[key].hasOwnProperty("table")) {
|
|
399
|
+
chainsTable.push(widget_table);
|
|
400
|
+
var widget_table = widgets[key].table;
|
|
401
|
+
objChains[widget_table] = {
|
|
402
|
+
key: key,
|
|
403
|
+
changes: []
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (isChain) {
|
|
410
|
+
for (let key in objChains) {
|
|
411
|
+
const model_table = MYMODELS[key];// require(`./../models/${key}`);
|
|
412
|
+
for (let q in model_table.widgets) {
|
|
413
|
+
if (model_table.widgets[q].hasOwnProperty("table")) {
|
|
414
|
+
if (Util.in_array(model_table.widgets[q].table, chainsTable)) {
|
|
415
|
+
const objChanges = {
|
|
416
|
+
target: objChains[key].key,
|
|
417
|
+
table: key,
|
|
418
|
+
column: q,
|
|
419
|
+
name: widgets[objChains[key].key].fields[1]
|
|
420
|
+
};
|
|
421
|
+
objChains[model_table.widgets[q].table].changes.push(objChanges);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
//console.log(JSON.stringify(objChains))
|
|
427
|
+
//update model
|
|
428
|
+
for (let key in objChains) {
|
|
429
|
+
const keykey = objChains[key].key;
|
|
430
|
+
widgets[keykey].chains = objChains[key].changes
|
|
431
|
+
}
|
|
432
|
+
MYMODEL.widgets = widgets;
|
|
433
|
+
let newModel = `module.exports = ${Util.newLine}${Util.tab}{${Util.newLine}`;
|
|
434
|
+
//newModel += JSON.stringify(MYMODEL, null, 2)
|
|
435
|
+
newModel += zRoute.buildFileModel(MYMODEL);
|
|
436
|
+
newModel += `${Util.tab}};`;
|
|
437
|
+
|
|
438
|
+
fs.writeFileSync(`${dirRoot}/models/${filesKey.filename}`, newModel);
|
|
439
|
+
//console.log(JSON.stringify(objChains))
|
|
440
|
+
}
|
|
441
|
+
//check model if it has select relation in concat
|
|
442
|
+
await scanning(MYMODEL);
|
|
443
|
+
}
|
|
444
|
+
//generate views
|
|
445
|
+
let DIR_VIEW = `${dirRoot}/views/${table}`;
|
|
446
|
+
if (key == "views") {
|
|
447
|
+
if (!fs.existsSync(DIR_VIEW)) {
|
|
448
|
+
fs.mkdirSync(DIR_VIEW);
|
|
449
|
+
}
|
|
450
|
+
let compilesJS = ['createjs.ejs', 'updatejs.ejs', 'importjs.ejs'];
|
|
451
|
+
|
|
452
|
+
let resultJSON = Object.prototype.hasOwnProperty.call(result,'json') ? result.json : {};
|
|
453
|
+
if(resultJSON.hasOwnProperty('dummy')) {
|
|
454
|
+
dummy = resultJSON.dummy;
|
|
455
|
+
}
|
|
456
|
+
if(!dummy) {
|
|
457
|
+
for (const q in filesKey) {
|
|
458
|
+
console.log(q);
|
|
459
|
+
if (Util.in_array(q, compilesJS)) {
|
|
460
|
+
fs.writeFileSync(`${DIR_VIEW}/${q}`, filesKey[q]);
|
|
461
|
+
/* console.log(filesKey[q]);
|
|
462
|
+
let myscript = filesKey[q];
|
|
463
|
+
myscript = myscript.replaceAll(`<script>`,'').replaceAll(`</script>`,'');
|
|
464
|
+
console.log(myscript);
|
|
465
|
+
let script = uglifyJS.minify(myscript);
|
|
466
|
+
if (script.error) throw script.error;
|
|
467
|
+
fs.writeFileSync(`${DIR_VIEW}/${q}`, script.code);*/
|
|
468
|
+
} else {
|
|
469
|
+
fs.writeFileSync(`${DIR_VIEW}/${q}`, await minify(filesKey[q],
|
|
470
|
+
{
|
|
471
|
+
minifyJS: true,
|
|
472
|
+
minifyCSS: true,
|
|
473
|
+
collapseWhitespace: true
|
|
474
|
+
}
|
|
475
|
+
));
|
|
476
|
+
}
|
|
477
|
+
console.log(`The files views of ${q} is saved!`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
if (key == "route") {
|
|
482
|
+
if(!dummy) {
|
|
483
|
+
fs.writeFileSync(`${dirRoot}/routes/${filesKey.filename}`, filesKey.content);
|
|
484
|
+
}
|
|
485
|
+
//console.log(`The files route of ${filesKey.filename} is saved!`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
//make a directory
|
|
490
|
+
if(!dummy) {
|
|
491
|
+
let path_script = `${dirRoot}/public/runtime/script/${table}`;
|
|
492
|
+
Util.dirExist(path_script, true);
|
|
493
|
+
let path_head = `${dirRoot}/public/runtime/head/${table}`;
|
|
494
|
+
Util.dirExist(path_head, true);
|
|
495
|
+
let path_end = `${dirRoot}/public/runtime/end/${table}`;
|
|
496
|
+
Util.dirExist(path_end, true);
|
|
497
|
+
//we need to generate javascript code into runtime
|
|
498
|
+
let relations = await zRoute.relations(req, res, MYMODEL.table);
|
|
499
|
+
//add script
|
|
500
|
+
let jsObj = zRoute.generateJS(req, res, MYMODEL, relations);
|
|
501
|
+
//minify script
|
|
502
|
+
let script = uglifyJS.minify(jsObj.script);
|
|
503
|
+
if (script.error) {
|
|
504
|
+
console.log(jsObj.script);
|
|
505
|
+
throw script.error;
|
|
506
|
+
}
|
|
507
|
+
let time = new Date().getTime();
|
|
508
|
+
Util.deleteAllFiles(path_script);
|
|
509
|
+
Util.deleteAllFiles(path_head);
|
|
510
|
+
Util.deleteAllFiles(path_end);
|
|
511
|
+
Util.writeFile(`${path_script}/${time}.js`, script.code);
|
|
512
|
+
Util.writeFile(`${path_head}/head.txt`, jsObj.head);
|
|
513
|
+
Util.writeFile(`${path_end}/end.txt`, jsObj.end);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
//restart pm2 module in production
|
|
517
|
+
if (process.env.NODE_ENV == "production") {
|
|
518
|
+
pm2.connect(function (err) {
|
|
519
|
+
if (err) {
|
|
520
|
+
console.log(err.toString());
|
|
521
|
+
}
|
|
522
|
+
pm2.restart(process.env.PM2_NAME, (err, proc) => {
|
|
523
|
+
//io.to(room).emit("message","Restart done")
|
|
524
|
+
});
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return Util.jsonSuccess("Success");
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
router.post('/savetabs', async (req, res) => {
|
|
532
|
+
let body = req.body;
|
|
533
|
+
let table = body.table;
|
|
534
|
+
let details = body.details;
|
|
535
|
+
let left = [], right = [], tabLeft = {}, tabRight = {};
|
|
536
|
+
let json = {status: 0, title: 'error', message: 'error', url: ''};
|
|
537
|
+
let obj = {}
|
|
538
|
+
obj.notabs = []
|
|
539
|
+
let labels = {};
|
|
540
|
+
let hasTab = false;
|
|
541
|
+
if (nots.includes(table)) {
|
|
542
|
+
return res.json(Util.flashError("Table is locked"));
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
let rows = await connection.results({table: "zfields", where: {table: table}});
|
|
546
|
+
if (rows.length > 0) {
|
|
547
|
+
let tabsValue = rows[0].tabs + "";
|
|
548
|
+
if (tabsValue.length > 5) {
|
|
549
|
+
hasTab = true;
|
|
550
|
+
let tabs = rows[0].tabs;
|
|
551
|
+
for (let i = 0; i < tabs.length; i++) {
|
|
552
|
+
obj['arr' + i] = [];
|
|
553
|
+
tabLeft['arr' + i] = [];
|
|
554
|
+
tabRight['arr' + i] = [];
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
for (let i = 0; i < details.length; i++) {
|
|
560
|
+
let name = details[i].name;
|
|
561
|
+
let value = details[i].value;
|
|
562
|
+
if (name.indexOf("___") > -1) {
|
|
563
|
+
let explode = name.split("___");
|
|
564
|
+
obj[explode[1]].push(explode[0])
|
|
565
|
+
labels[explode[0]] = value;
|
|
566
|
+
} else {
|
|
567
|
+
if (name == 'LEFT') {
|
|
568
|
+
if (value.indexOf("___") > -1) {
|
|
569
|
+
var explode = value.split("___");
|
|
570
|
+
tabLeft[explode[1]].push(explode[0])
|
|
571
|
+
} else {
|
|
572
|
+
left.push(value);
|
|
573
|
+
}
|
|
574
|
+
} else if (name == 'RIGHT') {
|
|
575
|
+
if (value.indexOf("___") > -1) {
|
|
576
|
+
let explode = value.split("___");
|
|
577
|
+
tabRight[explode[1]].push(explode[0])
|
|
578
|
+
} else {
|
|
579
|
+
right.push(value);
|
|
580
|
+
}
|
|
581
|
+
} else {
|
|
582
|
+
obj['notabs'].push(name);
|
|
583
|
+
labels[name] = value;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
let post = {}
|
|
588
|
+
post.labels = JSON.stringify(labels);
|
|
589
|
+
post.details = JSON.stringify(obj);
|
|
590
|
+
post.left = hasTab ? JSON.stringify(tabLeft) : JSON.stringify(left);
|
|
591
|
+
post.right = hasTab ? JSON.stringify(tabRight) : JSON.stringify(right);
|
|
592
|
+
//console.log(post.left)
|
|
593
|
+
//console.log(JSON.stringify(post))
|
|
594
|
+
try {
|
|
595
|
+
if (rows.length > 0) {
|
|
596
|
+
await connection.update({table: "zfields", data: post, where: {id: rows[0].id}})
|
|
597
|
+
} else {
|
|
598
|
+
post.table = table;
|
|
599
|
+
await connection.insert({table: "zfields", data: post})
|
|
600
|
+
}
|
|
601
|
+
json = {status: 1, title: 'Success', message: 'Success', url: ''}
|
|
602
|
+
} catch (error) {
|
|
603
|
+
json = Util.flashError(error.sqlMessage);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
res.send(json)
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
const columnLR = (items, dataName) => {
|
|
610
|
+
return `<div class="col-md-6"><ol class="mydragable divboxlittle" data-name="${dataName}">${items}</ol></div>`;
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
const columnOne = (items) => {
|
|
614
|
+
return `<div class="row sortable"><i class="fa fa-arrows icon-float"></i><div class="col-md-12"><ol class="mydragable divboxlittle" data-name="ONE_COLUMN">${items}</ol></div></div>`;
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
const reformatProperties = async (position, item, table, arr) => {
|
|
618
|
+
const newData = JSON.stringify(Util.arrayDelete(arr, item));
|
|
619
|
+
const data = {
|
|
620
|
+
[position]: newData
|
|
621
|
+
};
|
|
622
|
+
await connection.update({
|
|
623
|
+
table: "zfields",
|
|
624
|
+
data: data,
|
|
625
|
+
where: {
|
|
626
|
+
table: table
|
|
627
|
+
}
|
|
628
|
+
})
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
router.delete("/delete-table", csrfProtection, async (req, res) => {
|
|
632
|
+
let table = req.body.table;
|
|
633
|
+
let json = Util.jsonSuccess("Successfully delete module");
|
|
634
|
+
if (Util.in_array(table, nots)) {
|
|
635
|
+
return res.json(Util.flashError("Can not be deleted!"))
|
|
636
|
+
}
|
|
637
|
+
if (nots.includes(table)) {
|
|
638
|
+
return res.json(Util.flashError("Table is locked"));
|
|
639
|
+
}
|
|
640
|
+
try {
|
|
641
|
+
await connection.delete({
|
|
642
|
+
table: "zfields",
|
|
643
|
+
where: {
|
|
644
|
+
table: table
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
//await connection.query("DELETE FROM zfields WHERE `table` = ?", [table]);
|
|
648
|
+
await connection.query(`DROP table "${table}";`);
|
|
649
|
+
//delete file
|
|
650
|
+
let modelFile = dirRoot + "/models/" + table + ".js";
|
|
651
|
+
fs.stat(modelFile, function (err, stats) {
|
|
652
|
+
console.log(stats);//here we got all information of file in stats variable
|
|
653
|
+
if (err) {
|
|
654
|
+
return console.error(err);
|
|
655
|
+
} else {
|
|
656
|
+
fs.unlink(modelFile, function (err) {
|
|
657
|
+
if (err) return console.log(err);
|
|
658
|
+
console.log('file deleted successfully');
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
let routesFile = dirRoot + "/routes/" + table + ".js";
|
|
664
|
+
fs.stat(routesFile, function (err, stats) {
|
|
665
|
+
console.log(stats);//here we got all information of file in stats variable
|
|
666
|
+
if (err) {
|
|
667
|
+
return console.error(err);
|
|
668
|
+
} else {
|
|
669
|
+
fs.unlink(routesFile, function (err) {
|
|
670
|
+
if (err) return console.log(err);
|
|
671
|
+
console.log('file deleted successfully');
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
let runtimeFile = dirRoot + "/runtime/scripts/" + table + ".js";
|
|
677
|
+
fs.stat(runtimeFile, function (err, stats) {
|
|
678
|
+
if (err) {
|
|
679
|
+
return console.error(err);
|
|
680
|
+
} else {
|
|
681
|
+
fs.unlink(runtimeFile, function (err) {
|
|
682
|
+
if (err) return console.log(err);
|
|
683
|
+
console.log('file deleted successfully');
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
});
|
|
688
|
+
await connection.delete({
|
|
689
|
+
table: "zgrid",
|
|
690
|
+
where: {route_name: table}
|
|
691
|
+
});
|
|
692
|
+
if (table) {
|
|
693
|
+
const viewsFile = dirRoot + "/views/" + table;
|
|
694
|
+
fs.stat(viewsFile, function (err, stats) {
|
|
695
|
+
if (err) {
|
|
696
|
+
return console.error(err);
|
|
697
|
+
} else {
|
|
698
|
+
fs.rmdirSync(viewsFile, {recursive: true});
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
await connection.delete({
|
|
703
|
+
table: "zgrid_default",
|
|
704
|
+
where: {table: table}
|
|
705
|
+
});
|
|
706
|
+
} catch (e) {
|
|
707
|
+
json = Util.flashError(e.toString(), "")
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
res.json(json)
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
router.post("/add_field", csrfProtection, async (req, res) => {
|
|
714
|
+
try {
|
|
715
|
+
const body = req.body;
|
|
716
|
+
//console.log(JSON.stringify(body.others))
|
|
717
|
+
const table = body.table;
|
|
718
|
+
if (nots.includes(table)) {
|
|
719
|
+
return res.json(Util.flashError("Table is locked"));
|
|
720
|
+
}
|
|
721
|
+
body.zFields = await connection.results({table: "zfields", where: {table: table}});
|
|
722
|
+
const results = await axios.post(`${generatorUrl}/api/generator/create_field`, body);
|
|
723
|
+
const datas = results.data;
|
|
724
|
+
if (datas.status == 1) {
|
|
725
|
+
await connection.update({table: 'zfields', where: {table: table}, data: datas.post})
|
|
726
|
+
}
|
|
727
|
+
res.json(datas)
|
|
728
|
+
} catch (e) {
|
|
729
|
+
res.json(Util.flashError(e.toString()));
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
router.post('/add_container', async (req, res) => {
|
|
734
|
+
let others = req.body.others;
|
|
735
|
+
let table = req.body.table;
|
|
736
|
+
//console.log(JSON.stringify(req.body))
|
|
737
|
+
try {
|
|
738
|
+
if (others && table) {
|
|
739
|
+
await connection.update({
|
|
740
|
+
table: 'zfields',
|
|
741
|
+
data: {
|
|
742
|
+
others: others
|
|
743
|
+
},
|
|
744
|
+
where: {
|
|
745
|
+
table: table
|
|
746
|
+
}
|
|
747
|
+
})
|
|
748
|
+
}
|
|
749
|
+
} catch (e) {
|
|
750
|
+
return res.json(Util.flashError(e.toString()))
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
res.json(Util.jsonSuccess("Success"));
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
router.post("/setting_field", csrfProtection, async (req, res) => {
|
|
758
|
+
if (nots.includes(req.body.table)) {
|
|
759
|
+
return res.json(Util.flashError("Table is locked"));
|
|
760
|
+
}
|
|
761
|
+
const body = req.body;
|
|
762
|
+
const table = body.table;
|
|
763
|
+
const html = "";
|
|
764
|
+
body.result = await connection.result({table: "zfields", where: {table: table}});
|
|
765
|
+
const results = await axios.post(`${generatorUrl}/api/generator/modal_settings`, body);
|
|
766
|
+
const datas = results.data;
|
|
767
|
+
res.json(datas.html)
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
router.post("/save_setting", async (req, res) => {
|
|
772
|
+
const html = "", table = req.query.table || "";
|
|
773
|
+
let json = Util.jsonSuccess("Success to update");
|
|
774
|
+
try {
|
|
775
|
+
if (nots.includes(req.body.table)) {
|
|
776
|
+
return res.json(Util.flashError("Table is locked"));
|
|
777
|
+
}
|
|
778
|
+
const post = req.body;
|
|
779
|
+
let data = await connection.result({
|
|
780
|
+
table: "zfields",
|
|
781
|
+
where: {table: table}
|
|
782
|
+
})
|
|
783
|
+
let properties = data.properties ? data.properties : {};
|
|
784
|
+
let propertyKey = "";
|
|
785
|
+
for (var key in post) {
|
|
786
|
+
propertyKey = key;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
properties[propertyKey].values = post[propertyKey];
|
|
790
|
+
let insert = {
|
|
791
|
+
properties: JSON.stringify(properties)
|
|
792
|
+
};
|
|
793
|
+
await connection.update({
|
|
794
|
+
table: "zfields",
|
|
795
|
+
data: insert,
|
|
796
|
+
where: {table: table}
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
} catch (e) {
|
|
800
|
+
json = Util.flashError(e.toString())
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
res.json(json);
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
router.delete("/delete_field", csrfProtection, async (req, res) => {
|
|
808
|
+
let json = Util.jsonSuccess("Success to update");
|
|
809
|
+
try {
|
|
810
|
+
if (nots.includes(req.body.table)) {
|
|
811
|
+
return res.json(Util.flashError("Table is locked"));
|
|
812
|
+
}
|
|
813
|
+
const table = req.body.table, name = req.body.name;
|
|
814
|
+
let data = await connection.result({
|
|
815
|
+
table: "zfields",
|
|
816
|
+
where: {table: table}
|
|
817
|
+
});
|
|
818
|
+
let properties = data.properties ? data.properties : {};
|
|
819
|
+
delete properties[name];
|
|
820
|
+
let labels = data.labels ? data.labels : {};
|
|
821
|
+
delete labels[name];
|
|
822
|
+
|
|
823
|
+
let left = data.left ? data.left : [];
|
|
824
|
+
left = Util.arrayDelete(left, name);
|
|
825
|
+
let right = data.right ? data.right : [];
|
|
826
|
+
right = Util.arrayDelete(right, name);
|
|
827
|
+
let oneColumn = data.one_column ? data.one_column : [];
|
|
828
|
+
oneColumn = Util.arrayDelete(oneColumn, name);
|
|
829
|
+
let details = data.details ? data.details : {};
|
|
830
|
+
let detailsTemp = {}
|
|
831
|
+
for (var keys in details) {
|
|
832
|
+
detailsTemp[keys] = Util.arrayDelete(details[keys], name);
|
|
833
|
+
}
|
|
834
|
+
let newProperty = {};
|
|
835
|
+
newProperty.properties = JSON.stringify(properties);
|
|
836
|
+
newProperty.labels = JSON.stringify(labels);
|
|
837
|
+
newProperty.left = JSON.stringify(left);
|
|
838
|
+
newProperty.right = JSON.stringify(right);
|
|
839
|
+
newProperty.one_column = JSON.stringify(oneColumn);
|
|
840
|
+
newProperty.details = JSON.stringify(detailsTemp);
|
|
841
|
+
newProperty.sorting = JSON.stringify(data.sorting);
|
|
842
|
+
await connection.update({
|
|
843
|
+
table: "zfields",
|
|
844
|
+
data: newProperty,
|
|
845
|
+
where: {table: table}
|
|
846
|
+
});
|
|
847
|
+
//DROP COULUMN
|
|
848
|
+
//ALTER TABLE table_name DROP COLUMN IF EXISTS column_name;
|
|
849
|
+
await connection.query(`ALTER TABLE "${table}" DROP COLUMN IF EXISTS "${name}";`)
|
|
850
|
+
} catch (err) {
|
|
851
|
+
json = Util.flashError(err.toString())
|
|
852
|
+
console.log(err);
|
|
853
|
+
console.log("ada error di update zfields");
|
|
854
|
+
}
|
|
855
|
+
res.json(json);
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
router.post("/tab_rename", csrfProtection, async (req, res) => {
|
|
860
|
+
const html = "", table = req.body.table || "", name = req.body.name || "", id = req.body.id || 0;
|
|
861
|
+
let json = Util.jsonSuccess("Success to rename");
|
|
862
|
+
try {
|
|
863
|
+
if (table == "") {
|
|
864
|
+
return res.json(Util.flashError("table empty"))
|
|
865
|
+
}
|
|
866
|
+
if (name == "") {
|
|
867
|
+
return res.json(Util.flashError("name empty"));
|
|
868
|
+
}
|
|
869
|
+
let data = await connection.result({
|
|
870
|
+
table: "zfields",
|
|
871
|
+
where: {table: table}
|
|
872
|
+
});
|
|
873
|
+
const tabs = data.tabs || [];
|
|
874
|
+
let arr = []
|
|
875
|
+
tabs.forEach(function (item, index) {
|
|
876
|
+
if (index == id) {
|
|
877
|
+
arr.push(name);
|
|
878
|
+
} else {
|
|
879
|
+
arr.push(item);
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
let post = {
|
|
883
|
+
tabs: JSON.stringify(arr)
|
|
884
|
+
}
|
|
885
|
+
await connection.update({
|
|
886
|
+
table: "zfields",
|
|
887
|
+
data: post,
|
|
888
|
+
where: {
|
|
889
|
+
table: table
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
} catch (e) {
|
|
893
|
+
json = Util.flashError(e.toString())
|
|
894
|
+
}
|
|
895
|
+
res.json(json);
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
const zfields = async () => {
|
|
899
|
+
return await connection.results({
|
|
900
|
+
select: `id, "table", "name", "route",tabs,labels, details, "left","right",one_column, sorting, properties,hardcode_grid,others,json`,
|
|
901
|
+
table: "zfields",
|
|
902
|
+
orderBy: ['table', 'asc']
|
|
903
|
+
});
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
router.post('/load-form', async (req, res) => {
|
|
907
|
+
const table = req.body.table;
|
|
908
|
+
let json = Util.flashError("error");
|
|
909
|
+
const result = await connection.result({
|
|
910
|
+
table: "zfields",
|
|
911
|
+
where: {
|
|
912
|
+
table: table
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
if (result.id) {
|
|
916
|
+
json = Util.jsonSuccess("success");
|
|
917
|
+
json.data = result;
|
|
918
|
+
}
|
|
919
|
+
res.json(json)
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
var saveToZFields = async (body) => {
|
|
923
|
+
const table = body.table;
|
|
924
|
+
let is_approval = body.is_approval;
|
|
925
|
+
if (typeof body.is_approval == "string") {
|
|
926
|
+
if (body.is_approval == "false") {
|
|
927
|
+
is_approval = 0;
|
|
928
|
+
} else if (body.is_approval == "true") {
|
|
929
|
+
is_approval = 1;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
const zapprovals = {};
|
|
934
|
+
zapprovals.title = body.approval_title;
|
|
935
|
+
zapprovals.type = body.type;
|
|
936
|
+
zapprovals.approvers = body.approvers;
|
|
937
|
+
zapprovals.knowings = body.knowings;
|
|
938
|
+
zapprovals.content = body.template;
|
|
939
|
+
var data = {
|
|
940
|
+
index_ejs: body.index_ejs,
|
|
941
|
+
indexcss_ejs: body.indexcss_ejs,
|
|
942
|
+
indexjs_ejs: body.indexjs_ejs,
|
|
943
|
+
form_ejs: body.form_ejs,
|
|
944
|
+
create_ejs: body.create_ejs,
|
|
945
|
+
createjs_ejs: body.createjs_ejs,
|
|
946
|
+
update_ejs: body.update_ejs,
|
|
947
|
+
updatejs_ejs: body.updatejs_ejs,
|
|
948
|
+
import_ejs: body.import_ejs,
|
|
949
|
+
importjs_ejs: body.importjs_ejs,
|
|
950
|
+
view_ejs: body.view_ejs,
|
|
951
|
+
is_approval: is_approval || 0,
|
|
952
|
+
approval_json: JSON.stringify(zapprovals),
|
|
953
|
+
others: body.others
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
await connection.update({
|
|
957
|
+
table: "zfields",
|
|
958
|
+
data: data,
|
|
959
|
+
where: {
|
|
960
|
+
table: table
|
|
961
|
+
}
|
|
962
|
+
})
|
|
963
|
+
};
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
//drop down chains effect
|
|
967
|
+
const chainings = async (table, arr) => {
|
|
968
|
+
const results = await connection.query(connection.showFields(table));
|
|
969
|
+
const obj = {};
|
|
970
|
+
const tableObj = {};
|
|
971
|
+
for (let i = 0; i < results.length; i++) {
|
|
972
|
+
const result = results[i];
|
|
973
|
+
if (Util.in_array(result.COLUMN_NAME, arr)) {
|
|
974
|
+
obj[result.COLUMN_NAME] = {
|
|
975
|
+
table: result.REFERENCED_TABLE_NAME
|
|
976
|
+
}
|
|
977
|
+
tableObj[result.REFERENCED_TABLE_NAME] = result.COLUMN_NAME;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
for (const key in obj) {
|
|
982
|
+
const rows = await connection.query(connection.showFields(obj[key].table));
|
|
983
|
+
rows.forEach(function (row) {
|
|
984
|
+
for (var q in obj) {
|
|
985
|
+
if (row.REFERENCED_TABLE_NAME == obj[q].table) {
|
|
986
|
+
if (!obj[q].chains) {
|
|
987
|
+
obj[q].chains = {};
|
|
988
|
+
}
|
|
989
|
+
obj[q].chains[key] = {
|
|
990
|
+
column: row.COLUMN_NAME,
|
|
991
|
+
table: row.TABLE_NAME
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
return obj;
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
router.post('/sorting', async (req, res) => {
|
|
1001
|
+
let sorting = req.body.sorting;
|
|
1002
|
+
let table = req.body.table;
|
|
1003
|
+
await connection.update({
|
|
1004
|
+
table: "zfields",
|
|
1005
|
+
data: {
|
|
1006
|
+
sorting: sorting
|
|
1007
|
+
},
|
|
1008
|
+
where: {table: table}
|
|
1009
|
+
});
|
|
1010
|
+
res.send("OK")
|
|
1011
|
+
});
|
|
1012
|
+
|
|
1013
|
+
router.post("/export", async (req, res) => {
|
|
1014
|
+
const table = req.body.table;
|
|
1015
|
+
let json = Util.jsonSuccess("file Complete");
|
|
1016
|
+
if (table) {
|
|
1017
|
+
const result = await connection.result({
|
|
1018
|
+
table: "zfields",
|
|
1019
|
+
where: {
|
|
1020
|
+
table: table
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
const dir = `${dirRoot}/public/uploads/zgenerator`;
|
|
1024
|
+
if (!fs.existsSync(dir)) {
|
|
1025
|
+
fs.mkdirSync(dir);
|
|
1026
|
+
}
|
|
1027
|
+
const text = JSON.stringify(result);
|
|
1028
|
+
fs.writeFileSync(`${dir}/${table}.json`, text);
|
|
1029
|
+
} else {
|
|
1030
|
+
json = Util.flashError("no table selected")
|
|
1031
|
+
}
|
|
1032
|
+
res.json(json)
|
|
1033
|
+
})
|
|
1034
|
+
|
|
1035
|
+
router.post("/import", async (req, res) => {
|
|
1036
|
+
let json = Util.flashError("Error File")
|
|
1037
|
+
let table = "";
|
|
1038
|
+
try {
|
|
1039
|
+
let isEmptyFiles = Util.isEmptyObject(req.files);
|
|
1040
|
+
if (!isEmptyFiles) {
|
|
1041
|
+
const file = req.files["import-file"];
|
|
1042
|
+
const name = file.name;
|
|
1043
|
+
const mime = file.mimetype;
|
|
1044
|
+
if (mime == "application/json") {
|
|
1045
|
+
const string = file.data.toString('utf8');
|
|
1046
|
+
const jsonFile = JSON.parse(string);
|
|
1047
|
+
table = jsonFile.table;
|
|
1048
|
+
delete jsonFile.id;
|
|
1049
|
+
const data = {}
|
|
1050
|
+
for (const key in jsonFile) {
|
|
1051
|
+
let value = jsonFile[key];
|
|
1052
|
+
if (typeof value == "object") {
|
|
1053
|
+
value = JSON.stringify(value)
|
|
1054
|
+
}
|
|
1055
|
+
data[key] = value;
|
|
1056
|
+
}
|
|
1057
|
+
if (!data.tabs) {
|
|
1058
|
+
data.tabs = "[]";
|
|
1059
|
+
}
|
|
1060
|
+
data.company_id = 1;
|
|
1061
|
+
data.created_by = res.locals.userId || 1;
|
|
1062
|
+
data.updated_by = res.locals.userId || 1;
|
|
1063
|
+
const results = await connection.results({
|
|
1064
|
+
table: "zfields",
|
|
1065
|
+
where: {
|
|
1066
|
+
table: table
|
|
1067
|
+
}
|
|
1068
|
+
})
|
|
1069
|
+
if (results.length) {
|
|
1070
|
+
await connection.update({
|
|
1071
|
+
table: "zfields",
|
|
1072
|
+
data: data,
|
|
1073
|
+
where: {
|
|
1074
|
+
table: table
|
|
1075
|
+
}
|
|
1076
|
+
})
|
|
1077
|
+
} else {
|
|
1078
|
+
await connection.insert({
|
|
1079
|
+
table: "zfields",
|
|
1080
|
+
data: data,
|
|
1081
|
+
})
|
|
1082
|
+
}
|
|
1083
|
+
json = Util.jsonSuccess("Success to add module, please generate tax to make a file")
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
} catch (e) {
|
|
1087
|
+
console.log(e)
|
|
1088
|
+
json.message = e.toString();
|
|
1089
|
+
}
|
|
1090
|
+
json.table = table;
|
|
1091
|
+
res.json(json)
|
|
1092
|
+
});
|
|
1093
|
+
|
|
1094
|
+
/*
|
|
1095
|
+
Scanning relation id to name
|
|
1096
|
+
*/
|
|
1097
|
+
const scanning = async (MYMODEL) => {
|
|
1098
|
+
//let MYMODEL = require(`./../models/${table}`);
|
|
1099
|
+
//console.log(JSON.stringify(MYMODEL))
|
|
1100
|
+
let table = MYMODEL.table;
|
|
1101
|
+
const widgets = MYMODEL.widgets;
|
|
1102
|
+
const not_scanning = ['created_by', 'updated_by'];
|
|
1103
|
+
const concat_bracket = /(?<=\().+?(?=\))/g;
|
|
1104
|
+
let changeWidgets = {}
|
|
1105
|
+
let changes = [];
|
|
1106
|
+
for (let key in widgets) {
|
|
1107
|
+
if (widgets[key].name == "relation" || widgets[key].name == "dropdown_multi" || widgets[key].name == "typeahead") {
|
|
1108
|
+
if (!Util.in_array(key, not_scanning)) {
|
|
1109
|
+
let fields = widgets[key].fields;
|
|
1110
|
+
//let concat = fields[1].indexOf('CONCAT(') > -1 ? fields[1].substring()
|
|
1111
|
+
let arr = fields[1].match(concat_bracket) || [];
|
|
1112
|
+
if (arr.length) {
|
|
1113
|
+
let str = Util.replaceAll(arr[0], '"', '');
|
|
1114
|
+
let mysplits = str.indexOf(',') > -1 ? str.split(',') : [str];
|
|
1115
|
+
let MYMODEL_TABLE = require(`./../models/${widgets[key].table}`);
|
|
1116
|
+
let widgetsRelations = MYMODEL_TABLE.widgets;
|
|
1117
|
+
let relationsKeys = [];
|
|
1118
|
+
let relationsKeysObject = {}
|
|
1119
|
+
for (let k in widgetsRelations) {
|
|
1120
|
+
if (widgetsRelations[k].name == 'relation') {
|
|
1121
|
+
if (!Util.in_array(k, not_scanning)) {
|
|
1122
|
+
relationsKeys.push(k);
|
|
1123
|
+
relationsKeysObject[k] = `(SELECT ${widgetsRelations[k].fields[1]} FROM ${widgetsRelations[k].table} where id = `
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
let myarr = [];
|
|
1128
|
+
mysplits.forEach(function (item) {
|
|
1129
|
+
if (Util.in_array(item, relationsKeys)) {
|
|
1130
|
+
changes.push(key)
|
|
1131
|
+
myarr.push(relationsKeysObject[item] + ` ${item} )`)
|
|
1132
|
+
} else {
|
|
1133
|
+
myarr.push(item)
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
let myjoin = `CONCAT(${myarr.join(',')})`;
|
|
1137
|
+
widgets[key].fields = ['id', myjoin];
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
if (changes.length) {
|
|
1144
|
+
//rewrite model
|
|
1145
|
+
MYMODEL.widgets = widgets;
|
|
1146
|
+
let newModel = `module.exports = { ${Util.newLine}`;
|
|
1147
|
+
newModel += zRoute.buildFileModel(MYMODEL);
|
|
1148
|
+
newModel += `${Util.newLine}`;
|
|
1149
|
+
newModel += `}`;
|
|
1150
|
+
fs.writeFileSync(`${dirRoot}/models/${MYMODEL.table}.js`, newModel);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
//return MYMODEL;
|
|
1154
|
+
};
|
|
1155
|
+
|
|
1156
|
+
//generate all css/js assets
|
|
1157
|
+
router.post('/generate-assets', async (req, res) => {
|
|
1158
|
+
let notifObj = Util.jsonSuccess("Success, generate all assets");
|
|
1159
|
+
try {
|
|
1160
|
+
let MYMODELS = zRoute.MYMODELS();
|
|
1161
|
+
delete MYMODELS.zrole;
|
|
1162
|
+
for (let key in MYMODELS) {
|
|
1163
|
+
let MYMODEL = MYMODELS[key];
|
|
1164
|
+
let table = MYMODEL.table;
|
|
1165
|
+
let path_script = `${dirRoot}/public/runtime/script/${table}`;
|
|
1166
|
+
Util.dirExist(path_script, true);
|
|
1167
|
+
let path_head = `${dirRoot}/public/runtime/head/${table}`;
|
|
1168
|
+
Util.dirExist(path_head, true);
|
|
1169
|
+
let path_end = `${dirRoot}/public/runtime/end/${table}`;
|
|
1170
|
+
Util.dirExist(path_end, true);
|
|
1171
|
+
//we need to generate javascript code into runtime
|
|
1172
|
+
let relations = await zRoute.relations(req, res, MYMODEL.table);
|
|
1173
|
+
//add script
|
|
1174
|
+
let jsObj = zRoute.generateJS(req, res, MYMODEL, relations);
|
|
1175
|
+
let time = new Date().getTime();
|
|
1176
|
+
Util.deleteAllFiles(path_head);
|
|
1177
|
+
Util.deleteAllFiles(path_end);
|
|
1178
|
+
Util.deleteAllFiles(path_script);
|
|
1179
|
+
|
|
1180
|
+
//minify script
|
|
1181
|
+
let script = uglifyJS.minify(jsObj.script);
|
|
1182
|
+
if (script.error) throw script.error;
|
|
1183
|
+
Util.writeFile(`${path_script}/${time}.js`, script.code);
|
|
1184
|
+
Util.writeFile(`${path_head}/head.txt`, jsObj.head);
|
|
1185
|
+
Util.writeFile(`${path_end}/end.txt`, jsObj.end);
|
|
1186
|
+
}
|
|
1187
|
+
} catch (e) {
|
|
1188
|
+
notifObj = Util.flashError(e.toString());
|
|
1189
|
+
}
|
|
1190
|
+
res.json(notifObj);
|
|
1191
|
+
});
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
router.post('/minify', async (req, res) => {
|
|
1195
|
+
let notifyObj = Util.jsonSuccess("Success to cached");
|
|
1196
|
+
try {
|
|
1197
|
+
notifyObj = await viewsMini();
|
|
1198
|
+
} catch (e) {
|
|
1199
|
+
console.log(e);
|
|
1200
|
+
notifyObj = Util.flashError(e.toString())
|
|
1201
|
+
}
|
|
1202
|
+
res.json(notifyObj);
|
|
1203
|
+
});
|
|
1204
|
+
|
|
1205
|
+
const viewsMini = async () => {
|
|
1206
|
+
let notifyObj = Util.jsonSuccess("Success");
|
|
1207
|
+
const viewDir = `${dirRoot}/views`;
|
|
1208
|
+
const layoutsDir = `${dirRoot}/views/layouts`;
|
|
1209
|
+
let item;
|
|
1210
|
+
try {
|
|
1211
|
+
let views = Util.getAllFiles(viewDir);
|
|
1212
|
+
let options = {
|
|
1213
|
+
minifyJS: true,
|
|
1214
|
+
minifyCSS: true,
|
|
1215
|
+
collapseWhitespace: true
|
|
1216
|
+
};
|
|
1217
|
+
const notViewDir = ['zgenerator', 'layouts', 'index', 'zindex'];
|
|
1218
|
+
for (const dir of views) {
|
|
1219
|
+
console.log('dir :', dir);
|
|
1220
|
+
if (!Util.in_array(dir, notViewDir)) {
|
|
1221
|
+
let files = Util.getAllFiles(`${viewDir}/${dir}`);
|
|
1222
|
+
//console.log(files);
|
|
1223
|
+
for (item of files) {
|
|
1224
|
+
if (item.includes('.ejs')) {
|
|
1225
|
+
let filename = `${viewDir}/${dir}/${item}`;
|
|
1226
|
+
let content = Util.readFile(filename);
|
|
1227
|
+
let contentChange = await minify(content, options);
|
|
1228
|
+
fs.writeFileSync(filename, contentChange);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
let layouts = Util.getAllFiles(layoutsDir);
|
|
1235
|
+
for (item of layouts) {
|
|
1236
|
+
if (item.includes('.ejs')) {
|
|
1237
|
+
let filename = `${layoutsDir}//${item}`;
|
|
1238
|
+
let content = Util.readFile(filename);
|
|
1239
|
+
let contentChange = await minify(content, options);
|
|
1240
|
+
fs.writeFileSync(filename, contentChange);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
} catch (e) {
|
|
1244
|
+
notifyObj = Util.flashError(`error in item : ${item} , error str :${e.toString()}`);
|
|
1245
|
+
}
|
|
1246
|
+
return notifyObj;
|
|
1247
|
+
};
|
|
1248
|
+
|
|
1249
|
+
module.exports = router;
|