zet-lib 1.3.23 → 1.3.25

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/Util.js CHANGED
@@ -1176,10 +1176,10 @@ Util.userAvatar = (img = '') => {
1176
1176
  }
1177
1177
 
1178
1178
  /*
1179
- MYSQL HELPER
1179
+ SQL HELPER
1180
1180
  */
1181
1181
  Util.selectParser = (fields = [], MYMODEL = {}) => {
1182
- //fields = fields.filter((e) => e !== 'actionColumn')
1182
+ let table = MYMODEL.table
1183
1183
  let virtuals = []
1184
1184
  let select = ''
1185
1185
  for (var key in MYMODEL.widgets) {
@@ -1190,19 +1190,40 @@ Util.selectParser = (fields = [], MYMODEL = {}) => {
1190
1190
  let arr = []
1191
1191
  fields.forEach((item) => {
1192
1192
  if (virtuals.includes(item)) {
1193
- select += MYMODEL.widgets[item].fields + ','
1193
+ select += `${MYMODEL.widgets[item].fields},`
1194
1194
  } else if (item === 'no') {
1195
- arr.push('id')
1195
+ arr.push(`${table}.id`)
1196
1196
  } else if (item === 'actionColumn') {
1197
- arr.push('lock')
1197
+ arr.push(`${table}.lock`)
1198
1198
  } else {
1199
- arr.push(item)
1199
+ arr.push(Util.fieldWithTable(item, MYMODEL))
1200
1200
  }
1201
1201
  })
1202
- select += `"${arr.join('","')}"`
1202
+ //select += `"${arr.join('","')}"`
1203
+ select += arr.join(',')
1203
1204
  return select
1204
1205
  }
1205
1206
 
1207
+ Util.fieldWithTable = (field, MYMODEL) => {
1208
+ let name = ''
1209
+ let joinList = MYMODEL.joins && MYMODEL.joins.list.length > 0 ? MYMODEL.joins.list : []
1210
+ if (joinList.length > 0) {
1211
+ if (joinList.includes(field)) {
1212
+ let split = field.split('___')
1213
+ name = `${split[0]}.${split[1]} as ${field}`
1214
+ } else {
1215
+ name = `${MYMODEL.table}.${field}`
1216
+ }
1217
+ } else {
1218
+ name = `${MYMODEL.table}.${field}`
1219
+ }
1220
+ return name
1221
+ }
1222
+
1223
+ Util.tableWithJoin = (MYMODEL) => {
1224
+ return MYMODEL.joins && MYMODEL.joins.list.length > 0 ? MYMODEL.joins.sql : []
1225
+ }
1226
+
1206
1227
  Util.selectMysql = (fields = [], relations = {}) => {
1207
1228
  let obj = {}
1208
1229
  let arr = []
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, '.', '')
@@ -418,7 +418,6 @@ const generate = async (req, res) => {
418
418
  //console.log(JSON.stringify(filesKey.modelObj))
419
419
  //check if has chains here
420
420
  MYMODEL = filesKey.modelObj
421
-
422
421
  //delete/clean zgrid after changes
423
422
  await connection.delete({
424
423
  table: 'zgrid',
@@ -503,7 +502,7 @@ const generate = async (req, res) => {
503
502
  fs.writeFileSync(`${dirRoot}/models/${filesKey.filename}`, newModel)
504
503
  }
505
504
  //check model if it has select relation in concat
506
- await scanning(MYMODEL)
505
+ await scanning(MYMODEL, result)
507
506
  }
508
507
  //generate views
509
508
  let DIR_VIEW = `${dirRoot}/views/${table}`
@@ -662,6 +661,113 @@ router.post('/savetabs', async (req, res) => {
662
661
  res.send(json)
663
662
  })
664
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
+
665
771
  const columnLR = (items, dataName) => {
666
772
  return `<div class="col-md-6"><ol class="mydragable divboxlittle" data-name="${dataName}">${items}</ol></div>`
667
773
  }
@@ -1074,13 +1180,15 @@ var saveToZFields = async (body) => {
1074
1180
  data.joins = JSON.stringify(joinsTables)
1075
1181
  }
1076
1182
 
1077
- await connection.update({
1183
+ let result = await connection.update({
1078
1184
  table: 'zfields',
1079
1185
  data: data,
1080
1186
  where: {
1081
1187
  table: table,
1082
1188
  },
1083
1189
  })
1190
+
1191
+ return result
1084
1192
  }
1085
1193
 
1086
1194
  //drop down chains effect
@@ -1218,16 +1326,15 @@ router.post('/import', async (req, res) => {
1218
1326
  /*
1219
1327
  Scanning relation id to name
1220
1328
  */
1221
- const scanning = async (MYMODEL) => {
1329
+ const scanning = async (MYMODEL, result) => {
1222
1330
  //let MYMODEL = require(`${dirRoot}/models/${table}`);
1223
- //console.log(JSON.stringify(MYMODEL))
1224
1331
  let table = MYMODEL.table
1225
1332
  const widgets = MYMODEL.widgets
1226
1333
  const not_scanning = ['created_by', 'updated_by']
1227
1334
  const concat_bracket = /(?<=\().+?(?=\))/g
1228
1335
  let changeWidgets = {}
1229
1336
  let changes = []
1230
- for (let key in widgets) {
1337
+ /*for (let key in widgets) {
1231
1338
  if (widgets[key].name == 'relation' || widgets[key].name == 'dropdown_multi' || widgets[key].name == 'typeahead') {
1232
1339
  if (!Util.in_array(key, not_scanning)) {
1233
1340
  let fields = widgets[key].fields
@@ -1262,7 +1369,7 @@ const scanning = async (MYMODEL) => {
1262
1369
  }
1263
1370
  }
1264
1371
  }
1265
- }
1372
+ }*/
1266
1373
 
1267
1374
  if (changes.length) {
1268
1375
  //rewrite model
@@ -1274,6 +1381,18 @@ const scanning = async (MYMODEL) => {
1274
1381
  fs.writeFileSync(`${dirRoot}/models/${MYMODEL.table}.js`, newModel)
1275
1382
  }
1276
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
+
1277
1396
  //return MYMODEL;
1278
1397
  }
1279
1398
 
@@ -1430,7 +1549,7 @@ router.post('/joins', async (req, res) => {
1430
1549
  },
1431
1550
  })
1432
1551
  let resultJoins = result.joins || {}
1433
- resultJoins[table_join] = {}
1552
+ resultJoins[table_join] = []
1434
1553
  let myzfield = await connection.update({
1435
1554
  table: 'zfields',
1436
1555
  data: {
package/lib/zRoute.js CHANGED
@@ -1901,12 +1901,14 @@ zRoute.listDataTable = async (req, res, objData = {}) => {
1901
1901
  try {
1902
1902
  const body = req.body
1903
1903
  const MYMODEL = objData.MYMODEL || {}
1904
+ const table = MYMODEL.table
1904
1905
  const fields = Object.prototype.hasOwnProperty.call(objData, 'fields') ? objData.fields : req.body.fields
1905
1906
  const relations = await zRoute.relations(req, res, MYMODEL.table)
1906
1907
  const select = Object.prototype.hasOwnProperty.call(objData, 'select') ? objData.select : Util.selectParser(fields, MYMODEL)
1907
1908
  const columns = Object.prototype.hasOwnProperty.call(objData, 'columns') ? objData.columns : body.columns
1908
1909
  const asDate = []
1909
1910
  const asJSONb = []
1911
+ const asArray = []
1910
1912
  for (let key in MYMODEL.widgets) {
1911
1913
  if (MYMODEL.widgets[key].name == 'datetime') {
1912
1914
  asDate.push(key)
@@ -1917,16 +1919,23 @@ zRoute.listDataTable = async (req, res, objData = {}) => {
1917
1919
  if (MYMODEL.widgets[key].name == 'dropdown_multi') {
1918
1920
  asJSONb.push(key)
1919
1921
  }
1922
+ if (MYMODEL.widgets[key].name == 'dragdrop') {
1923
+ asJSONb.push(key)
1924
+ }
1920
1925
  if (MYMODEL.widgets[key].name == 'dropdown_checkbox') {
1921
1926
  asJSONb.push(key)
1922
1927
  }
1928
+ if (MYMODEL.widgets[key].name == 'json_array' || MYMODEL.widgets[key].name == 'array' || MYMODEL.widgets[key].name == 'dropzone') {
1929
+ asArray.push(key)
1930
+ }
1923
1931
  }
1924
1932
  let whereArray = []
1925
1933
  if (objData.hasOwnProperty('whereArray')) {
1926
1934
  whereArray = objData['whereArray']
1927
1935
  }
1936
+
1928
1937
  whereArray.push({
1929
- field: 'company_id',
1938
+ field: `${table}.company_id`,
1930
1939
  option: '=',
1931
1940
  value: res.locals.companyId,
1932
1941
  operator: 'AND',
@@ -1941,17 +1950,28 @@ zRoute.listDataTable = async (req, res, objData = {}) => {
1941
1950
  if (asJSONb.includes(fields[item.data])) {
1942
1951
  astype = 'jsonb'
1943
1952
  }
1953
+ if (asArray.includes(fields[item.data])) {
1954
+ astype = 'array'
1955
+ }
1944
1956
  if (astype === 'jsonb') {
1945
1957
  whereArray.push({
1946
- field: fields[item.data],
1958
+ field: Util.fieldWithTable(fields[item.data], MYMODEL),
1947
1959
  option: ' ',
1948
1960
  value: ` @> '["${item.search.value}"]'`,
1949
1961
  operator: 'AND',
1950
1962
  type: 'inline',
1951
1963
  })
1964
+ } else if (astype === 'array') {
1965
+ whereArray.push({
1966
+ field: '',
1967
+ option: '',
1968
+ value: ` ${Util.fieldWithTable(fields[item.data], MYMODEL)}::text ILIKE '${item.search.value}' `,
1969
+ operator: 'AND',
1970
+ type: 'inline',
1971
+ })
1952
1972
  } else {
1953
1973
  whereArray.push({
1954
- field: fields[item.data],
1974
+ field: Util.fieldWithTable(fields[item.data], MYMODEL),
1955
1975
  option: MYMODEL.options[fields[item.data]],
1956
1976
  value: item.search.value,
1957
1977
  operator: 'AND',
@@ -1960,20 +1980,31 @@ zRoute.listDataTable = async (req, res, objData = {}) => {
1960
1980
  }
1961
1981
  }
1962
1982
  })
1963
- const orderColumn = fields[body.order[0].column] == 'actionColumn' ? 'id' : fields[body.order[0].column] == 'no' ? 'id' : fields[body.order[0].column] == 'actionColum' ? 'id' : fields[body.order[0].column]
1964
- const rows = await connection.results({
1983
+
1984
+ const orderColumn = fields[body.order[0].column] == 'actionColumn' ? `${table}.id` : fields[body.order[0].column] == 'no' ? `${table}.id` : fields[body.order[0].column] == 'actionColum' ? `${table}.id` : fields[body.order[0].column]
1985
+ let gridData = {
1965
1986
  select: select,
1966
1987
  table: MYMODEL.table,
1967
1988
  whereArray: whereArray,
1968
1989
  limit: body.length,
1969
1990
  offset: body.start,
1970
- orderBy: [orderColumn, body.order[0].dir],
1971
- })
1972
- const count = await connection.result({
1973
- select: 'count(id) as count',
1991
+ order_by: [`${orderColumn} ${body.order[0].dir}`],
1992
+ }
1993
+ let joins = Util.tableWithJoin(MYMODEL)
1994
+ if (joins.length > 0) {
1995
+ gridData.joins = joins
1996
+ }
1997
+ const rows = await connection.results(gridData)
1998
+ let gridCount = {
1999
+ select: `count(${table}.id) as count`,
1974
2000
  table: MYMODEL.table,
1975
2001
  whereArray: whereArray,
1976
- })
2002
+ }
2003
+ if (joins.length > 0) {
2004
+ gridCount.joins = joins
2005
+ }
2006
+ const count = await connection.result(gridCount)
2007
+
1977
2008
  let datas = []
1978
2009
  const zRole = objData.zRole || require('./zRole')
1979
2010
  const levels = objData.hasOwnProperty('levels') ? objData.levels : zRole.myLevel(req, res, MYMODEL.table)
@@ -2014,6 +2045,7 @@ zRoute.listDataTable = async (req, res, objData = {}) => {
2014
2045
 
2015
2046
  zRoute.listData = async (req, res, MYMODEL, zRole, actionButtonsFn) => {
2016
2047
  const room = res.locals.token || 'aa'
2048
+ const table = MYMODEL.table
2017
2049
  try {
2018
2050
  actionButtonsFn = actionButtonsFn || function () {}
2019
2051
  const relations = await zRoute.relations(req, res, MYMODEL.table)
@@ -2040,7 +2072,7 @@ zRoute.listData = async (req, res, MYMODEL, zRole, actionButtonsFn) => {
2040
2072
  if (MYMODEL.widgets[key].name == 'dropdown_checkbox') {
2041
2073
  asJSONb.push(key)
2042
2074
  }
2043
- if (MYMODEL.widgets[key].name == 'json_array' || MYMODEL.widgets[key].name == 'array') {
2075
+ if (MYMODEL.widgets[key].name == 'json_array' || MYMODEL.widgets[key].name == 'array' || MYMODEL.widgets[key].name == 'dropzone') {
2044
2076
  asArray.push(key)
2045
2077
  }
2046
2078
  }
@@ -2048,7 +2080,7 @@ zRoute.listData = async (req, res, MYMODEL, zRole, actionButtonsFn) => {
2048
2080
  const columns = body.columns
2049
2081
  if (MYMODEL.keys.includes('company_id')) {
2050
2082
  whereArray.push({
2051
- field: 'company_id',
2083
+ field: `${table}.company_id`,
2052
2084
  option: '=',
2053
2085
  value: res.locals.companyId,
2054
2086
  operator: 'AND',
@@ -2068,7 +2100,7 @@ zRoute.listData = async (req, res, MYMODEL, zRole, actionButtonsFn) => {
2068
2100
  }
2069
2101
  if (astype === 'jsonb') {
2070
2102
  whereArray.push({
2071
- field: fields[item.data],
2103
+ field: Util.fieldWithTable(fields[item.data], MYMODEL),
2072
2104
  option: ' ',
2073
2105
  value: ` @> '["${item.search.value}"]'`,
2074
2106
  operator: 'AND',
@@ -2078,13 +2110,13 @@ zRoute.listData = async (req, res, MYMODEL, zRole, actionButtonsFn) => {
2078
2110
  whereArray.push({
2079
2111
  field: '',
2080
2112
  option: '',
2081
- value: ` ${fields[item.data]}::text ILIKE '${item.search.value}' `,
2113
+ value: ` ${Util.fieldWithTable(fields[item.data], MYMODEL)}::text ILIKE '${item.search.value}' `,
2082
2114
  operator: 'AND',
2083
2115
  type: 'inline',
2084
2116
  })
2085
2117
  } else {
2086
2118
  whereArray.push({
2087
- field: fields[item.data],
2119
+ field: Util.fieldWithTable(fields[item.data], MYMODEL),
2088
2120
  option: MYMODEL.options[fields[item.data]],
2089
2121
  value: item.search.value,
2090
2122
  operator: 'AND',
@@ -2093,20 +2125,30 @@ zRoute.listData = async (req, res, MYMODEL, zRole, actionButtonsFn) => {
2093
2125
  }
2094
2126
  }
2095
2127
  })
2096
- const orderColumn = fields[body.order[0].column] == 'actionColumn' ? 'id' : fields[body.order[0].column] == 'no' ? 'id' : fields[body.order[0].column] == 'actionColum' ? 'id' : fields[body.order[0].column]
2097
- const rows = await connection.results({
2128
+
2129
+ const orderColumn = fields[body.order[0].column] == 'actionColumn' ? `${table}.id` : fields[body.order[0].column] == 'no' ? `${table}.id` : fields[body.order[0].column] == 'actionColum' ? `${table}.id` : fields[body.order[0].column]
2130
+ let gridData = {
2098
2131
  select: select,
2099
2132
  table: MYMODEL.table,
2100
2133
  whereArray: whereArray,
2101
2134
  limit: body.length,
2102
2135
  offset: body.start,
2103
- orderBy: [orderColumn, body.order[0].dir],
2104
- })
2105
- const count = await connection.result({
2106
- select: 'count(id) as count',
2136
+ order_by: [`${orderColumn} ${body.order[0].dir}`],
2137
+ }
2138
+ let joins = Util.tableWithJoin(MYMODEL)
2139
+ if (joins.length > 0) {
2140
+ gridData.joins = joins
2141
+ }
2142
+ const rows = await connection.results(gridData)
2143
+ let gridCount = {
2144
+ select: `count(${table}.id) as count`,
2107
2145
  table: MYMODEL.table,
2108
2146
  whereArray: whereArray,
2109
- })
2147
+ }
2148
+ if (joins.length > 0) {
2149
+ gridCount.joins = joins
2150
+ }
2151
+ const count = await connection.result(gridCount)
2110
2152
  let datas = []
2111
2153
  const levels = zRole.myLevel(req, res, MYMODEL.table)
2112
2154
  rows.forEach(function (row, index) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zet-lib",
3
- "version": "1.3.23",
3
+ "version": "1.3.25",
4
4
  "description": "zet is a library that part of zet generator.",
5
5
  "engines": {
6
6
  "node": ">=18"