zet-lib 3.1.5 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Model.js +10 -24
- package/lib/generatorApi.js +242 -375
- package/lib/generatorModel.js +10 -0
- package/lib/views/generatorjs.ejs +69 -0
- package/lib/zAppRouter.js +86 -0
- package/lib/zGeneratorRouter.js +1 -22
- package/lib/zRoute.js +239 -90
- package/package.json +1 -1
- package/lib/routes/api.js +0 -52
- package/lib/routes/index.js +0 -9
|
@@ -189,6 +189,75 @@
|
|
|
189
189
|
html += `</ul>`
|
|
190
190
|
return html
|
|
191
191
|
}
|
|
192
|
+
function deleteTab($this) {
|
|
193
|
+
// Dapatkan index tab dari tombol edit yang ada di sebelah tombol delete
|
|
194
|
+
let $editBtn = $($this).siblings('.edittab');
|
|
195
|
+
let tabIndex = $editBtn.data('id');
|
|
196
|
+
|
|
197
|
+
// Jika tidak ada data-id, cari dari posisi tab dalam list
|
|
198
|
+
if (tabIndex === undefined || tabIndex === null) {
|
|
199
|
+
let $tabItem = $($this).closest('li.item');
|
|
200
|
+
let $allTabs = $('#tabs li.item');
|
|
201
|
+
tabIndex = $allTabs.index($tabItem);
|
|
202
|
+
|
|
203
|
+
// Jika masih tidak ditemukan, coba cari dari nama tab
|
|
204
|
+
if (tabIndex < 0) {
|
|
205
|
+
let tabName = $($this).siblings('.tabname').text().trim();
|
|
206
|
+
$allTabs.each(function(index) {
|
|
207
|
+
if ($(this).find('.tabname').text().trim() === tabName) {
|
|
208
|
+
tabIndex = index;
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Cek apakah tab memiliki konten di dalam tab content
|
|
216
|
+
let $tabContent = $('#tabgo' + tabIndex);
|
|
217
|
+
if ($tabContent.length === 0) {
|
|
218
|
+
// Jika tidak ada tab content, mungkin tab belum dibuat atau sudah dihapus
|
|
219
|
+
$($this).closest('li.item').remove();
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Cek di LEFT, RIGHT, dan ONE_COLUMN untuk tab ini
|
|
224
|
+
// Cari semua ol dengan id yang sesuai di dalam tab content
|
|
225
|
+
let $allBoxes = $tabContent.find('ol[id="arr' + tabIndex + '"]');
|
|
226
|
+
|
|
227
|
+
// Fungsi untuk cek apakah ol memiliki konten yang valid (bukan hanya icon add-container)
|
|
228
|
+
function hasValidContent($ol) {
|
|
229
|
+
if (!$ol || $ol.length === 0) return false;
|
|
230
|
+
|
|
231
|
+
// Cek apakah ada input-group (field) di dalam ol ini
|
|
232
|
+
// Ini akan menangkap semua field baik yang langsung di dalam ol maupun di dalam container
|
|
233
|
+
let $fields = $ol.find('.input-group');
|
|
234
|
+
|
|
235
|
+
// Jika ada field, berarti ada konten
|
|
236
|
+
if ($fields.length > 0) {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Cek apakah ada konten di salah satu box
|
|
244
|
+
let hasContent = false;
|
|
245
|
+
$allBoxes.each(function() {
|
|
246
|
+
if (hasValidContent($(this))) {
|
|
247
|
+
hasContent = true;
|
|
248
|
+
return false; // break loop
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Jika ada konten, tampilkan alert dan jangan hapus
|
|
253
|
+
if (hasContent) {
|
|
254
|
+
alert('Tab tidak dapat dihapus karena masih memiliki field. Silakan hapus semua field terlebih dahulu.');
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Jika tidak ada konten, hapus tab
|
|
259
|
+
$($this).closest('li.item').remove();
|
|
260
|
+
}
|
|
192
261
|
|
|
193
262
|
$(function () {
|
|
194
263
|
let counter = $('.divtabs').length || 1
|
package/lib/zAppRouter.js
CHANGED
|
@@ -2269,4 +2269,90 @@ router.post("/zcompress-dropbox", async (req, res) => {
|
|
|
2269
2269
|
res.json(Util.jsonSuccess("Compress all images completed..."));
|
|
2270
2270
|
});
|
|
2271
2271
|
|
|
2272
|
+
router.post('/zcall-information_info', async(req,res) => {
|
|
2273
|
+
let data = ''
|
|
2274
|
+
try {
|
|
2275
|
+
const {table, elementId, myvalue} = req.body;
|
|
2276
|
+
let content = Util.readFile(`${dirRoot}/public/runtime/info/${table}/${elementId}.txt`)
|
|
2277
|
+
data = content;
|
|
2278
|
+
|
|
2279
|
+
// Fungsi untuk mengekstrak semua field dari template
|
|
2280
|
+
const extractFields = (template) => {
|
|
2281
|
+
const regex = /\{\{([^}]+)\}\}/g;
|
|
2282
|
+
const fields = [];
|
|
2283
|
+
let match;
|
|
2284
|
+
while ((match = regex.exec(template)) !== null) {
|
|
2285
|
+
fields.push(match[1].trim());
|
|
2286
|
+
}
|
|
2287
|
+
return [...new Set(fields)]; // Remove duplicates
|
|
2288
|
+
};
|
|
2289
|
+
|
|
2290
|
+
if(content){
|
|
2291
|
+
let others = {}
|
|
2292
|
+
const MYMODELS = myCache.get("MYMODELS");
|
|
2293
|
+
let mymodel = MYMODELS[table];
|
|
2294
|
+
let mytable = mymodel.widgets[elementId].table;
|
|
2295
|
+
//console.log(mymodel);
|
|
2296
|
+
const result = await connection.result({
|
|
2297
|
+
table: mytable,
|
|
2298
|
+
where: {
|
|
2299
|
+
id: myvalue,
|
|
2300
|
+
},
|
|
2301
|
+
});
|
|
2302
|
+
//others = Object.assign({}, result);
|
|
2303
|
+
let fields = extractFields(content);
|
|
2304
|
+
fields.map((item) => {
|
|
2305
|
+
if(item.includes(".")){
|
|
2306
|
+
let name = item.split(".")[0];
|
|
2307
|
+
others[name] = {};
|
|
2308
|
+
}
|
|
2309
|
+
})
|
|
2310
|
+
|
|
2311
|
+
for(let key in others){
|
|
2312
|
+
let modelkey = MYMODELS[mytable].widgets[key].table;
|
|
2313
|
+
const resultkey = await connection.result({
|
|
2314
|
+
table: modelkey,
|
|
2315
|
+
where: {
|
|
2316
|
+
id: result[key],
|
|
2317
|
+
},
|
|
2318
|
+
});
|
|
2319
|
+
others[key] = resultkey;
|
|
2320
|
+
///disini saya ingin replace content dengan format {{}}
|
|
2321
|
+
//data = data.replace(`{{${key}}}`, resultkey[key]);
|
|
2322
|
+
|
|
2323
|
+
}
|
|
2324
|
+
let dataReplace = result;
|
|
2325
|
+
for(let key in others){
|
|
2326
|
+
dataReplace[key] = others[key];
|
|
2327
|
+
}
|
|
2328
|
+
console.log(dataReplace);
|
|
2329
|
+
|
|
2330
|
+
//saya ingin replace data dengan dataReplace
|
|
2331
|
+
// Fungsi untuk mendapatkan nilai dari path nested object
|
|
2332
|
+
const getNestedValue = (obj, path) => {
|
|
2333
|
+
const keys = path.split('.');
|
|
2334
|
+
let value = obj;
|
|
2335
|
+
for (const key of keys) {
|
|
2336
|
+
if (value && typeof value === 'object' && key in value) {
|
|
2337
|
+
value = value[key];
|
|
2338
|
+
} else {
|
|
2339
|
+
return ''; // Return empty string if path not found
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
return value !== null && value !== undefined ? String(value) : '';
|
|
2343
|
+
};
|
|
2344
|
+
|
|
2345
|
+
// Replace semua placeholder {{field}} dengan nilai dari dataReplace
|
|
2346
|
+
data = content.replace(/\{\{([^}]+)\}\}/g, (match, fieldPath) => {
|
|
2347
|
+
const trimmedPath = fieldPath.trim();
|
|
2348
|
+
return getNestedValue(dataReplace, trimmedPath);
|
|
2349
|
+
});
|
|
2350
|
+
|
|
2351
|
+
}
|
|
2352
|
+
} catch (e) {
|
|
2353
|
+
console.log(e)
|
|
2354
|
+
}
|
|
2355
|
+
res.json(data)
|
|
2356
|
+
})
|
|
2357
|
+
|
|
2272
2358
|
module.exports = router;
|
package/lib/zGeneratorRouter.js
CHANGED
|
@@ -169,20 +169,7 @@ router.post("/fields", async (req, res) => {
|
|
|
169
169
|
rowsFields: rowsFields,
|
|
170
170
|
table: table,
|
|
171
171
|
};
|
|
172
|
-
|
|
173
|
-
`${generatorUrl}/api/generator/modal`,
|
|
174
|
-
objData
|
|
175
|
-
); */
|
|
176
|
-
let others = result.others || {};
|
|
177
|
-
let othersArr = Object.keys(others) || [];
|
|
178
|
-
let json = {}
|
|
179
|
-
if(othersArr.length) {
|
|
180
|
-
console.log('masuk ke container')
|
|
181
|
-
json = await Api.modalWithContainer(objData);
|
|
182
|
-
} else {
|
|
183
|
-
json = await Api.modalClassic(objData);
|
|
184
|
-
}
|
|
185
|
-
|
|
172
|
+
let json = await Api.modal(objData);
|
|
186
173
|
res.json(json);
|
|
187
174
|
} catch (e) {
|
|
188
175
|
console.log(e);
|
|
@@ -195,10 +182,6 @@ Create new Module/Table
|
|
|
195
182
|
*/
|
|
196
183
|
router.post("/", csrfProtection, async (req, res) => {
|
|
197
184
|
try {
|
|
198
|
-
/* let results = await axios.post(
|
|
199
|
-
`${generatorUrl}/api/generator/create`,
|
|
200
|
-
req.body
|
|
201
|
-
); */
|
|
202
185
|
let body = req.body;
|
|
203
186
|
let datas = Api.createTable(body);
|
|
204
187
|
if (datas.status == 0) {
|
|
@@ -227,10 +210,6 @@ router.post("/reset", async (req, res) => {
|
|
|
227
210
|
return res.json(Util.flashError("Table is locked"));
|
|
228
211
|
}
|
|
229
212
|
if (table) {
|
|
230
|
-
/* let results = await axios.post(
|
|
231
|
-
`${generatorUrl}/api/generator/reset`,
|
|
232
|
-
req.body
|
|
233
|
-
); */
|
|
234
213
|
let body = req.body;
|
|
235
214
|
let datas = Api.reset(body);
|
|
236
215
|
//let datas = results.data;
|
package/lib/zRoute.js
CHANGED
|
@@ -4175,6 +4175,8 @@ zRoute.generateJS = (req, res, MYMODEL, relations, zForms = "", data = {}) => {
|
|
|
4175
4175
|
let joinsFields = [];
|
|
4176
4176
|
let selectize = [];
|
|
4177
4177
|
let moneys = [];
|
|
4178
|
+
let hasRelationInfo = false;
|
|
4179
|
+
let relationInfos = [];
|
|
4178
4180
|
if (MYMODEL.joins) {
|
|
4179
4181
|
joinsFields = MYMODEL.joins.list;
|
|
4180
4182
|
}
|
|
@@ -4267,6 +4269,11 @@ zRoute.generateJS = (req, res, MYMODEL, relations, zForms = "", data = {}) => {
|
|
|
4267
4269
|
selectize.push(key);
|
|
4268
4270
|
hasSelectize = true;
|
|
4269
4271
|
}
|
|
4272
|
+
if (widgets[key].relation_info) {
|
|
4273
|
+
hasRelationInfo = true;
|
|
4274
|
+
relationInfos.push(key);
|
|
4275
|
+
}
|
|
4276
|
+
|
|
4270
4277
|
}
|
|
4271
4278
|
}
|
|
4272
4279
|
}
|
|
@@ -4276,6 +4283,27 @@ zRoute.generateJS = (req, res, MYMODEL, relations, zForms = "", data = {}) => {
|
|
|
4276
4283
|
headObj.datepicker = datePickerObj.head;
|
|
4277
4284
|
endObj.datepicker = datePickerObj.end;
|
|
4278
4285
|
}
|
|
4286
|
+
if(hasRelationInfo){
|
|
4287
|
+
scriptForm += `function callRelationInfo(table, elementId, myvalue) {
|
|
4288
|
+
ajaxPost('/zcall-information_info',{table: table, elementId: elementId, myvalue: myvalue}, function (data) {
|
|
4289
|
+
let elemclass = 'information_' + elementId;
|
|
4290
|
+
if($("."+elemclass).length > 0){
|
|
4291
|
+
$("."+elemclass).html(data);
|
|
4292
|
+
} else {
|
|
4293
|
+
$(".div"+elementId).append('<div class="' + elemclass + ' mt-2 boxy">' + data + '</div>');
|
|
4294
|
+
}
|
|
4295
|
+
})
|
|
4296
|
+
} \r\n`
|
|
4297
|
+
let infoScript = '';
|
|
4298
|
+
relationInfos.map((relationInfo) => {
|
|
4299
|
+
infoScript += `$("#${relationInfo}").on('change', function () {
|
|
4300
|
+
callRelationInfo('${MYMODEL.table}','${relationInfo}', $(this).val())
|
|
4301
|
+
})
|
|
4302
|
+
callRelationInfo('${MYMODEL.table}','${relationInfo}', $("#${relationInfo}").val()) \r\n`
|
|
4303
|
+
})
|
|
4304
|
+
|
|
4305
|
+
scriptForm += `$(function() {${infoScript}});`;
|
|
4306
|
+
}
|
|
4279
4307
|
if (hasNumber) {
|
|
4280
4308
|
let numberObj = moduleLib.number(req, res);
|
|
4281
4309
|
scriptForm += numberObj.script;
|
|
@@ -6178,84 +6206,211 @@ zRoute.history = async (
|
|
|
6178
6206
|
users,
|
|
6179
6207
|
results = []
|
|
6180
6208
|
) => {
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6209
|
+
try {
|
|
6210
|
+
//html
|
|
6211
|
+
let html = "";
|
|
6212
|
+
|
|
6213
|
+
// Validasi input parameter
|
|
6214
|
+
if (!MYMODEL || !MYMODEL.widgets || !MYMODEL.labels) {
|
|
6215
|
+
return "Invalid model configuration";
|
|
6216
|
+
}
|
|
6217
|
+
|
|
6218
|
+
if (!users || typeof users !== 'object') {
|
|
6219
|
+
users = {};
|
|
6220
|
+
}
|
|
6221
|
+
|
|
6222
|
+
if (!Array.isArray(results)) {
|
|
6223
|
+
results = [];
|
|
6224
|
+
}
|
|
6225
|
+
|
|
6226
|
+
let unhistories = [
|
|
6227
|
+
"created_by",
|
|
6228
|
+
"updated_by",
|
|
6229
|
+
"created_at",
|
|
6230
|
+
"updated_at",
|
|
6231
|
+
"company_id",
|
|
6232
|
+
"id",
|
|
6233
|
+
];
|
|
6234
|
+
let arrHistories = [];
|
|
6235
|
+
let arrDataAttributes = [];
|
|
6236
|
+
let objectType = [
|
|
6237
|
+
"dropzone",
|
|
6238
|
+
"dropdown_multi",
|
|
6239
|
+
"dropdown_checkbox",
|
|
6240
|
+
"array",
|
|
6241
|
+
"json_array",
|
|
6242
|
+
"table",
|
|
6243
|
+
"json",
|
|
6244
|
+
];
|
|
6245
|
+
const widgets = MYMODEL.widgets;
|
|
6246
|
+
let fields = Object.keys(MYMODEL.labels || {});
|
|
6247
|
+
|
|
6248
|
+
if (results.length == 0) {
|
|
6249
|
+
html = "No History...";
|
|
6250
|
+
} else {
|
|
6251
|
+
for (const result of results) {
|
|
6252
|
+
try {
|
|
6253
|
+
if (!result || typeof result !== 'object') {
|
|
6254
|
+
continue;
|
|
6255
|
+
}
|
|
6256
|
+
|
|
6257
|
+
let obj = {};
|
|
6258
|
+
let data1 = result.data_1 || {};
|
|
6259
|
+
let data2 = result.data_2 || {};
|
|
6260
|
+
|
|
6261
|
+
if (!data1 || typeof data1 !== 'object') {
|
|
6262
|
+
data1 = {};
|
|
6263
|
+
}
|
|
6264
|
+
if (!data2 || typeof data2 !== 'object') {
|
|
6265
|
+
data2 = {};
|
|
6266
|
+
}
|
|
6267
|
+
|
|
6268
|
+
for (const key in data1) {
|
|
6269
|
+
try {
|
|
6270
|
+
if (!unhistories.includes(key)) {
|
|
6271
|
+
if (fields.includes(key)) {
|
|
6272
|
+
if (data1[key] || data2[key]) {
|
|
6273
|
+
// Validasi widget exists
|
|
6274
|
+
if (!MYMODEL.widgets[key] || !MYMODEL.widgets[key].name) {
|
|
6275
|
+
continue;
|
|
6276
|
+
}
|
|
6277
|
+
|
|
6278
|
+
let name = MYMODEL.widgets[key].name;
|
|
6279
|
+
if (objectType.includes(name)) {
|
|
6280
|
+
try {
|
|
6281
|
+
if (JSON.stringify(data1[key]) != JSON.stringify(data2[key])) {
|
|
6282
|
+
obj[key] = [data1[key], data2[key]];
|
|
6283
|
+
}
|
|
6284
|
+
} catch (jsonError) {
|
|
6285
|
+
// Jika JSON.stringify error, gunakan perbandingan biasa
|
|
6286
|
+
if (data1[key] != data2[key]) {
|
|
6287
|
+
obj[key] = [data1[key], data2[key]];
|
|
6288
|
+
}
|
|
6289
|
+
}
|
|
6290
|
+
} else {
|
|
6291
|
+
if (data1[key] != data2[key]) {
|
|
6292
|
+
obj[key] = [data1[key], data2[key]];
|
|
6293
|
+
}
|
|
6294
|
+
}
|
|
6295
|
+
}
|
|
6224
6296
|
}
|
|
6225
6297
|
}
|
|
6298
|
+
} catch (keyError) {
|
|
6299
|
+
// Skip key yang error, lanjut ke key berikutnya
|
|
6300
|
+
console.error(`Error processing key ${key}:`, keyError);
|
|
6301
|
+
continue;
|
|
6226
6302
|
}
|
|
6227
6303
|
}
|
|
6304
|
+
|
|
6305
|
+
if (Object.keys(obj).length > 0) {
|
|
6306
|
+
arrHistories.push(obj);
|
|
6307
|
+
arrDataAttributes.push({
|
|
6308
|
+
date1: result.data_1_date || null,
|
|
6309
|
+
date2: result.data_2_date || null,
|
|
6310
|
+
by1: (result.data_1 && result.data_1.updated_by) || null,
|
|
6311
|
+
by2: result.created_by || null,
|
|
6312
|
+
});
|
|
6313
|
+
}
|
|
6314
|
+
} catch (resultError) {
|
|
6315
|
+
// Skip result yang error, lanjut ke result berikutnya
|
|
6316
|
+
console.error('Error processing result:', resultError);
|
|
6317
|
+
continue;
|
|
6228
6318
|
}
|
|
6229
6319
|
}
|
|
6230
|
-
if (Object.keys(obj).length > 0) {
|
|
6231
|
-
arrHistories.push(obj);
|
|
6232
|
-
arrDataAttributes.push({
|
|
6233
|
-
date1: result.data_1_date,
|
|
6234
|
-
date2: result.data_2_date,
|
|
6235
|
-
by1: result.data_1.updated_by,
|
|
6236
|
-
by2: result.created_by,
|
|
6237
|
-
});
|
|
6238
|
-
}
|
|
6239
|
-
}
|
|
6240
6320
|
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6321
|
+
let index = 0;
|
|
6322
|
+
for (const item of arrHistories) {
|
|
6323
|
+
try {
|
|
6324
|
+
if (!item || typeof item !== 'object') {
|
|
6325
|
+
index++;
|
|
6326
|
+
continue;
|
|
6327
|
+
}
|
|
6328
|
+
|
|
6329
|
+
let obj1 = {};
|
|
6330
|
+
let obj2 = {};
|
|
6331
|
+
for (let key in item) {
|
|
6332
|
+
if (Array.isArray(item[key]) && item[key].length >= 2) {
|
|
6333
|
+
obj1[key] = item[key][0];
|
|
6334
|
+
obj2[key] = item[key][1];
|
|
6335
|
+
}
|
|
6336
|
+
}
|
|
6337
|
+
|
|
6338
|
+
let viewFormsSync1, viewFormsSync2;
|
|
6339
|
+
try {
|
|
6340
|
+
viewFormsSync1 = await zRoute.viewFormsSync(req, res, MYMODEL, obj1);
|
|
6341
|
+
viewFormsSync2 = await zRoute.viewFormsSync(req, res, MYMODEL, obj2);
|
|
6342
|
+
} catch (viewFormsError) {
|
|
6343
|
+
console.error('Error in viewFormsSync:', viewFormsError);
|
|
6344
|
+
index++;
|
|
6345
|
+
continue;
|
|
6346
|
+
}
|
|
6347
|
+
|
|
6348
|
+
if (!viewFormsSync1 || !viewFormsSync1.build) {
|
|
6349
|
+
viewFormsSync1 = { build: {} };
|
|
6350
|
+
}
|
|
6351
|
+
if (!viewFormsSync2 || !viewFormsSync2.build) {
|
|
6352
|
+
viewFormsSync2 = { build: {} };
|
|
6353
|
+
}
|
|
6354
|
+
|
|
6355
|
+
let html1 = "";
|
|
6356
|
+
let html2 = "";
|
|
6357
|
+
for (let key in item) {
|
|
6358
|
+
html1 += (viewFormsSync1.build[key] || '');
|
|
6359
|
+
html2 += (viewFormsSync2.build[key] || '');
|
|
6360
|
+
}
|
|
6361
|
+
|
|
6362
|
+
// Validasi arrDataAttributes[index]
|
|
6363
|
+
const dataAttr = arrDataAttributes[index] || {};
|
|
6364
|
+
const date1 = dataAttr.date1 || null;
|
|
6365
|
+
const date2 = dataAttr.date2 || null;
|
|
6366
|
+
const by1 = dataAttr.by1 || null;
|
|
6367
|
+
const by2 = dataAttr.by2 || null;
|
|
6257
6368
|
|
|
6258
|
-
|
|
6369
|
+
// Validasi users sebelum mengakses fullname
|
|
6370
|
+
let user1Fullname = '';
|
|
6371
|
+
let user2Fullname = '';
|
|
6372
|
+
|
|
6373
|
+
try {
|
|
6374
|
+
if (by1 && users[by1] && users[by1].fullname) {
|
|
6375
|
+
user1Fullname = users[by1].fullname;
|
|
6376
|
+
} else {
|
|
6377
|
+
user1Fullname = by1 || 'Unknown';
|
|
6378
|
+
}
|
|
6379
|
+
} catch (user1Error) {
|
|
6380
|
+
user1Fullname = by1 || 'Unknown';
|
|
6381
|
+
}
|
|
6382
|
+
|
|
6383
|
+
try {
|
|
6384
|
+
if (by2 && users[by2] && users[by2].fullname) {
|
|
6385
|
+
user2Fullname = users[by2].fullname;
|
|
6386
|
+
} else {
|
|
6387
|
+
user2Fullname = by2 || 'Unknown';
|
|
6388
|
+
}
|
|
6389
|
+
} catch (user2Error) {
|
|
6390
|
+
user2Fullname = by2 || 'Unknown';
|
|
6391
|
+
}
|
|
6392
|
+
|
|
6393
|
+
// Format date dengan error handling
|
|
6394
|
+
let formattedDate1 = '';
|
|
6395
|
+
let formattedDate2 = '';
|
|
6396
|
+
|
|
6397
|
+
try {
|
|
6398
|
+
if (date1 && Util && Util.dateFormat) {
|
|
6399
|
+
formattedDate1 = Util.dateFormat(date1, "DD MMM YYYY HH:mm") || "";
|
|
6400
|
+
}
|
|
6401
|
+
} catch (date1Error) {
|
|
6402
|
+
formattedDate1 = '';
|
|
6403
|
+
}
|
|
6404
|
+
|
|
6405
|
+
try {
|
|
6406
|
+
if (date2 && Util && Util.dateFormat) {
|
|
6407
|
+
formattedDate2 = Util.dateFormat(date2, "DD MMM YYYY HH:mm") || "";
|
|
6408
|
+
}
|
|
6409
|
+
} catch (date2Error) {
|
|
6410
|
+
formattedDate2 = '';
|
|
6411
|
+
}
|
|
6412
|
+
|
|
6413
|
+
html += `<div class="row">
|
|
6259
6414
|
<!-- timeline item 1 left dot -->
|
|
6260
6415
|
<div class="col-auto text-center flex-column d-none d-sm-flex">
|
|
6261
6416
|
<div class="row h-50">
|
|
@@ -6276,15 +6431,7 @@ zRoute.history = async (
|
|
|
6276
6431
|
<div class="col-md-6">
|
|
6277
6432
|
<div class="card">
|
|
6278
6433
|
<div class="card-body">
|
|
6279
|
-
<div class="float-end text-muted text-end">${
|
|
6280
|
-
Util.dateFormat(
|
|
6281
|
-
arrDataAttributes[index]
|
|
6282
|
-
.date1,
|
|
6283
|
-
"DD MMM YYYY HH:mm"
|
|
6284
|
-
) || ""
|
|
6285
|
-
}<br><small>${
|
|
6286
|
-
users[arrDataAttributes[index].by1].fullname
|
|
6287
|
-
}</small></div>
|
|
6434
|
+
<div class="float-end text-muted text-end">${formattedDate1}<br><small>${user1Fullname}</small></div>
|
|
6288
6435
|
<h4 class="card-title text-muted">Semula</h4>
|
|
6289
6436
|
<div class="card-text">${html1}</div>
|
|
6290
6437
|
</div>
|
|
@@ -6293,15 +6440,7 @@ zRoute.history = async (
|
|
|
6293
6440
|
<div class="col-md-6">
|
|
6294
6441
|
<div class="card">
|
|
6295
6442
|
<div class="card-body">
|
|
6296
|
-
<div class="float-end text-muted text-end">${
|
|
6297
|
-
Util.dateFormat(
|
|
6298
|
-
arrDataAttributes[index]
|
|
6299
|
-
.date2,
|
|
6300
|
-
"DD MMM YYYY HH:mm"
|
|
6301
|
-
) || ""
|
|
6302
|
-
} <br><small>${
|
|
6303
|
-
users[arrDataAttributes[index].by2].fullname
|
|
6304
|
-
}</small></div>
|
|
6443
|
+
<div class="float-end text-muted text-end">${formattedDate2} <br><small>${user2Fullname}</small></div>
|
|
6305
6444
|
<h4 class="card-title text-success">Menjadi </h4>
|
|
6306
6445
|
<div class="card-text">${html2}</div>
|
|
6307
6446
|
</div>
|
|
@@ -6311,10 +6450,20 @@ zRoute.history = async (
|
|
|
6311
6450
|
</div>
|
|
6312
6451
|
</div>`;
|
|
6313
6452
|
|
|
6314
|
-
|
|
6453
|
+
index++;
|
|
6454
|
+
} catch (itemError) {
|
|
6455
|
+
// Skip item yang error, lanjut ke item berikutnya
|
|
6456
|
+
console.error(`Error processing history item at index ${index}:`, itemError);
|
|
6457
|
+
index++;
|
|
6458
|
+
continue;
|
|
6459
|
+
}
|
|
6460
|
+
}
|
|
6315
6461
|
}
|
|
6462
|
+
return html;
|
|
6463
|
+
} catch (error) {
|
|
6464
|
+
console.error('Error in zRoute.history:', error);
|
|
6465
|
+
return "Error loading history. Please try again later.";
|
|
6316
6466
|
}
|
|
6317
|
-
return html;
|
|
6318
6467
|
};
|
|
6319
6468
|
|
|
6320
6469
|
zRoute.tableBody = (
|
package/package.json
CHANGED
package/lib/routes/api.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
const express = require('express');
|
|
2
|
-
const router = express.Router();
|
|
3
|
-
const Api = require('../generatorApi');
|
|
4
|
-
const Model = require('../Model');
|
|
5
|
-
|
|
6
|
-
//Home of Generator index
|
|
7
|
-
router.post('/generator/index', (req,res) => {
|
|
8
|
-
let json = {};
|
|
9
|
-
try {
|
|
10
|
-
let datas = {table: '', tabs: [], labels: {}, details: {}, hardcode_grid: ""};
|
|
11
|
-
let table = req.body.table || "", route = "";
|
|
12
|
-
json = {
|
|
13
|
-
datas: datas,
|
|
14
|
-
table: table,
|
|
15
|
-
route: table,
|
|
16
|
-
selects: Model.keys,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
} catch (e) {
|
|
20
|
-
console.log(e.toString());
|
|
21
|
-
res.status(400).json({message: e.toString()})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
res.json(json)
|
|
25
|
-
});
|
|
26
|
-
router.post('/generator/modal', async(req,res) => {
|
|
27
|
-
let body = req.body;
|
|
28
|
-
let result = body.result;
|
|
29
|
-
let others = result.others || {};
|
|
30
|
-
let othersArr = Object.keys(others) || [];
|
|
31
|
-
let json = {}
|
|
32
|
-
if(othersArr.length) {
|
|
33
|
-
console.log('masuk ke container')
|
|
34
|
-
json = await Api.modalWithContainer(req,res);
|
|
35
|
-
} else {
|
|
36
|
-
json = await Api.modalClassic(req,res);
|
|
37
|
-
}
|
|
38
|
-
//console.log(JSON.stringify(json))
|
|
39
|
-
res.json(json)
|
|
40
|
-
});
|
|
41
|
-
router.post('/generator/create', (req,res) => {
|
|
42
|
-
res.json(Api.createTable(req.body))
|
|
43
|
-
});
|
|
44
|
-
router.post('/generator/create_field', Api.create_field);
|
|
45
|
-
router.post('/generator/modal_settings', Api.modal_settings);
|
|
46
|
-
|
|
47
|
-
//generate
|
|
48
|
-
router.post('/generator/properties', Api.properties);
|
|
49
|
-
router.post('/generator/generate', Api.generate);
|
|
50
|
-
router.post('/generator/reset', Api.reset);
|
|
51
|
-
|
|
52
|
-
module.exports = router;
|