@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.
- package/lib/fgta5js-dist/fgta5js-v1.8.5.min.js +11 -0
- package/lib/fgta5js-dist/fgta5js-v1.8.5.min.js.map +1 -0
- package/{libs → lib}/webmodule/module-edit.css +73 -18
- package/{libs → lib}/webmodule/module-list.css +13 -0
- package/lib/webmodule/module-print.css +28 -0
- package/{libs → lib}/webmodule/module.css +13 -6
- package/{libs → lib}/webmodule/module.js +14 -4
- package/lib/webmodule/pagehelper.mjs +129 -0
- package/modules/generator/appgen-io.mjs +153 -76
- package/modules/generator/appgen-ui.mjs +234 -167
- package/modules/generator/generator-designtemplate-def.html +38 -0
- package/modules/generator/generator-designtemplate.html +11 -1492
- package/modules/generator/generator.css +103 -65
- package/modules/generator/generator.mjs +1 -1
- package/modules/generator/generator.svg +98 -0
- package/modules/generator/generatorEdit.mjs +43 -35
- package/modules/generator/generatorList.mjs +27 -0
- package/modules/generator/tpl-designerinfo.html +100 -0
- package/modules/generator/tpl-field-checkbox.html +200 -0
- package/modules/generator/tpl-field-combobox.html +228 -0
- package/modules/generator/tpl-field-datepicker.html +192 -0
- package/modules/generator/tpl-field-filebox.html +189 -0
- package/modules/generator/tpl-field-numberbox.html +218 -0
- package/modules/generator/tpl-field-textbox.html +255 -0
- package/modules/generator/tpl-field-timepicker.html +192 -0
- package/modules/generator/tpl-searchdesign.html +32 -0
- package/modules/generator/tpl-uniquedesign.html +25 -0
- package/modules/login/login.css +10 -2
- package/package.json +5 -3
- package/percobaan/coba-sequencer.js +16 -0
- package/src/api.js +12 -9
- package/src/apis/generator.api.js +35 -23
- package/src/apis/login.api.js +1 -0
- package/src/context.js +12 -2
- package/src/db.js +58 -32
- package/src/generator/createApiModule.js +4 -1
- package/src/generator/createIcon.js +24 -2
- package/src/generator/createLayoutCss.js +107 -0
- package/src/generator/createModuleDetilEditHtml.js +12 -1
- package/src/generator/createModuleDetilEditMjs.js +32 -28
- package/src/generator/createModuleDetilListHtml.js +14 -7
- package/src/generator/createModuleDetilListMjs.js +13 -1
- package/src/generator/createModuleHeaderEditHtml.js +13 -1
- package/src/generator/createModuleHeaderEditMjs.js +23 -2
- package/src/generator/createProgramData.js +3 -2
- package/src/generator/createTable.js +45 -38
- package/src/generator/helper.js +45 -27
- package/src/generator/templates/__rollup-module.ejs +1 -1
- package/src/generator/templates/api-module.js.ejs +171 -32
- package/src/generator/templates/layout.css.ejs +24 -0
- package/src/generator/templates/module-ext.html.ejs +1 -1
- package/src/generator/templates/module-ext.mjs.ejs +19 -1
- package/src/generator/templates/module.ejs.ejs +8 -0
- package/src/generator/templates/module.mjs.ejs +42 -5
- package/src/generator/templates/moduleDetilEdit.html.ejs +11 -0
- package/src/generator/templates/moduleDetilEdit.mjs.ejs +135 -30
- package/src/generator/templates/moduleDetilList.html.ejs +2 -1
- package/src/generator/templates/moduleDetilList.mjs.ejs +86 -11
- package/src/generator/templates/moduleHeaderEdit.html.ejs +8 -1
- package/src/generator/templates/moduleHeaderEdit.mjs.ejs +123 -36
- package/src/generator/templates/moduleHeaderList.html.ejs +5 -1
- package/src/generator/templates/moduleHeaderList.mjs.ejs +47 -15
- package/src/generator/trygenerate.js +18 -2
- package/src/generator/worker.js +83 -72
- package/src/helper.js +12 -13
- package/src/logger.js +12 -12
- package/src/notifier.js +29 -0
- package/src/routers/generatorApi.js +9 -3
- package/src/routers/generatorPage.js +3 -1
- package/src/routers/moduleApi.js +1 -1
- package/src/routers/modulePage.js +32 -7
- package/src/sequencerdoc.js +22 -46
- package/src/sequencerline.js +16 -4
- package/src/session.js +69 -33
- package/src/startup.js +47 -10
- package/src/webapps.js +62 -18
- package/templates/_lib_debug.ejs +8 -8
- package/templates/_lib_production.ejs +2 -2
- package/templates/application.page.ejs +39 -6
- package/templates/generator.page.ejs +4 -3
- package/templates/index.page.ejs +2 -2
- package/templates/login.page.ejs +3 -3
- package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js +0 -11
- package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js.map +0 -1
- package/libs/webmodule/pagehelper.mjs +0 -45
- package/modules/generator/generator.png +0 -0
- /package/{libs/fgta5js-dist/fgta5js-v1.8.3.min.css → lib/fgta5js-dist/fgta5js-v1.8.5.min.css} +0 -0
- /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin-ext.woff2 +0 -0
- /package/{libs → lib}/fgta5js-dist/fonts/karla-italic-latin.woff2 +0 -0
- /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin-ext.woff2 +0 -0
- /package/{libs → lib}/fgta5js-dist/fonts/karla-normal-latin.woff2 +0 -0
- /package/{libs → lib}/fgta5js-dist/fonts/karla.css +0 -0
- /package/{libs → lib}/webmodule/module-footer.css +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import Context from './<%= moduleName %>-context.mjs'
|
|
2
|
-
import * as
|
|
3
|
-
import * as pageHelper from '/public/
|
|
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
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
168
|
-
|
|
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
|
-
|
|
214
|
-
|
|
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 = '
|
|
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
|
|