Everything outside Addin funcitonnal - good generation of the yaml file
This commit is contained in:
parent
cb291719d7
commit
70dc28e69c
59
index.html
59
index.html
@ -239,6 +239,7 @@
|
||||
<button class="tab-btn" data-tab="counters" id="counters-tab-btn">Counters</button>
|
||||
<button class="tab-btn" data-tab="setpoints" id="setpoints-tab-btn">Setpoints</button>
|
||||
<button class="tab-btn" data-tab="realtime" id="realtime-tab-btn">Real Time Variables</button>
|
||||
<button class="tab-btn" data-tab="states" id="states-tab-btn">States</button>
|
||||
</nav>
|
||||
|
||||
<form id="machine-form">
|
||||
@ -515,9 +516,56 @@
|
||||
</table>
|
||||
<button type="button" class="add-row-btn" id="add-realtime-btn">Add Real Time Variable</button>
|
||||
</fieldset>
|
||||
<input type="submit" value="Validate and Submit Description">
|
||||
<button type="button" class="next-tab-btn">Next</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="states-tab" class="tab-content">
|
||||
<fieldset>
|
||||
<legend>States Exposed by the Machine</legend>
|
||||
<p>The first four states are predefined by PackML and are mandatory. You can add more states as needed.</p>
|
||||
<table class="dynamic-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-id">ID</th>
|
||||
<th class="col-name">Name</th>
|
||||
<th>Description</th>
|
||||
<th class="col-description">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody> <!-- Predefined states -->
|
||||
<tr>
|
||||
<td><input type="text" value="1" disabled></td>
|
||||
<td><input type="text" value="StateCurrent" disabled></td>
|
||||
<td><textarea rows="2" cols="50" disabled>Current state of the packML State Machine defined as an enumeration described in EOS-002-OPEN-202</textarea></td>
|
||||
<td><span style="color: #999;">Predefined</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" value="2" disabled></td>
|
||||
<td><input type="text" value="ModeCurrent" disabled></td>
|
||||
<td><textarea rows="2" cols="50" disabled>Current Mode of the packML State Machine defined as an enumeration described in EOS-002-OPEN-202</textarea></td>
|
||||
<td><span style="color: #999;">Predefined</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" value="3" disabled></td>
|
||||
<td><input type="text" value="EquipmentInterlock : Blocked" disabled></td>
|
||||
<td><textarea rows="3" cols="50" disabled>If TRUE, then processing is suspended because downstream equipment is unable to receive material (e.g. downstream buffer is full)</textarea></td>
|
||||
<td><span style="color: #999;">Predefined</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" value="4" disabled></td>
|
||||
<td><input type="text" value="EquipmentInterlock : Starved" disabled></td>
|
||||
<td><textarea rows="2" cols="50" disabled>If TRUE, then processing is suspended because upstream equipment is unable to send material.</textarea></td>
|
||||
<td><span style="color: #999;">Predefined</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody id="states-table-body"></tbody>
|
||||
</table>
|
||||
<button type="button" id="add-state-btn" class="add-row-btn" style="width:auto;">Add States</button>
|
||||
</fieldset>
|
||||
<button type="button" class="next-tab-btn" style="visibility: hidden;">Next</button>
|
||||
<input type="submit" value="Validate and Submit Description">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -572,6 +620,15 @@
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<template id="state-row-template">
|
||||
<tr>
|
||||
<td><input type="number" name="state_id" min="5" placeholder="e.g., 5"></td>
|
||||
<td><input type="text" name="state_name" placeholder="e.g., CUSTOM_STATE"></td>
|
||||
<td><textarea name="state_description" rows="1" cols="50" placeholder="Description of the state"></textarea></td>
|
||||
<td class="col-actions"><button type="button" class="remove-row-btn">Remove</button></td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script src="renderer.js"></script>
|
||||
|
||||
157
main.js
157
main.js
@ -16,17 +16,14 @@ const createWindow = () => {
|
||||
});
|
||||
|
||||
win.maximize();
|
||||
|
||||
win.loadFile('index.html');
|
||||
win.webContents.openDevTools();
|
||||
// win.webContents.openDevTools(); // You can comment this out for production
|
||||
};
|
||||
|
||||
app.whenReady().then(() => {
|
||||
ipcMain.handle('form:submit', (event, data) => {
|
||||
console.log('--- Data received in main.js ---', data);
|
||||
|
||||
// --- YAML Generation by Building an Array of Lines ---
|
||||
|
||||
// Define spacing constants for indentation
|
||||
const sp2 = ' ';
|
||||
const sp4 = ' ';
|
||||
@ -36,7 +33,9 @@ app.whenReady().then(() => {
|
||||
// Create an array to hold each line of the YAML file
|
||||
const yamlLines = [];
|
||||
|
||||
// Build the 'machine' section line by line
|
||||
// --- Build the YAML content section by section ---
|
||||
|
||||
// 1. Build the 'machine' section
|
||||
const machineType = data.machineType || 'Unspecified';
|
||||
const machineModel = data.model || '';
|
||||
const serialNo = data.serialNo || '';
|
||||
@ -52,56 +51,66 @@ app.whenReady().then(() => {
|
||||
yamlLines.push(`${sp4}yearofconstruction: "${data.buildYear || ''}"`);
|
||||
yamlLines.push(`${sp2}version: "${data.version || 'Unset'}"`);
|
||||
|
||||
// 2. Build the 'alarms' section from the alarms data
|
||||
// 2. Build the 'alarms' section
|
||||
if (data.alarms) {
|
||||
yamlLines.push(''); // Blank line for separation
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}alarms:`);
|
||||
yamlLines.push(`${sp4}packing: OBJECTS`); // As per PowerShell script logic
|
||||
yamlLines.push(`${sp4}packing: ${data.alarmPacking || 'OBJECTS'}`);
|
||||
yamlLines.push(`${sp4}behavior: ${data.alarmBehavior || 'STATIC'}`);
|
||||
yamlLines.push(`${sp4}count: ${data.alarmCount}`);
|
||||
if (data.alarms.length > 0) {
|
||||
yamlLines.push(`${sp4}alarms: `); // Note the trailing space
|
||||
data.alarms.forEach(alarm => {
|
||||
const id = alarm.id || 0;
|
||||
const name = alarm.name || `Alarm_${id}`;
|
||||
const message = alarm.message.replace(/:/g, ';'); // Sanitize message as in PowerShell
|
||||
|
||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||
yamlLines.push(`${sp8}name: ${name}`);
|
||||
yamlLines.push(`${sp8}message: ${message}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//3. Build the 'warning' section from the warnings data
|
||||
if (data.warnings && data.warnings.length > 0) {
|
||||
yamlLines.push(''); // Blank line for separation
|
||||
yamlLines.push(`${sp2}warnings:`);
|
||||
yamlLines.push(`${sp4}count: ${data.warnings.length}`);
|
||||
yamlLines.push(`${sp4}warnings: `); // Note the trailing space
|
||||
|
||||
data.warnings.forEach(warning => {
|
||||
const id = warning.id || 0;
|
||||
const name = warning.name || `Warning_${id}`;
|
||||
const message = warning.message.replace(/:/g, ';'); // Sanitize message as in PowerShell
|
||||
|
||||
yamlLines.push(`${sp4}count: ${data.alarmCount || data.alarms.length}`);
|
||||
yamlLines.push(`${sp4}alarms:`);
|
||||
data.alarms.forEach(alarm => {
|
||||
const id = alarm.id || 0;
|
||||
const name = alarm.name || `Alarm_${id}`;
|
||||
const message = (alarm.message || '').replace(/:/g, ';');
|
||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||
yamlLines.push(`${sp8}name: ${name}`);
|
||||
yamlLines.push(`${sp8}message: ${message}`);
|
||||
});
|
||||
}
|
||||
|
||||
//Build the 'counters' section from the counters data
|
||||
if (data.counters && data.counters.length > 0) {
|
||||
yamlLines.push(''); // Blank line for separation
|
||||
yamlLines.push(`${sp2}counters:`);
|
||||
// 3. Build the 'warnings' section
|
||||
if (data.warnings && data.warnings.length > 0) {
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}warnings:`);
|
||||
yamlLines.push(`${sp4}packing: ${data.warningPacking || 'OBJECTS'}`);
|
||||
yamlLines.push(`${sp4}behavior: ${data.warningBehavior || 'STATIC'}`);
|
||||
yamlLines.push(`${sp4}count: ${data.warningCount || data.warnings.length}`);
|
||||
yamlLines.push(`${sp4}warnings:`);
|
||||
data.warnings.forEach(warning => {
|
||||
const id = warning.id || 0;
|
||||
const name = warning.name || `Warning_${id}`;
|
||||
const message = (warning.message || '').replace(/:/g, ';');
|
||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||
yamlLines.push(`${sp8}name: ${name}`);
|
||||
yamlLines.push(`${sp8}message: ${message}`);
|
||||
});
|
||||
}
|
||||
|
||||
// 4. Build the 'states' section
|
||||
if (data.states && data.states.length > 0) {
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}states:`);
|
||||
yamlLines.push(`${sp4}states:`);
|
||||
data.states.forEach(state => {
|
||||
const id = state.id || 0;
|
||||
const name = state.name || `State_${id}`;
|
||||
const description = (state.description || '').replace(/:/g, ';');
|
||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||
yamlLines.push(`${sp8}name: ${name}`);
|
||||
yamlLines.push(`${sp8}description: ${description}`);
|
||||
});
|
||||
}
|
||||
|
||||
// 5. Build the 'counters' section
|
||||
if (data.counters && data.counters.length > 0) {
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}counters:`);
|
||||
data.counters.forEach(counter => {
|
||||
const id = counter.id || 0;
|
||||
const name = counter.name || `Counter_${id}`;
|
||||
const type = counter.type || '';
|
||||
const description = counter.description || '';
|
||||
|
||||
const description = (counter.description || '').replace(/:/g, ';');
|
||||
yamlLines.push(`${sp4}- name: ${name}`);
|
||||
yamlLines.push(`${sp6}ID: ${id}`);
|
||||
yamlLines.push(`${sp6}type: ${type}`);
|
||||
@ -109,20 +118,48 @@ app.whenReady().then(() => {
|
||||
});
|
||||
}
|
||||
|
||||
// Build and Append the 'optionals' section if needed
|
||||
// 6. Build the 'setpoints' section
|
||||
if (data.setpoints && data.setpoints.length > 0) {
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}setpoints:`);
|
||||
yamlLines.push(`${sp4}setpoints:`);
|
||||
data.setpoints.forEach(setpoint => {
|
||||
const id = setpoint.id || 0;
|
||||
const name = setpoint.name || `Setpoint_${id}`;
|
||||
const message = (setpoint.message || '').replace(/:/g, ';');
|
||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||
yamlLines.push(`${sp8}name: ${name}`);
|
||||
yamlLines.push(`${sp8}message: ${message}`);
|
||||
});
|
||||
}
|
||||
|
||||
// 7. Build the 'realtimes' section
|
||||
if (data.realtime && data.realtime.length > 0) {
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}realtimes:`);
|
||||
yamlLines.push(`${sp4}realtimes:`);
|
||||
data.realtime.forEach(rt => {
|
||||
const id = rt.id || 0;
|
||||
const name = rt.name || `Realtime_${id}`;
|
||||
const message = (rt.message || '').replace(/:/g, ';');
|
||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||
yamlLines.push(`${sp8}name: ${name}`);
|
||||
yamlLines.push(`${sp8}message: ${message}`);
|
||||
});
|
||||
}
|
||||
|
||||
// 8. Build the 'optionals' section
|
||||
if (data.stopReason === 'Yes') {
|
||||
yamlLines.push(''); // Add a blank line for spacing
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}optionals:`);
|
||||
yamlLines.push(`${sp4}- StopReason`);
|
||||
}
|
||||
|
||||
// Build and Append the 'addins' section if needed
|
||||
const selectedAddins = data.addins || []; // Default to an empty array
|
||||
|
||||
// 9. Build the 'addins' section
|
||||
const selectedAddins = data.addins || [];
|
||||
if (selectedAddins.length > 0) {
|
||||
yamlLines.push('');
|
||||
yamlLines.push(`${sp2}addins:`);
|
||||
|
||||
if (selectedAddins.includes('AcPower')) {
|
||||
yamlLines.push(`${sp4}- name: AcPower`);
|
||||
}
|
||||
@ -135,36 +172,19 @@ app.whenReady().then(() => {
|
||||
yamlLines.push(`${sp6}# Requires data from a future 'TrackAdvance ADDIN' UI.`);
|
||||
}
|
||||
if (selectedAddins.includes('AGV')) {
|
||||
yamlLines.push(`${sp4}- name: AGV`);
|
||||
yamlLines.push(`${sp6}# Requires data from a future 'AGV ADDIN' UI.`);
|
||||
yamlLines.push(`${sp4}- name: AGV`);
|
||||
yamlLines.push(`${sp6}# Requires data from a future 'AGV ADDIN' UI.`);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Join all the generated lines into a single string
|
||||
// --- Finalize and Save the File ---
|
||||
const generatedContent = yamlLines.join('\n');
|
||||
|
||||
// --- End of YAML Generation Logic ---
|
||||
|
||||
console.log('--- Generated YAML Content ---\n', generatedContent);
|
||||
|
||||
// File saving logic
|
||||
const nameParts = [
|
||||
data.machineType,
|
||||
data.vendor,
|
||||
data.model,
|
||||
data.serialNo,
|
||||
data.browseName
|
||||
];
|
||||
|
||||
// Filter out any empty or null values
|
||||
const nameParts = [data.machineType, data.vendor, data.model, data.serialNo, data.browseName];
|
||||
const nonEmptyParts = nameParts.filter(Boolean);
|
||||
|
||||
// Join the parts with an underscore
|
||||
const baseName = nonEmptyParts.join('_');
|
||||
|
||||
// Sanitize the final string to remove characters invalid for filenames, but keep underscores and hyphens.
|
||||
const safeBaseName = baseName.replace(/[/\\?%*:|"<>]/g, '-');
|
||||
|
||||
const yamlFileName = `${safeBaseName}.yml`;
|
||||
const documentsPath = app.getPath('documents');
|
||||
const yamlFilePath = path.join(documentsPath, yamlFileName);
|
||||
@ -188,4 +208,5 @@ app.whenReady().then(() => {
|
||||
createWindow();
|
||||
app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); });
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });
|
||||
203
renderer.js
203
renderer.js
@ -31,6 +31,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
fields, // Array of field names in order (e.g. ['alarm_id', 'alarm_name', 'alarm_message'])
|
||||
prefix, // e.g. 'ALARM'
|
||||
nameFormat, // e.g. (id, paddedId) => `ALARM_${paddedId}`
|
||||
initialRow = true, // Number of initial rows to add
|
||||
}) {
|
||||
const tableBody = document.getElementById(tableBodyId);
|
||||
const rowTemplate = document.getElementById(templateId);
|
||||
@ -38,7 +39,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const bulkBtn = bulkBtnId ? document.getElementById(bulkBtnId) : null;
|
||||
|
||||
// Add initial row
|
||||
addRow(tableBody, rowTemplate, 1, fields, prefix, nameFormat);
|
||||
if (initialRow) {
|
||||
addRow(tableBody, rowTemplate, 1, fields, prefix, nameFormat);
|
||||
}
|
||||
|
||||
// Bulk add
|
||||
if (bulkBtn && bulkInput) {
|
||||
@ -55,6 +58,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
addRow(tableBody, rowTemplate, maxId + i, fields, prefix, nameFormat);
|
||||
}
|
||||
});
|
||||
} else if (bulkBtn){
|
||||
bulkBtn.addEventListener('click', () => {
|
||||
const currentIdInputs = tableBody.querySelectorAll(`[name="${fields[0]}"]`);
|
||||
let maxId = 0;
|
||||
currentIdInputs.forEach(input => {
|
||||
const currentId = parseInt(input.value, 10);
|
||||
if (!isNaN(currentId) && currentId > maxId) maxId = currentId;
|
||||
});
|
||||
addRow(tableBody, rowTemplate, maxId + 1, fields, prefix, nameFormat);
|
||||
});
|
||||
}
|
||||
|
||||
// Paste from Excel
|
||||
@ -147,7 +160,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
bulkBtnId: 'add-multiple-alarms-btn',
|
||||
fields: ['alarm_id', 'alarm_name', 'alarm_message'],
|
||||
prefix: 'ALARM',
|
||||
nameFormat: (id, paddedId) => `ALARM_${paddedId}`
|
||||
nameFormat: (id, paddedId) => `ALARM_${paddedId}`,
|
||||
initialRow: true
|
||||
});
|
||||
|
||||
// --- WARNINGS ---
|
||||
@ -158,7 +172,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
bulkBtnId: 'add-multiple-warnings-btn',
|
||||
fields: ['warning_id', 'warning_name', 'warning_message'],
|
||||
prefix: 'WARNING',
|
||||
nameFormat: (id, paddedId) => `WARNING_${paddedId}`
|
||||
nameFormat: (id, paddedId) => `WARNING_${paddedId}`,
|
||||
initialRow: true
|
||||
});
|
||||
|
||||
// --- COUNTERS ---
|
||||
@ -166,10 +181,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
tableBodyId: 'counters-table-body',
|
||||
templateId: 'counter-row-template',
|
||||
bulkInputId: null, // Add bulk if you want
|
||||
bulkBtnId: null, // Add bulk if you want
|
||||
bulkBtnId: 'add-counter-btn', // Add bulk if you want
|
||||
fields: ['counter_id', 'counter_name', 'counter_type', 'counter_description'],
|
||||
prefix: 'COUNTER',
|
||||
nameFormat: (id, paddedId) => `COUNTER_${paddedId}`
|
||||
nameFormat: (id, paddedId) => `COUNTER_${paddedId}`,
|
||||
initialRow: true
|
||||
});
|
||||
|
||||
// --- SETPOINTS ---
|
||||
@ -177,10 +193,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
tableBodyId: 'setpoints-table-body',
|
||||
templateId: 'setpoint-row-template',
|
||||
bulkInputId: null, // Add bulk if you want
|
||||
bulkBtnId: null, // Add bulk if you want
|
||||
bulkBtnId: 'add-setpoint-btn', // Add bulk if you want
|
||||
fields: ['setpoint_id', 'setpoint_name', 'setpoint_message'],
|
||||
prefix: 'SETPOINT',
|
||||
nameFormat: (id, paddedId) => `SETPOINT_${paddedId}`
|
||||
nameFormat: (id, paddedId) => `SETPOINT_${paddedId}`,
|
||||
initialRow: false
|
||||
});
|
||||
|
||||
// --- REALTIME VARIABLES ---
|
||||
@ -188,93 +205,108 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
tableBodyId: 'realtime-table-body',
|
||||
templateId: 'realtime-row-template',
|
||||
bulkInputId: null, // Add bulk if you want
|
||||
bulkBtnId: null, // Add bulk if you want
|
||||
bulkBtnId: 'add-realtime-btn', // Add bulk if you want
|
||||
fields: ['realtime_id', 'realtime_name', 'realtime_message'],
|
||||
prefix: 'REALTIME',
|
||||
nameFormat: (id, paddedId) => `REALTIME_${paddedId}`
|
||||
nameFormat: (id, paddedId) => `REALTIME_${paddedId}`,
|
||||
initialRow: false
|
||||
});
|
||||
|
||||
// --- 3. FORM SUBMISSION LOGIC ---
|
||||
const form = document.getElementById('machine-form');
|
||||
if (form) {
|
||||
form.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
// --- STATES ---
|
||||
setupDynamicTable({
|
||||
tableBodyId: 'states-table-body',
|
||||
templateId: 'state-row-template',
|
||||
bulkInputId: null,
|
||||
bulkBtnId: 'add-state-btn',
|
||||
fields: ['state_id', 'state_name', 'state_description'],
|
||||
prefix: 'STATE',
|
||||
nameFormat: (id, paddedId) => `STATE_${paddedId}`,
|
||||
initialRow: false
|
||||
});
|
||||
|
||||
// A. Collect data from the main "Machine" tab using FormData
|
||||
const formData = new FormData(form);
|
||||
// Convert FormData to a plain object
|
||||
const mainData = {};
|
||||
for (const [key, value] of formData.entries()) {
|
||||
// This check prevents multi-value fields from overwriting themselves
|
||||
if (!mainData[key]) {
|
||||
mainData[key] = value;
|
||||
// 3. FORM SUBMISSION LOGIC (MODULARIZED)
|
||||
|
||||
/**
|
||||
* Collects data from a dynamic table.
|
||||
* @param {string} tableBodyId - The ID of the table's tbody element.
|
||||
* @param {string[]} fields - An array of field names (name attributes of inputs).
|
||||
* @param {string} keyField - A field name that must have a value for the row to be included.
|
||||
* @returns {Object[]} An array of objects, where each object represents a row.
|
||||
*/
|
||||
const collectTableData = (tableBodyId, fields, keyField) => {
|
||||
const tableBody = document.getElementById(tableBodyId);
|
||||
if (!tableBody) return [];
|
||||
|
||||
const rows = tableBody.querySelectorAll('tr');
|
||||
const data = [];
|
||||
|
||||
rows.forEach(row => {
|
||||
const rowData = {};
|
||||
let hasKeyField = false;
|
||||
fields.forEach(field => {
|
||||
const input = row.querySelector(`[name="${field}"]`);
|
||||
if (input) {
|
||||
rowData[field.split('_').pop()] = input.value;
|
||||
if (field === keyField && input.value) {
|
||||
hasKeyField = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
// Only add the row if the key field is present and has a value
|
||||
if (hasKeyField) {
|
||||
data.push(rowData);
|
||||
}
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
const form = document.getElementById('machine-form');
|
||||
if (form) {
|
||||
form.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
// A. Collect data from the main "Machine" tab using FormData
|
||||
const formData = new FormData(form);
|
||||
const mainData = {};
|
||||
for (const [key, value] of formData.entries()) {
|
||||
// This check prevents multi-value fields (like addins) from being overwritten
|
||||
if (!mainData[key]) {
|
||||
mainData[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
mainData.addins = formData.getAll('addins');
|
||||
|
||||
// B. Collect all alarm rows from the table
|
||||
const alarmRows = alarmsTableBody.querySelectorAll('tr');
|
||||
const alarmsData = [];
|
||||
alarmRows.forEach(row => {
|
||||
const alarm = {
|
||||
id: row.querySelector('[name="alarm_id"]').value,
|
||||
name: row.querySelector('[name="alarm_name"]').value,
|
||||
message: row.querySelector('[name="alarm_message"]').value,
|
||||
mainData.addins = formData.getAll('addins');
|
||||
// B. Collect data from all dynamic tables using the modular function
|
||||
const alarmsData = collectTableData('alarms-table-body', ['alarm_id', 'alarm_name', 'alarm_message'], 'alarm_message');
|
||||
const warningsData = collectTableData('warnings-table-body', ['warning_id', 'warning_name', 'warning_message'], 'warning_message');
|
||||
const statesData = collectTableData('states-table-body', ['state_id', 'state_name', 'state_description'], 'state_description');
|
||||
const countersData = collectTableData('counters-table-body', ['counter_id', 'counter_name', 'counter_type', 'counter_description'], 'counter_type');
|
||||
const setpointsData = collectTableData('setpoints-table-body', ['setpoint_id', 'setpoint_name', 'setpoint_message'], 'setpoint_message');
|
||||
const realtimeData = collectTableData('realtime-table-body', ['realtime_id', 'realtime_name', 'realtime_message'], 'realtime_message');
|
||||
// C. Combine all data into a single object
|
||||
const finalData = {
|
||||
...mainData,
|
||||
alarms: alarmsData,
|
||||
warnings: warningsData,
|
||||
states: statesData,
|
||||
counters: countersData,
|
||||
setpoints: setpointsData,
|
||||
realtime: realtimeData,
|
||||
states: statesData
|
||||
};
|
||||
if (alarm.message) {
|
||||
alarmsData.push(alarm);
|
||||
console.log('Sending all collected data to main process:', finalData);
|
||||
try {
|
||||
const result = await window.electronAPI.submitForm(finalData);
|
||||
if (result.success) {
|
||||
console.log('Form submitted successfully!');
|
||||
// Optionally reset the form or give user feedback
|
||||
// form.reset();
|
||||
// document.getElementById('publicationDate').value = new Date().toISOString().split('T')[0];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during form submission process:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// D. Collect all warning rows from the table
|
||||
const warningRows = warningsTableBody.querySelectorAll('tr');
|
||||
const warningsData = [];
|
||||
warningRows.forEach(row => {
|
||||
const warning = {
|
||||
id: row.querySelector('[name="warning_id"]').value,
|
||||
name: row.querySelector('[name="warning_name"]').value,
|
||||
message: row.querySelector('[name="warning_message"]').value,
|
||||
};
|
||||
if (warning.message) {
|
||||
warningsData.push(warning);
|
||||
}
|
||||
});
|
||||
|
||||
// E. Collect all counter rows from the table
|
||||
const counterRows = countersTableBody.querySelectorAll('tr');
|
||||
const countersData = [];
|
||||
counterRows.forEach(row => {
|
||||
const counter = {
|
||||
id: row.querySelector('[name="counter_id"]').value,
|
||||
name: row.querySelector('[name="counter_name"]').value,
|
||||
type: row.querySelector('[name="counter_type"]').value,
|
||||
description: row.querySelector('[name="counter_description"]').value,
|
||||
};
|
||||
if (counter.type) {
|
||||
countersData.push(counter);
|
||||
}
|
||||
});
|
||||
|
||||
// C. Combine all data into a single object
|
||||
const finalData = { ...mainData, alarms: alarmsData, warnings: warningsData, counters: countersData };
|
||||
|
||||
console.log('Sending all collected data to main process:', finalData);
|
||||
|
||||
try {
|
||||
const result = await window.electronAPI.submitForm(finalData);
|
||||
if (result.success) {
|
||||
// // Reset the entire form to its initial state
|
||||
// form.reset();
|
||||
// // Re-apply the defaults that are not part of the standard reset
|
||||
// document.getElementById('publicationDate').value = new Date().toISOString().split('T')[0];
|
||||
// document.querySelector('#stopReasonYes').checked = true; // Set StopReason back to Yes
|
||||
// updateFilename(); // Clear the filename preview
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during form submission process:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- 4. TAB NAVIGATION BUTTONS ---
|
||||
const tabOrder = [
|
||||
@ -283,7 +315,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
'warnings-tab',
|
||||
'counters-tab',
|
||||
'setpoints-tab',
|
||||
'realtime-tab'
|
||||
'realtime-tab',
|
||||
'states-tab'
|
||||
];
|
||||
|
||||
// Add event listeners to all "Next" buttons
|
||||
|
||||
Loading…
Reference in New Issue
Block a user