@agung_dhewe/webapps 1.1.2

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 (130) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +2 -0
  3. package/jsconfig.json +10 -0
  4. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.css +2 -0
  5. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js +11 -0
  6. package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js.map +1 -0
  7. package/libs/fgta5js-dist/fonts/karla-italic-latin-ext.woff2 +0 -0
  8. package/libs/fgta5js-dist/fonts/karla-italic-latin.woff2 +0 -0
  9. package/libs/fgta5js-dist/fonts/karla-normal-latin-ext.woff2 +0 -0
  10. package/libs/fgta5js-dist/fonts/karla-normal-latin.woff2 +0 -0
  11. package/libs/fgta5js-dist/fonts/karla.css +142 -0
  12. package/libs/webmodule/module-edit.css +163 -0
  13. package/libs/webmodule/module-footer.css +22 -0
  14. package/libs/webmodule/module-list.css +25 -0
  15. package/libs/webmodule/module.css +52 -0
  16. package/libs/webmodule/module.js +195 -0
  17. package/libs/webmodule/pagehelper.mjs +45 -0
  18. package/modules/generator/appgen-components.mjs +142 -0
  19. package/modules/generator/appgen-icons.mjs +6 -0
  20. package/modules/generator/appgen-io.mjs +784 -0
  21. package/modules/generator/appgen-ui-search.mjs +173 -0
  22. package/modules/generator/appgen-ui-unique.mjs +153 -0
  23. package/modules/generator/appgen-ui.mjs +1181 -0
  24. package/modules/generator/generator-context.mjs +18 -0
  25. package/modules/generator/generator-designtemplate.html +1508 -0
  26. package/modules/generator/generator-ext.html +0 -0
  27. package/modules/generator/generator-ext.mjs +3 -0
  28. package/modules/generator/generator.css +642 -0
  29. package/modules/generator/generator.mjs +195 -0
  30. package/modules/generator/generator.png +0 -0
  31. package/modules/generator/generatorEdit.html +185 -0
  32. package/modules/generator/generatorEdit.mjs +238 -0
  33. package/modules/generator/generatorList.html +32 -0
  34. package/modules/generator/generatorList.mjs +243 -0
  35. package/modules/login/login.css +11 -0
  36. package/modules/login/login.html +12 -0
  37. package/modules/login/login.mjs +111 -0
  38. package/package.json +46 -0
  39. package/percobaan/simmpan-ke-minio.js +24 -0
  40. package/src/api.js +80 -0
  41. package/src/apis/generator.api.js +226 -0
  42. package/src/apis/login.api.js +109 -0
  43. package/src/bucket.js +24 -0
  44. package/src/context.js +26 -0
  45. package/src/datalog.sql +22 -0
  46. package/src/datarecords.js +0 -0
  47. package/src/db.js +61 -0
  48. package/src/generator/createApiExtenderModule.js +54 -0
  49. package/src/generator/createApiModule.js +218 -0
  50. package/src/generator/createIcon.js +62 -0
  51. package/src/generator/createInfoAboutExtender.js +42 -0
  52. package/src/generator/createInfoLogs.js +41 -0
  53. package/src/generator/createInfoRecordExtender.js +41 -0
  54. package/src/generator/createModuleContext.js +48 -0
  55. package/src/generator/createModuleDetilEditHtml.js +110 -0
  56. package/src/generator/createModuleDetilEditMjs.js +172 -0
  57. package/src/generator/createModuleDetilListHtml.js +146 -0
  58. package/src/generator/createModuleDetilListMjs.js +73 -0
  59. package/src/generator/createModuleEjs.js +51 -0
  60. package/src/generator/createModuleExtenderHtml.js +43 -0
  61. package/src/generator/createModuleExtenderMjs.js +43 -0
  62. package/src/generator/createModuleHeaderEditHtml.js +148 -0
  63. package/src/generator/createModuleHeaderEditMjs.js +197 -0
  64. package/src/generator/createModuleHeaderListHtml.js +144 -0
  65. package/src/generator/createModuleHeaderListMjs.js +67 -0
  66. package/src/generator/createModuleMjs.js +67 -0
  67. package/src/generator/createModuleRollup.js +42 -0
  68. package/src/generator/createProgramData.js +96 -0
  69. package/src/generator/createTable.js +156 -0
  70. package/src/generator/ddl.js +475 -0
  71. package/src/generator/helper.js +149 -0
  72. package/src/generator/templates/__rollup-module.ejs +90 -0
  73. package/src/generator/templates/api-extender-module.js.ejs +0 -0
  74. package/src/generator/templates/api-module.js.ejs +818 -0
  75. package/src/generator/templates/module-context.ejs +16 -0
  76. package/src/generator/templates/module-ext-about.ejs +1 -0
  77. package/src/generator/templates/module-ext-record.ejs +1 -0
  78. package/src/generator/templates/module-ext.html.ejs +3 -0
  79. package/src/generator/templates/module-ext.mjs.ejs +21 -0
  80. package/src/generator/templates/module-logs.ejs +14 -0
  81. package/src/generator/templates/module.ejs.ejs +48 -0
  82. package/src/generator/templates/module.mjs.ejs +256 -0
  83. package/src/generator/templates/moduleDetilEdit.html.ejs +34 -0
  84. package/src/generator/templates/moduleDetilEdit.mjs.ejs +792 -0
  85. package/src/generator/templates/moduleDetilList.html.ejs +26 -0
  86. package/src/generator/templates/moduleDetilList.mjs.ejs +319 -0
  87. package/src/generator/templates/moduleHeaderEdit.html.ejs +53 -0
  88. package/src/generator/templates/moduleHeaderEdit.mjs.ejs +807 -0
  89. package/src/generator/templates/moduleHeaderList.html.ejs +24 -0
  90. package/src/generator/templates/moduleHeaderList.mjs.ejs +308 -0
  91. package/src/generator/templates/sqlAddField.ejs +3 -0
  92. package/src/generator/templates/sqlAddForeignKey.ejs +12 -0
  93. package/src/generator/templates/sqlAddUniqueIndex.ejs +4 -0
  94. package/src/generator/templates/sqlCreateTable.ejs +9 -0
  95. package/src/generator/templates/sqlDropForeignKey.ejs +3 -0
  96. package/src/generator/templates/sqlDropUniqueIndex.ejs +4 -0
  97. package/src/generator/templates/sqlModifyField.ejs +6 -0
  98. package/src/generator/trygenerate.js +83 -0
  99. package/src/generator/worker.js +389 -0
  100. package/src/helper.js +82 -0
  101. package/src/logger.js +39 -0
  102. package/src/router.js +84 -0
  103. package/src/routers/defaultLoginApi.js +29 -0
  104. package/src/routers/defaultLoginAsset.js +18 -0
  105. package/src/routers/defaultLoginPage.js +36 -0
  106. package/src/routers/defaultRootIndex.js +16 -0
  107. package/src/routers/downloadHandler.js +51 -0
  108. package/src/routers/fileUploadApi.js +15 -0
  109. package/src/routers/generatorApi.js +30 -0
  110. package/src/routers/generatorAsset.js +18 -0
  111. package/src/routers/generatorPage.js +37 -0
  112. package/src/routers/handleError.js +43 -0
  113. package/src/routers/handleModuleNotfound.js +12 -0
  114. package/src/routers/moduleApi.js +34 -0
  115. package/src/routers/modulePage.js +102 -0
  116. package/src/sequencerdoc.js +311 -0
  117. package/src/sequencerline.js +214 -0
  118. package/src/session.js +57 -0
  119. package/src/startup.js +59 -0
  120. package/src/webapps.js +239 -0
  121. package/src/workermanager.js +83 -0
  122. package/templates/_lib_debug.ejs +11 -0
  123. package/templates/_lib_production.ejs +5 -0
  124. package/templates/application.page.ejs +143 -0
  125. package/templates/generator.page.ejs +131 -0
  126. package/templates/index.page.ejs +24 -0
  127. package/templates/login.page.ejs +102 -0
  128. package/templates/moduleError.ejs +16 -0
  129. package/templates/moduleNotfound.ejs +14 -0
  130. package/webapps.code-workspace +11 -0
