@agung_dhewe/webapps 1.1.2 → 1.2.3

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 (93) 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 +45 -38
  47. package/src/generator/helper.js +45 -27
  48. package/src/generator/templates/__rollup-module.ejs +1 -1
  49. package/src/generator/templates/api-module.js.ejs +171 -32
  50. package/src/generator/templates/layout.css.ejs +24 -0
  51. package/src/generator/templates/module-ext.html.ejs +1 -1
  52. package/src/generator/templates/module-ext.mjs.ejs +19 -1
  53. package/src/generator/templates/module.ejs.ejs +8 -0
  54. package/src/generator/templates/module.mjs.ejs +42 -5
  55. package/src/generator/templates/moduleDetilEdit.html.ejs +11 -0
  56. package/src/generator/templates/moduleDetilEdit.mjs.ejs +135 -30
  57. package/src/generator/templates/moduleDetilList.html.ejs +2 -1
  58. package/src/generator/templates/moduleDetilList.mjs.ejs +86 -11
  59. package/src/generator/templates/moduleHeaderEdit.html.ejs +8 -1
  60. package/src/generator/templates/moduleHeaderEdit.mjs.ejs +123 -36
  61. package/src/generator/templates/moduleHeaderList.html.ejs +5 -1
  62. package/src/generator/templates/moduleHeaderList.mjs.ejs +47 -15
  63. package/src/generator/trygenerate.js +18 -2
  64. package/src/generator/worker.js +83 -72
  65. package/src/helper.js +12 -13
  66. package/src/logger.js +12 -12
  67. package/src/notifier.js +29 -0
  68. package/src/routers/generatorApi.js +9 -3
  69. package/src/routers/generatorPage.js +3 -1
  70. package/src/routers/moduleApi.js +1 -1
  71. package/src/routers/modulePage.js +32 -7
  72. package/src/sequencerdoc.js +22 -46
  73. package/src/sequencerline.js +16 -4
  74. package/src/session.js +69 -33
  75. package/src/startup.js +47 -10
  76. package/src/webapps.js +62 -18
  77. package/templates/_lib_debug.ejs +8 -8
  78. package/templates/_lib_production.ejs +2 -2
  79. package/templates/application.page.ejs +39 -6
  80. package/templates/generator.page.ejs +4 -3
  81. package/templates/index.page.ejs +2 -2
  82. package/templates/login.page.ejs +3 -3
  83. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js +0 -11
  84. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js.map +0 -1
  85. package/libs/webmodule/pagehelper.mjs +0 -45
  86. package/modules/generator/generator.png +0 -0
  87. /package/{libs/fgta5js-dist/fgta5js-v1.8.3.min.css → lib/fgta5js-dist/fgta5js-v1.8.5.min.css} +0 -0
  88. /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin-ext.woff2 +0 -0
  89. /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin.woff2 +0 -0
  90. /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin-ext.woff2 +0 -0
  91. /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin.woff2 +0 -0
  92. /package/{libs → lib}/fgta5js-dist/fonts/karla.css +0 -0
  93. /package/{libs → lib}/webmodule/module-footer.css +0 -0
@@ -1,13 +1,15 @@
1
1
  import Context from './<%= moduleName %>-context.mjs'
2
- import * as Extender from './<%= moduleName %>-ext.mjs'
3
- import * as pageHelper from '/public/libs/webmodule/pagehelper.mjs'
2
+ import * as Ext from './<%= moduleName %>-ext.mjs'
3
+ import * as pageHelper from '/public/lib/webmodule/pagehelper.mjs'
4
+
5
+ const Extender = Ext.extenderHeader ?? Ext
6
+
4
7
 
5
- const CurrentState = {}
6
8
  const Crsl = Context.Crsl
7
9
  const CurrentSectionId = Context.Sections.<%= modulePart %>
8
10
  const CurrentSection = Crsl.Items[CurrentSectionId]
9
11
  const Source = Context.Source
10
-
12
+ const CurrentState = {}
11
13
 
12
14
  const TitleWhenNew = 'New <%= title %>'
13
15
  const TitleWhenView = 'View <%= title %>'
