@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,16 @@
|
|
|
1
|
+
const app = new $fgta5.Application('mainapp')
|
|
2
|
+
const urlDir = 'public/modules/<%=moduleName%>'
|
|
3
|
+
const Crsl = new $fgta5.SectionCarousell(app.Nodes.Main)
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
moduleName: '<%=moduleName%>',
|
|
7
|
+
app: app,
|
|
8
|
+
urlDir: urlDir,
|
|
9
|
+
Crsl: Crsl,
|
|
10
|
+
Sections: { <% sections.forEach(section => { %>
|
|
11
|
+
<%= section.sectionName %>: '<%= section.sectionElementId %>', <% }) %>
|
|
12
|
+
},
|
|
13
|
+
SectionMap: { <% sections.forEach(section => { %>
|
|
14
|
+
'<%= section.sectionElementId %>' : '<%= section.sectionName %>', <% }) %>
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!-- about text here -->
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!-- tambahan informasi record, misalnya postby commitby, dlll -->
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Context from './<%=moduleName%>-context.mjs'
|
|
2
|
+
|
|
3
|
+
export async function init(self, args) {
|
|
4
|
+
console.log('initializing <%=moduleName%>Extender ...')
|
|
5
|
+
|
|
6
|
+
// tambahkan extender inisiasi module <%=moduleName%>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/* // contoh menambahkan content dari template extender
|
|
10
|
+
{
|
|
11
|
+
const target = secRec.querySelector('#fRecord-section div[name="column"][exteder]')
|
|
12
|
+
const tpl = document.querySelector('template[name="record-panel"]')
|
|
13
|
+
if (tpl!=null) {
|
|
14
|
+
const clone = tpl.content.cloneNode(true); // salin isi template
|
|
15
|
+
target.prepend(clone)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
*/
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<table cellpadding="0" cellspacing="0">
|
|
2
|
+
<thead>
|
|
3
|
+
<tr>
|
|
4
|
+
<td class="logheader">Date Time</td>
|
|
5
|
+
<td class="logheader">User</td>
|
|
6
|
+
<td class="logheader">Action</td>
|
|
7
|
+
<td class="logheader">IP</td>
|
|
8
|
+
<td class="logheader">Remark</td>
|
|
9
|
+
</tr>
|
|
10
|
+
</thead>
|
|
11
|
+
<tbody>
|
|
12
|
+
|
|
13
|
+
</tbody>
|
|
14
|
+
</table>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<% sections.forEach(section => { %><section id="<%= section.sectionElementId %>" class="fgta5-carousell" data-title="<%= section.sectionTitle %>">
|
|
2
|
+
<%- '<' %>%- include(`${moduleDir}/<%= section.sectionName %>.html`) %<%- '>' %>
|
|
3
|
+
</section>
|
|
4
|
+
|
|
5
|
+
<% }) %>
|
|
6
|
+
|
|
7
|
+
<section id="fRecord-section" class="fgta5-carousell" data-title="Record Status">
|
|
8
|
+
<div name="panel">
|
|
9
|
+
|
|
10
|
+
<!-- LEFT: Standard Info -->
|
|
11
|
+
<div name="column">
|
|
12
|
+
<div name="row">
|
|
13
|
+
<span name="caption">Create By</span>
|
|
14
|
+
<span name="value" id="fRecord-section-createby">-</span>
|
|
15
|
+
</div>
|
|
16
|
+
<div name="row">
|
|
17
|
+
<span name="caption">Create Date</span>
|
|
18
|
+
<span name="value" id="fRecord-section-createdate">-</span>
|
|
19
|
+
</div>
|
|
20
|
+
<div name="row">
|
|
21
|
+
<span name="caption">Modify By</span>
|
|
22
|
+
<span name="value" id="fRecord-section-modifyby">-</span>
|
|
23
|
+
</div>
|
|
24
|
+
<div name="row">
|
|
25
|
+
<span name="caption">Modify Date</span>
|
|
26
|
+
<span name="value"id="fRecord-section-modifydate">-</span>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<!-- RIGHT: Extended Info -->
|
|
33
|
+
<div name="column" exteder>
|
|
34
|
+
<%- '<' %>%- include(`${moduleDir}/<%= moduleName %>-ext-record.html`) %<%- '>' %>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
</div>
|
|
38
|
+
</section>
|
|
39
|
+
|
|
40
|
+
<section id="fLogs-section" class="fgta5-carousell" data-title="Logs">
|
|
41
|
+
<%- '<' %>%- include(`${moduleDir}/<%= moduleName %>-logs.html`) %<%- '>' %>
|
|
42
|
+
</section>
|
|
43
|
+
|
|
44
|
+
<section id="fAbout-section" class="fgta5-carousell" data-title="About">
|
|
45
|
+
<%- '<' %>%- include(`${moduleDir}/<%= moduleName %>-ext-about.html`) %<%- '>' %>
|
|
46
|
+
</section>
|
|
47
|
+
|
|
48
|
+
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import Context from './<%= moduleName %>-context.mjs' <% sections.forEach(section => { %>
|
|
2
|
+
import * as <%= section.sectionName %> from './<%= section.sectionName %>.mjs' <% }) %>
|
|
3
|
+
import * as Extender from './<%= moduleName %>-ext.mjs'
|
|
4
|
+
|
|
5
|
+
const app = Context.app
|
|
6
|
+
const Crsl = Context.Crsl
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export default class extends Module {
|
|
10
|
+
constructor() {
|
|
11
|
+
super()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async main(args={}) {
|
|
15
|
+
|
|
16
|
+
console.log('initializing module...')
|
|
17
|
+
app.setTitle('<%= title %>')
|
|
18
|
+
app.showFooter(true)
|
|
19
|
+
|
|
20
|
+
args.autoLoadGridData = true
|
|
21
|
+
|
|
22
|
+
const self = this
|
|
23
|
+
|
|
24
|
+
// module-module yang di load perlu di pack dulu ke dalam variable
|
|
25
|
+
// jangan import lagi module-module ini di dalam mjs tersebut
|
|
26
|
+
// karena akan terjadi cyclic redudancy pada saat di rollup
|
|
27
|
+
self.Modules = { <% sections.forEach(section => { %>
|
|
28
|
+
<%= section.sectionName %>, <% }) %>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
|
|
33
|
+
// inisiasi sisi server
|
|
34
|
+
try {
|
|
35
|
+
const result = await Module.apiCall(`/${Context.moduleName}/init`, { })
|
|
36
|
+
Context.notifierId = result.notifierId
|
|
37
|
+
Context.notifierSocket = result.notifierSocket
|
|
38
|
+
Context.userId = result.userId
|
|
39
|
+
Context.userFullname = result.userFullname
|
|
40
|
+
Context.sid = result.sid
|
|
41
|
+
Context.appsUrls = result.appsUrls
|
|
42
|
+
} catch (err) {
|
|
43
|
+
throw err
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
await Promise.all([ <% sections.forEach(section => { %>
|
|
47
|
+
<%= section.sectionName %>.init(self, args), <% }) %>
|
|
48
|
+
Extender.init(self, args)
|
|
49
|
+
])
|
|
50
|
+
|
|
51
|
+
// render dan setup halaman
|
|
52
|
+
await render(self)
|
|
53
|
+
|
|
54
|
+
// listen keyboard action
|
|
55
|
+
listenUserKeys(self)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
// kalau user melakukan reload, konfirm dulu
|
|
59
|
+
const modNameList = [<%- entityNameList %>]
|
|
60
|
+
window.onbeforeunload = (evt)=>{
|
|
61
|
+
// cek dulu semua form
|
|
62
|
+
let isFormDirty = false
|
|
63
|
+
for (var modname of modNameList) {
|
|
64
|
+
const module = self.Modules[modname]
|
|
65
|
+
const frm = module.getForm(self)
|
|
66
|
+
if (frm.isChanged()) {
|
|
67
|
+
isFormDirty = isFormDirty || true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (isFormDirty) {
|
|
71
|
+
evt.preventDefault();
|
|
72
|
+
return "Changes you made may not be saved."
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
} catch (err) {
|
|
78
|
+
throw err
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function render(self) {
|
|
85
|
+
try {
|
|
86
|
+
const footerButtonsContainer = document.getElementsByClassName('footer-buttons-container')
|
|
87
|
+
Module.renderFooterButtons(footerButtonsContainer)
|
|
88
|
+
|
|
89
|
+
// Setup Icon
|
|
90
|
+
Crsl.setIconUrl('<%= iconUrl %>')
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
// Set listener untuk section carousel
|
|
94
|
+
Crsl.addEventListener($fgta5.SectionCarousell.EVT_SECTIONSHOWING, (evt)=>{
|
|
95
|
+
var sectionId = evt.detail.commingSection.Id
|
|
96
|
+
for (let cont of footerButtonsContainer) {
|
|
97
|
+
var currContainerSectionId = cont.getAttribute('data-section')
|
|
98
|
+
if (currContainerSectionId==sectionId) {
|
|
99
|
+
setTimeout(()=>{
|
|
100
|
+
cont.classList.remove('hidden')
|
|
101
|
+
cont.style.animation = 'dropped 0.3s forwards'
|
|
102
|
+
setTimeout(()=>{
|
|
103
|
+
cont.style.animation = 'unset'
|
|
104
|
+
}, 300)
|
|
105
|
+
}, 500)
|
|
106
|
+
} else {
|
|
107
|
+
cont.classList.add('hidden')
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
Crsl.Items['fRecord-section'].addEventListener($fgta5.Section.EVT_BACKBUTTONCLICK, async (evt)=>{
|
|
113
|
+
evt.detail.fn_ShowNextSection()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
Crsl.Items['fLogs-section'].addEventListener($fgta5.Section.EVT_BACKBUTTONCLICK, async (evt)=>{
|
|
117
|
+
evt.detail.fn_ShowNextSection()
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
Crsl.Items['fAbout-section'].addEventListener($fgta5.Section.EVT_BACKBUTTONCLICK, async (evt)=>{
|
|
121
|
+
evt.detail.fn_ShowNextSection()
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
// Set panel detil saat hover di detil item
|
|
126
|
+
const detilpanel = document.getElementById('panel-detil-selector')
|
|
127
|
+
detilpanel.querySelectorAll('.panel-detil-row a').forEach(link => {
|
|
128
|
+
link.addEventListener('mouseenter', () => {
|
|
129
|
+
link.closest('.panel-detil-row').classList.add('panel-detil-row-highligted');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
link.addEventListener('mouseleave', () => {
|
|
133
|
+
link.closest('.panel-detil-row').classList.remove('panel-detil-row-highligted');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
const sectionTargetName = link.getAttribute('data-target-section')
|
|
138
|
+
const sectionCurrentName = link.getAttribute('data-current-section')
|
|
139
|
+
|
|
140
|
+
link.addEventListener('click', (evt)=>{
|
|
141
|
+
openDetilSection(self, sectionTargetName, sectionCurrentName)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// jika ada event-event yang khusus untuk mobile device
|
|
145
|
+
// if (Module.isMobileDevice()) {
|
|
146
|
+
// }
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
// <%= moduleName %>-ext.mjs, export function extendPage(self) {}
|
|
151
|
+
const fn_name = 'extendPage'
|
|
152
|
+
const fn_extendPage = Extender[fn_name]
|
|
153
|
+
if (typeof fn_extendPage === 'function') {
|
|
154
|
+
fn_extendPage(self)
|
|
155
|
+
} else {
|
|
156
|
+
console.warn(`'extendPage' tidak diimplementasikan di extender`)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
} catch (err) {
|
|
160
|
+
throw err
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
function openDetilSection(self, sectionTargetName, sectionCurrentName) {
|
|
166
|
+
const sectionCurrentId = Context.Sections[sectionCurrentName]
|
|
167
|
+
const sectionCurrent = Crsl.Items[sectionCurrentId]
|
|
168
|
+
|
|
169
|
+
const sectionId = Context.Sections[sectionTargetName]
|
|
170
|
+
const section = Crsl.Items[sectionId]
|
|
171
|
+
|
|
172
|
+
section.setSectionReturn(sectionCurrent)
|
|
173
|
+
section.show({}, ()=>{
|
|
174
|
+
const moduleTarget = self.Modules[sectionTargetName]
|
|
175
|
+
const moduleHeaderEdit = self.Modules[sectionCurrentName]
|
|
176
|
+
moduleTarget.openList(self, {
|
|
177
|
+
moduleHeaderEdit
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
function listenUserKeys(self) {
|
|
184
|
+
|
|
185
|
+
// capture tombol
|
|
186
|
+
const allowedKeys = /^[a-zA-Z0-9 ]$/; // huruf, angka, spasi
|
|
187
|
+
document.addEventListener('keydown', (evt) => {
|
|
188
|
+
if (evt.ctrlKey || evt.metaKey || evt.altKey) {
|
|
189
|
+
// bebaskan jika tekan Ctrl / alt
|
|
190
|
+
} else if (allowedKeys.test(evt.key) || evt.key === 'Backspace' || evt.key === 'Delete') {
|
|
191
|
+
// Tangani huruf, angka, spasi, backspace dan delete
|
|
192
|
+
const id = Crsl.CurrentSection.Id
|
|
193
|
+
const moduleId = Context.SectionMap[id]
|
|
194
|
+
const module = self.Modules[moduleId]
|
|
195
|
+
keyboardAction(self, module, 'typing', evt)
|
|
196
|
+
}
|
|
197
|
+
}, true)
|
|
198
|
+
|
|
199
|
+
// handle keyboard event
|
|
200
|
+
document.addEventListener('keydown', (evt) => {
|
|
201
|
+
const id = Crsl.CurrentSection.Id
|
|
202
|
+
const moduleId = Context.SectionMap[id]
|
|
203
|
+
const module = self.Modules[moduleId]
|
|
204
|
+
|
|
205
|
+
// jika ada dialog yang terbuka, semua event keyboard abaikan dulu, keculai tombol escape
|
|
206
|
+
const dialog = document.querySelector('dialog[open]');
|
|
207
|
+
if (dialog) {
|
|
208
|
+
if (evt.key.toLowerCase()=='escape') {
|
|
209
|
+
dialog.close();
|
|
210
|
+
evt.preventDefault();
|
|
211
|
+
} else if ((evt.ctrlKey || evt.metaKey) && evt.key.toLowerCase() === 's') {
|
|
212
|
+
evt.preventDefault();
|
|
213
|
+
}
|
|
214
|
+
return
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Cek apakah tombol Ctrl (atau Cmd di Mac) ditekan bersamaan dengan huruf 'S'
|
|
218
|
+
const key = evt.key.toLowerCase()
|
|
219
|
+
if ((evt.ctrlKey || evt.metaKey) && key === 's') {
|
|
220
|
+
evt.preventDefault(); // Mencegah aksi default (save page)
|
|
221
|
+
keyboardAction(self, module, 'save', evt)
|
|
222
|
+
} else if (((evt.ctrlKey || evt.metaKey) && key === 'n') || (evt.ctrlKey && key==='f2')) {
|
|
223
|
+
evt.preventDefault(); // Mencegah aksi default
|
|
224
|
+
keyboardAction(self, module, 'new', evt)
|
|
225
|
+
} else if ( key ==='escape') {
|
|
226
|
+
evt.preventDefault();
|
|
227
|
+
keyboardAction(self, module, 'escape', evt)
|
|
228
|
+
} else if ( key === 'f2' ) {
|
|
229
|
+
keyboardAction(self, module, 'togleEdit', evt)
|
|
230
|
+
} else if ( key === 'arrowup' ) {
|
|
231
|
+
keyboardAction(self, module, 'up', evt)
|
|
232
|
+
} else if ( key === 'arrowdown' ) {
|
|
233
|
+
keyboardAction(self, module, 'down', evt)
|
|
234
|
+
} else if ( key === 'arrowright' ) {
|
|
235
|
+
keyboardAction(self, module, 'right', evt)
|
|
236
|
+
} else if ( key === 'arrowleft' ) {
|
|
237
|
+
keyboardAction(self, module, 'left', evt)
|
|
238
|
+
} else if ( key === 'enter' ) {
|
|
239
|
+
keyboardAction(self, module, 'enter', evt)
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
function keyboardAction(self, module, actionName, evt) {
|
|
246
|
+
|
|
247
|
+
if (module!=null) {
|
|
248
|
+
module.keyboardAction(self, actionName, evt)
|
|
249
|
+
} else {
|
|
250
|
+
// untuk keperluan log dan about, saat escape: back
|
|
251
|
+
if (actionName=='escape') {
|
|
252
|
+
Crsl.CurrentSection.back()
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
<div class="panel-recordbar" data-view="nodetil">
|
|
15
|
+
<div><a id="<%= moduleSection %>-btn_recordstatus" href="javascript:void(0)" tabindex="-1">Record Status</a></div>
|
|
16
|
+
<div><a id="<%= moduleSection %>-btn_logs" href="javascript:void(0)" tabindex="-1">Logs</a></div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
<div class="footer-buttons-container hidden">
|
|
21
|
+
<div>
|
|
22
|
+
<button id="<%= modulePart %>-btn_prev"><span>««</span></button>
|
|
23
|
+
</div>
|
|
24
|
+
<div>
|
|
25
|
+
<button id="<%= modulePart %>-btn_save">Save</button>
|
|
26
|
+
<button id="<%= modulePart %>-btn_edit">Edit</button>
|
|
27
|
+
<button id="<%= modulePart %>-btn_new" data-action="<%= moduleSection %>-addrow">New</button>
|
|
28
|
+
<button id="<%= modulePart %>-btn_reset">Reset</button>
|
|
29
|
+
<button id="<%= modulePart %>-btn_delete">Delete</button>
|
|
30
|
+
</div>
|
|
31
|
+
<div>
|
|
32
|
+
<button id="<%= modulePart %>-btn_next"><span>»»</span></button>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|