Frontend update

This commit is contained in:
Leon Meier 2023-06-06 23:49:16 +02:00
parent 3b1e4a7cde
commit f249a4552c
9 changed files with 119 additions and 15 deletions

View File

@ -38,7 +38,9 @@
<tbody> <tbody>
<% it.recents.forEach(function(user){ %> <% it.recents.forEach(function(user){ %>
<tr> <tr>
<th scope="row" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="ID: <%= user.id %>"><%= user.SKU %></th> <th scope="row" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="ID: <%= user.id %>"><% if (user.SKU == null) { %>
<i>No SKU assigned</i>
<% } else { %> <%= user.SKU %> <% } %></th>
<td><%= user.name %></td> <td><%= user.name %></td>
<% if(user.status == "normal") { %> <% if(user.status == "normal") { %>

View File

@ -1,4 +1,4 @@
<%~ E.includeFile("partials/head.eta.html", {"title": "Items"}) %> <%~ E.includeFile("partials/controls.eta.html", {"active": "Items"}) %> <%~ E.includeFile("partials/head.eta.html", {"title": "Items"}) %> <%~ E.includeFile("partials/controls.eta.html", {"active": "Items"}) %> <%~ E.includeFile("./partials/deleteModal.eta.html") %>
<div class="modal fade" id="itemModifyModal" tabindex="-1" aria-labelledby="itemModifyModal" aria-hidden="true"> <div class="modal fade" id="itemModifyModal" tabindex="-1" aria-labelledby="itemModifyModal" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg "> <div class="modal-dialog modal-dialog-centered modal-lg ">
@ -7,7 +7,7 @@
<h1 class="modal-title fs-5" id="itemModifyModalLabel">Edit a item</h1> <h1 class="modal-title fs-5" id="itemModifyModalLabel">Edit a item</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<form class="frontendForm" method="patch" data-target="/api/v1/items" id="CategoryModalForm"> <form class="frontendForm" method="patch" data-target="/api/v1/items" id="ItemModalForm">
<div class="modal-body"> <div class="modal-body">
<div class="mb-3"> <div class="mb-3">
<label for="itemModifyModalName" class="form-label">Name</label> <label for="itemModifyModalName" class="form-label">Name</label>
@ -41,7 +41,7 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="itemModifyModalManuf" class="form-label">Manufacturer</label> <label for="itemModifyModalManuf" class="form-label">Manufacturer</label>
<input type="number" min="0" class="form-control" id="itemModifyModalManuf" name="manufacturer" /> <input type="text" class="form-control" id="itemModifyModalManuf" name="manufacturer" />
<div id="itemModifyModalSKUText" class="form-text">Optional</div> <div id="itemModifyModalSKUText" class="form-text">Optional</div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
@ -54,7 +54,6 @@
</select> </select>
<div id="storageLocationModalLocationText" class="form-text">You have to create a storage location beforehand.</div> <div id="storageLocationModalLocationText" class="form-text">You have to create a storage location beforehand.</div>
<input type="hidden" id="storageLocationModalIdHidden" name="id" />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="itemModifyModalStatus" class="form-label">Status</label> <label for="itemModifyModalStatus" class="form-label">Status</label>
@ -68,7 +67,6 @@
</select> </select>
<div id="storageLocationModalLocationText" class="form-text">You have to create a storage location beforehand.</div> <div id="storageLocationModalLocationText" class="form-text">You have to create a storage location beforehand.</div>
<input type="hidden" id="storageLocationModalIdHidden" name="id" />
</div> </div>
<input type="text" id="itemModifyModalId" name="id" hidden /> <input type="text" id="itemModifyModalId" name="id" hidden />
</div> </div>
@ -107,7 +105,10 @@
<tbody> <tbody>
<% it.items.forEach(function(user){ %> <% it.items.forEach(function(user){ %>
<tr> <tr>
<td scope="row" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="ID: <%= user.id %>"><%= user.SKU %></td> <td scope="row" data-bs-toggle="tooltip" data-bs-placement="left" data-bs-title="ID: <%= user.id %>">
<% if (user.SKU == null) { %>
<i>No SKU assigned</i>
<% } else { %> <%= user.SKU %> <% } %></td>
<td><%= user.name %></td> <td><%= user.name %></td>
<% if(user.status == "normal") { %> <% if(user.status == "normal") { %>
@ -119,7 +120,14 @@
<% } else if(user.status == "borrowed") { %> <% } else if(user.status == "borrowed") { %>
<td><span class="badge text-bg-info"><%= user.status %></span></td> <td><span class="badge text-bg-info"><%= user.status %></span></td>
<% } %> <% } %>
<td><a href="#" class="btn btn-primary">Edit</a></td> <td>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#itemModifyModal" onclick="primeEdit(); getDataForEdit('<%= user.id %>')">
<i class="bi bi-pencil"></i>
</button>
<button class="btn btn-danger" onclick="preFillDeleteModalNxt('<%= user.id %>','items','Item')" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
<i class="bi bi-trash"></i>
</button>
</td>
</tr> </tr>
<% }) %> <% }) %>
</tbody> </tbody>
@ -138,5 +146,5 @@
</nav> </nav>
<% } %> <% } %>
</div> </div>
<script src="/js/editItems.js"></script>
<%~ E.includeFile("partials/controlsFoot.eta.html") %> <%~ E.includeFile("partials/foot.eta.html") %> <%~ E.includeFile("partials/controlsFoot.eta.html") %> <%~ E.includeFile("partials/foot.eta.html") %>

View File

@ -14,7 +14,7 @@
<div class="" id="navbarSupportedContent"> <div class="" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul> <ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul>
<form class="d-flex" role="search"> <form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" id="SearchBox" /> <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" id="SearchBox" data-bs-trigger="focus" autocomplete="false" data-bs-toggle="popover" data-bs-title="Search" data-bs-content="Please type a little more" data-bs-placement="bottom" />
<div class="autocomplete-items bg-secondary border-primary me-2 p-2" id="autocomplete-items"></div> <div class="autocomplete-items bg-secondary border-primary me-2 p-2" id="autocomplete-items"></div>
</form> </form>
</div> </div>
@ -28,6 +28,15 @@
</div> </div>
</div> </div>
<div class="toast-container position-fixed bottom-0 end-0 p-3" id="toastMainController">
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" id="generalToast" style="z-index: 2000">
<div class="d-flex">
<div class="toast-body">Hello, world! This is a toast message.</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<nav id="sidebarMenu" class="col-md-2 col-lg-2 d-md-block sidebar collapse"> <nav id="sidebarMenu" class="col-md-2 col-lg-2 d-md-block sidebar collapse">

View File

@ -5,3 +5,7 @@
<script src="/js/searchBox.js"></script> <script src="/js/searchBox.js"></script>
<script src="/js/handleSidebarTriangles.js"></script> <script src="/js/handleSidebarTriangles.js"></script>
<script src="/js/formHandler.js"></script> <script src="/js/formHandler.js"></script>
<script>
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl))
</script>

View File

@ -3,7 +3,7 @@
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">Do you really want to delete <strong id="deleteNamePlaceholder">Placeholder</strong>?</h1> <h1 class="modal-title fs-5" id="staticBackdropLabel">Do you really want to delete <strong id="deleteNamePlaceholder"><span class="placeholder col-4"></span></strong>?</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div class="modal-body">This will permanently delete the category and all its associated data.<br />Items will be kept but will be unassigned from this category.</div> <div class="modal-body">This will permanently delete the category and all its associated data.<br />Items will be kept but will be unassigned from this category.</div>

View File

@ -91,6 +91,7 @@ body {
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25); box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
} }
/*
.autocomplete-items { .autocomplete-items {
position: absolute; position: absolute;
z-index: 99; z-index: 99;
@ -98,7 +99,7 @@ body {
left: 0; left: 0;
right: 0; right: 0;
} }
*/
.rotate { .rotate {
transform: rotate(-90deg) !important; transform: rotate(-90deg) !important;
transition: 0.5s; transition: 0.5s;

77
static/js/editItems.js Normal file
View File

@ -0,0 +1,77 @@
function primeCreateNew() {
// Clear the form
$('.form-control').val('');
const form = document.getElementById('ItemModalForm');
document.getElementById('itemModifyModalLabel').innerText= "Create a new item";
form.setAttribute('method', 'POST');
return true;
}
function primeEdit() {
const form = document.getElementById('ItemModalForm');
document.getElementById('itemModifyModalLabel').innerText = 'Edit an item';
form.setAttribute('method', 'PATCH');
return true;
}
function getDataForEdit(id) {
$.ajax({
type: 'get',
url: `/api/v1/items?id=${id}`,
success: function (data) {
const result = JSON.parse(data);
// Get elements inside the editCategoryModal
const modal_itemName = document.getElementById('itemModifyModalName');
const modal_itemComment = document.getElementById('itemModifyModalComment');
const modal_itemAmount = document.getElementById('itemModifyModalAmount');
const modal_itemSKU = document.getElementById('itemModifyModalSKU');
const modal_itemStorageLocation = document.getElementById('itemModifyModalStorageLocation');
const modal_itemManufacturer = document.getElementById('itemModifyModalManuf');
const modal_itemCategory = document.getElementById('itemModifyModalCategory');
const modal_itemStatus = document.getElementById('itemModifyModalStatus');
const modal_itemid = document.getElementById('itemModifyModalId');
modal_itemName.value = result.name;
modal_itemComment.value = result.comment;
modal_itemAmount.value = result.amount;
modal_itemSKU.value = result.SKU;
modal_itemManufacturer.value = result.manufacturer;
// Select the correct option in the dropdown
const modal_itemCategoryOptions = modal_itemCategory.options;
for (let i = 0; i < modal_itemCategoryOptions.length; i++) {
if (modal_itemCategoryOptions[i].value == result.category.id) {
modal_itemCategoryOptions[i].selected = true;
}
}
// Select the correct option in the dropdown
const modal_itemStatusOptions = modal_itemStatus.options;
for (let i = 0; i < modal_itemStatusOptions.length; i++) {
if (modal_itemStatusOptions[i].value == result.status.id) {
modal_itemStatusOptions[i].selected = true;
}
}
// Select the correct option in the dropdown
const modal_itemStorageLocationOptions = modal_itemStorageLocation.options;
for (let i = 0; i < modal_itemStorageLocationOptions.length; i++) {
if (modal_itemStorageLocationOptions[i].value == result.storageLocation.id) {
modal_itemStorageLocationOptions[i].selected = true;
}
}
modal_itemid.value = result.id;
},
error: function (data) {
console.log('!!!! ERROR !!!!', data);
// Hide overlay with spinner
$('.loader-overlay').removeClass('active');
// Close the modal
$('.modal').modal('hide');
createNewToast('<i class="bi bi-exclamation-triangle-fill"></i> Something went wrong. The category does no longer exist.', "text-bg-danger")
}
});
}

View File

@ -1,5 +1,6 @@
var amountOfForms = $('.frontendForm').length; var amountOfForms = $('.frontendForm').length;
$('.frontendForm').each(function () { $('.frontendForm').each(function () {
// TODO Handle empty strings as null or undefined, not as ''
$(this).on('submit', function (e) { $(this).on('submit', function (e) {
e.preventDefault(); // Prevent the form from submitting via the browser e.preventDefault(); // Prevent the form from submitting via the browser
@ -108,7 +109,7 @@ function preFillDeleteModalNxt(id, route, name, requestIdent='id') {
document.getElementById('deleteNamePlaceholder').innerText = 'Deleted'; document.getElementById('deleteNamePlaceholder').innerText = 'Deleted';
$('#staticBackdrop').modal('hide'); $('#staticBackdrop').modal('hide');
createNewToast(`<i class="bi bi-exclamation-triangle-fill"></i> Something went wrong. The ${name} does no longer exist.', "text-bg-danger`) createNewToast(`<i class="bi bi-exclamation-triangle-fill"></i> Something went wrong. The ${name} does no longer exist.`, `text-bg-danger`)
} }
}); });
} }

View File

@ -3,6 +3,8 @@ const autocompleteBox = document.getElementById("autocomplete-items");
autocompleteBox.style.display = "none"; autocompleteBox.style.display = "none";
function handleSearchChange(e) { function handleSearchChange(e) {
console.log(e.target.value); console.log(e.target.value);
// document.getElementById("SearchBox").setAttribute("data-bs-content", "Search results will show up here soon")
return; // No you won't. I'm not done yet. return; // No you won't. I'm not done yet.
// Check if known prefix is used (either > or #) // Check if known prefix is used (either > or #)