diff --git a/src/frontend/manage/storageManager.eta.html b/src/frontend/manage/storageManager.eta.html
index e316755..52ee58b 100644
--- a/src/frontend/manage/storageManager.eta.html
+++ b/src/frontend/manage/storageManager.eta.html
@@ -62,8 +62,8 @@
-
@@ -82,13 +83,13 @@
@@ -195,10 +196,10 @@
<%= units.name %> |
<%= units.contactInfo.street %> <%= units.contactInfo.houseNumber %>, <%= units.contactInfo.city %> <%= units.contactInfo.country %> |
- |
<% }) %>
diff --git a/src/frontend/partials/head.eta.html b/src/frontend/partials/head.eta.html
index bcff16e..cfec940 100644
--- a/src/frontend/partials/head.eta.html
+++ b/src/frontend/partials/head.eta.html
@@ -11,6 +11,7 @@
+
diff --git a/src/routes/api/v1/storageUnits.ts b/src/routes/api/v1/storageUnits.ts
index 76f5a6a..aecd451 100644
--- a/src/routes/api/v1/storageUnits.ts
+++ b/src/routes/api/v1/storageUnits.ts
@@ -1,18 +1,19 @@
import { Request, Response } from 'express';
import { prisma, __path, log } from '../../../index.js';
+import { contactType } from '@prisma/client';
// Get storageUnit.
function get(req: Request, res: Response) {
if (req.query.getAll === undefined) {
// Check if required fields are present.
- if (!req.query.name) {
+ if (!req.query.id) {
res.status(400).render(__path + '/src/frontend/errors/400.eta.html');
return;
}
prisma.storageUnit
.findUnique({
where: {
- name: req.query.name.toString()
+ id: parseInt(req.query.id.toString())
},
// Get category name from relation.
include: {
@@ -54,36 +55,120 @@ function get(req: Request, res: Response) {
// Create storageUnit.
function post(req: Request, res: Response) {
- log.web.debug(JSON.stringify(req.body));
-/* // Check if required fields are present.
- if (!req.body.name) {
+ // If the frontend wants to create a StorageUnit with non-existing ContactInfo.
+ if (req.body.locationId === 'META_CREATENEW') {
+ // Check if required fields are present.
+ if (!req.body.street || !req.body.houseNumber || !req.body.zipCode || !req.body.city || !req.body.country || !req.body.name) {
+ res.status(400).render(__path + '/src/frontend/errors/400.eta.html');
+ return;
+ }
+
+ // Create storageUnit and location.
+ prisma.storageUnit
+ .create({
+ data: {
+ name: req.body.name,
+ contactInfo: {
+ create: {
+ type: contactType.storageUnit,
+ street: req.body.street,
+ houseNumber: req.body.houseNumber,
+ zipCode: req.body.zipCode,
+ city: req.body.city,
+ country: req.body.country
+ }
+ }
+ }
+ })
+ .then(() => {
+ res.status(201).json({ status: 'created' });
+ })
+ .catch((err) => {
+ // Check if an entry already exists.
+ if (err.code === 'P2002') {
+ // P2002 -> "Unique constraint failed on the {constraint}"
+ // https://www.prisma.io/docs/reference/api-reference/error-reference
+ res.status(409).json({ error: 'storageUnit already exists.' });
+ } else {
+ log.db.error(err);
+ res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
+ }
+ });
+ } else {
+ // Check if required fields are present.
+ if (!req.body.name || !req.body.locationId) {
+ res.status(400).render(__path + '/src/frontend/errors/400.eta.html');
+ return;
+ }
+ // Create storageUnit with existing location.
+ prisma.storageUnit
+ .create({
+ data: {
+ name: req.body.name,
+ contactInfo: {
+ connect: {
+ id: parseInt(req.body.locationId)
+ }
+ }
+ }
+ })
+ .then(() => {
+ res.status(201).json({ status: 'created' });
+ })
+ .catch((err) => {
+ // Check if an entry already exists.
+ if (err.code === 'P2002') {
+ // P2002 -> "Unique constraint failed on the {constraint}"
+ // https://www.prisma.io/docs/reference/api-reference/error-reference
+ res.status(409).json({ error: 'storageUnit already exists.' });
+ } else {
+ log.db.error(err);
+ res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
+ }
+ });
+ }
+}
+
+// Update storageUnit. -> Only existing contactInfo.
+async function patch(req: Request, res: Response) {
+ // Check if required fields are present.
+ if (!req.body.id || !req.body.name || !req.body.locationId) {
res.status(400).render(__path + '/src/frontend/errors/400.eta.html');
return;
}
- // Save data.
- prisma.storageUnit
- .create({
- data: {
- name: req.body.name
+ // Check if the storageUnit id exists. If not return 410 Gone.
+ try {
+ const result = await prisma.storageUnit.findUnique({
+ where: {
+ id: parseInt(req.body.id)
}
- })
- .then(() => {
- res.status(201).json({ status: 'created' });
- })
- .catch((err) => {
- // TODO Catch if is a duplicate error and show a message to the user
- log.db.error(err);
- res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
- }); */
-}
+ });
-// Update category.
-function patch(req: Request, res: Response) {
- // Check if required fields are present.
- if (!req.body.id || !req.body.name) {
- res.status(400).render(__path + '/src/frontend/errors/400.eta.html');
- return;
+ if (result === null) {
+ res.status(410).json({ error: 'storageUnit does not exist.' });
+ return;
+ }
+ } catch (err) {
+ log.db.error(err);
+ res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
+ }
+
+ // Check if the locationId(contactInfo) exists. If not return 410 Gone.
+ try {
+ const result = await prisma.contactInfo.findUnique({
+ where: {
+ id: parseInt(req.body.locationId)
+ }
+ });
+
+ if (result === null) {
+ res.status(410).json({ error: 'locationId does not exist.' });
+ return;
+ }
+ } catch (err) {
+ log.db.error(err);
+ res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
}
prisma.storageUnit
@@ -92,20 +177,31 @@ function patch(req: Request, res: Response) {
id: parseInt(req.body.id)
},
data: {
- name: req.body.name
+ name: req.body.name,
+ contactInfo: {
+ connect: {
+ id: parseInt(req.body.locationId)
+ }
+ }
}
})
.then(() => {
res.status(201).json({ status: 'updated' });
})
.catch((err) => {
- // TODO Catch if is a duplicate error and show a message to the user
- log.db.error(err);
- res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
+ // Check if an entry already exists.
+ if (err.code === 'P2002') {
+ // P2002 -> "Unique constraint failed on the {constraint}"
+ // https://www.prisma.io/docs/reference/api-reference/error-reference
+ res.status(409).json({ error: 'storageUnit already exists.' });
+ } else {
+ log.db.error(err);
+ res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
+ }
});
}
-// Delete category.
+// Delete storageUnit.
async function del(req: Request, res: Response) {
// Check if required fields are present.
if (!req.body.id) {
@@ -122,7 +218,7 @@ async function del(req: Request, res: Response) {
});
if (result === null) {
- res.status(410).json({ error: 'Storage Unit does not exist.' });
+ res.status(410).json({ error: 'storageUnit does not exist.' });
return;
}
} catch (err) {
@@ -137,7 +233,7 @@ async function del(req: Request, res: Response) {
}
})
.then(() => {
- res.status(201).json({ status: 'deleted' });
+ res.status(200).json({ status: 'deleted' });
})
.catch((err) => {
log.db.error(err);
diff --git a/static/js/editCategory.js b/static/js/editCategory.js
index a8eab1f..50edd96 100644
--- a/static/js/editCategory.js
+++ b/static/js/editCategory.js
@@ -20,7 +20,7 @@ function getDataForEdit(name) {
$('.loader-overlay').removeClass('active');
// Close the modal
$('.modal').modal('hide');
- $('#generalToast').removeClass('text-bg-primary');
+ normalizeToast()
$('#generalToast').addClass('text-bg-danger');
$('#generalToast').toast('show');
$('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. The category does no longer exist.');
@@ -81,14 +81,13 @@ function deleteEntry(id) {
error: function (data) {
// hide the staticBackdrop modal
$('#staticBackdrop').modal('hide');
- $('#generalToast').removeClass('text-bg-primary');
+ normalizeToast()
+
$('#generalToast').addClass('text-bg-danger');
$('#generalToast').toast('show');
$('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. Please try again later.');
setTimeout(() => {
$('#generalToast').toast('hide');
- $('#generalToast').removeClass('text-bg-danger');
- $('#generalToast').addClass('text-bg-primary');
}, 3000);
}
});
@@ -118,7 +117,7 @@ function preFillDeleteModal(name) {
document.getElementById('deleteNamePlaceholder').innerText = 'Deleted';
$('#staticBackdrop').modal('hide');
- $('#generalToast').removeClass('text-bg-primary');
+ normalizeToast()
$('#generalToast').addClass('text-bg-danger');
$('#generalToast').toast('show');
$('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. The category does no longer exist.');
diff --git a/static/js/editStorages.js b/static/js/editStorages.js
index 701a583..b233dec 100644
--- a/static/js/editStorages.js
+++ b/static/js/editStorages.js
@@ -26,6 +26,9 @@ $('.nav-link').on('click', function (e) {
function primeCreateNew() {
const form = document.getElementById('storageUnitModalForm');
const form2 = document.getElementById('storageLocationModal');
+ document.getElementById('createNewLocationSelection').disabled = false;
+ document.getElementById('storageUnitModalLocationSelectText').innerText= "Select or create a new location.";
+ document.getElementById('storageUnitModalLabel').innerText = "Create new storage unit";
form.setAttribute('method', 'POST');
form2.setAttribute('method', 'POST');
return true;
@@ -34,6 +37,12 @@ function primeCreateNew() {
function primeEdit() {
const form = document.getElementById('storageUnitModalForm');
const form2 = document.getElementById('storageLocationModal');
+ // Disable create new location
+ document.getElementById('createNewLocationSelection').disabled = true;
+ document.getElementById('storageUnitModalLocationSelectText').innerText= "While editing you can only select already existing locations. Use the settings to create new ones.";
+ document.getElementById('storageUnitModalLabel').innerText = "Edit a storage unit";
+ document.getElementById('storageUnitModalLocationSelect').value = 1
+ handleSelector()
form.setAttribute('method', 'PATCH');
form2.setAttribute('method', 'PATCH');
return true;
@@ -52,4 +61,135 @@ function handleSelector(){
console.log(value);
}
+
+
+function preFillDeleteModal(id) {
+ $.ajax({
+ type: 'get',
+ url: `/api/v1/storageUnits?id=${id}`,
+ success: function (data) {
+ const result = JSON.parse(data);
+
+ // Get elements inside the editCategoryModal
+ const modal_categoryName = document.getElementById('deleteNamePlaceholder');
+ const modal_deleteButton = document.getElementById('deleteActionBtn');
+ //const modal_categoryDescription = document.getElementById('editCategoryModalDescription');
+ //const modal_categoryid = document.getElementById('editCategoryModalId');
+
+ modal_categoryName.innerText = result.name;
+ modal_deleteButton.setAttribute('onclick', `deleteEntry(${result.id})`);
+
+ //modal_categoryDescription.value = result.description;
+ //modal_categoryid.value = result.id;
+ },
+ error: function (data) {
+ console.log('!!!! ERROR !!!!', data);
+ document.getElementById('deleteNamePlaceholder').innerText = 'Deleted';
+
+ $('#staticBackdrop').modal('hide');
+ normalizeToast()
+
+ $('#generalToast').addClass('text-bg-danger');
+ $('#generalToast').toast('show');
+ $('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. The storageUnit does no longer exist.');
+ setTimeout(() => {
+ window.location.reload();
+ }, 3000);
+ }
+ });
+}
+
+
+function deleteEntry(id) {
+ $.ajax({
+ type: 'delete',
+ url: `/api/v1/storageUnits`,
+ data: { id: id },
+ success: function (data) {
+ $('#staticBackdrop').modal('hide');
+ normalizeToast()
+
+ $('#generalToast').addClass('text-bg-success');
+ $('#generalToast').toast('show');
+ $('#generalToast').children('.d-flex').children('.toast-body').html(' Storage Unit deleted successfully.');
+ confetti({
+ spread: 360,
+ ticks: 100,
+ gravity: 0.1,
+ decay: 0.94,
+ startVelocity: 30,
+ particleCount: 20,
+ scalar: 2,
+ shapes: ['text'],
+ shapeOptions: {
+ text: {
+ value: ['❌', '🗑️', '🚫']
+ }
+ }
+ });
+ setTimeout(() => {
+ $('#generalToast').toast('hide');
+ window.location.reload();
+ }, 2000);
+ },
+ error: function (data) {
+ // hide the staticBackdrop modal
+ $('#staticBackdrop').modal('hide');
+ normalizeToast()
+ $('#generalToast').addClass('text-bg-danger');
+ $('#generalToast').toast('show');
+ $('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. Please try again later.');
+ setTimeout(() => {
+ $('#generalToast').toast('hide');
+ }, 3000);
+ }
+ });
+}
+
+
+function getDataForEdit(id) {
+ $.ajax({
+ type: 'get',
+ url: `/api/v1/storageUnits?id=${id}`,
+ success: function (data) {
+ const result = JSON.parse(data);
+
+ // Get elements inside the editCategoryModal
+ const modal_unitName = document.getElementById('storageUnitModalName');
+ const modal_unitLocation = document.getElementById('storageUnitModalLocationSelect');
+ const modal_unitId = document.getElementById('storageUnitModalLocationSelectHidden');
+ // const modal_categoryid = document.getElementById('editCategoryModalId');
+
+ modal_unitName.value = result.name;
+ modal_unitId.value = result.id;
+
+ // Select the correct location from the select based on the value of the option
+ for(var i, j = 0; i = modal_unitLocation.options[j]; j++) {
+ console.log(i.value, result.contactInfoId);
+ if(i.value == result.contactInfoId) {
+ console.log("Found it");
+ modal_unitLocation.selectedIndex = j;
+ break;
+ }
+ }
+
+
+ },
+ error: function (data) {
+ console.log('!!!! ERROR !!!!', data);
+ // Hide overlay with spinner
+ $('.loader-overlay').removeClass('active');
+ // Close the modal
+ $('.modal').modal('hide');
+ normalizeToast()
+ $('#generalToast').addClass('text-bg-danger');
+ $('#generalToast').toast('show');
+ $('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. The storage unit does no longer exist.');
+ setTimeout(() => {
+ window.location.reload();
+ }, 3000);
+ }
+ });
+}
+
handleSelector()
\ No newline at end of file
diff --git a/static/js/formHandler.js b/static/js/formHandler.js
index e836785..81fb579 100644
--- a/static/js/formHandler.js
+++ b/static/js/formHandler.js
@@ -26,14 +26,12 @@ $('.frontendForm').each(function() {
// Clear all fields
form.find('input, textarea').val('');
- $('#generalToast').removeClass('text-bg-primary');
+ normalizeToast()
$('#generalToast').addClass('text-bg-success');
$('#generalToast').toast('show');
$('#generalToast').children('.d-flex').children('.toast-body').html(' Changes saved successfully.');
setTimeout(() => {
$('#generalToast').toast('hide');;
- $('#generalToast').removeClass('text-bg-success');
- $('#generalToast').addClass('text-bg-primary');
window.location.reload();
}, 1500);
},
@@ -41,15 +39,20 @@ $('.frontendForm').each(function() {
console.log('error');
// Hide overlay with spinner
$('.loader-overlay').removeClass('loaderActive');
-
- $('#generalToast').removeClass('text-bg-primary');
+
+ // Check for response code 409
+ normalizeToast()
$('#generalToast').addClass('text-bg-danger');
$('#generalToast').toast('show');
- $('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. Please try again later.');
+
+
+ if (data.status == 409) {
+ $('#generalToast').children('.d-flex').children('.toast-body').html(' The element you tried to create already exists.');
+ }else {
+ $('#generalToast').children('.d-flex').children('.toast-body').html(' Something went wrong. Please try again later.');
+ }
setTimeout(() => {
$('#generalToast').toast('hide');
- $('#generalToast').removeClass('text-bg-danger');
- $('#generalToast').addClass('text-bg-primary');
}, 3000);
}
});
diff --git a/static/js/normalizeToast.js b/static/js/normalizeToast.js
new file mode 100644
index 0000000..351d2b8
--- /dev/null
+++ b/static/js/normalizeToast.js
@@ -0,0 +1,7 @@
+function normalizeToast(){
+ $('#generalToast').removeClass('text-bg-primary');
+ $('#generalToast').removeClass('text-bg-success');
+ $('#generalToast').removeClass('text-bg-danger');
+ $('#generalToast').removeClass('text-bg-warning');
+ $('#generalToast').removeClass('text-bg-info');
+}