@@ -0,0 +1,26 @@
1
+ <div id="<%= modulePart %>-head">
2
+
3
+ </div>
4
+
5
+
6
+ <table id="<%= modulePart %>-tbl" fgta5-component="Gridview">
7
+ <thead>
8
+ <tr data-header key="<%= section.primaryKey %>">
9
+ <th rowselector></th><% fields.forEach(field => { %>
10
+ <th data-name="<%= field.dataName %>" binding="<%= field.binding %>" <%- field.additionalAttributes %>><%= field.label %></th><% }); %>
11
+ </tr>
12
+ </thead>
13
+ </table>
14
+
15
+ <div id="<%= modulePart %>-foot">
16
+
17
+ </div>
18
+
19
+ <div class="footer-buttons-container hidden">
20
+ <div></div>
21
+ <div>
22
+ <button id="<%=modulePart%>-btn_addrow" data-action="<%= moduleSection %>-addrow" data-sectionsource="<%=modulePart%>-section">Add Row</button>
23
+ <button id="<%=modulePart%>-btn_delrow">Delete Row</button>
24
+ </div>
25
+ <div></div>
26
+ </div>
@@ -0,0 +1,319 @@
1
+ import Context from './<%= moduleName %>-context.mjs'
2
+ import * as Extender from './<%= moduleName %>-ext.mjs'
3
+
4
+ const Crsl = Context.Crsl
5
+ const CurrentSectionId = Context.Sections.<%= modulePart %>
6
+ const CurrentSection = Crsl.Items[CurrentSectionId]
7
+ const CurrentState = {}
8
+
9
+ const tbl = new $fgta5.Gridview('<%= modulePart %>-tbl')
10
+
11
+ const btn_addrow = document.getElementById('<%= modulePart %>-btn_addrow') // tidak perlu pakai action, karna action didefine di edit
12
+ const btn_delrow = new $fgta5.ActionButton('<%= modulePart %>-btn_delrow')
13
+
14
+ let headerForm
15
+
16
+ export const Section = CurrentSection
17
+
18
+
19
+ export async function init(self, args) {
20
+
21
+ // Back
22
+ CurrentSection.addEventListener($fgta5.Section.EVT_BACKBUTTONCLICK, async (evt)=>{
23
+ const sectionId = Context.Sections.<%= headerModulePartEdit %>
24
+ const section = Crsl.Items[sectionId]
25
+ section.show({direction: 1})
26
+ })
27
+
28
+
29
+ tbl.addEventListener('nextdata', async evt=>{ tbl_nextdata(self, evt) })
30
+ tbl.addEventListener('sorting', async evt=>{ tbl_sorting(self, evt) })
31
+
32
+ // tambahkan event lain di extender: rowrender, rowremoving
33
+ // dapatkan parameternya di evt.detail
34
+ const fn_addTableEvents_name = '<%= sectionName %>List_addTableEvents'
35
+ const fn_addTableEvents = Extender[fn_addTableEvents_name]
36
+ if (typeof fn_addTableEvents === 'function') {
37
+ fn_addTableEvents(self, tbl)
38
+ }
39
+
40
+ if (Module.isMobileDevice()) {
41
+ tbl.addEventListener('cellclick', async evt=>{ tbl_cellclick(self, evt) })
42
+ } else {
43
+ tbl.addEventListener('celldblclick', async evt=>{ tbl_cellclick(self, evt) })
44
+ }
45
+
46
+
47
+ btn_delrow.addEventListener('click', (evt)=>{ btn_delrow_click(self, evt) })
48
+
49
+ // Extend list detil
50
+ const fn_name = '<%= modulePart %>_init'
51
+ const fn_<%= modulePart %>_init = Extender[fn_name]
52
+ if (typeof fn_<%= modulePart %>_init === 'function') {
53
+ fn_<%= modulePart %>_init(self)
54
+ }
55
+
56
+ CurrentState.headerFormLocked = true
57
+ }
58
+
59
+ export async function openList(self, params) {
60
+ const moduleHeaderEdit = params.moduleHeaderEdit
61
+
62
+ headerForm = moduleHeaderEdit.getHeaderForm()
63
+ const pk = headerForm.getPrimaryInput()
64
+ const id = pk.value
65
+
66
+
67
+ // apabila mau menambahkan informasi saat detil list dibuka,
68
+ // misalnya menambahkan informasi beberapa data dari formHeader
69
+ // bisa di set pada Extender.<%= modulePart %>_openList : bisa menggunakan template untuk di embed ke header pada detil list
70
+ const fn_name = '<%= modulePart %>_openList'
71
+ const fn_<%= modulePart %>_openList = Extender[fn_name]
72
+ if (typeof fn_<%= modulePart %>_openList === 'function') {
73
+ fn_<%= modulePart %>_openList(self, headerForm)
74
+ }
75
+
76
+ const criteria={
77
+ <%= headerPrimaryKey %>: id
78
+ }
79
+ const sort = tbl.getSort()
80
+
81
+ tbl.clear()
82
+ tbl_loadData(self, {criteria, sort})
83
+
84
+
85
+ if (CurrentState.headerFormLocked) {
86
+ btn_addrow.setAttribute('disabled', '')
87
+ btn_delrow.disabled = true
88
+ } else {
89
+ btn_addrow.removeAttribute('disabled')
90
+ btn_delrow.disabled = false
91
+ }
92
+ }
93
+
94
+ export function getGrid(self) {
95
+ return tbl
96
+ }
97
+
98
+ export function getCurrentRow(self) {
99
+ return CurrentState.SelectedRow
100
+ }
101
+
102
+ export function addNewRow(self, data) {
103
+ const tr = tbl.addRow(data)
104
+ setCurrentRow(self, tr)
105
+ }
106
+
107
+ export function updateCurrentRow(self, data) {
108
+ const tr = CurrentState.SelectedRow
109
+
110
+ try {
111
+ tbl.updateRow(tr, data)
112
+ } catch (err) {
113
+ throw err
114
+ }
115
+ }
116
+
117
+ export function removeCurrentRow(self) {
118
+ const tr = CurrentState.SelectedRow
119
+ tbl.removeRow(tr)
120
+ }
121
+
122
+ export function selectNextRow(self) {
123
+ const tr = CurrentState.SelectedRow
124
+ if (tr.nextElementSibling) {
125
+ tbl.CurrentRow = tr.nextElementSibling
126
+ openRow(self, tr.nextElementSibling)
127
+ }
128
+ }
129
+
130
+ export function selectPreviousRow(self) {
131
+ const tr = CurrentState.SelectedRow
132
+ if (tr.previousElementSibling) {
133
+ tbl.CurrentRow = tr.previousElementSibling
134
+ openRow(self, tr.previousElementSibling)
135
+ }
136
+ }
137
+
138
+ export function setPagingButton(self, editModule) {
139
+ const tr = CurrentState.SelectedRow
140
+
141
+ if (tr.previousElementSibling) {
142
+ editModule.disablePrevButton(self, false)
143
+ } else {
144
+ editModule.disablePrevButton(self, true)
145
+ }
146
+
147
+ if (tr.nextElementSibling) {
148
+ editModule.disableNextButton(self, false)
149
+ } else {
150
+ editModule.disableNextButton(self, true)
151
+ }
152
+
153
+ }
154
+
155
+ export function headerLocked(self) {
156
+ console.log('header locked')
157
+ CurrentState.headerFormLocked = true
158
+ }
159
+
160
+ export function headerUnlocked(self) {
161
+ console.log('header unlocked')
162
+ CurrentState.headerFormLocked = false
163
+ }
164
+
165
+
166
+ export function keyboardAction(self, actionName) {
167
+ if (actionName=='up') {
168
+ tbl.previousRecord()
169
+ } else if (actionName=='down') {
170
+ tbl.nextRecord()
171
+ } else if (actionName=='enter') {
172
+ const <%= moduleEdit %> = self.Modules.<%= moduleEdit %>
173
+ <%= moduleEdit %>.Section.show({}, (evt)=>{
174
+ openRow(self, tbl.CurrentRow)
175
+ })
176
+ }
177
+ }
178
+
179
+
180
+ function setCurrentRow(self, tr) {
181
+ CurrentState.SelectedRow = tr
182
+ }
183
+
184
+
185
+ async function openRow(self, tr) {
186
+ const keyvalue = tr.getAttribute('keyvalue')
187
+ const key = tr.getAttribute('key')
188
+
189
+ const <%= moduleEdit %> = self.Modules.<%= moduleEdit %>
190
+ <%= moduleEdit %>.clearForm(self, 'loading...')
191
+
192
+ try {
193
+ setCurrentRow(self, tr)
194
+ CurrentState.SelectedRow.keyValue = keyvalue
195
+ CurrentState.SelectedRow.key = key
196
+ await <%= moduleEdit %>.openSelectedData(self, {key:key, keyvalue:keyvalue})
197
+ } catch (err) {
198
+ console.error(err)
199
+ await $fgta5.MessageBox.error(err.message)
200
+
201
+ setCurrentRow(self, null)
202
+ CurrentSection.show() // kembalikan ke list kalau error saat buka data
203
+ }
204
+
205
+ // matikan atau nyalakan button prev/next sesuai kondisi
206
+ setPagingButton(self, <%= moduleEdit %>)
207
+ }
208
+
209
+
210
+ async function listRows(self, criteria, offset, limit, sort) {
211
+ const url = `/${Context.moduleName}/<%= sectionName %>-list`
212
+ try {
213
+ const columns = []
214
+ const result = await Module.apiCall(url, {
215
+ columns,
216
+ criteria,
217
+ offset,
218
+ limit,
219
+ sort
220
+ })
221
+ return result
222
+ } catch (err) {
223
+ throw err
224
+ }
225
+ }
226
+
227
+
228
+ async function deleteRows(self, data) {
229
+ const url = `/${Context.moduleName}/<%= sectionName %>-delete-rows`
230
+ try {
231
+
232
+ const result = await Module.apiCall(url, { data })
233
+ if (result.deleted) {
234
+ return true
235
+ } else {
236
+ throw new Error(result.message)
237
+ }
238
+ } catch (err) {
239
+ throw err
240
+ }
241
+ }
242
+
243
+ async function tbl_nextdata(self, evt) {
244
+ const criteria = evt.detail.criteria
245
+ const limit = evt.detail.limit
246
+ const offset = evt.detail.nextoffset
247
+ const sort = evt.detail.sort
248
+
249
+ await tbl_loadData(self, {criteria, limit, offset, sort})
250
+ tbl.scrollToFooter()
251
+ }
252
+
253
+ async function tbl_sorting(self, evt) {
254
+ tbl.clear()
255
+ const sort = evt.detail.sort
256
+ const criteria = evt.detail.Criteria
257
+ tbl_loadData(self, {criteria, sort})
258
+ }
259
+
260
+ async function tbl_cellclick(self, evt) {
261
+ const tr = evt.detail.tr
262
+
263
+ const <%= moduleEdit %> = self.Modules.<%= moduleEdit %>
264
+ <%= moduleEdit %>.Section.show({}, (evt)=>{
265
+ openRow(self, tr)
266
+ })
267
+ }
268
+
269
+
270
+ async function tbl_loadData(self, params={}) {
271
+ const { criteria={}, limit=0, offset=0, sort={} } = params
272
+
273
+ let mask = $fgta5.Modal.createMask()
274
+ try {
275
+ const result = await listRows(self, criteria, offset,limit, sort)
276
+
277
+ if (offset===0) {
278
+ tbl.clear()
279
+ }
280
+ tbl.addRows(result.data)
281
+ tbl.setNext(result.nextoffset, result.limit)
282
+ } catch (err) {
283
+ console.error(err)
284
+ $fgta5.MessageBox.error(err.message)
285
+ } finally {
286
+ mask.close()
287
+ mask = null
288
+ }
289
+ }
290
+
291
+
292
+ async function btn_delrow_click(self, evt) {
293
+ // cek dahulu apakah ada data yang dipilih
294
+ const selected = tbl.getSelected()
295
+ if (selected.length==0) {
296
+ return
297
+ }
298
+
299
+ // konfirmasi apakah yakin mau dihapus
300
+ var ret = await $fgta5.MessageBox.confirm(`Apakah anda yakin akan menghappus ${selected.length} data yang dipilih?`)
301
+ if (ret!='ok') {
302
+ return
303
+ }
304
+
305
+ let mask = $fgta5.Modal.createMask()
306
+ try {
307
+ const deleted = await deleteRows(self, selected)
308
+ if (deleted) {
309
+ tbl.removeSelected()
310
+ }
311
+ } catch (err) {
312
+ console.error(err)
313
+ $fgta5.MessageBox.error(err.message)
314
+ } finally {
315
+ mask.close()
316
+ mask = null
317
+ }
318
+
319
+ }
@@ -0,0 +1,53 @@
1
+ <form id="<%= modulePart %>-frm" class="module-form" locked="true" autoid="<%= autoid %>" primarykey="<%= primaryKeyElementId %>"><% fields.forEach(field => { %>
2
+
3
+ <!-- <%= field.component %>: <%= field.fieldname %>-->
4
+ <div id="<%= field.elementId %>-container" class="<%= field.cssContainer %>" field="<%= field.elementId %>">
5
+ <label for="<%= field.elementId %>"><%= field.label %></label>
6
+ <input id="<%= field.elementId %>" fgta5-component="<%= field.component %>" placeholder="<%= field.placeholder %>" autocomplete="off" spellcheck="false"
7
+ binding="<%= field.binding %>"<% field.additionalAttributes.forEach(config => { %>
8
+ <%- config %> <% }) %>
9
+ >
10
+ </div>
11
+ <% }) %>
12
+ </form>
13
+
14
+
15
+ <div id="panel-detil-selector" class="panel-detil <% if (detilCount==0) { %>hidden<% } %>">
16
+ <div panel-title>
17
+ Information Detil
18
+ </div>
19
+ <div panel-content><% sectionDetils.forEach(detil => { %>
20
+ <div class="panel-detil-row">
21
+ <div data-label><a href="javascript:void(0)" data-target-section="<%= detil.listModulePart %>" data-current-section="<%= modulePart %>"><%= detil.title %></a></div>
22
+ <div data-info>&nbsp</div>
23
+ </div><% }) %>
24
+
25
+ <div id="panel-detil-additionalinfo">
26
+ <!-- tambahkan additional info disini -->
27
+ </div>
28
+ </div>
29
+ </div>
30
+
31
+
32
+ <div class="panel-recordbar" <% if (detilCount==0) { %>data-view="nodetil"<% } %>>
33
+ <div><a id="<%= moduleSection %>-btn_recordstatus" href="javascript:void(0)" tabindex="-1">Record Status</a></div>
34
+ <div><a id="<%= moduleSection %>-btn_logs" href="javascript:void(0)" tabindex="-1">Logs</a></div>
35
+ <div><a id="<%= moduleSection %>-btn_about" href="javascript:void(0)" tabindex="-1">About</a></div>
36
+ </div>
37
+
38
+
39
+ <div class="footer-buttons-container hidden">
40
+ <div>
41
+ <button id="<%= modulePart %>-btn_prev"><span>&laquo;&laquo;</span></button>
42
+ </div>
43
+ <div>
44
+ <button id="<%= modulePart %>-btn_save">Save</button>
45
+ <button id="<%= modulePart %>-btn_edit">Edit</button>
46
+ <button id="<%= modulePart %>-btn_new" data-action="<%= moduleSection %>-new">New</button>
47
+ <button id="<%= modulePart %>-btn_reset">Reset</button>
48
+ <button id="<%= modulePart %>-btn_delete">Delete</button>
49
+ </div>
50
+ <div>
51
+ <button id="<%= modulePart %>-btn_next"><span>&raquo;&raquo;</span></button>
52
+ </div>
53
+ </div>