@agung_dhewe/webapps 1.1.2 → 1.2.4

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.
Files changed (94) hide show
  1. package/lib/fgta5js-dist/fgta5js-v1.8.5.min.js +11 -0
  2. package/lib/fgta5js-dist/fgta5js-v1.8.5.min.js.map +1 -0
  3. package/{libs → lib}/webmodule/module-edit.css +73 -18
  4. package/{libs → lib}/webmodule/module-list.css +13 -0
  5. package/lib/webmodule/module-print.css +28 -0
  6. package/{libs → lib}/webmodule/module.css +13 -6
  7. package/{libs → lib}/webmodule/module.js +14 -4
  8. package/lib/webmodule/pagehelper.mjs +129 -0
  9. package/modules/generator/appgen-io.mjs +153 -76
  10. package/modules/generator/appgen-ui.mjs +234 -167
  11. package/modules/generator/generator-designtemplate-def.html +38 -0
  12. package/modules/generator/generator-designtemplate.html +11 -1492
  13. package/modules/generator/generator.css +103 -65
  14. package/modules/generator/generator.mjs +1 -1
  15. package/modules/generator/generator.svg +98 -0
  16. package/modules/generator/generatorEdit.mjs +43 -35
  17. package/modules/generator/generatorList.mjs +27 -0
  18. package/modules/generator/tpl-designerinfo.html +100 -0
  19. package/modules/generator/tpl-field-checkbox.html +200 -0
  20. package/modules/generator/tpl-field-combobox.html +228 -0
  21. package/modules/generator/tpl-field-datepicker.html +192 -0
  22. package/modules/generator/tpl-field-filebox.html +189 -0
  23. package/modules/generator/tpl-field-numberbox.html +218 -0
  24. package/modules/generator/tpl-field-textbox.html +255 -0
  25. package/modules/generator/tpl-field-timepicker.html +192 -0
  26. package/modules/generator/tpl-searchdesign.html +32 -0
  27. package/modules/generator/tpl-uniquedesign.html +25 -0
  28. package/modules/login/login.css +10 -2
  29. package/package.json +5 -3
  30. package/percobaan/coba-sequencer.js +16 -0
  31. package/src/api.js +12 -9
  32. package/src/apis/generator.api.js +35 -23
  33. package/src/apis/login.api.js +1 -0
  34. package/src/context.js +12 -2
  35. package/src/db.js +58 -32
  36. package/src/generator/createApiModule.js +4 -1
  37. package/src/generator/createIcon.js +24 -2
  38. package/src/generator/createLayoutCss.js +107 -0
  39. package/src/generator/createModuleDetilEditHtml.js +12 -1
  40. package/src/generator/createModuleDetilEditMjs.js +32 -28
  41. package/src/generator/createModuleDetilListHtml.js +14 -7
  42. package/src/generator/createModuleDetilListMjs.js +13 -1
  43. package/src/generator/createModuleHeaderEditHtml.js +13 -1
  44. package/src/generator/createModuleHeaderEditMjs.js +23 -2
  45. package/src/generator/createProgramData.js +3 -2
  46. package/src/generator/createTable.js +42 -38
  47. package/src/generator/helper.js +45 -27
  48. package/src/generator/templates/__rollup-module copy.ejs +90 -0
  49. package/src/generator/templates/__rollup-module.ejs +102 -31
  50. package/src/generator/templates/api-module.js.ejs +171 -32
  51. package/src/generator/templates/layout.css.ejs +24 -0
  52. package/src/generator/templates/module-ext.html.ejs +1 -1
  53. package/src/generator/templates/module-ext.mjs.ejs +19 -1
  54. package/src/generator/templates/module.ejs.ejs +8 -0
  55. package/src/generator/templates/module.mjs.ejs +42 -5
  56. package/src/generator/templates/moduleDetilEdit.html.ejs +11 -0
  57. package/src/generator/templates/moduleDetilEdit.mjs.ejs +135 -30
  58. package/src/generator/templates/moduleDetilList.html.ejs +2 -1
  59. package/src/generator/templates/moduleDetilList.mjs.ejs +86 -11
  60. package/src/generator/templates/moduleHeaderEdit.html.ejs +8 -1
  61. package/src/generator/templates/moduleHeaderEdit.mjs.ejs +123 -36
  62. package/src/generator/templates/moduleHeaderList.html.ejs +5 -1
  63. package/src/generator/templates/moduleHeaderList.mjs.ejs +47 -15
  64. package/src/generator/trygenerate.js +18 -2
  65. package/src/generator/worker.js +83 -72
  66. package/src/helper.js +12 -13
  67. package/src/logger.js +12 -12
  68. package/src/notifier.js +29 -0
  69. package/src/routers/generatorApi.js +9 -3
  70. package/src/routers/generatorPage.js +3 -1
  71. package/src/routers/moduleApi.js +1 -1
  72. package/src/routers/modulePage.js +42 -7
  73. package/src/sequencerdoc.js +22 -46
  74. package/src/sequencerline.js +16 -4
  75. package/src/session.js +69 -33
  76. package/src/startup.js +47 -10
  77. package/src/webapps.js +62 -18
  78. package/templates/_lib_debug.ejs +8 -8
  79. package/templates/_lib_production.ejs +2 -2
  80. package/templates/application.page.ejs +43 -8
  81. package/templates/generator.page.ejs +4 -3
  82. package/templates/index.page.ejs +2 -2
  83. package/templates/login.page.ejs +3 -3
  84. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js +0 -11
  85. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js.map +0 -1
  86. package/libs/webmodule/pagehelper.mjs +0 -45
  87. package/modules/generator/generator.png +0 -0
  88. /package/{libs/fgta5js-dist/fgta5js-v1.8.3.min.css → lib/fgta5js-dist/fgta5js-v1.8.5.min.css} +0 -0
  89. /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin-ext.woff2 +0 -0
  90. /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin.woff2 +0 -0
  91. /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin-ext.woff2 +0 -0
  92. /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin.woff2 +0 -0
  93. /package/{libs → lib}/fgta5js-dist/fonts/karla.css +0 -0
  94. /package/{libs → lib}/webmodule/module-footer.css +0 -0
