@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.
- 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 +42 -38
- package/src/generator/helper.js +45 -27
- package/src/generator/templates/__rollup-module copy.ejs +90 -0
- package/src/generator/templates/__rollup-module.ejs +102 -31
- 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 +42 -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 +43 -8
- 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,3 +1,8 @@
|
|
|
1
|
+
<div id="<%= modulePart %>-head">
|
|
2
|
+
<div id="<%= modulePart %>-head-title" class="section-detil-title"></div>
|
|
3
|
+
<div id="<%= modulePart %>-head-descr" class="section-detil-descr"></div>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
1
6
|
<form id="<%= modulePart %>-frm" class="module-form" locked="true" autoid="<%= autoid %>" primarykey="<%= primaryKeyElementId %>"><% fields.forEach(field => { %>
|
|
2
7
|
|
|
3
8
|
<!-- <%= field.component %>: <%= field.fieldname %>-->
|
|
@@ -9,8 +14,14 @@
|
|
|
9
14
|
>
|
|
10
15
|
</div>
|
|
11
16
|
<% }) %>
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
<div id="<%= modulePart %>-footer"></div>
|
|
20
|
+
|
|
12
21
|
</form>
|
|
13
22
|
|
|
23
|
+
|
|
24
|
+
|
|
14
25
|
<div class="panel-recordbar" data-view="nodetil">
|
|
15
26
|
<div><a id="<%= moduleSection %>-btn_recordstatus" href="javascript:void(0)" tabindex="-1">Record Status</a></div>
|
|
16
27
|
<div><a id="<%= moduleSection %>-btn_logs" href="javascript:void(0)" tabindex="-1">Logs</a></div>
|
|
@@ -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.<%=extenderDetil%> ?? Ext
|
|
4
6
|
|
|
5
7
|
|
|
6
|
-
const CurrentState = {}
|
|
7
8
|
const Crsl = Context.Crsl
|
|
8
9
|
const CurrentSectionId = Context.Sections.<%= modulePart %>
|
|
9
10
|
const CurrentSection = Crsl.Items[CurrentSectionId]
|
|
10
11
|
const Source = Context.Source
|
|
12
|
+
const CurrentState = {}
|
|
11
13
|
|
|
12
14
|
const TitleWhenNew = 'New <%= title %>'
|
|
13
15
|
const TitleWhenView = 'View <%= title %>'
|
|
@@ -30,10 +32,11 @@ const btn_logs = document.getElementById('<%= moduleSection %>-btn_logs')
|
|
|
30
32
|
|
|
31
33
|
const frm = new $fgta5.Form('<%= modulePart %>-frm');<% fields.forEach(field => { %>
|
|
32
34
|
const <%= field.inputname %> = frm.Inputs['<%= field.elementId %>']<% }) %>
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
35
|
+
const rec_createby = document.getElementById('fRecord-section-createby')
|
|
36
|
+
const rec_createdate = document.getElementById('fRecord-section-createdate')
|
|
37
|
+
const rec_modifyby = document.getElementById('fRecord-section-modifyby')
|
|
38
|
+
const rec_modifydate = document.getElementById('fRecord-section-modifydate')
|
|
39
|
+
const rec_id = document.getElementById('fRecord-section-id')
|
|
37
40
|
|
|
38
41
|
export const Section = CurrentSection
|
|
39
42
|
|
|
@@ -63,35 +66,53 @@ export async function init(self, args) {
|
|
|
63
66
|
CurrentState.headerFormLocked = true
|
|
64
67
|
CurrentState.editDisabled = false
|
|
65
68
|
|
|
69
|
+
CurrentState.Actions = {
|
|
70
|
+
newdata: btn_new,
|
|
71
|
+
edit: btn_edit,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
CurrentState.getHeaderForm = () => {
|
|
75
|
+
const <%= moduleName %>HeaderEdit = self.Modules.<%= moduleName %>HeaderEdit
|
|
76
|
+
const frmHeader = <%= moduleName %>HeaderEdit.getHeaderForm()
|
|
77
|
+
return frmHeader
|
|
78
|
+
}
|
|
79
|
+
|
|
66
80
|
|
|
67
81
|
<% fieldHandles.forEach(field => { %>
|
|
68
82
|
// <%= field.component %>: <%= field.inputname %><% field.handles.forEach(hnd => { %>
|
|
69
83
|
<%= field.inputname %>.addEventListener('<%= hnd.eventname %>', <% if (hnd.eventname=='selecting') { %>async <% } %>(evt)=>{
|
|
70
84
|
const fn_<%= hnd.eventname %>_name = '<%= field.inputname %>_<%= hnd.eventname %>'
|
|
71
85
|
const fn_<%= hnd.eventname %> = Extender[fn_<%= hnd.eventname %>_name]
|
|
72
|
-
if (typeof fn_<%=
|
|
86
|
+
if (typeof fn_<%= hnd.eventname %> === 'function') {
|
|
73
87
|
// create function di Extender<% if (field.component=='Combobox' && hnd.eventname=='selecting') { %> (jika perlu)<% } %>:
|
|
74
|
-
// export async function <%= field.inputname %>_<%= hnd.eventname %>(self, <%= field.inputname %>, frm, evt)
|
|
75
|
-
fn_<%=
|
|
88
|
+
// export async function <%= field.inputname %>_<%= hnd.eventname %>(self, <%= field.inputname %>, frm, evt) {}
|
|
89
|
+
fn_<%= hnd.eventname %>(self, <%= field.inputname %>, frm, evt)
|
|
76
90
|
} else {<% if (field.component=='Combobox' && hnd.eventname=='selecting') { %>
|
|
77
91
|
// default selecting
|
|
78
92
|
const cbo = evt.detail.sender
|
|
79
93
|
const dialog = evt.detail.dialog
|
|
80
94
|
const searchtext = evt.detail.searchtext!=null ? evt.detail.searchtext : ''
|
|
81
|
-
const url =
|
|
95
|
+
const url = <% if (hnd.appId=='/') { %>'<%- hnd.path %>'<% } else { %>`${Context.appsUrls.<%= hnd.appId %>.url}/<%- hnd.path %>`<% } %>
|
|
96
|
+
const sort = {}
|
|
82
97
|
const criteria = {
|
|
83
98
|
searchtext: searchtext,
|
|
84
99
|
}
|
|
85
100
|
|
|
101
|
+
evt.detail.url = url
|
|
102
|
+
evt.detail.CurrentState = CurrentState
|
|
103
|
+
|
|
104
|
+
// buat function di extender:
|
|
105
|
+
// export function <%= field.inputname %>_<%= hnd.eventname %>_criteria(self, <%= field.inputname %>, frm, criteria, sort, evt) {}
|
|
86
106
|
const fn_<%= hnd.eventname %>_criteria_name = '<%= field.inputname %>_<%= hnd.eventname %>_criteria'
|
|
87
|
-
const fn_<%=
|
|
107
|
+
const fn_<%= hnd.eventname %>_criteria = Extender[fn_<%= hnd.eventname %>_criteria_name]
|
|
88
108
|
if (typeof fn_<%= hnd.eventname %>_criteria === 'function') {
|
|
89
|
-
fn_<%=
|
|
109
|
+
fn_<%= hnd.eventname %>_criteria(self, <%= field.inputname %>, frm, criteria, sort, evt)
|
|
90
110
|
}
|
|
91
111
|
|
|
92
112
|
cbo.wait()
|
|
93
113
|
try {
|
|
94
|
-
const result = await Module.apiCall(url, {
|
|
114
|
+
const result = await Module.apiCall(evt.detail.url, {
|
|
115
|
+
sort,
|
|
95
116
|
criteria,
|
|
96
117
|
offset: evt.detail.offset,
|
|
97
118
|
limit: evt.detail.limit,
|
|
@@ -129,9 +150,11 @@ export async function openSelectedData(self, params) {
|
|
|
129
150
|
<% if (detilHasUpload) { %>
|
|
130
151
|
dataOpened(self, data)<% } %>
|
|
131
152
|
|
|
153
|
+
const suspended = self.Modules.<%= headerModulePartEdit %>.getCurrentState().Actions.edit.isSuspended()
|
|
154
|
+
|
|
155
|
+
CurrentState.editDisabled = suspended
|
|
132
156
|
CurrentState.currentOpenedId = id
|
|
133
157
|
|
|
134
|
-
|
|
135
158
|
// jika posisi header dalam keadaan unlock (bisa edit, perlu cek kondisi data, untuk menentukan bisa diedit atau tidak)
|
|
136
159
|
if (!CurrentState.headerFormLocked) {
|
|
137
160
|
const fn_iseditdisabled_name = '<%= modulePart %>_isEditDisabled'
|
|
@@ -145,15 +168,22 @@ export async function openSelectedData(self, params) {
|
|
|
145
168
|
// disable primary key
|
|
146
169
|
setPrimaryKeyState(self, {disabled:true})
|
|
147
170
|
|
|
171
|
+
// isi form dengan data
|
|
148
172
|
frm.setData(data)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
173
|
+
|
|
174
|
+
// jika ada kebutuhan untuk oleh lagi form dan data, bisa lakukan di extender
|
|
175
|
+
// export function <%= modulePart %>_formOpened(self, frm, CurrentState) {}
|
|
152
176
|
const fn_formopened_name = '<%= modulePart %>_formOpened'
|
|
153
177
|
const fn_formopened = Extender[fn_formopened_name]
|
|
154
178
|
if (typeof fn_formopened === 'function') {
|
|
155
179
|
fn_formopened(self, frm, CurrentState)
|
|
156
180
|
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
// finally, accept changes dan lock form
|
|
184
|
+
frm.acceptChanges()
|
|
185
|
+
frm.lock()
|
|
186
|
+
|
|
157
187
|
} catch (err) {
|
|
158
188
|
CurrentState.currentOpenedId = null
|
|
159
189
|
throw err
|
|
@@ -163,6 +193,10 @@ export async function openSelectedData(self, params) {
|
|
|
163
193
|
}
|
|
164
194
|
}
|
|
165
195
|
|
|
196
|
+
export function getCurrentState(self) {
|
|
197
|
+
return CurrentState
|
|
198
|
+
}
|
|
199
|
+
|
|
166
200
|
export function getForm(self) {
|
|
167
201
|
return frm
|
|
168
202
|
}
|
|
@@ -175,12 +209,28 @@ export function headerLocked(self) {
|
|
|
175
209
|
CurrentState.headerFormLocked = true
|
|
176
210
|
CurrentState.editDisabled = true
|
|
177
211
|
btn_new.disabled = true
|
|
212
|
+
|
|
213
|
+
// Extender untuk event Locked
|
|
214
|
+
// export function <%= modulePart %>_formLocked(self, frm, CurrentState) {}
|
|
215
|
+
const fn_name = '<%= modulePart %>_formLocked'
|
|
216
|
+
const fn = Extender[fn_name]
|
|
217
|
+
if (typeof fn === 'function') {
|
|
218
|
+
fn(self, frm, CurrentState)
|
|
219
|
+
}
|
|
178
220
|
}
|
|
179
221
|
|
|
180
222
|
export function headerUnlocked(self) {
|
|
181
223
|
CurrentState.headerFormLocked = false
|
|
182
224
|
CurrentState.editDisabled = false
|
|
183
225
|
btn_new.disabled = false
|
|
226
|
+
|
|
227
|
+
// Extender untuk event Unlocked
|
|
228
|
+
// export function <%= modulePart %>_formUnlocked(self, frm, CurrentState) {}
|
|
229
|
+
const fn_name = '<%= modulePart %>_formUnlocked'
|
|
230
|
+
const fn = Extender[fn_name]
|
|
231
|
+
if (typeof fn === 'function') {
|
|
232
|
+
fn(self, frm, CurrentState)
|
|
233
|
+
}
|
|
184
234
|
}
|
|
185
235
|
|
|
186
236
|
export function disableNextButton(self, disabled=true) {
|
|
@@ -316,6 +366,7 @@ async function frm_locked(self, evt) {
|
|
|
316
366
|
|
|
317
367
|
|
|
318
368
|
// Extender untuk event locked
|
|
369
|
+
// export function <%= modulePart %>_formLocked(self, frm, CurrentState) {}
|
|
319
370
|
const fn_name = '<%= modulePart %>_formLocked'
|
|
320
371
|
const fn = Extender[fn_name]
|
|
321
372
|
if (typeof fn === 'function') {
|
|
@@ -352,6 +403,7 @@ async function frm_unlocked(self, evt) {
|
|
|
352
403
|
btn_next.disabled = true
|
|
353
404
|
|
|
354
405
|
// Extender untuk event Unlocked
|
|
406
|
+
// export function <%= modulePart %>_formUnlocked(self, frm) {}
|
|
355
407
|
const fn_name = '<%= modulePart %>_formUnlocked'
|
|
356
408
|
const fn = Extender[fn_name]
|
|
357
409
|
if (typeof fn === 'function') {
|
|
@@ -458,19 +510,20 @@ async function btn_new_click(self, evt) {
|
|
|
458
510
|
const <%= headerPrimaryKey %> = header_pk.value
|
|
459
511
|
|
|
460
512
|
// inisiasi data baru
|
|
461
|
-
|
|
513
|
+
const datainit = {
|
|
462
514
|
<%= headerPrimaryKey %>,<% defaultInits.forEach(setdefault => { %>
|
|
463
|
-
<%- setdefault
|
|
464
|
-
|
|
515
|
+
<%- setdefault %>,<% }) %>
|
|
516
|
+
}
|
|
465
517
|
|
|
466
518
|
|
|
467
519
|
// jika perlu modifikasi data initial,
|
|
468
520
|
// atau dialog untuk opsi data baru,
|
|
469
521
|
// dapat dibuat di Extender.newData
|
|
522
|
+
// export async function <%= modulePart %>_newData(self, datainit, frm, CurrentState) {}
|
|
470
523
|
const fn_newdata_name = '<%= modulePart %>_newData'
|
|
471
524
|
const fn_newdata = Extender[fn_newdata_name]
|
|
472
525
|
if (typeof fn_newdata === 'function') {
|
|
473
|
-
await fn_newdata(self, datainit, frm)
|
|
526
|
+
await fn_newdata(self, datainit, frm, CurrentState)
|
|
474
527
|
}
|
|
475
528
|
|
|
476
529
|
// buat data baru
|
|
@@ -497,6 +550,7 @@ async function btn_save_click(self, evt) {
|
|
|
497
550
|
console.log('btn_save_click')
|
|
498
551
|
|
|
499
552
|
// Extender Autofill
|
|
553
|
+
// export async function <%= modulePart %>_autofill(self, frm) {}
|
|
500
554
|
const fn_autofill_name = '<%= modulePart %>_autofill'
|
|
501
555
|
const fn_autofill = Extender[fn_autofill_name]
|
|
502
556
|
if (typeof fn_autofill === 'function') {
|
|
@@ -547,12 +601,19 @@ async function btn_save_click(self, evt) {
|
|
|
547
601
|
|
|
548
602
|
|
|
549
603
|
// Extender Saving
|
|
604
|
+
// export async function <%= modulePart %>_dataSaving(self, dataToSave, frm, args) {}
|
|
605
|
+
const args = { cancelSave: false }
|
|
550
606
|
const fn_datasaving_name = '<%= modulePart %>_dataSaving'
|
|
551
607
|
const fn_datasaving = Extender[fn_datasaving_name]
|
|
552
608
|
if (typeof fn_datasaving === 'function') {
|
|
553
|
-
await fn_datasaving(self, dataToSave, frm)
|
|
609
|
+
await fn_datasaving(self, dataToSave, frm, args)
|
|
554
610
|
}
|
|
555
611
|
|
|
612
|
+
// batalkan save, jika ada request cancel
|
|
613
|
+
if (args.cancelSave) {
|
|
614
|
+
console.log('save is canceled')
|
|
615
|
+
return
|
|
616
|
+
}
|
|
556
617
|
|
|
557
618
|
|
|
558
619
|
let mask = $fgta5.Modal.createMask()
|
|
@@ -596,7 +657,8 @@ async function btn_save_click(self, evt) {
|
|
|
596
657
|
const fn_datasaved_name = '<%= modulePart %>_dataSaved'
|
|
597
658
|
const fn_datasaved = Extender[fn_datasaved_name]
|
|
598
659
|
if (typeof fn_datasaved === 'function') {
|
|
599
|
-
|
|
660
|
+
// export async function <%= modulePart %>_dataSaved(self, data, frm) {}
|
|
661
|
+
await fn_datasaved(self, result, frm)
|
|
600
662
|
}
|
|
601
663
|
|
|
602
664
|
|
|
@@ -650,11 +712,38 @@ async function btn_del_click(self, evt) {
|
|
|
650
712
|
console.log('delete data')
|
|
651
713
|
let mask = $fgta5.Modal.createMask()
|
|
652
714
|
try {
|
|
715
|
+
|
|
716
|
+
// Extender Deleting
|
|
717
|
+
// export async function <%= modulePart %>_dataDeleting(self, id, args) {}
|
|
718
|
+
const args = { cancelDelete: false }
|
|
719
|
+
const fn_datadeleting_name = '<%= modulePart %>_dataDeleting'
|
|
720
|
+
const fn_datadeleting = Extender[fn_datadeleting_name]
|
|
721
|
+
if (typeof fn_datadeleting === 'function') {
|
|
722
|
+
await fn_datadeleting(self, idValue, args)
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// batalkan save, jika ada request cancel
|
|
726
|
+
if (args.cancelDelete) {
|
|
727
|
+
console.log('delete is canceled')
|
|
728
|
+
return
|
|
729
|
+
}
|
|
730
|
+
|
|
653
731
|
const result = await deleteData(self, idValue)
|
|
654
732
|
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
// Extender Delete
|
|
736
|
+
// export async function <%= modulePart %>_dataDeleted(self, data) {}
|
|
737
|
+
const fn_datadeleted_name = '<%= modulePart %>_dataDeleted'
|
|
738
|
+
const fn_datadeleted = Extender[fn_datadeleted_name]
|
|
739
|
+
if (typeof fn_datadeleted === 'function') {
|
|
740
|
+
await fn_datadeleted(self, result)
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
|
|
655
744
|
// hapus current row yang dipilih di list
|
|
656
745
|
self.Modules.<%= moduleSection %>List.removeCurrentRow(self)
|
|
657
|
-
|
|
746
|
+
|
|
658
747
|
// kembali ke list
|
|
659
748
|
self.Modules.<%= moduleSection %>List.Section.show()
|
|
660
749
|
|
|
@@ -716,6 +805,12 @@ async function btn_recordstatus_click(self, evt) {
|
|
|
716
805
|
sectionReturn: CurrentSection
|
|
717
806
|
}
|
|
718
807
|
|
|
808
|
+
if (frm.isNew()) {
|
|
809
|
+
console.warn('tidak bisa buka rescord status jika data baru')
|
|
810
|
+
$fgta5.MessageBox.warning('Record Status bisa dibuka setelah data disimpan')
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
|
|
719
814
|
pageHelper.openSection(self, 'fRecord-section', params, async ()=>{
|
|
720
815
|
|
|
721
816
|
let mask = $fgta5.Modal.createMask()
|
|
@@ -725,15 +820,17 @@ async function btn_recordstatus_click(self, evt) {
|
|
|
725
820
|
const id = pk.value
|
|
726
821
|
const data = await openData(self, id)
|
|
727
822
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
823
|
+
rec_id.innerHTML = id
|
|
824
|
+
rec_createby.innerHTML = data._createby
|
|
825
|
+
rec_createdate.innerHTML = data._createdate
|
|
826
|
+
rec_modifyby.innerHTML = data._modifyby
|
|
827
|
+
rec_modifydate.innerHTML = data._modifydate
|
|
732
828
|
|
|
733
829
|
|
|
734
830
|
// jika mau menambah beberapa informasi mengenai record,
|
|
735
831
|
// misalnya commit by, postby, dll
|
|
736
832
|
// melalui extender <%= modulePart %>_addRecordInfo
|
|
833
|
+
// export async function <%= modulePart %>_addRecordInfo(self, data) {}
|
|
737
834
|
const fn_addrecordinfo_name = '<%= modulePart %>_addRecordInfo'
|
|
738
835
|
const fn_addrecordinfo = Extender[fn_addrecordinfo_name]
|
|
739
836
|
if (typeof fn_addrecordinfo === 'function') {
|
|
@@ -757,6 +854,12 @@ async function btn_logs_click(self, evt) {
|
|
|
757
854
|
sectionReturn: CurrentSection
|
|
758
855
|
}
|
|
759
856
|
|
|
857
|
+
if (frm.isNew()) {
|
|
858
|
+
console.warn('tidak bisa buka logs jika data baru')
|
|
859
|
+
$fgta5.MessageBox.warning('Logs bisa dibuka setelah data disimpan')
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
|
|
760
863
|
pageHelper.openSection(self, 'fLogs-section', params, async ()=>{
|
|
761
864
|
// get log data
|
|
762
865
|
const pk = frm.getPrimaryInput()
|
|
@@ -766,7 +869,9 @@ async function btn_logs_click(self, evt) {
|
|
|
766
869
|
let mask = $fgta5.Modal.createMask()
|
|
767
870
|
try {
|
|
768
871
|
|
|
769
|
-
|
|
872
|
+
|
|
873
|
+
const logApp = Context.appsUrls.core ?? Context.appsUrls[Context.appName]
|
|
874
|
+
const url = `${logApp.url}/logs/list`
|
|
770
875
|
const criteria = {
|
|
771
876
|
module: Context.moduleName,
|
|
772
877
|
table: '<%= tablename %>',
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Context from './<%= moduleName %>-context.mjs'
|
|
2
|
-
import * as
|
|
2
|
+
import * as Ext from './<%= moduleName %>-ext.mjs'
|
|
3
|
+
|
|
4
|
+
const Extender = Ext.<%=extenderDetil%> ?? Ext
|
|
3
5
|
|
|
4
6
|
const Crsl = Context.Crsl
|
|
5
7
|
const CurrentSectionId = Context.Sections.<%= modulePart %>
|
|
@@ -31,7 +33,8 @@ export async function init(self, args) {
|
|
|
31
33
|
|
|
32
34
|
// tambahkan event lain di extender: rowrender, rowremoving
|
|
33
35
|
// dapatkan parameternya di evt.detail
|
|
34
|
-
|
|
36
|
+
// export function <%= modulePart %>_addTableEvents(self, tbl) {}
|
|
37
|
+
const fn_addTableEvents_name = '<%= modulePart %>_addTableEvents'
|
|
35
38
|
const fn_addTableEvents = Extender[fn_addTableEvents_name]
|
|
36
39
|
if (typeof fn_addTableEvents === 'function') {
|
|
37
40
|
fn_addTableEvents(self, tbl)
|
|
@@ -47,6 +50,7 @@ export async function init(self, args) {
|
|
|
47
50
|
btn_delrow.addEventListener('click', (evt)=>{ btn_delrow_click(self, evt) })
|
|
48
51
|
|
|
49
52
|
// Extend list detil
|
|
53
|
+
// export function <%= modulePart %>_init(self) {}
|
|
50
54
|
const fn_name = '<%= modulePart %>_init'
|
|
51
55
|
const fn_<%= modulePart %>_init = Extender[fn_name]
|
|
52
56
|
if (typeof fn_<%= modulePart %>_init === 'function') {
|
|
@@ -56,6 +60,22 @@ export async function init(self, args) {
|
|
|
56
60
|
CurrentState.headerFormLocked = true
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
function setDefaultHeadTitle(self, headerForm) {
|
|
64
|
+
const data = headerForm.getData()
|
|
65
|
+
|
|
66
|
+
<% if (bindHeadTitle!='') { %>const detilTitleElements = document.getElementsByClassName('section-detil-title')
|
|
67
|
+
for (let el of detilTitleElements) {
|
|
68
|
+
el.innerHTML = data.<%= bindHeadTitle %>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
<% } %><% if (bindHeadDescr!='') { %>const detilDescrElements = document.getElementsByClassName('section-detil-descr')
|
|
72
|
+
for (let el of detilDescrElements) {
|
|
73
|
+
el.innerHTML = data.<%= bindHeadDescr %>
|
|
74
|
+
}<% } %>
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
59
79
|
export async function openList(self, params) {
|
|
60
80
|
const moduleHeaderEdit = params.moduleHeaderEdit
|
|
61
81
|
|
|
@@ -63,10 +83,13 @@ export async function openList(self, params) {
|
|
|
63
83
|
const pk = headerForm.getPrimaryInput()
|
|
64
84
|
const id = pk.value
|
|
65
85
|
|
|
86
|
+
// set title halaman ini sesuai data di header
|
|
87
|
+
setDefaultHeadTitle(self, headerForm)
|
|
66
88
|
|
|
67
89
|
// apabila mau menambahkan informasi saat detil list dibuka,
|
|
68
90
|
// misalnya menambahkan informasi beberapa data dari formHeader
|
|
69
91
|
// bisa di set pada Extender.<%= modulePart %>_openList : bisa menggunakan template untuk di embed ke header pada detil list
|
|
92
|
+
// export function <%= modulePart %>_openList(self, headerForm) {}
|
|
70
93
|
const fn_name = '<%= modulePart %>_openList'
|
|
71
94
|
const fn_<%= modulePart %>_openList = Extender[fn_name]
|
|
72
95
|
if (typeof fn_<%= modulePart %>_openList === 'function') {
|
|
@@ -81,16 +104,31 @@ export async function openList(self, params) {
|
|
|
81
104
|
tbl.clear()
|
|
82
105
|
tbl_loadData(self, {criteria, sort})
|
|
83
106
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
107
|
+
const <%= moduleEdit %> = self.Modules.<%= moduleEdit %>
|
|
108
|
+
const btn_addrow = <%= moduleEdit %>.getCurrentState().Actions.newdata
|
|
109
|
+
<% if (!allowRowAdd) { %>
|
|
110
|
+
const btn_edit = <%= moduleEdit %>.getCurrentState().Actions.edit
|
|
111
|
+
btn_addrow.suspend() <% } %><% if (!allowRowRemove) { %>
|
|
112
|
+
btn_delrow.suspend() <% } %><% if (!allowRowEdit) { %>
|
|
113
|
+
btn_edit.suspend()
|
|
114
|
+
<% } %>
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
// walaupun CurrentState.headerFormLocked, tapi kalau header edit tidak di suspend tetap bisa add/remove row di detil
|
|
118
|
+
const suspended = self.Modules.<%= headerModulePartEdit %>.getCurrentState().Actions.edit.isSuspended()
|
|
119
|
+
if (suspended) {
|
|
120
|
+
btn_addrow.disabled = true
|
|
87
121
|
btn_delrow.disabled = true
|
|
88
122
|
} else {
|
|
89
|
-
btn_addrow.
|
|
123
|
+
btn_addrow.disabled = false
|
|
90
124
|
btn_delrow.disabled = false
|
|
91
125
|
}
|
|
92
126
|
}
|
|
93
127
|
|
|
128
|
+
export function getCurrentState(self) {
|
|
129
|
+
return CurrentState
|
|
130
|
+
}
|
|
131
|
+
|
|
94
132
|
export function getGrid(self) {
|
|
95
133
|
return tbl
|
|
96
134
|
}
|
|
@@ -170,19 +208,26 @@ export function keyboardAction(self, actionName) {
|
|
|
170
208
|
tbl.nextRecord()
|
|
171
209
|
} else if (actionName=='enter') {
|
|
172
210
|
const <%= moduleEdit %> = self.Modules.<%= moduleEdit %>
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
211
|
+
if (tbl.CurrentRow!=null) {
|
|
212
|
+
<%= moduleEdit %>.Section.show({}, (evt)=>{
|
|
213
|
+
openRow(self, tbl.CurrentRow)
|
|
214
|
+
})
|
|
215
|
+
}
|
|
176
216
|
}
|
|
177
217
|
}
|
|
178
218
|
|
|
179
219
|
|
|
180
220
|
function setCurrentRow(self, tr) {
|
|
181
221
|
CurrentState.SelectedRow = tr
|
|
222
|
+
tbl.CurrentRow = tr
|
|
182
223
|
}
|
|
183
224
|
|
|
184
225
|
|
|
185
226
|
async function openRow(self, tr) {
|
|
227
|
+
if (tr==null) {
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
|
|
186
231
|
const keyvalue = tr.getAttribute('keyvalue')
|
|
187
232
|
const key = tr.getAttribute('key')
|
|
188
233
|
|
|
@@ -209,13 +254,22 @@ async function openRow(self, tr) {
|
|
|
209
254
|
|
|
210
255
|
async function listRows(self, criteria, offset, limit, sort) {
|
|
211
256
|
const url = `/${Context.moduleName}/<%= sectionName %>-list`
|
|
257
|
+
const evt = { url, limit }
|
|
258
|
+
|
|
259
|
+
// export async function <%= modulePart %>_dataLoad(self, criteria, sort, evt) {}
|
|
260
|
+
const fn_dataLoad_name = '<%= modulePart %>_dataLoad'
|
|
261
|
+
const fn_dataLoad = Extender[fn_dataLoad_name]
|
|
262
|
+
if (typeof fn_dataLoad === 'function') {
|
|
263
|
+
await fn_dataLoad(self, criteria, sort, evt)
|
|
264
|
+
}
|
|
265
|
+
|
|
212
266
|
try {
|
|
213
267
|
const columns = []
|
|
214
|
-
const result = await Module.apiCall(url, {
|
|
268
|
+
const result = await Module.apiCall(evt.url, {
|
|
215
269
|
columns,
|
|
216
270
|
criteria,
|
|
217
271
|
offset,
|
|
218
|
-
limit,
|
|
272
|
+
limit: evt.limit,
|
|
219
273
|
sort
|
|
220
274
|
})
|
|
221
275
|
return result
|
|
@@ -231,6 +285,14 @@ async function deleteRows(self, data) {
|
|
|
231
285
|
|
|
232
286
|
const result = await Module.apiCall(url, { data })
|
|
233
287
|
if (result.deleted) {
|
|
288
|
+
|
|
289
|
+
// export async function <%= modulePart %>_rowsDeleted(self, data) {}
|
|
290
|
+
const fn_name = '<%= modulePart %>_rowsDeleted'
|
|
291
|
+
const fn = Extender[fn_name]
|
|
292
|
+
if (typeof fn === 'function') {
|
|
293
|
+
await fn(self, result)
|
|
294
|
+
}
|
|
295
|
+
|
|
234
296
|
return true
|
|
235
297
|
} else {
|
|
236
298
|
throw new Error(result.message)
|
|
@@ -277,8 +339,21 @@ async function tbl_loadData(self, params={}) {
|
|
|
277
339
|
if (offset===0) {
|
|
278
340
|
tbl.clear()
|
|
279
341
|
}
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
tbl.setCriteria(criteria)
|
|
280
345
|
tbl.addRows(result.data)
|
|
281
346
|
tbl.setNext(result.nextoffset, result.limit)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
// export async function <%= modulePart %>_tableDataLoaded(self, tbl, result) {}
|
|
350
|
+
const fn_name = '<%= modulePart %>_tableDataLoaded'
|
|
351
|
+
const fn = Extender[fn_name]
|
|
352
|
+
if (typeof fn === 'function') {
|
|
353
|
+
await fn(self, tbl, result)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
|
|
282
357
|
} catch (err) {
|
|
283
358
|
console.error(err)
|
|
284
359
|
$fgta5.MessageBox.error(err.message)
|
|
@@ -12,12 +12,15 @@
|
|
|
12
12
|
</form>
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
<div id="<%= modulePart %>-footer">
|
|
16
|
+
</div>
|
|
17
|
+
|
|
15
18
|
<div id="panel-detil-selector" class="panel-detil <% if (detilCount==0) { %>hidden<% } %>">
|
|
16
19
|
<div panel-title>
|
|
17
20
|
Information Detil
|
|
18
21
|
</div>
|
|
19
22
|
<div panel-content><% sectionDetils.forEach(detil => { %>
|
|
20
|
-
<div class="panel-detil-row">
|
|
23
|
+
<div class="panel-detil-row" id="<%= modulePart %>-info-<%= detil.entityName %>-row">
|
|
21
24
|
<div data-label><a href="javascript:void(0)" data-target-section="<%= detil.listModulePart %>" data-current-section="<%= modulePart %>"><%= detil.title %></a></div>
|
|
22
25
|
<div data-info> </div>
|
|
23
26
|
</div><% }) %>
|
|
@@ -28,6 +31,10 @@
|
|
|
28
31
|
</div>
|
|
29
32
|
</div>
|
|
30
33
|
|
|
34
|
+
<div id="<%= modulePart %>-panelaction" class="panel-action<% if (actionList.length==0) { %> hidden<% } %>"><% if (actionList.length>0) { %><% actionList.forEach(action => { %>
|
|
35
|
+
<button id="<%= action.elementId %>"><%= action.title %></button><% }) %>
|
|
36
|
+
<% } %></div>
|
|
37
|
+
|
|
31
38
|
|
|
32
39
|
<div class="panel-recordbar" <% if (detilCount==0) { %>data-view="nodetil"<% } %>>
|
|
33
40
|
<div><a id="<%= moduleSection %>-btn_recordstatus" href="javascript:void(0)" tabindex="-1">Record Status</a></div>
|