zet-lib 1.3.22 → 1.3.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/connection.js CHANGED
@@ -353,6 +353,26 @@ connection.constraintList = (table, schema = 'public') => {
353
353
  WHERE nsp.nspname = '${schema}' AND rel.relname = '${table}'; `
354
354
  }
355
355
 
356
+ //find foreign key
357
+ connection.foreignKeyList = (table) => {
358
+ return `SELECT
359
+ tc.table_schema,
360
+ tc.constraint_name,
361
+ tc.table_name,
362
+ kcu.column_name,
363
+ ccu.table_schema AS foreign_table_schema,
364
+ ccu.table_name AS foreign_table_name,
365
+ ccu.column_name AS foreign_column_name
366
+ FROM information_schema.table_constraints AS tc
367
+ JOIN information_schema.key_column_usage AS kcu
368
+ ON tc.constraint_name = kcu.constraint_name
369
+ AND tc.table_schema = kcu.table_schema
370
+ JOIN information_schema.constraint_column_usage AS ccu
371
+ ON ccu.constraint_name = tc.constraint_name
372
+ WHERE tc.constraint_type = 'FOREIGN KEY'
373
+ AND tc.table_name='${table}';`
374
+ }
375
+
356
376
  var toNumber = function (num) {
357
377
  num = num + ''
358
378
  var t = replaceAll(num, '.', '')
@@ -91,10 +91,6 @@
91
91
  <form id="formfields" method="post" action="/generator/fields">
92
92
  <div id="divtablist" class="row"></div>
93
93
  <div id="contentfields"></div>
94
- <div id="divjoinmodules">
95
- <h4>Join Modules</h4>
96
- <div class="row" id="joinlist"></div>
97
- </div>
98
94
  <% if(lock==0) {%>
99
95
  <div class="text-center mt-4">
100
96
  <button class="btn btn-danger btn-reset text-white mr-2" type="button"><i
@@ -109,7 +105,7 @@
109
105
  <!-- Basic dropdown -->
110
106
  <button class="btn btn-warning m-0 px-3 waves-effect waves-light mr-2"
111
107
  data-toggle="modal" data-target="#modal_joins" type="button"><i
112
- class="fas fa-dice"></i> Join Module</button>
108
+ class="fas fa-dice"></i> Join Modules</button>
113
109
  <button class="btn m-0 px-3 waves-effect waves-light mr-2" data-toggle="modal"
114
110
  data-target="#modal_container" type="button"><i class="fa fa-plus"></i> Add
115
111
  Container</button>
@@ -120,13 +116,26 @@
120
116
  type="button"><i class="fa fa-paper-plane"></i> Save & Generate</button>
121
117
  </div>
122
118
  <%}%>
123
-
124
119
  </form>
125
120
  <!-- Default form reply -->
126
121
  </div>
127
122
  </div>
128
123
  <!--/Generator-->
129
124
 
125
+ <div class="card mb-4 wow fadeIn card-script">
126
+ <div class="card-header font-weight-bold">
127
+ <span> Join Modules</span>
128
+ </div>
129
+ <div class="card-body">
130
+ <div id="divjoinmodules">
131
+ <form id="formjoin">
132
+ <div class="row" id="joinlist"></div>
133
+ </form>
134
+ </div>
135
+ <hr>
136
+
137
+ </div>
138
+ </div>
130
139
 
131
140
  <!-- Card -->
132
141
  <div class="card mb-4 wow fadeIn card-script" style="display: none">
@@ -304,16 +313,12 @@
304
313
  </div>
305
314
  </div>
306
315
  <!--/.Card-->
307
-
308
316
  </div>
309
317
  </div>
310
318
  <!--Grid row-->
311
319
  </section>
312
320
  <!--Section: Post-->
313
321
 
314
-
315
-
316
-
317
322
  <!-- Modal -->
318
323
  <div class="modal fade" id="add_table" tabindex="-1" aria-labelledby="add_table" aria-hidden="true">
319
324
  <div class="modal-dialog">
@@ -445,7 +450,6 @@
445
450
  </div>
446
451
 
447
452
 
448
-
449
453
  <div class="modal fade" id="modal_tab" tabindex="-1" aria-labelledby="modal_setting" aria-hidden="true">
450
454
  <div class="modal-dialog">
451
455
  <div class="modal-content">
@@ -473,7 +477,7 @@
473
477
  <div class="modal-dialog">
474
478
  <div class="modal-content">
475
479
  <div class="modal-header">
476
- <h5 class="modal-title" id="exampleModalLabel">Import zfield File</h5>
480
+ <h5 class="modal-title">Import zfield File</h5>
477
481
  <button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times"></i>
478
482
  </button>
479
483
  </div>
@@ -501,7 +505,7 @@
501
505
  <div class="modal-dialog">
502
506
  <div class="modal-content">
503
507
  <div class="modal-header">
504
- <h5 class="modal-title" id="exampleModalLabel">Add Container</h5>
508
+ <h5 class="modal-title">Add Container</h5>
505
509
  <button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times"></i>
506
510
  </button>
507
511
  </div>
@@ -534,8 +538,9 @@
534
538
  <div class="modal-dialog">
535
539
  <div class="modal-content">
536
540
  <div class="modal-header">
537
- <h5 class="modal-title" id="exampleModalLabel">Join Module</h5>
538
- <button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times"></i>
541
+ <h5 class="modal-title">Join Module</h5>
542
+ <button type="button" class="close" id="closejoin" data-dismiss="modal" aria-label="Close"><i
543
+ class="fa fa-times"></i>
539
544
  </button>
540
545
  </div>
541
546
  <div class="modal-body">
@@ -270,7 +270,7 @@
270
270
  let html = ``
271
271
  let time = new Date().getTime()
272
272
  let col_md = `col-md-${12 / columncount}`
273
- container_time = `container_${time}`
273
+ let container_time = `container_${time}`
274
274
  html += `<li class="container-nav"><i class="fa fa-arrows icon-float"></i><div class="row mt-1 mb-1">`
275
275
  for (let i = 1; i <= columncount; i++) {
276
276
  html += `<div class="${col_md}" style="background-color: rgba(0,0,0,.03)" ><ol class="divboxlittle container-box"><li><i data-container="${container_time}" data-id="${i}" data-split="${columncount}" data-column="ONE_COLUMN" class="fa fa-plus-circle fa-2x add-container text-success"></i></li></ol> </div>`
@@ -406,6 +406,7 @@
406
406
  approvers: approvers,
407
407
  knowings: knowings,
408
408
  others: JSON.stringify(others),
409
+ joins: $('#formjoin').serializeArray(),
409
410
  },
410
411
  function (data) {
411
412
  if (data.status == 0) {
@@ -815,26 +816,6 @@
815
816
  })
816
817
  })
817
818
  }
818
- /* let myobj = {}
819
- let isContainer = Object.keys(obj).length ? true : false;
820
- if(isContainer) {
821
- for(let key in obj) {
822
- let arr = obj[key] || [];
823
- if(arr.length) {
824
- arr.forEach(function (item) {
825
- if(Array.isArray(item)) {
826
- let length = item.length;
827
- if(isEmpty(item)) {
828
- obj[key].splice(0,1);
829
- }
830
- console.log(length)
831
- }
832
- })
833
- }
834
- }
835
- }
836
- console.log(JSON.stringify(obj))*/
837
-
838
819
  others = obj
839
820
  return obj
840
821
  }
@@ -877,10 +858,11 @@
877
858
  )
878
859
  }
879
860
  })
861
+
880
862
  $("#modal-joins-save").on("click", function (e) {
881
863
  let table_join = $('#select_module_joins').val();
882
864
  let table = $('#table').val()
883
- if (table == route) {
865
+ if (table == table_join) {
884
866
  toastr.error("Your selected module is equal with current module");
885
867
  return;
886
868
  }
@@ -894,6 +876,7 @@
894
876
  toastrForm(dt);
895
877
  if (dt.status == 1) {
896
878
  $("#joinlist").html(dt.html);
879
+ $("#closejoin").click();
897
880
  }
898
881
  }
899
882
  )
@@ -937,9 +920,7 @@
937
920
  table_join: table_join
938
921
  },
939
922
  function (dt) {
940
- if (dt.status == 1) {
941
- location.href = '';
942
- }
923
+ location.reload();
943
924
  }
944
925
  )
945
926
  }
@@ -266,6 +266,7 @@ router.post('/save_and_generate', csrfProtection, async (req, res) => {
266
266
  if (nots.includes(req.body.table)) {
267
267
  return res.json(Util.flashError('Table is locked'))
268
268
  }
269
+ //console.log(JSON.stringify(req.body))
269
270
  const json = await generate(req, res)
270
271
  res.json(json)
271
272
  } catch (e) {
@@ -417,7 +418,6 @@ const generate = async (req, res) => {
417
418
  //console.log(JSON.stringify(filesKey.modelObj))
418
419
  //check if has chains here
419
420
  MYMODEL = filesKey.modelObj
420
-
421
421
  //delete/clean zgrid after changes
422
422
  await connection.delete({
423
423
  table: 'zgrid',
@@ -502,7 +502,7 @@ const generate = async (req, res) => {
502
502
  fs.writeFileSync(`${dirRoot}/models/${filesKey.filename}`, newModel)
503
503
  }
504
504
  //check model if it has select relation in concat
505
- await scanning(MYMODEL)
505
+ await scanning(MYMODEL, result)
506
506
  }
507
507
  //generate views
508
508
  let DIR_VIEW = `${dirRoot}/views/${table}`
@@ -661,6 +661,113 @@ router.post('/savetabs', async (req, res) => {
661
661
  res.send(json)
662
662
  })
663
663
 
664
+ const buildJoin = async (MYMODEL, result) => {
665
+ let joins = result.joins || {}
666
+ let table = MYMODEL.table
667
+ let table_joins = []
668
+ let join_list = []
669
+
670
+ if (result.joins && Object.keys(joins).length > 0) {
671
+ let newDataObj = {}
672
+ for (let key in joins) {
673
+ //find relation
674
+ //sql.push(` LEFT JOIN ${key} ON ${key}.id = ${table}.${key}_id `)
675
+ let THEIR_MODEL = require(`${dirRoot}/models/${key}`)
676
+ //console.log(THEIR_MODEL)
677
+ let arr = joins[key] || []
678
+ table_joins.push(key)
679
+ if (arr.length > 0) {
680
+ arr.map((item) => {
681
+ //console.log(item)
682
+ //console.log(typeof item)
683
+ const originKey = key.replace(`${key}___`, '')
684
+ newDataObj[item.key] = item.value
685
+ MYMODEL.keys.push(item.key)
686
+ MYMODEL.keysExcel.push(item.key)
687
+ MYMODEL.labels[item.key] = item.value
688
+ MYMODEL.fields[item.key] = THEIR_MODEL.fields[originKey]
689
+ MYMODEL.options[item.key] = THEIR_MODEL.options[originKey]
690
+ MYMODEL.grids.invisibles.push(item.key)
691
+ MYMODEL.datas[item.key] = THEIR_MODEL.datas[originKey]
692
+ //MYMODEL.widgets[item.key] = THEIR_MODEL.widgets[originKey];
693
+ join_list.push(item.key)
694
+ })
695
+ }
696
+ }
697
+
698
+ let sql = []
699
+ //get all foreign key
700
+ let rows = await connection.query(connection.foreignKeyList(table))
701
+ let foreign_table_name = {}
702
+ let foreignTables = []
703
+ rows.map((row) => {
704
+ foreignTables.push(row.foreign_table_name)
705
+ foreign_table_name[row.foreign_table_name] = ` LEFT JOIN ${row.foreign_table_name} ON ${row.foreign_table_name}.id = ${table}.${row.column_name} `
706
+ })
707
+
708
+ //step by step
709
+ let table_steps = []
710
+ table_joins.map((item) => {
711
+ if (foreignTables.includes(item)) {
712
+ sql.push(foreign_table_name[item])
713
+ table_steps.push(item)
714
+ }
715
+ })
716
+
717
+ if (table_steps.length > 0) {
718
+ for (let table_steps_item of table_steps) {
719
+ let rows = await connection.query(connection.foreignKeyList(table_steps_item))
720
+ let foreign_table_name = {}
721
+ let foreignTables = []
722
+ rows.map((row) => {
723
+ foreignTables.push(row.foreign_table_name)
724
+ foreign_table_name[row.foreign_table_name] = ` LEFT JOIN ${row.foreign_table_name} ON ${row.foreign_table_name}.id = ${table_steps_item}.${row.column_name} `
725
+ })
726
+ console.log(foreignTables)
727
+ table_joins.map((item) => {
728
+ if (!table_steps.includes(item)) {
729
+ if (foreignTables.includes(item)) {
730
+ sql.push(foreign_table_name[item])
731
+ table_steps.push(item)
732
+ }
733
+ }
734
+ })
735
+ }
736
+ }
737
+
738
+ if (table_steps.length > 0) {
739
+ for (let table_steps_item of table_steps) {
740
+ let rows = await connection.query(connection.foreignKeyList(table_steps_item))
741
+ let foreign_table_name = {}
742
+ let foreignTables = []
743
+ rows.map((row) => {
744
+ foreignTables.push(row.foreign_table_name)
745
+ foreign_table_name[row.foreign_table_name] = ` LEFT JOIN ${row.foreign_table_name} ON ${row.foreign_table_name}.id = ${table_steps_item}.${row.column_name} `
746
+ })
747
+ console.log(foreignTables)
748
+ table_joins.map((item) => {
749
+ if (!table_steps.includes(item)) {
750
+ if (foreignTables.includes(item)) {
751
+ sql.push(foreign_table_name[item])
752
+ table_steps.push(item)
753
+ }
754
+ }
755
+ })
756
+ }
757
+ }
758
+
759
+ //add join
760
+ let JOINS_DATA = {}
761
+ JOINS_DATA.tables = table_joins
762
+ JOINS_DATA.list = join_list
763
+ JOINS_DATA.data = joins
764
+ JOINS_DATA.sql = sql
765
+
766
+ MYMODEL.joins = JOINS_DATA
767
+ }
768
+ return MYMODEL
769
+ }
770
+
664
771
  const columnLR = (items, dataName) => {
665
772
  return `<div class="col-md-6"><ol class="mydragable divboxlittle" data-name="${dataName}">${items}</ol></div>`
666
773
  }
@@ -1015,6 +1122,7 @@ router.post('/load-form', async (req, res) => {
1015
1122
  res.json(json)
1016
1123
  })
1017
1124
 
1125
+ //save to table zfields
1018
1126
  var saveToZFields = async (body) => {
1019
1127
  const table = body.table
1020
1128
  let is_approval = body.is_approval
@@ -1049,13 +1157,38 @@ var saveToZFields = async (body) => {
1049
1157
  others: body.others,
1050
1158
  }
1051
1159
 
1052
- await connection.update({
1160
+ let joinsTables = {}
1161
+ let bodyJoins = body.joins || []
1162
+ let bodyJoinsObj = {}
1163
+ if (bodyJoins.length > 0) {
1164
+ bodyJoins.map((item) => {
1165
+ bodyJoinsObj[item.name] = item.value
1166
+ })
1167
+ }
1168
+ for (let key in bodyJoinsObj) {
1169
+ if (key.includes('joins_checks___')) {
1170
+ let tablekeys = key.split('___')
1171
+ let keyName = key.replace('joins_checks___', '')
1172
+ if (!joinsTables[tablekeys[1]]) {
1173
+ joinsTables[tablekeys[1]] = []
1174
+ }
1175
+ joinsTables[tablekeys[1]].push({ key: keyName, value: bodyJoinsObj[`joins_labels___${keyName}`] })
1176
+ }
1177
+ }
1178
+ //console.log(joinsTables);
1179
+ if (Object.keys(joinsTables).length > 0) {
1180
+ data.joins = JSON.stringify(joinsTables)
1181
+ }
1182
+
1183
+ let result = await connection.update({
1053
1184
  table: 'zfields',
1054
1185
  data: data,
1055
1186
  where: {
1056
1187
  table: table,
1057
1188
  },
1058
1189
  })
1190
+
1191
+ return result
1059
1192
  }
1060
1193
 
1061
1194
  //drop down chains effect
@@ -1193,16 +1326,15 @@ router.post('/import', async (req, res) => {
1193
1326
  /*
1194
1327
  Scanning relation id to name
1195
1328
  */
1196
- const scanning = async (MYMODEL) => {
1329
+ const scanning = async (MYMODEL, result) => {
1197
1330
  //let MYMODEL = require(`${dirRoot}/models/${table}`);
1198
- //console.log(JSON.stringify(MYMODEL))
1199
1331
  let table = MYMODEL.table
1200
1332
  const widgets = MYMODEL.widgets
1201
1333
  const not_scanning = ['created_by', 'updated_by']
1202
1334
  const concat_bracket = /(?<=\().+?(?=\))/g
1203
1335
  let changeWidgets = {}
1204
1336
  let changes = []
1205
- for (let key in widgets) {
1337
+ /*for (let key in widgets) {
1206
1338
  if (widgets[key].name == 'relation' || widgets[key].name == 'dropdown_multi' || widgets[key].name == 'typeahead') {
1207
1339
  if (!Util.in_array(key, not_scanning)) {
1208
1340
  let fields = widgets[key].fields
@@ -1237,7 +1369,7 @@ const scanning = async (MYMODEL) => {
1237
1369
  }
1238
1370
  }
1239
1371
  }
1240
- }
1372
+ }*/
1241
1373
 
1242
1374
  if (changes.length) {
1243
1375
  //rewrite model
@@ -1249,6 +1381,18 @@ const scanning = async (MYMODEL) => {
1249
1381
  fs.writeFileSync(`${dirRoot}/models/${MYMODEL.table}.js`, newModel)
1250
1382
  }
1251
1383
 
1384
+ //check if has join
1385
+ //build join
1386
+ //console.log(JSON.stringify(MYMODEL))
1387
+ MYMODEL = await buildJoin(MYMODEL, result)
1388
+ //console.log(JSON.stringify(MYMODEL))
1389
+
1390
+ let newModel = `module.exports = { ${Util.newLine}`
1391
+ newModel += zRoute.buildFileModel(MYMODEL)
1392
+ newModel += `${Util.newLine}`
1393
+ newModel += `}`
1394
+ fs.writeFileSync(`${dirRoot}/models/${MYMODEL.table}.js`, newModel)
1395
+
1252
1396
  //return MYMODEL;
1253
1397
  }
1254
1398
 
@@ -1405,8 +1549,8 @@ router.post('/joins', async (req, res) => {
1405
1549
  },
1406
1550
  })
1407
1551
  let resultJoins = result.joins || {}
1408
- resultJoins[table_join] = {}
1409
- await connection.update({
1552
+ resultJoins[table_join] = []
1553
+ let myzfield = await connection.update({
1410
1554
  table: 'zfields',
1411
1555
  data: {
1412
1556
  joins: JSON.stringify(resultJoins),
@@ -1416,7 +1560,7 @@ router.post('/joins', async (req, res) => {
1416
1560
  },
1417
1561
  })
1418
1562
  jsonNotif.json = resultJoins
1419
- html = await joinHTML(resultJoins)
1563
+ html = await joinHTML(resultJoins, myzfield)
1420
1564
  } catch (e) {
1421
1565
  console.log(e)
1422
1566
  jsonNotif = Util.flashError(e + '')
@@ -1428,6 +1572,8 @@ router.post('/joins', async (req, res) => {
1428
1572
  async function loadJoins(table) {
1429
1573
  let html = ''
1430
1574
  try {
1575
+ /* let sql = `select ${table}.* from ${table} `;
1576
+ console.log(sql)*/
1431
1577
  let result = await connection.result({
1432
1578
  table: 'zfields',
1433
1579
  where: {
@@ -1435,7 +1581,7 @@ async function loadJoins(table) {
1435
1581
  },
1436
1582
  })
1437
1583
  let joinsObj = result.joins || {}
1438
- html = await joinHTML(joinsObj)
1584
+ html = await joinHTML(joinsObj, result)
1439
1585
  } catch (e) {
1440
1586
  console.log(e)
1441
1587
  html = e + ''
@@ -1443,7 +1589,7 @@ async function loadJoins(table) {
1443
1589
  return html
1444
1590
  }
1445
1591
 
1446
- async function joinHTML(json) {
1592
+ async function joinHTML(json, myzfield) {
1447
1593
  let html = ``
1448
1594
  try {
1449
1595
  let zfields = await connection.results({
@@ -1452,8 +1598,8 @@ async function joinHTML(json) {
1452
1598
  let zfieldsObj = Util.arrayToObject(zfields, 'table')
1453
1599
  for (let key in json) {
1454
1600
  html += `<div class="joinContainer col-md-4">`
1455
- html += `<h5>${zfieldsObj[key].name} <button class="btn btn-danger" onclick="removeJoins('${key}')"><i class="fa fa-trash "></i> </button></h5>`
1456
- html += fieldHTML(zfieldsObj[key])
1601
+ html += `<h5>${zfieldsObj[key].name} <button type="button" class="btn btn-danger" onclick="removeJoins('${key}')"><i class="fa fa-trash "></i> </button></h5>`
1602
+ html += fieldHTML(zfieldsObj[key], myzfield)
1457
1603
  html += `</div>`
1458
1604
  }
1459
1605
  } catch (e) {
@@ -1462,17 +1608,29 @@ async function joinHTML(json) {
1462
1608
  return html
1463
1609
  }
1464
1610
 
1465
- function fieldHTML(obj) {
1611
+ function fieldHTML(obj, myzfield) {
1466
1612
  let html = ``
1467
1613
  try {
1468
1614
  let labels = obj.labels
1469
1615
  let table = obj.table
1616
+ let myzfieldJoins = myzfield.joins || {}
1470
1617
  for (let key in labels) {
1618
+ let mylabel = labels[key]
1619
+ let selected = ''
1620
+ if (myzfieldJoins[table]) {
1621
+ let arr = myzfieldJoins[table] || []
1622
+ arr.map((item) => {
1623
+ if (item.key == `${table}___${key}`) {
1624
+ selected = ` checked `
1625
+ mylabel = item.value
1626
+ }
1627
+ })
1628
+ }
1471
1629
  html += `<div class="input-group">
1472
1630
  <div class="input-group-prepend">
1473
- <span class="input-group-text"><input type="checkbox" name=""></span>
1631
+ <span class="input-group-text"><input type="checkbox" ${selected} name="joins_checks___${table}___${key}"></span>
1474
1632
  <span class="input-group-text">${key}</span>
1475
- <input type="text" class="form-control" name="joins[${table}][${key}]" id="joins___${table}___${key}" value="${labels[key]}">
1633
+ <input type="text" class="form-control" name="joins_labels___${table}___${key}" id="joins___${table}___${key}" value="${mylabel}">
1476
1634
  </div>
1477
1635
  </div>`
1478
1636
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zet-lib",
3
- "version": "1.3.22",
3
+ "version": "1.3.24",
4
4
  "description": "zet is a library that part of zet generator.",
5
5
  "engines": {
6
6
  "node": ">=18"