@@ -29,13 +29,16 @@ export default class extends Api {
29
29
  // header-open-data
30
30
  async init(body) { return await <%= moduleName %>_init(this, body) }
31
31
 
32
+ // extender call
33
+ async execute(body) { return await <%= moduleName %>_execute(this, body) }
34
+
32
35
  // header
33
36
  async headerList(body) { return await <%= moduleName %>_headerList(this, body) }
34
37
  async headerOpen(body) { return await <%= moduleName %>_headerOpen(this, body) }
35
38
  async headerUpdate(body) { return await <%= moduleName %>_headerUpdate(this, body)}
36
39
  async headerCreate(body) { return await <%= moduleName %>_headerCreate(this, body)}
37
40
  async headerDelete(body) { return await <%= moduleName %>_headerDelete(this, body) }
38
-
41
+
39
42
  <% entitiesDetil.forEach(entity => { %>
40
43
  // <%= entity.name %>
41
44
  async <%= entity.name %>List(body) { return await <%= moduleName %>_<%= entity.name %>List(this, body) }
@@ -66,22 +69,49 @@ async function <%= moduleName %>_init(self, body) {
66
69
  }
67
70
  }
68
71
 
69
- return {
72
+ const initialData = {
70
73
  userId: req.session.user.userId,
71
74
  userName: req.session.user.userName,
72
75
  userFullname: req.session.userFullname,
73
76
  sid: req.session.sid ,
74
77
  notifierId: Api.generateNotifierId(moduleName, req.sessionID),
75
78
  notifierSocket: req.app.locals.appConfig.notifierSocket,
76
- appsUrls: appsUrls
79
+ appName: req.app.locals.appConfig.appName,
80
+ appsUrls: appsUrls,
81
+ setting: {}
77
82
  }
78
83
 
84
+ if (typeof Extender.<%= moduleName %>_init === 'function') {
85
+ // export async function <%= moduleName %>_init(self, initialData) {}
86
+ await Extender.<%= moduleName %>_init(self, initialData)
87
+ }
88
+
89
+ return initialData
90
+
79
91
  } catch (err) {
80
92
  throw err
81
93
  }
82
94
  }
83
95
 
84
96
 
97
+ // execute extender function
98
+ async function <%= moduleName %>_execute(self, body) {
99
+ const { fnName } = body
100
+
101
+ if (fnName==null || fnName=='') {
102
+ throw new Error('fnName belum didefinisikan di api call')
103
+ }
104
+
105
+ if (typeof Extender[fnName] === 'function') {
106
+ // export async function [fnName](self, db, body, <%= moduleName %>_log) {}
107
+ return await Extender[fnName](self, db, body, <%= moduleName %>_log)
108
+ } else {
109
+ // api function extender tidak ditemukan
110
+ throw new Error(`${fnName} tidak ditmukan di extender`)
111
+ }
112
+ }
113
+
114
+
85
115
  // data logging
86
116
  async function <%= moduleName %>_log(self, body, startTime, tablename, id, action, data={}, remark='') {
87
117
  const { source } = body
@@ -98,6 +128,8 @@ async function <%= moduleName %>_log(self, body, startTime, tablename, id, actio
98
128
  return ret
99
129
  }
100
130
 
131
+
132
+
101
133
  <% if (importbucket) { %>
102
134
  async function <%= moduleName %>_upload(self, data, files, detilName, id, fn_uploadSuccess) {
103
135
  const bucketname = '<%= moduleName %>'
@@ -162,14 +194,26 @@ async function <%= moduleName %>_headerList(self, body) {
162
194
  }
163
195
  }
164
196
 
197
+ const args = { db, criteria, tablename }
198
+
165
199
  // apabila ada keperluan untuk recompose criteria
166
200
  if (typeof Extender.headerListCriteria === 'function') {
167
- await Extender.headerListCriteria(self, db, searchMap, criteria, sort, columns)
201
+ // export async function headerListCriteria(self, db, searchMap, criteria, sort, columns, args) {}
202
+ await Extender.headerListCriteria(self, db, searchMap, criteria, sort, columns, args)
168
203
  }
169
204
 
170
205
  var max_rows = limit==0 ? 10 : limit
171
206
  const {whereClause, queryParams} = sqlUtil.createWhereClause(criteria, searchMap)
172
- const sql = sqlUtil.createSqlSelect({tablename, columns, whereClause, sort, limit:max_rows+1, offset, queryParams})
207
+ const sql = sqlUtil.createSqlSelect({
208
+ tablename: args.tablename,
209
+ columns,
210
+ whereClause,
211
+ sort: args.sqlSort ?? sort,
212
+ limit:max_rows+1,
213
+ offset,
214
+ queryParams
215
+ })
216
+
173
217
  const rows = await db.any(sql, queryParams);
174
218
 
175
219
 
@@ -187,7 +231,8 @@ async function <%= moduleName %>_headerList(self, body) {
187
231
  <% }) %>
188
232
  // pasang extender di sini
189
233
  if (typeof Extender.headerListRow === 'function') {
190
- await Extender.headerListRow(self, row)
234
+ // export async function headerListRow(self, row, args) {}
235
+ await Extender.headerListRow(self, row, args)
191
236
  }
192
237
 
193
238
  data.push(row)
@@ -252,8 +297,10 @@ async function <%= moduleName %>_headerOpen(self, body) {
252
297
  }
253
298
 
254
299
  // pasang extender untuk olah data
300
+ // export async function headerOpen(self, db, data) {}
255
301
  if (typeof Extender.headerOpen === 'function') {
256
- await Extender.headerOpen(self, data)
302
+ // export async function headerOpen(self, db, data) {}
303
+ await Extender.headerOpen(self, db, data)
257
304
  }
258
305
 
259
306
  return data
@@ -282,6 +329,9 @@ async function <%= moduleName %>_headerCreate(self, body) {
282
329
  const result = await db.tx(async tx=>{
283
330
  sqlUtil.connect(tx)
284
331
 
332
+
333
+ const args = { section: 'header', doc_id:'<%= identifierPrefix %>' }
334
+
285
335
  <% if (usesequencer) { %>// buat sequencer document
286
336
  const sequencer = createSequencerDocument(tx, {
287
337
  COMPANY_CODE: req.app.locals.appConfig.COMPANY_CODE,
@@ -292,49 +342,54 @@ async function <%= moduleName %>_headerCreate(self, body) {
292
342
  if (typeof Extender.sequencerSetup === 'function') {
293
343
  // jika ada keperluan menambahkan code block/cluster di sequencer
294
344
  // dapat diimplementasikan di exterder sequencerSetup
295
- await Extender.sequencerSetup(self, tx, sequencer, data)
345
+ // export async function sequencerSetup(self, tx, sequencer, data, args) {}
346
+ await Extender.sequencerSetup(self, tx, sequencer, data, args)
296
347
  }
297
348
 
298
- <%if (yearly) { %>// generate data <%= identifierPrefix %> reset pertahun
299
- const seqdata = await sequencer.yearly('<%= identifierPrefix %>')<% }
349
+ <%if (yearly) { %>// generate data sesuai prefix dari doc_id (default: <%= identifierPrefix %>) reset pertahun
350
+ const seqdata = await sequencer.yearly(args.doc_id)<% }
300
351
  else {
301
352
 
302
- %>// generate data <%= identifierPrefix %> reset perbulan
303
- const seqdata = await sequencer.monthly('<%= identifierPrefix %>')<% } %>
353
+ %>// generate data sesuai prefix dari doc_id (default: <%= identifierPrefix %>) reset perbulan
354
+ const seqdata = await sequencer.monthly(args.doc_id)<% } %>
304
355
  data.<%= headerPrimaryKey %> = seqdata.id
305
356
 
306
357
  // apabila ada keperluan pengelohan data sebelum disimpan, lakukan di extender headerCreating
307
358
  if (typeof Extender.headerCreating === 'function') {
308
- await Extender.headerCreating(self, tx, data, seqdata)
359
+ // export async function headerCreating(self, tx, data, seqdata, args) {}
360
+ await Extender.headerCreating(self, tx, data, seqdata, args)
309
361
  }
310
362
 
311
- <% } else if (usesequencerline) { %>
363
+ <% } else if (shortsequencer) { %>
312
364
  // buat short sequencer
313
365
  const sequencer = createSequencerLine(tx, {})
314
366
 
315
367
  if (typeof Extender.sequencerSetup === 'function') {
316
368
  // jika ada keperluan menambahkan code block/cluster di sequencer
317
369
  // dapat diimplementasikan di exterder sequencerSetup
318
- await Extender.sequencerSetup(self, tx, sequencer, data)
370
+ // export async function sequencerSetup(self, tx, sequencer, data, args) {}
371
+ await Extender.sequencerSetup(self, tx, sequencer, data, args)
319
372
  }
320
373
 
321
- // generate short id untuk <%= identifierPrefix %> reset pertahun
322
- const id = await sequencer.yearlyshort('<%= identifierPrefix %>')
323
- data.<%= headerPrimaryKey %> = id
374
+ // generate short id sesuai prefix (default: <%= identifierPrefix %>) reset pertahun
375
+ const seqdata = await sequencer.yearlyshort(args.prefix)
376
+ data.<%= headerPrimaryKey %> = seqdata.id
324
377
 
325
378
  // apabila ada keperluan pengelohan data sebelum disimpan, lakukan di extender headerCreating
326
379
  if (typeof Extender.headerCreating === 'function') {
327
- await Extender.headerCreating(self, tx, data)
380
+ // export async function headerCreating(self, tx, data, seqdata, args) {}
381
+ await Extender.headerCreating(self, tx, data, seqdata, args)
328
382
  }
329
383
 
330
384
  <% } else { %>
331
385
  // apabila ada keperluan pengelohan data sebelum disimpan, lakukan di extender headerCreating
332
386
  if (typeof Extender.headerCreating === 'function') {
333
- await Extender.headerCreating(self, tx, data)
387
+ // export async function headerCreating(self, tx, data, seqdata, args) {}
388
+ await Extender.headerCreating(self, tx, data, null, args)
334
389
  }<% } %>
335
390
 
336
391
  <% if (autoid) {
337
- %><% if (usesequencer || usesequencerline) { %>const cmd = sqlUtil.createInsertCommand(tablename, data)<% } else { %>const cmd = sqlUtil.createInsertCommand(tablename, data, ['<%= headerPrimaryKey %>'])<% } %><%
392
+ %><% if (usesequencer || shortsequencer) { %>const cmd = sqlUtil.createInsertCommand(tablename, data)<% } else { %>const cmd = sqlUtil.createInsertCommand(tablename, data, ['<%= headerPrimaryKey %>'])<% } %><%
338
393
  } else { %>const cmd = sqlUtil.createInsertCommand(tablename, data)<% } %>
339
394
  const ret = await cmd.execute(data)
340
395
 
@@ -350,7 +405,8 @@ async function <%= moduleName %>_headerCreate(self, body) {
350
405
 
351
406
  // apabila ada keperluan pengelohan data setelah disimpan, lakukan di extender headerCreated
352
407
  if (typeof Extender.headerCreated === 'function') {
353
- await Extender.headerCreated(self, tx, ret, data, logMetadata)
408
+ // export async function headerCreated(self, tx, ret, data, logMetadata, args) {}
409
+ await Extender.headerCreated(self, tx, ret, data, logMetadata, args)
354
410
  }
355
411
 
356
412
  // record log
@@ -387,6 +443,7 @@ async function <%= moduleName %>_headerUpdate(self, body) {
387
443
 
388
444
  // apabila ada keperluan pengelohan data sebelum disimpan, lakukan di extender headerCreating
389
445
  if (typeof Extender.headerUpdating === 'function') {
446
+ // export async function headerUpdating(self, tx, data) {}
390
447
  await Extender.headerUpdating(self, tx, data)
391
448
  }
392
449
 
@@ -406,6 +463,7 @@ async function <%= moduleName %>_headerUpdate(self, body) {
406
463
 
407
464
  // apabila ada keperluan pengelohan data setelah disimpan, lakukan di extender headerCreated
408
465
  if (typeof Extender.headerUpdated === 'function') {
466
+ // export async function headerUpdated(self, tx, ret, data, logMetadata) {}
409
467
  await Extender.headerUpdated(self, tx, ret, data, logMetadata)
410
468
  }
411
469
 
@@ -439,6 +497,7 @@ async function <%= moduleName %>_headerDelete(self, body) {
439
497
 
440
498
  // apabila ada keperluan pengelohan data sebelum dihapus, lakukan di extender headerDeleting
441
499
  if (typeof Extender.headerDeleting === 'function') {
500
+ // export async function headerDeleting(self, tx, dataToRemove) {}
442
501
  await Extender.headerDeleting(self, tx, dataToRemove)
443
502
  }
444
503
 
@@ -448,8 +507,12 @@ async function <%= moduleName %>_headerDelete(self, body) {
448
507
  const sql = `select * from ${<%= entity.name %>TableName} where <%= headerPrimaryKey %>=\${<%= headerPrimaryKey %>}`
449
508
  const rows = await tx.any(sql, dataToRemove)
450
509
  for (let row<%= entity.name %> of rows) {
510
+
511
+ const logMetadata = {}
512
+
451
513
  // apabila ada keperluan pengelohan data sebelum dihapus, lakukan di extender
452
514
  if (typeof Extender.<%= entity.name %>Deleting === 'function') {
515
+ // export async function <%= entity.name %>Deleting(self, tx, row<%= entity.name %>, logMetadata) {}
453
516
  await Extender.<%= entity.name %>Deleting(self, tx, row<%= entity.name %>, logMetadata)
454
517
  }
455
518
 
@@ -459,6 +522,7 @@ async function <%= moduleName %>_headerDelete(self, body) {
459
522
 
460
523
  // apabila ada keperluan pengelohan data setelah dihapus, lakukan di extender
461
524
  if (typeof Extender.<%= entity.name %>Deleted === 'function') {
525
+ // export async function <%= entity.name %>Deleted(self, tx, deletedRow, logMetadata) {}
462
526
  await Extender.<%= entity.name %>Deleted(self, tx, deletedRow, logMetadata)
463
527
  }
464
528
 
@@ -480,7 +544,8 @@ async function <%= moduleName %>_headerDelete(self, body) {
480
544
 
481
545
  // apabila ada keperluan pengelohan data setelah dihapus, lakukan di extender headerDeleted
482
546
  if (typeof Extender.headerDeleted === 'function') {
483
- await Extender.headerDeleted(self, tx, ret, logMetadata)
547
+ // export async function headerDeleted(self, tx, deletedRow, logMetadata) {}
548
+ await Extender.headerDeleted(self, tx, deletedRow, logMetadata)
484
549
  }
485
550
 
486
551
  // record log
@@ -508,6 +573,11 @@ async function <%= moduleName %>_<%= entity.name %>List(self, body) {
508
573
  };
509
574
 
510
575
 
576
+ if (Object.keys(sort).length === 0) {
577
+ sort.<%= entity.pk %> = 'asc'
578
+ }
579
+
580
+
511
581
  try {
512
582
 
513
583
  // hilangkan criteria '' atau null
@@ -517,14 +587,25 @@ async function <%= moduleName %>_<%= entity.name %>List(self, body) {
517
587
  }
518
588
  }
519
589
 
590
+ const args = { db, criteria, tablename }
591
+
520
592
  // apabila ada keperluan untuk recompose criteria
521
- if (typeof Extender.<%= moduleName %>ListCriteria === 'function') {
522
- await Extender.<%= moduleName %>ListCriteria(self, db, searchMap, criteria, sort, columns)
593
+ if (typeof Extender.<%= entity.name %>ListCriteria === 'function') {
594
+ // export async function <%= entity.name %>ListCriteria(self, db, searchMap, criteria, sort, columns, args) {}
595
+ await Extender.<%= entity.name %>ListCriteria(self, db, searchMap, criteria, sort, columns, args)
523
596
  }
524
597
 
525
598
  var max_rows = limit==0 ? 10 : limit
526
599
  const {whereClause, queryParams} = sqlUtil.createWhereClause(criteria, searchMap)
527
- const sql = sqlUtil.createSqlSelect({tablename, columns, whereClause, sort, limit:max_rows+1, offset, queryParams})
600
+ const sql = sqlUtil.createSqlSelect({
601
+ tablename: args.tablename,
602
+ columns,
603
+ whereClause,
604
+ sort: args.sqlSort ?? sort,
605
+ limit:max_rows+1,
606
+ offset,
607
+ queryParams
608
+ })
528
609
  const rows = await db.any(sql, queryParams);
529
610
 
530
611
 
@@ -543,7 +624,8 @@ async function <%= moduleName %>_<%= entity.name %>List(self, body) {
543
624
 
544
625
  // pasang extender di sini
545
626
  if (typeof Extender.detilListRow === 'function') {
546
- await Extender.detilListRow(row)
627
+ // export async function detilListRow(self, row, args) {}
628
+ await Extender.detilListRow(self, row, args)
547
629
  }
548
630
 
549
631
  data.push(row)
@@ -554,13 +636,20 @@ async function <%= moduleName %>_<%= entity.name %>List(self, body) {
554
636
  nextoffset = offset+max_rows
555
637
  }
556
638
 
557
- return {
639
+
640
+ const listData = {
558
641
  criteria: criteria,
559
642
  limit: max_rows,
560
643
  nextoffset: nextoffset,
561
644
  data: data
562
645
  }
563
646
 
647
+ if (typeof Extender.detilList === 'function') {
648
+ // export async function detilList(self, listData, args) {}
649
+ await Extender.detilList(self, listData, args)
650
+ }
651
+
652
+ return listData
564
653
  } catch (err) {
565
654
  throw err
566
655
  }
@@ -608,6 +697,14 @@ async function <%= moduleName %>_<%= entity.name %>Open(self, body) {
608
697
  data._modifyby = user_fullname ?? ''
609
698
  }
610
699
 
700
+
701
+ // pasang extender untuk olah data
702
+ // export async function <%= entity.name %>Open(self, db, data) {}
703
+ if (typeof Extender.<%= entity.name %>Open === 'function') {
704
+ // export async function <%= entity.name %>Open(self, db, data) {}
705
+ await Extender.<%= entity.name %>Open(self, db, data)
706
+ }
707
+
611
708
  return data
612
709
  } catch (err) {
613
710
  throw err
@@ -633,13 +730,30 @@ async function <%= moduleName %>_<%= entity.name %>Create(self, body) {
633
730
  const result = await db.tx(async tx=>{
634
731
  sqlUtil.connect(tx)
635
732
 
733
+
734
+ const args = {
735
+ section: '<%= entity.name %>',
736
+ prefix: '<%= identifierPrefix %>'
737
+ }
738
+
636
739
  const sequencer = createSequencerLine(tx, {})
637
- const id = await sequencer.increment('<%= identifierPrefix %>')
638
- data.<%= entity.pk %> = id
740
+
741
+
742
+ if (typeof Extender.sequencerSetup === 'function') {
743
+ // jika ada keperluan menambahkan code block/cluster di sequencer
744
+ // dapat diimplementasikan di exterder sequencerSetup
745
+ // export async function sequencerSetup(self, tx, sequencer, data, args) {}
746
+ await Extender.sequencerSetup(self, tx, sequencer, data, args)
747
+ }
748
+
749
+
750
+ const seqdata = await sequencer.increment(args.prefix)
751
+ data.<%= entity.pk %> = seqdata.id
639
752
 
640
753
  // apabila ada keperluan pengolahan data SEBELUM disimpan
641
754
  if (typeof Extender.<%= entity.name %>Creating === 'function') {
642
- await Extender.<%= entity.name %>Creating(self, tx, data)
755
+ // export async function <%= entity.name %>Creating(self, tx, data, seqdata, args) {}
756
+ await Extender.<%= entity.name %>Creating(self, tx, data, seqdata, args)
643
757
  }
644
758
 
645
759
  const cmd = sqlUtil.createInsertCommand(tablename, data)
@@ -656,7 +770,8 @@ async function <%= moduleName %>_<%= entity.name %>Create(self, body) {
656
770
 
657
771
  // apabila ada keperluan pengelohan data setelah disimpan, lakukan di extender headerCreated
658
772
  if (typeof Extender.<%= entity.name %>Created === 'function') {
659
- await Extender.<%= entity.name %>Created(self, tx, ret, data, logMetadata)
773
+ // export async function <%= entity.name %>Created(self, tx, ret, data, logMetadata, args) {}
774
+ await Extender.<%= entity.name %>Created(self, tx, ret, data, logMetadata, args)
660
775
  }
661
776
 
662
777
  // record log
@@ -693,6 +808,7 @@ async function <%= moduleName %>_<%= entity.name %>Update(self, body) {
693
808
 
694
809
  // apabila ada keperluan pengolahan data SEBELUM disimpan
695
810
  if (typeof Extender.<%= entity.name %>Updating === 'function') {
811
+ // export async function <%= entity.name %>Updating(self, tx, data) {}
696
812
  await Extender.<%= entity.name %>Updating(self, tx, data)
697
813
  }
698
814
 
@@ -710,6 +826,7 @@ async function <%= moduleName %>_<%= entity.name %>Update(self, body) {
710
826
 
711
827
  // apabila ada keperluan pengelohan data setelah disimpan, lakukan di extender headerCreated
712
828
  if (typeof Extender.<%= entity.name %>Updated === 'function') {
829
+ // export async function <%= entity.name %>Updated(self, tx, ret, data, logMetadata) {}
713
830
  await Extender.<%= entity.name %>Updated(self, tx, ret, data, logMetadata)
714
831
  }
715
832
 
@@ -741,9 +858,11 @@ async function <%= moduleName %>_<%= entity.name %>Delete(self, body) {
741
858
  const sql = `select * from ${<%= entity.name %>TableName} where <%= entity.pk %>=\${<%= entity.pk %>}`
742
859
  const row<%= entity.name %> = await tx.oneOrNone(sql, dataToRemove)
743
860
 
861
+ const logMetadata = {}
744
862
 
745
863
  // apabila ada keperluan pengelohan data sebelum dihapus, lakukan di extender
746
864
  if (typeof Extender.<%= entity.name %>Deleting === 'function') {
865
+ // export async function <%= entity.name %>Deleting(self, tx, row<%= entity.name %>, logMetadata) {}
747
866
  await Extender.<%= entity.name %>Deleting(self, tx, row<%= entity.name %>, logMetadata)
748
867
  }
749
868
 
@@ -753,6 +872,7 @@ async function <%= moduleName %>_<%= entity.name %>Delete(self, body) {
753
872
 
754
873
  // apabila ada keperluan pengelohan data setelah dihapus, lakukan di extender
755
874
  if (typeof Extender.<%= entity.name %>Deleted === 'function') {
875
+ // export async function <%= entity.name %>Deleted(self, tx, deletedRow, logMetadata) {}
756
876
  await Extender.<%= entity.name %>Deleted(self, tx, deletedRow, logMetadata)
757
877
  }
758
878
 
@@ -778,6 +898,8 @@ async function <%= moduleName %>_<%= entity.name %>DeleteRows(self, body) {
778
898
 
779
899
 
780
900
  try {
901
+
902
+ let <%= headerPrimaryKey %>
781
903
  const result = await db.tx(async tx=>{
782
904
  sqlUtil.connect(tx)
783
905
 
@@ -785,9 +907,14 @@ async function <%= moduleName %>_<%= entity.name %>DeleteRows(self, body) {
785
907
  const dataToRemove = {<%= entity.pk %>: id}
786
908
  const sql = `select * from ${<%= entity.name %>TableName} where <%= entity.pk %>=\${<%= entity.pk %>}`
787
909
  const row<%= entity.name %> = await tx.oneOrNone(sql, dataToRemove)
910
+ <%= headerPrimaryKey %> = row<%= entity.name %>.<%= headerPrimaryKey %>
788
911
 
912
+ const logMetadata = {}
913
+
914
+
789
915
  // apabila ada keperluan pengelohan data sebelum dihapus, lakukan di extender
790
916
  if (typeof Extender.<%= entity.name %>Deleting === 'function') {
917
+ // async function <%= entity.name %>Deleting(self, tx, row<%= entity.name %>, logMetadata) {}
791
918
  await Extender.<%= entity.name %>Deleting(self, tx, row<%= entity.name %>, logMetadata)
792
919
  }
793
920
 
@@ -797,6 +924,7 @@ async function <%= moduleName %>_<%= entity.name %>DeleteRows(self, body) {
797
924
 
798
925
  // apabila ada keperluan pengelohan data setelah dihapus, lakukan di extender
799
926
  if (typeof Extender.<%= entity.name %>Deleted === 'function') {
927
+ // export async function <%= entity.name %>Deleted(self, tx, deletedRow, logMetadata) {}
800
928
  await Extender.<%= entity.name %>Deleted(self, tx, deletedRow, logMetadata)
801
929
  }
802
930
 
@@ -804,11 +932,22 @@ async function <%= moduleName %>_<%= entity.name %>DeleteRows(self, body) {
804
932
  <%= moduleName %>_log(self, body, startTime, headerTableName, row<%= entity.name %>.<%= headerPrimaryKey %>, 'DELETE ROW <%= entity.name.toUpperCase() %>', {<%= entity.pk %>: row<%= entity.name %>.<%= entity.pk %>, tablename: <%= entity.name %>TableName}, `removed: ${row<%= entity.name %>.<%= entity.pk %>}`)
805
933
  }
806
934
  })
935
+
807
936
 
808
937
  const res = {
809
938
  deleted: true,
939
+ <%= headerPrimaryKey %>: <%= headerPrimaryKey %>,
810
940
  message: ''
811
941
  }
942
+
943
+ // apabila ada keperluan update info / pemrosesan data setelah hapus multirow, lakukan di extender
944
+ const fn_name = '<%= entity.name %>RowsDeleted'
945
+ const fn = Extender[fn_name]
946
+ if (typeof fn === 'function') {
947
+ // export async function <%= entity.name %>RowsDeleted(self, db, res) {}
948
+ await fn(self, db, res)
949
+ }
950
+
812
951
  return res
813
952
  } catch (err) {
814
953
  throw err
@@ -0,0 +1,24 @@
1
+ @media screen and (min-width: 501px) {
2
+
3
+ #<%= modulePart %>-frm {
4
+ display: grid;
5
+ grid-template-columns: repeat(6, 1fr);
6
+ grid-auto-rows: auto;
7
+ gap: 0;
8
+ width: 850px;
9
+ }
10
+
11
+ #<%= modulePart %>-frm > div {
12
+ padding: 5px;
13
+ }
14
+
15
+ <% fields.forEach(field => { %>
16
+ #<%= field.elementId %>-container {
17
+ grid-row: <%= field.dposrow %><%= field.dposrowspan %>;
18
+ grid-column: <%= field.dposcol %><%= field.dposcolspan %>;
19
+ <%= field.dposstyle %>
20
+ }
21
+ <% }) %>
22
+
23
+
24
+ }
@@ -1,3 +1,3 @@
1
1
  <!-- Additional Search Parameter-->
2
- <template name="custom-search-panel">
2
+ <template id="tpl-custom-search-panel">
3
3
  </template>
@@ -9,13 +9,31 @@ export async function init(self, args) {
9
9
  /* // contoh menambahkan content dari template extender
10
10
  {
11
11
  const target = secRec.querySelector('#fRecord-section div[name="column"][exteder]')
12
- const tpl = document.querySelector('template[name="record-panel"]')
12
+ const tpl = document.getElementById('tpl-record-panel')
13
13
  if (tpl!=null) {
14
14
  const clone = tpl.content.cloneNode(true); // salin isi template
15
15
  target.prepend(clone)
16
16
  }
17
17
  }
18
18
  */
19
+
20
+
21
+
22
+ /* // contoh menambahkan custom validator
23
+ // pada html, tambahkan validator="cobaFunction:paramValue"
24
+ const frm = self.Modules.coaHeaderEdit.getHeaderForm()
25
+ const obj_coa_normal = frm.Inputs['coaHeaderEdit-obj_coa_normal']
26
+ $validators.addCustomValidator('cobaFunction', (v, param)=>{
27
+ console.log(v)
28
+ setTimeout(()=>{
29
+ obj_coa_normal.setError('ini error')
30
+ }, 500)
31
+ })
32
+
33
+
34
+ */
35
+
36
+
19
37
  }
20
38
 
21
39
 
@@ -5,8 +5,16 @@
5
5
  <% }) %>
6
6
 
7
7
  <section id="fRecord-section" class="fgta5-carousell" data-title="Record Status">
8
+
8
9
  <div name="panel">
10
+ <div name="row">
11
+ <span name="caption">Id</span>
12
+ <span name="value" id="fRecord-section-id">-</span>
13
+ </div>
14
+ </div>
9
15
 
16
+
17
+ <div name="panel">
10
18
  <!-- LEFT: Standard Info -->
11
19
  <div name="column">
12
20
  <div name="row">
@@ -20,6 +20,22 @@ export default class extends Module {
20
20
  args.autoLoadGridData = true
21
21
 
22
22
  const self = this
23
+ Context.program = self
24
+
25
+ // ambil metadata variance dan id
26
+ const variance = document.querySelector('meta[name="variance"]').getAttribute('content');
27
+ const id = document.querySelector('meta[name="id"]').getAttribute('content');
28
+ Context.variance = variance
29
+ Context.id = id
30
+
31
+
32
+ // configureModule
33
+ // gunakan untuk setup context atau args
34
+ const fn_configureModule_name = 'configureModule'
35
+ const fn_configureModule = Extender[fn_configureModule_name]
36
+ if (typeof fn_configureModule === 'function') {
37
+ fn_configureModule(self, args)
38
+ }
23
39
 
24
40
  // module-module yang di load perlu di pack dulu ke dalam variable
25
41
  // jangan import lagi module-module ini di dalam mjs tersebut
@@ -38,7 +54,9 @@ export default class extends Module {
38
54
  Context.userId = result.userId
39
55
  Context.userFullname = result.userFullname
40
56
  Context.sid = result.sid
57
+ Context.appName = result.appName
41
58
  Context.appsUrls = result.appsUrls
59
+ Context.setting = result.setting
42
60
  } catch (err) {
43
61
  throw err
44
62
  }
@@ -73,7 +91,7 @@ export default class extends Module {
73
91
  }
74
92
  };
75
93
 
76
-
94
+ app.finalize()
77
95
  } catch (err) {
78
96
  throw err
79
97
  }
@@ -137,7 +155,16 @@ async function render(self) {
137
155
  const sectionTargetName = link.getAttribute('data-target-section')
138
156
  const sectionCurrentName = link.getAttribute('data-current-section')
139
157
 
158
+ // Detil bisa dibuka apabila data sudah di save
140
159
  link.addEventListener('click', (evt)=>{
160
+ const moduleHeaderEdit = self.Modules[sectionCurrentName]
161
+ const form = moduleHeaderEdit.getForm()
162
+ if (form.isNew()) {
163
+ console.warn('tidak bisa buka detil jika data baru')
164
+ $fgta5.MessageBox.warning('Detil bisa dibuka setelah data disimpan')
165
+ return;
166
+ }
167
+
141
168
  openDetilSection(self, sectionTargetName, sectionCurrentName)
142
169
  })
143
170
 
@@ -169,10 +196,17 @@ function openDetilSection(self, sectionTargetName, sectionCurrentName) {
169
196
  const sectionId = Context.Sections[sectionTargetName]
170
197
  const section = Crsl.Items[sectionId]
171
198
 
199
+ const moduleHeaderEdit = self.Modules[sectionCurrentName]
200
+ const frm = moduleHeaderEdit.getForm()
201
+
202
+ if (frm.isChanged()) {
203
+ $fgta5.MessageBox.warning(`simpan data dulu sebelum ke <b>${section.Title}</b>`)
204
+ return
205
+ }
206
+
172
207
  section.setSectionReturn(sectionCurrent)
173
208
  section.show({}, ()=>{
174
209
  const moduleTarget = self.Modules[sectionTargetName]
175
- const moduleHeaderEdit = self.Modules[sectionCurrentName]
176
210
  moduleTarget.openList(self, {
177
211
  moduleHeaderEdit
178
212
  })
@@ -203,11 +237,14 @@ function listenUserKeys(self) {
203
237
  const module = self.Modules[moduleId]
204
238
 
205
239
  // jika ada dialog yang terbuka, semua event keyboard abaikan dulu, keculai tombol escape
206
- const dialog = document.querySelector('dialog[open]');
240
+ const dialogs = [...document.querySelectorAll('dialog[open]')];
241
+ const dialog = dialogs.pop() || null;
242
+ // const dialog = document.querySelector('dialog[open]');
207
243
  if (dialog) {
208
244
  if (evt.key.toLowerCase()=='escape') {
209
- dialog.close();
210
- evt.preventDefault();
245
+ dialog.close()
246
+ evt.preventDefault()
247
+ evt.stopPropagation()
211
248
  } else if ((evt.ctrlKey || evt.metaKey) && evt.key.toLowerCase() === 's') {
212
249
  evt.preventDefault();
213
250
  }