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