21 Commits

Author SHA1 Message Date
29fd2e0a15 added right actionbar icons and asset solution list 2024-03-15 20:05:01 +01:00
3613565b39 added bools for actionbar rendering 2024-03-12 20:36:26 +01:00
7af5c0ce0d bugfix credentials 2024-03-12 18:32:35 +01:00
ba8073b6f4 added cors header 2024-03-12 18:14:31 +01:00
acae90ee13 fixed signup and renaming problems 2024-03-12 17:46:44 +01:00
d1bdffb834 resolved missing authstore errors 2024-03-11 20:21:08 +01:00
3f111743ed tried to solve errors 2024-03-11 20:12:39 +01:00
cbc1e73bb0 Merge branch 'AccountingPages' 2024-03-11 19:57:54 +01:00
e56af94a88 implemented accounting pages 2024-03-11 19:44:31 +01:00
9954158475 del dublicate icon 2024-03-11 18:31:49 +01:00
a7bbfea9c1 Merge branch 'authentication' into main 2024-03-11 18:27:29 +01:00
6d6b36bdd9 implemented authentication with sidebase/nuxt-auth 2024-03-11 18:19:11 +01:00
fa29921afe replaced clients/s with customer/s (2) 2024-03-04 20:07:31 +01:00
889eb3571f Merge branch 'main' of https://git.tueit.de/jo.kuehner/TueIT_App into main 2024-03-04 19:31:17 +01:00
6a4a53ce4b replaced client/s with customer/s 2024-03-04 18:43:19 +01:00
3a1e468789 Merge pull request 'mv templates and solutions' (#21) from potInstances into main
Reviewed-on: jo.kuehner/TueIT_App#21
2024-03-04 09:25:46 +00:00
488eba45e1 implemented mvt and solutions 2024-03-04 10:24:55 +01:00
7c19ee9215 implemented authentication 2024-02-29 21:05:08 +01:00
1e001bb4a1 added functionality for mvt table 2024-02-29 09:31:05 +01:00
df60461a53 Merge pull request 'productionOrders' (#19) from productionOrders into main
Reviewed-on: jo.kuehner/TueIT_App#19
2024-02-28 13:50:45 +00:00
601449d7e0 added page titles and icon 2024-02-27 16:53:28 +01:00
186 changed files with 21948 additions and 3748 deletions

14
app.vue
View File

@ -7,9 +7,21 @@
<script setup>
//import { createPinia } from "pinia";
//import piniaPluginPersistedState from "pinia-plugin-persistedstate"
//const layout = "empty";
//const layout = "empty";
//const route = useRoute();
//const pinia = createPinia();
//pinia.use(piniaPluginPersistedState);
useHead({
//title: `Tüit ERP - ${route.meta.title}`,
title: `tüit app`,
link: [{ rel: "icon", type: "image/png", href: "/favicon-gelb-rot-32x32.png" }]
})
</script>

View File

@ -1,14 +1,30 @@
import axios from 'axios';
import axios, {AxiosError} from 'axios';
import clientsideConfig from './clientsideConfig'
//create axios instance
const Axios = axios.create({
// baseURL: `https://${serversideConfig.url}:${serversideConfig.port}`,
//baseURL: `https://${serversideConfig.url}:${serversideConfig.port}/`,
baseURL: `https://${clientsideConfig.url}:${clientsideConfig.port}/`,
headers: {
// 'Accept': 'application/json',
'Content-Type': 'application/json',
//Authorization: `Bearer`,
Accept: "*",
},
withCredentials: true,
credentials: true,
})
Axios.interceptors.response.use((response) => response, (error) => {
if (error instanceof AxiosError) {
console.error('Status: ', error.response?.status, '\nHeaders: '. error.response?.headers, '\nMessage: '. error.response?.data.message)
} else { console.error('Error: ', error); };
if (error.response?.status === 403) { window.location.href = '/login'; };
return Promise.reject(error);
});
export default Axios;

View File

@ -5,6 +5,8 @@ import {
deleteIssueById,
insertIssue,
getAllIssues,
getSelectedIssuesByState,
getSelectedIssuesByIssueName,
} from "../models/issuesModel.js";
//get all issues
@ -18,6 +20,28 @@ export const showIssues = (req, res) => {
});
};
//get all selected issues by name
export const showSelectedIssuesByIssueName = (req, res) => {
getSelectedIssuesByIssueName(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected issues by state
export const showSelectedIssuesByState = (req, res) => {
getSelectedIssuesByState(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Delete issue
export const deleteIssue = (req, res) => {
const id = req.params.id;

View File

@ -93,7 +93,15 @@ export const login = async (req, res, next) => {
}
if (bResult) {
// password match
const token = jwt.sign(
const authtoken = jwt.sign(
{
username: result[0].username,
userId: result[0].id,
},
'SECRETTUEITKEY',
{ expiresIn: '300s' } // 5min
);
const refreshtoken = jwt.sign(
{
username: result[0].username,
userId: result[0].id,
@ -115,7 +123,7 @@ export const login = async (req, res, next) => {
const results = await ownConn.query(sql1, [dateTimeString, result[0].id]);
return res.status(200).send({
message: 'Logged in!',
token,
token: { authToken: authtoken, refreshToken: refreshtoken },
user: result[0],
});
}

View File

@ -4,6 +4,7 @@ import ownConn from "../dbConfig.js";
export const insertChecklistSolutionTodo = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO checklistsolutions(solutionID, step, asset, task, comments) VALUES(?, ?, ?, ?, ?)`, [data.solutionID, data.step, data.asset, data.task, data.comments]);
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -47,6 +48,7 @@ export const updateChecklistSolutionTodoById = async (data, result) => {
const id = data.primaryID;
let sql = `UPDATE checklistsolutions SET step = ?, asset = ?, task = ?, comments = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.step, data.asset, data.task, data.comments, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -61,6 +63,7 @@ export const deleteAllChecklistSolutionTodosSolutionID = async (id, result) => {
try {
let sql = `DELETE FROM checklistsolutions WHERE solutionID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -75,6 +78,7 @@ export const deleteChecklistSolutionTodo = async (id, result) => {
try {
let sql = `DELETE FROM checklistsolutions WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -61,6 +61,7 @@ export const deleteIssueSlipById = async (id, result) => {
try {
let sql = `DELETE FROM issueslips WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -75,6 +76,7 @@ export const deleteIssueSlipByTicketNo = async (id, result) => {
try {
let sql = `DELETE FROM issueslips WHERE ticketNo = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -87,7 +89,8 @@ export const deleteIssueSlipByTicketNo = async (id, result) => {
//insert issue slip to database
export const insertIssueSlip = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO issueslips(customerID, customer, ticketNo, creationDate, lastView, user, notes, supplierRequest, supplierOffer, clientOffer, clientOrder, supplierOrder, ingress, egress, ingressBill, egressBill) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.customerID, data.customer, data.ticketNo, data.creationDate, data.lastView, data.user, data.notes, data.supplierRequest, data.supplierOffer, data.clientOffer, data.clientOrder, data.supplierOrder, data.ingress, data.egress, data.ingressBill, data.egressBill])
const results = await ownConn.query(`INSERT INTO issueslips(customerID, customer, ticketNo, creationDate, lastView, user, notes, deliveryAddress, supplierRequestDate, supplierRequest, supplierOfferDate, supplierOffer, clientOfferDate, clientOffer, clientOrderDate, clientOrder, supplierOrderDate, supplierOrder, ingressDate, ingress, egressDate, egress, ingressBillDate, ingressBill, egressBillDate, egressBill) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.customerID, data.customer, data.ticketNo, data.creationDate, data.lastView, data.user, data.notes, data.deliveryAddress, data.supplierRequestDate, data.supplierRequest, data.supplierOfferDate, data.supplierOffer, data.clientOfferDate, data.clientOffer, data.clientOrderDate, data.clientOrder, data.supplierOrderDate, data.supplierOrder, data.ingressDate, data.ingress, data.egressDate, data.egress, data.ingressBillDate, data.ingressBill, data.egressBillDate, data.egressBill])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -129,8 +132,9 @@ export const getIssueSlipById = async (id, result) => {
export const updateIssueSlipById = async (data, result) => {
const id = data.primaryID;
try {
let sql = `UPDATE issueslips SET customerID = ?, customer = ?, ticketNo = ?, creationDate = ?, lastView = ?, user = ?, notes = ?, supplierRequest = ?, supplierOffer = ?, clientOffer = ?, clientOrder = ?, supplierOrder = ?, ingress = ?, egress = ?, ingressBill = ?, egressBill = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.customerID, data.customer, data.ticketNo, data.creationDate, data.lastView, data.user, data.notes, data.supplierRequest, data.supplierOffer, data.clientOffer, data.clientOrder, data.supplierOrder, data.ingress, data.egress, data.ingressBill, data.egressBill, id])
let sql = `UPDATE issueslips SET customerID = ?, customer = ?, ticketNo = ?, creationDate = ?, lastView = ?, user = ?, notes = ?, deliveryAddress = ?, supplierRequestDate = ?, supplierRequest = ?, supplierOfferDate = ?, supplierOffer = ?, clientOfferDate = ?, clientOffer = ?, clientOrderDate = ?, clientOrder = ?, supplierOrderDate = ?, supplierOrder = ?, ingressDate = ?, ingress = ?, egressDate = ?, egress = ?, ingressBillDate = ?, ingressBill = ?, egressBillDate = ?, egressBill = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.customerID, data.customer, data.ticketNo, data.creationDate, data.lastView, data.user, data.notes, data.deliveryAddress, data.supplierRequestDate, data.supplierRequest, data.supplierOfferDate, data.supplierOffer, data.clientOfferDate, data.clientOffer, data.clientOrderDate, data.clientOrder, data.supplierOrderDate, data.supplierOrder, data.ingressDate, data.ingress, data.egressDate, data.egress, data.ingressBillDate, data.ingressBill, data.egressBillDate, data.egressBill, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -19,7 +19,7 @@ export const getIssueVariantById = async (id, result) => {
try {
let sql = `SELECT * FROM issuevariants WHERE primaryID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
result(null, results[0]);
}
catch (err) {
// Manage Errors
@ -62,6 +62,7 @@ export const updateIssueVariantById = async (data, result) => {
const id = data.primaryID;
let sql = `UPDATE issuevariants SET issueID = ?, name = ? , properties = ?, state = ?, amount = ?, price = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.issueID, data.name, data.properties, data.state, data.amount, data.price, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -77,6 +78,7 @@ export const deleteIssueVariantById = async (id, result) => {
try {
let sql = `DELETE FROM issuevariants WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -91,6 +93,7 @@ export const deleteIssueVariantByIssueSlipId = async (id, result) => {
try {
let sql = `DELETE FROM issuevariants WHERE issueID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -104,6 +107,7 @@ export const deleteIssueVariantByIssueSlipId = async (id, result) => {
export const insertIssueVariant = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO issuevariants(issueID, name, properties, state, amount, price) VALUES(?, ?, ?, ?, ?, ?)`, [data.issueID, data.name, data.properties, data.state, data.amount, data.price])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -14,12 +14,40 @@ export const getAllIssues = async (result) => {
}
};
//get all selected issues by state
export const getSelectedIssuesByState = async (selected, result) => {
try {
let sql = `SELECT * FROM issues WHERE state LIKE '%${selected}%' ORDER BY state ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get all selected issues by issue name
export const getSelectedIssuesByIssueName = async (selected, result) => {
try {
let sql = `SELECT * FROM issues WHERE name LIKE '%${selected}%' ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get single issue
export const getIssueById = async (id, result) => {
try {
let sql = `SELECT * FROM issues WHERE primaryID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
result(null, results[0]);
}
catch (err) {
// Manage Errors
@ -34,6 +62,7 @@ export const updateIssueById = async (data, result) => {
const id = data.primaryID;
let sql = `UPDATE issues SET name = ?, type = ? , state = ?, amount = ?, properties = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.name, data.type, data.state, data.amount, data.properties, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -48,6 +77,7 @@ export const deleteIssueById = async (id, result) => {
try {
let sql = `DELETE FROM issues WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -61,6 +91,7 @@ export const deleteIssueById = async (id, result) => {
export const insertIssue = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO issues(name, type, state, amount, properties) VALUES(?, ?, ?, ?, ?)`, [data.name, data.type, data.state, data.amount, data.properties])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -88,6 +88,7 @@ export const deleteMaintenanceVisitById = async (id, result) => {
export const insertMaintenanceVisit = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO maintenancevisits(name, templateID, maintenanceType, state, creationDate, completionDate, user, customer, customerID, templateNotes, type, timeSpent, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.name, data.templateID, data.maintenanceType, data.state, data.creationDate, data.completionDate, data.user, data.customer, data.customerID, data.templateNotes, data.type, data.timeSpent, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -100,7 +101,7 @@ export const insertMaintenanceVisit = async (data, result) => {
//get single maintenance visit by name
export const getMaintenanceVisitByName = async (id, result) => {
try {
let sql = `SELECT * FROM maintenancevisits WHERE name = ?`;
let sql = `SELECT * FROM maintenancevisits WHERE name = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -114,7 +115,7 @@ export const getMaintenanceVisitByName = async (id, result) => {
//get single maintenance visit by id
export const getMaintenanceVisitById = async (id, result) => {
try {
let sql = `SELECT * FROM maintenancevisits WHERE primaryID = ?`;
let sql = `SELECT * FROM maintenancevisits WHERE primaryID = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -131,6 +132,7 @@ export const updateMaintenanceVisitStateById = async (data, result) => {
const id = data.primaryID;
let sql = `UPDATE maintenancevisits SET state = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.state, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -4,6 +4,7 @@ import ownConn from "../dbConfig.js";
export const insertMaintenanceVisitTodo = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO maintenancevisittodos(templateID, step, asset, task, comment, done) VALUES(?, ?, ?, ?, ?, ?)`, [data.templateID, data.step, data.asset, data.task, data.comment, data.done])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -47,6 +48,7 @@ export const updateMaintenanceVisitTodoById = async (data, result) => {
const id = data.primaryID;
let sql = `UPDATE maintenancevisittodos SET step = ?, asset = ?, task = ?, comment = ?, done = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.step, data.asset, data.task, data.comment, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -18,8 +18,9 @@ export const getMasterMaintenanceVisitTodoById = async (id, result) => {
export const updateMasterMaintenanceVisitTodoById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE mastermaintenancetodos SET templateID = ?, asset = ? , task = ?, comments = ? WHERE primaryID = ?`;
let sql = `UPDATE mastermaintenancetodos SET templateID = ?, asset = ? , task = ?, commets = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.templateID, data.asset, data.task, data.comments, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -35,6 +36,7 @@ export const deleteMasterMaintenanceVisitTodoById = async (id, result) => {
try {
let sql = `DELETE FROM mastermaintenancetodos WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -49,6 +51,7 @@ export const deleteMasterMaintenanceVisitTodoByTemplateId = async (id, result) =
try {
let sql = `DELETE FROM mastermaintenancetodos WHERE templateID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -79,7 +82,8 @@ export const updateMasterMaintenanceVisitTodos = async (data, result) => {
//insert master maintenance visit todo to databased
export const insertMasterMaintenanceVisitTodo = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO mastermaintenancetodos(templateID, rowID, asset, task, comments) VALUES(?, ?, ?, ?, ?)`, [data.templateID, data.rowID, data.asset, data.task, asset.comments])
const results = await ownConn.query(`INSERT INTO mastermaintenancetodos(templateID, rowID, asset, task, commets) VALUES(?, ?, ?, ?, ?)`, [data.templateID, data.rowID, data.asset, data.task, data.comment])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -62,6 +62,7 @@ export const updateMasterMaintenanceVisitById = async (data, result) => {
const id = data.checklistID;
let sql = `UPDATE mastermaintenancevisits SET name = ?, customerID = ? , customer = ?, type = ?, lastView = ?, user = ?, notes = ? WHERE checklistID = ?`;
const results = await ownConn.query(sql, [data.name, data.customerID, data.customer, data.type, data.lastView, data.user, data.notes, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -75,6 +76,7 @@ export const updateMasterMaintenanceVisitById = async (data, result) => {
export const insertMasterMaintenanceVisit = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO mastermaintenancevisits(name, customerID, customer, type, lastView, user, notes) VALUES(?, ?, ?, ?, ?, ?, ?)`, [data.name, data.customerID, data.customer, data.type, data.lastView, data.user, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -89,6 +91,7 @@ export const deleteMasterMaintenanceVisitById = async (id, result) => {
try {
let sql = `DELETE FROM mastermaintenancevisits WHERE checklistID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -20,6 +20,7 @@ export const updateOrderingInfoIssueSlipById = async (data, result) => {
const id = data.primaryID;
let sql = `UPDATE orderinginfoissueslips SET issueSlipID = ?, article = ? , amount = ?, price = ?, comment = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.issueSlipID, data.article, data.amount, data.price, data.comment, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -35,6 +36,7 @@ export const deleteOrderingInfoIssueSlipById = async (id, result) => {
try {
let sql = `DELETE FROM orderinginfoissueslips WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -49,6 +51,7 @@ export const deleteOrderingInfoIssueSlipByIssueSlipId = async (id, result) => {
try {
let sql = `DELETE FROM orderinginfoissueslips WHERE issueSlipID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -62,6 +65,7 @@ export const deleteOrderingInfoIssueSlipByIssueSlipId = async (id, result) => {
export const insertOrderingInfoIssueSlip = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO orderinginfoissueslips(issueSlipID, article, amount, price, comment) VALUES(?, ?, ?, ?, ?)`, [data.issueSlipID, data.article, data.amount, data.price, data.comment])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -115,7 +115,7 @@ export const insertProductionOrder = async (data, result) => {
//get single production order by name
export const getProductionOrderByName = async (id, result) => {
try {
let sql = `SELECT * FROM productionorders WHERE name = ?`;
let sql = `SELECT * FROM productionorders WHERE name = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -129,7 +129,7 @@ export const getProductionOrderByName = async (id, result) => {
//get single production order by id
export const getProductionOrderById = async (id, result) => {
try {
let sql = `SELECT * FROM productionorders WHERE ticketNumber = ?`;
let sql = `SELECT * FROM productionorders WHERE ticketNumber = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}

View File

@ -46,6 +46,7 @@ export const getSolutionByName = async (id, result) => {
export const insertSolution = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO solutions(solutionName, assetName, customer, customerID, type, lastView, user, description, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.solutionName, data.assetName, data.customer, data.customerID, data.type, data.lastView, data.user, data.description, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -61,6 +62,7 @@ export const updateSolutionById = async (data, result) => {
const id = data.primaryID;
let sql = `UPDATE solutions SET solutionName = ?, assetName = ?, customer = ?, customerID = ?, type = ?, lastView = ?, user = ?, description = ?, notes = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.solutionName, data.assetName, data.customer, data.customerID, data.type, data.lastView, data.user, data.description, data.notes, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -101,8 +103,8 @@ export const getSelectedSolutionsBySolutionName = async (selected, result) => {
//get all selected solutions by asset name
export const getSelectedSolutionsByAssetName = async (selected, result) => {
try {
let sql = `SELECT * FROM solutions WHERE LOWER(assetName) LIKE '%${selected.toLowerCase()}%' ORDER BY assetName ASC`;
const results = await ownConn.execute(sql)
let sql = `SELECT * FROM solutions WHERE assetName = ? ORDER BY solutionName ASC`;
const results = await ownConn.execute(sql, [selected])
result(null, results);
}
catch (err) {
@ -131,6 +133,7 @@ export const deleteSolutionById = async (id, result) => {
try {
let sql = `DELETE FROM solutions WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -138,4 +141,4 @@ export const deleteSolutionById = async (id, result) => {
console.log("SQL error : ", err);
result(err, null);
}
};
};

View File

@ -166,6 +166,8 @@ import {
showIssueById,
updateIssue,
showIssues,
showSelectedIssuesByIssueName,
showSelectedIssuesByState,
} from "../controller/issues.js";
import {
@ -219,8 +221,8 @@ router.put("/masterMaintenanceVisitTodos", updateMasterMaintenanceVisitTodo);
// Delete master maintenance visit todo
router.delete("/masterMaintenanceVisitTodos/:id", deleteMasterMaintenanceVisitTodo);
// Delete master maintenance visit todo by customer id
router.delete("/masterMaintenanceVisitTodosByCustomerid/:id", deleteMasterMaintenanceVisitTodoByTemplateIds);
// Delete master maintenance visit todo by template id
router.delete("/masterMaintenanceVisitTodosByTemplateid/:id", deleteMasterMaintenanceVisitTodoByTemplateIds);
// Update all master maintenance visit todos
router.put("/allMasterMaintenanceVisitTodos", updateAllMasterMaintenanceVisitTodos)
@ -552,6 +554,12 @@ router.get("/issues", showIssues);
//get issue by id
router.get("/issues/:id", showIssueById);
//get all issues by selected name
router.get("/selectedIssuesByIssueName/:id", showSelectedIssuesByIssueName)
//get all issues by selected state
router.get("/selectedIssuesByState/:id", showSelectedIssuesByState)
// Update issue
router.put("/issues", updateIssue);

View File

@ -1,15 +1,40 @@
<template>
<section :class="['asset-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Asset:</div>
<pre :class="['data', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Asset name</pre>
<pre :class="['data', darkMode ? 'pre-darkmode' : 'pre-lightmode']">{{ asset.assetName }}</pre>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const chosenAssetId = computed(() => store.state.chosenAssetId);
const asset = ref({});
const darkMode = ref(true)
// get config item from id
const getItemById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getConfigItem/${chosenAssetId.value}`
);
asset.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
onMounted(() => {
getItemById();
});
</script>
<script>

View File

@ -1,9 +1,10 @@
<template>
<section :class="['client-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Client</div>
<pre v-if="!filtered" :class="['data', darkMode ? 'pre-darkmode' : 'pre-lightmode']">{{ clientFilter }}</pre>
<input v-if="filtered" v-model="clientFilter" @change="filterConfigItemList()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
<section :class="['customer-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Customer</div>
<pre v-if="!filtered"
:class="['data', 'pre-customer', darkMode ? 'pre-darkmode' : 'pre-lightmode']">{{ customerFilter }}</pre>
<input v-if="filtered" v-model="customerFilter" @change="filterList()"
:class="['data', 'input-customer', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
</template>
@ -14,32 +15,40 @@ import { computed } from 'vue';
const store = useStore();
const filtered = computed(() => store.state.filtered);
const filteredTerm = computed(() => store.state.filteredByClient);
const clientFilter = ref(store.state.filteredByClient);
const filteredTerm = computed(() => store.state.filteredByCustomer);
const customerFilter = ref(store.state.filteredByCustomer);
const darkMode = ref(true)
// update filtered term
const updateFilterTerm = () => {
clientFilter.value = filteredTerm.value
customerFilter.value = filteredTerm.value
}
const checkFiltered = () => {
if (!filtered.value) {
customerFilter.value = ''
filterList();
}
}
// update the filtered term in the store
const filterConfigItemList = () => {
store.commit('updateFilterbyClient', clientFilter.value);
const filterList = () => {
store.commit('updateFilterbyCustomer', customerFilter.value);
}
watch(filteredTerm, updateFilterTerm)
watch(filtered, checkFiltered)
</script>
<script>
export default {
name: "ClientSearch",
name: "CustomerSearch",
};
</script>
<style scoped>
.client-search {
.customer-search {
display: flex;
align-items: center;
padding: 0.625em 1.875em;
@ -98,8 +107,13 @@ export default {
color: #000;
}
.input {
.input-customer {
border: none;
margin-left: 1rem;
}
.pre-customer {
margin-left: 1rem;
}
.data-darkmode {

View File

@ -0,0 +1,128 @@
<template>
<section :class="['issue-state-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Issue state</div>
<pre v-if="!filtered"
:class="['data', 'pre-issue', darkMode ? 'pre-darkmode' : 'pre-lightmode']">{{ issueStateFilter }}</pre>
<input v-if="filtered" v-model="issueStateFilter" @change="filterList()"
:class="['data', 'input-state', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
</template>
<script setup>
import { ref, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const filtered = computed(() => store.state.filtered);
const filteredTerm = computed(() => store.state.filteredByCustomer);
const issueStateFilter = ref(store.state.filteredByCustomer);
const darkMode = ref(true)
// update filtered term
const updateFilterTerm = () => {
issueStateFilter.value = filteredTerm.value
}
const checkFiltered = () => {
if (!filtered.value) {
issueStateFilter.value = ''
filterList();
}
}
// update the filtered term in the store
const filterList = () => {
store.commit('updateFilterbyCustomer', issueStateFilter.value);
}
watch(filteredTerm, updateFilterTerm)
watch(filtered, checkFiltered)
</script>
<script>
export default {
name: "IssueStateSearch",
};
</script>
<style scoped>
.issue-state-search {
display: flex;
align-items: center;
padding: 0.625em 1.875em;
gap: 1.25em;
width: 30.125em;
height: 3.125em;
box-shadow: 0.25em 0.25em 0.25em rgba(0, 0, 0, 0.25);
border-radius: 0.625em;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.label {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";
font-style: normal;
font-weight: 400;
font-size: 0.875em;
line-height: 1.875;
letter-spacing: 0.05em;
}
.label-darkmode {
color: #FFFFFF;
}
.label-lightmode {
color: #000;
}
.data {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.pre-darkmode {
background-color: #212121;
color: #fff;
}
.pre-lightmode {
background-color: #EBEBEB;
color: #000;
}
.input-state {
border: none;
margin-left: 1rem;
}
.pre-issue {
margin-left: 1rem;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
</style>

View File

@ -4,13 +4,13 @@
<span class="title-icon" id="logo-icon">
<img loading="lazy" srcSet="../favicon-gelb-rot-32x32.png" />
</span>
<pre :class="['title', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Login</pre>
<pre :class="['title', darkMode ? 'title-darkmode' : 'title-lightmode']">Login</pre>
</div>
<div class="login-field">
<div class="form-field" id="username-field">
<label for="username-input" id="username-label">
<span :class="['icon', darkMode ? 'icon-darkmode' : 'icon-lightmode']" id="username-icon">
<img loading="lazy" src="../icons/Mail-Icon.svg" />
<img loading="lazy" src="/icons/Mail-Icon.svg" />
</span>
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Username:</div>
</label>
@ -21,14 +21,13 @@
<div class="form-field" id="password-field">
<label for="password-input" id="password-label">
<span :class="['icon', darkMode ? 'icon-darkmode' : 'icon-lightmode']" id="password-icon">
<img loading="lazy" src="../icons/Lock-Icon.svg" />
<img loading="lazy" src="/icons/Lock-Icon.svg" />
</span>
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Password:</div>
</label>
<div :class="['input-field', darkMode ? 'input-darkmode' : 'input-lightmode']">
<input type="text" id="password-input" placeholder="*******">
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="show-password-toggle"
value="Show">
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="show-password-toggle" value="Show">
</div>
</div>
</div>
@ -37,20 +36,20 @@
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']"> {{ errorMsg }} </div>
</label>
</div>
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="login-button" value="Login"
@click="handleLogin">
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="login-button" value="Signup"
@click="testFunctionSignup">
<div class="buttons">
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="login-button" value="Login" @click="handleLogin">
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="signup-button" value="Signup" @click="testFunctionSignup">
</div>
</form>
</template>
<script setup>
import { useRouter } from 'vue-router';
import { ref } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../clientsideConfig.js';
const { signIn } = useAuth()
const router = useRouter();
const darkMode = ref(true);
const isError = ref(false);
@ -63,19 +62,29 @@ const handleLogin = async () => {
const username = document.getElementById('username-input').value;
const password = document.getElementById('password-input').value;
const requestBody = {
//const requestBody = {
const credentials = {
username: username,
password: password,
}
try {
let res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/login`, requestBody);
/*let res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/login`, requestBody);
const sessionToken = useCookie('token', {maxAge: 604800, sameSite: true});
sessionToken.value = res.data.token;
Axios.defaults.headers.common['Authorization'] = `${username}`;
const userToken = useCookie('user', {maxAge: 604800, sameSite: true});
userToken.value = username;
// something to do with the res?
console.log(res.data)
console.log(sessionToken)
console.log(res.data.message)
// sucessfully logged in
router.push('/')
router.push('/home')*/
let res = await signIn( credentials, { callbackUrl: '/home' })
// console.log("res", res)
} catch (err) {
// handle the error
console.log(err.response.statusText)
@ -88,16 +97,16 @@ const testFunctionSignup = async () => {
isError.value = false;
errorMsg.value = '';
const username = 'franzzzzzrtg'
const password = '112345678'
const password_repeat = '112345678'
const fullName = 'hallo'
const email = 'test.sdj@web.de'
const phonenumber = '015736283729'
const address = 'Strasse'
const city = 'tuebingen'
const postcode = '72121'
const adminBool = false
const username = 'adm_tueit'
const password = 'SvF=?bfEx7_hV,cMEu4m'
const password_repeat = 'SvF=?bfEx7_hV,cMEu4m'
const fullName = 'administrator'
const email = 'support@tueit.de'
const phonenumber = ''
const address = ''
const city = ''
const postcode = ''
const adminBool = true
const technician1Bool = false
const technician2Bool = false
const technicianMonitoringBool = false
@ -123,10 +132,11 @@ const testFunctionSignup = async () => {
}
try {
let res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/signup`, requestBody);
// something to do with the res?
console.log(res)
// console.log(res)
} catch (err) {
// handle the error
@ -162,22 +172,22 @@ export default {
align-items: center;
justify-content: center;
width: 31.25rem;
height: 33rem;
min-height: 33rem;
height: fit-content;
border-radius: 0.625rem;
padding: 2.5rem 1.875rem;
gap: 1.875rem;
}
.form-darkmode {
border: 0.0625rem solid #000;
background-color: #2c2c2c;
}
.form-lightmode {
border: 0.0625rem solid #8e8e8e;
background-color: #fff;
}
.title-field {
display: flex;
flex-direction: column;
@ -192,7 +202,6 @@ export default {
width: 3.125rem;
height: 3.125rem;
}
.title-icon>img {
width: 3.125rem;
height: 3.125rem;
@ -203,20 +212,14 @@ export default {
.title {
margin: 0;
letter-spacing: 5%;
letter-spacing: 0.05rem;
white-space: nowrap;
font: 400 1.875rem/1.875rem Overpass, sans-serif;
}
.title-darkmode { color: #ffffff; }
.title-lightmode { color: #000000; }
.pre-darkmode,
.title-darkmode {
color: #fff;
}
.pre-lightmode,
.title-lightmode {
color: #000;
}
.login-field {
display: flex;
@ -227,6 +230,7 @@ export default {
gap: 1.25rem;
}
.form-field {
display: flex;
flex-direction: column;
@ -238,16 +242,6 @@ export default {
gap: 0.625rem;
}
.form-field-error-msg {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
width: 25rem;
height: 3rem;
gap: 0.4rem;
}
label {
display: flex;
flex-direction: row;
@ -265,43 +259,28 @@ label {
width: 1.875rem;
height: 1.875rem;
}
.icon>img {
object-fit: contain;
object-position: center;
overflow: hidden;
}
.icon-darkmode>img {
filter: invert(100%);
}
.icon-lightmode>img {
filter: invert(0%);
}
#username-icon>img {
width: auto;
height: 0.9375rem;
}
}
#password-icon>img {
width: 0.9375rem;
height: auto;
}
.icon-darkmode>img { filter: invert(100%); }
.icon-lightmode>img { filter: invert(0%); }
.label {
letter-spacing: 2%;
letter-spacing: 0.02rem;
font: 400 0.9375rem/1.875rem Overpass, sans-serif;
}
.label-darkmode {
color: #fff;
}
.label-lightmode {
color: #000;
}
.label-darkmode { color: #ffffff; }
.label-lightmode { color: #000000; }
.input-field {
display: flex;
@ -314,15 +293,9 @@ label {
border-radius: 0.3125rem;
padding: 0.1875rem 0.625rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
}
.input-darkmode {
background-color: #212121;
}
.input-lightmode {
background-color: #EBEBEB;
}
}
.input-darkmode { background-color: #212121; }
.input-lightmode { background-color: #EBEBEB; }
input[type=text] {
width: 100%;
@ -330,40 +303,63 @@ input[type=text] {
background-color: #00000000;
border: none;
color: #8e8e8e;
letter-spacing: 5%;
letter-spacing: 0.01rem;
white-space: nowrap;
font: 100 0.75rem/1.25rem Overpass, sans-serif;
}
input[type=button] {
#show-password-toggle {
width: fit-content;
height: auto;
align-self: flex-end;
padding: 0;
border-radius: 0;
background-color: #00000000;
background: none;
border: none;
letter-spacing: 5%;
letter-spacing: 0.01rem;
white-space: nowrap;
font: 300 0.75rem/1.25rem Overpass, sans-serif;
}
.button-darkmode {
color: #fff;
.form-field-error-msg {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
width: 25rem;
height: 3rem;
gap: 0.4rem;
}
.button-lightmode {
color: #000;
.buttons {
display: flex;
flex-direction: row;
height: fit-content;
width: 100%;
align-items: center;
justify-content: center;
padding: 0.625rem 0.625rem 0;
gap: 2.5rem;
}
#login-button {
width: 13.75rem;
height: 4.375rem;
input[type=button] {
width: 9.375rem;
height: 3.125rem;
padding: 0.625rem;
border-radius: 0.625rem;
align-self: center;
border: none;
color: #000;
background: linear-gradient(93deg, #ff0f00 3.67%, #ffe608 100%);
letter-spacing: 2%;
letter-spacing: 0.02rem;
white-space: nowrap;
font: 600 1.25rem/1.875rem Overpass, sans-serif;
font: 600 1.125rem/1.875rem Overpass, sans-serif;
}
.button-darkmode { color: #ffffff; }
.button-lightmode { color: #000000; }
</style>

View File

@ -1,8 +1,207 @@
<template>
<section :class="['accounting-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<section v-if="!addBool" :class="['accounting-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']" id="accounting">Accounting:
<div class="asset-data">
<table class="data-table" id="asset-table-no-client">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Action', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Action</th>
<th
:class="['Date', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
Date</th>
<th :class="['Comments', darkMode ? 'th-darkmode' : 'th-lightmode']">Comments</th>
</tr>
<tr :class="['table-row', darkMode ? 'first-tr-darkmode' : 'first-tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Supplier request</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.supplierRequestDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.supplierRequestDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.supplierRequest }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.supplierRequest" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Supplier offer</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.supplierOfferDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.supplierOfferDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.supplierOffer }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.supplierOffer" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Customer offer</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.clientOfferDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.clientOfferDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.clientOffer }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.clientOffer" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Customer order</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.clientOrderDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.clientOrderDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.clientOrder }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.clientOrder" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Supplier order</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.supplierOrderDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.supplierOrderDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.supplierOrder }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.supplierOrder" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Ingress</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.ingressDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.ingressDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.ingress }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.ingress" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Egress</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.egressDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.egressDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.egress }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.egress" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'final-tr-darkmode' : 'final-tr-lightmode']" id="row-2">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Ingress bill</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.ingressBillDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.ingressBillDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.ingressBill }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.ingressBill" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'final-tr-darkmode' : 'final-tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Egress bill</td>
<td v-if="!editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
{{
issueSlip.egressBillDate }}</td>
<td v-if="editable"
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<input type="text" v-model="issueSlip.egressBillDate" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
issueSlip.egressBill }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="issueSlip.egressBill" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section v-if="addBool" :class="['accounting-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']" id="accounting">Accounting:
<div class="asset-data">
<table class="data-table" id="asset-table-no-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
@ -19,8 +218,13 @@
Supplier request</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newSupplierRequestDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newSupplierRequest" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
@ -28,26 +232,41 @@
Supplier offer</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newSupplierOfferDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newSupplierOffer" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Client offer</td>
Customer offer</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newClientOfferDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newClientOffer" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Client order</td>
Customer order</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newClientOrderDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newClientOrder" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
@ -55,8 +274,13 @@
Supplier order</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newSupplierOrderDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newSupplierOrder" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
@ -64,8 +288,13 @@
Ingress</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newIngressDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newIngress" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
@ -73,8 +302,13 @@
Egress</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newEgressDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newEgress" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'final-tr-darkmode' : 'final-tr-lightmode']" id="row-2">
<td
@ -82,8 +316,13 @@
Ingress bill</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newIngressBillDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newIngressBill" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr :class="['table-row', darkMode ? 'final-tr-darkmode' : 'final-tr-lightmode']" id="row-1">
<td
@ -91,29 +330,233 @@
Egress bill</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newEgressBillDate" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newEgressBill" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section v-if="addBool" id="saveNewItem">
<button :class="[darkMode ? 'saveNewItem-darkmode' : 'saveNewItem-lightmode']"
@click="addIssueSlip()">Save</button>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const editable = computed(() => store.state.editable);
const chosenIssueSlipId = computed(() => store.state.chosenIssueSlipId);
const addBool = computed(() => store.state.new);
const newTicketNoIS = computed(() => store.state.newTicketNoIS);
const newCustomerIdIS = computed(() => store.state.newCustomerIdIS);
const newCustomerIS = computed(() => store.state.newCustomerIS);
const newNotesIS = computed(() => store.state.newNotesIS);
const newUserIS = computed(() => store.state.newUserIS);
const newDeliveryAddressIS = computed(() => store.state.newDeliveryAddressIS);
const newAddRowOI = computed(() => store.state.newAddRowOI);
const newOIs = computed(() => store.state.newOIs);
const newClientOffer = ref('');
const newClientOrder = ref('');
const newSupplierOffer = ref('');
const newSupplierOrder = ref('');
const newSupplierRequest = ref('');
const newIngress = ref('');
const newIngressBill = ref('');
const newEgress = ref('');
const newEgressBill = ref('');
const newClientOfferDate = ref('');
const newClientOrderDate = ref('');
const newSupplierOfferDate = ref('');
const newSupplierOrderDate = ref('');
const newSupplierRequestDate = ref('');
const newIngressDate = ref('');
const newIngressBillDate = ref('');
const newEgressDate = ref('');
const newEgressBillDate = ref('');
const darkMode = ref(true)
const issueSlip = ref({});
// get issue slip from id
const getIssueSlipById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getIssueSlip/${chosenIssueSlipId.value}`
);
issueSlip.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update accounting fields in the store
const updateIS = () => {
const is = {
supplierRequestDate: newSupplierRequestDate.value,
supplierRequest: newSupplierRequest.value,
supplierOfferDate: newSupplierOfferDate.value,
supplierOffer: newSupplierOffer.value,
clientOfferDate: newClientOfferDate.value,
clientOffer: newClientOffer.value,
clientOrderDate: newClientOrderDate.value,
clientOrder: newClientOrder.value,
supplierOrderDate: newSupplierOrderDate.value,
supplierOrder: newSupplierOrder.value,
ingressDate: newIngressDate.value,
ingress: newIngress.value,
egressDate: newEgressDate.value,
egress: newEgress.value,
ingressBillDate: newIngressBillDate.value,
ingressBill: newIngressBill.value,
egressBillDate: newEgressBillDate.value,
egressBill: newEgressBill.value,
};
store.commit('updateAccountingComponent', is);
}
//update data
const updateIssueSlip = async () => {
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateIssueSlip`,
{
primaryID: issueSlip.value.primaryID,
customerID: issueSlip.value.customerID,
customer: issueSlip.value.customer,
ticketNo: issueSlip.value.ticketNo,
creationDate: issueSlip.value.creationDate,
lastView: issueSlip.value.lastView,
user: issueSlip.value.user,
notes: issueSlip.value.notes,
deliveryAddress: issueSlip.value.deliveryAddress,
supplierRequestDate: issueSlip.value.supplierRequestDate,
supplierRequest: issueSlip.value.supplierRequest,
supplierOfferDate: issueSlip.value.supplierOfferDate,
supplierOffer: issueSlip.value.supplierOffer,
clientOfferDate: issueSlip.value.clientOfferDate,
clientOffer: issueSlip.value.clientOffer,
clientOrderDate: issueSlip.value.clientOrderDate,
clientOrder: issueSlip.value.clientOrder,
supplierOrder: issueSlip.value.supplierOrder,
supplierOrderDate: issueSlip.value.supplierOrderDate,
ingressDate: issueSlip.value.ingressDate,
ingress: issueSlip.value.ingress,
egressDate: issueSlip.value.egressDate,
egress: issueSlip.value.egress,
ingressBillDate: issueSlip.value.ingressBillDate,
ingressBill: issueSlip.value.ingressBill,
egressBillDate: issueSlip.value.egressBillDate,
egressBill: issueSlip.value.egressBill,
}
)
await getIssueSlipById();
} catch (err) {
console.log(err.response.statusText);
}
}
// add new issue slip
const addIssueSlip = async () => {
if (newTicketNoIS.value.length === 0) {
alert("Please add a ticket number!");
return;
}
if (newCustomerIS.value.length === 0) {
alert("Please choose a customer!");
return;
}
// get the time and date
const today = new Date();
const date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
const time = today.getHours() + ":" + today.getMinutes();
const dateTime = date + ' ' + time;
let allFine = true;
newOIs.value.forEach(oi => {
if (oi.article.length === 0 && oi.amount.length === 0 && oi.price.length === 0 && oi.comment.length === 0) {
alert(`Please add data for all ordering info.`);
allFine = false
}
})
if (!allFine) {
return
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addIssueSlip`,
{
customerID: newCustomerIdIS.value,
customer: newCustomerIS.value,
ticketNo: newTicketNoIS.value,
creationDate: dateTime,
lastView: '',
user: newUserIS.value,
notes: newNotesIS.value,
deliveryAddress: newDeliveryAddressIS.value,
supplierRequestDate: newSupplierRequestDate.value,
supplierRequest: newSupplierRequest.value,
supplierOfferDate: newSupplierOfferDate.value,
supplierOffer: newSupplierOffer.value,
clientOfferDate: newClientOfferDate.value,
clientOffer: newClientOffer.value,
clientOrderDate: newClientOrderDate.value,
clientOrder: newClientOrder.value,
supplierOrderDate: newClientOrderDate.value,
supplierOrder: newSupplierOrder.value,
ingressDate: newIngressDate.value,
ingress: newIngress.value,
egressDate: newEgressDate.value,
egress: newEgress.value,
ingressBillDate: newIngressBillDate.value,
ingressBill: newIngressBill.value,
egressBillDate: newEgressBillDate.value,
egressBill: newEgressBill.value,
});
newOIs.value.forEach(async oi => {
try {
const res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addOrderingInfo`,
{
issueSlipID: response.data,
article: oi.article,
amount: oi.amount,
price: oi.price,
comment: oi.comment,
});
} catch (err) {
console.log(err);
}
store.commit('resetStore');
store.commit('changeToIssueSliplist');
})
} catch (err) {
console.log(err.response.statusText);
}
}
onMounted(() => {
getIssueSlipById();
});
</script>
<script>
export default {
name: "Accounting",
};
</script>
</script>
<style scoped>
.accounting-information {
display: flex;
@ -134,6 +577,31 @@ export default {
background-color: #fff;
}
.input {
border: none;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.data {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.label {
letter-spacing: 5%;
font: 400 1rem/1.875rem Overpass, sans-serif;
@ -204,6 +672,41 @@ export default {
background-color: #EBEBEB;
}
.saveNewItem-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.saveNewItem-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.saveNewItem-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.saveNewItem-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#saveNewItem {
text-align: center;
}
th,
td {

View File

@ -5,9 +5,9 @@
<input v-if="editable" v-model="item.assetName" @change="updateConfigItem()"
:class="['data', 'asset-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="asset-data">
<div class="client-location">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<div class="customer-location">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ item.customer }}</pre>
<select v-if="editable" id="customersDropDownChosenCI" v-model="item.customer"
@ -81,9 +81,9 @@
<input v-model="newAssetName" @change="updateAsset()"
:class="['data', 'asset-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="asset-data">
<div class="client-location">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<div class="customer-location">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<select id="customersDropDownChosenCI" v-model="newCustomer" @change="updateNewCustomerID()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
@ -217,7 +217,7 @@ const updateConfigItem = async () => {
counter += 1;
}
});
if (counter == 1) {
if (counter == 2) {
alert("This asset name already exists. Please choose an unique asset name or modify respectively delete the old one!");
item.value.assetName = '';
return;
@ -280,6 +280,7 @@ const confirmDeleteAsset = async () => {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteConfigItem/${chosenAssetId.value}`);
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToAssetlist');
} catch (err) {
console.log(err.response.statusText);
@ -337,7 +338,6 @@ onMounted(() => {
getConfigItems();
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
@ -475,7 +475,7 @@ export default {
align-self: stretch;
}
.client-location,
.customer-location,
.info {
display: flex;
flex-direction: column;

View File

@ -1,4 +1,14 @@
<template>
<section v-if="searchable" :class="['solution-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['solutionLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Solution</div>
<input v-model="solutionSearchFilter" @change="searchSolution()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<section v-if="filtered" :class="['solution-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['solutionLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Type</div>
<input v-model="typeSearchFilter" @change="filterSolutionByType()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Solutions:</div>
<table class="data-table" id="solution-checkklist">
@ -9,32 +19,135 @@
Solution</th>
<th :class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode']">Type</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<tr v-for="sol in solutions" :key="sol.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Solution', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Solution-darkmode' : 'Solution-lightmode']">
...</td>
<td :class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<nuxt-link to="/solutions" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
@click="goToChosenSolution(sol.primaryID)">
{{ sol.solutionName }}
</nuxt-link>
</td>
<td :class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode']">{{ sol.type }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
<script setup>
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const chosenAssetId = computed(() => store.state.chosenAssetId);
const searchable = computed(() => store.state.searchable);
const filtered = computed(() => store.state.filtered);
const solutionSearchFilter = ref('');
const typeSearchFilter = ref('');
const asset = ref({});
const solutions = ref([]);
const solutionsBySol = ref([]);
const solutionsByType = ref([]);
const darkMode = ref(true)
//get all solutions from the chosen asset
const getSolutions = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedSolutionsByAsset/${asset.value.assetName}`);
solutions.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update search term
const updateSearchTerm = async () => {
solutionSearchFilter.value = '';
await getSolutions();
}
// update filter term
const updateFilterTerm = async () => {
typeSearchFilter.value = '';
await getSolutions();
}
const goToChosenSolution = (id) => {
store.commit('setChosenSolution', id);
store.commit('changeToSolution');
};
// get config item from id
const getItemById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getConfigItem/${chosenAssetId.value}`
);
asset.value = response.data;
await getSolutions();
} catch (err) {
console.log(err.response.statusText);
}
}
//get all solutions based on the searched solution name
const searchSolution = async () => {
if (solutionSearchFilter.value === '') {
await getSolutions();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedSolutionsBySolution/${solutionSearchFilter.value}`);
solutionsBySol.value = response.data;
solutions.value = filterObjectsWithMatchingIds(solutions.value, solutionsBySol.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all solutions based on the searched solution name
const filterSolutionByType = async () => {
if (typeSearchFilter.value === '') {
await getSolutions();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedSolutionsByType/${typeSearchFilter.value}`);
solutionsByType.value = response.data;
solutions.value = filterObjectsWithMatchingIds(solutions.value, solutionsByType.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
const filterObjectsWithMatchingIds = (arr1, arr2) => {
return arr1.filter(obj1 => {
return arr2.some(obj2 => obj2.primaryID === obj1.primaryID);
});
};
watch(searchable, updateSearchTerm);
watch(filtered, updateFilterTerm);
onMounted(() => {
getItemById();
});
</script>
<script>
export default {
name: "AssetSolutionList",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -57,6 +170,62 @@ export default {
background-color: #fff;
}
.solutionLabel {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";
font-style: normal;
font-weight: 400;
font-size: 0.875em;
line-height: 1.875;
letter-spacing: 0.05em;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.dataInput {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.input {
border: none;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.solution-search {
display: flex;
align-items: center;
padding: 0.625em 1.875em;
gap: 1.25em;
width: 30.125em;
height: 3.125em;
box-shadow: 0.25em 0.25em 0.25em rgba(0, 0, 0, 0.25);
border-radius: 0.625em;
box-sizing: border-box;
}
.data-table {
width: 100%;
padding: 0 0.625rem;
@ -73,6 +242,11 @@ export default {
gap: 0.625rem;
}
#nuxt-link {
text-decoration: none;
color: white;
}
.tr-head-darkmode {
border-top: none;
border-bottom: 0.0625rem solid #000000;

View File

@ -1,6 +1,6 @@
<template>
<section v-if="searchable" :class="['asset-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['clientLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Config item</div>
<section v-if="assetSearchable" :class="['asset-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['customerLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Config item</div>
<input v-model="assetSearchFilter" @change="searchConfigItem()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
@ -10,8 +10,8 @@
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Client', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
Client</th>
:class="['Customer', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
Customer</th>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
@ -26,7 +26,7 @@
<tr v-for="item in configItemList" :key="item.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
:class="['Customer', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
{{ item.customer }}
</td>
<td
@ -63,8 +63,8 @@ const goToChosenAsset = (id) => {
store.commit('setChosenAsset', id);
store.commit('changeToAsset');
};
const clientFilter = computed(() => store.state.filteredByClient);
const searchable = computed(() => store.state.searchable);
const customerFilter = computed(() => store.state.filteredByCustomer);
const assetSearchable = computed(() => store.state.searchable);
const assetSearchFilter = ref('');
const darkMode = ref(true)
@ -78,8 +78,8 @@ const updateSearchTerm = async () => {
//get all config items
const getConfigItems = async () => {
if (!(clientFilter.value === '')) {
await getFilteredConfigItemsByClient();
if (!(customerFilter.value === '')) {
await getFilteredConfigItemsByCustomer();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllConfigItems`);
@ -90,10 +90,10 @@ const getConfigItems = async () => {
}
}
//get all config items based on the searched client
const getFilteredConfigItemsByClient = async () => {
//get all config items based on the searched customer
const getFilteredConfigItemsByCustomer = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedConfigItemsByClient/${clientFilter.value}`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedConfigItemsByCustomer/${customerFilter.value}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
@ -114,8 +114,8 @@ const searchConfigItem = async () => {
}
}
watch(clientFilter, getConfigItems);
watch(searchable, updateSearchTerm);
watch(customerFilter, getConfigItems);
watch(assetSearchable, updateSearchTerm);
onMounted(async () => {
await getConfigItems();
@ -136,7 +136,6 @@ export default {
align-items: flex-start;
justify-content: center;
align-self: stretch;
/* width: 100%; */
padding: 1.25rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
@ -253,15 +252,15 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Client {
.Customer {
width: 33.3%;
}
.Client-darkmode {
.Customer-darkmode {
border-right: 0.0625rem solid #000000;
}
.Client-lightmode {
.Customer-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
@ -316,7 +315,7 @@ th {
letter-spacing: 0.05em;
}
.clientLabel {
.customerLabel {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";

View File

@ -1,7 +1,7 @@
<template>
<!-- <template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Assets:</div>
<table class="data-table" id="asset-table-no-client">
<table class="data-table" id="asset-table-no-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
@ -40,7 +40,7 @@ const darkMode = ref(true)
<script>
export default {
name: "AssetTableNoClient",
name: "AssetTableNoCustomer",
};
</script>
@ -183,4 +183,4 @@ th {
.label-lightmode {
color: #000;
}
</style>
</style> -->

View File

@ -1,11 +1,11 @@
<template>
<section :class="[darkMode ? 'section-darkmode' : 'section-lightmode']">
<pre :class="['title', darkMode ? 'title-darkmode' : 'title-lightmode']">Client name</pre>
<div class="data-field" id="client-id">
<pre :class="['title', darkMode ? 'title-darkmode' : 'title-lightmode']">Customer name</pre>
<div class="data-field" id="customer-id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="client-data">
<div class="customer-data">
<div class="contact">
<pre :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Contact:</pre>
<div class="data-field" id="contact-person">
@ -59,7 +59,7 @@ const darkMode = ref(true)
<script>
export default {
name: "Client",
name: "Customer",
};
</script>
@ -94,12 +94,12 @@ section {
display: flex;
flex: auto;
flex-direction: row;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
align-items: center;
justify-content: flex-start;
gap: 1.25rem;
}
.data-field#client-id { padding: 0.625rem 1.875rem; }
.data-field#customer-id { padding: 0.625rem 1.875rem; }
.data-field#street-name { flex: 3; }
.label {
@ -135,7 +135,7 @@ pre {
}
.client-data {
.customer-data {
display: flex;
flex: auto;
flex-direction: row;

View File

@ -6,8 +6,8 @@
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="data-field" id="client-id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client ID:</pre>
<div class="data-field" id="customer-id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="data-field" id="head">
@ -32,7 +32,7 @@ const darkMode = ref(true)
<script>
export default {
name: "ClientDepartment",
name: "CustomerDepartment",
};
</script>
@ -86,7 +86,7 @@ display: flex;
flex: auto;
width: 30%;
flex-direction: row;
padding: 0.625rem 1.875rem;
padding: 0.8rem 1.875rem;
align-items: center;
justify-content: flex-start;
gap: 1.25rem;

View File

@ -2,7 +2,7 @@
<template>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Employees:</div>
<table class="data-table" id="client-employee-table">
<table class="data-table" id="customer-employee-table">
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th :class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID</th>
<th :class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">Name</th>
@ -28,7 +28,7 @@ const darkMode = ref(true)
<script>
export default {
name: "ClientDepartmentEmployeeList",
name: "CustomerDepartmentEmployeeList",
};
</script>

View File

@ -1,7 +1,7 @@
<template>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Departments:</div>
<table class="data-table" id="client-employee-table">
<table class="data-table" id="customer-employee-table">
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th :class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID</th>
<th :class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">Name</th>
@ -25,7 +25,7 @@ const darkMode = ref(true)
<script>
export default {
name: "ClientDepartmentList",
name: "CustomerDepartmentList",
};
</script>

View File

@ -32,8 +32,8 @@
</div>
</div>
<div class="data-group" id="employment-data">
<div class="data-field" id="client-id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client ID:</pre>
<div class="data-field" id="customer-id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="data-field" id="department">
@ -72,7 +72,7 @@ const darkMode = ref(true)
<script>
export default {
name: "ClientEmployee",
name: "CustomerEmployee",
};
</script>
@ -133,7 +133,7 @@ section {
flex: auto;
width: 20%;
flex-direction: row;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
align-items: center;
justify-content: flex-start;
gap: 1.25rem;

View File

@ -1,7 +1,7 @@
<template>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Employees:</div>
<table class="data-table" id="client-employee-table">
<table class="data-table" id="customer-employee-table">
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th :class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID</th>
<th :class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">Name</th>
@ -27,7 +27,7 @@ const darkMode = ref(true)
<script>
export default {
name: "ClientEmployeeList",
name: "CustomerEmployeeList",
};
</script>

View File

@ -1,6 +1,6 @@
<template>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<table class="data-table" id="client-table">
<table class="data-table" id="customer-table">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
@ -33,7 +33,7 @@ const darkMode = ref(true)
<script>
export default {
name: "ClientTable",
name: "CustomerTable",
};
</script>

View File

@ -1,22 +1,33 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['issue-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Name</h2>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['issue-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{ issue.name }}</h2>
<input v-if="editable" v-model="issue.name" @change="updateIssueItem()"
:class="['data', 'issue-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="issue-data">
<div class="type">
<div class="data-field" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issue.type }}</pre>
<input v-if="editable" v-model="issue.type" @change="updateIssueItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="info">
<div class="state-amount">
<div class="data-field" id="state">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">State:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issue.state }}</pre>
<input v-if="editable" v-model="issue.state" @change="updateIssueItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="amount">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Amount:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issue.amount }}</pre>
<input v-if="editable" v-model="issue.amount" @change="updateIssueItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
@ -25,28 +36,192 @@
<div class="additional">
<div class="properties">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Properties:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="properties">...</pre>
<input v-model="issue.properties" :readonly="!editable" @change="updateIssueItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="properties">
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<input v-model="newName" @change="updateII()"
:class="['data', 'issue-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="issue-data">
<div class="type">
<div class="data-field" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<input v-model="newType" @change="updateII()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="info">
<div class="state-amount">
<div class="data-field" id="state">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">State:</pre>
<input v-model="newState" @change="updateII()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="amount">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Amount:</pre>
<input v-model="newAmount" @change="updateII()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="issue-data">
<div class="additional">
<div class="properties">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Properties:</h3>
<input v-model="newProperties" @change="updateII()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="properties">
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const editable = computed(() => store.state.editable);
const chosenIssueId = computed(() => store.state.chosenIssueId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref(true)
const issue = ref({});
const issues = ref([]);
const newName = ref('');
const newType = ref('');
const newState = ref('');
const newAmount = ref('');
const newProperties = ref('');
//get all issue
const getIssues = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllIssues`);
issues.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
const confirmDeleteIssue = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this issue? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteIssueItem/${chosenIssueId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteIV/${chosenIssueId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToIssueItemList');
} else {
store.commit('undoDelete');
}
}
}
//update data
const updateIssueItem = async () => {
if (issue.value.name.trim() === "") {
alert("Please add an issue name!");
return;
} else {
var counter = 0;
// check if the issue name already exists
issues.value.forEach(i => {
if (i.name === issue.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This issue name already exists. Please choose an unique issue name or modify respectively delete the old one!");
issue.value.name = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateIssueItem`,
{
primaryID: issue.value.primaryID,
name: issue.value.name,
type: issue.value.type,
state: issue.value.state,
amount: issue.value.amount,
properties: issue.value.properties,
}
)
await getIssueById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
// get issue from id
const getIssueById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getIssueItem/${chosenIssueId.value}`
);
issue.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update issue fields in the store
const updateII = () => {
const ii = {
name: newName.value,
type: newType.value,
state: newState.value,
amount: newAmount.value,
properties: newProperties.value,
};
store.commit('updateIssueComponent', ii);
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
watch(deleteBool, confirmDeleteIssue);
onMounted(() => {
getIssueById();
triggerBackendCallsWithDelay(getIssues);
});
</script>
<script>
export default {
name: "Issue",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -67,7 +242,27 @@ export default {
background-color: #fff;
}
.issue-name-input {
padding: 1rem 0;
margin: 1rem;
font-size: initial;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.input {
border: none;
}
.issue-name {
align-self: stretch;
@ -92,7 +287,7 @@ export default {
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}

View File

@ -1,22 +1,33 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['issueSlip-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">ID issue slips</h2>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['issueSlip-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{ issueSlip.primaryID }}</h2>
<div class="issueSlip-data">
<div class="client">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<div class="customer">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issueSlip.customer }}</pre>
<select v-if="editable" id="customersDropDownChosenCI" v-model="issueSlip.customer"
@change="updateCustomerID()" :class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
{{ cust.customername }}
</option>
</select>
</div>
</div>
<div class="info">
<div class="ticketNo-user">
<div class="data-field" id="ticketNo">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Ticket No.:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issueSlip.ticketNo }}</pre>
</div>
<div class="data-field" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issueSlip.user }}</pre>
<input v-if="editable" v-model="issueSlip.user" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
@ -25,28 +36,266 @@
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">...</pre>
<input v-model="issueSlip.notes" :readonly="!editable" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</div>
<div class="additional">
<div class="deliveryAddress">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Different delivery address:
</h3>
<input v-model="issueSlip.deliveryAddress" :readonly="!editable" @change="updateIssueSlip()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="deliveryAddress">
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['issueSlip-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Issue slip ID</h2>
<div class="issueSlip-data">
<div class="client">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<select id="customersDropDownChosenCI" v-model="newCustomer" @change="updateNewCustomerID()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
{{ cust.customername }}
</option>
</select>
</div>
</div>
<div class="info">
<div class="ticketNo-user">
<div class="data-field" id="ticketNo">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Ticket No.:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"></pre>
<!-- <select id="ticketNoDropDownChosenCI" v-model="newTicketNo" @change="updateIS()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="po in productionOrders" :key="po.ticketNumber">
{{ po.ticketNumber }}
</option>
</select> -->
</div>
<div class="data-field" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<input v-model="newUser" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="issueSlip-data">
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<input v-model="newNotes" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</div>
<div class="additional">
<div class="deliveryAddress">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Different delivery address:
</h3>
<input v-model="newDeliveryAddress" @change="updateIS()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="deliveryAddress">
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const editable = computed(() => store.state.editable);
const chosenIssueSlipId = computed(() => store.state.chosenIssueSlipId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref(true)
const issueSlip = ref({});
const customer = ref({});
const productionOrders = ref([]);
const customers = ref([]);
const newTicketNo = ref('');
const newCustomerID = ref('');
const newCustomer = ref('');
const newUser = ref('');
const newNotes = ref('');
const newDeliveryAddress = ref('');
// get issue slip from id
const getIssueSlipById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getIssueSlip/${chosenIssueSlipId.value}`
);
issueSlip.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update issue slip fields in the store
const updateIS = () => {
const is = {
customerId: newCustomerID.value,
customer: newCustomer.value,
// ticketNo: newTicketNo.value,
ticketNo: 1,
notes: newNotes.value,
user: newUser.value,
deliveryAddress: newDeliveryAddress.value,
};
store.commit('updateIssueSlipComponent', is);
}
//update data
const updateIssueSlip = async () => {
// delete later
issueSlip.value.ticketNo = 1;
if (issueSlip.value.ticketNo.length === 0) {
alert("Please add a ticket Number!");
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateIssueSlip`,
{
primaryID: issueSlip.value.primaryID,
customerID: issueSlip.value.customerID,
customer: issueSlip.value.customer,
ticketNo: issueSlip.value.ticketNo,
creationDate: issueSlip.value.creationDate,
lastView: issueSlip.value.lastView,
user: issueSlip.value.user,
notes: issueSlip.value.notes,
deliveryAddress: issueSlip.value.deliveryAddress,
supplierRequestDate: issueSlip.value.supplierRequestDate,
supplierRequest: issueSlip.value.supplierRequest,
supplierOfferDate: issueSlip.value.supplierOfferDate,
supplierOffer: issueSlip.value.supplierOffer,
clientOfferDate: issueSlip.value.clientOfferDate,
clientOffer: issueSlip.value.clientOffer,
clientOrderDate: issueSlip.value.clientOrderDate,
clientOrder: issueSlip.value.clientOrder,
supplierOrder: issueSlip.value.supplierOrder,
supplierOrderDate: issueSlip.value.supplierOrderDate,
ingressDate: issueSlip.value.ingressDate,
ingress: issueSlip.value.ingress,
egressDate: issueSlip.value.egressDate,
egress: issueSlip.value.egress,
ingressBillDate: issueSlip.value.ingressBillDate,
ingressBill: issueSlip.value.ingressBill,
egressBillDate: issueSlip.value.egressBillDate,
egressBill: issueSlip.value.egressBill,
}
)
await getIssueSlipById();
} catch (err) {
console.log(err.response.statusText);
}
}
//get all customers
const getCustomers = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllCustomers`
);
customers.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//get all production orders
const getProductionOrders = async () => {
// try {
// const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllCustomers`
// );
// customers.value = response.data;
// } catch (err) {
// console.log(err.response.statusText);
// }
}
const confirmDeleteIssueSlip = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this issue slip? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteIssueSlip/${chosenIssueSlipId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteTodosOI/${chosenIssueSlipId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToIssueSliplist');
} else {
store.commit('undoDelete');
}
}
}
// update customerid if customer was changed
const updateCustomerID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${issueSlip.value.customer}`);
customer.value = response.data;
issueSlip.value.customerID = customer.value.customerID;
} catch (err) {
console.log(err.response.statusText);
}
await updateIssueSlip();
}
// update customerid if customer was changed
const updateNewCustomerID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${newCustomer.value}`);
newCustomerID.value = response.data.customerID;
} catch (err) {
console.log(err.response.statusText);
}
updateIS();
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
watch(deleteBool, confirmDeleteIssueSlip);
onMounted(() => {
getIssueSlipById();
getProductionOrders();
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "IssueSlip",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -92,7 +341,7 @@ export default {
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
@ -129,6 +378,10 @@ export default {
font: 400 0.75rem/250% Overpass, sans-serif;
}
.input {
border: none;
}
.data-darkmode {
background-color: #212121;
color: #fff;
@ -147,7 +400,7 @@ export default {
align-self: stretch;
}
.client,
.customer,
.info {
display: flex;
flex-direction: column;
@ -165,7 +418,7 @@ export default {
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 100%;
width: 50%;
padding: 0rem 0.625rem;
border-radius: 0.3125rem;
}
@ -193,10 +446,12 @@ export default {
gap: 0.625rem;
}
.data#notes {
.data#notes,
.data#deliveryAddress {
align-self: stretch;
}
.deliveryAddress,
.notes {
display: flex;
flex-direction: column;
@ -206,4 +461,20 @@ export default {
padding: 0.625rem 1.875rem 0.625rem 1.25rem;
padding-top: 0rem;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
</style>

View File

@ -1,12 +1,17 @@
<template>
<section v-if="searchable" :class="['issue-slip-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['clientLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Ticket No</div>
<input v-model="issueSlipSearchFilter" @change="searchIssueSlip()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Last viewed:</div>
<table class="data-table" id="asset-table">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Client', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
Client</th>
:class="['Customer', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
Customer</th>
<th
:class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
ID
@ -22,11 +27,16 @@
<tr v-for="issueSlip in issueSlips" :key="issueSlip.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
:class="['Customer', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
{{ issueSlip.customer }}</td>
<td
:class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
{{ issueSlip.primaryID }}</td>
<nuxt-link to="/issueSlips" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
@click="goToChosenIssueSlip(issueSlip.primaryID)">
{{ issueSlip.primaryID }}
</nuxt-link>
</td>
<td
:class="['TicketNo', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
{{ issueSlip.ticketNo }}</td>
@ -39,28 +49,79 @@
</table>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
// get accesss to the store
const store = useStore()
const goToChosenIssueSlip = (id) => {
store.commit('setChosenIssueSlip', id);
store.commit('changeToIssueSlip');
};
const customerFilter = computed(() => store.state.filteredByCustomer);
const searchable = computed(() => store.state.searchable);
const issueSlipSearchFilter = ref('');
const darkMode = ref(true)
const issueSlips = ref([]);
// update search term
const updateSearchTerm = async () => {
issueSlipSearchFilter.value = '';
await getIssueSlips();
}
//get all issueSlips
const getIssueSlips = async () => {
if (!(customerFilter.value === '')) {
await getFilteredIssueSlipsByClient();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllIssueSlips`);
issueSlips.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all issue slips based on the searched client
const getFilteredIssueSlipsByClient = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllIssueSlips`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedIssueSlipsByClient/${customerFilter.value}`);
issueSlips.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
onMounted(() => {
getIssueSlips();
//get all issue slips based on the searched issue slip id
const searchIssueSlip = async () => {
if (issueSlipSearchFilter.value === '') {
await getIssueSlips();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedIssueSlipsByTicketNo/${issueSlipSearchFilter.value}`);
issueSlips.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
watch(customerFilter, getIssueSlips);
watch(searchable, updateSearchTerm);
onMounted(async () => {
await getIssueSlips();
});
</script>
@ -69,7 +130,7 @@ export default {
name: "IssueSlipTable",
};
</script>
<style scoped>
.data {
display: flex;
@ -77,7 +138,6 @@ export default {
align-items: flex-start;
justify-content: center;
align-self: stretch;
width: 100%;
padding: 1.25rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
@ -92,6 +152,46 @@ export default {
background-color: #fff;
}
#nuxt-link {
text-decoration: none;
color: white;
}
.issue-slip-search {
display: flex;
align-items: center;
padding: 0.625em 1.875em;
gap: 1.25em;
width: 30.125em;
height: 3.125em;
box-shadow: 0.25em 0.25em 0.25em rgba(0, 0, 0, 0.25);
border-radius: 0.625em;
box-sizing: border-box;
}
.dataInput {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.input {
border: none;
}
.data-table {
width: 100%;
padding: 0 0.625rem;
@ -118,6 +218,27 @@ export default {
border-bottom: 0.0625rem solid #8e8e8e;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.clientLabel {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";
font-style: normal;
font-weight: 400;
font-size: 0.875em;
line-height: 1.875;
letter-spacing: 0.05em;
}
.tr-darkmode {
border-top: 0.0625rem solid #000000;
}
@ -149,15 +270,15 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Client {
.Customer {
width: 31.6%;
}
.Client-darkmode {
.Customer-darkmode {
border-right: 0.0625rem solid #000000;
}
.Client-lightmode {
.Customer-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
@ -218,4 +339,5 @@ th {
.label-lightmode {
color: #000;
}</style>
}
</style>

View File

@ -1,4 +1,4 @@
<template>
<!-- <template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Issue slip:</div>
<table class="data-table" id="asset-table">
@ -42,7 +42,7 @@ const darkMode = ref(true)
<script>
export default {
name: "IssueSlipTableNoClient",
name: "IssueSlipTableNoCustomer",
};
</script>
@ -184,4 +184,4 @@ th {
.label-lightmode {
color: #000;
}</style>
}</style> -->

View File

@ -1,4 +1,9 @@
<template>
<section v-if="searchable" :class="['issue-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['clientLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Issue name</div>
<input v-model="issueSearchFilter" @change="searchIssue()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Issues:</div>
<table class="data-table" id="asset-table">
@ -19,7 +24,12 @@
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
{{ issue.name }}</td>
<nuxt-link to="/issueItems" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
@click="goToChosenIssue(issue.primaryID)">
{{ issue.name }}
</nuxt-link>
</td>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
{{ issue.type }}</td>
@ -32,28 +42,79 @@
</table>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
// get accesss to the store
const store = useStore()
const goToChosenIssue = (id) => {
store.commit('setChosenIssue', id);
store.commit('changeToIssueItem');
};
const stateFilter = computed(() => store.state.filteredByCustomer);
const searchable = computed(() => store.state.searchable);
const issueSearchFilter = ref('');
const darkMode = ref(true)
const issues = ref([]);
// update search term
const updateSearchTerm = async () => {
issueSearchFilter.value = '';
await getIssues();
}
//get all issue
const getIssues = async () => {
if (!(stateFilter.value === '')) {
await getFilteredIssuesByState();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllIssues`);
issues.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all issues based on the searched state
const getFilteredIssuesByState = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllIssues`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedIssuesByState/${stateFilter.value}`);
issues.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
onMounted(() => {
getIssues();
//get all issues based on the searched issue name
const searchIssue = async () => {
if (issueSearchFilter.value === '') {
await getIssues();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedIssuesByIssueName/${issueSearchFilter.value}`);
issues.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
watch(stateFilter, getIssues);
watch(searchable, updateSearchTerm);
onMounted(async () => {
await getIssues();
});
</script>
@ -61,10 +122,10 @@ onMounted(() => {
export default {
name: "IssueTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -87,6 +148,27 @@ export default {
background-color: #fff;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.clientLabel {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";
font-style: normal;
font-weight: 400;
font-size: 0.875em;
line-height: 1.875;
letter-spacing: 0.05em;
}
.data-table {
width: 100%;
padding: 0 0.625rem;
@ -94,6 +176,46 @@ export default {
border-collapse: collapse;
}
#nuxt-link {
text-decoration: none;
color: white;
}
.issue-search {
display: flex;
align-items: center;
padding: 0.625em 1.875em;
gap: 1.25em;
width: 30.125em;
height: 3.125em;
box-shadow: 0.25em 0.25em 0.25em rgba(0, 0, 0, 0.25);
border-radius: 0.625em;
box-sizing: border-box;
}
.dataInput {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.input {
border: none;
}
.table-row {
display: flex;
flex-direction: row;

View File

@ -1,26 +1,40 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['issue-variant-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Name</h2>
<h2 v-if="!editable" :class="['issue-variant-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
issueVariant.name }}</h2>
<input v-if="editable" v-model="issueVariant.name" @change="updateIssueVariant()"
:class="['data', 'issue-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="issue-variant-data">
<div class="variantOf">
<div class="data-field" id="variantOf">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Variant of:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"><nuxt-link to="/issueItems" id="nuxt-link" class="button" @click="goToChosenIssue(issue.primaryID)">{{ nameOfVariant }}</nuxt-link></pre>
</div>
</div>
<div class="info">
<div class="state-amount-price">
<div class="data-field" id="state">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">State:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issueVariant.state }}</pre>
<input v-if="editable" v-model="issueVariant.state" @change="updateIssueVariant()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="amount">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Amount:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issueVariant.amount }}</pre>
<input v-if="editable" v-model="issueVariant.amount" @change="updateIssueVariant()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="price">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Price:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issueVariant.price }}</pre>
<input v-if="editable" v-model="issueVariant.price" @change="updateIssueVariant()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
@ -29,28 +43,153 @@
<div class="additional">
<div class="properties">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Properties:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="properties">...</pre>
<input v-model="issueVariant.properties" :readonly="!editable" @change="updateIssueVariant()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="properties">
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const editable = computed(() => store.state.editable);
const chosenIssueId = computed(() => store.state.chosenIssueId);
const chosenIssueVariantId = computed(() => store.state.chosenIssueVariantId);
const deleteBool = computed(() => store.state.deleteBool);
const darkMode = ref(true)
const issue = ref({});
const issueVariant = ref({});
const issueVariants = ref([]);
const nameOfVariant = ref('');
//get all issue variants
const getIssueVariants = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllIssueVariants`);
issueVariants.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
const goToChosenIssue = (id) => {
store.commit('setChosenIssue', id);
store.commit('changeToIssueItem');
};
const confirmDeleteIssueVariant = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this issue variant? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteIssueVariant/${chosenIssueVariantId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToIssueItemList');
} else {
store.commit('undoDelete');
}
}
}
//update data
const updateIssueVariant = async () => {
if (issueVariant.value.name.trim() === "") {
alert("Please add an issue variant name!");
return;
} else {
var counter = 0;
// check if the issue variant name already exists
issueVariants.value.forEach(i => {
if (i.name === issueVariant.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This issue variant name already exists. Please choose an unique issue variant name or modify respectively delete the old one!");
issueVariant.value.name = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateIssueVariant`,
{
primaryID: issueVariant.value.primaryID,
issueID: issueVariant.value.issueID,
name: issueVariant.value.name,
state: issueVariant.value.state,
amount: issueVariant.value.amount,
properties: issueVariant.value.properties,
price: issueVariant.value.price,
}
)
await getIssueVariantById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
// get issue variant from id
const getIssueVariantById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getIssueVariant/${chosenIssueVariantId.value}`
);
issueVariant.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// get issue from id
const getIssueById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getIssueItem/${chosenIssueId.value}`
);
issue.value = response.data;
nameOfVariant.value = issue.value.name;
} catch (err) {
console.log(err.response.statusText);
}
}
watch(deleteBool, confirmDeleteIssueVariant);
onMounted(() => {
getIssueVariantById();
getIssueById();
triggerBackendCallsWithDelay(getIssueVariants);
});
</script>
<script>
export default {
name: "IssueVariant",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -71,8 +210,6 @@ export default {
background-color: #fff;
}
.issue-variant-name {
align-self: stretch;
padding: 1rem 0;
@ -96,7 +233,7 @@ export default {
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
@ -151,18 +288,46 @@ export default {
align-self: stretch;
}
.variantOf,
.variantOf {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 30%;
padding: 0 0;
border-radius: 0.3125rem;
}
.info {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 50%;
width: 70%;
padding: 0 0;
border-radius: 0.3125rem;
}
.issue-name-input {
margin: 1rem;
letter-spacing: 5%;
text-decoration-line: underline;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.input {
border: none;
}
.additional {
display: flex;
flex-direction: column;
@ -210,4 +375,9 @@ export default {
padding: 0.625rem 1.875rem 0.625rem 1.25rem;
padding-top: 0rem;
}
#nuxt-link {
text-decoration: none;
color: white;
}
</style>

View File

@ -1,5 +1,6 @@
<template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<section v-if="!addBool"
:class="['issue-variant-list-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Variants:</div>
<table class="data-table" id="issue-variants-table">
<tbody>
@ -18,59 +19,452 @@
Amount</th>
<th :class="['Price', darkMode ? 'th-darkmode' : 'th-lightmode']">Price</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<tr v-for="issueVar in issueVariants" :key="issueVar.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td v-if="!editable"
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/issueItems" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
@click="goToChosenIssueVariant(issueVar.primaryID)">
{{ issueVar.name }}
</nuxt-link>
</td>
<td v-if="editable"
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<input type="text" v-model="issueVar.name" @change="updateIssueVariant(issueVar)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable"
:class="['Properties', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Properties-darkmode' : 'Properties-lightmode']">
{{ issueVar.properties }}</td>
<td v-if="editable"
:class="['Properties', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Properties-darkmode' : 'Properties-lightmode']">
<input type="text" v-model="issueVar.properties" @change="updateIssueVariant(issueVar)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable"
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
{{ issueVar.state }}</td>
<td v-if="editable"
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
<input type="text" v-model="issueVar.state" @change="updateIssueVariant(issueVar)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable"
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
{{ issueVar.amount }}</td>
<td v-if="editable"
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
<input type="text" v-model="issueVar.amount" @change="updateIssueVariant(issueVar)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode']">{{ issueVar.price
}}</td>
<td v-if="editable" :class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="text"
v-model="issueVar.price" @change="updateIssueVariant(issueVar)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"><button
:class="[darkMode ? 'deleteIssueVariant-darkmode' : 'deleteIssueVariant-lightmode']"
@click="deleteIssueVariant(issueVar.primaryID)">-</button>
</td>
</tr>
<tr v-if="editable && addRow" :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']"
id="row-1">
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
...</td>
<input type="text" v-model="newNameIV"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Properties', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Properties-darkmode' : 'Properties-lightmode']">
...</td>
<input type="text" v-model="newPropertiesIV"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
...</td>
<input type="text" v-model="newStateIV"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
...</td>
<td :class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newAmountIV"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="text"
v-model="newPriceIV"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'saveIssueVariant-darkmode' : 'saveIssueVariant-lightmode']"
@click="addIssueVariant()">Save</button> <button
:class="[darkMode ? 'deleteLastIssueVariant-darkmode' : 'deleteLastIssueVariant-lightmode']"
@click="deleteNewRow()">-</button>
</td>
</tr>
</tbody>
</table>
</div>
</section>
<section v-if="editable && !addBool" id="editIssueVariant">
<button :class="[darkMode ? 'editIssueVariant-darkmode' : 'editIssueVariant-lightmode']"
@click="addChecklistRow()">+</button>
</section>
<section v-if="addBool"
:class="['issue-variant-list-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Variants:</div>
<table class="data-table" id="issue-variants-table">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
<th
:class="['Properties', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Properties-darkmode' : 'Properties-lightmode']">
Properties</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th
:class="['Amount', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
Amount</th>
<th :class="['Price', darkMode ? 'th-darkmode' : 'th-lightmode']">Price</th>
</tr>
<tr v-for="(newIV, index) in newVariants" :key="index"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<input type="text" v-model="newIV.name"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Properties', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Properties-darkmode' : 'Properties-lightmode']">
<input type="text" v-model="newIV.properties"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
<input type="text" v-model="newIV.state"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
<input type="text" v-model="newIV.amount"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="text"
v-model="newIV.price"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'deleteLastIssueVariant-darkmode' : 'deleteLastIssueVariant-lightmode']"
@click="deleteIssueVariantFromNewTodos(index)">-</button>
</td>
</tr>
</tbody>
</table>
</section>
<section v-if="addBool" id="editIssueVariant">
<button :class="[darkMode ? 'editIssueVariant-darkmode' : 'editIssueVariant-lightmode']"
@click="addRowForNewIVs()">+</button>
</section>
<section v-if="addBool" id="saveNewIssueVariant">
<button :class="[darkMode ? 'saveNewIssueVariant-darkmode' : 'saveNewIssueVariant-lightmode']"
@click="addIV()">Save</button>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const addBool = computed(() => store.state.new);
const editable = computed(() => store.state.editable);
const newName = computed(() => store.state.newNameII);
const newType = computed(() => store.state.newTypeII);
const newState = computed(() => store.state.newStateII);
const newAmount = computed(() => store.state.newAmountII);
const newProperties = computed(() => store.state.newPropertiesII);
const chosenIssueId = computed(() => store.state.chosenIssueId);
const darkMode = ref(true)
const addRow = ref(false);
const issueVariants = ref([])
const issue = ref({})
const issues = ref([])
const newNameIV = ref('');
const newAmountIV = ref('');
const newStateIV = ref('');
const newPropertiesIV = ref('');
const newPriceIV = ref('');
const newVariants = reactive([]);
// delete new todo row
const deleteNewRow = () => {
newNameIV.value = '';
newAmountIV.value = '';
newPropertiesIV.value = '';
newStateIV.value = '';
newPriceIV.value = '';
addRow.value = false;
}
const goToChosenIssueVariant = (id) => {
store.commit('setChosenIssueVariant', id);
store.commit('changeToIssueItemVariant');
};
const deleteIssueVariantFromNewTodos = (index) => {
newVariants.splice(index, 1);
}
// add issue variant
const addIV = async () => {
// check if all input data is valid
if (newName.value.trim() === "") {
alert("Please add an issue name!");
return;
} else {
var counter = 0;
if (!(issues.value.length == null)) {
// check if issue name already exists
issues.value.forEach(i => {
if (i.name === newName.value) {
counter += 1;
}
});
if (counter >= 1) {
alert("This issue name already exists. Please choose an unique issue name or modify respectively delete the old one!");
return;
}
}
}
let allFine = true;
newVariants.forEach(variant => {
if (variant.name.length === 0) {
alert(`Please choose a name for all variants.`);
allFine = false
}
})
if (!allFine) {
return
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addII`,
{
name: newName.value,
type: newType.value,
state: newState.value,
amount: newAmount.value,
properties: newProperties.value,
});
store.commit('resetStore');
store.commit('changeToIssueItemList');
newVariants.forEach(async variant => {
try {
const res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addIssueVariant`,
{
issueID: response.data,
name: variant.name,
properties: variant.properties,
state: variant.state,
amount: variant.amount,
price: variant.price,
});
} catch (err) {
console.log(err.response.statusText);
}
})
} catch (err) {
console.log(err.response.statusText);
}
}
// add new row of variant for the new issue
const addRowForNewIVs = async () => {
newVariants.push({
issueID: chosenIssueId.value,
name: '',
properties: '',
state: '',
amount: '',
price: ''
});
}
//update data
const updateIssueVariant = async (todo) => {
if (todo.name.length === 0) {
alert(`Please add the missing variant name!`);
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateIssueVariant`,
{
primaryID: todo.primaryID,
issueID: todo.issueID,
name: todo.name,
properties: todo.properties,
asset: todo.asset,
state: todo.state,
amount: todo.amount,
price: todo.price,
}
);
await getIssueById();
} catch (err) {
console.log(err.response.statusText);
}
}
// add new issue variant
const addIssueVariant = async () => {
// check if all input data is valid
if (newNameIV.value.length === 0) {
alert("Please choose a name for the new issue variant!");
return;
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addIssueVariant`,
{
issueID: chosenIssueId.value,
name: newNameIV.value,
properties: newPropertiesIV.value,
state: newStateIV.value,
amount: newAmountIV.value,
price: newPriceIV.value,
});
addRow.value = false;
await getIssueVariantsById();
newNameIV.value = '';
newPropertiesIV.value = '';
newStateIV.value = '';
newAmountIV.value = '';
newPriceIV.value = '';
} catch (err) {
console.log(err.response.statusText);
}
}
// add new row for the issue variant
const addChecklistRow = async () => {
if (addRow.value) {
alert('Please confirm the last added row first.')
return
}
addRow.value = true
}
// get issue variants from id
const getIssueVariantsById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getIVs/${chosenIssueId.value}`
);
issueVariants.value = response.data;
} catch (err) {
// console.log(err.response.statusText);
console.log(err.response);
}
}
}
// get issue from id
const getIssueById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getIssueItem/${chosenIssueId.value}`
);
issue.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
const deleteIssueVariant = async (id) => {
if (confirm("Do you really want to delete this issue variant? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteIssueVariant/${id}`);
} catch (err) {
console.log(err.response.statusText);
}
}
await getIssueVariantsById();
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1000);
}
//get all issue
const getAllIssues = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllIssues`);
issues.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
onMounted(() => {
getIssueVariantsById();
getIssueById();
triggerBackendCallsWithDelay(getAllIssues);
});
</script>
<script>
export default {
name: "IssueVariants",
};
</script>
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
flex-direction: row;
align-items: flex-start;
justify-content: center;
align-self: stretch;
width: 100%;
padding: 1.25rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.div-darkmode {
.saveIssueVariant-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 3.25rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.saveIssueVariant-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 3.25rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.section-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
.section-lightmode {
background-color: #fff;
}
@ -90,6 +484,64 @@ export default {
gap: 0.625rem;
}
.deleteLastIssueVariant-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 1rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteLastIssueVariant-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 1rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.editIssueVariant-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 0.825rem 0.7rem;
width: 4%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.editIssueVariant-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
margin-left: 15rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
border-radius: 0.625rem;
}
.input {
border: none;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.tr-head-darkmode {
border-top: none;
border-bottom: 0.0625rem solid #000000;
@ -108,6 +560,38 @@ export default {
border-top: 0.0625rem solid #8e8e8e;
}
.deleteIssueVariant-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteIssueVariant-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.issue-variant-list-information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 1.25rem 1.875rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
th,
td {
height: 1.875rem;
@ -131,8 +615,58 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.deleteIssueVariant-darkmode:hover,
.deleteLastIssueVariant-darkmode:hover,
.saveIssueVariant-darkmode:hover,
.editIssueVariant-darkmode:hover,
.saveNewIssueVariant-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.deleteIssueVariant-lightmode:hover,
.deleteLastIssueVariant-lightmode:hover,
.saveIssueVariant-lightmode:hover,
.editIssueVariant-lightmode:hover,
.saveNewIssueVariant-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
.saveNewIssueVariant-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.saveNewIssueVariant-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
#saveNewIssueVariant {
text-align: center;
}
#editIssueVariant {
text-align: right;
}
.Properties {
width: 30%;
width: 25%;
}
.Properties-darkmode {
@ -144,7 +678,7 @@ th {
}
.Name {
width: 30%;
width: 20%;
}
.Name-darkmode {
@ -180,7 +714,8 @@ th {
}
.Price {
width: 10%;
width: 25%;
display: flex;
}
.label {
@ -201,4 +736,9 @@ th {
.label-lightmode {
color: #000;
}
#nuxt-link {
text-decoration: none;
color: white;
}
</style>

View File

@ -4,15 +4,15 @@
<div class="maintenance-visits-instance-data">
<div class="instanceInfo">
<div class="data-field" id="info">
<div class="templateId-client-type" id="templateID">
<div class="templateId-customer-type" id="templateID">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Template ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="templateId-client-type" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<div class="templateId-customer-type" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="templateId-client-type" id="type">
<div class="templateId-customer-type" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
@ -129,14 +129,14 @@ export default {
align-items: center;
justify-content: flex-start;
width: 95%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
.maintenanceType-state-user,
.creationDate-completionDate-timeSpent,
.templateId-client-type {
.templateId-customer-type {
display: flex;
flex-direction: row;
align-items: center;

View File

@ -1,24 +1,41 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['maintenance-visits-template-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Template name</h2>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['maintenance-visits-template-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
mvt.name }}</h2>
<input v-if="editable" v-model="mvt.name" @change="updateMVT()"
:class="['data', 'mvt-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="maintenance-visits-template-data">
<div class="client-ID-type-user">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<div class="customer-ID-type-user">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvt.customer }}</pre>
<select v-if="editable" id="customersDropDownChosenCI" v-model="mvt.customer"
@change="updateCustomerID()" :class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
{{ cust.customername }}
</option>
</select>
</div>
<div class="data-field" id="info">
<div class="id-type-user" id="ID">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvt.checklistID }}</pre>
</div>
<div class="id-type-user" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvt.type }}</pre>
<input v-if="editable" v-model="mvt.type" @change="updateMVT()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="id-type-user" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvt.user }}</pre>
<input v-if="editable" v-model="mvt.user" @change="updateMVT()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
@ -27,28 +44,245 @@
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">...</pre>
<input v-model="mvt.notes" :readonly="!editable" @change="updateMVT()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<input v-model="newName" @change="updateMaintenanceVisit()"
:class="['data', 'maintenance-visits-template-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="maintenance-visits-template-data">
<div class="customer-ID-type-user">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<select id="customersDropDownChosenCI" v-model="newCustomer" @change="updateNewCustomerID()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
{{ cust.customername }}
</option>
</select>
</div>
<div class="data-field" id="info">
<div class="id-type-user" id="ID">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="id-type-user" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<input v-model="newType" @change="updateMaintenanceVisit()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="id-type-user" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<input v-model="newUser" @change="updateMaintenanceVisit()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="maintenance-visits-template-data">
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<input v-model="newNotes" @change="updateMaintenanceVisit()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const editable = computed(() => store.state.editable);
const chosenMVTId = computed(() => store.state.chosenMVTId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref(true)
const mvt = ref({});
const customers = ref([]);
const customer = ref({});
const maintenanceVisitTemplates = ref([]);
const newName = ref('');
const newCustomerID = ref('');
const newCustomer = ref('');
const newUser = ref('');
const newType = ref('');
const newNotes = ref('');
//get all customers
const getCustomers = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllCustomers`
);
customers.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// function to delete a maintenance visit template
const confirmDeleteMVT = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this maintenance visit template? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteMaintenanceVisitTemplate/${chosenMVTId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteTodosMVT/${chosenMVTId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToTemplatelist');
} else {
store.commit('undoDelete');
}
}
}
//get all maintenance visit templates
const getMaintenanceVisitTemplates = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllMaintenanceVisitTemplates`);
maintenanceVisitTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//update data
const updateMVT = async () => {
if (mvt.value.name.trim() === "") {
alert("Please add a maintenance visit template name!");
return;
} else {
var counter = 0;
// check if maintenance visit template name already exists
maintenanceVisitTemplates.value.forEach(m => {
if (m.name === mvt.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This maintenance visit template name already exists. Please choose an unique production order template name or modify respectively delete the old one!");
mvt.value.name = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateMaintenanceVisitTemplate`,
{
checklistID: mvt.value.checklistID,
name: mvt.value.name,
customerID: mvt.value.customerID,
customer: mvt.value.customer,
lastView: mvt.value.lastView,
user: mvt.value.user,
type: mvt.value.type,
notes: mvt.value.notes,
}
)
await getMVTById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update customerid if customer was changed
const updateCustomerID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${mvt.value.customer}`);
customer.value = response.data;
mvt.value.customerID = customer.value.customerID;
store.commit('toggleCustomerChanged');
store.commit('toggleCustomerId', mvt.value.customerID);
} catch (err) {
console.log(err.response.statusText);
}
await updateMVT();
}
// get maintenance visit template from id
const getMVTById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getMaintenanceVisitTemplate/${chosenMVTId.value}`
);
mvt.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update customerid if customer was changed
const updateNewCustomerID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${newCustomer.value}`);
newCustomerID.value = response.data.customerID;
store.commit('toggleCustomerChanged');
store.commit('toggleCustomerId', newCustomerID.value)
} catch (err) {
console.log(err.response.statusText);
}
updateMaintenanceVisit();
}
// update maintenance visit template fields in the store
const updateMaintenanceVisit = () => {
const maintenanceVisitTemplate = {
name: newName.value,
customerId: newCustomerID.value,
customer: newCustomer.value,
user: newUser.value,
type: newType.value,
notes: newNotes.value
};
store.commit('updateMaintenanceVisitTemplateComponent', maintenanceVisitTemplate);
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
watch(deleteBool, confirmDeleteMVT);
onMounted(() => {
getMVTById();
triggerBackendCallsWithDelay(getMaintenanceVisitTemplates);
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "MaintenanceVisitsTemplate",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -61,6 +295,17 @@ export default {
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.data {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.section-darkmode {
background-color: #2c2c2c;
}
@ -69,7 +314,21 @@ export default {
background-color: #fff;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.maintenance-visits-template-name {
align-self: stretch;
@ -80,6 +339,16 @@ export default {
sans-serif;
}
.maintenance-visits-template-name-input {
padding: 0 0.625rem;
margin: 1rem;
font-size: initial;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.h2-darkmode {
color: #fff;
}
@ -94,11 +363,23 @@ export default {
align-items: center;
justify-content: flex-start;
width: 95%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.input {
border: none;
}
.id-type-user {
display: flex;
flex-direction: row;
@ -123,17 +404,6 @@ export default {
color: #000;
}
.data {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.data-darkmode {
background-color: #212121;
color: #fff;
@ -144,6 +414,16 @@ export default {
color: #000;
}
.mvt-name-input {
padding: 0 0.625rem;
margin: 1rem;
font-size: initial;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.maintenance-visits-template-data {
display: flex;
flex-direction: row;
@ -152,7 +432,7 @@ export default {
align-self: stretch;
}
.client-ID-type-user,
.customer-ID-type-user,
.info {
display: flex;
flex-direction: column;

View File

@ -1,12 +1,17 @@
<template>
<section v-if="searchable" :class="['mvt-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['customerLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Template:</div>
<input v-model="mvtSearchFilter" @change="searchMVT()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Last viewed:</div>
<table class="data-table" name="maintenance-visits-template-table">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Client', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
Client</th>
:class="['Customer', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
Customer</th>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
@ -22,11 +27,15 @@
<tr v-for="template in maintenanceVisitTemplates" :key="template.checklistID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
:class="['Customer', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
{{ template.customer }}</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
{{ template.name }}</td>
<nuxt-link to="/maintenanceVisits" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
@click="goToChosenMVT(template.checklistID)">
{{ template.name }}
</nuxt-link></td>
<td
:class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
{{ template.checklistID }}</td>
@ -42,25 +51,75 @@
<script setup>
import { ref, onMounted } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
// get accesss to the store
const store = useStore()
const goToChosenMVT = (id) => {
store.commit('setChosenMVT', id);
store.commit('changeToTemplate');
};
const customerFilter = computed(() => store.state.filteredByCustomer);
const searchable = computed(() => store.state.searchable);
const mvtSearchFilter = ref('');
const darkMode = ref(true)
const maintenanceVisitTemplates = ref([]);
//get all maintenance visit templates
const getMaintenanceVisitTemplates = async () => {
if (!(customerFilter.value === '')) {
await getFilteredMVTByCustomer();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllMaintenanceVisitTemplates`);
maintenanceVisitTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all maintenance visit templates based on the searched mvt name
const searchMVT = async () => {
if (mvtSearchFilter.value === '') {
await getMaintenanceVisitTemplates();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedMVTsByMVT/${mvtSearchFilter.value}`);
maintenanceVisitTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update search term
const updateSearchTerm = async () => {
mvtSearchFilter.value = '';
await getMaintenanceVisitTemplates();
}
//get all maintenance visit templates based on the searched customer
const getFilteredMVTByCustomer = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllMaintenanceVisitTemplates`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedMVTsByCustomer/${customerFilter.value}`);
maintenanceVisitTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
onMounted(() => {
getMaintenanceVisitTemplates();
watch(searchable, updateSearchTerm);
watch(customerFilter, getMaintenanceVisitTemplates);
onMounted(async () => {
await getMaintenanceVisitTemplates();
});
</script>
@ -79,13 +138,30 @@ export default {
align-items: flex-start;
justify-content: center;
align-self: stretch;
width: 100%;
padding: 1.25rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.div-darkmode {
background-color: #2c2c2c;
}
@ -94,6 +170,37 @@ export default {
background-color: #fff;
}
.input {
border: none;
}
#nuxt-link {
text-decoration: none;
color: white;
}
.dataInput {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.customerLabel {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";
font-style: normal;
font-weight: 400;
font-size: 0.875em;
line-height: 1.875;
letter-spacing: 0.05em;
}
.data-table {
width: 100%;
padding: 0 0.625rem;
@ -101,6 +208,18 @@ export default {
border-collapse: collapse;
}
.mvt-search {
display: flex;
align-items: center;
padding: 0.625em 1.875em;
gap: 1.25em;
width: 30.125em;
height: 3.125em;
box-shadow: 0.25em 0.25em 0.25em rgba(0, 0, 0, 0.25);
border-radius: 0.625em;
box-sizing: border-box;
}
.table-row {
display: flex;
flex-direction: row;
@ -151,15 +270,15 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Client {
.Customer {
width: 33.3%;
}
.Client-darkmode {
.Customer-darkmode {
border-right: 0.0625rem solid #000000;
}
.Client-lightmode {
.Customer-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
@ -220,4 +339,5 @@ th {
.label-lightmode {
color: #000;
}</style>
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<!-- <template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Templates:</div>
<table class="data-table" id="maintenance-visits-templat-table-no-client">
<table class="data-table" id="maintenance-visits-templat-table-no-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
@ -42,7 +42,7 @@ const darkMode = ref(true)
<script>
export default {
name: "MaintenanceVisitsTemplateTableNoClient",
name: "MaintenanceVisitsTemplateTableNoCustomer",
};
</script>
@ -184,4 +184,4 @@ th {
.label-lightmode {
color: #000;
}</style>
}</style> -->

View File

@ -67,7 +67,7 @@
</div>
</section>
<section v-if="addBool" id="saveNewItem">
<button :class="[darkMode ? 'saveNewItem-darkmode' : 'saveNewItem-lightmode']" @click="addItem()">Safe</button>
<button :class="[darkMode ? 'saveNewItem-darkmode' : 'saveNewItem-lightmode']" @click="addItem()">Save</button>
</section>
</template>

View File

@ -1,5 +1,92 @@
<template>
<section :class="['ordering-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<section v-if="!addBool" :class="['ordering-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']" id="ordering">Ordering information:
<div class="asset-data">
<table class="data-table" id="asset-table-no-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Article', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Article-darkmode' : 'Article-lightmode']">
Article</th>
<th
:class="['Amount', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
Amount</th>
<th
:class="['Price', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Price-darkmode' : 'Price-lightmode']">
Price</th>
<th :class="['Comments', darkMode ? 'th-darkmode' : 'th-lightmode']">Comments</th>
</tr>
<tr v-for="info in orderingInfo" :key="info.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td v-if="!editable"
:class="['Article', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Article-darkmode' : 'Article-lightmode']">
{{ info.article }}</td>
<td v-if="editable"
:class="['Article', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Article-darkmode' : 'Article-lightmode']">
<input type="text" v-model="info.article" @change="updateOrderingInfo(info)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable"
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
{{ info.amount }}</td>
<td v-if="editable"
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
<input type="text" v-model="info.amount" @change="updateOrderingInfo(info)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable"
:class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Price-darkmode' : 'Price-lightmode']">
{{ info.price }}</td>
<td v-if="editable"
:class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Price-darkmode' : 'Price-lightmode']">
<input type="text" v-model="info.price" @change="updateOrderingInfo(info)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
info.comment }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="info.comment" @change="updateOrderingInfo(info)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'deleteOrderingInfo-darkmode' : 'deleteOrderingInfo-lightmode']"
@click="deleteOrderingInfo(info.primaryID)">-</button>
</td>
</tr>
<tr v-if="editable && addRow" :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']"
id="row-1">
<td
:class="['Article', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Article-darkmode' : 'Article-lightmode']">
<input type="text" v-model="newArticle"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
<input type="text" v-model="newAmount"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Price-darkmode' : 'Price-lightmode']">
<input type="text" v-model="newPrice"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="text"
v-model="newComment"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'saveOrderingInfo-darkmode' : 'saveOrderingInfo-lightmode']"
@click="addOrderingInfo()">Save</button> <button
:class="[darkMode ? 'deleteLastOrderingInfo-darkmode' : 'deleteLastOrderingInfo-lightmode']"
@click="deleteNewRow()">-</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section v-if="editable && !addBool" id="editOrderingInfo">
<button :class="[darkMode ? 'editOrderingInfo-darkmode' : 'editOrderingInfo-lightmode']"
@click="addChecklistRow()">+</button>
</section>
<section v-if="addBool" :class="['ordering-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']" id="ordering">Ordering information:
<div class="asset-data">
<table class="data-table" id="asset-table-no-client">
@ -16,30 +103,184 @@
Price</th>
<th :class="['Comments', darkMode ? 'th-darkmode' : 'th-lightmode']">Comments</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<tr v-for="(newOI, index) in newOIs" :key="index"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Article', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Article-darkmode' : 'Article-lightmode']">
...</td>
<input type="text" v-model="newOI.article" @change="updateOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-lightmode']">
...</td>
<input type="text" v-model="newOI.amount" @change="updateOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Price', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Price-darkmode' : 'Price-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newOI.price" @change="updateOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newOI.comment" @change="updateOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'deleteOrderingInfo-darkmode' : 'deleteOrderingInfo-lightmode']"
@click="deleteOIFromNewTodos(index)">-</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section v-if="addBool" id="editOrderingInfo">
<button :class="[darkMode ? 'editOrderingInfo-darkmode' : 'editOrderingInfo-lightmode']"
@click="addRowForNewOI()">+</button>
</section>
</template>
<script setup>
import { ref } from 'vue';
<script setup>
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const addBool = computed(() => store.state.new);
const editable = computed(() => store.state.editable);
const chosenIssueSlipId = computed(() => store.state.chosenIssueSlipId);
const addRow = ref(false);
const orderingInfo = ref([])
const newArticle = ref('');
const newAmount = ref('');
const newPrice = ref('');
const newComment = ref('');
const newOIs = reactive([]);
const darkMode = ref(true)
// delete new todo row
const deleteNewRow = () => {
newArticle.value = '';
newAmount.value = '';
newPrice.value = '';
newComment.value = '';
addRow.value = false;
}
const deleteOIFromNewTodos = (index) => {
newOIs.splice(index, 1);
}
// add new ordering info
const addOrderingInfo = async () => {
// check if all input data is valid
if (newAmount.value.length === 0 && newArticle.value.length === 0 && newPrice.value.length === 0 && newComment.value.length === 0) {
alert(`Please add some data in the ordering info row!`);
return;
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addOrderingInfo`,
{
issueSlipID: chosenIssueSlipId.value,
article: newArticle.value,
amount: newAmount.value,
price: newPrice.value,
comment: newComment.value,
});
addRow.value = false;
await getOIById();
newArticle.value = '';
newAmount.value = '';
newPrice.value = '';
newComment.value = '';
} catch (err) {
console.log(err.response.statusText);
}
}
// update ordering info fields in the store
const updateOI = () => {
const infos = {
ois: newOIs,
};
store.commit('updateOrderingInfoComponent', infos);
}
// add new row of ordering info
const addRowForNewOI = async () => {
newOIs.push({
issueSlipID: -1,
article: '',
amount: '',
price: '',
comment: ''
});
}
//update data
const updateOrderingInfo = async (info) => {
if (info.amount.length === 0 && info.article.length === 0 && info.price.length === 0 && info.comment.length === 0) {
alert(`Please add some data in the ordering info row!`);
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateOrderingInfo`,
{
primaryID: info.primaryID,
issueSlipID: info.issueSlipID,
article: info.article,
amount: info.amount,
price: info.price,
comment: info.comment,
}
);
await getOIById();
} catch (err) {
console.log(err.response.statusText);
}
}
// add new row for the ordering info
const addChecklistRow = async () => {
if (addRow.value) {
alert('Please confirm the last added row first.')
return
}
addRow.value = true
}
// get ordering info from id
const getOIById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getOrderingInfo/${chosenIssueSlipId.value}`
);
orderingInfo.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
const deleteOrderingInfo = async (id) => {
if (confirm("Do you really want to delete this ordering info? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteOrderingInfo/${id}`);
} catch (err) {
console.log(err.response.statusText);
}
}
await getOIById();
}
onMounted(() => {
getOIById();
});
</script>
<script>
@ -47,9 +288,9 @@ export default {
name: "OrderingInformation",
};
</script>
<style scoped>
.ordering-information {
display: flex;
@ -70,6 +311,31 @@ export default {
background-color: #fff;
}
.data {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.input {
border: none;
}
.label {
letter-spacing: 5%;
font: 400 1rem/1.875rem Overpass, sans-serif;
@ -194,5 +460,116 @@ th {
.Comments {
width: 50%;
display: flex;
}
.deleteOrderingInfo-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 24.8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteLastOrderingInfo-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 2rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.editOrderingInfo-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 0.825rem 0.7rem;
width: 4%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.editOrderingInfo-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
margin-left: 15rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
border-radius: 0.625rem;
}
.saveOrderingInfo-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 19rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.saveOrderingInfo-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 19rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteOrderingInfo-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 24.8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteLastOrderingInfo-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 2rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteOrderingInfo-darkmode:hover,
.deleteLastOrderingInfo-darkmode:hover,
.saveOrderingInfo-darkmode:hover,
.editOrderingInfo-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.deleteOrderingInfo-lightmode:hover,
.deleteLastOrderingInfo-lightmode:hover,
.saveOrderingInfo-lightmode:hover,
.editOrderingInfo-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#editOrderingInfo {
text-align: right;
}
</style>

View File

@ -4,12 +4,12 @@
<div class="production-orders-instance-data">
<div class="instanceInfo">
<div class="data-field" id="info">
<div class="templateId-client" id="templateID">
<div class="templateId-customer" id="templateID">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Template ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="templateId-client" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<div class="templateId-customer" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
</div>
@ -135,7 +135,7 @@ export default {
align-items: center;
justify-content: flex-start;
width: 95%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
@ -163,7 +163,7 @@ export default {
}
.creationDate-completionDate-timeSpent,
.templateId-client {
.templateId-customer {
display: flex;
flex-direction: row;
align-items: center;
@ -250,7 +250,7 @@ export default {
border-radius: 0.3125rem;
}
div#client {
div#customer {
padding-left: 2.9em;
}

View File

@ -1,13 +1,13 @@
<template>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['production-orders-template-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
pot.name }}</h2>
pot.name }}</h2>
<input v-if="editable" v-model="pot.name" @change="updatePOT()"
:class="['data', 'pot-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="production-orders-template-data">
<div class="client-ID">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Client:</pre>
<div class="customer-ID">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Customer:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ pot.customer }}</pre>
<select v-if="editable" id="customersDropDownChosenCI" v-model="pot.customer"
@ -56,9 +56,9 @@
<input v-model="newName" @change="updateProductionOrder()"
:class="['data', 'production-orders-template-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="production-orders-template-data">
<div class="client-ID">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<div class="customer-ID">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<select id="customersDropDownChosenCI" v-model="newCustomer" @change="updateNewCustomerID()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
@ -100,7 +100,7 @@
</div>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
@ -143,8 +143,6 @@ const confirmDeletePOT = async () => {
if (confirm("Do you really want to delete this production order template? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteProductionOrderTemplate/${chosenPOTId.value}`);
store.commit('undoDelete');
store.commit('changeToTemplatelist');
} catch (err) {
console.log(err.response.statusText);
}
@ -153,13 +151,16 @@ const confirmDeletePOT = async () => {
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToTemplatelist');
} else {
store.commit('undoDelete');
}
}
}
//get all productionOrder templates todos
//get all productionOrder templates
const getProductionOrderTemplates = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderTemplates`);
@ -214,8 +215,8 @@ const updateCustomerID = async () => {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${pot.value.customer}`);
customer.value = response.data;
pot.value.customerID = customer.value.customerID;
store.commit('toggleClientChanged');
store.commit('toggleClientId', pot.value.customerID);
store.commit('toggleCustomerChanged');
store.commit('toggleCustomerId', pot.value.customerID);
} catch (err) {
console.log(err.response.statusText);
}
@ -241,8 +242,8 @@ const updateNewCustomerID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${newCustomer.value}`);
newCustomerID.value = response.data.customerID;
store.commit('toggleClientChanged');
store.commit('toggleClientId', newCustomerID.value)
store.commit('toggleCustomerChanged');
store.commit('toggleCustomerId', newCustomerID.value)
} catch (err) {
console.log(err.response.statusText);
}
@ -282,9 +283,9 @@ onMounted(() => {
export default {
name: "ProductionOrdersTemplate",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -423,7 +424,23 @@ export default {
border-radius: 0.3125rem;
}
.client-ID,
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.customer-ID,
.user {
display: flex;
flex-direction: column;

View File

@ -1,6 +1,6 @@
<template>
<section v-if="searchable" :class="['pot-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['clientLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Config item</div>
<div :class="['customerLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Template:</div>
<input v-model="potSearchFilter" @change="searchPOT()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
@ -10,8 +10,8 @@
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Client', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
Client</th>
:class="['Customer', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
Customer</th>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
@ -24,7 +24,7 @@
<tr v-for="template in productionOrderTemplates" :key="template.templateID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
:class="['Customer', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
{{ template.customer }}</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
@ -59,7 +59,7 @@ const goToChosenPOT = (id) => {
store.commit('changeToTemplate');
};
const clientFilter = computed(() => store.state.filteredByClient);
const customerFilter = computed(() => store.state.filteredByCustomer);
const searchable = computed(() => store.state.searchable);
const potSearchFilter = ref('');
@ -68,8 +68,8 @@ const productionOrderTemplates = ref([]);
//get all productionOrder templates
const getProductionOrderTemplates = async () => {
if (!(clientFilter.value === '')) {
await getFilteredPOTByClient();
if (!(customerFilter.value === '')) {
await getFilteredPOTByCustomer();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderTemplates`);
@ -100,17 +100,17 @@ const updateSearchTerm = async () => {
await getProductionOrderTemplates();
}
//get all productionOrder templates based on the searched client
const getFilteredPOTByClient = async () => {
//get all productionOrder templates based on the searched customer
const getFilteredPOTByCustomer = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedPOTsByClient/${clientFilter.value}`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedPOTsByCustomer/${customerFilter.value}`);
productionOrderTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
watch(clientFilter, getProductionOrderTemplates);
watch(customerFilter, getProductionOrderTemplates);
watch(searchable, updateSearchTerm);
onMounted(async () => {
@ -255,15 +255,15 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Client {
.Customer {
width: 33.3%;
}
.Client-darkmode {
.Customer-darkmode {
border-right: 0.0625rem solid #000000;
}
.Client-lightmode {
.Customer-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
@ -314,7 +314,7 @@ th {
color: #000;
}
.clientLabel {
.customerLabel {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";

View File

@ -1,7 +1,7 @@
<template>
<!-- <template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Templates:</div>
<table class="data-table" id="production-orders-template-table-no-client">
<table class="data-table" id="production-orders-template-table-no-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
@ -36,7 +36,7 @@ const darkMode = ref(true)
<script>
export default {
name: "ProductionOrdersTemplateTableNoClient",
name: "ProductionOrdersTemplateTableNoCustomer",
};
</script>
@ -165,4 +165,4 @@ th {
.label-lightmode {
color: #000;
}</style>
}</style> -->

View File

@ -3,7 +3,7 @@
:class="['software-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']" id="software">Software specifications:
<div class="asset-data">
<table class="data-table" id="asset-table-no-client">
<table class="data-table" id="asset-table-no-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
@ -47,7 +47,7 @@
<section v-if="addBool" :class="['software-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']" id="software">Software specifications:
<div class="asset-data">
<table class="data-table" id="asset-table-no-client">
<table class="data-table" id="asset-table-no-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th

View File

@ -1,15 +1,96 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['solution-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Solution name</h2>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['solution-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{ sol.solutionName
}}</h2>
<input v-if="editable" v-model="sol.solutionName" @change="updateSolution()"
:class="['data', 'solution-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="solution-data">
<div class="client-asset">
<div class="data-field" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<div class="customer-asset">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ sol.customer }}</pre>
<select v-if="editable" id="customersDropDownChosenCI" v-model="sol.customer"
@change="updateCustomerID()" :class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
{{ cust.customername }}
</option>
</select>
</div>
<div class="data-field" id="asset">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Asset:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ sol.assetName }}</pre>
<select v-if="editable" id="customersDropDownChosenCI" v-model="sol.assetName"
@change="updateSolution()" :class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItems" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</div>
</div>
<div class="info">
<div class="data-field" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ sol.user }}</pre>
</div>
<div class="type-id">
<div class="data-field" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ sol.type }}</pre>
<input v-if="editable" v-model="sol.type" @change="updateSolution()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ sol.primaryID }}</pre>
</div>
</div>
</div>
</div>
<div class="solution-data">
<div class="additional">
<div class="description">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Description of the
problem/intended use:</h3>
<input v-model="sol.description" :readonly="!editable" @change="updateSolution()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">
</div>
</div>
</div>
<div class="solution-data">
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<input v-model="sol.notes" :readonly="!editable" @change="updateSolution()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<input v-model="newSolutionName" @change="updateSol()"
:class="['data', 'solution-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="solution-data">
<div class="customer-asset">
<div class="data-field" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<select id="customersDropDownChosenCI" v-model="newCustomer" @change="updateNewCustomerID()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="cust in customers" :key="cust.primaryID">
{{ cust.customername }}
</option>
</select>
</div>
<div class="data-field" id="asset">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Asset:</pre>
<select id="customersDropDownChosenCI" v-model="newAssetName" @change="updateSol()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItems" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</div>
</div>
<div class="info">
@ -17,13 +98,14 @@
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="type-state">
<div class="type-id">
<div class="data-field" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<input v-model="newType" @change="updateSol()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="state">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">State:</pre>
<div class="data-field" id="id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
</div>
@ -34,7 +116,8 @@
<div class="description">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Description of the
problem/intended use:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">...</pre>
<input v-model="newDescription" @change="updateSol()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">
</div>
</div>
</div>
@ -42,27 +125,236 @@
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">...</pre>
<input v-model="newNotes" @change="updateSol()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const editable = computed(() => store.state.editable);
const chosenSolutionId = computed(() => store.state.chosenSolutionId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref(true);
const sol = ref({});
const customer = ref({});
const solutions = ref([]);
const customers = ref([]);
const configItems = ref([]);
const newAssetName = ref('');
const newCustomerID = ref('');
const newCustomer = ref('');
const newSolutionName = ref('');
const newType = ref('');
const newDescription = ref('');
const newNotes = ref('');
const newLastView = ref('');
const newUser = ref('');
const changedCustomerId = computed(() => store.state.changedCustomerId);
const customerChanged = computed(() => store.state.customerChanged);
// get solution from id
const getSolutionById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSolution/${chosenSolutionId.value}`
);
sol.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
await getConfigItemsFromCustomer();
}
//get all config items from the selected customer
const getConfigItemsFromCustomer = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${sol.value.customerID}`);
configItems.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${changedCustomerId.value}`);
configItems.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
if (customerChanged.value) {
store.commit('toggleCustomerChanged');
}
}
// update solution fields in the store
const updateSol = () => {
const solution = {
solutionName: newSolutionName.value,
customerId: newCustomerID.value,
customer: newCustomer.value,
assetName: newAssetName.value,
lastView: newLastView.value,
type: newType.value,
description: newDescription.value,
notes: newNotes.value,
user: newUser.value
};
store.commit('updateSolutionComponent', solution);
}
//update data
const updateSolution = async () => {
if (sol.value.solutionName.trim() === "") {
alert("Please add a solution name!");
return;
} else {
var counter = 0;
// check if solution name already exists
solutions.value.forEach(s => {
if (s.solutionName === sol.value.solutionName) {
counter += 1;
}
});
if (counter == 2) {
alert("This solution name already exists. Please choose an unique solution name or modify respectively delete the old one!");
sol.value.solutionName = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateSolution`,
{
primaryID: sol.value.primaryID,
solutionName: sol.value.solutionName,
customerID: sol.value.customerID,
customer: sol.value.customer,
assetName: sol.value.assetName,
type: sol.value.type,
description: sol.value.description,
notes: sol.value.notes,
lastView: sol.value.lastView,
user: sol.value.user,
}
)
await getSolutionById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all customers
const getCustomers = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllCustomers`
);
customers.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
const confirmDeleteSolution = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this solution? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteSolution/${chosenSolutionId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteTodosSolution/${chosenSolutionId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToSolutionlist');
} else {
store.commit('undoDelete');
}
}
}
//get all solutions
const getSolutions = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllSolutions`);
solutions.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update customerid if customer was changed
const updateCustomerID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${sol.value.customer}`);
customer.value = response.data;
sol.value.customerID = customer.value.customerID;
store.commit('toggleCustomerChanged');
store.commit('toggleCustomerId', sol.value.customerID);
} catch (err) {
console.log(err.response.statusText);
}
await updateSolution();
}
// update customerid if customer was changed
const updateNewCustomerID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerByName/${newCustomer.value}`);
newCustomerID.value = response.data.customerID;
store.commit('toggleCustomerChanged');
store.commit('toggleCustomerId', newCustomerID.value);
} catch (err) {
console.log(err.response.statusText);
}
updateSol();
await getConfigItemsFromCustomer();
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
watch(deleteBool, confirmDeleteSolution);
watch(customerChanged, getSolutionById);
onMounted(() => {
getSolutionById();
getSolutions();
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "Solution",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -83,7 +375,15 @@ export default {
background-color: #fff;
}
.solution-name-input {
padding: 1rem 0;
margin: 1rem;
font-size: initial;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.solution-name {
align-self: stretch;
@ -102,17 +402,41 @@ export default {
color: #000;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.data-field {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.data-field#street-name {
width: 70%;
}
@ -163,7 +487,7 @@ export default {
align-self: stretch;
}
.client-asset,
.customer-asset,
.info {
display: flex;
flex-direction: column;
@ -175,6 +499,10 @@ export default {
border-radius: 0.3125rem;
}
.input {
border: none;
}
.additional {
display: flex;
flex-direction: column;
@ -199,7 +527,7 @@ export default {
color: #000;
}
.type-state {
.type-id {
display: flex;
flex-direction: row;
align-items: center;

View File

@ -1,5 +1,6 @@
<template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<section v-if="!addBool"
:class="['solution-checklist-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Checklist:</div>
<table class="data-table" id="solution-checkklist">
<tbody>
@ -15,51 +16,530 @@
Task</th>
<th :class="['Comments', darkMode ? 'th-darkmode' : 'th-lightmode']">Comments</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<tr v-for="todo in solTodos" :key="todo.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Step', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
...</td>
{{ todo.step }}</td>
<td v-if="!editable"
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
{{ todo.asset }}</td>
<td v-if="editable"
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
<select id="customersDropDownChosenCI" v-model="todo.asset" @change="updateSolTodo(todo)"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItemList" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</td>
<td v-if="!editable"
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
{{ todo.task }}</td>
<td v-if="editable"
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
<input type="text" v-model="todo.task" @change="updateSolTodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">{{
todo.comments }}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="todo.comments" @change="updateSolTodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
<button :class="[darkMode ? 'deleteSolTodos-darkmode' : 'deleteSolTodos-lightmode']"
@click="deleteSolTodo(todo.primaryID)">-</button>
</td>
</tr>
</tbody>
<tr v-if="editable && addRow" :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Step', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
{{ newStepTodo }}
</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
<select id="customersDropDownChosenCI" v-model="newAssetTodo"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItemList" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
<input type="text" v-model="newTaskTodo"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="text"
v-model="newCommentsTodo"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'saveSolTodos-darkmode' : 'saveSolTodos-lightmode']"
@click="addSolTodo()">Save</button> <button
:class="[darkMode ? 'deleteLastSolTodos-darkmode' : 'deleteLastSolTodos-lightmode']"
@click="deleteNewRow()">-</button>
</td>
</tr>
</table>
</section>
<section v-if="editable && !addBool" id="editSolTodos">
<button :class="[darkMode ? 'editSolTodos-darkmode' : 'editSolTodos-lightmode']"
@click="addChecklistRow()">+</button>
</section>
<section v-if="addBool"
:class="['solution-checklist-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Checklist:</div>
<table class="data-table" id="template-checklist">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Step', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
Step</th>
<th
:class="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['Task', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
Task</th>
<th :class="['Comments', darkMode ? 'th-darkmode' : 'th-lightmode']">Comments</th>
</tr>
<tr v-for="(newT, index) in newTodos" :key="index"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Step', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
{{ newT.step }}
</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
...</td>
<select id="customersDropDownChosenCI" v-model="newT.asset"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItemList" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<input type="text" v-model="newT.task"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"> <input type="text"
v-model="newT.comments"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'deleteSolTodos-darkmode' : 'deleteLastSolTodos-lightmode']"
@click="deleteSolTodoFromNewTodos(index)">-</button>
</td>
</tr>
</tbody>
</table>
</div>
</section>
<section v-if="addBool" id="editSolTodos">
<button :class="[darkMode ? 'editSolTodos-darkmode' : 'editSolTodos-lightmode']"
@click="addRowForNewSol()">+</button>
</section>
<section v-if="addBool" id="saveNewSol">
<button :class="[darkMode ? 'saveNewSol-darkmode' : 'saveNewSol-lightmode']" @click="addSol()">Save</button>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const addBool = computed(() => store.state.new);
const editable = computed(() => store.state.editable);
const newSolutionNameSol = computed(() => store.state.newSolutionNameSol);
const newCustomerIDSol = computed(() => store.state.newCustomerIDSol);
const newCustomerSol = computed(() => store.state.newCustomerSol);
const newAssetNameSol = computed(() => store.state.newAssetNameSol);
const newLastViewSol = computed(() => store.state.newLastViewSol);
const newUserSol = computed(() => store.state.newUserSol);
const newTypeSol = computed(() => store.state.newTypeSol);
const newNotesSol = computed(() => store.state.newNotesSol);
const newDescriptionSol = computed(() => store.state.newDescriptionSol);
const newStepTodo = computed(() => solTodos.value.length);
const chosenSolId = computed(() => store.state.chosenSolutionId);
const customerChanged = computed(() => store.state.customerChanged);
const changedCustomerId = computed(() => store.state.changedCustomerId);
const darkMode = ref(true)
const addRow = ref(false);
const configItemList = ref([]);
const solutions = ref([]);
const solTodos = ref([])
const sol = ref({})
const newAssetTodo = ref('');
const newTaskTodo = ref('');
const newCommentsTodo = ref('');
const newTodos = reactive([]);
const newRowId = computed(() => newTodos.length)
// delete new todo row
const deleteNewRow = () => {
newAssetTodo.value = '';
newTaskTodo.value = '';
newCommentsTodo.value = '';
addRow.value = false;
}
const deleteSolTodoFromNewTodos = (index) => {
newTodos.splice(index, 1);
newTodos.forEach((todo, i) => {
todo.step = i
})
}
// add new solution
const addSol = async () => {
// check if all input data is valid
if (newSolutionNameSol.value.trim() === "") {
alert("Please add a solution name!");
return;
} else {
var counter = 0;
if (!(solutions.value.length == null)) {
// check if solution name already exists
solutions.value.forEach(s => {
if (s.solutionName === newSolutionNameSol.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This solution name already exists. Please choose an unique solution name or modify respectively delete the old one!");
return;
}
}
}
if (newCustomerSol.value.length === 0) {
alert("Please choose a customer!");
return;
}
let allFine = true;
newTodos.forEach(todo => {
if (todo.asset.length === 0) {
alert(`Please choose a config item for all todos.`);
allFine = false
}
})
if (!allFine) {
return
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addSol`,
{
solutionName: newSolutionNameSol.value,
assetName: newAssetNameSol.value,
customerID: newCustomerIDSol.value,
customer: newCustomerSol.value,
type: newTypeSol.value,
lastView: newLastViewSol.value,
user: newUserSol.value,
description: newDescriptionSol.value,
notes: newNotesSol.value,
});
store.commit('resetStore');
store.commit('changeToSolutionlist');
newTodos.forEach(async todo => {
try {
const res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addTodoSol`,
{
solutionID: response.data,
step: todo.step,
asset: todo.asset,
task: todo.task,
comments: todo.comments,
});
} catch (err) {
console.log(err.response.statusText);
}
})
} catch (err) {
console.log(err.response.statusText);
}
}
// add new row of todo for the new solution
const addRowForNewSol = async () => {
if (newCustomerSol.value.length === 0) {
alert("Please choose a customer first!");
return;
}
await getConfigItemsFromCustomer();
newTodos.push({
solutionID: chosenSolId.value,
step: newRowId.value,
asset: '',
task: '',
comments: ''
});
}
//update data
const updateSolTodo = async (todo) => {
if (todo.asset.length === 0) {
alert(`Please add the missing config item in row ${todo.step}!`);
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateSolTodo`,
{
primaryID: todo.primaryID,
solutionID: todo.solutionIDID,
step: todo.step,
asset: todo.asset,
task: todo.task,
comments: todo.comments,
}
);
await getSolutionById();
} catch (err) {
console.log(err.response.statusText);
}
}
// add new solution todo
const addSolTodo = async () => {
// check if all input data is valid
if (newAssetTodo.value.length === 0) {
alert("Please choose an asset for the new todo!");
return;
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addTodoSol`,
{
solutionID: chosenSolId.value,
step: newStepTodo.value,
asset: newAssetTodo.value,
task: newTaskTodo.value,
comments: newCommentsTodo.value,
});
addRow.value = false;
await getSolutionTodosById();
newAssetTodo.value = '';
newTaskTodo.value = '';
newCommentsTodo.value = '';
} catch (err) {
console.log(err.response.statusText);
}
}
// add new row for the template
const addChecklistRow = async () => {
await getConfigItemsFromCustomer();
if (addRow.value) {
alert('Please confirm the last added row first.')
return
}
addRow.value = true
}
//get all solutions
const getAllSolutions = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllSolutions`);
solutions.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1000);
}
// get solution todos from id
const getSolutionTodosById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosSolution/${chosenSolId.value}`
);
solTodos.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all config items from the selected customer
const getConfigItemsFromCustomer = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${sol.value.customerID}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${changedCustomerId.value}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
if (customerChanged.value) {
store.commit('toggleCustomerChanged');
}
}
// get solution from id
const getSolutionById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSolution/${chosenSolId.value}`
);
sol.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
await getConfigItemsFromCustomer();
}
const deleteSolTodo = async (id) => {
if (confirm("Do you really want to delete this solution todo? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteSolTodo/${id}`);
} catch (err) {
console.log(err.response.statusText);
}
}
await getSolutionTodosById();
}
watch(customerChanged, getSolutionById);
onMounted(() => {
getSolutionTodosById();
getSolutionById();
triggerBackendCallsWithDelay(getAllSolutions);
});
</script>
<script>
export default {
name: "SolutionChecklist",
};
</script>
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
flex-direction: row;
align-items: flex-start;
justify-content: center;
align-self: stretch;
width: 100%;
padding: 1.25rem 1.875rem;
gap: 1.25rem;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.saveSolTodos-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 10rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.saveSolTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 10rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.saveNewSol-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.saveNewSol-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.deleteSolTodos-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 15.8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteLastSolTodos-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 2rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteSolTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 15.8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteLastSolTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 2rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.input {
border: none;
}
.div-darkmode {
background-color: #2c2c2c;
}
@ -68,6 +548,16 @@ export default {
background-color: #fff;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.data-table {
width: 100%;
padding: 0 0.625rem;
@ -75,6 +565,24 @@ export default {
border-collapse: collapse;
}
.solution-checklist-information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 1.25rem 1.875rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.table-row {
display: flex;
flex-direction: row;
@ -84,6 +592,22 @@ export default {
gap: 0.625rem;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.tr-head-darkmode {
border-top: none;
border-bottom: 0.0625rem solid #000000;
@ -163,6 +687,7 @@ th {
.Comments {
width: 35%;
display: flex;
}
.label {
@ -183,4 +708,54 @@ th {
.label-lightmode {
color: #000;
}
.editSolTodos-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 0.825rem 0.7rem;
width: 4%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.editSolTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
margin-left: 15rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
border-radius: 0.625rem;
}
.deleteSolTodos-darkmode:hover,
.deleteLastSolTodos-darkmode:hover,
.saveSolTodos-darkmode:hover,
.editSolTodos-darkmode:hover,
.saveNewSol-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.deleteSolTodos-lightmode:hover,
.deleteLastSolTodos-lightmode:hover,
.saveSolTodos-lightmode:hover,
.editSolTodos-lightmode:hover,
.saveNewSol-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#saveNewSol {
text-align: center;
}
#editSolTodos {
text-align: right;
}
</style>

View File

@ -1,12 +1,17 @@
<template>
<section v-if="searchable" :class="['solution-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['customerLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Solution</div>
<input v-model="solutionSearchFilter" @change="searchSolution()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Last viewed:</div>
<table class="data-table" id="solution-table">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Client', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
Client</th>
:class="['Customer', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
Customer</th>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
@ -21,11 +26,16 @@
<tr v-for="sol in solutions" :key="sol.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
:class="['Customer', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
{{ sol.customer }}</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
{{ sol.solutionName }}</td>
<nuxt-link to="/solutions" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
@click="goToChosenSolution(sol.primaryID)">
{{ sol.solutionName }}
</nuxt-link>
</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
{{ sol.assetName }}</td>
@ -38,28 +48,79 @@
</table>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
// get accesss to the store
const store = useStore()
const goToChosenSolution = (id) => {
store.commit('setChosenSolution', id);
store.commit('changeToSolution');
};
const customerFilter = computed(() => store.state.filteredByCustomer);
const searchable = computed(() => store.state.searchable);
const solutionSearchFilter = ref('');
const darkMode = ref(true)
const solutions = ref([]);
// update search term
const updateSearchTerm = async () => {
solutionSearchFilter.value = '';
await getSolutions();
}
//get all solutions
const getSolutions = async () => {
if (!(customerFilter.value === '')) {
await getFilteredSolutionsByCustomer();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllSolutions`);
solutions.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all solutions based on the searched customer
const getFilteredSolutionsByCustomer = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllSolutions`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedSolutionsByCustomer/${customerFilter.value}`);
solutions.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
onMounted(() => {
getSolutions();
//get all solutions based on the searched solution name
const searchSolution = async () => {
if (solutionSearchFilter.value === '') {
await getSolutions();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedSolutionsBySolution/${solutionSearchFilter.value}`);
solutions.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
watch(customerFilter, getSolutions);
watch(searchable, updateSearchTerm);
onMounted(async () => {
await getSolutions();
});
</script>
@ -67,9 +128,9 @@ onMounted(() => {
export default {
name: "SolutionTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -77,7 +138,6 @@ export default {
align-items: flex-start;
justify-content: center;
align-self: stretch;
width: 100%;
padding: 1.25rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
@ -118,6 +178,32 @@ export default {
border-bottom: 0.0625rem solid #8e8e8e;
}
.input {
border: none;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.solution-search {
display: flex;
align-items: center;
padding: 0.625em 1.875em;
gap: 1.25em;
width: 30.125em;
height: 3.125em;
box-shadow: 0.25em 0.25em 0.25em rgba(0, 0, 0, 0.25);
border-radius: 0.625em;
box-sizing: border-box;
}
.tr-darkmode {
border-top: 0.0625rem solid #000000;
}
@ -126,6 +212,17 @@ export default {
border-top: 0.0625rem solid #8e8e8e;
}
.dataInput {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
th,
td {
height: 1.875rem;
@ -135,6 +232,14 @@ td {
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.th-darkmode,
.td-darkmode {
color: #ffffff;
@ -149,15 +254,31 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Client {
#nuxt-link {
text-decoration: none;
color: white;
}
.customerLabel {
width: 5.5625em;
height: 1.875em;
font-family: "Overpass";
font-style: normal;
font-weight: 400;
font-size: 0.875em;
line-height: 1.875;
letter-spacing: 0.05em;
}
.Customer {
width: 33.3%;
}
.Client-darkmode {
.Customer-darkmode {
border-right: 0.0625rem solid #000000;
}
.Client-lightmode {
.Customer-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}

View File

@ -1,4 +1,4 @@
<template>
<!-- <template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Solutions:</div>
<table class="data-table" id="solution-table">
@ -41,7 +41,7 @@ const darkMode = ref(true)
<script>
export default {
name: "SolutionTableNoClient",
name: "SolutionTableNoCustomer",
};
</script>
@ -183,4 +183,4 @@ th {
.label-lightmode {
color: #000;
}
</style>
</style> -->

View File

@ -126,7 +126,7 @@
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"> <input type="text"
v-model="newT.comments"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'deletePOTTodos-darkmode' : 'deleteLastPOTTodos-lightmode']"
:class="[darkMode ? 'deleteLastPOTTodos-darkmode' : 'deleteLastPOTTodos-lightmode']"
@click="deletePOTTodoFromNewTodos(index)">-</button>
</td>
</tr>
@ -138,7 +138,7 @@
@click="addRowForNewPOT()">+</button>
</section>
<section v-if="addBool" id="saveNewPOT">
<button :class="[darkMode ? 'saveNewPOT-darkmode' : 'saveNewPOT-lightmode']" @click="addPOT()">Safe</button>
<button :class="[darkMode ? 'saveNewPOT-darkmode' : 'saveNewPOT-lightmode']" @click="addPOT()">Save</button>
</section>
</template>
@ -163,8 +163,8 @@ const newDescriptionPOT = computed(() => store.state.newDescriptionPOT);
const newNotesPOT = computed(() => store.state.newNotesPOT);
const newStepTodo = computed(() => potTodos.value.length);
const chosenPOTId = computed(() => store.state.chosenPOTId);
const clientChanged = computed(() => store.state.clientChanged);
const changedClientId = computed(() => store.state.changedClientId);
const customerChanged = computed(() => store.state.customerChanged);
const changedCustomerId = computed(() => store.state.changedCustomerId);
const darkMode = ref(true)
const addRow = ref(false);
@ -215,7 +215,7 @@ const addPOT = async () => {
}
}
if (newCustomerPOT.value.length === 0) {
alert("Please choose a client!");
alert("Please choose a customer!");
return;
}
let allFine = true;
@ -263,10 +263,10 @@ const addPOT = async () => {
// add new row of todo for the new pot
const addRowForNewPOT = async () => {
if (newCustomerPOT.value.length === 0) {
alert("Please choose a client first!");
alert("Please choose a customer first!");
return;
}
await getConfigItemsFromClient();
await getConfigItemsFromCustomer();
newTodos.push({
templateID: chosenPOTId.value,
rowID: newRowId.value,
@ -328,7 +328,7 @@ const addPOTTodo = async () => {
// add new row for the template checklist
const addChecklistRow = async () => {
await getConfigItemsFromClient();
await getConfigItemsFromCustomer();
if (addRow.value) {
alert('Please confirm the last added row first.')
return
@ -367,25 +367,25 @@ const getPOTTodosById = async () => {
}
}
//get all config items from the selected client
const getConfigItemsFromClient = async () => {
//get all config items from the selected customer
const getConfigItemsFromCustomer = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromClient/${pot.value.customerID}`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${pot.value.customerID}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromClient/${changedClientId.value}`);
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${changedCustomerId.value}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
if (clientChanged.value) {
store.commit('toggleClientChanged');
if (customerChanged.value) {
store.commit('toggleCustomerChanged');
}
}
@ -401,7 +401,7 @@ const getPOTById = async () => {
console.log(err.response.statusText);
}
}
await getConfigItemsFromClient();
await getConfigItemsFromCustomer();
}
const deletePOTTodo = async (id) => {
@ -415,7 +415,7 @@ const deletePOTTodo = async (id) => {
await getPOTTodosById();
}
watch(clientChanged, getPOTById);
watch(customerChanged, getPOTById);
onMounted(() => {
getPOTTodosById();
@ -619,7 +619,6 @@ th {
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.savePOTTodos-darkmode {
background: #212121;
color: #fff;
@ -659,7 +658,7 @@ th {
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 2rem;
margin-left: 15.8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}

View File

@ -0,0 +1,750 @@
<template>
<section v-if="!addBool"
:class="['template-checklist-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Checklist:</div>
<table class="data-table" id="template-checklist">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Step', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
Step</th>
<th
:class="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['Task', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
Task</th>
<th :class="['Comments', darkMode ? 'th-darkmode' : 'th-lightmode']">Comments</th>
</tr>
<tr v-for="todo in mvtTodos" :key="todo.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Step', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
{{ todo.rowID }}
</td>
<td v-if="!editable"
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
{{ todo.asset }}</td>
<td v-if="editable"
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
<select id="customersDropDownChosenCI" v-model="todo.asset" @change="updateMVTTodo(todo)"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItemList" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</td>
<td v-if="!editable"
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
{{ todo.task }}</td>
<td v-if="editable"
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
<input type="text" v-model="todo.task" @change="updateMVTTodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td v-if="!editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"> {{ todo.commets
}}</td>
<td v-if="editable" :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"> <input type="text"
v-model="todo.commets" @change="updateMVTTodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'deleteMvtTodos-darkmode' : 'deleteMvtTodos-lightmode']"
@click="deleteMVTTodo(todo.primaryID)">-</button>
</td>
</tr>
<tr v-if="editable && addRow" :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Step', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
{{ newStepTodo }}
</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
<select id="customersDropDownChosenCI" v-model="newAssetTodo"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItemList" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
<input type="text" v-model="newTaskTodo"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="text"
v-model="newCommentsTodo"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'saveMvtTodos-darkmode' : 'saveMvtTodos-lightmode']"
@click="addMVTTodo()">Save</button> <button
:class="[darkMode ? 'deleteLastMvtTodos-darkmode' : 'deleteLastMvtTodos-lightmode']"
@click="deleteNewRow()">-</button>
</td>
</tr>
</tbody>
</table>
</section>
<section v-if="editable && !addBool" id="editMvtTodos">
<button :class="[darkMode ? 'editMvtTodos-darkmode' : 'editMvtTodos-lightmode']"
@click="addChecklistRow()">+</button>
</section>
<section v-if="addBool"
:class="['template-checklist-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Checklist:</div>
<table class="data-table" id="template-checklist">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Step', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
Step</th>
<th
:class="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['Task', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
Task</th>
<th :class="['Comments', darkMode ? 'th-darkmode' : 'th-lightmode']">Comments</th>
</tr>
<tr v-for="(newT, index) in newTodos" :key="index"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Step', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Step-darkmode' : 'Step-lightmode']">
{{ newT.rowID }}
</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
<select id="customersDropDownChosenCI" v-model="newT.asset"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="ci in configItemList" :key="ci.primaryID">
{{ ci.assetName }}
</option>
</select>
</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
<input type="text" v-model="newT.task"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']"> <input type="text"
v-model="newT.comments"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> <button
:class="[darkMode ? 'deleteMvtTodos-darkmode' : 'deleteLastMvtTodos-lightmode']"
@click="deleteMVTTodoFromNewTodos(index)">-</button>
</td>
</tr>
</tbody>
</table>
</section>
<section v-if="addBool" id="editMvtTodos">
<button :class="[darkMode ? 'editMvtTodos-darkmode' : 'editMvtTodos-lightmode']"
@click="addRowForNewMVT()">+</button>
</section>
<section v-if="addBool" id="saveNewMVT">
<button :class="[darkMode ? 'saveNewMVT-darkmode' : 'saveNewMVT-lightmode']" @click="addMVT()">Save</button>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const addBool = computed(() => store.state.new);
const editable = computed(() => store.state.editable);
const newNameMVT = computed(() => store.state.newNameMVT);
const newCustomerIDMVT = computed(() => store.state.newCustomerIDMVT);
const newCustomerMVT = computed(() => store.state.newCustomerMVT);
const newLastViewMVT = computed(() => store.state.newLastViewMVT);
const newUserMVT = computed(() => store.state.newUserMVT);
const newTypeMVT = computed(() => store.state.newTypeMVT);
const newNotesMVT = computed(() => store.state.newNotesMVT);
const newStepTodo = computed(() => mvtTodos.value.length);
const chosenMVTId = computed(() => store.state.chosenMVTId);
const customerChanged = computed(() => store.state.customerChanged);
const changedCustomerId = computed(() => store.state.changedCustomerId);
const darkMode = ref(true)
const addRow = ref(false);
const configItemList = ref([]);
const maintenanceVisitTemplates = ref([]);
const mvtTodos = ref([])
const MVT = ref({})
const newAssetTodo = ref('');
const newTaskTodo = ref('');
const newCommentsTodo = ref('');
const newTodos = reactive([]);
const newRowId = computed(() => newTodos.length)
// delete new todo row
const deleteNewRow = () => {
newAssetTodo.value = '';
newTaskTodo.value = '';
newCommentsTodo.value = '';
addRow.value = false;
}
const deleteMVTTodoFromNewTodos = (index) => {
newTodos.splice(index, 1);
newTodos.forEach((todo, i) => {
todo.rowID = i
})
}
// add new maintenance visit template
const addMVT = async () => {
// check if all input data is valid
if (newNameMVT.value.trim() === "") {
alert("Please add a maintenance visit template name!");
return;
} else {
var counter = 0;
if (!(maintenanceVisitTemplates.value.length == null)) {
// check if maintenance visit template name already exists
maintenanceVisitTemplates.value.forEach(MVT => {
if (MVT.name === newNameMVT.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This maintenance visit template name already exists. Please choose an unique maintenance visit template name or modify respectively delete the old one!");
return;
}
}
}
if (newCustomerMVT.value.length === 0) {
alert("Please choose a customer!");
return;
}
let allFine = true;
newTodos.forEach(todo => {
if (todo.asset.length === 0) {
alert(`Please choose a config item for all todos.`);
allFine = false
}
})
if (!allFine) {
return
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addMVT`,
{
name: newNameMVT.value,
customerID: newCustomerIDMVT.value,
customer: newCustomerMVT.value,
lastView: newLastViewMVT.value,
user: newUserMVT.value,
type: newTypeMVT.value,
notes: newNotesMVT.value,
});
store.commit('resetStore');
store.commit('changeToTemplatelist');
newTodos.forEach(async todo => {
try {
const res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addTodoMVT`,
{
templateID: response.data,
rowID: todo.rowID,
asset: todo.asset,
task: todo.task,
comment: todo.comments,
});
} catch (err) {
console.log(err.response.statusText);
}
})
} catch (err) {
console.log(err.response.statusText);
}
}
// add new row of todo for the new MVT
const addRowForNewMVT = async () => {
if (newCustomerMVT.value.length === 0) {
alert("Please choose a customer first!");
return;
}
await getConfigItemsFromCustomer();
newTodos.push({
templateID: chosenMVTId.value,
rowID: newRowId.value,
asset: '',
task: '',
comments: ''
});
}
//update data
const updateMVTTodo = async (todo) => {
if (todo.asset.length === 0) {
alert(`Please add the missing config item in row ${todo.rowID}!`);
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateMVTTodo`,
{
primaryID: todo.primaryID,
templateID: todo.templateID,
rowID: todo.rowID,
asset: todo.asset,
task: todo.task,
comments: todo.commets,
}
);
await getMVTById();
} catch (err) {
console.log(err.response.statusText);
}
}
// add new maintenance visit template todo
const addMVTTodo = async () => {
// check if all input data is valid
if (newAssetTodo.value.length === 0) {
alert("Please choose an asset for the new todo!");
return;
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addTodoMVT`,
{
templateID: chosenMVTId.value,
rowID: newStepTodo.value,
asset: newAssetTodo.value,
task: newTaskTodo.value,
comment: newCommentsTodo.value,
});
addRow.value = false;
await getMvtTodosById();
newAssetTodo.value = '';
newTaskTodo.value = '';
newCommentsTodo.value = '';
} catch (err) {
console.log(err.response.statusText);
}
}
// add new row for the template checklist
const addChecklistRow = async () => {
await getConfigItemsFromCustomer();
if (addRow.value) {
alert('Please confirm the last added row first.')
return
}
addRow.value = true
}
//get all maintenance visit templates
const getMaintenanceVisitTemplates = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllMaintenanceVisitTemplates`);
maintenanceVisitTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1000);
}
// get maintenance visit template todos from id
const getMvtTodosById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosMaintenanceVisitTemplate/${chosenMVTId.value}`
);
mvtTodos.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all config items from the selected customer
const getConfigItemsFromCustomer = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${MVT.value.customerID}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${changedCustomerId.value}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
if (customerChanged.value) {
store.commit('toggleCustomerChanged');
}
}
// get maintenance visit template from id
const getMVTById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getMaintenanceVisitTemplate/${chosenMVTId.value}`
);
MVT.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
await getConfigItemsFromCustomer();
}
const deleteMVTTodo = async (id) => {
if (confirm("Do you really want to delete this maintenance visit template todo? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteMVTTodo/${id}`);
} catch (err) {
console.log(err.response.statusText);
}
}
await getMvtTodosById();
}
watch(customerChanged, getMVTById);
onMounted(() => {
getMvtTodosById();
getMVTById();
triggerBackendCallsWithDelay(getMaintenanceVisitTemplates);
});
</script>
<script>
export default {
name: "TemplateChecklist",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.input {
border: none;
}
.data-table {
width: 100%;
padding: 0 0.625rem;
table-layout: fixed;
border-collapse: collapse;
}
.table-row {
display: flex;
flex-direction: row;
align-items: center;
height: 3.125rem;
padding: 0.625rem;
gap: 0.625rem;
}
.tr-head-darkmode {
border-top: none;
border-bottom: 0.0625rem solid #000000;
}
.tr-head-lightmode {
border-top: none;
border-bottom: 0.0625rem solid #8e8e8e;
}
.tr-darkmode {
border-top: 0.0625rem solid #000000;
}
.tr-lightmode {
border-top: 0.0625rem solid #8e8e8e;
}
th,
td {
height: 1.875rem;
text-align: left;
padding: 0;
letter-spacing: 5%;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.th-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
.template-checklist-information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 1.25rem 1.875rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.Step {
width: 8%;
}
.Step-darkmode {
border-right: 0.0625rem solid #000000;
}
.Step-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Asset {
width: 22%;
}
.Asset-darkmode {
border-right: 0.0625rem solid #000000;
}
.Asset-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Task {
width: 35%;
}
.Task-darkmode {
border-right: 0.0625rem solid #000000;
}
.Task-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Comments {
width: 35%;
display: flex;
}
.label {
width: 6.0625em;
height: 1.875em;
font-family: 'Overpass';
font-style: normal;
font-weight: 400;
font-size: 1em;
line-height: 1.875em;
letter-spacing: 0.05em;
}
.label-darkmode {
color: #FFFFFF;
}
.label-lightmode {
color: #000;
}
.editMvtTodos-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 0.825rem 0.7rem;
width: 4%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.saveMvtTodos-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 10rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.saveNewMVT-darkmode {
background: #2c2c2c;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.deleteMvtTodos-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 15.8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteLastMvtTodos-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 2rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.editMvtTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
margin-left: 15rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
border-radius: 0.625rem;
}
.saveMvtTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 10rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteMvtTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 15.8rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.deleteLastMvtTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 2rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
}
.saveNewMVT-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
padding: 1rem 1.875rem;
width: 8%;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.deleteMvtTodos-darkmode:hover,
.deleteLastMvtTodos-darkmode:hover,
.saveMvtTodos-darkmode:hover,
.editMvtTodos-darkmode:hover,
.saveNewMVT-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.deleteMvtTodos-lightmode:hover,
.deleteLastMvtTodos-lightmode:hover,
.saveMvtTodos-lightmode:hover,
.editMvtTodos-lightmode:hover,
.saveNewMVT-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#saveNewMVT {
text-align: center;
}
#editMvtTodos {
text-align: right;
}
</style>

View File

@ -99,7 +99,7 @@ export default {
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
border-radius: 0.625rem;
gap: 1.25rem;
}

View File

@ -70,7 +70,7 @@ export default {
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
border-radius: 0.625rem;
gap: 1.25rem;
}

View File

@ -100,7 +100,7 @@ export default {
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
padding: 0.8rem 1.875rem;
border-radius: 0.625rem;
gap: 1.25rem;
}

39
composables/UserObject.ts Normal file
View File

@ -0,0 +1,39 @@
export var UserObjectDefinition: {
id: string;
username: string;
password: string;
registered: string;
lastLogin: string;
fullName: string;
email: string;
phonenumber: string;
address: string;
city: string;
postcode: string;
adminBool: boolean;
technician1Bool: boolean;
technician2Bool: boolean;
technicianMonitoringBool: boolean;
merchantBool: boolean;
internBool: boolean;
}
export interface UserObject {
id: string;
username: string;
password: string;
registered: string;
lastLogin: string;
fullName: string;
email: string;
phonenumber: string;
address: string;
city: string;
postcode: string;
adminBool: boolean;
technician1Bool: boolean;
technician2Bool: boolean;
technicianMonitoringBool: boolean;
merchantBool: boolean;
internBool: boolean;
}

View File

@ -1,6 +1,6 @@
<mxfile host="Electron" modified="2024-02-14T10:28:35.536Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.0.3 Chrome/114.0.5735.289 Electron/25.8.4 Safari/537.36" etag="_zOGEdVgp7g5JHBy-mYE" version="22.0.3" type="device" pages="2">
<mxfile host="Electron" modified="2024-02-27T19:18:30.556Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.0.3 Chrome/114.0.5735.289 Electron/25.8.4 Safari/537.36" etag="pTIMz7977P7LLgTl7RJZ" version="22.0.3" type="device" pages="2">
<diagram name="Seite-1" id="VLuSDTVFFHJCdRpH-1WC">
<mxGraphModel dx="393" dy="2849" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxGraphModel dx="395" dy="2842" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
@ -427,10 +427,10 @@
<mxCell id="WukdXvazNq34soQIU5Al-32" value="supplierOffer" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="300" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-33" value="clientOffer" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="WukdXvazNq34soQIU5Al-33" value="customerOffer" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="330" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-34" value="clientOrder" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="WukdXvazNq34soQIU5Al-34" value="customerOrder" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="360" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-35" value="supplierOrder" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
@ -580,7 +580,7 @@
<mxCell id="WukdXvazNq34soQIU5Al-108" value="task" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-103" vertex="1">
<mxGeometry y="150" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-109" value="comment" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-103" vertex="1">
<mxCell id="WukdXvazNq34soQIU5Al-109" value="comments" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-103" vertex="1">
<mxGeometry y="180" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-128" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="WukdXvazNq34soQIU5Al-126" target="DauqCNUrC7Z9yIe88X-r-22" edge="1">

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
<mxfile host="Electron" modified="2024-02-27T19:18:30.556Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.0.3 Chrome/114.0.5735.289 Electron/25.8.4 Safari/537.36" etag="pTIMz7977P7LLgTl7RJZ" version="22.0.3" type="device" pages="2">
<mxfile host="Electron" modified="2024-03-11T18:43:59.748Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.0.3 Chrome/114.0.5735.289 Electron/25.8.4 Safari/537.36" etag="Ub9Iakw2VLrdzjhM2iAH" version="22.0.3" type="device" pages="2">
<diagram name="Seite-1" id="VLuSDTVFFHJCdRpH-1WC">
<mxGraphModel dx="395" dy="2842" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxGraphModel dx="409" dy="2842" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
@ -395,7 +395,7 @@
<mxGeometry y="510" width="150" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-15" value="issueSlips" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#00CC00;" parent="1" vertex="1">
<mxGeometry x="2040" y="-560" width="140" height="540" as="geometry" />
<mxGeometry x="2040" y="-560" width="140" height="840" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-16" value="primaryID*" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="30" width="140" height="30" as="geometry" />
@ -421,33 +421,63 @@
<mxCell id="WukdXvazNq34soQIU5Al-21" value="notes" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="240" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-23" value="supplierRequest" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="6nz9YpIofWTpyD1iDkT1-14" value="deliveryAddress" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="270" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-32" value="supplierOffer" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="WukdXvazNq34soQIU5Al-23" value="supplierRequestDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="300" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-33" value="clientOffer" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="6nz9YpIofWTpyD1iDkT1-5" value="supplierRequest" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="330" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-34" value="clientOrder" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="WukdXvazNq34soQIU5Al-32" value="supplierOfferDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="360" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-35" value="supplierOrder" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="6nz9YpIofWTpyD1iDkT1-6" value="supplierOffer" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="390" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-36" value="ingress" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="WukdXvazNq34soQIU5Al-33" value="clientOfferDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="420" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-37" value="egress" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="6nz9YpIofWTpyD1iDkT1-7" value="clientOffer" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="450" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-38" value="ingressBill" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="WukdXvazNq34soQIU5Al-34" value="clientOrderDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="480" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-39" value="egressBill" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxCell id="6nz9YpIofWTpyD1iDkT1-8" value="clientOrder" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="510" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-35" value="supplierOrderDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="540" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="6nz9YpIofWTpyD1iDkT1-9" value="supplierOrder" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="570" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-36" value="ingressDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="600" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="6nz9YpIofWTpyD1iDkT1-10" value="ingress" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="630" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="6nz9YpIofWTpyD1iDkT1-11" value="egressDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="660" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-37" value="egress" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="690" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="6nz9YpIofWTpyD1iDkT1-12" value="ingressBillDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="720" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-38" value="ingressBill" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="750" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="6nz9YpIofWTpyD1iDkT1-13" value="egressBillDate" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="780" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-39" value="egressBill" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-15" vertex="1">
<mxGeometry y="810" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-40" value="orderingInfoIssueSlips" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#00CC00;" parent="1" vertex="1">
<mxGeometry x="2220" y="-440" width="140" height="210" as="geometry" />
</mxCell>
@ -470,7 +500,7 @@
<mxGeometry y="180" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-48" value="issues" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#00CC00;" parent="1" vertex="1">
<mxGeometry x="2040" y="120" width="140" height="210" as="geometry" />
<mxGeometry x="2040" y="400" width="140" height="210" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-49" value="primaryID*" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-48" vertex="1">
<mxGeometry y="30" width="140" height="30" as="geometry" />
@ -491,7 +521,7 @@
<mxGeometry y="180" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-56" value="issueVariants" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#00CC00;" parent="1" vertex="1">
<mxGeometry x="2220" y="180" width="140" height="240" as="geometry" />
<mxGeometry x="2220" y="460" width="140" height="240" as="geometry" />
</mxCell>
<mxCell id="WukdXvazNq34soQIU5Al-57" value="primaryID*" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="WukdXvazNq34soQIU5Al-56" vertex="1">
<mxGeometry y="30" width="140" height="30" as="geometry" />

View File

@ -1,76 +1,123 @@
<template>
<aside :class="['actionbar', darkMode ? 'actionbar-darkmode' : 'actionbar-lightmode', isExpanded ? 'is-expanded' : 'is-not-expanded']">
<div :class="['icon', darkMode ? 'indicator-darkmode' : 'indicator-lightmode']" id="indicator-icon" @click="toggleActionbar">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Indicator-Icon-Opened.svg" />
<aside
:class="['actionbar', darkMode ? 'actionbar-darkmode' : 'actionbar-lightmode', isExpanded ? 'is-expanded' : 'is-not-expanded']">
<div :class="['icon', darkMode ? 'indicator-darkmode' : 'indicator-lightmode']" id="indicator-icon"
@click="toggleActionbar">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Indicator-Icon-Opened.svg" />
</div>
<nav class="actions">
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="search" @click="toggleSearched">
<button v-if="searchIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="search"
@click="toggleSearched">
<div class="icon" id="search-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Search-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Search-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Search</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="filter" @click="toggleFiltered">
<button v-if="filterIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="filter"
@click="toggleFiltered">
<div class="icon" id="filter-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Filter-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Filter-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Filter</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="instances">
<button v-if="instancesIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="instances">
<div class="icon" id="instances-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Instances-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Instances-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Instances</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="attachments">
<button v-if="solutionIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="solutions"
@click="changeToSolutions">
<div class="icon" id="instances-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Instances-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Solutions</pre>
</Transition>
</button>
<button v-if="attachmentsIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="attachments">
<div class="icon" id="attachments-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Attachments-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Attachments-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Attachments</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="sell">
<button v-if="sellIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="sell">
<div class="icon" id="sell-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Sell-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Sell-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Sell</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="archive">
<button v-if="archiveIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="archive">
<div class="icon" id="archive-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Archive-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Archive-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Archive</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="new" @click="add">
<button v-if="addIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="new" @click="add">
<div class="icon" id="new-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Add-New-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Add-New-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">New</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="edit" @click="toggleEditable">
<button v-if="addInstanceIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="new-instance">
<div class="icon" id="new-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Add-New-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Instance</pre>
</Transition>
</button>
<router-link v-if="addSolutionIcon" to="/solutions" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="solutions-button">
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="new-solution"
@click="addSolution">
<div class="icon" id="new-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Add-New-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Solution</pre>
</Transition>
</button>
</router-link>
<button v-if="editIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="edit"
@click="toggleEditable">
<div class="icon" id="edit-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Edit-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Edit-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Edit</pre>
</Transition>
</button>
<button :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="delete" @click="deleteFunc">
<button v-if="deleteIcon" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="delete"
@click="deleteFunc">
<div class="icon" id="delete-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/actionbar-icons/Delete-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy"
src="/icons/actionbar-icons/Delete-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Delete</pre>
@ -81,8 +128,22 @@
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const addIcon = computed(() => store.state.addIcon);
const addInstanceIcon = computed(() => store.state.addInstanceIcon);
const addSolutionIcon = computed(() => store.state.addSolutionIcon);
const solutionIcon = computed(() => store.state.solutionIcon);
const filterIcon = computed(() => store.state.filterIcon);
const searchIcon = computed(() => store.state.searchIcon);
const instancesIcon = computed(() => store.state.instancesIcon);
const attachmentsIcon = computed(() => store.state.attachmentsIcon);
const sellIcon = computed(() => store.state.sellIcon);
const archiveIcon = computed(() => store.state.archiveIcon);
const editIcon = computed(() => store.state.editIcon);
const deleteIcon = computed(() => store.state.deleteIcon);
const darkMode = ref(true)
const isExpanded = ref(true)
@ -108,6 +169,18 @@ const toggleSearched = () => {
const add = () => {
store.commit('add');
};
const addSolution = () => {
store.commit('add');
};
const changeToSolutions = () => {
store.commit('changeToSolutionlistAsset');
}
onMounted(() => {
store.commit('changeToAssetlist')
});
</script>
@ -129,7 +202,7 @@ aside.actionbar {
display: flex;
flex-direction: column;
position: sticky;
top: 5rem;
top: 3.75rem;
height: fit-content;
width: fit-content;
inline-size: fit-content;
@ -141,17 +214,21 @@ aside.actionbar {
gap: 1.25rem;
overflow: clip;
}
.actionbar-darkmode {
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
background-color: #2C2C2C;
}
.actionbar-lightmode {
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
background-color: #FFFFFF;
}
aside.is-expanded {
animation: expand 0.5s linear both;
}
aside.is-not-expanded {
animation: contract 0.5s linear both;
}
@ -181,16 +258,30 @@ button {
transition: 0.2s ease-in-out;
overflow: clip;
}
.button-darkmode { background-color: #2C2C2C; }
.button-lightmode { background-color: #FFFFFF; }
.button-darkmode:hover,
.indicator-darkmode:hover { background-color: #444444; }
.button-darkmode {
background-color: #2C2C2C;
}
.button-lightmode:hover,
.indicator-lightmode:hover { background-color: #ACACAC; }
.button-lightmode {
background-color: #FFFFFF;
}
.is-not-expanded>button { align-self: center; }
.button-darkmode:hover,
.indicator-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.button-lightmode:hover,
.indicator-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
.is-not-expanded>button {
align-self: center;
}
.icon {
@ -202,6 +293,7 @@ button {
justify-content: center;
padding: 0 0.5rem;
}
.is-not-expanded .icon {
align-self: center;
}
@ -211,8 +303,11 @@ button {
height: 1.875rem;
border-radius: 0.3125rem;
transition: 0.2s ease-in-out;
}
.is-not-expanded #indicator-icon { transform: rotate(180deg); }
}
.is-not-expanded #indicator-icon {
transform: rotate(180deg);
}
img {
@ -222,8 +317,14 @@ img {
object-position: center;
overflow: hidden;
}
.img-darkmode { filter: invert(100%); }
#indicator-icon>img { height: 1.25rem; }
.img-darkmode {
filter: invert(100%);
}
#indicator-icon>img {
height: 1.25rem;
}
.label {
@ -234,13 +335,20 @@ img {
letter-spacing: 0.02rem;
white-space: nowrap;
font: 400 0.875rem/1.25rem Overpass, sans-serif;
}
.label-darkmode { color: #FFFFFF; }
.label-lightmode { color: #000000; }
}
.label-darkmode {
color: #FFFFFF;
}
.label-lightmode {
color: #000000;
}
.fade-enter-from, .fade-leave-to {
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}

View File

@ -2,17 +2,17 @@
<aside :class="['navbar', darkMode ? 'navbar-darkmode' : 'navbar-lightmode', isExpanded ? 'is-expanded' : 'is-not-expanded']">
<div class="toggleNavbar">
<div v-if="isExpanded" :class="['icon', darkMode ? 'back-darkmode' : 'back-lightmode']" id="back-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/Back-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/Back-Icon.svg" />
</div>
<div :class="['icon', darkMode ? 'indicator-darkmode' : 'indicator-lightmode']" id="indicator-icon" @click="ToggleSidebar">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/navbar-icons/Nav-Indicator-Icon-Opened.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/navbar-icons/Nav-Indicator-Icon-Opened.svg" />
</div>
</div>
<div class="menus">
<nav id="home-menu" :class="[darkMode ? 'menu-darkmode' : 'menu-lightmode']">
<router-link to="/home" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="home-button">
<div class="icon" id="home-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/navbar-icons/Home-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/navbar-icons/Home-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Home</pre>
@ -20,9 +20,9 @@
</router-link>
</nav>
<nav id="site-menu">
<router-link to="/maintenanceVisits" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" @click="defaultProductionOrderPage()" id="checklists-button">
<router-link to="/maintenanceVisits" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" @click="defaultMasterChecklistPage()" id="checklists-button">
<div class="icon" id="checklists-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/navbar-icons/Checklists-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/navbar-icons/Checklists-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Checklists</pre>
@ -30,34 +30,34 @@
</router-link>
<nuxt-link to="/assets" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" @click="defaultAssetPage()" id="assets-button">
<div class="icon" id="assets-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/navbar-icons/Assets-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/navbar-icons/Assets-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Assets</pre>
</Transition>
</nuxt-link>
<router-link to="/solutions" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="solutions-button">
<router-link to="/solutions" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" @click="defaultSolutionPage()" id="solutions-button">
<div class="icon" id="solutions-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/navbar-icons/Solutions-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/navbar-icons/Solutions-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Solutions</pre>
</Transition>
</router-link>
<router-link to="/issueSlips" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="accounting-button">
<router-link to="/issueSlips" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" @click="defaultIssueSlipPage()" id="accounting-button">
<div class="icon" id="accounting-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/navbar-icons/Accounting-Icon.svg" />
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/navbar-icons/Accounting-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Accounting</pre>
</Transition>
</router-link>
<router-link to="/clients" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="clients-button">
<div class="icon" id="clients-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="../icons/navbar-icons/Clients-Icon.svg" />
<router-link to="/customers" class="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="customers-button">
<div class="icon" id="customers-icon">
<img :class="[darkMode ? 'img-darkmode' : 'img-lightmode']" loading="lazy" src="/icons/navbar-icons/Customers-Icon.svg" />
</div>
<Transition name="fade">
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Clients</pre>
<pre v-if="isExpanded" :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Customers</pre>
</Transition>
</router-link>
</nav>
@ -81,11 +81,21 @@ const defaultAssetPage = () => {
store.commit('changeToAssetlist');
};
const defaultProductionOrderPage = () => {
const defaultMasterChecklistPage = () => {
store.commit('resetStore');
store.commit('changeToTemplatelist')
}
const defaultSolutionPage = () => {
store.commit('resetStore');
store.commit('changeToSolutionlist')
}
const defaultIssueSlipPage = () => {
store.commit('resetStore');
store.commit('changeToIssueSliplist')
}
const ToggleSidebar = () => {
isExpanded.value = !isExpanded.value;
};
@ -108,7 +118,7 @@ aside.navbar {
display: flex;
flex-direction: column;
position: sticky;
top: 5rem;
top: 3.75rem;
height: fit-content;
width: fit-content;
inline-size: fit-content;

View File

@ -1,8 +1,8 @@
<template>
<header :class="[darkMode ? 'header-darkmode' : 'header-lightmode']">
<img id="header-logo" loading="lazy" src="../tüit-logo.svg.png" />
<img id="header-logo" loading="lazy" src="/tüit-logo.svg.png" />
<div class="profile">
<div :class="['username', darkMode ? 'username-darkmode' : 'username-lightmode']">username</div>
<pre :class="['username', darkMode ? 'username-darkmode' : 'username-lightmode']" id='uname'>username</pre>
<div :class="['picture', darkMode ? 'picture-darkmode' : 'picture-lightmode']">
<img id="picture" loading="lazy" src="" />
</div>
@ -15,16 +15,20 @@
import { ref } from 'vue';
const darkMode = ref(true)
const username = ref('username');
</script>
<script>
export default {
name: "PageHeader",
}
</script>
<style scoped>
* {
box-sizing: border-box;
@ -36,28 +40,28 @@ header {
position: sticky;
top: 0;
width: 100%;
height: 4.375rem;
height: 3.125rem;
align-self: stretch;
justify-content: space-between;
align-items: center;
padding: 0.625rem 1.25rem;
padding: 0.375rem 1.875rem;
}
.header-darkmode {
background-color: #212121;
border-bottom: 0.125em solid #000;
border-bottom: 0.125em solid #000000;
}
.header-lightmode {
background-color: #EBEBEB;
border-bottom: 0.125em solid #8e8e8e61;
background-color: #ebebeb;
border-bottom: 0.125em solid #8e8e8e;
}
#header-logo {
object-fit: contain;
object-position: center;
width: 5rem;
height: 2.5rem;
width: 4rem;
height: 2rem;
justify-content: center;
align-items: center;
overflow: hidden;
@ -68,37 +72,36 @@ header {
flex-direction: row;
align-items: flex-end;
gap: 0.625rem;
padding: 0 0.625rem;
padding: 0 0.375rem;
}
.username {
align-self: center;
margin: auto 0;
text-align: right;
font: 200 0.875rem Overpass, sans-serif;
letter-spacing: 5%;
font: 200 0.75rem/1.25rem Overpass, sans-serif;
letter-spacing: 0.01rem;
}
.username-darkmode {
color: #fff;
color: #ffffff;
}
.username-lightmode {
color: #000;
color: #000000;
}
.picture {
display: flex;
width: 2.5rem;
height: 2.5rem;
width: 1.875rem;
height: 1.875rem;
border-radius: 50%;
}
.picture-darkmode {
background-color: #fff;
background-color: #ffffff;
}
.picture-lightmode {
background-color: #000;
background-color: #000000;
}
</style>

24
nuxt-app/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example

75
nuxt-app/README.md Normal file
View File

@ -0,0 +1,75 @@
# Nuxt 3 Minimal Starter
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install the dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
# bun
bun install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm run dev
# yarn
yarn dev
# bun
bun run dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm run build
# yarn
yarn build
# bun
bun run build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm run preview
# yarn
yarn preview
# bun
bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

5
nuxt-app/app.vue Normal file
View File

@ -0,0 +1,5 @@
<template>
<div>
<NuxtWelcome />
</div>
</template>

4
nuxt-app/nuxt.config.ts Normal file
View File

@ -0,0 +1,4 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true }
})

9593
nuxt-app/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
nuxt-app/package.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"nuxt": "^3.10.3",
"vue": "^3.4.19",
"vue-router": "^4.3.0"
}
}

BIN
nuxt-app/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}

4
nuxt-app/tsconfig.json Normal file
View File

@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}

View File

@ -1,10 +1,54 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
import type {
NuxtPage
} from 'nuxt/schema'
import type { NuxtPage } from 'nuxt/schema'
import clientsideConfig from './clientsideConfig'
import { UserObjectDefinition } from './composables/UserObject'
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@pinia/nuxt',
'@sidebase/nuxt-auth',
],
auth: {
//baseURL: `https://${clientsideConfig.url}:${clientsideConfig.port}/.output/server/chunks/routes/api/auth`,
computed: {
origin: `https://${clientsideConfig.url}:${clientsideConfig.port}/`,
//pathname: '/server/chunks/routes/api/auth/',
//fullBaseUrl: `https://${clientsideConfig.url}:${clientsideConfig.port}/server/chunks/routes/api/auth/`,
},
//baseUrl: `https://${clientsideConfig.url}:${clientsideConfig.port}/server/chunks/routes/api/auth/`,
provider: {
type: 'refresh',
endpoints: {
signIn: { path: '/login', method: 'post' },
signout: false,
signUp: { path: '/signup', method: 'post' },
getSession: { path: '/session', method: 'get' },
refresh: { path: '/refresh', method: 'post' }
},
token: {
signInResponseTokenPointer: '/token/authToken',
maxAgeInSeconds: 300, // 5 min
sameSiteAttribute: 'lax'
},
refreshToken: {
signInResponseRefreshTokenPointer: '/token/refreshToken',
maxAgeInSeconds: 604800, // 7 days
sameSiteAttribute: 'lax'
},
// TODO: define UserObject
//sessionDataType: UserObjectDefinition,
},
session: {
enableRefreshPeriodically: false,
enableRefreshOnWindowFocus: true,
},
globalAppMiddleware: true,
},
/*buildModules: [
//'@nuxtjs/composition-api/module',
['@pinia/nuxt', { disableVuex: false }],
],*/
devServer: {
https: {
key: './certs/privkey.pem',
@ -15,10 +59,24 @@ export default defineNuxtConfig({
server: {
cors: {
origin: true,
credentials: true,
optionsSuccessStatus: 204,
},
}
},
runtimeConfig: {
public: {
apiBase: `https://${clientsideConfig.url}:${clientsideConfig.port}/server/chunks/routes/api`,
axios: {
browserBaseURL: `https://${clientsideConfig.url}:${clientsideConfig.port}/`,
},
},
private: {
axios: {
baseURL: `https://${clientsideConfig.url}:${clientsideConfig.port}/`,
}
}
},
// hooks: {
// 'pages:extend'(pages) {
// function setMiddleware(pages: NuxtPage[]) {

4665
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,25 +7,37 @@
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
"prepare": "nuxt prepare",
"cleanup": "nuxt cleanup"
},
"devDependencies": {
"@nuxt/devtools": "latest",
"nuxt": "^3.8.0",
"@pinia/nuxt": "^0.5.1",
"@sidebase/nuxt-auth": "^0.6.7",
"nuxt": "^3.10.3",
"pinia": "^2.1.7",
"vue": "^3.3.7",
"vue-router": "^4.2.5"
},
"dependencies": {
"@nuxt/module-builder": "^0.5.5",
"@types/jsonwebtoken": "^9.0.6",
"@types/node": "^20.11.24",
"@vueform/toggle": "^2.1.4",
"axios": "^1.6.7",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"express": "^4.18.2",
"h3": "^1.11.1",
"jsonwebtoken": "^9.0.2",
"leading-trim": "^1.0.2",
"mariadb": "^3.2.3",
"nuxi": "^3.10.1",
"pinia-plugin-persistedstate": "^3.2.1",
"typescript": "^5.3.3",
"uuid": "^9.0.1",
"vite": "^5.1.0",
"vue-tsc": "^2.0.5",
"vuex": "^4.1.0"
}
}

View File

@ -1,12 +1,14 @@
<template>
<section id="content">
<div id="content-header">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Assets</h1>
<router-link to="/assets" class="button" id="assets-button" @click="defaultAssetPage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Assets</h1>
</router-link>
</div>
<div id="content-body">
<ClientSearch v-if="onAssetlist || onCustomerAssetlist" />
<CustomerSearch v-if="onAssetlist" />
<AssetTable v-if="onAssetlist" />
<AssetTableNoClient v-if="onCustomerAssetlist" />
<!-- <AssetTableNoCustomer v-if="onCustomerAssetlist" /> -->
<Asset v-if="onAsset" />
<HardwareSpecifications v-if="onAsset" />
<SoftwareSpecifications v-if="onAsset" />
@ -16,14 +18,14 @@
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import ClientSearch from "../components/ClientSearch.vue";
import CustomerSearch from "../components/CustomerSearch.vue";
import AssetTable from "../components/server/AssetTable.vue";
import AssetTableNoClient from "../components/server/AssetTableNoClient.vue";
// import AssetTableNoCustomer from "../components/server/AssetTableNoCustomer.vue";
import Asset from "../components/server/Asset.vue";
import HardwareSpecifications from "../components/server/HardwareSpecifications.vue";
import SoftwareSpecifications from "../components/server/SoftwareSpecifications.vue";
@ -35,14 +37,20 @@ import { computed } from 'vue';
const store = useStore();
const onAssetlist = computed(() => store.state.onAssetlist);
const onCustomerAssetlist = computed(() => store.state.onCustomerAssetlist);
// const onCustomerAssetlist = computed(() => store.state.onCustomerAssetlist);
const onAsset = computed(() => store.state.onAsset);
const onSolutionlistAsset = computed(() => store.state.onSolutionlistAsset);
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Assets'
})
const defaultAssetPage = () => {
store.commit('resetStore');
store.commit('changeToAssetlist')
}
const darkMode = ref(true)
</script>
@ -51,7 +59,7 @@ export default {
name: "AssetPage",
}
</script>
<style scoped>
* {
box-sizing: border-box;
@ -102,4 +110,8 @@ export default {
margin-bottom: 0.625rem;
border-radius: 0.625rem;
}
.button {
text-decoration: none;
}
</style>

View File

@ -1,36 +1,36 @@
<template>
<section id="content">
<div id="content-header">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Clients</h1>
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Customers</h1>
</div>
<div id="content-body">
<ClientTable v-if="onCustomerlist"/>
<Client v-if="onCustomer"/>
<ClientQuickAccess v-if="onCustomer"/>
<ClientEmployeeList v-if="onEmployeelist"/>
<ClientEmployee v-if="onEmployee"/>
<ClientDepartmentList v-if="onDepartmentlist"/>
<ClientDepartment v-if="onDepartment"/>
<ClientDepartmentEmployeeList v-if="onDepartment"/>
<CustomerTable v-if="onCustomerlist"/>
<Customer v-if="onCustomer"/>
<CustomerQuickAccess v-if="onCustomer"/>
<CustomerEmployeeList v-if="onEmployeelist"/>
<CustomerEmployee v-if="onEmployee"/>
<CustomerDepartmentList v-if="onDepartmentlist"/>
<CustomerDepartment v-if="onDepartment"/>
<CustomerDepartmentEmployeeList v-if="onDepartment"/>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import ClientTable from "../components/server/ClientTable.vue";
import Client from "../components/server/Client.vue";
import ClientQuickAccess from "../components/server/ClientQuickAccess.vue";
import ClientEmployeeList from "../components/server/ClientEmployeeList.vue";
import ClientEmployee from "../components/server/ClientEmployee.vue";
import ClientDepartmentList from '~/components/server/ClientDepartmentList.vue';
import ClientDepartment from '~/components/server/ClientDepartment.vue';
import ClientDepartmentEmployeeList from '~/components/server/ClientDepartmentEmployeeList.vue';
import CustomerTable from "../components/server/CustomerTable.vue";
import Customer from "../components/server/Customer.vue";
import CustomerQuickAccess from "../components/server/CustomerQuickAccess.vue";
import CustomerEmployeeList from "../components/server/CustomerEmployeeList.vue";
import CustomerEmployee from "../components/server/CustomerEmployee.vue";
import CustomerDepartmentList from '~/components/server/CustomerDepartmentList.vue';
import CustomerDepartment from '~/components/server/CustomerDepartment.vue';
import CustomerDepartmentEmployeeList from '~/components/server/CustomerDepartmentEmployeeList.vue';
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Customers'
})
const darkMode = ref(true)
@ -46,7 +46,7 @@ const onDepartment = ref(true)
<script>
export default {
name: "ClientsPage",
name: "CustomersPage",
}
</script>

View File

@ -20,7 +20,8 @@ import Dashboard from "../components/Dashboard.vue";
import QuickAccess from "../components/QuickAccess.vue";
definePageMeta({
layout: 'empty'
layout: 'empty',
title: 'Home'
})
const darkMode = ref(true)

View File

@ -14,7 +14,8 @@
import { ref } from 'vue';
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Test'
})
const darkMode = ref(true)

View File

@ -1,7 +1,7 @@
<template>
<section id="content">
<div id="content-header">
<router-link to="/issueSlips" class="button" id="issueSlips-button">
<router-link to="/issueSlips" class="button" id="issueSlips-button" @click="defaultIssueSlipPage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Issue slips</h1>
</router-link>
&nbsp;
@ -20,11 +20,12 @@
&nbsp;
&nbsp;
&nbsp;
<router-link to="/issues" class="button" id="issues-button">
<router-link to="/issueItems" class="button" id="issues-button" @click="defaultIssuePage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="active-page-name">Issues</h1>
</router-link>
</div>
<div id="content-body">
<IssueStateSearch v-if="onIssueItemList" />
<IssueTable v-if="onIssueItemList"/>
<Issue v-if="onIssueItem"/>
<IssueVariants v-if="onIssueItem"/>
@ -37,26 +38,40 @@
<script setup>
import { ref } from 'vue';
import IssueStateSearch from "../components/IssueStateSearch.vue";
import IssueTable from "../components/server/IssueTable.vue";
import Issue from "../components/server/Issue.vue";
import IssueVariants from "../components/server/IssueVariants.vue";
import IssueVariant from "../components/server/IssueVariant.vue";
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const onIssueItemList = computed(() => store.state.onIssueItemList);
const onIssueItem = computed(() => store.state.onIssueItem);
const onIssueItemVariant = computed(() => store.state.onIssueItemVariant);
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Issue Items'
})
const darkMode = ref(true)
// to render the right components
const onIssueItem = ref(false)
const onIssueItemList = ref(true)
const onIssueItemVariant = ref(false)
const defaultIssueSlipPage = () => {
store.commit('resetStore');
store.commit('changeToIssueSliplist')
}
const defaultIssuePage = () => {
store.commit('resetStore');
store.commit('changeToIssueItemList')
}
</script>
<script>
export default {
name: "IssuePage",
name: "IssueItemsPage",
}
</script>
@ -123,4 +138,4 @@ export default {
margin-bottom: 0.625rem;
border-radius: 0.625rem;
}
</style>
</style>../components/IssueStateSearch.vue

View File

@ -1,7 +1,7 @@
<template>
<section id="content">
<div id="content-header">
<router-link to="/issueSlips" class="button" id="issueSlips-button">
<router-link to="/issueSlips" class="button" id="issueSlips-button" @click="defaultIssueSlipPage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="active-page-name">Issue slips</h1>
</router-link>
&nbsp;
@ -20,52 +20,65 @@
&nbsp;
&nbsp;
&nbsp;
<router-link to="/issues" class="button" id="issues-button">
<router-link to="/issueItems" class="button" id="issues-button" @click="defaultIssuePage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Issues</h1>
</router-link>
</div>
<div id="content-body">
<ClientSearch v-if="onIssueSliplist || onCustomerIssueSliplist"/>
<IssueSlipTable v-if="onIssueSliplist"/>
<IssueSlipTableNoClient v-if="onCustomerIssueSliplist"/>
<IssueSlip v-if="onIssueSlip"/>
<OrderingInformation v-if="onIssueSlip"/>
<Accounting v-if="onIssueSlip"/>
<CustomerSearch v-if="onIssueSliplist" />
<IssueSlipTable v-if="onIssueSliplist" />
<!-- <IssueSlipTableNoCustomer v-if="onCustomerIssueSliplist" /> -->
<IssueSlip v-if="onIssueSlip" />
<OrderingInformation v-if="onIssueSlip" />
<Accounting v-if="onIssueSlip" />
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import ClientSearch from "../components/ClientSearch.vue";
import CustomerSearch from "../components/CustomerSearch.vue";
import IssueSlipTable from "../components/server/IssueSlipTable.vue";
import IssueSlipTableNoClient from "../components/server/IssueSlipTableNoClient.vue";
// import IssueSlipTableNoCustomer from "../components/server/IssueSlipTableNoCustomer.vue";
import IssueSlip from "../components/server/IssueSlip.vue";
import OrderingInformation from "../components/server/OrderingInformation.vue";
import Accounting from "../components/server/Accounting.vue";
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const onIssueSliplist = computed(() => store.state.onIssueSliplist);
// const onCustomerIssueSliplist = computed(() => store.state.onCustomerIssueSliplist);
const onIssueSlip = computed(() => store.state.onIssueSlip);
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Issue Slips'
})
const darkMode = ref(true)
// to render the right components
const onIssueSliplist = ref(true)
const onCustomerIssueSliplist = ref(false)
const onIssueSlip = ref(false)
const defaultIssueSlipPage = () => {
store.commit('resetStore');
store.commit('changeToIssueSliplist')
}
const defaultIssuePage = () => {
store.commit('resetStore');
store.commit('changeToIssueItemList')
}
</script>
<script>
export default {
name: "IssueSlipPage",
}
</script>
<style scoped>
* {
box-sizing: border-box;

View File

@ -16,7 +16,9 @@ import { ref } from 'vue';
import LoginForm from "../components/LoginForm.vue";
definePageMeta({
layout: 'empty'
layout: 'empty',
title: 'Login',
auth: false,
})
const darkMode = ref(true)

View File

@ -1,7 +1,8 @@
<template>
<section id="content">
<div id="content-header">
<router-link to="/maintenanceVisits" class="button" id="maintenanceVisits-button">
<router-link to="/maintenanceVisits" class="button" id="maintenanceVisits-button"
@click="defaultMasterChecklistPage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="active-page-name">Maintenance visits</h1>
</router-link>
&nbsp;
@ -20,20 +21,21 @@
&nbsp;
&nbsp;
&nbsp;
<router-link to="/productionOrders" class="button" id="productionOrders-button">
<router-link to="/productionOrders" class="button" id="productionOrders-button"
@click="defaultMasterChecklistPage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Production orders</h1>
</router-link>
</div>
<div id="content-body">
<ClientSearch v-if="onTemplatelist || onCustomerTemplatelist"/>
<MaintenanceVisitsTemplateTable v-if="onTemplatelist"/>
<MaintenanceVisitsTemplateTableNoClient v-if="onCustomerTemplatelist"/>
<MaintenanceVisitsTemplate v-if="onTemplate"/>
<TemplateChecklist v-if="onTemplate"/>
<TemplateSearch v-if="onInstancelist"/>
<MaintenanceVisitsInstanceTable v-if="onInstancelist"/>
<MaintenanceVisitsInstance v-if="onInstance"/>
<InstanceChecklist v-if="onInstance"/>
<CustomerSearch v-if="onTemplatelist" />
<MaintenanceVisitsTemplateTable v-if="onTemplatelist" />
<!-- <MaintenanceVisitsTemplateTableNoCustomer v-if="onCustomerTemplatelist" /> -->
<MaintenanceVisitsTemplate v-if="onTemplate" />
<TemplateChecklistMVT v-if="onTemplate" />
<TemplateSearch v-if="onInstancelist" />
<MaintenanceVisitsInstanceTable v-if="onInstancelist" />
<MaintenanceVisitsInstance v-if="onInstance" />
<InstanceChecklist v-if="onInstance" />
</div>
</section>
</template>
@ -42,28 +44,36 @@
<script setup>
import { ref } from 'vue';
import ClientSearch from "../components/ClientSearch.vue";
import CustomerSearch from "../components/CustomerSearch.vue";
import MaintenanceVisitsTemplateTable from "../components/server/MaintenanceVisitsTemplateTable.vue";
import MaintenanceVisitsTemplateTableNoClient from "../components/server/MaintenanceVisitsTemplateTableNoClient.vue";
// import MaintenanceVisitsTemplateTableNoCustomer from "../components/server/MaintenanceVisitsTemplateTableNoCustomer.vue";
import MaintenanceVisitsTemplate from "../components/server/MaintenanceVisitsTemplate.vue";
import TemplateChecklist from "../components/server/TemplateChecklist.vue";
import TemplateChecklistMVT from "../components/server/TemplateChecklistMVT.vue";
import TemplateSearch from "../components/TemplateSearch.vue";
import MaintenanceVisitsInstanceTable from "../components/server/MaintenanceVisitsInstanceTable.vue";
import MaintenanceVisitsInstance from "../components/server/MaintenanceVisitsInstance.vue";
import InstanceChecklist from "../components/server/InstanceChecklist.vue";
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const onTemplatelist = computed(() => store.state.onTemplatelist);
// const onCustomerTemplatelist = computed(() => store.state.onCustomerTemplatelist);
const onTemplate = computed(() => store.state.onTemplate);
const onInstancelist = computed(() => store.state.onInstancelist);
const onInstance = computed(() => store.state.onInstance);
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Maintenance Visits'
})
const darkMode = ref(true)
// to render the right components
const onTemplatelist = ref(true)
const onCustomerTemplatelist = ref(false)
const onTemplate = ref(false)
const onInstancelist = ref(false)
const onInstance = ref(false)
const defaultMasterChecklistPage = () => {
store.commit('resetStore');
store.commit('changeToTemplatelist')
}
</script>
<script>

View File

@ -1,7 +1,8 @@
<template>
<section id="content">
<div id="content-header">
<router-link to="/maintenanceVisits" class="button" id="maintenanceVisits-button">
<router-link to="/maintenanceVisits" class="button" id="maintenanceVisits-button"
@click="defaultMasterChecklistPage">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Maintenance visits</h1>
</router-link>
&nbsp;
@ -21,13 +22,14 @@
&nbsp;
&nbsp;
<router-link to="/productionOrders" class="button" id="productionOrders-button">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="active-page-name">Production orders</h1>
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="active-page-name"
@click="defaultMasterChecklistPage()">Production orders</h1>
</router-link>
</div>
<div id="content-body">
<ClientSearch v-if="onTemplatelist || onCustomerTemplatelist"/>
<CustomerSearch v-if="onTemplatelist"/>
<ProductionOrdersTemplateTable v-if="onTemplatelist"/>
<ProductionOrdersTemplateTableNoClient v-if="onCustomerTemplatelist"/>
<!-- <ProductionOrdersTemplateTableNoCustomer v-if="onCustomerTemplatelist"/> -->
<ProductionOrdersTemplate v-if="onTemplate"/>
<TemplateChecklist v-if="onTemplate"/>
<TemplateSearch v-if="onInstancelist"/>
@ -42,9 +44,9 @@
<script setup>
import { ref } from 'vue';
import ClientSearch from "../components/ClientSearch.vue";
import CustomerSearch from "../components/CustomerSearch.vue";
import ProductionOrdersTemplateTable from "../components/server/ProductionOrdersTemplateTable.vue";
import ProductionOrdersTemplateTableNoClient from "../components/server/ProductionOrdersTemplateTableNoClient.vue";
// import ProductionOrdersTemplateTableNoCustomer from "../components/server/ProductionOrdersTemplateTableNoCustomer.vue";
import ProductionOrdersTemplate from "../components/server/ProductionOrdersTemplate.vue";
import TemplateChecklist from "../components/server/TemplateChecklist.vue";
import TemplateSearch from "../components/TemplateSearch.vue";
@ -56,16 +58,22 @@ import { computed } from 'vue';
const store = useStore();
const onTemplatelist = computed(() => store.state.onTemplatelist);
const onCustomerTemplatelist = computed(() => store.state.onCustomerTemplatelist);
// const onCustomerTemplatelist = computed(() => store.state.onCustomerTemplatelist);
const onTemplate = computed(() => store.state.onTemplate);
const onInstancelist = computed(() => store.state.onInstancelist);
const onInstance = computed(() => store.state.onInstance);
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Production Orders'
})
const darkMode = ref(true)
const defaultMasterChecklistPage = () => {
store.commit('resetStore');
store.commit('changeToTemplatelist')
}
</script>
<script>

View File

@ -39,7 +39,8 @@ import UserAppearance from "../components/server/UserAppearance.vue";
import UserRightsList from "../components/server/UserRightsList.vue";
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Settings'
})
const darkMode = ref(true)

View File

@ -1,38 +1,47 @@
<template>
<section id="content">
<div id="content-header">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Solutions</h1>
<router-link to="/solutions" class="button" id="solutions-button" @click="defaultSolutionPage()">
<h1 :class="[darkMode ? 'h1-darkmode' : 'h1-lightmode']" id="page-name">Solutions</h1>
</router-link>
</div>
<div id="content-body">
<ClientSearch v-if="onSolutionlist || onCustomerSolutionlist"/>
<SolutionTable v-if="onSolutionlist"/>
<SolutionTableNoClient v-if="onCustomerSolutionlist"/>
<Solution v-if="onSolution"/>
<SolutionChecklist v-if="onSolution"/>
<CustomerSearch v-if="onSolutionlist" />
<SolutionTable v-if="onSolutionlist" />
<!-- <SolutionTableNoCustomer v-if="onCustomerSolutionlist" /> -->
<Solution v-if="onSolution" />
<SolutionChecklist v-if="onSolution" />
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import ClientSearch from "../components/ClientSearch.vue";
import CustomerSearch from "../components/CustomerSearch.vue";
import SolutionTable from "../components/server/SolutionTable.vue";
import SolutionTableNoClient from "../components/server/SolutionTableNoClient.vue";
// import SolutionTableNoCustomer from "../components/server/SolutionTableNoCustomer.vue";
import Solution from "../components/server/Solution.vue";
import SolutionChecklist from "../components/server/SolutionChecklist.vue";
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const onSolutionlist = computed(() => store.state.onSolutionlist);
// const onCustomerSolutionlist = computed(() => store.state.onCustomerSolutionlist);
const onSolution = computed(() => store.state.onSolution);
definePageMeta({
layout: 'default'
layout: 'default',
title: 'Solutions'
})
const darkMode = ref(true)
const defaultSolutionPage = () => {
store.commit('resetStore');
store.commit('changeToSolutionlist')
}
// to render the right components
const onSolutionlist = ref(true)
const onCustomerSolutionlist = ref(false)
const onSolution = ref(false)
const darkMode = ref(true)
</script>
<script>
@ -40,9 +49,9 @@ export default {
name: "AssetPage",
}
</script>
<style scoped>
* {
box-sizing: border-box;
@ -93,4 +102,8 @@ export default {
margin-bottom: 0.625rem;
border-radius: 0.625rem;
}
.button {
text-decoration: none;
}
</style>

0
pinia.js Normal file
View File

View File

@ -8,15 +8,28 @@ const store = createStore({
searchable: false,
deleteBool: false,
new: false,
clientChanged: false,
changedClientId: -1,
filteredByClient: '',
customerChanged: false,
changedCustomerId: -1,
filteredByCustomer: '',
addIcon: false,
addSolutionIcon: false,
solutionIcon: false,
addInstanceIcon: false,
filterIcon: false,
searchIcon: false,
instancesIcon: false,
attachmentsIcon: false,
sellIcon: false,
archiveIcon: false,
editIcon: false,
deleteIcon: false,
onAssetlist: true,
onCustomerAssetlist: false,
onAsset: false,
onSolutionlistAsset: false,
chosenAssetId: -1,
newAsset: false,
newAssetName: '',
newCustomerID: '',
newCustomer: '',
@ -41,10 +54,10 @@ const store = createStore({
newLicense: '',
onTemplatelist: true,
onCustomerTemplatelist: false,
onTemplate: false,
onInstancelist: false,
onInstance: false,
newNamePOT: '',
newCustomerIDPOT: '',
newCustomerPOT: '',
@ -54,6 +67,67 @@ const store = createStore({
newNotesPOT: '',
chosenPOTId: -1,
newNameMVT: '',
newCustomerIDMVT: '',
newCustomerMVT: '',
newLastViewMVT: '',
newUserMVT: '',
newTypeMVT: '',
newNotesMVT: '',
chosenMVTId: -1,
onSolutionlist: true,
onSolution: false,
chosenSolutionId: -1,
newSolutionNameSol: '',
newCustomerIDSol: '',
newCustomerSol: '',
newAssetNameSol: '',
newTypeSol: '',
newLastViewSol: '',
newUserSol: '',
newDescriptionSol: '',
newNotesSol: '',
onIssueSliplist: true,
onIssueSlip: false,
chosenIssueSlipId: -1,
newTicketNoIS: '',
newCustomerIdIS: '',
newCustomerIS: '',
newNotesIS: '',
newUserIS: '',
newDeliveryAddressIS: '',
newOIs: [],
newSupplierRequestDateIS: '',
newSupplierRequestIS: '',
newSupplierOfferDateIS: '',
newSupplierOfferIS: '',
newClientOfferDateIS: '',
newClientOfferIS: '',
newClientOrderDateIS: '',
newClientOrderIS: '',
newSupplierOrderDateIS: '',
newSupplierOrderIS: '',
newIngressDateIS: '',
newIngressIS: '',
newEgressDateIS: '',
newEgressIS: '',
newIngressBillDateIS: '',
newIngressBillIS: '',
newEgressBillDateIS: '',
newEgressBillIS: '',
onIssueItemList: true,
onIssueItem: false,
onIssueItemVariant: false,
chosenIssueId: -1,
newNameII: '',
newTypeII: '',
newStateII: '',
newAmountII: '',
newPropertiesII: '',
chosenIssueVariantId: -1,
};
},
mutations: {
@ -76,77 +150,340 @@ const store = createStore({
} else {
state.searchable = false
}
state.filteredByClient = ''
state.filteredByCustomer = ''
},
toggleClientChanged(state) {
state.clientChanged = !state.clientChanged
toggleCustomerChanged(state) {
state.customerChanged = !state.customerChanged
},
toggleClientId(state, id) {
state.changedClientId = id
toggleCustomerId(state, id) {
state.changedCustomerId = id
},
refresh() {
//
},
// functions to change the asset pages
changeToAssetlist(state) {
state.onAssetlist = true
state.onCustomerAssetlist = false
state.onAsset = false
state.onSolutionlistAsset = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToCustomerAssetlist(state) {
state.onAssetlist = false
state.onCustomerAssetlist = true
state.onAsset = false
state.onSolutionlistAsset = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToAsset(state) {
state.onAssetlist = false
state.onCustomerAssetlist = false
state.onAsset = true
state.onSolutionlistAsset = false
state.addIcon = false
state.addSolutionIcon = false
state.solutionIcon = true
state.addInstanceIcon = false
state.filterIcon = false
state.searchIcon = false
state.instancesIcon = false
state.attachmentsIcon = true
state.sellIcon = false
state.archiveIcon = false
state.editIcon = true
state.deleteIcon = true
},
changeToSolutionlistAsset(state) {
state.onAssetlist = false
state.onCustomerAssetlist = false
state.onAsset = false
state.onSolutionlistAsset = true
state.addIcon = false
state.addSolutionIcon = true
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
// functions to change the production order pages
// functions to change the production order and maintenance visit pages
changeToTemplatelist(state) {
state.onTemplatelist = true
state.onCustomerTemplatelist = false
state.onTemplate = false
state.onInstancelist = false
state.onInstance = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToCustomerTemplatelist(state) {
state.onTemplatelist = false
state.onCustomerTemplatelist = true
state.onTemplate = false
state.onInstancelist = false
state.onInstance = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToTemplate(state) {
state.onTemplatelist = false
state.onCustomerTemplatelist = false
state.onTemplate = true
state.onInstancelist = false
state.onInstance = false
state.addIcon = false
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = true
state.filterIcon = false
state.searchIcon = false
state.instancesIcon = true
state.attachmentsIcon = true
state.sellIcon = false
state.archiveIcon = false
state.editIcon = true
state.deleteIcon = true
},
changeToInstancelist(state) {
state.onTemplatelist = false
state.onCustomerTemplatelist = false
state.onTemplate = false
state.onInstancelist = true
state.onInstance = false
state.addIcon = false
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = true
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToInstance(state) {
state.onTemplatelist = false
state.onCustomerTemplatelist = false
state.onTemplate = false
state.onInstancelist = false
state.onInstance = true
addNewAsset(state) {
state.newAsset = true
state.editable = false
state.filtered = false
state.searchable = false
state.onAssetlist = false
state.onAsset = true
state.onSolutionlistAsset = false
},
// functions to change the solution pages
changeToSolutionlist(state) {
state.onSolutionlist = true
state.onSolution = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToCustomerSolutionlist(state) {
state.onSolutionlist = false
state.onSolution = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToSolution(state) {
state.onSolutionlist = false
state.onSolution = true
state.addIcon = false
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = false
state.searchIcon = false
state.instancesIcon = false
state.attachmentsIcon = true
state.sellIcon = false
state.archiveIcon = false
state.editIcon = true
state.deleteIcon = true
},
// functions to change the issue slip pages
changeToIssueSliplist(state) {
state.onIssueSliplist = true
state.onIssueSlip = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToCustomerIssueSliplist(state) {
state.onIssueSliplist = false
state.onIssueSlip = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToIssueSlip(state) {
state.onIssueSliplist = false
state.onIssueSlip = true
state.addIcon = false
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = false
state.searchIcon = false
state.instancesIcon = false
state.attachmentsIcon = true
state.sellIcon = false
state.archiveIcon = false
state.editIcon = true
state.deleteIcon = true
},
// functions to change the issue pages
changeToIssueItemList(state) {
state.onIssueItemList = true
state.onIssueItem = false
state.onIssueItemVariant = false
state.addIcon = true
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = false
state.editIcon = false
state.deleteIcon = false
},
changeToIssueItem(state) {
state.onIssueItemList = false
state.onIssueItem = true
state.onIssueItemVariant = false
state.addIcon = false
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = true
state.searchIcon = true
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = false
state.archiveIcon = true
state.editIcon = true
state.deleteIcon = true
},
changeToIssueItemVariant(state) {
state.onIssueItemList = false
state.onIssueItem = false
state.onIssueItemVariant = true
state.addIcon = false
state.addSolutionIcon = false
state.solutionIcon = false
state.addInstanceIcon = false
state.filterIcon = false
state.searchIcon = false
state.instancesIcon = false
state.attachmentsIcon = false
state.sellIcon = true
state.archiveIcon = true
state.editIcon = true
state.deleteIcon = true
},
// functions to update the asset
@ -187,6 +524,75 @@ const store = createStore({
state.newNotesPOT = pot.notes
},
// functions to update the maintenance visit template
updateMaintenanceVisitTemplateComponent(state, mvt) {
state.newNameMVT = mvt.name
state.newCustomerIDMVT = mvt.customerId
state.newCustomerMVT = mvt.customer
state.newUserMVT = mvt.user
state.newTypeMVT = mvt.type
state.newNotesMVT = mvt.notes
},
// functions to update the solution
updateSolutionComponent(state, sol) {
state.newSolutionNameSol = sol.solutionName
state.newCustomerIDSol = sol.customerId
state.newCustomerSol = sol.customer
state.newAssetNameSol = sol.assetName
state.newLastViewSol = sol.lastView
state.newTypeSol = sol.type
state.newDescriptionSol = sol.description
state.newNotesSol = sol.notes
state.newUserSol = sol.user
},
// functions to update the issue slip component
updateIssueSlipComponent(state, is) {
state.newTicketNoIS = is.ticketNo
state.newCustomerIdIS = is.customerId
state.newCustomerIS = is.customer
state.newNotesIS = is.notes
state.newUserIS = is.user
state.newDeliveryAddressIS = is.deliveryAddress
},
// functions to update the accounting info component
updateOrderingInfoComponent(state, o) {
state.newOIs = o.ois
},
// functions to update the accounting component
updateAccountingComponent(state, is) {
state.newSupplierRequestDateIS = is.supplierRequestDate
state.newSupplierRequestIS = is.supplierRequest
state.newSupplierOfferDateIS = is.supplierOfferDate
state.newSupplierOfferIS = is.supplierOffer
state.newClientOfferDateIS = is.clientOfferDate
state.newClientOfferIS = is.clientOffer
state.newClientOrderDateIS = is.clientOrderDate
state.newClientOrderIS = is.clientOrder
state.newSupplierOrderDateIS = is.supplierOrderDate
state.newSupplierOrderIS = is.supplierOrder
state.newIngressDateIS = is.ingressDate
state.newIngressIS = is.ingress
state.newEgressDateIS = is.egressDate
state.newEgressIS = is.egress
state.newIngressBillDateIS = is.ingressBillDate
state.newIngressBillIS = is.ingressBill
state.newEgressBillDateIS = is.egressBillDate
state.newEgressBillIS = is.egressBill
},
// functions to update the issue component
updateIssueComponent(state, is) {
state.newNameII = is.name
state.newTypeII = is.type
state.newStateII = is.state
state.newAmountII = is.amount
state.newPropertiesII = is.properties
},
// function to set the chosen asset
setChosenAsset(state, id) {
state.chosenAssetId = id
@ -197,6 +603,31 @@ const store = createStore({
state.chosenPOTId = id
},
// function to set the chosen maintenance visit template
setChosenMVT(state, id) {
state.chosenMVTId = id
},
// function to set the chosen solution
setChosenSolution(state, id) {
state.chosenSolutionId = id
},
// function to set the chosen issue slip
setChosenIssueSlip(state, id) {
state.chosenIssueSlipId = id
},
// function to set the chosen issue
setChosenIssue(state, id) {
state.chosenIssueId = id
},
// function to set the chosen issue variant
setChosenIssueVariant(state, id) {
state.chosenIssueVariantId = id
},
// function to reset the pages
resetStore(state) {
state.editable = false
@ -204,10 +635,10 @@ const store = createStore({
state.searchable = false
state.deleteBool = false
state.chosenAssetId = -1
state.filteredByClient = ''
state.filteredByCustomer = ''
state.new = false
state.clientChanged = false
state.changedClientId = -1
state.customerChanged = false
state.changedCustomerId = -1
// reset the asset page variables
state.newAssetName = ''
@ -237,10 +668,70 @@ const store = createStore({
state.newNamePOT = ''
state.newCustomerIDPOT = ''
state.newCustomerPOT = ''
state.newUserPOT = false
state.newUserPOT = ''
state.newDescriptionPOT = ''
state.newNotesPOT = ''
state.newLastViewPOT = ''
state.chosenPOTId = -1
// reset the maintenance visit template page variables
state.newNameMVT = ''
state.newCustomerIDMVT = ''
state.newCustomerMVT = ''
state.newUserMVT = ''
state.newTypeMVT = ''
state.newNotesMVT = ''
state.newLastViewMVT = ''
state.chosenMVTId = -1
// reset the solution page variables
state.newSolutionNameSol = ''
state.newCustomerIDSol = ''
state.newCustomerSol = ''
state.newAssetNameSol = ''
state.newLastViewSol = ''
state.newTypeSol = ''
state.newDescriptionSol = ''
state.newNotesSol = ''
state.newUserSol = ''
state.chosenSolutionId = -1
// reset the issue slip page variables
state.chosenIssueSlipId = -1
state.newCustomerIdIS = ''
state.newCustomerIS = ''
state.newTicketNoIS = ''
state.newNotesIS = ''
state.newUserIS = ''
state.newOIs = []
state.newDeliveryAddressIS = ''
state.newSupplierRequestIS = ''
state.newSupplierOfferIS = ''
state.newClientOfferIS = ''
state.newClientOrderIS = ''
state.newSupplierOrderIS = ''
state.newIngressIS = ''
state.newEgressIS = ''
state.newIngressBillIS = ''
state.newEgressBillIS = ''
state.newSupplierRequestDateIS = ''
state.newSupplierOfferDateIS = ''
state.newClientOfferDateIS = ''
state.newClientOrderDateIS = ''
state.newSupplierOrderDateIS = ''
state.newIngressDateIS = ''
state.newEgressDateIS = ''
state.newIngressBillDateIS = ''
state.newEgressBillDateIS = ''
// reset the issue page variables
state.chosenIssueId = -1
state.chosenIssueVariantId = -1
state.newNameII = ''
state.newTypeII = ''
state.newStateII = ''
state.newAmountII = ''
state.newPropertiesII = ''
},
// functions to (undo) delete an asset
@ -252,8 +743,8 @@ const store = createStore({
},
// function to update the asset filter
updateFilterbyClient(state, client) {
state.filteredByClient = client
updateFilterbyCustomer(state, customer) {
state.filteredByCustomer = customer
},
// function to get to the add page
@ -265,18 +756,28 @@ const store = createStore({
// set the asset variables
state.onAssetlist = false
state.onCustomerAssetlist = false
state.onAsset = true
state.onSolutionlistAsset = false
// set the production order variables
// set the production order and maintenance visit variables
state.onTemplatelist = false
state.onCustomerTemplatelist = false
state.onTemplate = true
state.onInstancelist = false
state.onInstance = false
},
// set the solution variables
state.onSolutionlist = false
state.onSolution = true
// set the issue slips variables
state.onIssueSliplist = false
state.onIssueSlip = true
// set the issue variables
state.onIssueItemList = false
state.onIssueItemVariant = false
state.onIssueItem = true
},
},
});

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="11" fill="none" viewBox="0 0 12 11">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M5 7v2c0 .6-.4 1-1 1H2a1 1 0 0 1-1-1V7c0-.6.4-1 1-1h2c.6 0 1 .4 1 1Zm3-5v2c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1V2c0-.6.4-1 1-1h2c.6 0 1 .4 1 1Zm3 5v2c0 .6-.4 1-1 1H8a1 1 0 0 1-1-1V7c0-.6.4-1 1-1h2c.6 0 1 .4 1 1Zm-8 .5V6m3-3.5V1m3 6.5V6"/>
</svg>

After

Width:  |  Height:  |  Size: 415 B

View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="11" fill="none" viewBox="0 0 12 11">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="0.75" d="M7.5 5.5v-.3a1.7 1.7 0 1 1 3.5 0v.3"/>
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="0.75" d="M9.3 3.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM6 2.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm-5 3v-.3a1.7 1.7 0 1 1 3.5 0v.3"/>
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="0.75" d="M2.8 3.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"/>
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M3 9.9v-.5a3 3 0 1 1 6 0v.5"/>
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M6 6.4A1.7 1.7 0 1 0 6 3a1.7 1.7 0 0 0 0 3.4Z"/>
</svg>

After

Width:  |  Height:  |  Size: 831 B

View File

Before

Width:  |  Height:  |  Size: 506 B

After

Width:  |  Height:  |  Size: 506 B

View File

@ -1,6 +1,6 @@
// import { createRouter, createWebHistory } from 'vue-router';
// import HomePage from '../pages/home.vue';
// import ClientsPage from '../pages/clients.vue';
// import CustomersPage from '../pages/customers.vue';
// import LoginPage from '../pages/login.vue';
// import AssetPage from '../pages/assets.vue';
// import SolutionPage from '../pages/solutions.vue';
@ -52,8 +52,8 @@
// component: IssuesPages
// },
// {
// path: '/clients',
// component: ClientsPage
// path: '/customers',
// component: CustomersPage
// },
// {
// path: '/settings',

View File

@ -7,6 +7,7 @@ export default defineEventHandler(async (event) => {
'Access-Control-Allow-Origin': 'https://tueitapp.tueit.de',
'Access-Control-Allow-Headers': 'authorization, content-type',
'Access-Control-Allow-Methods': 'OPTIONS,GET,HEAD,PUT,PATCH,POST,DELETE',
'Access-Control-Allow-Credentials': 'true',
};
setResponseHeaders(event, headers)

23
server/api/addII.ts Normal file
View File

@ -0,0 +1,23 @@
import { insertId, errorMsg } from "../middleware/issues";
import { OutgoingMessage } from 'http';
export default defineEventHandler(async (event) => {
const headers: Record<string, Parameters<OutgoingMessage['setHeader']>[1]> = {
'Access-Control-Allow-Origin': 'https://tueitapp.tueit.de',
'Access-Control-Allow-Headers': 'authorization, content-type',
'Access-Control-Allow-Methods': 'OPTIONS,GET,HEAD,PUT,PATCH,POST,DELETE',
'Access-Control-Allow-Credentials': 'true',
};
setResponseHeaders(event, headers)
if (!(errorMsg === '')) {
throw createError({
statusCode: 400,
statusMessage: errorMsg,
})
}
setResponseStatus(event, 200)
return insertId
})

View File

@ -0,0 +1,23 @@
import { insertId, errorMsg } from "../middleware/issueSlips";
import { OutgoingMessage } from 'http';
export default defineEventHandler(async (event) => {
const headers: Record<string, Parameters<OutgoingMessage['setHeader']>[1]> = {
'Access-Control-Allow-Origin': 'https://tueitapp.tueit.de',
'Access-Control-Allow-Headers': 'authorization, content-type',
'Access-Control-Allow-Methods': 'OPTIONS,GET,HEAD,PUT,PATCH,POST,DELETE',
'Access-Control-Allow-Credentials': 'true',
};
setResponseHeaders(event, headers)
if (!(errorMsg === '')) {
throw createError({
statusCode: 400,
statusMessage: errorMsg,
})
}
setResponseStatus(event, 200)
return insertId
})

View File

@ -0,0 +1,22 @@
import { errorMsg } from "../middleware/issues";
import { OutgoingMessage } from 'http';
export default defineEventHandler(async (event) => {
const headers: Record<string, Parameters<OutgoingMessage['setHeader']>[1]> = {
'Access-Control-Allow-Origin': 'https://tueitapp.tueit.de',
'Access-Control-Allow-Headers': 'authorization, content-type',
'Access-Control-Allow-Methods': 'OPTIONS,GET,HEAD,PUT,PATCH,POST,DELETE',
'Access-Control-Allow-Credentials': 'true',
};
setResponseHeaders(event, headers)
if (!(errorMsg === '')) {
throw createError({
statusCode: 400,
statusMessage: errorMsg,
})
}
setResponseStatus(event, 200)
})

Some files were not shown because too many files have changed in this diff Show More