@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,218 @@
|
|
|
1
|
+
import { kebabToCamel, isFileExist, getSectionData } from './helper.js'
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs/promises'
|
|
5
|
+
import ejs from 'ejs'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export async function createApiModule(context, options) {
|
|
11
|
+
const overwrite = options.overwrite===true
|
|
12
|
+
const moduleName = context.moduleName
|
|
13
|
+
const title = context.title
|
|
14
|
+
const targetFile = path.join(context.apiDir, `${moduleName}.api.js`)
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// cek dulu apakah file ada
|
|
18
|
+
let fileExists = await isFileExist(targetFile)
|
|
19
|
+
if (fileExists && !overwrite) {
|
|
20
|
+
context.postMessage({message: `skip file: '${targetFile}`})
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// reporting progress to parent process
|
|
25
|
+
context.postMessage({message: `generating file: '${targetFile}`})
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// get header information
|
|
29
|
+
const entityHeader = context.entities['header']
|
|
30
|
+
const headerTableName = entityHeader.table
|
|
31
|
+
const headerPrimaryKey = entityHeader.pk
|
|
32
|
+
const headerSearchMap = createSearchMap(entityHeader.Search, entityHeader.Items, headerTableName)
|
|
33
|
+
const usesequencer = ['auto-yearly', 'auto-monthly'].includes(entityHeader.identifierMethod) ? true : false
|
|
34
|
+
|
|
35
|
+
const yearly = entityHeader.identifierMethod == 'auto-yearly' ? true : false
|
|
36
|
+
const identifierPrefix = entityHeader.identifierPrefix
|
|
37
|
+
const identifierBlock = entityHeader.identifierBlock
|
|
38
|
+
const identifierLength = entityHeader.identifierLength
|
|
39
|
+
const headerFieldsLookup = createLookup(entityHeader.Items)
|
|
40
|
+
|
|
41
|
+
// cek apakah di header ada file upload
|
|
42
|
+
let importbucket = false
|
|
43
|
+
let headerHasUpload = false
|
|
44
|
+
for (var fieldName in entityHeader.Items) {
|
|
45
|
+
const item = entityHeader.Items[fieldName]
|
|
46
|
+
const component = item.component
|
|
47
|
+
if (component=='Filebox') {
|
|
48
|
+
headerHasUpload = true
|
|
49
|
+
importbucket = true
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
// get detil information
|
|
56
|
+
const entitiesDetil = []
|
|
57
|
+
for (let entityName in context.entities) {
|
|
58
|
+
if (entityName=='header') {
|
|
59
|
+
continue
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const entity = context.entities[entityName]
|
|
63
|
+
|
|
64
|
+
let detilHasUpload
|
|
65
|
+
for (var fieldName in entity.Items) {
|
|
66
|
+
const item = entity.Items[fieldName]
|
|
67
|
+
const component = item.component
|
|
68
|
+
if (component=='Filebox') {
|
|
69
|
+
detilHasUpload = true
|
|
70
|
+
importbucket = true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const e = {
|
|
75
|
+
name: entityName,
|
|
76
|
+
table: entity.table,
|
|
77
|
+
pk: entity.pk,
|
|
78
|
+
detilHasUpload: detilHasUpload,
|
|
79
|
+
fieldsLookup: createLookup(entity.Items)
|
|
80
|
+
}
|
|
81
|
+
entitiesDetil.push(e)
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const usesequencerline = entityHeader.identifierMethod=='auto-yearly-short' || entitiesDetil.length>0 ? true : false
|
|
86
|
+
// const autoid = usesequencer || usesequencerline ? true : false
|
|
87
|
+
const autoid = ['auto-by-default', 'auto-always', 'auto-yearly', 'auto-monthly', 'auto-yearly-short'].includes(entityHeader.identifierMethod)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
const variables = {
|
|
91
|
+
timeGenerated: context.timeGenerated,
|
|
92
|
+
title: title,
|
|
93
|
+
moduleName: moduleName,
|
|
94
|
+
autoid,
|
|
95
|
+
usesequencer,
|
|
96
|
+
usesequencerline,
|
|
97
|
+
yearly,
|
|
98
|
+
identifierPrefix,
|
|
99
|
+
identifierBlock,
|
|
100
|
+
identifierLength,
|
|
101
|
+
headerTableName,
|
|
102
|
+
headerPrimaryKey,
|
|
103
|
+
headerSearchMap,
|
|
104
|
+
headerFieldsLookup,
|
|
105
|
+
headerHasUpload,
|
|
106
|
+
importbucket,
|
|
107
|
+
entitiesDetil
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
const tplFilePath = path.join(__dirname, 'templates', 'api-module.js.ejs')
|
|
112
|
+
const template = await fs.readFile(tplFilePath, 'utf-8');
|
|
113
|
+
const content = ejs.render(template, variables)
|
|
114
|
+
|
|
115
|
+
await fs.writeFile(targetFile, content, 'utf8');
|
|
116
|
+
} catch (err) {
|
|
117
|
+
throw err
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
function createSearchMap(searchdata, items, tablename) {
|
|
124
|
+
// searchtext: `user_fullname ILIKE '%' || \${searchtext} || '%' OR user_id=try_cast_bigint(\${searchtext}, 0)`,
|
|
125
|
+
// searchgroup: `group_id = \${searchgroup}`,
|
|
126
|
+
// user_isdisabled: `user_isdisabled = \${user_isdisabled}`
|
|
127
|
+
|
|
128
|
+
let searchtextExists = false
|
|
129
|
+
const searchMap = []
|
|
130
|
+
for (let searchname in searchdata) {
|
|
131
|
+
const search = searchdata[searchname]
|
|
132
|
+
const searchfield = parseSearchField(search.fields)
|
|
133
|
+
|
|
134
|
+
// harus ada 1 criteria searchtext
|
|
135
|
+
if (searchname=='searchtext') {
|
|
136
|
+
searchtextExists = true
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// cek tipe data dari masing-masing search field
|
|
140
|
+
const params = []
|
|
141
|
+
for (let fieldname in searchfield) {
|
|
142
|
+
const field = items[fieldname]
|
|
143
|
+
const search = searchfield[fieldname]
|
|
144
|
+
if (field===undefined) {
|
|
145
|
+
throw new Error(`parameter search '${searchname}' tidak mengacu pada design tabel '${tablename}' `)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const datatype = field.data_type
|
|
149
|
+
const hasPercent = search.hasPercent
|
|
150
|
+
|
|
151
|
+
let searchToken
|
|
152
|
+
if (datatype=='int') {
|
|
153
|
+
searchToken = `${fieldname}=try_cast_int(\\\${${searchname}}, 0)`
|
|
154
|
+
} else if (datatype=='bigint') {
|
|
155
|
+
searchToken = `${fieldname}=try_cast_bigint(\\\${${searchname}}, 0)`
|
|
156
|
+
} else {
|
|
157
|
+
if (hasPercent) {
|
|
158
|
+
searchToken = `${fieldname} ILIKE '%' || \\\${${searchname}} || '%'`
|
|
159
|
+
} else {
|
|
160
|
+
searchToken = `${fieldname} = \\\${${searchname}}`
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
params.push(searchToken)
|
|
164
|
+
}
|
|
165
|
+
const searchcriteria = params.join(' OR ')
|
|
166
|
+
|
|
167
|
+
searchMap.push({
|
|
168
|
+
name: searchname,
|
|
169
|
+
data: searchcriteria
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!searchtextExists) {
|
|
174
|
+
throw new Error(`search criteria untuk 'searchtext' belum dibuat`)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return searchMap
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function parseSearchField(rawFields) {
|
|
181
|
+
const parsedFields = rawFields
|
|
182
|
+
.split(',')
|
|
183
|
+
.map(field => field.trim())
|
|
184
|
+
.reduce((acc, field) => {
|
|
185
|
+
const hasPercent = field.startsWith('%');
|
|
186
|
+
const name = hasPercent ? field.slice(1) : field;
|
|
187
|
+
|
|
188
|
+
acc[name] = {
|
|
189
|
+
name,
|
|
190
|
+
hasPercent
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return acc;
|
|
194
|
+
}, {}
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
return parsedFields
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function createLookup(items) {
|
|
201
|
+
const lookup = []
|
|
202
|
+
for (let fieldname in items) {
|
|
203
|
+
const item = items[fieldname]
|
|
204
|
+
if (item.component=='Combobox') {
|
|
205
|
+
const {bindingValue, bindingText, bindingDisplay, table} = item.Reference
|
|
206
|
+
|
|
207
|
+
let displayField = bindingText
|
|
208
|
+
if (bindingDisplay!='' && bindingDisplay!=null) {
|
|
209
|
+
displayField = bindingDisplay
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
lookup.push({
|
|
213
|
+
fieldname, bindingValue, bindingText, bindingDisplay:displayField, table
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return lookup
|
|
218
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { isFileExist } from './helper.js'
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs/promises'
|
|
5
|
+
import ejs from 'ejs'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export async function createIcon(context, options) {
|
|
11
|
+
const rawData = context.icon
|
|
12
|
+
|
|
13
|
+
if (rawData=='' || rawData==null) {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const overwrite = options.overwrite===true
|
|
18
|
+
const moduleName = context.moduleName
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
|
|
22
|
+
const ext = detectImageType(rawData);
|
|
23
|
+
const targetFile = path.join(context.moduleDir, `${moduleName}.${ext}`)
|
|
24
|
+
const base64 = getBase64data(rawData, ext)
|
|
25
|
+
|
|
26
|
+
if (base64==null) {
|
|
27
|
+
throw new Error('data icon tidak di support, gunakan svg atau png')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const svgBuffer = Buffer.from(base64, 'base64');
|
|
31
|
+
await fs.writeFile(targetFile, svgBuffer, 'utf8');
|
|
32
|
+
|
|
33
|
+
return `${moduleName}.${ext}`
|
|
34
|
+
} catch (err) {
|
|
35
|
+
throw err
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
function detectImageType(dataUrl) {
|
|
41
|
+
const match = dataUrl.match(/^url\("data:(image\/[a-zA-Z0-9\+\.-]+);base64,/);
|
|
42
|
+
if (!match) return null;
|
|
43
|
+
const mime = match[1];
|
|
44
|
+
|
|
45
|
+
if (mime === 'image/png') return 'png';
|
|
46
|
+
if (mime === 'image/jpeg') return 'jpg';
|
|
47
|
+
if (mime === 'image/svg+xml') return 'svg';
|
|
48
|
+
return mime; // fallback: raw MIME
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
function getBase64data(rawData, ext) {
|
|
53
|
+
if (ext=='svg') {
|
|
54
|
+
return rawData.replace(/^url\("data:image\/svg\+xml;base64,/, '').replace(/"\)$/, '');
|
|
55
|
+
} else if (ext=='png') {
|
|
56
|
+
return rawData.replace(/^url\("data:image\/png;base64,/, '').replace(/"\)$/, '');
|
|
57
|
+
} else if (ext=='jpg') {
|
|
58
|
+
return rawData.replace(/^url\("data:image\/jpeg;base64,/, '').replace(/"\)$/, '');
|
|
59
|
+
} else {
|
|
60
|
+
return null
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { isFileExist } from './helper.js'
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs/promises'
|
|
5
|
+
import ejs from 'ejs'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export async function createInfoAboutExtender(context, options) {
|
|
11
|
+
const overwrite = options.overwrite===true
|
|
12
|
+
const moduleName = context.moduleName
|
|
13
|
+
const targetFile = path.join(context.moduleDir, `${moduleName}-ext-about.html`)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// cek dulu apakah file ada
|
|
18
|
+
var fileExists = await isFileExist(targetFile)
|
|
19
|
+
if (fileExists && !overwrite) {
|
|
20
|
+
context.postMessage({message: `skip file: '${targetFile}`})
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// reporting progress to parent process
|
|
25
|
+
context.postMessage({message: `generating file: '${targetFile}`})
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// start geneate program code
|
|
29
|
+
const variables = {
|
|
30
|
+
moduleName: moduleName
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const tplFilePath = path.join(__dirname, 'templates', 'module-ext-about.ejs')
|
|
35
|
+
const template = await fs.readFile(tplFilePath, 'utf-8');
|
|
36
|
+
const content = ejs.render(template, variables)
|
|
37
|
+
|
|
38
|
+
await fs.writeFile(targetFile, content, 'utf8');
|
|
39
|
+
} catch (err) {
|
|
40
|
+
throw err
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isFileExist } from './helper.js'
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs/promises'
|
|
5
|
+
import ejs from 'ejs'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export async function createInfoLogs(context, options) {
|
|
11
|
+
const overwrite = options.overwrite===true
|
|
12
|
+
const moduleName = context.moduleName
|
|
13
|
+
const targetFile = path.join(context.moduleDir, `${moduleName}-logs.html`)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// cek dulu apakah file ada
|
|
18
|
+
var fileExists = await isFileExist(targetFile)
|
|
19
|
+
if (fileExists && !overwrite) {
|
|
20
|
+
context.postMessage({message: `skip file: '${targetFile}`})
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// reporting progress to parent process
|
|
25
|
+
context.postMessage({message: `generating file: '${targetFile}`})
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// start geneate program code
|
|
29
|
+
const variables = {
|
|
30
|
+
moduleName: moduleName
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const tplFilePath = path.join(__dirname, 'templates', 'module-logs.ejs')
|
|
34
|
+
const template = await fs.readFile(tplFilePath, 'utf-8');
|
|
35
|
+
const content = ejs.render(template, variables)
|
|
36
|
+
|
|
37
|
+
await fs.writeFile(targetFile, content, 'utf8');
|
|
38
|
+
} catch (err) {
|
|
39
|
+
throw err
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isFileExist } from './helper.js'
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs/promises'
|
|
5
|
+
import ejs from 'ejs'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export async function createInfoRecordExtender(context, options) {
|
|
11
|
+
const overwrite = options.overwrite===true
|
|
12
|
+
const moduleName = context.moduleName
|
|
13
|
+
const targetFile = path.join(context.moduleDir, `${moduleName}-ext-record.html`)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// cek dulu apakah file ada
|
|
18
|
+
var fileExists = await isFileExist(targetFile)
|
|
19
|
+
if (fileExists && !overwrite) {
|
|
20
|
+
context.postMessage({message: `skip file: '${targetFile}`})
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// reporting progress to parent process
|
|
25
|
+
context.postMessage({message: `generating file: '${targetFile}`})
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// start geneate program code
|
|
29
|
+
const variables = {
|
|
30
|
+
moduleName: moduleName
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const tplFilePath = path.join(__dirname, 'templates', 'module-ext-record.ejs')
|
|
34
|
+
const template = await fs.readFile(tplFilePath, 'utf-8');
|
|
35
|
+
const content = ejs.render(template, variables)
|
|
36
|
+
|
|
37
|
+
await fs.writeFile(targetFile, content, 'utf8');
|
|
38
|
+
} catch (err) {
|
|
39
|
+
throw err
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { kebabToCamel, isFileExist, getSectionData } from './helper.js'
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs/promises'
|
|
5
|
+
import ejs from 'ejs'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export async function createModuleContext(context, options) {
|
|
11
|
+
const overwrite = options.overwrite===true
|
|
12
|
+
const moduleName = context.moduleName
|
|
13
|
+
const targetFile = path.join(context.moduleDir, `${moduleName}-context.mjs`)
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
// cek dulu apakah file ada
|
|
17
|
+
var fileExists = await isFileExist(targetFile)
|
|
18
|
+
if (fileExists && !overwrite) {
|
|
19
|
+
context.postMessage({message: `skip file: '${targetFile}`})
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// reporting progress to parent process
|
|
24
|
+
context.postMessage({message: `generating file: '${targetFile}`})
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// start geneate program code
|
|
28
|
+
let sections = []
|
|
29
|
+
for (var entityName in context.entities) {
|
|
30
|
+
sections.push(getSectionData(moduleName, entityName, context.entities[entityName], 'list'))
|
|
31
|
+
sections.push(getSectionData(moduleName, entityName, context.entities[entityName], 'edit'))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const variables = {
|
|
35
|
+
timeGenerated: context.timeGenerated,
|
|
36
|
+
moduleName: moduleName,
|
|
37
|
+
sections: sections
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const tplFilePath = path.join(__dirname, 'templates', 'module-context.ejs')
|
|
41
|
+
const template = await fs.readFile(tplFilePath, 'utf-8');
|
|
42
|
+
const content = ejs.render(template, variables)
|
|
43
|
+
|
|
44
|
+
await fs.writeFile(targetFile, content, 'utf8');
|
|
45
|
+
} catch (err) {
|
|
46
|
+
throw err
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { kebabToCamel, isFileExist, getSectionData, createAdditionalAttributes } from './helper.js'
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs/promises'
|
|
5
|
+
import ejs from 'ejs'
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export async function createModuleDetilEditHtml(context, options) {
|
|
11
|
+
const overwrite = options.overwrite===true
|
|
12
|
+
const moduleName = context.moduleName
|
|
13
|
+
const title = context.title
|
|
14
|
+
const sectionPart = 'edit'
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
for (let entityName in context.entities) {
|
|
18
|
+
// process selain header
|
|
19
|
+
if (entityName=='header') {
|
|
20
|
+
continue
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const sectionName = entityName
|
|
24
|
+
const modulePart = kebabToCamel(`${moduleName}-${sectionName}-${sectionPart}`)
|
|
25
|
+
const targetFile = path.join(context.moduleDir, `${modulePart}.html`)
|
|
26
|
+
|
|
27
|
+
// cek dulu apakah file ada
|
|
28
|
+
var fileExists = await isFileExist(targetFile)
|
|
29
|
+
if (fileExists && !overwrite) {
|
|
30
|
+
context.postMessage({message: `skip file: '${targetFile}`})
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
context.postMessage({message: `generating file: '${targetFile}`}) // reporting progress to parent process
|
|
34
|
+
|
|
35
|
+
// start geneate program code
|
|
36
|
+
const entityData = context.entities[entityName]
|
|
37
|
+
const sectionData = getSectionData(moduleName, entityName, entityData, 'edit')
|
|
38
|
+
const primaryKeyFieldData = entityData.Items[sectionData.primaryKey]
|
|
39
|
+
const primaryKeyName = primaryKeyFieldData.input_name
|
|
40
|
+
const primaryKeyElementId = `${modulePart}-${primaryKeyName}`
|
|
41
|
+
|
|
42
|
+
const autoid = true // untuk detil, pasti autoid
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
// ambil data field header
|
|
46
|
+
const fields = []
|
|
47
|
+
let index = 0
|
|
48
|
+
for (var fieldName in entityData.Items) {
|
|
49
|
+
const item = entityData.Items[fieldName]
|
|
50
|
+
index++
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
item.index = index
|
|
54
|
+
// if (item.data_fieldname=='grouptype_id') {
|
|
55
|
+
// console.log(item)
|
|
56
|
+
// }
|
|
57
|
+
|
|
58
|
+
if (!item.showInForm) {
|
|
59
|
+
continue
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const component = item.component
|
|
63
|
+
const fieldname = item.data_fieldname
|
|
64
|
+
const elementId = `${modulePart}-${item.input_name}`
|
|
65
|
+
const placeholder = item.input_placeholder
|
|
66
|
+
const label = item.input_label
|
|
67
|
+
const tabindex = item.input_index
|
|
68
|
+
const binding = item.data_fieldname
|
|
69
|
+
const additionalAttributes = createAdditionalAttributes(item)
|
|
70
|
+
const cssContainer = item.input_containercss.trim() == '' ? 'input-field' : `input-field ${item.input_containercss.trim()}`
|
|
71
|
+
|
|
72
|
+
fields.push({
|
|
73
|
+
component,
|
|
74
|
+
cssContainer,
|
|
75
|
+
fieldname,
|
|
76
|
+
elementId,
|
|
77
|
+
placeholder,
|
|
78
|
+
label,
|
|
79
|
+
tabindex,
|
|
80
|
+
binding,
|
|
81
|
+
additionalAttributes
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
const variables = {
|
|
88
|
+
timeGenerated: context.timeGenerated,
|
|
89
|
+
title: title,
|
|
90
|
+
moduleName: moduleName,
|
|
91
|
+
modulePart: modulePart,
|
|
92
|
+
moduleSection: kebabToCamel(`${moduleName}-${sectionName}`),
|
|
93
|
+
section: sectionData,
|
|
94
|
+
autoid,
|
|
95
|
+
primaryKeyElementId: primaryKeyElementId,
|
|
96
|
+
fields: fields,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const tplFilePath = path.join(__dirname, 'templates', 'moduleDetilEdit.html.ejs')
|
|
100
|
+
const template = await fs.readFile(tplFilePath, 'utf-8');
|
|
101
|
+
const content = ejs.render(template, variables)
|
|
102
|
+
|
|
103
|
+
await fs.writeFile(targetFile, content, 'utf8');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
} catch (err) {
|
|
107
|
+
throw err
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
}
|