Refactor settings template to improve structure and enhance readability of room editor functionality
This commit is contained in:
parent
34cdc17eee
commit
7fb117a95e
1 changed files with 119 additions and 117 deletions
|
@ -25,32 +25,32 @@
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitizeFk(val) {
|
function sanitizeFk(val) {
|
||||||
if (val && val !== "null" && val !== "" && val !== "None") {
|
if (val && val !== "null" && val !== "" && val !== "None") {
|
||||||
return /^\d+$/.test(val) ? parseInt(val, 10) : val;
|
return /^\d+$/.test(val) ? parseInt(val, 10) : val;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const roomOptions = Array.from(document.getElementById('room-list').options);
|
const roomOptions = Array.from(document.getElementById('room-list').options);
|
||||||
|
|
||||||
const rooms = roomOptions.map(opt => {
|
const rooms = roomOptions.map(opt => {
|
||||||
const id = opt.value?.trim();
|
const id = opt.value?.trim();
|
||||||
const name = opt.textContent.trim();
|
const name = opt.textContent.trim();
|
||||||
const sectionId = sanitizeFk(opt.dataset.sectionId);
|
const sectionId = sanitizeFk(opt.dataset.sectionId);
|
||||||
const functionId = sanitizeFk(opt.dataset.functionId);
|
const functionId = sanitizeFk(opt.dataset.functionId);
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
name,
|
name,
|
||||||
...(id ? { id } : {}),
|
...(id ? { id } : {}),
|
||||||
section_id: sectionId,
|
section_id: sectionId,
|
||||||
function_id: functionId
|
function_id: functionId
|
||||||
};
|
};
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
brands: extractOptions("brand"),
|
brands: extractOptions("brand"),
|
||||||
types: extractOptions("type"),
|
types: extractOptions("type"),
|
||||||
|
@ -76,9 +76,9 @@
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(state)
|
body: JSON.stringify(state)
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentType = response.headers.get("content-type");
|
const contentType = response.headers.get("content-type");
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (contentType && contentType.includes("application/json")) {
|
if (contentType && contentType.includes("application/json")) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
@ -88,11 +88,11 @@
|
||||||
throw new Error("Unexpected response:\n" + text.slice(0, 200));
|
throw new Error("Unexpected response:\n" + text.slice(0, 200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log("Sync result:", data);
|
console.log("Sync result:", data);
|
||||||
renderToast({ message: 'Settings updated successfully.', type: 'success' });
|
renderToast({ message: 'Settings updated successfully.', type: 'success' });
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Submission error:", err);
|
console.error("Submission error:", err);
|
||||||
renderToast({ message: `Failed to update settings, ${err}`, type: 'danger' });
|
renderToast({ message: `Failed to update settings, ${err}`, type: 'danger' });
|
||||||
|
@ -112,13 +112,19 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form id="settingsForm">
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="card mb-3">
|
<ul class="nav nav-tabs">
|
||||||
<div class="card-body">
|
<li class="nav-item">
|
||||||
<h5 class="card-title">
|
<button class="nav-link active" id="inventory-tab" data-bs-toggle="tab" data-bs-target="#inventory-tab-pane"
|
||||||
Inventory Settings
|
type="button">Inventory</button>
|
||||||
</h5>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<button class="nav-link" id="location-tab" data-bs-toggle="tab" data-bs-target="#location-tab-pane"
|
||||||
|
type="button">Location</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content" id="tabContent">
|
||||||
|
<div class="tab-pane fade show active border border-top-0 p-3" id="inventory-tab-pane">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{{ combos.render_combobox(
|
{{ combos.render_combobox(
|
||||||
|
@ -138,10 +144,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="tab-pane fade border border-top-0 p-3" id="location-tab-pane">
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Location Settings</h5>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{{ combos.render_combobox(
|
{{ combos.render_combobox(
|
||||||
|
@ -196,127 +199,126 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="modal fade" id="roomEditor" data-bs-backdrop="static" tabindex="-1">
|
||||||
<div class="modal fade" id="roomEditor" data-bs-backdrop="static" tabindex="-1">
|
<div class="modal-dialog">
|
||||||
<div class="modal-dialog">
|
<div class="modal-content">
|
||||||
<div class="modal-content">
|
<div class="modal-header">
|
||||||
<div class="modal-header">
|
<h1 class="modal-title fs-5" id="roomEditorLabel">Room Editor</h1>
|
||||||
<h1 class="modal-title fs-5" id="roomEditorLabel">Room Editor</h1>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<label for="roomName" class="form-label">Room Name</label>
|
|
||||||
<input type="text" class="form-input" id="roomName" placeholder="Enter room name">
|
|
||||||
<input type="hidden" id="roomId">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="modal-body">
|
||||||
<div class="col">
|
<div class="row">
|
||||||
<label for="roomSection" class="form-label">Section</label>
|
<div class="col">
|
||||||
<select id="roomSection" class="form-select">
|
<label for="roomName" class="form-label">Room Name</label>
|
||||||
<option value="">Select a section</option>
|
<input type="text" class="form-input" id="roomName" placeholder="Enter room name">
|
||||||
{% for section in sections %}
|
<input type="hidden" id="roomId">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<label for="roomSection" class="form-label">Section</label>
|
||||||
|
<select id="roomSection" class="form-select">
|
||||||
|
<option value="">Select a section</option>
|
||||||
|
{% for section in sections %}
|
||||||
<option value="{{ section.id }}">{{ section.name }}</option>
|
<option value="{{ section.id }}">{{ section.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<label class="form-label">Function</label>
|
<label class="form-label">Function</label>
|
||||||
<select id="roomFunction" class="form-select">
|
<select id="roomFunction" class="form-select">
|
||||||
<option value="">Select a function</option>
|
<option value="">Select a function</option>
|
||||||
{% for function in functions %}
|
{% for function in functions %}
|
||||||
<option value="{{ function.id }}">{{ function.name }}</option>
|
<option value="{{ function.id }}">{{ function.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="modal-footer">
|
||||||
<div class="modal-footer">
|
<button type="button" class="btn btn-danger" data-bs-dismiss="modal" id="roomEditorCancelButton">{{
|
||||||
<button type="button" class="btn btn-danger" data-bs-dismiss="modal"
|
icons.render_icon('x-lg', 16) }}</button>
|
||||||
id="roomEditorCancelButton">{{ icons.render_icon('x-lg', 16) }}</button>
|
{% set editorSaveLogic %}
|
||||||
{% set editorSaveLogic %}
|
const modal = document.getElementById('roomEditor');
|
||||||
const modal = document.getElementById('roomEditor');
|
const name = document.getElementById('roomName').value.trim();
|
||||||
const name = document.getElementById('roomName').value.trim();
|
const sectionVal = document.getElementById('roomSection').value;
|
||||||
const sectionVal = document.getElementById('roomSection').value;
|
const funcVal = document.getElementById('roomFunction').value;
|
||||||
const funcVal = document.getElementById('roomFunction').value;
|
let idRaw = document.getElementById('roomId').value;
|
||||||
let idRaw = document.getElementById('roomId').value;
|
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
alert('Please enter a room name.');
|
alert('Please enter a room name.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const roomList = document.getElementById('room-list');
|
const roomList = document.getElementById('room-list');
|
||||||
let existingOption = Array.from(roomList.options).find(opt => opt.value === idRaw);
|
let existingOption = Array.from(roomList.options).find(opt => opt.value === idRaw);
|
||||||
|
|
||||||
if (!idRaw) {
|
if (!idRaw) {
|
||||||
idRaw = ComboBoxWidget.createTempId("room");
|
idRaw = ComboBoxWidget.createTempId("room");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existingOption) {
|
if (!existingOption) {
|
||||||
existingOption = ComboBoxWidget.createOption(name, idRaw);
|
existingOption = ComboBoxWidget.createOption(name, idRaw);
|
||||||
roomList.appendChild(existingOption);
|
roomList.appendChild(existingOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
existingOption.textContent = name;
|
existingOption.textContent = name;
|
||||||
existingOption.value = idRaw;
|
existingOption.value = idRaw;
|
||||||
existingOption.dataset.sectionId = sectionVal || "";
|
existingOption.dataset.sectionId = sectionVal || "";
|
||||||
existingOption.dataset.functionId = funcVal || "";
|
existingOption.dataset.functionId = funcVal || "";
|
||||||
|
|
||||||
ComboBoxWidget.sortOptions(roomList);
|
ComboBoxWidget.sortOptions(roomList);
|
||||||
|
|
||||||
bootstrap.Modal.getInstance(modal).hide();
|
bootstrap.Modal.getInstance(modal).hide();
|
||||||
{% endset %}
|
{% endset %}
|
||||||
{{ buttons.render_button(
|
{{ buttons.render_button(
|
||||||
id='editorSave',
|
id='editorSave',
|
||||||
icon='floppy',
|
icon='floppy',
|
||||||
logic=editorSaveLogic
|
logic=editorSaveLogic
|
||||||
) }}
|
) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
const modal = document.getElementById('roomEditor');
|
const modal = document.getElementById('roomEditor');
|
||||||
const cancelButton = document.getElementById('roomEditorCancelButton');
|
const cancelButton = document.getElementById('roomEditorCancelButton');
|
||||||
const form = document.getElementById('settingsForm');
|
const form = document.getElementById('settingsForm');
|
||||||
|
|
||||||
modal.addEventListener('roomEditor:prepare', (event) => {
|
modal.addEventListener('roomEditor:prepare', (event) => {
|
||||||
const { id, name, sectionId, functionId } = event.detail;
|
const { id, name, sectionId, functionId } = event.detail;
|
||||||
document.getElementById('roomId').value = id;
|
document.getElementById('roomId').value = id;
|
||||||
document.getElementById('roomName').value = name;
|
document.getElementById('roomName').value = name;
|
||||||
|
|
||||||
// Populate dropdowns before assigning selection
|
// Populate dropdowns before assigning selection
|
||||||
const modalSections = document.getElementById('roomSection');
|
const modalSections = document.getElementById('roomSection');
|
||||||
const modalFunctions = document.getElementById('roomFunction');
|
const modalFunctions = document.getElementById('roomFunction');
|
||||||
const pageSections = document.getElementById('section-list');
|
const pageSections = document.getElementById('section-list');
|
||||||
const pageFunctions = document.getElementById('function-list');
|
const pageFunctions = document.getElementById('function-list');
|
||||||
|
|
||||||
modalSections.innerHTML = '<option value="">Select a section</option>';
|
modalSections.innerHTML = '<option value="">Select a section</option>';
|
||||||
modalFunctions.innerHTML = '<option value="">Select a function</option>';
|
modalFunctions.innerHTML = '<option value="">Select a function</option>';
|
||||||
|
|
||||||
Array.from(pageSections.options).forEach(opt => {
|
Array.from(pageSections.options).forEach(opt => {
|
||||||
const option = new Option(opt.textContent, opt.value);
|
const option = new Option(opt.textContent, opt.value);
|
||||||
if (opt.value === sectionId) {
|
if (opt.value === sectionId) {
|
||||||
option.selected = true;
|
option.selected = true;
|
||||||
}
|
}
|
||||||
modalSections.appendChild(option);
|
modalSections.appendChild(option);
|
||||||
});
|
|
||||||
|
|
||||||
Array.from(pageFunctions.options).forEach(opt => {
|
|
||||||
const option = new Option(opt.textContent, opt.value);
|
|
||||||
if (opt.value === functionId) {
|
|
||||||
option.selected = true;
|
|
||||||
}
|
|
||||||
modalFunctions.appendChild(option);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cancelButton.addEventListener('click', () => {
|
Array.from(pageFunctions.options).forEach(opt => {
|
||||||
bootstrap.Modal.getInstance(modal).hide();
|
const option = new Option(opt.textContent, opt.value);
|
||||||
|
if (opt.value === functionId) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
modalFunctions.appendChild(option);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.addEventListener('click', () => {
|
||||||
|
bootstrap.Modal.getInstance(modal).hide();
|
||||||
|
});
|
||||||
{% endblock %}
|
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue