underpost 2.85.1 → 2.89.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/.env.development +2 -1
- package/.env.production +2 -1
- package/.env.test +2 -1
- package/.github/workflows/release.cd.yml +3 -3
- package/.vscode/zed.keymap.json +22 -0
- package/README.md +3 -3
- package/bin/build.js +8 -10
- package/bin/deploy.js +4 -2
- package/bin/file.js +4 -0
- package/bin/vs.js +4 -4
- package/cli.md +16 -11
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +50 -50
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/package.json +2 -2
- package/src/api/file/file.service.js +29 -3
- package/src/cli/baremetal.js +4 -5
- package/src/cli/deploy.js +26 -4
- package/src/cli/index.js +8 -3
- package/src/cli/repository.js +42 -45
- package/src/cli/run.js +217 -48
- package/src/client/components/core/AgGrid.js +42 -3
- package/src/client/components/core/CommonJs.js +5 -0
- package/src/client/components/core/Css.js +95 -48
- package/src/client/components/core/CssCore.js +0 -1
- package/src/client/components/core/LoadingAnimation.js +2 -2
- package/src/client/components/core/Logger.js +2 -9
- package/src/client/components/core/Modal.js +22 -14
- package/src/client/components/core/ObjectLayerEngine.js +300 -9
- package/src/client/components/core/ObjectLayerEngineModal.js +686 -148
- package/src/client/components/core/ObjectLayerEngineViewer.js +1061 -0
- package/src/client/components/core/Pagination.js +15 -5
- package/src/client/components/core/Router.js +5 -1
- package/src/client/components/core/SocketIo.js +5 -1
- package/src/client/components/core/Translate.js +4 -0
- package/src/client/components/core/Worker.js +8 -1
- package/src/client/services/default/default.management.js +86 -16
- package/src/client/sw/default.sw.js +193 -97
- package/src/client.dev.js +1 -1
- package/src/db/mariadb/MariaDB.js +2 -2
- package/src/index.js +1 -1
- package/src/proxy.js +1 -1
- package/src/runtime/express/Express.js +4 -1
- package/src/server/auth.js +2 -1
- package/src/server/client-build.js +57 -2
- package/src/server/conf.js +132 -15
- package/src/server/object-layer.js +44 -0
- package/src/server/proxy.js +53 -26
- package/src/server/start.js +25 -3
- package/src/server/tls.js +1 -1
- package/src/ws/IoInterface.js +2 -3
- package/AUTHORS.md +0 -21
- package/src/server/network.js +0 -72
|
@@ -5,11 +5,19 @@ import { DropDown } from './DropDown.js';
|
|
|
5
5
|
import { EventsUI } from './EventsUI.js';
|
|
6
6
|
import { Translate } from './Translate.js';
|
|
7
7
|
import { s, append, hexToRgbA } from './VanillaJs.js';
|
|
8
|
-
import { getProxyPath } from './Router.js';
|
|
8
|
+
import { getProxyPath, getQueryParams, setPath, setQueryParams } from './Router.js';
|
|
9
9
|
import { s4 } from './CommonJs.js';
|
|
10
10
|
import { Input } from './Input.js';
|
|
11
11
|
import { ToggleSwitch } from './ToggleSwitch.js';
|
|
12
12
|
import { ObjectLayerService } from '../../services/object-layer/object-layer.service.js';
|
|
13
|
+
import { NotificationManager } from './NotificationManager.js';
|
|
14
|
+
import { AgGrid } from './AgGrid.js';
|
|
15
|
+
import { Modal } from './Modal.js';
|
|
16
|
+
import { loggerFactory } from './Logger.js';
|
|
17
|
+
import { LoadingAnimation } from './LoadingAnimation.js';
|
|
18
|
+
import { DefaultManagement } from '../../services/default/default.management.js';
|
|
19
|
+
|
|
20
|
+
const logger = loggerFactory(import.meta, { trace: true });
|
|
13
21
|
|
|
14
22
|
const ObjectLayerEngineModal = {
|
|
15
23
|
templates: [
|
|
@@ -19,6 +27,46 @@ const ObjectLayerEngineModal = {
|
|
|
19
27
|
data: [],
|
|
20
28
|
},
|
|
21
29
|
],
|
|
30
|
+
statDescriptions: {
|
|
31
|
+
effect: {
|
|
32
|
+
title: 'Effect',
|
|
33
|
+
icon: 'fa-solid fa-burst',
|
|
34
|
+
description: 'Amount of life removed when an entity collides or deals an impact.',
|
|
35
|
+
detail: 'Measured in life points.',
|
|
36
|
+
},
|
|
37
|
+
resistance: {
|
|
38
|
+
title: 'Resistance',
|
|
39
|
+
icon: 'fa-solid fa-shield',
|
|
40
|
+
description: "Adds to the owner's maximum life (survivability cap).",
|
|
41
|
+
detail:
|
|
42
|
+
"This value is summed with the entity's base max life. It also increases the amount of life restored when a regeneration event occurs (adds directly to current life).",
|
|
43
|
+
},
|
|
44
|
+
agility: {
|
|
45
|
+
title: 'Agility',
|
|
46
|
+
icon: 'fa-solid fa-person-running',
|
|
47
|
+
description: 'Increases the movement speed of entities.',
|
|
48
|
+
detail: 'Higher values result in faster movement.',
|
|
49
|
+
},
|
|
50
|
+
range: {
|
|
51
|
+
title: 'Range',
|
|
52
|
+
icon: 'fa-solid fa-bullseye',
|
|
53
|
+
description: 'Increases the lifetime of a cast/summoned entity.',
|
|
54
|
+
detail: 'Measured in milliseconds.',
|
|
55
|
+
},
|
|
56
|
+
intelligence: {
|
|
57
|
+
title: 'Intelligence',
|
|
58
|
+
icon: 'fa-solid fa-brain',
|
|
59
|
+
description: 'Probability-based stat that increases the chance to spawn/trigger a summoned entity.',
|
|
60
|
+
detail: 'Higher values increase summoning success rate.',
|
|
61
|
+
},
|
|
62
|
+
utility: {
|
|
63
|
+
title: 'Utility',
|
|
64
|
+
icon: 'fa-solid fa-wrench',
|
|
65
|
+
description: 'Reduces the cooldown time between actions, allowing for more frequent actions.',
|
|
66
|
+
detail: 'It also increases the chance to trigger life-regeneration events.',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
|
|
22
70
|
RenderTemplate: (colorTemplate) => {
|
|
23
71
|
const ole = s('object-layer-engine');
|
|
24
72
|
if (!ole) {
|
|
@@ -34,7 +82,88 @@ const ObjectLayerEngineModal = {
|
|
|
34
82
|
ole.loadMatrix(matrix);
|
|
35
83
|
},
|
|
36
84
|
ObjectLayerData: {},
|
|
37
|
-
|
|
85
|
+
clearData: function () {
|
|
86
|
+
// Clear all cached object layer data to prevent contamination between sessions
|
|
87
|
+
this.ObjectLayerData = {};
|
|
88
|
+
|
|
89
|
+
// Clear the canvas if it exists
|
|
90
|
+
const ole = s('object-layer-engine');
|
|
91
|
+
if (ole && typeof ole.clear === 'function') {
|
|
92
|
+
ole.clear();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Clear all frame previews from DOM for all direction codes
|
|
96
|
+
const directionCodes = ['08', '18', '02', '12', '04', '14', '06', '16'];
|
|
97
|
+
for (const directionCode of directionCodes) {
|
|
98
|
+
const framesContainer = s(`.frames-${directionCode}`);
|
|
99
|
+
if (framesContainer) {
|
|
100
|
+
framesContainer.innerHTML = '';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Clear form inputs with correct IDs
|
|
105
|
+
const itemIdInput = s('#ol-input-item-id');
|
|
106
|
+
if (itemIdInput) itemIdInput.value = '';
|
|
107
|
+
|
|
108
|
+
const itemDescInput = s('#ol-input-item-description');
|
|
109
|
+
if (itemDescInput) itemDescInput.value = '';
|
|
110
|
+
|
|
111
|
+
const frameDurationInput = s('#ol-input-render-frame-duration');
|
|
112
|
+
if (frameDurationInput) frameDurationInput.value = '100';
|
|
113
|
+
|
|
114
|
+
// Reset toggle switches with correct IDs
|
|
115
|
+
const activableCheckbox = s('#ol-toggle-item-activable');
|
|
116
|
+
if (activableCheckbox) activableCheckbox.checked = false;
|
|
117
|
+
|
|
118
|
+
const statelessCheckbox = s('#ol-toggle-render-is-stateless');
|
|
119
|
+
if (statelessCheckbox) statelessCheckbox.checked = false;
|
|
120
|
+
|
|
121
|
+
// Clear stat inputs with correct IDs
|
|
122
|
+
const statTypes = Object.keys(ObjectLayerEngineModal.statDescriptions);
|
|
123
|
+
for (const stat of statTypes) {
|
|
124
|
+
const statInput = s(`#ol-input-item-stats-${stat}`);
|
|
125
|
+
if (statInput) statInput.value = '0';
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
loadFromDatabase: async (objectLayerId) => {
|
|
129
|
+
try {
|
|
130
|
+
// Load metadata first (lightweight)
|
|
131
|
+
const { status: metaStatus, data: metadata } = await ObjectLayerService.getMetadata({ id: objectLayerId });
|
|
132
|
+
|
|
133
|
+
if (metaStatus !== 'success' || !metadata) {
|
|
134
|
+
NotificationManager.Push({
|
|
135
|
+
html: `Failed to load object layer metadata`,
|
|
136
|
+
status: 'error',
|
|
137
|
+
});
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Load render data separately (heavy)
|
|
142
|
+
const { status: renderStatus, data: renderData } = await ObjectLayerService.getRender({ id: objectLayerId });
|
|
143
|
+
|
|
144
|
+
if (renderStatus !== 'success' || !renderData) {
|
|
145
|
+
NotificationManager.Push({
|
|
146
|
+
html: `Failed to load object layer render data`,
|
|
147
|
+
status: 'error',
|
|
148
|
+
});
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { metadata, renderData };
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error('Error loading object layer from database:', error);
|
|
155
|
+
NotificationManager.Push({
|
|
156
|
+
html: `Error loading object layer: ${error.message}`,
|
|
157
|
+
status: 'error',
|
|
158
|
+
});
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
Render: async (options = { idModal: '', Elements: {} }) => {
|
|
163
|
+
// Clear all cached data at the start of each render to prevent contamination
|
|
164
|
+
ObjectLayerEngineModal.clearData();
|
|
165
|
+
|
|
166
|
+
const { Elements } = options;
|
|
38
167
|
await import(`${getProxyPath()}components/core/ObjectLayerEngine.js`);
|
|
39
168
|
// await import(`${getProxyPath()}components/core/WebComponent.js`);
|
|
40
169
|
const directionCodes = ['08', '18', '02', '12', '04', '14', '06', '16'];
|
|
@@ -45,6 +174,37 @@ const ObjectLayerEngineModal = {
|
|
|
45
174
|
let renderIsStateless = false;
|
|
46
175
|
let renderFrameDuration = 100;
|
|
47
176
|
|
|
177
|
+
// Check if we have a 'cid' query parameter to load existing object layer
|
|
178
|
+
const queryParams = getQueryParams();
|
|
179
|
+
let loadedData = null;
|
|
180
|
+
let existingObjectLayerId = null; // Track the _id for updates
|
|
181
|
+
let originalDirectionCodes = []; // Track original direction codes for update mode
|
|
182
|
+
if (queryParams.cid) {
|
|
183
|
+
existingObjectLayerId = queryParams.cid;
|
|
184
|
+
loadedData = await ObjectLayerEngineModal.loadFromDatabase(queryParams.cid);
|
|
185
|
+
|
|
186
|
+
if (loadedData) {
|
|
187
|
+
const { metadata, renderData } = loadedData;
|
|
188
|
+
|
|
189
|
+
// Set form values from metadata
|
|
190
|
+
if (metadata.data) {
|
|
191
|
+
if (metadata.data.item) {
|
|
192
|
+
selectItemType = metadata.data.item.type || itemTypes[0];
|
|
193
|
+
itemActivable = metadata.data.item.activable || false;
|
|
194
|
+
|
|
195
|
+
// Add loaded item type to itemTypes array if it doesn't exist
|
|
196
|
+
if (selectItemType && !itemTypes.includes(selectItemType)) {
|
|
197
|
+
itemTypes.push(selectItemType);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (metadata.data.render) {
|
|
201
|
+
renderIsStateless = metadata.data.render.is_stateless || false;
|
|
202
|
+
renderFrameDuration = metadata.data.render.frame_duration || 100;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
48
208
|
for (const url of [
|
|
49
209
|
`${getProxyPath()}assets/templates/item-skin-08.json`,
|
|
50
210
|
`${getProxyPath()}assets/templates/item-skin-06.json`,
|
|
@@ -64,173 +224,471 @@ const ObjectLayerEngineModal = {
|
|
|
64
224
|
|
|
65
225
|
let directionsCodeBarRender = '';
|
|
66
226
|
|
|
227
|
+
// Helper function to add a frame to the direction bar
|
|
228
|
+
const addFrameToBar = async (directionCode, id, image, json) => {
|
|
229
|
+
// Capture directionCode in a local variable to ensure proper closure
|
|
230
|
+
const capturedDirectionCode = directionCode;
|
|
231
|
+
|
|
232
|
+
append(
|
|
233
|
+
`.frames-${capturedDirectionCode}`,
|
|
234
|
+
html`
|
|
235
|
+
<div class="in fll ${id}">
|
|
236
|
+
<img
|
|
237
|
+
class="in fll direction-code-bar-frames-img direction-code-bar-frames-img-${id}"
|
|
238
|
+
src="${URL.createObjectURL(image)}"
|
|
239
|
+
data-direction-code="${capturedDirectionCode}"
|
|
240
|
+
/>
|
|
241
|
+
${await BtnIcon.Render({
|
|
242
|
+
label: html`<i class="fa-solid fa-trash"></i>`,
|
|
243
|
+
class: `abs direction-code-bar-trash-btn direction-code-bar-trash-btn-${id}`,
|
|
244
|
+
})}
|
|
245
|
+
</div>
|
|
246
|
+
`,
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
EventsUI.onClick(`.direction-code-bar-frames-img-${id}`, async (e) => {
|
|
250
|
+
// Get direction code from data attribute to ensure we're using the correct one
|
|
251
|
+
const clickedDirectionCode = e.target.getAttribute('data-direction-code') || capturedDirectionCode;
|
|
252
|
+
console.log(`Clicked frame ${id} from direction code: ${clickedDirectionCode}`);
|
|
253
|
+
const frameData = ObjectLayerEngineModal.ObjectLayerData[clickedDirectionCode]?.find(
|
|
254
|
+
(frame) => frame.id === id,
|
|
255
|
+
);
|
|
256
|
+
if (frameData && frameData.json) {
|
|
257
|
+
console.log(`Loading frame data for direction code ${clickedDirectionCode}:`, frameData.json);
|
|
258
|
+
s('object-layer-engine').importMatrixJSON(frameData.json);
|
|
259
|
+
} else {
|
|
260
|
+
console.error(`Frame data not found for id ${id} in direction code ${clickedDirectionCode}`);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
EventsUI.onClick(`.direction-code-bar-trash-btn-${id}`, async () => {
|
|
265
|
+
s(`.${id}`).remove();
|
|
266
|
+
ObjectLayerEngineModal.ObjectLayerData[capturedDirectionCode] = ObjectLayerEngineModal.ObjectLayerData[
|
|
267
|
+
capturedDirectionCode
|
|
268
|
+
].filter((frame) => frame.id !== id);
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Helper function to show loading animation
|
|
273
|
+
const showFrameLoading = () => {
|
|
274
|
+
if (!s(`.frame-editor-container`) || s(`.frame-editor-container`).classList.contains('hide')) return;
|
|
275
|
+
LoadingAnimation.spinner.play(`.frame-editor-container-loading`, 'dual-ring-mini', {
|
|
276
|
+
prepend: html`<span class="inl loading-text">Loading </span><br /><br /> ` + '<div style="color: gray;">',
|
|
277
|
+
append: '</div>',
|
|
278
|
+
});
|
|
279
|
+
s(`.frame-editor-container`).classList.add('hide');
|
|
280
|
+
s(`.frame-editor-container-loading`).classList.remove('hide');
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
// Helper function to hide loading animation
|
|
284
|
+
const hideFrameLoading = () => {
|
|
285
|
+
if (!s(`.frame-editor-container-loading`) || s(`.frame-editor-container-loading`).classList.contains('hide'))
|
|
286
|
+
return;
|
|
287
|
+
LoadingAnimation.spinner.stop(`.frame-editor-container-loading`);
|
|
288
|
+
s(`.frame-editor-container-loading`).classList.add('hide');
|
|
289
|
+
s(`.frame-editor-container`).classList.remove('hide');
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// Helper function to process and add frame from PNG URL using ObjectLayerPngLoader
|
|
293
|
+
const processAndAddFrameFromPngUrl = async (directionCode, pngUrl) => {
|
|
294
|
+
// Wait for components to be available with retry logic
|
|
295
|
+
let ole = s('object-layer-engine');
|
|
296
|
+
let loader = s('object-layer-png-loader');
|
|
297
|
+
|
|
298
|
+
if (!ole || !loader) {
|
|
299
|
+
console.error('object-layer-engine or object-layer-png-loader component not found after retries');
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
// Load PNG using the loader component - it will automatically load into the editor
|
|
305
|
+
await loader.loadPngUrl(pngUrl);
|
|
306
|
+
|
|
307
|
+
// Export as blob and JSON from component after loading
|
|
308
|
+
const image = await ole.toBlob();
|
|
309
|
+
const json = ole.exportMatrixJSON();
|
|
310
|
+
const id = `frame-loaded-${s4()}-${s4()}`;
|
|
311
|
+
|
|
312
|
+
// Add to ObjectLayerData
|
|
313
|
+
if (!ObjectLayerEngineModal.ObjectLayerData[directionCode]) {
|
|
314
|
+
ObjectLayerEngineModal.ObjectLayerData[directionCode] = [];
|
|
315
|
+
}
|
|
316
|
+
ObjectLayerEngineModal.ObjectLayerData[directionCode].push({ id, image, json });
|
|
317
|
+
console.log(
|
|
318
|
+
`Stored frame ${id} in direction code ${directionCode}. Total frames:`,
|
|
319
|
+
ObjectLayerEngineModal.ObjectLayerData[directionCode].length,
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
// Add to UI
|
|
323
|
+
await addFrameToBar(directionCode, id, image, json);
|
|
324
|
+
} catch (error) {
|
|
325
|
+
console.error('Error loading frame from PNG URL:', error);
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
|
|
67
329
|
for (const directionCode of directionCodes) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (!ObjectLayerEngineModal.ObjectLayerData[directionCode])
|
|
75
|
-
ObjectLayerEngineModal.ObjectLayerData[directionCode] = [];
|
|
76
|
-
ObjectLayerEngineModal.ObjectLayerData[directionCode].push({ id, image, json });
|
|
77
|
-
|
|
78
|
-
append(
|
|
79
|
-
`.frames-${directionCode}`,
|
|
80
|
-
html`
|
|
81
|
-
<div class="in fll ${id}">
|
|
82
|
-
<img class="in fll direction-code-bar-frames-img" src="${URL.createObjectURL(image)}" />
|
|
330
|
+
directionsCodeBarRender += html`
|
|
331
|
+
<div class="in section-mp-border">
|
|
332
|
+
<div class="fl">
|
|
333
|
+
<div class="in fll">
|
|
334
|
+
<div class="in direction-code-bar-frames-title">${directionCode}</div>
|
|
335
|
+
<div class="in direction-code-bar-frames-btn">
|
|
83
336
|
${await BtnIcon.Render({
|
|
84
|
-
label: html`<i class="fa-solid fa-
|
|
85
|
-
class: `
|
|
337
|
+
label: html`<i class="fa-solid fa-plus"></i>`,
|
|
338
|
+
class: `direction-code-bar-frames-btn-${directionCode}`,
|
|
86
339
|
})}
|
|
87
340
|
</div>
|
|
88
|
-
|
|
89
|
-
|
|
341
|
+
</div>
|
|
342
|
+
<div class="frames-${directionCode}"></div>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
`;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
let statsInputsRender = '';
|
|
349
|
+
for (const statType of statTypes) {
|
|
350
|
+
const statInfo = ObjectLayerEngineModal.statDescriptions[statType];
|
|
351
|
+
const statValue = loadedData?.metadata?.data?.stats?.[statType] || 0;
|
|
352
|
+
statsInputsRender += html`
|
|
353
|
+
<div class="inl" style="margin-bottom: 10px; position: relative;">
|
|
354
|
+
${await Input.Render({
|
|
355
|
+
id: `ol-input-item-stats-${statType}`,
|
|
356
|
+
label: html`<div
|
|
357
|
+
title="${statInfo.description} ${statInfo.detail}"
|
|
358
|
+
class="inl stat-label-container stat-info-icon"
|
|
359
|
+
style="width: 120px; font-size: 16px; overflow: visible; position: relative;"
|
|
360
|
+
>
|
|
361
|
+
<i class="${statInfo.icon}" style="margin-right: 5px;"></i> ${statInfo.title}
|
|
362
|
+
</div>`,
|
|
363
|
+
containerClass: 'inl',
|
|
364
|
+
type: 'number',
|
|
365
|
+
min: 0,
|
|
366
|
+
max: 10,
|
|
367
|
+
placeholder: true,
|
|
368
|
+
value: statValue,
|
|
369
|
+
})}
|
|
370
|
+
<div class="in stat-description">
|
|
371
|
+
${statInfo.description}<br />
|
|
372
|
+
<span style="color: #888; font-style: italic;">${statInfo.detail}</span>
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
`;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
setTimeout(async () => {
|
|
379
|
+
showFrameLoading();
|
|
380
|
+
for (const directionCode of directionCodes) {
|
|
381
|
+
// Use IIFE to properly capture directionCode and handle async operations
|
|
382
|
+
await (async (currentDirectionCode) => {
|
|
383
|
+
// Register frame add button handler after DOM is ready
|
|
384
|
+
// Wait longer to ensure all direction bars are rendered
|
|
385
|
+
|
|
386
|
+
if (loadedData && loadedData.metadata && loadedData.metadata.data && currentDirectionCode) {
|
|
387
|
+
// Show loading animation only once on first direction that has frames
|
|
388
|
+
|
|
389
|
+
const { type, id } = loadedData.metadata.data.item;
|
|
390
|
+
const directions = ObjectLayerEngineModal.getDirectionsFromDirectionCode(currentDirectionCode);
|
|
391
|
+
|
|
392
|
+
console.log(`Loading frames for direction code: ${currentDirectionCode}, directions:`, directions);
|
|
90
393
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
394
|
+
// Check if frames exist for any direction mapped to this direction code
|
|
395
|
+
const { frames } = loadedData.renderData.data.render;
|
|
396
|
+
for (const direction of directions) {
|
|
397
|
+
if (frames[direction] && frames[direction].length > 0) {
|
|
398
|
+
// Track this direction code as having original data
|
|
399
|
+
if (!originalDirectionCodes.includes(currentDirectionCode)) {
|
|
400
|
+
originalDirectionCodes.push(currentDirectionCode);
|
|
401
|
+
}
|
|
402
|
+
// Load frames from static PNG URLs sequentially to avoid race conditions
|
|
403
|
+
const frameCount = frames[direction].length;
|
|
404
|
+
console.log(`Found ${frameCount} frames for direction: ${direction} (code: ${currentDirectionCode})`);
|
|
405
|
+
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
406
|
+
const pngUrl = `${getProxyPath()}assets/${type}/${id}/${currentDirectionCode}/${frameIndex}.png`;
|
|
407
|
+
console.log(`Loading frame ${frameIndex} for direction code ${currentDirectionCode} from: ${pngUrl}`);
|
|
408
|
+
await processAndAddFrameFromPngUrl(currentDirectionCode, pngUrl);
|
|
409
|
+
}
|
|
410
|
+
console.log(`Completed loading ${frameCount} frames for direction code: ${currentDirectionCode}`);
|
|
411
|
+
// Once we found frames for this direction code, we can break to avoid duplicates
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const buttonSelector = `.direction-code-bar-frames-btn-${currentDirectionCode}`;
|
|
418
|
+
console.log(`Registering click handler for: ${buttonSelector}`);
|
|
419
|
+
|
|
420
|
+
EventsUI.onClick(buttonSelector, async () => {
|
|
421
|
+
console.log(`Add frame button clicked for direction: ${currentDirectionCode}`);
|
|
422
|
+
const ole = s('object-layer-engine');
|
|
423
|
+
if (!ole) {
|
|
424
|
+
console.error('object-layer-engine not found');
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const image = await ole.toBlob();
|
|
428
|
+
const json = ole.exportMatrixJSON();
|
|
429
|
+
const id = `frame-capture-${s4()}-${s4()}`;
|
|
430
|
+
console.log(`Creating new frame ${id} for direction ${currentDirectionCode}`);
|
|
431
|
+
|
|
432
|
+
if (!ObjectLayerEngineModal.ObjectLayerData[currentDirectionCode])
|
|
433
|
+
ObjectLayerEngineModal.ObjectLayerData[currentDirectionCode] = [];
|
|
434
|
+
ObjectLayerEngineModal.ObjectLayerData[currentDirectionCode].push({ id, image, json });
|
|
435
|
+
console.log(
|
|
436
|
+
`Stored frame ${id} in direction code ${currentDirectionCode}. Total frames:`,
|
|
437
|
+
ObjectLayerEngineModal.ObjectLayerData[currentDirectionCode].length,
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
await addFrameToBar(currentDirectionCode, id, image, json);
|
|
96
441
|
});
|
|
97
|
-
});
|
|
442
|
+
})(directionCode);
|
|
443
|
+
}
|
|
444
|
+
hideFrameLoading();
|
|
445
|
+
s('object-layer-engine').clear();
|
|
98
446
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
447
|
+
EventsUI.onClick(`.ol-btn-save`, async () => {
|
|
448
|
+
// Validate minimum frame_duration 100ms
|
|
449
|
+
const frameDuration = parseInt(s(`.ol-input-render-frame-duration`).value);
|
|
450
|
+
if (!frameDuration || frameDuration < 100) {
|
|
451
|
+
NotificationManager.Push({
|
|
452
|
+
html: 'Frame duration must be at least 100ms',
|
|
453
|
+
status: 'error',
|
|
454
|
+
});
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Validate that item.id is not empty
|
|
459
|
+
const itemId = s(`.ol-input-item-id`).value;
|
|
460
|
+
if (!itemId || itemId.trim() === '') {
|
|
461
|
+
NotificationManager.Push({
|
|
462
|
+
html: 'Item ID is required',
|
|
463
|
+
status: 'error',
|
|
464
|
+
});
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const objectLayer = {
|
|
469
|
+
data: {
|
|
470
|
+
render: {
|
|
471
|
+
frames: {},
|
|
472
|
+
color: [],
|
|
473
|
+
frame_duration: 0,
|
|
474
|
+
is_stateless: false,
|
|
110
475
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
476
|
+
stats: {},
|
|
477
|
+
item: {},
|
|
478
|
+
},
|
|
479
|
+
};
|
|
480
|
+
for (const directionCode of directionCodes) {
|
|
481
|
+
const directions = ObjectLayerEngineModal.getDirectionsFromDirectionCode(directionCode);
|
|
482
|
+
for (const direction of directions) {
|
|
483
|
+
if (!objectLayer.data.render.frames[direction]) objectLayer.data.render.frames[direction] = [];
|
|
116
484
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
485
|
+
if (!(directionCode in ObjectLayerEngineModal.ObjectLayerData)) {
|
|
486
|
+
console.warn('No set directionCodeBarFrameData for directionCode', directionCode);
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
121
489
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (colorIndex === -1) {
|
|
140
|
-
objectLayer.data.render.color.push(value);
|
|
141
|
-
colorIndex = objectLayer.data.render.color.length - 1;
|
|
142
|
-
}
|
|
143
|
-
frameIndexColorMatrix[indexRow][indexCol] = colorIndex;
|
|
490
|
+
for (const frameData of ObjectLayerEngineModal.ObjectLayerData[directionCode]) {
|
|
491
|
+
const { matrix } = JSON.parse(frameData.json);
|
|
492
|
+
const frameIndexColorMatrix = [];
|
|
493
|
+
let indexRow = -1;
|
|
494
|
+
for (const row of matrix) {
|
|
495
|
+
indexRow++;
|
|
496
|
+
frameIndexColorMatrix[indexRow] = [];
|
|
497
|
+
let indexCol = -1;
|
|
498
|
+
for (const value of row) {
|
|
499
|
+
indexCol++;
|
|
500
|
+
let colorIndex = objectLayer.data.render.color.findIndex(
|
|
501
|
+
(color) =>
|
|
502
|
+
color[0] === value[0] && color[1] === value[1] && color[2] === value[2] && color[3] === value[3],
|
|
503
|
+
);
|
|
504
|
+
if (colorIndex === -1) {
|
|
505
|
+
objectLayer.data.render.color.push(value);
|
|
506
|
+
colorIndex = objectLayer.data.render.color.length - 1;
|
|
144
507
|
}
|
|
508
|
+
frameIndexColorMatrix[indexRow][indexCol] = colorIndex;
|
|
145
509
|
}
|
|
146
|
-
objectLayer.data.render.frames[direction].push(frameIndexColorMatrix);
|
|
147
510
|
}
|
|
511
|
+
objectLayer.data.render.frames[direction].push(frameIndexColorMatrix);
|
|
148
512
|
}
|
|
149
513
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
514
|
+
}
|
|
515
|
+
objectLayer.data.render.frame_duration = parseInt(s(`.ol-input-render-frame-duration`).value);
|
|
516
|
+
objectLayer.data.render.is_stateless = renderIsStateless;
|
|
517
|
+
objectLayer.data.stats = {
|
|
518
|
+
effect: parseInt(s(`.ol-input-item-stats-effect`).value),
|
|
519
|
+
resistance: parseInt(s(`.ol-input-item-stats-resistance`).value),
|
|
520
|
+
agility: parseInt(s(`.ol-input-item-stats-agility`).value),
|
|
521
|
+
range: parseInt(s(`.ol-input-item-stats-range`).value),
|
|
522
|
+
intelligence: parseInt(s(`.ol-input-item-stats-intelligence`).value),
|
|
523
|
+
utility: parseInt(s(`.ol-input-item-stats-utility`).value),
|
|
524
|
+
};
|
|
525
|
+
objectLayer.data.item = {
|
|
526
|
+
type: selectItemType,
|
|
527
|
+
activable: itemActivable,
|
|
528
|
+
id: s(`.ol-input-item-id`).value,
|
|
529
|
+
description: s(`.ol-input-item-description`).value,
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
// Add _id if we're updating an existing object layer
|
|
533
|
+
if (existingObjectLayerId) {
|
|
534
|
+
objectLayer._id = existingObjectLayerId;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
console.warn('objectLayer', objectLayer, existingObjectLayerId ? '(UPDATE MODE)' : '(CREATE MODE)');
|
|
538
|
+
|
|
539
|
+
if (Elements.Data.user.main.model.user.role === 'guest') {
|
|
540
|
+
NotificationManager.Push({
|
|
541
|
+
html: 'Guests cannot save object layers. Please log in.',
|
|
542
|
+
status: 'warning',
|
|
543
|
+
});
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Upload images
|
|
548
|
+
{
|
|
549
|
+
// Get all direction codes that currently have frames
|
|
550
|
+
const directionCodesToUpload = Object.keys(ObjectLayerEngineModal.ObjectLayerData);
|
|
551
|
+
|
|
552
|
+
// In UPDATE mode, also include original direction codes that may have been cleared
|
|
553
|
+
const allDirectionCodes = existingObjectLayerId
|
|
554
|
+
? [...new Set([...directionCodesToUpload, ...originalDirectionCodes])]
|
|
555
|
+
: directionCodesToUpload;
|
|
556
|
+
|
|
557
|
+
console.warn(
|
|
558
|
+
`Uploading frames for ${allDirectionCodes.length} directions:`,
|
|
559
|
+
allDirectionCodes,
|
|
560
|
+
existingObjectLayerId ? '(UPDATE MODE)' : '(CREATE MODE)',
|
|
561
|
+
);
|
|
562
|
+
|
|
563
|
+
for (const directionCode of allDirectionCodes) {
|
|
564
|
+
const frames = ObjectLayerEngineModal.ObjectLayerData[directionCode] || [];
|
|
565
|
+
console.warn(`Direction ${directionCode}: ${frames.length} frames`);
|
|
566
|
+
|
|
567
|
+
// Create FormData with ALL frames for this direction
|
|
568
|
+
const form = new FormData();
|
|
569
|
+
let frameIndex = -1;
|
|
570
|
+
for (const frame of frames) {
|
|
571
|
+
frameIndex++;
|
|
572
|
+
const pngBlob = frame.image;
|
|
573
|
+
|
|
574
|
+
if (!pngBlob) {
|
|
575
|
+
console.error(`Frame ${frameIndex} in direction ${directionCode} has no image blob!`);
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Append all frames to the same FormData
|
|
580
|
+
form.append(directionCode, pngBlob, `${frameIndex}.png`);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Send all frames for this direction in one request (even if empty, to remove frames)
|
|
584
|
+
try {
|
|
585
|
+
if (existingObjectLayerId) {
|
|
586
|
+
// UPDATE: use PUT endpoint with object layer ID
|
|
587
|
+
const { status, data } = await ObjectLayerService.put({
|
|
588
|
+
id: `${existingObjectLayerId}/frame-image/${objectLayer.data.item.type}/${objectLayer.data.item.id}/${directionCode}`,
|
|
181
589
|
body: form,
|
|
182
590
|
headerId: 'file',
|
|
183
591
|
});
|
|
592
|
+
console.warn(`Updated ${frames.length} frames for direction ${directionCode}`);
|
|
593
|
+
} else {
|
|
594
|
+
// CREATE: use POST endpoint (only if frames exist)
|
|
595
|
+
if (frames.length > 0) {
|
|
596
|
+
const { status, data } = await ObjectLayerService.post({
|
|
597
|
+
id: `frame-image/${objectLayer.data.item.type}/${objectLayer.data.item.id}/${directionCode}`,
|
|
598
|
+
body: form,
|
|
599
|
+
headerId: 'file',
|
|
600
|
+
});
|
|
601
|
+
console.warn(`Created ${frames.length} frames for direction ${directionCode}`);
|
|
602
|
+
}
|
|
184
603
|
}
|
|
604
|
+
} catch (error) {
|
|
605
|
+
console.error(`Error uploading frames for direction ${directionCode}:`, error);
|
|
606
|
+
NotificationManager.Push({
|
|
607
|
+
html: `Error uploading frames for direction ${directionCode}: ${error.message}`,
|
|
608
|
+
status: 'error',
|
|
609
|
+
});
|
|
610
|
+
return;
|
|
185
611
|
}
|
|
186
612
|
}
|
|
187
613
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
614
|
+
console.warn('All frames uploaded successfully');
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// Upload metadata
|
|
618
|
+
{
|
|
619
|
+
delete objectLayer.data.render.frames;
|
|
620
|
+
delete objectLayer.data.render.color;
|
|
621
|
+
|
|
622
|
+
let response;
|
|
623
|
+
if (existingObjectLayerId) {
|
|
624
|
+
// UPDATE existing object layer
|
|
625
|
+
console.warn(
|
|
626
|
+
'PUT path:',
|
|
627
|
+
`${existingObjectLayerId}/metadata/${objectLayer.data.item.type}/${objectLayer.data.item.id}`,
|
|
628
|
+
);
|
|
629
|
+
response = await ObjectLayerService.put({
|
|
630
|
+
id: `${existingObjectLayerId}/metadata/${objectLayer.data.item.type}/${objectLayer.data.item.id}`,
|
|
631
|
+
body: objectLayer,
|
|
632
|
+
});
|
|
633
|
+
} else {
|
|
634
|
+
// CREATE new object layer
|
|
635
|
+
response = await ObjectLayerService.post({
|
|
193
636
|
id: `metadata/${objectLayer.data.item.type}/${objectLayer.data.item.id}`,
|
|
194
637
|
body: objectLayer,
|
|
195
638
|
});
|
|
196
639
|
}
|
|
197
|
-
|
|
640
|
+
|
|
641
|
+
const { status, data, message } = response;
|
|
642
|
+
|
|
643
|
+
if (status === 'success') {
|
|
644
|
+
NotificationManager.Push({
|
|
645
|
+
html: `Object layer "${objectLayer.data.item.id}" ${existingObjectLayerId ? 'updated' : 'created'} successfully!`,
|
|
646
|
+
status: 'success',
|
|
647
|
+
});
|
|
648
|
+
ObjectLayerEngineModal.toManagement();
|
|
649
|
+
} else {
|
|
650
|
+
NotificationManager.Push({
|
|
651
|
+
html: `Error ${existingObjectLayerId ? 'updating' : 'creating'} object layer: ${message}`,
|
|
652
|
+
status: 'error',
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
}
|
|
198
656
|
});
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
class: `direction-code-bar-frames-btn-${directionCode}`,
|
|
208
|
-
})}
|
|
657
|
+
|
|
658
|
+
// Add reset button event listener
|
|
659
|
+
EventsUI.onClick(`.ol-btn-reset`, async () => {
|
|
660
|
+
const confirmResult = await Modal.RenderConfirm({
|
|
661
|
+
html: async () => {
|
|
662
|
+
return html`
|
|
663
|
+
<div class="in section-mp" style="text-align: center">
|
|
664
|
+
Are you sure you want to reset the form? All unsaved data will be lost.
|
|
209
665
|
</div>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
`;
|
|
215
|
-
}
|
|
666
|
+
`;
|
|
667
|
+
},
|
|
668
|
+
id: `reset-ol-modal-confirm`,
|
|
669
|
+
});
|
|
216
670
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
671
|
+
if (confirmResult.status === 'confirm') {
|
|
672
|
+
NotificationManager.Push({
|
|
673
|
+
html: 'Resetting form to create new object layer...',
|
|
674
|
+
status: 'info',
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
// Clear all data
|
|
678
|
+
ObjectLayerEngineModal.clearData();
|
|
679
|
+
|
|
680
|
+
setPath(`${getProxyPath()}object-layer-engine`);
|
|
681
|
+
|
|
682
|
+
// Reload the modal
|
|
683
|
+
await ObjectLayerEngineModal.Reload();
|
|
684
|
+
|
|
685
|
+
NotificationManager.Push({
|
|
686
|
+
html: 'Form reset! Ready to create new object layer.',
|
|
687
|
+
status: 'success',
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
});
|
|
234
692
|
|
|
235
693
|
return html`
|
|
236
694
|
<style>
|
|
@@ -243,6 +701,7 @@ const ObjectLayerEngineModal = {
|
|
|
243
701
|
width: 100px;
|
|
244
702
|
height: auto;
|
|
245
703
|
margin: 3px;
|
|
704
|
+
cursor: pointer;
|
|
246
705
|
}
|
|
247
706
|
.direction-code-bar-trash-btn {
|
|
248
707
|
top: 3px;
|
|
@@ -251,9 +710,16 @@ const ObjectLayerEngineModal = {
|
|
|
251
710
|
color: white;
|
|
252
711
|
}
|
|
253
712
|
.ol-btn-save {
|
|
713
|
+
width: 120px;
|
|
254
714
|
padding: 0.5rem;
|
|
255
|
-
font-size:
|
|
256
|
-
|
|
715
|
+
font-size: 20px;
|
|
716
|
+
min-height: 50px;
|
|
717
|
+
}
|
|
718
|
+
.ol-btn-reset {
|
|
719
|
+
width: 120px;
|
|
720
|
+
padding: 0.5rem;
|
|
721
|
+
font-size: 20px;
|
|
722
|
+
min-height: 50px;
|
|
257
723
|
}
|
|
258
724
|
.ol-number-label {
|
|
259
725
|
width: 120px;
|
|
@@ -264,10 +730,34 @@ const ObjectLayerEngineModal = {
|
|
|
264
730
|
.sub-title-modal {
|
|
265
731
|
color: #ffcc00;
|
|
266
732
|
}
|
|
733
|
+
.stat-label-container {
|
|
734
|
+
display: flex;
|
|
735
|
+
align-items: center;
|
|
736
|
+
}
|
|
737
|
+
.stat-info-icon {
|
|
738
|
+
cursor: default;
|
|
739
|
+
}
|
|
740
|
+
.stat-description {
|
|
741
|
+
padding: 2px 5px;
|
|
742
|
+
border-left: 2px solid #444;
|
|
743
|
+
margin-bottom: 5px;
|
|
744
|
+
max-width: 200px;
|
|
745
|
+
}
|
|
746
|
+
.frame-editor-container-loading {
|
|
747
|
+
width: 100%;
|
|
748
|
+
height: 150px;
|
|
749
|
+
color: #ffcc00;
|
|
750
|
+
}
|
|
751
|
+
.loading-text {
|
|
752
|
+
font-family: 'retro-font';
|
|
753
|
+
font-size: 26px;
|
|
754
|
+
}
|
|
267
755
|
</style>
|
|
268
|
-
${borderChar(2, 'black', ['.sub-title-modal'])}
|
|
269
|
-
|
|
270
|
-
|
|
756
|
+
${borderChar(2, 'black', ['.sub-title-modal', '.frame-editor-container-loading'])}
|
|
757
|
+
<div class="in frame-editor-container-loading">
|
|
758
|
+
<div class="abs center frame-editor-container-loading-center"></div>
|
|
759
|
+
</div>
|
|
760
|
+
<div class="in section-mp section-mp-border frame-editor-container">
|
|
271
761
|
<div class="in sub-title-modal"><i class="fa-solid fa-table-cells-large"></i> Frame editor</div>
|
|
272
762
|
|
|
273
763
|
<object-layer-engine id="ole" width="${cells}" height="${cells}" pixel-size="${pixelSize}">
|
|
@@ -346,16 +836,18 @@ const ObjectLayerEngineModal = {
|
|
|
346
836
|
label: html`<i class="fa-solid fa-pen-to-square"></i> ${Translate.Render('item-id')}`,
|
|
347
837
|
containerClass: '',
|
|
348
838
|
placeholder: true,
|
|
839
|
+
value: loadedData?.metadata?.data?.item?.id || '',
|
|
349
840
|
})}
|
|
350
841
|
${await Input.Render({
|
|
351
842
|
id: `ol-input-item-description`,
|
|
352
843
|
label: html`<i class="fa-solid fa-pen-to-square"></i> ${Translate.Render('item-description')}`,
|
|
353
844
|
containerClass: '',
|
|
354
845
|
placeholder: true,
|
|
846
|
+
value: loadedData?.metadata?.data?.item?.description || '',
|
|
355
847
|
})}
|
|
356
848
|
<div class="in section-mp">
|
|
357
849
|
${await DropDown.Render({
|
|
358
|
-
value:
|
|
850
|
+
value: selectItemType,
|
|
359
851
|
label: html`${Translate.Render('select-item-type')}`,
|
|
360
852
|
data: itemTypes.map((itemType) => {
|
|
361
853
|
return {
|
|
@@ -398,12 +890,17 @@ const ObjectLayerEngineModal = {
|
|
|
398
890
|
</div>
|
|
399
891
|
</div>
|
|
400
892
|
|
|
401
|
-
<div class="
|
|
893
|
+
<div class="fl section-mp">
|
|
402
894
|
${await BtnIcon.Render({
|
|
403
|
-
label: html`<i class="fa-solid fa-
|
|
895
|
+
label: html`<i class="submit-btn-icon fa-solid fa-folder-open"></i> ${Translate.Render('save')}`,
|
|
404
896
|
class: `in flr ol-btn-save`,
|
|
405
897
|
})}
|
|
898
|
+
${await BtnIcon.Render({
|
|
899
|
+
label: html`<i class="submit-btn-icon fa-solid fa-broom"></i> ${Translate.Render('reset')}`,
|
|
900
|
+
class: `in flr ol-btn-reset`,
|
|
901
|
+
})}
|
|
406
902
|
</div>
|
|
903
|
+
<div class="in section-mp"></div>
|
|
407
904
|
`;
|
|
408
905
|
},
|
|
409
906
|
getDirectionsFromDirectionCode(directionCode = '08') {
|
|
@@ -438,6 +935,47 @@ const ObjectLayerEngineModal = {
|
|
|
438
935
|
|
|
439
936
|
return objectLayerFrameDirections;
|
|
440
937
|
},
|
|
938
|
+
toManagement: async () => {
|
|
939
|
+
await ObjectLayerEngineModal.clearData();
|
|
940
|
+
const queryParams = getQueryParams();
|
|
941
|
+
queryParams.page = 1;
|
|
942
|
+
setQueryParams(queryParams);
|
|
943
|
+
const managerComponent = DefaultManagement.Tokens['modal-object-layer-engine-management'];
|
|
944
|
+
if (managerComponent) {
|
|
945
|
+
managerComponent.page = 1;
|
|
946
|
+
if (!managerComponent.readyRowDataEvent) managerComponent.readyRowDataEvent = {};
|
|
947
|
+
let readyLoad = false;
|
|
948
|
+
const gridId = 'object-layer-engine-management-grid-modal-object-layer-engine-management';
|
|
949
|
+
managerComponent.readyRowDataEvent['object-layer-engine-management'] = async () => {
|
|
950
|
+
if (readyLoad) {
|
|
951
|
+
AgGrid.grids[gridId].setGridOption('getRowClass', null);
|
|
952
|
+
return delete managerComponent.readyRowDataEvent['object-layer-engine-management'];
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
AgGrid.grids[gridId].setGridOption('getRowClass', (params) => {
|
|
956
|
+
if (params.node.rowIndex === 0) {
|
|
957
|
+
return 'row-new-highlight';
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
readyLoad = true;
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const _s = s(`.management-table-btn-reload-modal-object-layer-engine-management`);
|
|
965
|
+
if (_s) _s.click();
|
|
966
|
+
|
|
967
|
+
s(`.main-btn-object-layer-engine-management`).click();
|
|
968
|
+
},
|
|
969
|
+
Reload: async function () {
|
|
970
|
+
// Clear data before reload to prevent contamination
|
|
971
|
+
ObjectLayerEngineModal.clearData();
|
|
972
|
+
const idModal = 'modal-object-layer-engine';
|
|
973
|
+
if (s(`.modal-object-layer-engine`))
|
|
974
|
+
Modal.writeHTML({
|
|
975
|
+
idModal,
|
|
976
|
+
html: await Modal.Data[idModal].options.html(),
|
|
977
|
+
});
|
|
978
|
+
},
|
|
441
979
|
};
|
|
442
980
|
|
|
443
981
|
export { ObjectLayerEngineModal };
|