zet-lib 1.3.39 → 1.3.40
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/LICENSE +21 -21
- package/README.md +15 -15
- package/lib/ErrorWithCode.js +6 -6
- package/lib/Form.js +1019 -1019
- package/lib/Mail.js +68 -68
- package/lib/Modal.js +95 -95
- package/lib/Pool.js +437 -437
- package/lib/UI.js +7 -7
- package/lib/Util.js +1384 -1384
- package/lib/access.js +6 -6
- package/lib/cache.js +3 -3
- package/lib/connection.js +409 -409
- package/lib/debug.js +22 -22
- package/lib/index.js +36 -36
- package/lib/io.js +44 -44
- package/lib/languages/lang_en.js +125 -125
- package/lib/languages/lang_fr.js +125 -125
- package/lib/languages/lang_id.js +126 -126
- package/lib/languages/lang_jp.js +125 -125
- package/lib/moduleLib.js +661 -661
- package/lib/tableForm.js +10 -10
- package/lib/views/generator.ejs +598 -598
- package/lib/views/generator_layout.ejs +224 -224
- package/lib/views/generatorjs.ejs +927 -927
- package/lib/zAppRouter.js +1637 -1637
- package/lib/zCache.js +301 -301
- package/lib/zComponent.js +27 -27
- package/lib/zFn.js +58 -58
- package/lib/zFunction.js +20 -20
- package/lib/zGeneratorRouter.js +1641 -1641
- package/lib/zMenuRouter.js +556 -556
- package/lib/zPage.js +188 -188
- package/lib/zReport.js +982 -982
- package/lib/zRole.js +256 -256
- package/lib/zRoleRouter.js +609 -609
- package/lib/zRoute.js +5025 -5024
- package/lib/zTester.js +93 -93
- package/lib/zapp.js +65 -65
- package/lib/zdataTable.js +330 -330
- package/package.json +56 -56
package/lib/zMenuRouter.js
CHANGED
|
@@ -1,556 +1,556 @@
|
|
|
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 {Util, connection, zRole, zCache } = require('zet-lib');
|
|
7
|
-
const Util = require('./Util');
|
|
8
|
-
const connection = require('./connection');
|
|
9
|
-
const zRole = require('./zRole');
|
|
10
|
-
const zCache = require('./zCache');
|
|
11
|
-
const moduleLib = require('./moduleLib');
|
|
12
|
-
const config = require('dotenv').config();
|
|
13
|
-
const ejs = require('ejs');
|
|
14
|
-
|
|
15
|
-
/*
|
|
16
|
-
icons list for tabler and set to /public/js
|
|
17
|
-
*/
|
|
18
|
-
const iconList = () => {
|
|
19
|
-
const dir = `${dirRoot}/public/assets/icons`;
|
|
20
|
-
const icons = fs.readdirSync(dir);
|
|
21
|
-
return icons;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
router.get('/', async function (req, res, next) {
|
|
25
|
-
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
26
|
-
if(Object.prototype.hasOwnProperty.call(levels,'index')) {
|
|
27
|
-
if(!levels.index) {
|
|
28
|
-
return res.redirect(process.env.APP_AFTER_LOGIN);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
let name = "Standart";
|
|
32
|
-
let arr = [{"text":"Home","href":"zdashboard","icon":"fas fa-home","target":"_self","title":""}];
|
|
33
|
-
let hasAccessMenu = false;
|
|
34
|
-
let companyId = res.locals.companyId;
|
|
35
|
-
let id = req.query.id;
|
|
36
|
-
let findArr = [];
|
|
37
|
-
let idChanges;
|
|
38
|
-
let rows= await connection.results({
|
|
39
|
-
table: "zmenu",
|
|
40
|
-
where : {
|
|
41
|
-
company_id : companyId
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
if (rows.length > 0) {
|
|
45
|
-
hasAccessMenu = true;
|
|
46
|
-
//check id changes
|
|
47
|
-
let rowsChanges = rows.filter((item) => item.active == 1);
|
|
48
|
-
idChanges = rowsChanges[0].id;
|
|
49
|
-
if (id) {
|
|
50
|
-
await connection.update({
|
|
51
|
-
table : "zmenu",
|
|
52
|
-
data: {
|
|
53
|
-
active:0
|
|
54
|
-
},
|
|
55
|
-
where : {
|
|
56
|
-
company_id: companyId
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
await connection.update({
|
|
60
|
-
table : "zmenu",
|
|
61
|
-
data : {
|
|
62
|
-
active : 1,
|
|
63
|
-
},
|
|
64
|
-
where : {
|
|
65
|
-
id: id
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
} else {
|
|
69
|
-
id =1;
|
|
70
|
-
let selected = rows.filter(item=>item.active == 1)[0] || {}
|
|
71
|
-
id = selected.id;
|
|
72
|
-
name = selected.name;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
findArr = await connection.results({
|
|
76
|
-
table:"zmenu",
|
|
77
|
-
where: {
|
|
78
|
-
id:id
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
arr = findArr[0].json;
|
|
82
|
-
let refresh = 0;
|
|
83
|
-
if (id != idChanges) {
|
|
84
|
-
refresh = 1;
|
|
85
|
-
}
|
|
86
|
-
zCache.MENU();
|
|
87
|
-
if(!levels.update) {
|
|
88
|
-
hasAccessMenu = false;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let datas = {
|
|
92
|
-
hasAccessMenu: hasAccessMenu,
|
|
93
|
-
rows: rows,
|
|
94
|
-
name: name,
|
|
95
|
-
arr: arr,
|
|
96
|
-
id: id,
|
|
97
|
-
refresh: refresh,
|
|
98
|
-
menuApp: "Menu Generator",
|
|
99
|
-
}
|
|
100
|
-
const bodyHTML = ejs.render(body,datas);
|
|
101
|
-
const endBody = ejs.render(js, datas);
|
|
102
|
-
const headBody = ejs.render(css);
|
|
103
|
-
datas.bodyHTML = bodyHTML;
|
|
104
|
-
moduleLib.addModule(req,res,headBody,true);
|
|
105
|
-
moduleLib.addModule(req,res,endBody);
|
|
106
|
-
res.render("zgenerator/layout", datas );
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
router.post('/', csrfProtection, async(req,res) => {
|
|
110
|
-
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
111
|
-
if(Object.prototype.hasOwnProperty.call(levels,'create')) {
|
|
112
|
-
if(!levels.create) {
|
|
113
|
-
return Util.flashError('Not allowed')
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
let body = req.body;
|
|
117
|
-
let companyId = res.locals.companyId;
|
|
118
|
-
let id = body.name;
|
|
119
|
-
let json = body.json || [];
|
|
120
|
-
if (!id){
|
|
121
|
-
return res.json(Util.jsonError("name", "name can not be blank!"))
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
let data = {
|
|
125
|
-
company_id: companyId,
|
|
126
|
-
json: json,
|
|
127
|
-
updated_by: res.locals.userId
|
|
128
|
-
};
|
|
129
|
-
let cb = Util.jsonSuccess("Success.. Please relogin to see the changes!");
|
|
130
|
-
try {
|
|
131
|
-
let rows = await connection.results({
|
|
132
|
-
table : "zmenu",
|
|
133
|
-
where : {
|
|
134
|
-
company_id : companyId,
|
|
135
|
-
id: id
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
if (rows.length > 0) {
|
|
139
|
-
await connection.update({
|
|
140
|
-
table : "zmenu",
|
|
141
|
-
data:data,
|
|
142
|
-
where : {
|
|
143
|
-
id:rows[0].id
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
}
|
|
147
|
-
} catch (e) {
|
|
148
|
-
cb = Util.flashError(JSON.stringify(e))
|
|
149
|
-
}
|
|
150
|
-
zCache.MENU();
|
|
151
|
-
|
|
152
|
-
res.json(cb)
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
router.post('/edit', async(req,res) => {
|
|
156
|
-
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
157
|
-
if(Object.prototype.hasOwnProperty.call(levels,'update')) {
|
|
158
|
-
if(!levels.update) {
|
|
159
|
-
return res.json(Util.flashError('Not allowed'));
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
let name = req.body.name || "";
|
|
163
|
-
let id = req.body.id;
|
|
164
|
-
if(name.length < 3) {
|
|
165
|
-
return res.json(Util.flashError("name is empty or is not completed"));
|
|
166
|
-
}
|
|
167
|
-
let json = Util.jsonSuccess(LANGUAGE.success);
|
|
168
|
-
await connection.update({
|
|
169
|
-
table : "zmenu",
|
|
170
|
-
data : {
|
|
171
|
-
name : req.body.name,
|
|
172
|
-
updated_at : Util.now(),
|
|
173
|
-
updated_by : res.locals.userId
|
|
174
|
-
},
|
|
175
|
-
where : {
|
|
176
|
-
id : req.body.id
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
res.json(json);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
router.post('/add', async(req,res) => {
|
|
185
|
-
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
186
|
-
if(Object.prototype.hasOwnProperty.call(levels,'create')) {
|
|
187
|
-
if(!levels.create) {
|
|
188
|
-
return res.json(Util.flashError('Not allowed'));
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
let name = req.body.name || "";
|
|
192
|
-
if(name.length < 3) {
|
|
193
|
-
return res.json(Util.flashError("name is empty or is not completed"));
|
|
194
|
-
}
|
|
195
|
-
let json = Util.jsonSuccess(LANGUAGE.success);
|
|
196
|
-
await connection.insert({
|
|
197
|
-
table : "zmenu",
|
|
198
|
-
data : {
|
|
199
|
-
name : req.body.name,
|
|
200
|
-
updated_at : Util.now(),
|
|
201
|
-
created_at : Util.now(),
|
|
202
|
-
updated_by : res.locals.userId,
|
|
203
|
-
created_by : res.locals.userId,
|
|
204
|
-
company_id : res.locals.companyId
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
res.json(json);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
router.delete('/delete',async (req,res) => {
|
|
212
|
-
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
213
|
-
if(Object.prototype.hasOwnProperty.call(levels,'delete')) {
|
|
214
|
-
if(!levels.delete) {
|
|
215
|
-
return Util.flashError('Not allowed');
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
let id = req.body.id;
|
|
219
|
-
await connection.delete({
|
|
220
|
-
table :"zmenu",
|
|
221
|
-
where : {
|
|
222
|
-
id : id,
|
|
223
|
-
company_id : res.locals.companyId
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
let json = Util.jsonSuccess(LANGUAGE.success);
|
|
227
|
-
res.json(json);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
const body = `<section class="mt-4">
|
|
231
|
-
<div class="row">
|
|
232
|
-
<div class="col-md-5 mb-2">
|
|
233
|
-
<div class="card mb-3 wow fadeIn">
|
|
234
|
-
<div class="card-header bg-success text-white">Edit item</div>
|
|
235
|
-
<div class="card-body">
|
|
236
|
-
<form id="frmEdit">
|
|
237
|
-
<div class="form-group">
|
|
238
|
-
<div class="input-group mb-3">
|
|
239
|
-
<input type="text" class="form-control item-menu form-control-lg" name="text" id="text" placeholder="Text">
|
|
240
|
-
<div class="input-group-append">
|
|
241
|
-
<button class="btn btn-md btn-outline-default m-0 px-3 py-2 z-depth-0 waves-effect" id="myEditor_icon" type="button" id="button-addon2">Button</button>
|
|
242
|
-
</div>
|
|
243
|
-
<input type="hidden" name="icon" class="item-menu">
|
|
244
|
-
</div>
|
|
245
|
-
</div>
|
|
246
|
-
|
|
247
|
-
<div class="form-group">
|
|
248
|
-
<label for="href">URL</label>
|
|
249
|
-
<input type="text" class="form-control item-menu" id="href" name="href" placeholder="URL">
|
|
250
|
-
</div>
|
|
251
|
-
<div class="form-group">
|
|
252
|
-
<label for="target">Target</label>
|
|
253
|
-
<select name="target" id="target" class="form-control item-menu">
|
|
254
|
-
<option value="_self">Self</option>
|
|
255
|
-
<option value="_blank">Blank</option>
|
|
256
|
-
<option value="_top">Top</option>
|
|
257
|
-
</select>
|
|
258
|
-
</div>
|
|
259
|
-
<div class="form-group">
|
|
260
|
-
<label for="title">Tooltip</label>
|
|
261
|
-
<input type="text" name="title" class="form-control item-menu" id="title" placeholder="Tooltip">
|
|
262
|
-
</div>
|
|
263
|
-
</form>
|
|
264
|
-
</div>
|
|
265
|
-
<div class="card-footer">
|
|
266
|
-
<button type="button" id="btnUpdate" class="btn btn-sm btn-primary" disabled><i class="fas fa-sync-alt"></i> Update</button>
|
|
267
|
-
<button type="button" id="btnAdd" class="btn btn-sm btn-success"><i class="fas fa-plus"></i> Add</button>
|
|
268
|
-
</div>
|
|
269
|
-
</div>
|
|
270
|
-
|
|
271
|
-
<div class="row">
|
|
272
|
-
<div class="col-md-12">
|
|
273
|
-
<p class="note note-light">
|
|
274
|
-
<strong>Note:</strong> Using link below to find all <strong>icon</strong> available options and
|
|
275
|
-
advanced customization.<br>
|
|
276
|
-
See <a target="_blank" href="https://tabler-icons.io/" class="text-reset"><strong>https://tabler-icons.io/</strong></a>
|
|
277
|
-
</p>
|
|
278
|
-
</div>
|
|
279
|
-
</div>
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
<div class="row">
|
|
283
|
-
<div class="col-md-12">
|
|
284
|
-
<div class="card mb-3 wow fadeIn">
|
|
285
|
-
<div class="card-header"><h2>Menu List</h2></div>
|
|
286
|
-
<div class="card-body">
|
|
287
|
-
<table class="table">
|
|
288
|
-
<thead>
|
|
289
|
-
<tr>
|
|
290
|
-
<th>#</th>
|
|
291
|
-
<th>Choice</th>
|
|
292
|
-
<th>ID</th>
|
|
293
|
-
<th>Name</th>
|
|
294
|
-
<th>Action</th>
|
|
295
|
-
</tr>
|
|
296
|
-
</thead>
|
|
297
|
-
<tbody>
|
|
298
|
-
<% for(var i = 0;i < rows.length; i++) { %>
|
|
299
|
-
<tr>
|
|
300
|
-
<td><%- i + 1 %></td>
|
|
301
|
-
<td><a href="/zmenu?id=<%- rows[i].id %>&name=<%- rows[i].name %>"
|
|
302
|
-
class="btn btn-sm <%- id == rows[i].id ? "btn-success" : "btn-default" %>">Choice</a>
|
|
303
|
-
</td>
|
|
304
|
-
<td>
|
|
305
|
-
<%- rows[i].id %>
|
|
306
|
-
</td>
|
|
307
|
-
<td>
|
|
308
|
-
<a href="/zmenu?id=<%- rows[i].id %>&name=<%- rows[i].name %>"><%- rows[i].name %></a>
|
|
309
|
-
</td>
|
|
310
|
-
<td>
|
|
311
|
-
<div class="btn-group float-right">
|
|
312
|
-
|
|
313
|
-
<a data-name="<%- rows[i].name %>" data-id="<%- rows[i].id %>" class="btn btn-primary btn-sm edit-menu " data-toggle="modal" data-target="#editModal" href="#">Edit</a>
|
|
314
|
-
|
|
315
|
-
<% if (rows[i].id != id) { %>
|
|
316
|
-
<a data-id="<%- rows[i].id %>" class="btn btn-danger btn-sm delete-menu" href="#"><i class="fas fa-trash-alt"></i></a>
|
|
317
|
-
<% } %>
|
|
318
|
-
</div>
|
|
319
|
-
</td>
|
|
320
|
-
</tr>
|
|
321
|
-
<% } %>
|
|
322
|
-
</tbody>
|
|
323
|
-
</table>
|
|
324
|
-
</div>
|
|
325
|
-
</div>
|
|
326
|
-
</div>
|
|
327
|
-
</div>
|
|
328
|
-
</div>
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
<div class="col-md-7 mb-2">
|
|
332
|
-
<div class="card mb-3 wow fadeIn">
|
|
333
|
-
<div class="card-header secondary-color-dark text-white font-weight-bold">Menu</div>
|
|
334
|
-
|
|
335
|
-
<div class="card-body">
|
|
336
|
-
<div class="input-group">
|
|
337
|
-
<select class="form-control form-select" name="name" id="name">
|
|
338
|
-
<% for(var i = 0;i < rows.length; i++) {
|
|
339
|
-
let selected = rows[i].id == id ? ' selected ' : '';
|
|
340
|
-
%>
|
|
341
|
-
<option value="<%- rows[i].id %>" <%- selected %>><%- rows[i].name %></option>
|
|
342
|
-
<%} %>
|
|
343
|
-
|
|
344
|
-
</select>
|
|
345
|
-
<div class="input-group-btn">
|
|
346
|
-
<button id="btnOut" type="button" class="btn btn-sm btn-success"><i class="glyphicon glyphicon-ok"></i> Save </button>
|
|
347
|
-
|
|
348
|
-
<button id="btn-add" type="button" class="btn btn-sm btn-info " data-toggle="modal" data-target="#addModal"><i class="fas fa-plus-circle"></i> Add </button>
|
|
349
|
-
|
|
350
|
-
</div>
|
|
351
|
-
</div>
|
|
352
|
-
</div>
|
|
353
|
-
<div class="card-body" id="cont">
|
|
354
|
-
<ul id="myEditor" class="sortableLists list-group"></ul>
|
|
355
|
-
</div>
|
|
356
|
-
|
|
357
|
-
<div class="card-footer">
|
|
358
|
-
|
|
359
|
-
</div>
|
|
360
|
-
</div>
|
|
361
|
-
|
|
362
|
-
<div class="row" style="display: none">
|
|
363
|
-
<label for="out">Output:</label>
|
|
364
|
-
<textarea id="out" class="form-control" cols="50" rows="10"></textarea>
|
|
365
|
-
</div>
|
|
366
|
-
|
|
367
|
-
</div>
|
|
368
|
-
</div>
|
|
369
|
-
</section>
|
|
370
|
-
|
|
371
|
-
<!-- Modal Add -->
|
|
372
|
-
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
|
373
|
-
aria-hidden="true">
|
|
374
|
-
<div class="modal-dialog" role="document">
|
|
375
|
-
<div class="modal-content">
|
|
376
|
-
<div class="modal-header">
|
|
377
|
-
<h5 class="modal-title" id="exampleModalLabel">Add menu</h5>
|
|
378
|
-
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
379
|
-
<span aria-hidden="true">×</span>
|
|
380
|
-
</button>
|
|
381
|
-
</div>
|
|
382
|
-
<div class="modal-body">
|
|
383
|
-
<form>
|
|
384
|
-
<input type="text" class="form-control" id="add-name" value="">
|
|
385
|
-
</form>
|
|
386
|
-
</div>
|
|
387
|
-
<div class="modal-footer">
|
|
388
|
-
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
389
|
-
<button type="button" class="btn btn-primary save-add">Save changes</button>
|
|
390
|
-
</div>
|
|
391
|
-
</div>
|
|
392
|
-
</div>
|
|
393
|
-
</div>
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
<!-- Modal Edit -->
|
|
398
|
-
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
|
399
|
-
aria-hidden="true">
|
|
400
|
-
<div class="modal-dialog" role="document">
|
|
401
|
-
<div class="modal-content">
|
|
402
|
-
<div class="modal-header">
|
|
403
|
-
<h5 class="modal-title" id="exampleModalLabel">Edit menu name</h5>
|
|
404
|
-
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
405
|
-
<span aria-hidden="true">×</span>
|
|
406
|
-
</button>
|
|
407
|
-
</div>
|
|
408
|
-
<div class="modal-body">
|
|
409
|
-
<form>
|
|
410
|
-
<input type="text" class="form-control" id="edit-name" value="">
|
|
411
|
-
<input type="hidden" id="edit-id" value="">
|
|
412
|
-
</form>
|
|
413
|
-
</div>
|
|
414
|
-
<div class="modal-footer">
|
|
415
|
-
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
416
|
-
<button type="button" class="btn btn-primary save-edit">Save changes</button>
|
|
417
|
-
</div>
|
|
418
|
-
</div>
|
|
419
|
-
</div>
|
|
420
|
-
</div>
|
|
421
|
-
|
|
422
|
-
`;
|
|
423
|
-
|
|
424
|
-
const css = `<link rel="stylesheet" href="/css/bootstrap-iconpicker.min.css"/>
|
|
425
|
-
<link rel="stylesheet" href="/css/tabler.css"/>
|
|
426
|
-
<style type="text/css">
|
|
427
|
-
#myEditor_icon i {
|
|
428
|
-
margin-right: 5px;
|
|
429
|
-
}
|
|
430
|
-
.iconpickerxx i {
|
|
431
|
-
filter: invert(100%) sepia(100%) saturate(2%) hue-rotate(94deg) brightness(102%) contrast(100%)!important;
|
|
432
|
-
}
|
|
433
|
-
.iconpicker i {
|
|
434
|
-
filter:none!important;
|
|
435
|
-
}
|
|
436
|
-
li.list-group-item > div > i {
|
|
437
|
-
filter: none !important;
|
|
438
|
-
position:relative;
|
|
439
|
-
top : 6px;
|
|
440
|
-
}
|
|
441
|
-
.btn i {
|
|
442
|
-
padding: 0!important;
|
|
443
|
-
margin: 0!important;
|
|
444
|
-
}
|
|
445
|
-
</style>
|
|
446
|
-
`;
|
|
447
|
-
|
|
448
|
-
const js = `<script src="/js/icons.js" ></script>
|
|
449
|
-
<script src="/js/jquery-menu-editor-svg.js" ></script>
|
|
450
|
-
<script>
|
|
451
|
-
$(function () {
|
|
452
|
-
var iconPickerOptions = {searchText: 'Home...', labelHeader: '{0} of {1} Pages'};
|
|
453
|
-
//sortable list options
|
|
454
|
-
var sortableListOptions = {
|
|
455
|
-
placeholderCss: {'background-color': 'cyan'}
|
|
456
|
-
};
|
|
457
|
-
var editor = new MenuEditor('myEditor', {listOptions: sortableListOptions, iconPicker: iconPickerOptions, labelEdit: 'Edit'});
|
|
458
|
-
editor.setForm($('#frmEdit'));
|
|
459
|
-
editor.setUpdateButton($('#btnUpdate'));
|
|
460
|
-
<%if(hasAccessMenu) {%>
|
|
461
|
-
editor.setData(<%- JSON.stringify(arr)%>);
|
|
462
|
-
<%} %>
|
|
463
|
-
|
|
464
|
-
$('#btnOut').on('click', function () {
|
|
465
|
-
var str = editor.getString();
|
|
466
|
-
$("#out").text(str);
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
$("#btnUpdate").click(function(){
|
|
470
|
-
editor.update();
|
|
471
|
-
$("#out").text(editor.getString());
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
$('#btnAdd').click(function(){
|
|
475
|
-
editor.add();
|
|
476
|
-
$("#out").text(editor.getString());
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
var str = editor.getString();
|
|
480
|
-
$("#out").text(str);
|
|
481
|
-
|
|
482
|
-
$("#btnOut").on("click", function () {
|
|
483
|
-
ajaxPost("/zmenu",{
|
|
484
|
-
name : $("#name").val(),
|
|
485
|
-
json:$("#out").val()
|
|
486
|
-
},function (data) {
|
|
487
|
-
if(data.status == 0){
|
|
488
|
-
toastr.error(data.message)
|
|
489
|
-
} else {
|
|
490
|
-
toastr.success(data.message, data.title);
|
|
491
|
-
setTimeout(function () {
|
|
492
|
-
location.href = "";
|
|
493
|
-
}, 1000)
|
|
494
|
-
}
|
|
495
|
-
});
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
$("#name").on("change",function () {
|
|
499
|
-
let myval = $(this).val();
|
|
500
|
-
location.href = '/zmenu?id='+myval;
|
|
501
|
-
})
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
<% if(refresh == 1) {%>
|
|
505
|
-
setTimeout(function () {
|
|
506
|
-
location.href = "";
|
|
507
|
-
}, 1000);
|
|
508
|
-
<%}%>
|
|
509
|
-
|
|
510
|
-
$(".delete-menu").on("click", function (ev) {
|
|
511
|
-
ev.preventDefault();
|
|
512
|
-
let id = $(this).data("id");
|
|
513
|
-
if(window.confirm("Sure to delete")) {
|
|
514
|
-
ajaxDelete('/zmenu/delete',{
|
|
515
|
-
id:id
|
|
516
|
-
}, function (data) {
|
|
517
|
-
toastrForm(data);
|
|
518
|
-
if (data.status == 1) {
|
|
519
|
-
location.href = ''
|
|
520
|
-
}
|
|
521
|
-
})
|
|
522
|
-
}
|
|
523
|
-
})
|
|
524
|
-
$(".edit-menu").on("click", function () {
|
|
525
|
-
$("#edit-id").val($(this).data("id"));
|
|
526
|
-
$("#edit-name").val($(this).data("name"));
|
|
527
|
-
})
|
|
528
|
-
$(".save-edit").on("click", function () {
|
|
529
|
-
$("#edit-id").val();
|
|
530
|
-
$("#edit-name").val();
|
|
531
|
-
ajaxPost('/zmenu/edit',{
|
|
532
|
-
id:$("#edit-id").val(),
|
|
533
|
-
name: $("#edit-name").val()
|
|
534
|
-
}, function (data) {
|
|
535
|
-
toastrForm(data);
|
|
536
|
-
if (data.status == 1) {
|
|
537
|
-
location.href = ''
|
|
538
|
-
}
|
|
539
|
-
})
|
|
540
|
-
})
|
|
541
|
-
$(".save-add").on("click", function () {
|
|
542
|
-
ajaxPost('/zmenu/add',{
|
|
543
|
-
name: $("#add-name").val()
|
|
544
|
-
}, function (data) {
|
|
545
|
-
toastrForm(data);
|
|
546
|
-
if (data.status == 1) {
|
|
547
|
-
location.href = ''
|
|
548
|
-
}
|
|
549
|
-
})
|
|
550
|
-
})
|
|
551
|
-
</script>
|
|
552
|
-
|
|
553
|
-
`;
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
module.exports = router;
|
|
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 {Util, connection, zRole, zCache } = require('zet-lib');
|
|
7
|
+
const Util = require('./Util');
|
|
8
|
+
const connection = require('./connection');
|
|
9
|
+
const zRole = require('./zRole');
|
|
10
|
+
const zCache = require('./zCache');
|
|
11
|
+
const moduleLib = require('./moduleLib');
|
|
12
|
+
const config = require('dotenv').config();
|
|
13
|
+
const ejs = require('ejs');
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
icons list for tabler and set to /public/js
|
|
17
|
+
*/
|
|
18
|
+
const iconList = () => {
|
|
19
|
+
const dir = `${dirRoot}/public/assets/icons`;
|
|
20
|
+
const icons = fs.readdirSync(dir);
|
|
21
|
+
return icons;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
router.get('/', async function (req, res, next) {
|
|
25
|
+
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
26
|
+
if(Object.prototype.hasOwnProperty.call(levels,'index')) {
|
|
27
|
+
if(!levels.index) {
|
|
28
|
+
return res.redirect(process.env.APP_AFTER_LOGIN);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
let name = "Standart";
|
|
32
|
+
let arr = [{"text":"Home","href":"zdashboard","icon":"fas fa-home","target":"_self","title":""}];
|
|
33
|
+
let hasAccessMenu = false;
|
|
34
|
+
let companyId = res.locals.companyId;
|
|
35
|
+
let id = req.query.id;
|
|
36
|
+
let findArr = [];
|
|
37
|
+
let idChanges;
|
|
38
|
+
let rows= await connection.results({
|
|
39
|
+
table: "zmenu",
|
|
40
|
+
where : {
|
|
41
|
+
company_id : companyId
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
if (rows.length > 0) {
|
|
45
|
+
hasAccessMenu = true;
|
|
46
|
+
//check id changes
|
|
47
|
+
let rowsChanges = rows.filter((item) => item.active == 1);
|
|
48
|
+
idChanges = rowsChanges[0].id;
|
|
49
|
+
if (id) {
|
|
50
|
+
await connection.update({
|
|
51
|
+
table : "zmenu",
|
|
52
|
+
data: {
|
|
53
|
+
active:0
|
|
54
|
+
},
|
|
55
|
+
where : {
|
|
56
|
+
company_id: companyId
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
await connection.update({
|
|
60
|
+
table : "zmenu",
|
|
61
|
+
data : {
|
|
62
|
+
active : 1,
|
|
63
|
+
},
|
|
64
|
+
where : {
|
|
65
|
+
id: id
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
id =1;
|
|
70
|
+
let selected = rows.filter(item=>item.active == 1)[0] || {}
|
|
71
|
+
id = selected.id;
|
|
72
|
+
name = selected.name;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
findArr = await connection.results({
|
|
76
|
+
table:"zmenu",
|
|
77
|
+
where: {
|
|
78
|
+
id:id
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
arr = findArr[0].json;
|
|
82
|
+
let refresh = 0;
|
|
83
|
+
if (id != idChanges) {
|
|
84
|
+
refresh = 1;
|
|
85
|
+
}
|
|
86
|
+
zCache.MENU();
|
|
87
|
+
if(!levels.update) {
|
|
88
|
+
hasAccessMenu = false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let datas = {
|
|
92
|
+
hasAccessMenu: hasAccessMenu,
|
|
93
|
+
rows: rows,
|
|
94
|
+
name: name,
|
|
95
|
+
arr: arr,
|
|
96
|
+
id: id,
|
|
97
|
+
refresh: refresh,
|
|
98
|
+
menuApp: "Menu Generator",
|
|
99
|
+
}
|
|
100
|
+
const bodyHTML = ejs.render(body,datas);
|
|
101
|
+
const endBody = ejs.render(js, datas);
|
|
102
|
+
const headBody = ejs.render(css);
|
|
103
|
+
datas.bodyHTML = bodyHTML;
|
|
104
|
+
moduleLib.addModule(req,res,headBody,true);
|
|
105
|
+
moduleLib.addModule(req,res,endBody);
|
|
106
|
+
res.render("zgenerator/layout", datas );
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
router.post('/', csrfProtection, async(req,res) => {
|
|
110
|
+
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
111
|
+
if(Object.prototype.hasOwnProperty.call(levels,'create')) {
|
|
112
|
+
if(!levels.create) {
|
|
113
|
+
return Util.flashError('Not allowed')
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
let body = req.body;
|
|
117
|
+
let companyId = res.locals.companyId;
|
|
118
|
+
let id = body.name;
|
|
119
|
+
let json = body.json || [];
|
|
120
|
+
if (!id){
|
|
121
|
+
return res.json(Util.jsonError("name", "name can not be blank!"))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let data = {
|
|
125
|
+
company_id: companyId,
|
|
126
|
+
json: json,
|
|
127
|
+
updated_by: res.locals.userId
|
|
128
|
+
};
|
|
129
|
+
let cb = Util.jsonSuccess("Success.. Please relogin to see the changes!");
|
|
130
|
+
try {
|
|
131
|
+
let rows = await connection.results({
|
|
132
|
+
table : "zmenu",
|
|
133
|
+
where : {
|
|
134
|
+
company_id : companyId,
|
|
135
|
+
id: id
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
if (rows.length > 0) {
|
|
139
|
+
await connection.update({
|
|
140
|
+
table : "zmenu",
|
|
141
|
+
data:data,
|
|
142
|
+
where : {
|
|
143
|
+
id:rows[0].id
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
} catch (e) {
|
|
148
|
+
cb = Util.flashError(JSON.stringify(e))
|
|
149
|
+
}
|
|
150
|
+
zCache.MENU();
|
|
151
|
+
|
|
152
|
+
res.json(cb)
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
router.post('/edit', async(req,res) => {
|
|
156
|
+
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
157
|
+
if(Object.prototype.hasOwnProperty.call(levels,'update')) {
|
|
158
|
+
if(!levels.update) {
|
|
159
|
+
return res.json(Util.flashError('Not allowed'));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
let name = req.body.name || "";
|
|
163
|
+
let id = req.body.id;
|
|
164
|
+
if(name.length < 3) {
|
|
165
|
+
return res.json(Util.flashError("name is empty or is not completed"));
|
|
166
|
+
}
|
|
167
|
+
let json = Util.jsonSuccess(LANGUAGE.success);
|
|
168
|
+
await connection.update({
|
|
169
|
+
table : "zmenu",
|
|
170
|
+
data : {
|
|
171
|
+
name : req.body.name,
|
|
172
|
+
updated_at : Util.now(),
|
|
173
|
+
updated_by : res.locals.userId
|
|
174
|
+
},
|
|
175
|
+
where : {
|
|
176
|
+
id : req.body.id
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
res.json(json);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
router.post('/add', async(req,res) => {
|
|
185
|
+
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
186
|
+
if(Object.prototype.hasOwnProperty.call(levels,'create')) {
|
|
187
|
+
if(!levels.create) {
|
|
188
|
+
return res.json(Util.flashError('Not allowed'));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
let name = req.body.name || "";
|
|
192
|
+
if(name.length < 3) {
|
|
193
|
+
return res.json(Util.flashError("name is empty or is not completed"));
|
|
194
|
+
}
|
|
195
|
+
let json = Util.jsonSuccess(LANGUAGE.success);
|
|
196
|
+
await connection.insert({
|
|
197
|
+
table : "zmenu",
|
|
198
|
+
data : {
|
|
199
|
+
name : req.body.name,
|
|
200
|
+
updated_at : Util.now(),
|
|
201
|
+
created_at : Util.now(),
|
|
202
|
+
updated_by : res.locals.userId,
|
|
203
|
+
created_by : res.locals.userId,
|
|
204
|
+
company_id : res.locals.companyId
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
res.json(json);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
router.delete('/delete',async (req,res) => {
|
|
212
|
+
const levels = zRole.myLevel(req, res, 'zmenu');
|
|
213
|
+
if(Object.prototype.hasOwnProperty.call(levels,'delete')) {
|
|
214
|
+
if(!levels.delete) {
|
|
215
|
+
return Util.flashError('Not allowed');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
let id = req.body.id;
|
|
219
|
+
await connection.delete({
|
|
220
|
+
table :"zmenu",
|
|
221
|
+
where : {
|
|
222
|
+
id : id,
|
|
223
|
+
company_id : res.locals.companyId
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
let json = Util.jsonSuccess(LANGUAGE.success);
|
|
227
|
+
res.json(json);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const body = `<section class="mt-4">
|
|
231
|
+
<div class="row">
|
|
232
|
+
<div class="col-md-5 mb-2">
|
|
233
|
+
<div class="card mb-3 wow fadeIn">
|
|
234
|
+
<div class="card-header bg-success text-white">Edit item</div>
|
|
235
|
+
<div class="card-body">
|
|
236
|
+
<form id="frmEdit">
|
|
237
|
+
<div class="form-group">
|
|
238
|
+
<div class="input-group mb-3">
|
|
239
|
+
<input type="text" class="form-control item-menu form-control-lg" name="text" id="text" placeholder="Text">
|
|
240
|
+
<div class="input-group-append">
|
|
241
|
+
<button class="btn btn-md btn-outline-default m-0 px-3 py-2 z-depth-0 waves-effect" id="myEditor_icon" type="button" id="button-addon2">Button</button>
|
|
242
|
+
</div>
|
|
243
|
+
<input type="hidden" name="icon" class="item-menu">
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<div class="form-group">
|
|
248
|
+
<label for="href">URL</label>
|
|
249
|
+
<input type="text" class="form-control item-menu" id="href" name="href" placeholder="URL">
|
|
250
|
+
</div>
|
|
251
|
+
<div class="form-group">
|
|
252
|
+
<label for="target">Target</label>
|
|
253
|
+
<select name="target" id="target" class="form-control item-menu">
|
|
254
|
+
<option value="_self">Self</option>
|
|
255
|
+
<option value="_blank">Blank</option>
|
|
256
|
+
<option value="_top">Top</option>
|
|
257
|
+
</select>
|
|
258
|
+
</div>
|
|
259
|
+
<div class="form-group">
|
|
260
|
+
<label for="title">Tooltip</label>
|
|
261
|
+
<input type="text" name="title" class="form-control item-menu" id="title" placeholder="Tooltip">
|
|
262
|
+
</div>
|
|
263
|
+
</form>
|
|
264
|
+
</div>
|
|
265
|
+
<div class="card-footer">
|
|
266
|
+
<button type="button" id="btnUpdate" class="btn btn-sm btn-primary" disabled><i class="fas fa-sync-alt"></i> Update</button>
|
|
267
|
+
<button type="button" id="btnAdd" class="btn btn-sm btn-success"><i class="fas fa-plus"></i> Add</button>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<div class="row">
|
|
272
|
+
<div class="col-md-12">
|
|
273
|
+
<p class="note note-light">
|
|
274
|
+
<strong>Note:</strong> Using link below to find all <strong>icon</strong> available options and
|
|
275
|
+
advanced customization.<br>
|
|
276
|
+
See <a target="_blank" href="https://tabler-icons.io/" class="text-reset"><strong>https://tabler-icons.io/</strong></a>
|
|
277
|
+
</p>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
<div class="row">
|
|
283
|
+
<div class="col-md-12">
|
|
284
|
+
<div class="card mb-3 wow fadeIn">
|
|
285
|
+
<div class="card-header"><h2>Menu List</h2></div>
|
|
286
|
+
<div class="card-body">
|
|
287
|
+
<table class="table">
|
|
288
|
+
<thead>
|
|
289
|
+
<tr>
|
|
290
|
+
<th>#</th>
|
|
291
|
+
<th>Choice</th>
|
|
292
|
+
<th>ID</th>
|
|
293
|
+
<th>Name</th>
|
|
294
|
+
<th>Action</th>
|
|
295
|
+
</tr>
|
|
296
|
+
</thead>
|
|
297
|
+
<tbody>
|
|
298
|
+
<% for(var i = 0;i < rows.length; i++) { %>
|
|
299
|
+
<tr>
|
|
300
|
+
<td><%- i + 1 %></td>
|
|
301
|
+
<td><a href="/zmenu?id=<%- rows[i].id %>&name=<%- rows[i].name %>"
|
|
302
|
+
class="btn btn-sm <%- id == rows[i].id ? "btn-success" : "btn-default" %>">Choice</a>
|
|
303
|
+
</td>
|
|
304
|
+
<td>
|
|
305
|
+
<%- rows[i].id %>
|
|
306
|
+
</td>
|
|
307
|
+
<td>
|
|
308
|
+
<a href="/zmenu?id=<%- rows[i].id %>&name=<%- rows[i].name %>"><%- rows[i].name %></a>
|
|
309
|
+
</td>
|
|
310
|
+
<td>
|
|
311
|
+
<div class="btn-group float-right">
|
|
312
|
+
|
|
313
|
+
<a data-name="<%- rows[i].name %>" data-id="<%- rows[i].id %>" class="btn btn-primary btn-sm edit-menu " data-toggle="modal" data-target="#editModal" href="#">Edit</a>
|
|
314
|
+
|
|
315
|
+
<% if (rows[i].id != id) { %>
|
|
316
|
+
<a data-id="<%- rows[i].id %>" class="btn btn-danger btn-sm delete-menu" href="#"><i class="fas fa-trash-alt"></i></a>
|
|
317
|
+
<% } %>
|
|
318
|
+
</div>
|
|
319
|
+
</td>
|
|
320
|
+
</tr>
|
|
321
|
+
<% } %>
|
|
322
|
+
</tbody>
|
|
323
|
+
</table>
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
326
|
+
</div>
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
<div class="col-md-7 mb-2">
|
|
332
|
+
<div class="card mb-3 wow fadeIn">
|
|
333
|
+
<div class="card-header secondary-color-dark text-white font-weight-bold">Menu</div>
|
|
334
|
+
|
|
335
|
+
<div class="card-body">
|
|
336
|
+
<div class="input-group">
|
|
337
|
+
<select class="form-control form-select" name="name" id="name">
|
|
338
|
+
<% for(var i = 0;i < rows.length; i++) {
|
|
339
|
+
let selected = rows[i].id == id ? ' selected ' : '';
|
|
340
|
+
%>
|
|
341
|
+
<option value="<%- rows[i].id %>" <%- selected %>><%- rows[i].name %></option>
|
|
342
|
+
<%} %>
|
|
343
|
+
|
|
344
|
+
</select>
|
|
345
|
+
<div class="input-group-btn">
|
|
346
|
+
<button id="btnOut" type="button" class="btn btn-sm btn-success"><i class="glyphicon glyphicon-ok"></i> Save </button>
|
|
347
|
+
|
|
348
|
+
<button id="btn-add" type="button" class="btn btn-sm btn-info " data-toggle="modal" data-target="#addModal"><i class="fas fa-plus-circle"></i> Add </button>
|
|
349
|
+
|
|
350
|
+
</div>
|
|
351
|
+
</div>
|
|
352
|
+
</div>
|
|
353
|
+
<div class="card-body" id="cont">
|
|
354
|
+
<ul id="myEditor" class="sortableLists list-group"></ul>
|
|
355
|
+
</div>
|
|
356
|
+
|
|
357
|
+
<div class="card-footer">
|
|
358
|
+
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
|
|
362
|
+
<div class="row" style="display: none">
|
|
363
|
+
<label for="out">Output:</label>
|
|
364
|
+
<textarea id="out" class="form-control" cols="50" rows="10"></textarea>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
</section>
|
|
370
|
+
|
|
371
|
+
<!-- Modal Add -->
|
|
372
|
+
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
|
373
|
+
aria-hidden="true">
|
|
374
|
+
<div class="modal-dialog" role="document">
|
|
375
|
+
<div class="modal-content">
|
|
376
|
+
<div class="modal-header">
|
|
377
|
+
<h5 class="modal-title" id="exampleModalLabel">Add menu</h5>
|
|
378
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
379
|
+
<span aria-hidden="true">×</span>
|
|
380
|
+
</button>
|
|
381
|
+
</div>
|
|
382
|
+
<div class="modal-body">
|
|
383
|
+
<form>
|
|
384
|
+
<input type="text" class="form-control" id="add-name" value="">
|
|
385
|
+
</form>
|
|
386
|
+
</div>
|
|
387
|
+
<div class="modal-footer">
|
|
388
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
389
|
+
<button type="button" class="btn btn-primary save-add">Save changes</button>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
393
|
+
</div>
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
<!-- Modal Edit -->
|
|
398
|
+
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
|
399
|
+
aria-hidden="true">
|
|
400
|
+
<div class="modal-dialog" role="document">
|
|
401
|
+
<div class="modal-content">
|
|
402
|
+
<div class="modal-header">
|
|
403
|
+
<h5 class="modal-title" id="exampleModalLabel">Edit menu name</h5>
|
|
404
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
405
|
+
<span aria-hidden="true">×</span>
|
|
406
|
+
</button>
|
|
407
|
+
</div>
|
|
408
|
+
<div class="modal-body">
|
|
409
|
+
<form>
|
|
410
|
+
<input type="text" class="form-control" id="edit-name" value="">
|
|
411
|
+
<input type="hidden" id="edit-id" value="">
|
|
412
|
+
</form>
|
|
413
|
+
</div>
|
|
414
|
+
<div class="modal-footer">
|
|
415
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
416
|
+
<button type="button" class="btn btn-primary save-edit">Save changes</button>
|
|
417
|
+
</div>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
421
|
+
|
|
422
|
+
`;
|
|
423
|
+
|
|
424
|
+
const css = `<link rel="stylesheet" href="/css/bootstrap-iconpicker.min.css"/>
|
|
425
|
+
<link rel="stylesheet" href="/css/tabler.css"/>
|
|
426
|
+
<style type="text/css">
|
|
427
|
+
#myEditor_icon i {
|
|
428
|
+
margin-right: 5px;
|
|
429
|
+
}
|
|
430
|
+
.iconpickerxx i {
|
|
431
|
+
filter: invert(100%) sepia(100%) saturate(2%) hue-rotate(94deg) brightness(102%) contrast(100%)!important;
|
|
432
|
+
}
|
|
433
|
+
.iconpicker i {
|
|
434
|
+
filter:none!important;
|
|
435
|
+
}
|
|
436
|
+
li.list-group-item > div > i {
|
|
437
|
+
filter: none !important;
|
|
438
|
+
position:relative;
|
|
439
|
+
top : 6px;
|
|
440
|
+
}
|
|
441
|
+
.btn i {
|
|
442
|
+
padding: 0!important;
|
|
443
|
+
margin: 0!important;
|
|
444
|
+
}
|
|
445
|
+
</style>
|
|
446
|
+
`;
|
|
447
|
+
|
|
448
|
+
const js = `<script src="/js/icons.js" ></script>
|
|
449
|
+
<script src="/js/jquery-menu-editor-svg.js" ></script>
|
|
450
|
+
<script>
|
|
451
|
+
$(function () {
|
|
452
|
+
var iconPickerOptions = {searchText: 'Home...', labelHeader: '{0} of {1} Pages'};
|
|
453
|
+
//sortable list options
|
|
454
|
+
var sortableListOptions = {
|
|
455
|
+
placeholderCss: {'background-color': 'cyan'}
|
|
456
|
+
};
|
|
457
|
+
var editor = new MenuEditor('myEditor', {listOptions: sortableListOptions, iconPicker: iconPickerOptions, labelEdit: 'Edit'});
|
|
458
|
+
editor.setForm($('#frmEdit'));
|
|
459
|
+
editor.setUpdateButton($('#btnUpdate'));
|
|
460
|
+
<%if(hasAccessMenu) {%>
|
|
461
|
+
editor.setData(<%- JSON.stringify(arr)%>);
|
|
462
|
+
<%} %>
|
|
463
|
+
|
|
464
|
+
$('#btnOut').on('click', function () {
|
|
465
|
+
var str = editor.getString();
|
|
466
|
+
$("#out").text(str);
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
$("#btnUpdate").click(function(){
|
|
470
|
+
editor.update();
|
|
471
|
+
$("#out").text(editor.getString());
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
$('#btnAdd').click(function(){
|
|
475
|
+
editor.add();
|
|
476
|
+
$("#out").text(editor.getString());
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
var str = editor.getString();
|
|
480
|
+
$("#out").text(str);
|
|
481
|
+
|
|
482
|
+
$("#btnOut").on("click", function () {
|
|
483
|
+
ajaxPost("/zmenu",{
|
|
484
|
+
name : $("#name").val(),
|
|
485
|
+
json:$("#out").val()
|
|
486
|
+
},function (data) {
|
|
487
|
+
if(data.status == 0){
|
|
488
|
+
toastr.error(data.message)
|
|
489
|
+
} else {
|
|
490
|
+
toastr.success(data.message, data.title);
|
|
491
|
+
setTimeout(function () {
|
|
492
|
+
location.href = "";
|
|
493
|
+
}, 1000)
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
$("#name").on("change",function () {
|
|
499
|
+
let myval = $(this).val();
|
|
500
|
+
location.href = '/zmenu?id='+myval;
|
|
501
|
+
})
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
<% if(refresh == 1) {%>
|
|
505
|
+
setTimeout(function () {
|
|
506
|
+
location.href = "";
|
|
507
|
+
}, 1000);
|
|
508
|
+
<%}%>
|
|
509
|
+
|
|
510
|
+
$(".delete-menu").on("click", function (ev) {
|
|
511
|
+
ev.preventDefault();
|
|
512
|
+
let id = $(this).data("id");
|
|
513
|
+
if(window.confirm("Sure to delete")) {
|
|
514
|
+
ajaxDelete('/zmenu/delete',{
|
|
515
|
+
id:id
|
|
516
|
+
}, function (data) {
|
|
517
|
+
toastrForm(data);
|
|
518
|
+
if (data.status == 1) {
|
|
519
|
+
location.href = ''
|
|
520
|
+
}
|
|
521
|
+
})
|
|
522
|
+
}
|
|
523
|
+
})
|
|
524
|
+
$(".edit-menu").on("click", function () {
|
|
525
|
+
$("#edit-id").val($(this).data("id"));
|
|
526
|
+
$("#edit-name").val($(this).data("name"));
|
|
527
|
+
})
|
|
528
|
+
$(".save-edit").on("click", function () {
|
|
529
|
+
$("#edit-id").val();
|
|
530
|
+
$("#edit-name").val();
|
|
531
|
+
ajaxPost('/zmenu/edit',{
|
|
532
|
+
id:$("#edit-id").val(),
|
|
533
|
+
name: $("#edit-name").val()
|
|
534
|
+
}, function (data) {
|
|
535
|
+
toastrForm(data);
|
|
536
|
+
if (data.status == 1) {
|
|
537
|
+
location.href = ''
|
|
538
|
+
}
|
|
539
|
+
})
|
|
540
|
+
})
|
|
541
|
+
$(".save-add").on("click", function () {
|
|
542
|
+
ajaxPost('/zmenu/add',{
|
|
543
|
+
name: $("#add-name").val()
|
|
544
|
+
}, function (data) {
|
|
545
|
+
toastrForm(data);
|
|
546
|
+
if (data.status == 1) {
|
|
547
|
+
location.href = ''
|
|
548
|
+
}
|
|
549
|
+
})
|
|
550
|
+
})
|
|
551
|
+
</script>
|
|
552
|
+
|
|
553
|
+
`;
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
module.exports = router;
|