@@ -23,20 +25,24 @@ const btn_reset = new $fgta5.ActionButton('<%= modulePart %>-btn_reset')
23
25
  const btn_prev = new $fgta5.ActionButton('<%= modulePart %>-btn_prev')
24
26
  const btn_next = new $fgta5.ActionButton('<%= modulePart %>-btn_next')
25
27
 
28
+ <%if (actionList.length>0) {%><% actionList.forEach(action => { %>const <%= action.buttonName %> = new $fgta5.ActionButton('<%= action.elementId %>')
29
+ <% }) %><% } %>
26
30
  const btn_recordstatus = document.getElementById('<%= moduleSection %>-btn_recordstatus')
27
31
  const btn_logs = document.getElementById('<%= moduleSection %>-btn_logs')
28
32
  const btn_about = document.getElementById('<%= moduleSection %>-btn_about')
29
33
 
30
34
  const frm = new $fgta5.Form('<%= modulePart %>-frm');<% fields.forEach(field => { %>
31
35
  const <%= field.inputname %> = frm.Inputs['<%= field.elementId %>']<% }) %>
32
- const obj_createby = document.getElementById('fRecord-section-createby')
33
- const obj_createdate = document.getElementById('fRecord-section-createdate')
34
- const obj_modifyby = document.getElementById('fRecord-section-modifyby')
35
- const obj_modifydate = document.getElementById('fRecord-section-modifydate')
36
+ const rec_createby = document.getElementById('fRecord-section-createby')
37
+ const rec_createdate = document.getElementById('fRecord-section-createdate')
38
+ const rec_modifyby = document.getElementById('fRecord-section-modifyby')
39
+ const rec_modifydate = document.getElementById('fRecord-section-modifydate')
40
+ const rec_id = document.getElementById('fRecord-section-id')
36
41
 
37
42
 
38
43
  export const Section = CurrentSection
39
44
 
