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="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="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="realtime" id="realtime-tab-btn">Real Time Variables</button>
|
||||||
|
<button class="tab-btn" data-tab="states" id="states-tab-btn">States</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<form id="machine-form">
|
<form id="machine-form">
|
||||||
@ -515,9 +516,56 @@
|
|||||||
</table>
|
</table>
|
||||||
<button type="button" class="add-row-btn" id="add-realtime-btn">Add Real Time Variable</button>
|
<button type="button" class="add-row-btn" id="add-realtime-btn">Add Real Time Variable</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<input type="submit" value="Validate and Submit Description">
|
<button type="button" class="next-tab-btn">Next</button>
|
||||||
|
|
||||||
</div>
|
</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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -572,6 +620,15 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</template>
|
</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>
|
<script src="renderer.js"></script>
|
||||||
|
|||||||
125
main.js
125
main.js
@ -16,17 +16,14 @@ const createWindow = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
win.maximize();
|
win.maximize();
|
||||||
|
|
||||||
win.loadFile('index.html');
|
win.loadFile('index.html');
|
||||||
win.webContents.openDevTools();
|
// win.webContents.openDevTools(); // You can comment this out for production
|
||||||
};
|
};
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
ipcMain.handle('form:submit', (event, data) => {
|
ipcMain.handle('form:submit', (event, data) => {
|
||||||
console.log('--- Data received in main.js ---', data);
|
console.log('--- Data received in main.js ---', data);
|
||||||
|
|
||||||
// --- YAML Generation by Building an Array of Lines ---
|
|
||||||
|
|
||||||
// Define spacing constants for indentation
|
// Define spacing constants for indentation
|
||||||
const sp2 = ' ';
|
const sp2 = ' ';
|
||||||
const sp4 = ' ';
|
const sp4 = ' ';
|
||||||
@ -36,7 +33,9 @@ app.whenReady().then(() => {
|
|||||||
// Create an array to hold each line of the YAML file
|
// Create an array to hold each line of the YAML file
|
||||||
const yamlLines = [];
|
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 machineType = data.machineType || 'Unspecified';
|
||||||
const machineModel = data.model || '';
|
const machineModel = data.model || '';
|
||||||
const serialNo = data.serialNo || '';
|
const serialNo = data.serialNo || '';
|
||||||
@ -52,56 +51,66 @@ app.whenReady().then(() => {
|
|||||||
yamlLines.push(`${sp4}yearofconstruction: "${data.buildYear || ''}"`);
|
yamlLines.push(`${sp4}yearofconstruction: "${data.buildYear || ''}"`);
|
||||||
yamlLines.push(`${sp2}version: "${data.version || 'Unset'}"`);
|
yamlLines.push(`${sp2}version: "${data.version || 'Unset'}"`);
|
||||||
|
|
||||||
// 2. Build the 'alarms' section from the alarms data
|
// 2. Build the 'alarms' section
|
||||||
if (data.alarms) {
|
if (data.alarms) {
|
||||||
yamlLines.push(''); // Blank line for separation
|
yamlLines.push('');
|
||||||
yamlLines.push(`${sp2}alarms:`);
|
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}behavior: ${data.alarmBehavior || 'STATIC'}`);
|
||||||
yamlLines.push(`${sp4}count: ${data.alarmCount}`);
|
yamlLines.push(`${sp4}count: ${data.alarmCount || data.alarms.length}`);
|
||||||
if (data.alarms.length > 0) {
|
yamlLines.push(`${sp4}alarms:`);
|
||||||
yamlLines.push(`${sp4}alarms: `); // Note the trailing space
|
|
||||||
data.alarms.forEach(alarm => {
|
data.alarms.forEach(alarm => {
|
||||||
const id = alarm.id || 0;
|
const id = alarm.id || 0;
|
||||||
const name = alarm.name || `Alarm_${id}`;
|
const name = alarm.name || `Alarm_${id}`;
|
||||||
const message = alarm.message.replace(/:/g, ';'); // Sanitize message as in PowerShell
|
const message = (alarm.message || '').replace(/:/g, ';');
|
||||||
|
|
||||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||||
yamlLines.push(`${sp8}name: ${name}`);
|
yamlLines.push(`${sp8}name: ${name}`);
|
||||||
yamlLines.push(`${sp8}message: ${message}`);
|
yamlLines.push(`${sp8}message: ${message}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//3. Build the 'warning' section from the warnings data
|
// 3. Build the 'warnings' section
|
||||||
if (data.warnings && data.warnings.length > 0) {
|
if (data.warnings && data.warnings.length > 0) {
|
||||||
yamlLines.push(''); // Blank line for separation
|
yamlLines.push('');
|
||||||
yamlLines.push(`${sp2}warnings:`);
|
yamlLines.push(`${sp2}warnings:`);
|
||||||
yamlLines.push(`${sp4}count: ${data.warnings.length}`);
|
yamlLines.push(`${sp4}packing: ${data.warningPacking || 'OBJECTS'}`);
|
||||||
yamlLines.push(`${sp4}warnings: `); // Note the trailing space
|
yamlLines.push(`${sp4}behavior: ${data.warningBehavior || 'STATIC'}`);
|
||||||
|
yamlLines.push(`${sp4}count: ${data.warningCount || data.warnings.length}`);
|
||||||
|
yamlLines.push(`${sp4}warnings:`);
|
||||||
data.warnings.forEach(warning => {
|
data.warnings.forEach(warning => {
|
||||||
const id = warning.id || 0;
|
const id = warning.id || 0;
|
||||||
const name = warning.name || `Warning_${id}`;
|
const name = warning.name || `Warning_${id}`;
|
||||||
const message = warning.message.replace(/:/g, ';'); // Sanitize message as in PowerShell
|
const message = (warning.message || '').replace(/:/g, ';');
|
||||||
|
|
||||||
yamlLines.push(`${sp6}- ID: ${id}`);
|
yamlLines.push(`${sp6}- ID: ${id}`);
|
||||||
yamlLines.push(`${sp8}name: ${name}`);
|
yamlLines.push(`${sp8}name: ${name}`);
|
||||||
yamlLines.push(`${sp8}message: ${message}`);
|
yamlLines.push(`${sp8}message: ${message}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Build the 'counters' section from the counters data
|
// 4. Build the 'states' section
|
||||||
if (data.counters && data.counters.length > 0) {
|
if (data.states && data.states.length > 0) {
|
||||||
yamlLines.push(''); // Blank line for separation
|
yamlLines.push('');
|
||||||
yamlLines.push(`${sp2}counters:`);
|
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 => {
|
data.counters.forEach(counter => {
|
||||||
const id = counter.id || 0;
|
const id = counter.id || 0;
|
||||||
const name = counter.name || `Counter_${id}`;
|
const name = counter.name || `Counter_${id}`;
|
||||||
const type = counter.type || '';
|
const type = counter.type || '';
|
||||||
const description = counter.description || '';
|
const description = (counter.description || '').replace(/:/g, ';');
|
||||||
|
|
||||||
yamlLines.push(`${sp4}- name: ${name}`);
|
yamlLines.push(`${sp4}- name: ${name}`);
|
||||||
yamlLines.push(`${sp6}ID: ${id}`);
|
yamlLines.push(`${sp6}ID: ${id}`);
|
||||||
yamlLines.push(`${sp6}type: ${type}`);
|
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') {
|
if (data.stopReason === 'Yes') {
|
||||||
yamlLines.push(''); // Add a blank line for spacing
|
yamlLines.push('');
|
||||||
yamlLines.push(`${sp2}optionals:`);
|
yamlLines.push(`${sp2}optionals:`);
|
||||||
yamlLines.push(`${sp4}- StopReason`);
|
yamlLines.push(`${sp4}- StopReason`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build and Append the 'addins' section if needed
|
// 9. Build the 'addins' section
|
||||||
const selectedAddins = data.addins || []; // Default to an empty array
|
const selectedAddins = data.addins || [];
|
||||||
|
|
||||||
if (selectedAddins.length > 0) {
|
if (selectedAddins.length > 0) {
|
||||||
yamlLines.push('');
|
yamlLines.push('');
|
||||||
yamlLines.push(`${sp2}addins:`);
|
yamlLines.push(`${sp2}addins:`);
|
||||||
|
|
||||||
if (selectedAddins.includes('AcPower')) {
|
if (selectedAddins.includes('AcPower')) {
|
||||||
yamlLines.push(`${sp4}- name: AcPower`);
|
yamlLines.push(`${sp4}- name: AcPower`);
|
||||||
}
|
}
|
||||||
@ -140,31 +177,14 @@ app.whenReady().then(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Join all the generated lines into a single string
|
// --- Finalize and Save the File ---
|
||||||
const generatedContent = yamlLines.join('\n');
|
const generatedContent = yamlLines.join('\n');
|
||||||
|
|
||||||
// --- End of YAML Generation Logic ---
|
|
||||||
|
|
||||||
console.log('--- Generated YAML Content ---\n', generatedContent);
|
console.log('--- Generated YAML Content ---\n', generatedContent);
|
||||||
|
|
||||||
// File saving logic
|
const nameParts = [data.machineType, data.vendor, data.model, data.serialNo, data.browseName];
|
||||||
const nameParts = [
|
|
||||||
data.machineType,
|
|
||||||
data.vendor,
|
|
||||||
data.model,
|
|
||||||
data.serialNo,
|
|
||||||
data.browseName
|
|
||||||
];
|
|
||||||
|
|
||||||
// Filter out any empty or null values
|
|
||||||
const nonEmptyParts = nameParts.filter(Boolean);
|
const nonEmptyParts = nameParts.filter(Boolean);
|
||||||
|
|
||||||
// Join the parts with an underscore
|
|
||||||
const baseName = nonEmptyParts.join('_');
|
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 safeBaseName = baseName.replace(/[/\\?%*:|"<>]/g, '-');
|
||||||
|
|
||||||
const yamlFileName = `${safeBaseName}.yml`;
|
const yamlFileName = `${safeBaseName}.yml`;
|
||||||
const documentsPath = app.getPath('documents');
|
const documentsPath = app.getPath('documents');
|
||||||
const yamlFilePath = path.join(documentsPath, yamlFileName);
|
const yamlFilePath = path.join(documentsPath, yamlFileName);
|
||||||
@ -188,4 +208,5 @@ app.whenReady().then(() => {
|
|||||||
createWindow();
|
createWindow();
|
||||||
app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); });
|
app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });
|
app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });
|
||||||
161
renderer.js
161
renderer.js
@ -31,6 +31,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fields, // Array of field names in order (e.g. ['alarm_id', 'alarm_name', 'alarm_message'])
|
fields, // Array of field names in order (e.g. ['alarm_id', 'alarm_name', 'alarm_message'])
|
||||||
prefix, // e.g. 'ALARM'
|
prefix, // e.g. 'ALARM'
|
||||||
nameFormat, // e.g. (id, paddedId) => `ALARM_${paddedId}`
|
nameFormat, // e.g. (id, paddedId) => `ALARM_${paddedId}`
|
||||||
|
initialRow = true, // Number of initial rows to add
|
||||||
}) {
|
}) {
|
||||||
const tableBody = document.getElementById(tableBodyId);
|
const tableBody = document.getElementById(tableBodyId);
|
||||||
const rowTemplate = document.getElementById(templateId);
|
const rowTemplate = document.getElementById(templateId);
|
||||||
@ -38,7 +39,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const bulkBtn = bulkBtnId ? document.getElementById(bulkBtnId) : null;
|
const bulkBtn = bulkBtnId ? document.getElementById(bulkBtnId) : null;
|
||||||
|
|
||||||
// Add initial row
|
// Add initial row
|
||||||
|
if (initialRow) {
|
||||||
addRow(tableBody, rowTemplate, 1, fields, prefix, nameFormat);
|
addRow(tableBody, rowTemplate, 1, fields, prefix, nameFormat);
|
||||||
|
}
|
||||||
|
|
||||||
// Bulk add
|
// Bulk add
|
||||||
if (bulkBtn && bulkInput) {
|
if (bulkBtn && bulkInput) {
|
||||||
@ -55,6 +58,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
addRow(tableBody, rowTemplate, maxId + i, fields, prefix, nameFormat);
|
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
|
// Paste from Excel
|
||||||
@ -147,7 +160,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
bulkBtnId: 'add-multiple-alarms-btn',
|
bulkBtnId: 'add-multiple-alarms-btn',
|
||||||
fields: ['alarm_id', 'alarm_name', 'alarm_message'],
|
fields: ['alarm_id', 'alarm_name', 'alarm_message'],
|
||||||
prefix: 'ALARM',
|
prefix: 'ALARM',
|
||||||
nameFormat: (id, paddedId) => `ALARM_${paddedId}`
|
nameFormat: (id, paddedId) => `ALARM_${paddedId}`,
|
||||||
|
initialRow: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- WARNINGS ---
|
// --- WARNINGS ---
|
||||||
@ -158,7 +172,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
bulkBtnId: 'add-multiple-warnings-btn',
|
bulkBtnId: 'add-multiple-warnings-btn',
|
||||||
fields: ['warning_id', 'warning_name', 'warning_message'],
|
fields: ['warning_id', 'warning_name', 'warning_message'],
|
||||||
prefix: 'WARNING',
|
prefix: 'WARNING',
|
||||||
nameFormat: (id, paddedId) => `WARNING_${paddedId}`
|
nameFormat: (id, paddedId) => `WARNING_${paddedId}`,
|
||||||
|
initialRow: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- COUNTERS ---
|
// --- COUNTERS ---
|
||||||
@ -166,10 +181,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
tableBodyId: 'counters-table-body',
|
tableBodyId: 'counters-table-body',
|
||||||
templateId: 'counter-row-template',
|
templateId: 'counter-row-template',
|
||||||
bulkInputId: null, // Add bulk if you want
|
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'],
|
fields: ['counter_id', 'counter_name', 'counter_type', 'counter_description'],
|
||||||
prefix: 'COUNTER',
|
prefix: 'COUNTER',
|
||||||
nameFormat: (id, paddedId) => `COUNTER_${paddedId}`
|
nameFormat: (id, paddedId) => `COUNTER_${paddedId}`,
|
||||||
|
initialRow: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- SETPOINTS ---
|
// --- SETPOINTS ---
|
||||||
@ -177,10 +193,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
tableBodyId: 'setpoints-table-body',
|
tableBodyId: 'setpoints-table-body',
|
||||||
templateId: 'setpoint-row-template',
|
templateId: 'setpoint-row-template',
|
||||||
bulkInputId: null, // Add bulk if you want
|
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'],
|
fields: ['setpoint_id', 'setpoint_name', 'setpoint_message'],
|
||||||
prefix: 'SETPOINT',
|
prefix: 'SETPOINT',
|
||||||
nameFormat: (id, paddedId) => `SETPOINT_${paddedId}`
|
nameFormat: (id, paddedId) => `SETPOINT_${paddedId}`,
|
||||||
|
initialRow: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- REALTIME VARIABLES ---
|
// --- REALTIME VARIABLES ---
|
||||||
@ -188,87 +205,101 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
tableBodyId: 'realtime-table-body',
|
tableBodyId: 'realtime-table-body',
|
||||||
templateId: 'realtime-row-template',
|
templateId: 'realtime-row-template',
|
||||||
bulkInputId: null, // Add bulk if you want
|
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'],
|
fields: ['realtime_id', 'realtime_name', 'realtime_message'],
|
||||||
prefix: 'REALTIME',
|
prefix: 'REALTIME',
|
||||||
nameFormat: (id, paddedId) => `REALTIME_${paddedId}`
|
nameFormat: (id, paddedId) => `REALTIME_${paddedId}`,
|
||||||
|
initialRow: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- 3. FORM SUBMISSION LOGIC ---
|
// --- 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
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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');
|
const form = document.getElementById('machine-form');
|
||||||
if (form) {
|
if (form) {
|
||||||
form.addEventListener('submit', async (event) => {
|
form.addEventListener('submit', async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
// A. Collect data from the main "Machine" tab using FormData
|
// A. Collect data from the main "Machine" tab using FormData
|
||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
// Convert FormData to a plain object
|
|
||||||
const mainData = {};
|
const mainData = {};
|
||||||
for (const [key, value] of formData.entries()) {
|
for (const [key, value] of formData.entries()) {
|
||||||
// This check prevents multi-value fields from overwriting themselves
|
// This check prevents multi-value fields (like addins) from being overwritten
|
||||||
if (!mainData[key]) {
|
if (!mainData[key]) {
|
||||||
mainData[key] = value;
|
mainData[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mainData.addins = formData.getAll('addins');
|
mainData.addins = formData.getAll('addins');
|
||||||
|
// B. Collect data from all dynamic tables using the modular function
|
||||||
// B. Collect all alarm rows from the table
|
const alarmsData = collectTableData('alarms-table-body', ['alarm_id', 'alarm_name', 'alarm_message'], 'alarm_message');
|
||||||
const alarmRows = alarmsTableBody.querySelectorAll('tr');
|
const warningsData = collectTableData('warnings-table-body', ['warning_id', 'warning_name', 'warning_message'], 'warning_message');
|
||||||
const alarmsData = [];
|
const statesData = collectTableData('states-table-body', ['state_id', 'state_name', 'state_description'], 'state_description');
|
||||||
alarmRows.forEach(row => {
|
const countersData = collectTableData('counters-table-body', ['counter_id', 'counter_name', 'counter_type', 'counter_description'], 'counter_type');
|
||||||
const alarm = {
|
const setpointsData = collectTableData('setpoints-table-body', ['setpoint_id', 'setpoint_name', 'setpoint_message'], 'setpoint_message');
|
||||||
id: row.querySelector('[name="alarm_id"]').value,
|
const realtimeData = collectTableData('realtime-table-body', ['realtime_id', 'realtime_name', 'realtime_message'], 'realtime_message');
|
||||||
name: row.querySelector('[name="alarm_name"]').value,
|
|
||||||
message: row.querySelector('[name="alarm_message"]').value,
|
|
||||||
};
|
|
||||||
if (alarm.message) {
|
|
||||||
alarmsData.push(alarm);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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
|
// C. Combine all data into a single object
|
||||||
const finalData = { ...mainData, alarms: alarmsData, warnings: warningsData, counters: countersData };
|
const finalData = {
|
||||||
|
...mainData,
|
||||||
|
alarms: alarmsData,
|
||||||
|
warnings: warningsData,
|
||||||
|
states: statesData,
|
||||||
|
counters: countersData,
|
||||||
|
setpoints: setpointsData,
|
||||||
|
realtime: realtimeData,
|
||||||
|
states: statesData
|
||||||
|
};
|
||||||
console.log('Sending all collected data to main process:', finalData);
|
console.log('Sending all collected data to main process:', finalData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electronAPI.submitForm(finalData);
|
const result = await window.electronAPI.submitForm(finalData);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
// // Reset the entire form to its initial state
|
console.log('Form submitted successfully!');
|
||||||
|
// Optionally reset the form or give user feedback
|
||||||
// form.reset();
|
// 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.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) {
|
} catch (error) {
|
||||||
console.error('Error during form submission process:', error);
|
console.error('Error during form submission process:', error);
|
||||||
@ -276,6 +307,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- 4. TAB NAVIGATION BUTTONS ---
|
// --- 4. TAB NAVIGATION BUTTONS ---
|
||||||
const tabOrder = [
|
const tabOrder = [
|
||||||
'machine-tab',
|
'machine-tab',
|
||||||
@ -283,7 +315,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
'warnings-tab',
|
'warnings-tab',
|
||||||
'counters-tab',
|
'counters-tab',
|
||||||
'setpoints-tab',
|
'setpoints-tab',
|
||||||
'realtime-tab'
|
'realtime-tab',
|
||||||
|
'states-tab'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add event listeners to all "Next" buttons
|
// Add event listeners to all "Next" buttons
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user