@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.
- package/LICENSE +28 -0
- package/README.md +2 -0
- package/jsconfig.json +10 -0
- package/libs/fgta5js-dist/fgta5js-v1.8.3.min.css +2 -0
- package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js +11 -0
- package/libs/fgta5js-dist/fgta5js-v1.8.3.min.js.map +1 -0
- package/libs/fgta5js-dist/fonts/karla-italic-latin-ext.woff2 +0 -0
- package/libs/fgta5js-dist/fonts/karla-italic-latin.woff2 +0 -0
- package/libs/fgta5js-dist/fonts/karla-normal-latin-ext.woff2 +0 -0
- package/libs/fgta5js-dist/fonts/karla-normal-latin.woff2 +0 -0
- package/libs/fgta5js-dist/fonts/karla.css +142 -0
- package/libs/webmodule/module-edit.css +163 -0
- package/libs/webmodule/module-footer.css +22 -0
- package/libs/webmodule/module-list.css +25 -0
- package/libs/webmodule/module.css +52 -0
- package/libs/webmodule/module.js +195 -0
- package/libs/webmodule/pagehelper.mjs +45 -0
- package/modules/generator/appgen-components.mjs +142 -0
- package/modules/generator/appgen-icons.mjs +6 -0
- package/modules/generator/appgen-io.mjs +784 -0
- package/modules/generator/appgen-ui-search.mjs +173 -0
- package/modules/generator/appgen-ui-unique.mjs +153 -0
- package/modules/generator/appgen-ui.mjs +1181 -0
- package/modules/generator/generator-context.mjs +18 -0
- package/modules/generator/generator-designtemplate.html +1508 -0
- package/modules/generator/generator-ext.html +0 -0
- package/modules/generator/generator-ext.mjs +3 -0
- package/modules/generator/generator.css +642 -0
- package/modules/generator/generator.mjs +195 -0
- package/modules/generator/generator.png +0 -0
- package/modules/generator/generatorEdit.html +185 -0
- package/modules/generator/generatorEdit.mjs +238 -0
- package/modules/generator/generatorList.html +32 -0
- package/modules/generator/generatorList.mjs +243 -0
- package/modules/login/login.css +11 -0
- package/modules/login/login.html +12 -0
- package/modules/login/login.mjs +111 -0
- package/package.json +46 -0
- package/percobaan/simmpan-ke-minio.js +24 -0
- package/src/api.js +80 -0
- package/src/apis/generator.api.js +226 -0
- package/src/apis/login.api.js +109 -0
- package/src/bucket.js +24 -0
- package/src/context.js +26 -0
- package/src/datalog.sql +22 -0
- package/src/datarecords.js +0 -0
- package/src/db.js +61 -0
- package/src/generator/createApiExtenderModule.js +54 -0
- package/src/generator/createApiModule.js +218 -0
- package/src/generator/createIcon.js +62 -0
- package/src/generator/createInfoAboutExtender.js +42 -0
- package/src/generator/createInfoLogs.js +41 -0
- package/src/generator/createInfoRecordExtender.js +41 -0
- package/src/generator/createModuleContext.js +48 -0
- package/src/generator/createModuleDetilEditHtml.js +110 -0
- package/src/generator/createModuleDetilEditMjs.js +172 -0
- package/src/generator/createModuleDetilListHtml.js +146 -0
- package/src/generator/createModuleDetilListMjs.js +73 -0
- package/src/generator/createModuleEjs.js +51 -0
- package/src/generator/createModuleExtenderHtml.js +43 -0
- package/src/generator/createModuleExtenderMjs.js +43 -0
- package/src/generator/createModuleHeaderEditHtml.js +148 -0
- package/src/generator/createModuleHeaderEditMjs.js +197 -0
- package/src/generator/createModuleHeaderListHtml.js +144 -0
- package/src/generator/createModuleHeaderListMjs.js +67 -0
- package/src/generator/createModuleMjs.js +67 -0
- package/src/generator/createModuleRollup.js +42 -0
- package/src/generator/createProgramData.js +96 -0
- package/src/generator/createTable.js +156 -0
- package/src/generator/ddl.js +475 -0
- package/src/generator/helper.js +149 -0
- package/src/generator/templates/__rollup-module.ejs +90 -0
- package/src/generator/templates/api-extender-module.js.ejs +0 -0
- package/src/generator/templates/api-module.js.ejs +818 -0
- package/src/generator/templates/module-context.ejs +16 -0
- package/src/generator/templates/module-ext-about.ejs +1 -0
- package/src/generator/templates/module-ext-record.ejs +1 -0
- package/src/generator/templates/module-ext.html.ejs +3 -0
- package/src/generator/templates/module-ext.mjs.ejs +21 -0
- package/src/generator/templates/module-logs.ejs +14 -0
- package/src/generator/templates/module.ejs.ejs +48 -0
- package/src/generator/templates/module.mjs.ejs +256 -0
- package/src/generator/templates/moduleDetilEdit.html.ejs +34 -0
- package/src/generator/templates/moduleDetilEdit.mjs.ejs +792 -0
- package/src/generator/templates/moduleDetilList.html.ejs +26 -0
- package/src/generator/templates/moduleDetilList.mjs.ejs +319 -0
- package/src/generator/templates/moduleHeaderEdit.html.ejs +53 -0
- package/src/generator/templates/moduleHeaderEdit.mjs.ejs +807 -0
- package/src/generator/templates/moduleHeaderList.html.ejs +24 -0
- package/src/generator/templates/moduleHeaderList.mjs.ejs +308 -0
- package/src/generator/templates/sqlAddField.ejs +3 -0
- package/src/generator/templates/sqlAddForeignKey.ejs +12 -0
- package/src/generator/templates/sqlAddUniqueIndex.ejs +4 -0
- package/src/generator/templates/sqlCreateTable.ejs +9 -0
- package/src/generator/templates/sqlDropForeignKey.ejs +3 -0
- package/src/generator/templates/sqlDropUniqueIndex.ejs +4 -0
- package/src/generator/templates/sqlModifyField.ejs +6 -0
- package/src/generator/trygenerate.js +83 -0
- package/src/generator/worker.js +389 -0
- package/src/helper.js +82 -0
- package/src/logger.js +39 -0
- package/src/router.js +84 -0
- package/src/routers/defaultLoginApi.js +29 -0
- package/src/routers/defaultLoginAsset.js +18 -0
- package/src/routers/defaultLoginPage.js +36 -0
- package/src/routers/defaultRootIndex.js +16 -0
- package/src/routers/downloadHandler.js +51 -0
- package/src/routers/fileUploadApi.js +15 -0
- package/src/routers/generatorApi.js +30 -0
- package/src/routers/generatorAsset.js +18 -0
- package/src/routers/generatorPage.js +37 -0
- package/src/routers/handleError.js +43 -0
- package/src/routers/handleModuleNotfound.js +12 -0
- package/src/routers/moduleApi.js +34 -0
- package/src/routers/modulePage.js +102 -0
- package/src/sequencerdoc.js +311 -0
- package/src/sequencerline.js +214 -0
- package/src/session.js +57 -0
- package/src/startup.js +59 -0
- package/src/webapps.js +239 -0
- package/src/workermanager.js +83 -0
- package/templates/_lib_debug.ejs +11 -0
- package/templates/_lib_production.ejs +5 -0
- package/templates/application.page.ejs +143 -0
- package/templates/generator.page.ejs +131 -0
- package/templates/index.page.ejs +24 -0
- package/templates/login.page.ejs +102 -0
- package/templates/moduleError.ejs +16 -0
- package/templates/moduleNotfound.ejs +14 -0
- package/webapps.code-workspace +11 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import Context from './generator-context.mjs'
|
|
2
|
+
import * as Extender from './generator-ext.mjs'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const Crsl = Context.Crsl
|
|
6
|
+
const CurrentSectionId = Context.Sections.generatorList
|
|
7
|
+
const CurrentSection = Crsl.Items[CurrentSectionId]
|
|
8
|
+
const CurrentState = {}
|
|
9
|
+
|
|
10
|
+
const tbl = new $fgta5.Gridview('generatorList-tbl')
|
|
11
|
+
const pnl_search = document.getElementById('generatorList-pnl_search')
|
|
12
|
+
const btn_gridload = new $fgta5.ActionButton('generatorList-btn_gridload')
|
|
13
|
+
|
|
14
|
+
export const Section = CurrentSection
|
|
15
|
+
export const SearchParams = {}
|
|
16
|
+
|
|
17
|
+
export async function init(self, args) {
|
|
18
|
+
console.log('initializing generatorList ...')
|
|
19
|
+
|
|
20
|
+
// add event listener
|
|
21
|
+
tbl.addEventListener('nextdata', async evt=>{ tbl_nextdata(self, evt) })
|
|
22
|
+
tbl.addEventListener('sorting', async evt=>{ tbl_sorting(self, evt) })
|
|
23
|
+
tbl.addEventListener('cellclick', async evt=>{ tbl_cellclick(self, evt) })
|
|
24
|
+
tbl.addEventListener('celldblclick', async evt=>{ tbl_celldblclick(self, evt) })
|
|
25
|
+
|
|
26
|
+
btn_gridload.addEventListener('click', async evt=>{ btn_gridload_click(self, evt) })
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// extract custom search panel from template
|
|
31
|
+
const tplSearchPanel = document.querySelector('template[name="custom-search-panel"]')
|
|
32
|
+
if (tplSearchPanel!=null) {
|
|
33
|
+
const clone = tplSearchPanel.content.cloneNode(true); // salin isi template
|
|
34
|
+
pnl_search.prepend(clone)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// setup search panel
|
|
38
|
+
const cmps = pnl_search.querySelectorAll('[fgta5-component][binding')
|
|
39
|
+
for (var cmp of cmps) {
|
|
40
|
+
var id = cmp.getAttribute('id')
|
|
41
|
+
var componentname = cmp.getAttribute('fgta5-component')
|
|
42
|
+
var binding = cmp.getAttribute('binding')
|
|
43
|
+
SearchParams[binding] = new $fgta5[componentname](id)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// generator-ext.mjs, export function initSearchParams(self, SearchParams) {}
|
|
47
|
+
// jangan exekusi langsung dari generatorExtender, karena akan error saat di rollup
|
|
48
|
+
if (typeof Extender.initSearchParams === 'function') {
|
|
49
|
+
Extender.initSearchParams(self, SearchParams)
|
|
50
|
+
} else {
|
|
51
|
+
console.warn(`'initSearchParams' tidak diimplementasikan di extender`)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
} catch (err) {
|
|
55
|
+
throw err
|
|
56
|
+
} finally {
|
|
57
|
+
// load data
|
|
58
|
+
if (args.autoLoadGridData===true) {
|
|
59
|
+
loadData(self)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function render(self) {
|
|
67
|
+
console.log('generatorList render')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function keyboardAction(self, actionName) {
|
|
71
|
+
if (actionName=='up') {
|
|
72
|
+
tbl.previousRecord()
|
|
73
|
+
} else if (actionName=='down') {
|
|
74
|
+
tbl.nextRecord()
|
|
75
|
+
} else if (actionName=='enter') {
|
|
76
|
+
const generatorEdit = self.Modules.generatorEdit
|
|
77
|
+
generatorEdit.Section.show({}, (evt)=>{
|
|
78
|
+
openRow(self, tbl.CurrentRow)
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function loadData(self) {
|
|
84
|
+
await tbl.clear()
|
|
85
|
+
tbl_loadData(self)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function getCurrentRow(self) {
|
|
89
|
+
return CurrentState.SelectedRow
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function setCurrentRow(self, tr) {
|
|
93
|
+
CurrentState.SelectedRow = tr
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function addNewRow(self, data) {
|
|
97
|
+
const tr = tbl.addRow(data)
|
|
98
|
+
setCurrentRow(self, tr)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function updateCurrentRow(self, data) {
|
|
102
|
+
const tr = CurrentState.SelectedRow
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
tbl.updateRow(tr, data)
|
|
106
|
+
} catch (err) {
|
|
107
|
+
throw err
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function removeCurrentRow(self) {
|
|
112
|
+
const tr = CurrentState.SelectedRow
|
|
113
|
+
tr.remove()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function selectNextRow(self) {
|
|
117
|
+
const tr = CurrentState.SelectedRow
|
|
118
|
+
if (tr.nextElementSibling) {
|
|
119
|
+
openRow(self, tr.nextElementSibling)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function selectPreviousRow(self) {
|
|
124
|
+
const tr = CurrentState.SelectedRow
|
|
125
|
+
if (tr.previousElementSibling) {
|
|
126
|
+
openRow(self, tr.previousElementSibling)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
async function openRow(self, tr) {
|
|
132
|
+
const keyvalue = tr.getAttribute('keyvalue')
|
|
133
|
+
const key = tr.getAttribute('key')
|
|
134
|
+
|
|
135
|
+
const generatorEdit = self.Modules.generatorEdit
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
setCurrentRow(self, tr)
|
|
139
|
+
CurrentState.SelectedRow.keyValue = keyvalue
|
|
140
|
+
CurrentState.SelectedRow.key = key
|
|
141
|
+
await generatorEdit.openSelectedData(self, {key:key, keyvalue:keyvalue})
|
|
142
|
+
} catch (err) {
|
|
143
|
+
console.error(err)
|
|
144
|
+
await $fgta5.MessageBox.error(err.message)
|
|
145
|
+
|
|
146
|
+
setCurrentRow(self, null)
|
|
147
|
+
CurrentSection.show() // kembalikan ke list kalau error saat buka data
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
async function tbl_nextdata(self, evt) {
|
|
153
|
+
const criteria = evt.detail.criteria
|
|
154
|
+
const limit = evt.detail.limit
|
|
155
|
+
const offset = evt.detail.nextoffset
|
|
156
|
+
const sort = evt.detail.sort
|
|
157
|
+
|
|
158
|
+
await tbl_loadData(self, {criteria, limit, offset, sort})
|
|
159
|
+
tbl.scrollToFooter()
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function tbl_sorting(self, evt) {
|
|
163
|
+
tbl.clear()
|
|
164
|
+
const sort = evt.detail.sort
|
|
165
|
+
const criteria = evt.detail.Criteria
|
|
166
|
+
tbl_loadData(self, {criteria, sort})
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function tbl_cellclick(self, evt) {
|
|
170
|
+
if (Module.isMobileDevice()) {
|
|
171
|
+
await tbl_celldblclick(self, evt)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function tbl_celldblclick(self, evt) {
|
|
176
|
+
const tr = evt.detail.tr
|
|
177
|
+
|
|
178
|
+
const generatorEdit = self.Modules.generatorEdit
|
|
179
|
+
generatorEdit.Section.show()
|
|
180
|
+
|
|
181
|
+
await openRow(self, tr)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function btn_gridload_click(self, evt) {
|
|
185
|
+
setCurrentRow(self, null)
|
|
186
|
+
loadData(self)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
async function tbl_loadData(self, params={}) {
|
|
191
|
+
console.log('loading generator data')
|
|
192
|
+
console.log(params)
|
|
193
|
+
|
|
194
|
+
const { criteria={}, limit=0, offset=0, sort={} } = params
|
|
195
|
+
|
|
196
|
+
// isi criteria
|
|
197
|
+
for (var key in SearchParams) {
|
|
198
|
+
var cmp = SearchParams[key]
|
|
199
|
+
var valid = cmp.validate()
|
|
200
|
+
if (!valid) {
|
|
201
|
+
console.error('ada yang belum diisi')
|
|
202
|
+
return false
|
|
203
|
+
}
|
|
204
|
+
criteria[key] = SearchParams[key].value
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// cek sorting
|
|
208
|
+
if (sort===undefined) {
|
|
209
|
+
sort = tbl.getSort()
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const args = {
|
|
213
|
+
columns: ['generator_id', 'generator_appname', 'generator_modulename'],
|
|
214
|
+
criteria: criteria,
|
|
215
|
+
offset: offset,
|
|
216
|
+
limit: limit,
|
|
217
|
+
sort: sort
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let mask = $fgta5.Modal.createMask()
|
|
221
|
+
|
|
222
|
+
const apiList = new $fgta5.ApiEndpoint('/generator/list')
|
|
223
|
+
try {
|
|
224
|
+
const result = await apiList.execute(args)
|
|
225
|
+
|
|
226
|
+
// jika offset tidak didefinisikan, berarti start dari awal, table dikosongkan dahulua
|
|
227
|
+
// jika offset didefinisikan berarti request untuk halaman berikutnya
|
|
228
|
+
if (offset===undefined) {
|
|
229
|
+
tbl.clear()
|
|
230
|
+
}
|
|
231
|
+
tbl.addRows(result.data)
|
|
232
|
+
tbl.setNext(result.nextoffset, result.limit)
|
|
233
|
+
|
|
234
|
+
} catch (err) {
|
|
235
|
+
console.error(err)
|
|
236
|
+
$fgta5.MessageBox.error(err.message)
|
|
237
|
+
} finally {
|
|
238
|
+
apiList.dispose()
|
|
239
|
+
mask.close()
|
|
240
|
+
mask = null
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<div class="loginbox">
|
|
2
|
+
<h1>Login</h1>
|
|
3
|
+
<div>
|
|
4
|
+
<input type="text" id="obj_username" placeholder="username">
|
|
5
|
+
</div>
|
|
6
|
+
<div>
|
|
7
|
+
<input type="password" id="obj_password" placeholder="password">
|
|
8
|
+
</div>
|
|
9
|
+
<div>
|
|
10
|
+
<button id="btn_login">Login</button>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const Context = {}
|
|
2
|
+
const btn_login = document.getElementById('btn_login')
|
|
3
|
+
const obj_username = document.getElementById('obj_username')
|
|
4
|
+
const obj_password = document.getElementById('obj_password')
|
|
5
|
+
|
|
6
|
+
// need test direct open
|
|
7
|
+
// https://core-dev.transfashion.id/?nexturl=https://ent-dev.transfashion.id/sitetype&id=STO
|
|
8
|
+
// skenario: buka link di atas dalam kondisi belum login, setelah login, diredirect lagi ke halaman di atas
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export default class extends Module {
|
|
12
|
+
constructor() {
|
|
13
|
+
super()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async main(args={}) {
|
|
17
|
+
|
|
18
|
+
console.log('initializing module...')
|
|
19
|
+
|
|
20
|
+
sessionStorage.removeItem('nextmodule');
|
|
21
|
+
btn_login.addEventListener('click', (evt)=>{
|
|
22
|
+
btn_login_click(self, evt)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
obj_username.addEventListener('keypress', evt=>{
|
|
26
|
+
const key = evt.key.toLowerCase()
|
|
27
|
+
if (key=='enter' && obj_username.value.trim()!='') {
|
|
28
|
+
obj_password.focus()
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
obj_password.addEventListener('keypress', evt=>{
|
|
33
|
+
const key = evt.key.toLowerCase()
|
|
34
|
+
if (key=='enter' && obj_password.value.trim()!='') {
|
|
35
|
+
btn_login.click()
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
setTimeout(()=>{
|
|
40
|
+
obj_username.focus()
|
|
41
|
+
}, 500)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
// inisiasi sisi server
|
|
46
|
+
try {
|
|
47
|
+
const result = await Module.apiCall(`/login/init`, { })
|
|
48
|
+
if (result.isLogin) {
|
|
49
|
+
location.href = '/'
|
|
50
|
+
}
|
|
51
|
+
} catch (err) {
|
|
52
|
+
throw err
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
} catch (err) {
|
|
56
|
+
throw err
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async function btn_login_click(self, evt) {
|
|
66
|
+
console.log('login')
|
|
67
|
+
const username = obj_username.value
|
|
68
|
+
const password = obj_password.value
|
|
69
|
+
|
|
70
|
+
const queryString = window.location.search
|
|
71
|
+
const params = new URLSearchParams(queryString)
|
|
72
|
+
const nexturl = params.get('nexturl')
|
|
73
|
+
const nextmodule = params.get('nextmodule')
|
|
74
|
+
|
|
75
|
+
console.log(nexturl, nextmodule)
|
|
76
|
+
|
|
77
|
+
let mask = $fgta5.Modal.createMask()
|
|
78
|
+
try {
|
|
79
|
+
// login, tidak pakai self.apiCall, karena akan bypass session
|
|
80
|
+
const apiLogin = new $fgta5.ApiEndpoint('login/do-login')
|
|
81
|
+
const result = await apiLogin.execute({username, password})
|
|
82
|
+
if (result!=null) {
|
|
83
|
+
// login berhasil
|
|
84
|
+
|
|
85
|
+
// simpan flag login
|
|
86
|
+
sessionStorage.setItem('login', true);
|
|
87
|
+
|
|
88
|
+
if (nextmodule!=null) {
|
|
89
|
+
sessionStorage.setItem('nextmodule', nextmodule);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (nexturl!=null) {
|
|
93
|
+
// redirect ke next url
|
|
94
|
+
sessionStorage.setItem('login_nexturl', nexturl);
|
|
95
|
+
location.href = nexturl
|
|
96
|
+
} else {
|
|
97
|
+
location.href = '/'
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
// login gagal
|
|
101
|
+
$fgta5.MessageBox.error('Login salah!')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.log(err)
|
|
106
|
+
$fgta5.MessageBox.error(err.message)
|
|
107
|
+
} finally {
|
|
108
|
+
mask.close()
|
|
109
|
+
mask = null
|
|
110
|
+
}
|
|
111
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agung_dhewe/webapps",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "library javascript (nodejs+express) untuk pengembangan applikasi web",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/webapps.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"generate": "node ./src/generator/trygenerate.js"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/agungdhewe/webapps.git"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"webapps",
|
|
16
|
+
"postgresql"
|
|
17
|
+
],
|
|
18
|
+
"author": "Agung Nugroho",
|
|
19
|
+
"license": "GPL-3.0-or-later",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/agungdhewe/webapps/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/agungdhewe/webapps#readme",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@agung_dhewe/pgsqlc": "^1.1.5",
|
|
29
|
+
"bcrypt": "^6.0.0",
|
|
30
|
+
"connect-redis": "^9.0.0",
|
|
31
|
+
"cors": "^2.8.5",
|
|
32
|
+
"dotenv": "^16.5.0",
|
|
33
|
+
"ejs": "^3.1.10",
|
|
34
|
+
"express": "^5.1.0",
|
|
35
|
+
"express-session": "^1.18.1",
|
|
36
|
+
"jsonwebtoken": "^9.0.2",
|
|
37
|
+
"minio": "^8.0.6",
|
|
38
|
+
"multer": "^2.0.1",
|
|
39
|
+
"node-fetch": "^3.3.2",
|
|
40
|
+
"pg": "^8.16.2",
|
|
41
|
+
"pg-promise": "^11.14.0",
|
|
42
|
+
"redis": "^5.5.6",
|
|
43
|
+
"serve-favicon": "^2.5.0",
|
|
44
|
+
"ws": "^8.18.3"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Client } from 'minio';
|
|
2
|
+
|
|
3
|
+
const minioClient = new Client({
|
|
4
|
+
endPoint: 'localhost',
|
|
5
|
+
port: 9000,
|
|
6
|
+
useSSL: false,
|
|
7
|
+
accessKey: 'admin',
|
|
8
|
+
secretKey: 'gacutils13#!',
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const uploadFile = async () => {
|
|
12
|
+
const bucketName = 'testupload';
|
|
13
|
+
const objectName = '123543/testfile.txt';
|
|
14
|
+
const filePath = './src/datalog.sql';
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
await minioClient.fPutObject(bucketName, objectName, filePath);
|
|
18
|
+
console.log(`✅ File '${objectName}' uploaded to '${bucketName}'`);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error('❌ Upload failed:', error);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
uploadFile();
|
package/src/api.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export default class Api {
|
|
2
|
+
#req
|
|
3
|
+
#res
|
|
4
|
+
#next
|
|
5
|
+
|
|
6
|
+
constructor(req, res, next) {
|
|
7
|
+
this.#req = req
|
|
8
|
+
this.#res = res
|
|
9
|
+
this.#next = next
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get req() { return this.#req }
|
|
13
|
+
get res() { return this.#res }
|
|
14
|
+
get next() { return this.#next }
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
static generateNotifierId(moduleName, str) {
|
|
18
|
+
return `${moduleName}-${str}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
static cekLogin(req) {
|
|
23
|
+
// jika req.session.user tidak ada datanya, berarti belum login
|
|
24
|
+
try {
|
|
25
|
+
if (req.session.user==null) {
|
|
26
|
+
throw new Error('belum login')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (req.session.user.isLogin==null) {
|
|
30
|
+
throw new Error('belum login')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (req.session.user.isLogin==false) {
|
|
34
|
+
throw new Error('belum login')
|
|
35
|
+
}
|
|
36
|
+
} catch (err) {
|
|
37
|
+
err.status = 401
|
|
38
|
+
throw err
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static parseUploadData(data, files) {
|
|
43
|
+
const jsonFieldName = 'form-body-jsondata'
|
|
44
|
+
try {
|
|
45
|
+
if (files!=undefined) {
|
|
46
|
+
// ambil json data
|
|
47
|
+
const jsondata = files.filter(file => file.fieldname==jsonFieldName)
|
|
48
|
+
const jsonstring = jsondata[0].buffer.toString('utf-8')
|
|
49
|
+
Object.assign(data, JSON.parse(jsonstring).data)
|
|
50
|
+
|
|
51
|
+
const filelist = files.filter(file => file.fieldname!=jsonFieldName)
|
|
52
|
+
return filelist
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return null
|
|
56
|
+
} catch (err) {
|
|
57
|
+
throw err
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async handleRequest(methodName, body) {
|
|
63
|
+
try {
|
|
64
|
+
if (typeof this[methodName] === 'function') {
|
|
65
|
+
const result = await this[methodName](body)
|
|
66
|
+
return result
|
|
67
|
+
} else {
|
|
68
|
+
const errNotFound = new Error(`Method "${methodName}" tidak ditemukan.`)
|
|
69
|
+
errNotFound.code = 404
|
|
70
|
+
throw errNotFound
|
|
71
|
+
}
|
|
72
|
+
} catch (err) {
|
|
73
|
+
throw err
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|