45
+
40
46
  export async function init(self, args) {
41
47
  console.log('initializing <%= modulePart %> ...')
42
48
 
@@ -62,35 +68,73 @@ export async function init(self, args) {
62
68
  btn_logs.addEventListener('click', evt=>{ btn_logs_click(self, evt) })
63
69
  btn_about.addEventListener('click', evt=>{ btn_about_click(self, evt) })
64
70
 
71
+ // set actions
72
+ CurrentState.Actions = {
73
+ newdata: btn_new,
74
+ edit: btn_edit,<% actionList.forEach(action => { %>
75
+ <%= action.name %>: <%= action.buttonName %>,<% }) %>
76
+ }
77
+ <% if (!allowFormNew) { %>
78
+ btn_new.suspend()<% } %><% if (!allowFormEdit) { %>
79
+ btn_edit.suspend()
80
+ <% } %>
81
+ // export async function <%= modulePart %>_init(self, CurrentState)
82
+ const fn_init_name = '<%= modulePart %>_init'
83
+ const fn_init = Extender[fn_init_name]
84
+ if (typeof fn_init === 'function') {
85
+ await fn_init(self, CurrentState)
86
+ }
87
+
88
+
89
+ <%if (actionList.length>0) {%>// buat di Extender: export function setupActionButtonEvent(self, frm, CurrentState, buttons) { }
90
+ const fn_setupactionbuttonevent_name = 'setupActionButtonEvent'
91
+ const fn_setupactionbuttonevent = Extender[fn_setupactionbuttonevent_name]
92
+ if (typeof fn_setupactionbuttonevent === 'function') {
93
+ fn_setupactionbuttonevent(self, frm, CurrentState, {<% actionList.forEach(action => { %>
94
+ <%= action.buttonName %>,<% }) %>
95
+ })
96
+ } else {
97
+ console.warn('Extender.setupActionButtonEvent is not implemented')
98
+ console.log('buat function di extender: export function setupActionButtonEvent(self, buttons)')
99
+ }<% } %>
65
100
 
66
101
  <% fieldHandles.forEach(field => { %>
67
102
  // <%= field.component %>: <%= field.inputname %><% field.handles.forEach(hnd => { %>
68
103
  <%= field.inputname %>.addEventListener('<%= hnd.eventname %>', <% if (hnd.eventname=='selecting') { %>async <% } %>(evt)=>{
104
+
105
+ evt.detail.CurrentState = CurrentState
106
+
69
107
  const fn_<%= hnd.eventname %>_name = '<%= field.inputname %>_<%= hnd.eventname %>'
70
108
  const fn_<%= hnd.eventname %> = Extender[fn_<%= hnd.eventname %>_name]
71
109
  if (typeof fn_<%= hnd.eventname %> === 'function') {
72
110
  // create function di Extender<% if (field.component=='Combobox' && hnd.eventname=='selecting') { %> (jika perlu)<% } %>:
73
- // export async function <%= field.inputname %>_<%= hnd.eventname %>(self, <%= field.inputname %>, frm, evt)
111
+ // export async function <%= field.inputname %>_<%= hnd.eventname %>(self, <%= field.inputname %>, frm, evt) {}
74
112
  fn_<%= hnd.eventname %>(self, <%= field.inputname %>, frm, evt)
75
113
  } else {<% if (field.component=='Combobox' && hnd.eventname=='selecting') { %>
76
114
  // default selecting
77
115
  const cbo = evt.detail.sender
78
116
  const dialog = evt.detail.dialog
79
117
  const searchtext = evt.detail.searchtext!=null ? evt.detail.searchtext : ''
80
- const url = `${Context.appsUrls.<%= hnd.appId %>.url}/<%- hnd.path %>`
118
+ const url = <% if (hnd.appId=='/') { %>'<%- hnd.path %>'<% } else { %>`${Context.appsUrls.<%= hnd.appId %>.url}/<%- hnd.path %>`<% } %>
119
+ const sort = {}
81
120
  const criteria = {
82
121
  searchtext: searchtext,
83
122
  }
84
123
 
124
+ evt.detail.url = url
125
+
126
+ // buat function di extender:
127
+ // export function <%= field.inputname %>_<%= hnd.eventname %>_criteria(self, <%= field.inputname %>, frm, criteria, sort, evt) {}
85
128
  const fn_<%= hnd.eventname %>_criteria_name = '<%= field.inputname %>_<%= hnd.eventname %>_criteria'
86
129
  const fn_<%= hnd.eventname %>_criteria = Extender[fn_<%= hnd.eventname %>_criteria_name]
87
130
  if (typeof fn_<%= hnd.eventname %>_criteria === 'function') {
88
- fn_<%= hnd.eventname %>_criteria(self, <%= field.inputname %>, criteria)
131
+ fn_<%= hnd.eventname %>_criteria(self, <%= field.inputname %>, frm, criteria, sort, evt)
89
132
  }
90
133
 
91
134
  cbo.wait()
92
135
  try {
93
- const result = await Module.apiCall(url, {
136
+ const result = await Module.apiCall(evt.detail.url, {
137
+ sort,
94
138
  criteria,
95
139
  offset: evt.detail.offset,
96
140
  limit: evt.detail.limit,
@@ -131,6 +175,7 @@ export async function openSelectedData(self, params) {
131
175
 
132
176
  CurrentState.currentOpenedId = id
133
177
 
178
+ // export async function <%= modulePart %>_isEditDisabled(self, data)
134
179
  const fn_iseditdisabled_name = '<%= modulePart %>_isEditDisabled'
135
180
  const fn_iseditdisabled = Extender[fn_iseditdisabled_name]
136
181
  if (typeof fn_iseditdisabled === 'function') {
@@ -141,16 +186,21 @@ export async function openSelectedData(self, params) {
141
186
  // disable primary key
142
187
  setPrimaryKeyState(self, {disabled:true})
143
188
 
189
+ // isi form dengan data
144
190
  frm.setData(data)
145
- frm.acceptChanges()
146
- frm.lock()
147
191
 
192
+ // jika ada kebutuhan untuk oleh lagi form dan data, bisa lakukan di extender
193
+ // export async function <%= modulePart %>_formOpened(self, frm, CurrentState)
148
194
  const fn_formopened_name = '<%= modulePart %>_formOpened'
149
195
  const fn_formopened = Extender[fn_formopened_name]
150
196
  if (typeof fn_formopened === 'function') {
151
- fn_formopened(self, frm, CurrentState)
197
+ await fn_formopened(self, frm, CurrentState)
152
198
  }
153
199
 
200
+ // finally, accept changes dan lock form
201
+ frm.acceptChanges()
202
+ frm.lock()
203
+
154
204
  } catch (err) {
155
205
  CurrentState.currentOpenedId = null
156
206
  throw err
@@ -170,6 +220,10 @@ export function getForm(self) {
170
220
  return frm
171
221
  }
172
222
 
223
+ export function getCurrentState(self) {
224
+ return CurrentState
225
+ }
226
+
173
227
  export function clearForm(self, text) {
174
228
  frm.clear(text)
175
229
  }
@@ -289,8 +343,6 @@ async function backToList(self, evt) {
289
343
  }
290
344
 
291
345
  async function frm_locked(self, evt) {
292
- console.log('frm_locked')
293
-
294
346
  CurrentSection.Title = TitleWhenView
295
347
 
296
348
  btn_edit.setText(EditModeText)
@@ -303,8 +355,11 @@ async function frm_locked(self, evt) {
303
355
  btn_prev.disabled = false
304
356
  btn_next.disabled = false
305
357
 
358
+ <%if (actionList.length>0) {%>// Enable action: action hanya bisa dilakukan saat posisi edit off<% actionList.forEach(action => { %>
359
+ <%= action.buttonName %>.disabled = false<% }) %><% } %>
306
360
 
307
361
  // Extender untuk event locked
362
+ // export function <%= modulePart %>_formLocked(self, frm, CurrentState) {}
308
363
  const fn_name = '<%= modulePart %>_formLocked'
309
364
  const fn = Extender[fn_name]
310
365
  if (typeof fn === 'function') {
@@ -325,8 +380,6 @@ async function frm_locked(self, evt) {
325
380
  }
326
381
 
327
382
  async function frm_unlocked(self, evt) {
328
- console.log('frm_unlocked')
329
-
330
383
  if (frm.isNew()) {
331
384
  CurrentSection.Title = TitleWhenNew
332
385
  } else {
@@ -343,12 +396,15 @@ async function frm_unlocked(self, evt) {
343
396
  btn_prev.disabled = true
344
397
  btn_next.disabled = true
345
398
 
399
+ <%if (actionList.length>0) {%>// Disable action: action hanya bisa dilakukan saat posisi edit off<% actionList.forEach(action => { %>
400
+ <%= action.buttonName %>.disabled = true<% }) %><% } %>
346
401
 
347
402
  // Extender untuk event Unlocked
403
+ // export function <%= modulePart %>_formUnlocked(self, frm, CurrentState) {}
348
404
  const fn_name = '<%= modulePart %>_formUnlocked'
349
405
  const fn = Extender[fn_name]
350
406
  if (typeof fn === 'function') {
351
- fn(self, frm)
407
+ fn(self, frm, CurrentState)
352
408
  }
353
409
 
354
410
  <% entitiesDetil.forEach(entity => { %>
@@ -447,9 +503,9 @@ async function btn_new_click(self, evt) {
447
503
  try {
448
504
 
449
505
  // inisiasi data baru
450
- let datainit = {<% defaultInits.forEach(setdefault => { %>
451
- <%- setdefault %>,
452
- <% }) %>}
506
+ const datainit = {<% defaultInits.forEach(setdefault => { %>
507
+ <%- setdefault %>,<% }) %>
508
+ }
453
509
 
454
510
 
455
511
  // jika perlu modifikasi data initial,
@@ -457,6 +513,7 @@ async function btn_new_click(self, evt) {
457
513
  const fn_newdata_name = '<%= modulePart %>_newData'
458
514
  const fn_newdata = Extender[fn_newdata_name]
459
515
  if (typeof fn_newdata === 'function') {
516
+ // export async function <%= modulePart %>_newData(self, datainit, frm) {}
460
517
  await fn_newdata(self, datainit, frm)
461
518
  }
462
519
 
@@ -466,6 +523,10 @@ async function btn_new_click(self, evt) {
466
523
  // buka lock, agar user bisa edit
467
524
  frm.lock(false)
468
525
 
526
+ // jika edit di suspend, enable dulu
527
+ btn_edit.suspend(false)
528
+
529
+
469
530
  // matikan tombol edit dan del saat kondisi form adalah data baru
470
531
  btn_edit.disabled = true
471
532
  btn_del.disabled = true
@@ -520,12 +581,6 @@ async function btn_save_click(self, evt) {
520
581
  dataToSave = frm.getData()
521
582
  }
522
583
 
523
- // Extender Saving
524
- const fn_datasaving_name = '<%= modulePart %>_dataSaving'
525
- const fn_datasaving = Extender[fn_datasaving_name]
526
- if (typeof fn_datasaving === 'function') {
527
- await fn_datasaving(self, dataToSave, frm)
528
- }
529
584
 
530
585
 
531
586
  // bila ada file, upload filenya
@@ -537,7 +592,24 @@ async function btn_save_click(self, evt) {
537
592
  const file = files[name]
538
593
  formData.append(name, file)
539
594
  }
540
- }
595
+ }
596
+
597
+
598
+ // Extender Saving
599
+ // export async function <%= modulePart %>_dataSaving(self, dataToSave, frm, args) {}
600
+ const args = { cancelSave: false }
601
+ const fn_datasaving_name = '<%= modulePart %>_dataSaving'
602
+ const fn_datasaving = Extender[fn_datasaving_name]
603
+ if (typeof fn_datasaving === 'function') {
604
+ await fn_datasaving(self, dataToSave, frm, args)
605
+ }
606
+
607
+ // batalkan save, jika ada request cancel
608
+ if (args.cancelSave) {
609
+ console.log('save is canceled')
610
+ return
611
+ }
612
+
541
613
 
542
614
  let mask = $fgta5.Modal.createMask()
543
615
  try {
@@ -580,7 +652,8 @@ async function btn_save_click(self, evt) {
580
652
  const fn_datasaved_name = '<%= modulePart %>_dataSaved'
581
653
  const fn_datasaved = Extender[fn_datasaved_name]
582
654
  if (typeof fn_datasaved === 'function') {
583
- await fn_datasaved(self, data, frm)
655
+ // export async function <%= modulePart %>_dataSaved(self, data, frm) {}
656
+ await fn_datasaved(self, result, frm)
584
657
  }
585
658
 
586
659
 
@@ -703,6 +776,12 @@ async function btn_recordstatus_click(self, evt) {
703
776
  sectionReturn: CurrentSection
704
777
  }
705
778
 
779
+ if (frm.isNew()) {
780
+ console.warn('tidak bisa buka rescord status jika data baru')
781
+ $fgta5.MessageBox.warning('Record Status bisa dibuka setelah data disimpan')
782
+ return;
783
+ }
784
+
706
785
  pageHelper.openSection(self, 'fRecord-section', params, async ()=>{
707
786
 
708
787
  let mask = $fgta5.Modal.createMask()
@@ -712,10 +791,11 @@ async function btn_recordstatus_click(self, evt) {
712
791
  const id = pk.value
713
792
  const data = await openData(self, id)
714
793
 
715
- obj_createby.innerHTML = data._createby
716
- obj_createdate.innerHTML = data._createdate
717
- obj_modifyby.innerHTML = data._modifyby
718
- obj_modifydate.innerHTML = data._modifydate
794
+ rec_id.innerHTML = id
795
+ rec_createby.innerHTML = data._createby
796
+ rec_createdate.innerHTML = data._createdate
797
+ rec_modifyby.innerHTML = data._modifyby
798
+ rec_modifydate.innerHTML = data._modifydate
719
799
 
720
800
  const fn_addrecordinfo_name = '<%= modulePart %>_addRecordInfo'
721
801
  const fn_addrecordinfo = Extender[fn_addrecordinfo_name]
@@ -740,6 +820,12 @@ async function btn_logs_click(self, evt) {
740
820
  sectionReturn: CurrentSection
741
821
  }
742
822
 
823
+ if (frm.isNew()) {
824
+ console.warn('tidak bisa buka logs jika data baru')
825
+ $fgta5.MessageBox.warning('Logs bisa dibuka setelah data disimpan')
826
+ return;
827
+ }
828
+
743
829
  pageHelper.openSection(self, 'fLogs-section', params, async ()=>{
744
830
  // get log data
745
831
  const pk = frm.getPrimaryInput()
@@ -749,7 +835,8 @@ async function btn_logs_click(self, evt) {
749
835
  let mask = $fgta5.Modal.createMask()
750
836
  try {
751
837
 
752
- const url = `${Context.appsUrls.core.url}/logs/list`
838
+ const logApp = Context.appsUrls.core ?? Context.appsUrls[Context.appName]
839
+ const url = `${logApp.url}/logs/list`
753
840
  const criteria = {
754
841
  module: Context.moduleName,
755
842
  table: '<%= tablename %>',
@@ -1,3 +1,6 @@
1
+ <div id="<%= modulePart %>-header">
2
+ </div>
3
+
1
4
  <div class="search-container">
2
5
  <div id="<%= modulePart %>-pnl_search" class="search-parameters">
3
6
  <input id="<%= modulePart %>-txt_searchtext" fgta5-component="Textbox" placeholder="search" autocomplete="off" spellcheck="false" binding="searchtext" data-searchinput>
@@ -13,7 +16,8 @@
13
16
  </thead>
14
17
  </table>
15
18
 
16
-
19
+ <div id="<%= modulePart %>-foot">
20
+ </div>
17
21
 
18
22
  <div class="footer-buttons-container">
19
23
  <div></div>
@@ -1,6 +1,7 @@
1
1
  import Context from './<%= moduleName %>-context.mjs'
2
- import * as Extender from './<%= moduleName %>-ext.mjs'
2
+ import * as Ext from './<%= moduleName %>-ext.mjs'
3
3
 
4
+ const Extender = Ext.extenderHeader ?? Ext
4
5
 
5
6
  const Crsl = Context.Crsl
6
7
  const CurrentSectionId = Context.Sections.<%= modulePart %>
@@ -41,7 +42,7 @@ export async function init(self, args) {
41
42
 
42
43
  try {
43
44
  // extract custom search panel from template
44
- const tplSearchPanel = document.querySelector('template[name="custom-search-panel"]')
45
+ const tplSearchPanel = document.getElementById('tpl-custom-search-panel')
45
46
  if (tplSearchPanel!=null) {
46
47
  const clone = tplSearchPanel.content.cloneNode(true); // salin isi template
47
48
  pnl_search.prepend(clone)
@@ -94,6 +95,9 @@ export async function loadData(self) {
94
95
  tbl_loadData(self)
95
96
  }
96
97
 
98
+ export function getCurrentState(self) {
99
+ return CurrentState
100
+ }
97
101
 
98
102
  export function getGrid(self) {
99
103
  return tbl
@@ -164,9 +168,12 @@ export function keyboardAction(self, actionName, evt) {
164
168
  tbl.nextRecord()
165
169
  } else if (actionName=='enter') {
166
170
  const <%= moduleEdit %> = self.Modules.<%= moduleEdit %>
167
- <%= moduleEdit %>.Section.show({}, ()=>{
168
- openRow(self, tbl.CurrentRow)
169
- })
171
+ if (tbl.CurrentRow!=null) {
172
+ <%= moduleEdit %>.Section.show({}, ()=>{
173
+ openRow(self, tbl.CurrentRow)
174
+ })
175
+ }
176
+
170
177
  } else if (actionName=='typing') {
171
178
  evt.preventDefault();
172
179
  evt.stopPropagation();
@@ -187,9 +194,14 @@ export function keyboardAction(self, actionName, evt) {
187
194
 
188
195
  function setCurrentRow(self, tr) {
189
196
  CurrentState.SelectedRow = tr
197
+ tbl.CurrentRow = tr
190
198
  }
191
199
 
192
200
  async function openRow(self, tr) {
201
+ if (tr==null) {
202
+ return
203
+ }
204
+
193
205
  const keyvalue = tr.getAttribute('keyvalue')
194
206
  const key = tr.getAttribute('key')
195
207
 
@@ -201,28 +213,40 @@ async function openRow(self, tr) {
201
213
  CurrentState.SelectedRow.keyValue = keyvalue
202
214
  CurrentState.SelectedRow.key = key
203
215
  await <%= moduleEdit %>.openSelectedData(self, {key:key, keyvalue:keyvalue})
204
- } catch (err) {
205
- console.error(err)
206
- await $fgta5.MessageBox.error(err.message)
207
216
 
217
+ // matikan atau nyalakan button prev/next sesuai kondisi
218
+ setPagingButton(self, <%= moduleEdit %>)
219
+
220
+ } catch (err) {
208
221
  setCurrentRow(self, null)
209
222
  CurrentSection.show() // kembalikan ke list kalau error saat buka data
210
- }
211
-
212
223
 
213
- // matikan atau nyalakan button prev/next sesuai kondisi
214
- setPagingButton(self, <%= moduleEdit %>)
224
+ console.error(err)
225
+ await $fgta5.MessageBox.error(err.message)
226
+ }
227
+
215
228
  }
216
229
 
217
- async function listRows(self, criteria, offset,limit, sort) {
230
+ async function listRows(self, criteria, offset, limit, sort) {
231
+
218
232
  const url = `/${Context.moduleName}/header-list`
233
+ const evt = { url, limit }
234
+
235
+ // export function headerList_dataLoad(self, criteria, sort, evt) {}
236
+ const fn_dataLoad_name = 'headerList_dataLoad'
237
+ const fn_dataLoad = Extender[fn_dataLoad_name]
238
+ if (typeof fn_dataLoad === 'function') {
239
+ fn_dataLoad(self, criteria, sort, evt)
240
+ }
241
+
242
+
219
243
  try {
220
244
  const columns = []
221
- const result = await Module.apiCall(url, {
245
+ const result = await Module.apiCall(evt.url, {
222
246
  columns,
223
247
  criteria,
224
248
  offset,
225
- limit,
249
+ limit: evt.limit,
226
250
  sort
227
251
  })
228
252
  return result
@@ -292,6 +316,14 @@ async function tbl_loadData(self, params={}) {
292
316
  }
293
317
  tbl.addRows(result.data)
294
318
  tbl.setNext(result.nextoffset, result.limit)
319
+
320
+ // export function headerList_tableDataLoaded(self, tbl, result) {}
321
+ const fn_name = 'headerList_tableDataLoaded'
322
+ const fn = Extender[fn_name]
323
+ if (typeof fn === 'function') {
324
+ fn(self, tbl, result)
325
+ }
326
+
295
327
  } catch (err) {
296
328
  console.error(err)
297
329
  $fgta5.MessageBox.error(err.message)
@@ -1,5 +1,7 @@
1
1
  import dotenv from 'dotenv'
2
2
  import { Worker } from 'worker_threads'
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
3
5
 
4
6
  dotenv.config()
5
7
 
@@ -9,6 +11,9 @@ console.log('Testing Generator')
9
11
 
10
12
  const args = process.argv.slice(2)
11
13
  const generator_id = args[0]
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+
12
17
 
13
18
  if (generator_id==null) {
14
19
  console.log("\n\n\x1b[1m\x1b[31mERROR\x1b[0m")
@@ -19,6 +24,14 @@ if (generator_id==null) {
19
24
 
20
25
  const workerTimeoutMs = 1*60*1000
21
26
 
27
+ const ModuleDbContract = {
28
+ apps: {
29
+ table: 'core."apps"'
30
+ },
31
+ generator: {
32
+ table: 'core.generator'
33
+ }
34
+ }
22
35
 
23
36
  await main(generator_id)
24
37
 
@@ -26,14 +39,17 @@ await main(generator_id)
26
39
  async function main(generator_id) {
27
40
  console.log(`Start to generate program id:'${generator_id}'`)
28
41
 
42
+
43
+
29
44
  try {
30
- const workerPath = './src/generator/worker.js'
45
+ const workerPath = path.join(__dirname, 'worker.js')
31
46
  const worker = new Worker(workerPath, {
32
47
  workerData: {
33
48
  generator_id,
34
49
  user_id: 1,
35
50
  user_name: 'coredeveloper',
36
- ipaddress: 'local-cli'
51
+ ipaddress: 'local-cli',
52
+ ModuleDbContract: ModuleDbContract,
37
53
  }
38
54
  }, workerTimeoutMs)
39
55