64 Commits

Author SHA1 Message Date
a04cb4f333 Merge pull request 'finished customer pages' (#26) from clientPages into main
Reviewed-on: jo.kuehner/TueIT_App#26
2024-04-07 12:14:55 +00:00
a02cbbb187 finished customer pages 2024-04-07 14:14:02 +02:00
d0b867404e Merge pull request 'instances' (#25) from MVAndPO into main
Reviewed-on: jo.kuehner/TueIT_App#25
2024-04-02 12:54:50 +00:00
aaa3bba79f fixed small bugs and made comment fields bigger 2024-04-02 14:53:14 +02:00
423ff7e48b implemented poi and mvi 2024-04-01 18:37:15 +02:00
3c063fddca implemented instance lists and pot, todos still missing 2024-03-28 23:10:29 +01:00
979768e52e Merge pull request 'user page' (#24) from userPage into main 2024-03-26 21:55:15 +00:00
944b7d0503 implemented rights and fixed some appearance bugs 2024-03-26 22:54:13 +01:00
3f88f6b821 implemented mode change 2024-03-25 23:23:37 +01:00
45a4b58f26 implemented settings and user page (darkmode is still missing) 2024-03-24 21:02:56 +01:00
acb7bb7cb6 implemented userTable 2024-03-15 21:04:53 +01:00
8b237e8080 Merge pull request 'modularActionbar' (#23) from modularActionbar into main
Reviewed-on: jo.kuehner/TueIT_App#23
2024-03-15 19:05:31 +00:00
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
fcc6517110 added pot todos functionality 2024-02-28 14:48:18 +01:00
601449d7e0 added page titles and icon 2024-02-27 16:53:28 +01:00
c327355c8a basic functionality pot implemented 2024-02-27 10:31:03 +01:00
3a79ed12fa fixed padding 2024-02-26 12:57:56 +01:00
84c17ad855 Merge branch 'addConfigitem' 2024-02-26 12:36:30 +01:00
49fb1ef397 add config item 2024-02-26 12:31:58 +01:00
e4aa11b902 smoothed out navbar slide (unfinished) 2024-02-23 21:58:32 +01:00
8a77f18237 Merge branch 'main' of https://git.tueit.de/jo.kuehner/TueIT_App into main 2024-02-23 17:54:09 +01:00
e5a67b7e14 added client employee and department pages 2024-02-23 17:17:58 +01:00
13096ce679 Merge pull request 'communication from client to nuxt server' (#16) from loginFunctionality into main
Reviewed-on: jo.kuehner/TueIT_App#16

es funktioniert jetzt wie folgt:
- vom entsprechenden component wird eine axios Anfrage an den api Server Endpunkt geschickt
- parallel greift die passende server middleware ein und diese macht den call ins backend
- daraufhin übermittelt die server middleware die Antwort an den api Endpunkt. Dieser schickt dann eine Antwort zurück an den Component, wo dann die Antwort dem client übermittelt wird

was ich schon alles gemacht habe:
- cors Fehler behoben mit entsprechender Konfig und headern
- login (noch nicht initial dorthin geroutet)
- signup aber nur hardgecoded mit einem Beispieluser, da ich einen brauchte fürs Login
- get all Funktionen für die Tabellen aller Seiten (customer existiert schon aber ist noch nicht in die customer Seite eingebunden)
- bin gerade bei CI. hier funktioniert schon ein einziges Item getten, updaten und löschen. Als nächstes mache ich noch die Erstellung eines neuen CI. Du kannst dich daran orientieren.
2024-02-22 16:03:15 +00:00
8c18d80737 added login and sign Funtion properly 2024-02-22 16:43:08 +01:00
4b193ac5a1 implemented delete configitem 2024-02-21 10:45:53 +01:00
6ebad13a03 added all changed files from the server 2024-02-19 18:03:10 +00:00
0d37ba8c21 fixed preflight requests 2024-02-19 17:59:02 +00:00
3e87b2daa0 preflight cors header 2024-02-18 13:40:54 +01:00
2e1d3f7026 added update config items functionality 2024-02-18 12:04:14 +01:00
5242d4a3af fixed backend imports 2024-02-16 19:00:30 +01:00
5ca56d36cf false import 2024-02-16 17:36:24 +01:00
03e4164b97 changed all urls 2024-02-16 17:35:00 +01:00
fb59fb756e made server connections work 2024-02-16 16:15:04 +00:00
e18c605c8c addded single asset 2024-02-16 15:53:27 +01:00
e900ff4777 forgot to add new plugin 2024-02-14 09:39:35 +01:00
2ced6f82d1 fixed cors headers 2024-02-14 09:36:49 +01:00
8d05df01e9 added cors header for the nuxt server responses 2024-02-09 17:32:50 +01:00
c91f9a53b6 added get functions 2024-02-08 13:12:01 +01:00
73d0b89b4d implemented connection to the backend 2024-02-06 17:18:37 +01:00
876d066f3d Merge branch 'loginFunctionality' of https://git.tueit.de/jo.kuehner/TueIT_App into loginFunctionality 2024-02-06 17:16:27 +01:00
c5fbb12dfd tried it with axios 2024-02-02 11:02:34 +01:00
2a4dc80efa communication from client to nuxt server 2024-02-02 11:02:34 +01:00
bc1a80b53e Merge pull request 'added backend implementation' (#17) from backend into main
Reviewed-on: jo.kuehner/TueIT_App#17
2024-02-02 09:56:59 +00:00
0c589e3ae0 tried it with axios 2024-01-26 18:25:46 +01:00
772ffb2db5 communication from client to nuxt server 2024-01-22 19:43:20 +01:00
293 changed files with 45651 additions and 6210 deletions

View File

@ -22,11 +22,11 @@ bun install
## Development Server
Start the development server on `http://localhost:3000`:
Start the development server on `https://localhost:3000`:
```bash
# npm
npm run dev
npm run dev -- --host 0.0.0.0
# pnpm
pnpm run dev

37
app.vue
View File

@ -7,24 +7,41 @@
<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>
<style>
html, template, body, #__nuxt, #__layout {
height: 100vh;
width: 100vw;
height: 100%;
width: 100%;
margin: 0;
background-color: #212121;
font-size: 1rem;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, template, body, #__nuxt, #__layout {
min-height: 100vh;
width: 100vw;
min-height: 100%;
width: 100%;
background-color: #212121;
font-size: 1rem;
}
</style>

30
axios.config.js Normal file
View File

@ -0,0 +1,30 @@
import axios, {AxiosError} from 'axios';
import clientsideConfig from './clientsideConfig'
//create axios instance
const Axios = axios.create({
//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

@ -0,0 +1,89 @@
import {
getDepartmentById,
getDepartmentsByCustomerId,
updateDepartmentById,
insertDepartment,
getSelectedDepartmentsByName,
deleteDepartmentById,
getDepartmentByName
} from "../models/departmentsModel.js";
//get single department by id
export const showDepartmentById = (req, res) => {
getDepartmentById(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get single department by name
export const showDepartmentByName = (req, res) => {
getDepartmentByName(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get departments by customer id
export const showDepartmentByCustomerId = (req, res) => {
getDepartmentsByCustomerId(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Update department
export const updateDepartment = (req, res) => {
const data = req.body;
updateDepartmentById(data, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//create new department
export const createDepartment = (req, res) => {
const data = req.body;
insertDepartment(data, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected departments by name
export const showSelectedDepartmentsByName = (req, res) => {
getSelectedDepartmentsByName(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Delete department
export const deleteDepartment = (req, res) => {
const id = req.params.id;
deleteDepartmentById(id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};

View File

@ -0,0 +1,101 @@
import {
getEmployeeById,
getEmployeesByCustomerId,
updateEmployeeById,
insertEmployee,
getSelectedEmployeesByName,
deleteEmployeeById,
getSelectedEmployeesByDepartment,
getSelectedEmployeesByDepartmentName,
} from "../models/employeesModel.js";
//get single employee by id
export const showEmployeeById = (req, res) => {
getEmployeeById(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get employees by customer id
export const showEmployeeByCustomerId = (req, res) => {
getEmployeesByCustomerId(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get employees by customer id
export const showEmployeeByDepartmentId = (req, res) => {
getSelectedEmployeesByDepartment(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Update employee
export const updateEmployee = (req, res) => {
const data = req.body;
updateEmployeeById(data, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//create new employee
export const createEmployee = (req, res) => {
const data = req.body;
insertEmployee(data, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected employees by name
export const showSelectedEmployeesByName = (req, res) => {
getSelectedEmployeesByName(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected employees by name
export const showSelectedEmployeesByDepartmentName = (req, res) => {
getSelectedEmployeesByDepartmentName(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Delete employee
export const deleteEmployee = (req, res) => {
const id = req.params.id;
deleteEmployeeById(id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};

View File

@ -8,7 +8,7 @@ import {
deleteIssueVariantById,
deleteIssueVariantByIssueSlipId,
insertIssueVariant,
} from "../models/issuesModel.js";
} from "../models/issueVariantsModel.js";
//get all issue variants
export const showIssueVariants = (req, res) => {

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

@ -5,6 +5,8 @@ import {
getMaintenanceVisitTodosByAsset,
updateMaintenanceVisitTodoById,
deleteMaintenanceVisitTodosByPrimaryID,
deleteMaintenanceVisitTodosByTemplateID,
getMaintenanceVisitTodosByTemplate,
} from "../models/maintenanceVisitsTodosModel.js";
//create new maintenance visit todo
@ -41,6 +43,17 @@ export const showMaintenanceVisitTodosByAsset = (req, res) => {
});
};
//get maintenance visit todos by assetname
export const showMaintenanceVisitTodosByTemplateId = (req, res) => {
getMaintenanceVisitTodosByTemplate(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Update maintenance visit todo
export const updateMaintenanceVisitTodo = (req, res) => {
const data = req.body;
@ -63,4 +76,16 @@ export const deleteMaintenanceVisitTodos = (req, res) => {
res.json(results);
}
});
};
// Delete maintenance visit todos by template id
export const deleteMaintenanceVisitTodosBytemplateId = (req, res) => {
const id = req.params.id;
deleteMaintenanceVisitTodosByTemplateID(id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};

View File

@ -9,7 +9,9 @@ import {
insertMaintenanceVisit,
getMaintenanceVisitByName,
getMaintenanceVisitById,
updateMaintenanceVisitStateById,
updateMaintenanceVisitById,
getSelectedMaintenanceVisitsByUser,
getSelectedMaintenanceVisitsByTemplate,
} from "../models/maintenanceVisitsModel.js";
//get all maintenance visits
@ -34,6 +36,28 @@ export const showSelectedMaintenanceVisitsByChecklistname = (req, res) => {
});
};
//get all selected maintenance visits by user
export const showSelectedMaintenanceVisitsByUser = (req, res) => {
getSelectedMaintenanceVisitsByUser(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected maintenance visits by template
export const showSelectedMaintenanceVisitsByTemplate = (req, res) => {
getSelectedMaintenanceVisitsByTemplate(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected maintenance visits by customer
export const showSelectedMaintenanceVisitsByCustomer = (req, res) => {
getSelectedMaintenanceVisitsByCustomer(req.params.id, (err, results) => {
@ -114,9 +138,9 @@ export const showMaintenanceVisitById = (req, res) => {
};
// Update maintenance visit
export const updateMaintenanceVisitState = (req, res) => {
export const updateMaintenanceVisit = (req, res) => {
const data = req.body;
updateMaintenanceVisitStateById(data, (err, results) => {
updateMaintenanceVisitById(data, (err, results) => {
if (err) {
res.send(err);
} else {

View File

@ -5,6 +5,7 @@ import {
getProductionOrderTodosByAsset,
updateProductionOrderTodoById,
deleteProductionOrderTodosChecklistID,
getProductionOrderTodosByTemplate,
} from "../models/productionOrdersTodosModel.js";
//create new production order todo
@ -41,6 +42,18 @@ export const showProductionOrderTodosByAsset = (req, res) => {
});
};
//get production order todos by template
export const showProductionOrderTodosByTemplate = (req, res) => {
getProductionOrderTodosByTemplate(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Update production order todo
export const updateProductionOrderTodo = (req, res) => {
const data = req.body;

View File

@ -10,7 +10,9 @@ import {
getProductionOrderByName,
deleteProductionOrderById,
getProductionOrderById,
updateProductionOrderStateById,
updateProductionOrderById,
getSelectedProductionOrdersByTemplate,
getSelectedProductionOrdersByUser,
} from "../models/productionOrdersModel.js";
//get all production orders
@ -46,6 +48,28 @@ export const showSelectedProductionOrdersByCustomer = (req, res) => {
});
};
//get all selected production orders by user
export const showSelectedProductionOrdersByUser = (req, res) => {
getSelectedProductionOrdersByUser(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected production orders by template
export const showSelectedProductionOrdersByTemplate = (req, res) => {
getSelectedProductionOrdersByTemplate(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
//get all selected production orders by ticketnumber
export const showSelectedProductionOrdersByTicketnumber = (req, res) => {
getSelectedProductionOrdersByTicketnumber(req.params.id, (err, results) => {
@ -126,9 +150,9 @@ export const showProductionOrderById = (req, res) => {
};
// Update production order
export const updateProductionOrderState = (req, res) => {
export const updateProductionOrder = (req, res) => {
const data = req.body;
updateProductionOrderStateById(data, (err, results) => {
updateProductionOrderById(data, (err, results) => {
if (err) {
res.send(err);
} else {

View File

@ -10,13 +10,15 @@ import {
getUserById,
updateUserById,
deleteUserById,
getSelectedUsersByUser,
} from "../models/usersModel.js";
//insert user to databased
export const signUp = async (req, res, next) => {
try {
let sql = `SELECT id FROM users WHERE LOWER(username) = LOWER(?)`;
let sql = `SELECT id FROM users WHERE LOWER(username) = LOWER(?)`;
const result = await ownConn.execute(sql, [req.body.username])
if (result.length > 0) { //username already exists
return res.status(409).send({
message: 'This username is already in use!'
@ -39,7 +41,7 @@ export const signUp = async (req, res, next) => {
minute: '2-digit'
};
const dateTimeString = currentTime.toLocaleString('de-DE', options);
const results = ownConn.query(`INSERT INTO users(id, username, password, registered, fullName, email, phonenumber, address, city, postcode, adminBool, technician1Bool, technician2Bool, technicianMonitoringBool, merchantBool, internBool) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
const results = ownConn.query(`INSERT INTO users(id, username, password, registered, fullName, email, phonenumber, address, city, postcode, adminBool, technicianBool, readerBool, darkModeBool) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
uuidv4(),
req.body.username,
@ -52,11 +54,9 @@ export const signUp = async (req, res, next) => {
req.body.city,
req.body.postcode,
req.body.adminBool,
req.body.technician1Bool,
req.body.technician2Bool,
req.body.technicianMonitoringBool,
req.body.merchantBool,
req.body.internBool,
req.body.technicianBool,
req.body.readerBool,
req.body.darkModeBool,
]);
return res.status(201).send({
message: "Registered!",
@ -72,6 +72,32 @@ export const signUp = async (req, res, next) => {
}
};
// Update user password to Database
export const updatePasswordById = async (req, res, next) => {
try {
const id = req.body.id;
let sql = `UPDATE users SET password = ? WHERE id = ?`;
bcrypt.hash(req.body.password, 10, async (err, hash) => {
if (err) {
throw err;
return res.status(500).send({
message: err,
});
} else {
const results = await ownConn.query(sql, [hash, id]);
return res.status(200).send({
message: 'Password changed!',
});
}
});
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
export const login = async (req, res, next) => {
try {
let sql = `SELECT * FROM users WHERE username = ?`;
@ -92,7 +118,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,
@ -114,7 +148,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],
});
}
@ -152,6 +186,18 @@ export const showUserById = (req, res) => {
});
};
//get all selected users by user
export const showSelectedUsersByUser = (req, res) => {
getSelectedUsersByUser(req.params.id, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
};
// Update user
export const updateUser = (req, res) => {
const data = req.body;

View File

@ -15,12 +15,14 @@ import fs from "fs";
//import routes
import Router from "./routes/routes.js";
import clientsideConfig from '../clientsideConfig.js';
//init express
const app = express();
//setup cors
const corsOptions = {
origin: 'https://localhost:4173',
origin: `https://${clientsideConfig.url}:${clientsideConfig.port}`,
headers: 'authorization, content-type',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true,
@ -37,18 +39,18 @@ app.use(express.json());
app.use(Router);
//setup https
var privateKey = fs.readFileSync('../certs/localhost.key');
var certificate = fs.readFileSync('../certs/localhost.crt');
var privateKey = fs.readFileSync('../certs/privkey.pem');
var certificate = fs.readFileSync('../certs/fullchain.pem');
var server = https.createServer({
key: privateKey,
cert: certificate
cert: certificate,
}, app);
// const PORT = process.env.PORT || 5172;
const PORT = process.env.PORT || config.port;
// const PORT = process.env.PORT || 4172;
const PORT = process.env.PORT || serversideConfig.port;
//PORT
server.listen(PORT, () => {
console.log(`Server running successfully (port ${PORT})`);
});
});

View File

@ -38,10 +38,7 @@ export const validateRegister = (req, res, next) => {
});
}
// password (repeat) must match
if (
!req.body.password_repeat ||
req.body.password != req.body.password_repeat
) {
if (req.body.password != req.body.password_repeat) {
return res.status(400).send({
message: 'Both passwords must match',
});

View File

@ -3,7 +3,8 @@ import ownConn from "../dbConfig.js";
//insert checklist solution todo to databased
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]);
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) {
@ -16,7 +17,7 @@ export const insertChecklistSolutionTodo = async (data, result) => {
//get single checklist solution todo by id
export const getChecklistSolutionTodosById = async (id, result) => {
try {
let sql = `SELECT * FROM checklistSolutions WHERE solutionID = ? ORDER BY primaryID ASC`;
let sql = `SELECT * FROM checklistsolutions WHERE solutionID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -30,7 +31,7 @@ export const getChecklistSolutionTodosById = async (id, result) => {
//get single checklist solution todo by asset
export const getChecklistSolutionTodosByAsset = async (id, result) => {
try {
let sql = `SELECT * FROM checklistSolutions WHERE asset = ? ORDER BY primaryID ASC`;
let sql = `SELECT * FROM checklistsolutions WHERE asset = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -45,8 +46,9 @@ export const getChecklistSolutionTodosByAsset = async (id, result) => {
export const updateChecklistSolutionTodoById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE checklistSolutions SET step = ?, asset = ?, task = ?, comments = ? WHERE 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) {
@ -59,8 +61,9 @@ export const updateChecklistSolutionTodoById = async (data, result) => {
// Delete all checklist solution todos by template ID to Database
export const deleteAllChecklistSolutionTodosSolutionID = async (id, result) => {
try {
let sql = `DELETE FROM checklistSolutions WHERE solutionID = ?`;
let sql = `DELETE FROM checklistsolutions WHERE solutionID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -73,8 +76,9 @@ export const deleteAllChecklistSolutionTodosSolutionID = async (id, result) => {
// Delete single checklist solution todo by primary ID to Database
export const deleteChecklistSolutionTodo = async (id, result) => {
try {
let sql = `DELETE FROM checklistSolutions WHERE primaryID = ?`;
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

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get all master checklists
export const getConfigItems = async (result) => {
try {
let sql = `SELECT * FROM changeDB ORDER BY assetName ASC`;
let sql = `SELECT * FROM changedb ORDER BY assetName ASC`;
const results = await ownConn.query(sql)
result(null, results);
}
@ -17,7 +17,7 @@ export const getConfigItems = async (result) => {
//get single config item by id
export const getConfigItemById = async (id, result) => {
try {
let sql = `SELECT * FROM changeDB WHERE primaryID = ?`;
let sql = `SELECT * FROM changedb WHERE primaryID = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -31,7 +31,7 @@ export const getConfigItemById = async (id, result) => {
//get single config item by name
export const getConfigItemByName = async (name, result) => {
try {
let sql = `SELECT * FROM changeDB WHERE assetName = ?`;
let sql = `SELECT * FROM changedb WHERE assetName = ?`;
const results = await ownConn.query(sql, [name])
result(null, results[0]);
}
@ -45,7 +45,7 @@ export const getConfigItemByName = async (name, result) => {
//get config items by customer id
export const getConfigItemByCustomerId = async (customerId, result) => {
try {
let sql = `SELECT * FROM changeDB WHERE customerID = ? ORDER BY assetName ASC`;
let sql = `SELECT * FROM changedb WHERE customerID = ? ORDER BY assetName ASC`;
const results = await ownConn.query(sql, [customerId])
result(null, results);
}
@ -56,12 +56,13 @@ export const getConfigItemByCustomerId = async (customerId, result) => {
}
};
// Update customer to Database
// Update config item to Database
export const updateConfigItemById = async (data, result) => {
const id = data.primaryID;
try {
let sql = `UPDATE changeDB SET assetName = ?, customerID = ?, customer = ?, location = ?, remoteLocation = ?, type = ?, description = ?, notes = ?, state = ?, lastView = ?, user = ?, hardwareBool = ?, model = ?, serialnumber = ?, CPU = ?, RAM = ?, storageConfiguration = ?, miscellaneous = ?, softwareBool = ?, software = ?, version = ?, networkBool = ?, IPv4 = ?, IPv6 = ?, MAC = ?, subnetmask = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.assetName, data.customerID, data.customer, data.location, data.remoteLocation, data.type, data.description, data.notes, data.state, data.lastView, data.user, data.hardwareBool, data.model, data.serialnumber, data.CPU, data.RAM, data.storageConfiguration, data.miscellaneous, data.softwareBool, data.software, data.version, data.networkBool, data.IPv4, data.IPv6, data.MAC, data.subnetmask, id]);
let sql = `UPDATE changedb SET assetName = ?, customerID = ?, customer = ?, location = ?, remoteLocation = ?, type = ?, description = ?, notes = ?, state = ?, lastView = ?, user = ?, hardwareBool = ?, model = ?, serialnumber = ?, CPU = ?, RAM = ?, storageConfiguration = ?, miscellaneous = ?, softwareBool = ?, software = ?, version = ?, license = ?, networkBool = ?, IPv4 = ?, IPv6 = ?, MAC = ?, subnetmask = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.assetName, data.customerID, data.customer, data.location, data.remoteLocation, data.type, data.description, data.notes, data.state, data.lastView, data.user, data.hardwareBool, data.model, data.serialnumber, data.CPU, data.RAM, data.storageConfiguration, data.miscellaneous, data.softwareBool, data.software, data.version, data.license, data.networkBool, data.IPv4, data.IPv6, data.MAC, data.subnetmask, id]);
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -74,7 +75,8 @@ export const updateConfigItemById = async (data, result) => {
//insert config item to databased
export const insertConfigItem = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO changeDB(assetName, customerID, customer, location, remoteLocation, type, description, notes, state, lastView, user, hardwareBool, model, serialnumber, CPU, RAM, storageConfiguration, miscellaneous, softwareBool, software, version, networkBool, IPv4, IPv6, MAC, subnetmask) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.assetName, data.customerID, data.customer, data.location, data.remoteLocation, data.type, data.description, data.notes, data.state, data.lastView, data.user, data.hardwareBool, data.model, data.serialnumber, data.CPU, data.RAM, data.storageConfiguration, data.miscellaneous, data.softwareBool, data.software, data.version, data.networkBool, data.IPv4, data.IPv6, data.MAC, data.subnetmask])
const results = await ownConn.query(`INSERT INTO changedb(assetName, customerID, customer, location, remoteLocation, type, description, notes, state, lastView, user, hardwareBool, model, serialnumber, CPU, RAM, storageConfiguration, miscellaneous, softwareBool, software, version, license, networkBool, IPv4, IPv6, MAC, subnetmask) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.assetName, data.customerID, data.customer, data.location, data.remoteLocation, data.type, data.description, data.notes, data.state, data.lastView, data.user, data.hardwareBool, data.model, data.serialnumber, data.CPU, data.RAM, data.storageConfiguration, data.miscellaneous, data.softwareBool, data.software, data.version, data.license, data.networkBool, data.IPv4, data.IPv6, data.MAC, data.subnetmask])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -87,7 +89,7 @@ export const insertConfigItem = async (data, result) => {
//get all selected config items by customer
export const getSelectedConfigItemsByCustomer = async (selected, result) => {
try {
let sql = `SELECT * FROM changeDB WHERE customer LIKE '%${selected}%' ORDER BY customer ASC`;
let sql = `SELECT * FROM changedb WHERE LOWER(customer) LIKE '%${selected.toLowerCase()}%' ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -101,7 +103,7 @@ export const getSelectedConfigItemsByCustomer = async (selected, result) => {
//get all selected config items by asset name
export const getSelectedConfigItemsByAssetName = async (selected, result) => {
try {
let sql = `SELECT * FROM changeDB WHERE assetName LIKE '%${selected}%' ORDER BY assetName ASC`;
let sql = `SELECT * FROM changedb WHERE LOWER(assetName) LIKE '%${selected.toLowerCase()}%' ORDER BY assetName ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -115,8 +117,9 @@ export const getSelectedConfigItemsByAssetName = async (selected, result) => {
// Delete config item to Database
export const deleteConfigItemById = async (id, result) => {
try {
let sql = `DELETE FROM changeDB WHERE primaryID = ?`;
let sql = `DELETE FROM changedb WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -124,4 +127,4 @@ export const deleteConfigItemById = async (id, result) => {
console.log("SQL error : ", err);
result(err, null);
}
};
};

View File

@ -17,7 +17,7 @@ export const getCustomers = async (result) => {
//get all selected customers
export const getSelectedCustomers = async (selected, result) => {
try {
let sql = `SELECT * FROM customers WHERE customername LIKE '%${selected}%' ORDER BY customername ASC`;
let sql = `SELECT * FROM customers WHERE LOWER(customername) LIKE '%${selected.toLowerCase()}%' ORDER BY customername ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -63,7 +63,8 @@ export const getCustomerByMaintenanceVisitId = async (id, result) => {
//insert customer to databased
export const insertCustomer = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO customers(customername, contactperson, EMail, phonenumber, address, postcode, city, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?)`, [data.customername, data.contactperson, data.EMail, data.phonenumber, data.address, data.postcode, data.city, data.notes])
const results = await ownConn.query(`INSERT INTO customers(customername, contactperson, EMail, secondEMail, thirdEMail, phonenumber, secondPhonenumber, thirdPhonenumber, street, no, postcode, city, secondStreet, secondNo, secondPostcode, secondCity, thirdStreet, thirdNo, thirdPostcode, thirdCity, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.customername, data.contactperson, data.EMail, data.secondEMail, data.thirdEMail, data.phonenumber, data.secondPhonenumber, data.thirdPhonenumber, data.street, data.no, data.postcode, data.city, data.secondStreet, data.secondNo, data.secondPostcode, data.secondCity, data.thirdStreet, data.thirdNo, data.thirdPostcode, data.thirdCity, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -105,8 +106,9 @@ export const getCustomerByName = async (id, result) => {
export const updateCustomerById = async (data, result) => {
const id = data.customerID;
try {
let sql = `UPDATE customers SET customername = ?, contactperson = ?, EMail = ?, phonenumber = ?, address = ?, postcode = ?, city = ?, notes = ? WHERE customerID = ?`;
const results = await ownConn.query(sql, [data.customername, data.contactperson, data.EMail, data.phonenumber, data.address, data.postcode, data.city, data.notes, id]);
let sql = `UPDATE customers SET customername = ?, contactperson = ?, EMail = ?, secondEMail = ?, thirdEMail = ?, phonenumber = ?, secondPhonenumber = ?, thirdPhonenumber = ?, street = ?, no = ?, postcode = ?, city = ?, secondStreet = ?, secondNo = ?, secondPostcode = ?, secondCity = ?, thirdStreet = ?, thirdNo = ?, thirdPostcode = ?, thirdCity = ?, notes = ? WHERE customerID = ?`;
const results = await ownConn.query(sql, [data.customername, data.contactperson, data.EMail, data.secondEMail, data.thirdEMail, data.phonenumber, data.secondPhonenumber, data.thirdPhonenumber, data.street, data.no, data.postcode, data.city, data.secondStreet, data.secondNo, data.secondPostcode, data.secondCity, data.thirdStreet, data.thirdNo, data.thirdPostcode, data.thirdCity, data.notes, id]);
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -122,6 +124,7 @@ export const deleteCustomerById = async (id, result) => {
try {
let sql = `DELETE FROM customers WHERE customerID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -0,0 +1,102 @@
import ownConn from "../dbConfig.js";
//get single department by id
export const getDepartmentById = async (id, result) => {
try {
let sql = `SELECT * FROM customerdepartment WHERE primaryID = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get departments by customer id
export const getDepartmentsByCustomerId = async (customerId, result) => {
try {
let sql = `SELECT * FROM customerdepartment WHERE customerID = ? ORDER BY name ASC`;
const results = await ownConn.query(sql, [customerId])
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
// Update department to Database
export const updateDepartmentById = async (data, result) => {
const id = data.primaryID;
try {
let sql = `UPDATE customerdepartment SET name = ?, head = ?, notes = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.name, data.head, data.notes, id]);
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//insert department to databased
export const insertDepartment = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO customerdepartment(customerID, customername, name, head, notes) VALUES(?, ?, ?, ?, ?)`, [data.customerID, data.customername, data.name, data.head, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get all selected departments by name
export const getSelectedDepartmentsByName = async (selected, result) => {
try {
let sql = `SELECT * FROM customerdepartment WHERE LOWER(name) LIKE '%${selected.toLowerCase()}%' 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);
}
};
// Delete department to Database
export const deleteDepartmentById = async (id, result) => {
try {
let sql = `DELETE FROM customerdepartment WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get single department by name
export const getDepartmentByName = async (id, result) => {
try {
let sql = `SELECT * FROM customerdepartment WHERE name = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};

View File

@ -0,0 +1,116 @@
import ownConn from "../dbConfig.js";
//get single employee by id
export const getEmployeeById = async (id, result) => {
try {
let sql = `SELECT * FROM customeremployees WHERE primaryID = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get employees by customer id
export const getEmployeesByCustomerId = async (customerId, result) => {
try {
let sql = `SELECT * FROM customeremployees WHERE customerID = ? ORDER BY name ASC`;
const results = await ownConn.query(sql, [customerId])
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
// Update employee to Database
export const updateEmployeeById = async (data, result) => {
const id = data.primaryID;
try {
let sql = `UPDATE customeremployees SET name = ?, pronouns = ?, title = ?, firstName = ?, lastName = ?, preferredName = ?, department = ?, departmentID = ?, jobTitle = ?, phonenumber = ?, eMail = ?, notes = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.name, data.pronouns, data.title, data.firstName, data.lastName, data.preferredName, data.department, data.departmentID, data.jobTitle, data.phonenumber, data.eMail, data.notes, id]);
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//insert employee to databased
export const insertEmployee = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO customeremployees(customerID, customername, name, pronouns, title, firstName, lastName, preferredName, department, departmentID, jobTitle, phonenumber, eMail, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.customerID, data.customername, data.name, data.pronouns, data.title, data.firstName, data.lastName, data.preferredName, data.department, data.departmentID, data.jobTitle, data.phonenumber, data.eMail, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get all selected employees by name
export const getSelectedEmployeesByName = async (selected, result) => {
try {
let sql = `SELECT * FROM customeremployees WHERE LOWER(name) LIKE '%${selected.toLowerCase()}%' 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 all selected employees by department name
export const getSelectedEmployeesByDepartmentName = async (selected, result) => {
try {
let sql = `SELECT * FROM customeremployees WHERE LOWER(department) LIKE '%${selected.toLowerCase()}%' ORDER BY department 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 employees by departmentID
export const getSelectedEmployeesByDepartment = async (selected, result) => {
try {
let sql = `SELECT * FROM customeremployees WHERE departmentID = ? 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);
}
};
// Delete employee to Database
export const deleteEmployeeById = async (id, result) => {
try {
let sql = `DELETE FROM customeremployees WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};

View File

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get all issue slips
export const getIssueSlips = async (result) => {
try {
let sql = `SELECT * FROM issueSlips ORDER BY customer ASC`;
let sql = `SELECT * FROM issueslips ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -17,7 +17,7 @@ export const getIssueSlips = async (result) => {
//get all selected issue slips by ticketnumber
export const getSelectedIssueSlipsByTicketnumber = async (selected, result) => {
try {
let sql = `SELECT * FROM issueSlips WHERE ticketNo LIKE '%${selected}%' ORDER BY ticketNo ASC`;
let sql = `SELECT * FROM issueslips WHERE ticketNo LIKE '%${selected}%' ORDER BY ticketNo ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -31,7 +31,7 @@ export const getSelectedIssueSlipsByTicketnumber = async (selected, result) => {
//get all selected issue slips by customer
export const getSelectedIssueSlipsByCustomer = async (selected, result) => {
try {
let sql = `SELECT * FROM issueSlips WHERE customer LIKE '%${selected}%' ORDER BY customer ASC`;
let sql = `SELECT * FROM issueslips WHERE LOWER(customer) LIKE '%${selected.toLowerCase()}%' ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -45,7 +45,7 @@ export const getSelectedIssueSlipsByCustomer = async (selected, result) => {
//get all selected issue slips by date of creation
export const getSelectedIssueSlipsByDate = async (selected, result) => {
try {
let sql = `SELECT * FROM issueSlips WHERE creationDate LIKE '%${selected}%' ORDER BY creationDate ASC`;
let sql = `SELECT * FROM issueslips WHERE creationDate LIKE '%${selected}%' ORDER BY creationDate ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -59,8 +59,9 @@ export const getSelectedIssueSlipsByDate = async (selected, result) => {
// Delete issue slip to Database
export const deleteIssueSlipById = async (id, result) => {
try {
let sql = `DELETE FROM issueSlips WHERE primaryID = ?`;
let sql = `DELETE FROM issueslips WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -73,8 +74,9 @@ export const deleteIssueSlipById = async (id, result) => {
// Delete issue slip by ticketnumber to Database
export const deleteIssueSlipByTicketNo = async (id, result) => {
try {
let sql = `DELETE FROM issueSlips WHERE ticketNo = ?`;
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) {
@ -100,7 +103,7 @@ export const insertIssueSlip = async (data, result) => {
//get single issue slip by ticketNo
export const getIssueSlipByTicketNo = async (id, result) => {
try {
let sql = `SELECT * FROM issueSlips WHERE ticketNo = ?`;
let sql = `SELECT * FROM issueslips WHERE ticketNo = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -114,7 +117,7 @@ export const getIssueSlipByTicketNo = async (id, result) => {
//get single issue slip by id
export const getIssueSlipById = async (id, result) => {
try {
let sql = `SELECT * FROM issueSlips WHERE primaryID = ?`;
let sql = `SELECT * FROM issueslips WHERE primaryID = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -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

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get all issue variants
export const getAllIssueVariants = async (result) => {
try {
let sql = `SELECT * FROM issueVariants ORDER BY primaryID ASC`;
let sql = `SELECT * FROM issuevariants ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -17,9 +17,9 @@ export const getAllIssueVariants = async (result) => {
//get issue variant
export const getIssueVariantById = async (id, result) => {
try {
let sql = `SELECT * FROM issueVariants WHERE primaryID = ? ORDER BY primaryID ASC`;
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
@ -31,7 +31,7 @@ export const getIssueVariantById = async (id, result) => {
//get all selected issue variants by issueID
export const getSelectedIssueVariantsByIssueId = async (selected, result) => {
try {
let sql = `SELECT * FROM issueVariants WHERE issueID LIKE '%${selected}%' ORDER BY issueID ASC`;
let sql = `SELECT * FROM issuevariants WHERE issueID LIKE '%${selected}%' ORDER BY issueID ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -45,7 +45,7 @@ export const getSelectedIssueVariantsByIssueId = async (selected, result) => {
//get all selected issue variants by name
export const getSelectedIssueVariantsByName = async (selected, result) => {
try {
let sql = `SELECT * FROM issueVariants WHERE name LIKE '%${selected}%' ORDER BY name ASC`;
let sql = `SELECT * FROM issuevariants WHERE LOWER(name) LIKE '%${selected.toLowerCase()}%' ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -60,8 +60,9 @@ export const getSelectedIssueVariantsByName = async (selected, result) => {
export const updateIssueVariantById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE issueVariants SET issueID = ?, name = ? , properties = ?, state = ?, amount = ?, price = ? WHERE 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) {
@ -75,8 +76,9 @@ export const updateIssueVariantById = async (data, result) => {
// Delete issue variant to Database
export const deleteIssueVariantById = async (id, result) => {
try {
let sql = `DELETE FROM issueVariants WHERE primaryID = ?`;
let sql = `DELETE FROM issuevariants WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -89,8 +91,9 @@ export const deleteIssueVariantById = async (id, result) => {
// Delete issue variants by issueID to Database
export const deleteIssueVariantByIssueSlipId = async (id, result) => {
try {
let sql = `DELETE FROM issueVariants WHERE issueID = ?`;
let sql = `DELETE FROM issuevariants WHERE issueID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -103,7 +106,8 @@ export const deleteIssueVariantByIssueSlipId = async (id, result) => {
//insert issue to databased
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])
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

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get all maintenance visits
export const getMaintenanceVisits = async (result) => {
try {
let sql = `SELECT * FROM maintenanceVisits ORDER BY name ASC`;
let sql = `SELECT * FROM maintenancevisits ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -17,7 +17,35 @@ export const getMaintenanceVisits = async (result) => {
//get all selected maintenance visits by checklistname
export const getSelectedMaintenanceVisitsByChecklistname = async (selected, result) => {
try {
let sql = `SELECT * FROM maintenanceVisits WHERE name LIKE '%${selected}%' ORDER BY name ASC`;
let sql = `SELECT * FROM maintenancevisits WHERE LOWER(name) LIKE '%${selected.toLowerCase()}%' 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 all selected maintenance visits by template
export const getSelectedMaintenanceVisitsByTemplate = async (selected, result) => {
try {
let sql = `SELECT * FROM maintenancevisits WHERE templateID = ? ORDER BY name ASC`;
const results = await ownConn.execute(sql, [selected])
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get all selected maintenance visits by user
export const getSelectedMaintenanceVisitsByUser = async (selected, result) => {
try {
let sql = `SELECT * FROM maintenancevisits WHERE LOWER(user) LIKE '%${selected.toLowerCase()}%' ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -31,7 +59,7 @@ export const getSelectedMaintenanceVisitsByChecklistname = async (selected, resu
//get all selected maintenance visits by customer
export const getSelectedMaintenanceVisitsByCustomer = async (selected, result) => {
try {
let sql = `SELECT * FROM maintenanceVisits WHERE customer LIKE '%${selected}%' ORDER BY customer ASC`;
let sql = `SELECT * FROM maintenancevisits WHERE LOWER(customer) LIKE '%${selected.toLowerCase()}%' ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -45,7 +73,7 @@ export const getSelectedMaintenanceVisitsByCustomer = async (selected, result) =
//get all selected maintenance visits by date
export const getSelectedMaintenanceVisitsByDate = async (selected, result) => {
try {
let sql = `SELECT * FROM maintenanceVisits WHERE creationDate LIKE '%${selected}%' ORDER BY creationDate ASC`;
let sql = `SELECT * FROM maintenancevisits WHERE creationDate LIKE '%${selected}%' ORDER BY creationDate ASC`;
const results = await ownConn.execute(sql);
result(null, results);
}
@ -59,7 +87,7 @@ export const getSelectedMaintenanceVisitsByDate = async (selected, result) => {
//get all selected maintenance visits by state
export const getSelectedMaintenanceVisitsByState = async (selected, result) => {
try {
let sql = `SELECT * FROM maintenanceVisits WHERE state LIKE '%${selected}%' ORDER BY state ASC`;
let sql = `SELECT * FROM maintenancevisits WHERE LOWER(state) LIKE '%${selected.toLowerCase()}%' ORDER BY state ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -73,8 +101,9 @@ export const getSelectedMaintenanceVisitsByState = async (selected, result) => {
// Delete maintenance visit to Database
export const deleteMaintenanceVisitById = async (id, result) => {
try {
let sql = `DELETE FROM maintenanceVisits WHERE primaryID = ?`;
let sql = `DELETE FROM maintenancevisits WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -87,7 +116,8 @@ export const deleteMaintenanceVisitById = async (id, result) => {
//insert maintenance visit to databased
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])
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 +130,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 +144,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]);
}
@ -126,11 +156,12 @@ export const getMaintenanceVisitById = async (id, result) => {
};
// Update maintenance visit state to Database
export const updateMaintenanceVisitStateById = async (data, result) => {
export const updateMaintenanceVisitById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE maintenanceVisits SET state = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.state, id])
let sql = `UPDATE maintenancevisits SET primaryID = ?, name = ?, templateID = ?, maintenanceType = ?, state = ?, creationDate = ?, completionDate = ?, user = ?, customer = ?, customerID = ?, templateNotes = ?, type = ?, timeSpent = ?, notes = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.primaryID, 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, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -3,7 +3,8 @@ import ownConn from "../dbConfig.js";
//insert maintenance visit todo to databased
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])
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) {
@ -16,7 +17,7 @@ export const insertMaintenanceVisitTodo = async (data, result) => {
//get single maintenance visit todo by id
export const getMaintenanceVisitTodosById = async (id, result) => {
try {
let sql = `SELECT * FROM maintenanceVisitTodos WHERE templateID = ? ORDER BY primaryID ASC`;
let sql = `SELECT * FROM maintenancevisittodos WHERE templateID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -30,7 +31,21 @@ export const getMaintenanceVisitTodosById = async (id, result) => {
//get single maintenance visit todo by asset
export const getMaintenanceVisitTodosByAsset = async (id, result) => {
try {
let sql = `SELECT * FROM maintenanceVisitTodos WHERE asset = ? ORDER BY primaryID ASC`;
let sql = `SELECT * FROM maintenancevisittodos WHERE asset = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get maintenance visit todo by template
export const getMaintenanceVisitTodosByTemplate = async (id, result) => {
try {
let sql = `SELECT * FROM maintenancevisittodos WHERE templateID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -45,8 +60,9 @@ export const getMaintenanceVisitTodosByAsset = async (id, result) => {
export const updateMaintenanceVisitTodoById = async (data, result) => {
try {
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])
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, data.done, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -59,8 +75,24 @@ export const updateMaintenanceVisitTodoById = async (data, result) => {
// Delete maintenance visit todo to Database
export const deleteMaintenanceVisitTodosByPrimaryID = async (id, result) => {
try {
let sql = `DELETE FROM maintenanceVisitTodos WHERE primaryID = ?`;
let sql = `DELETE FROM maintenancevisittodos WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
// Delete maintenance visit todos by template to Database
export const deleteMaintenanceVisitTodosByTemplateID = async (id, result) => {
try {
let sql = `DELETE FROM maintenancevisittodos WHERE templateID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get single master maintenance visit todo
export const getMasterMaintenanceVisitTodoById = async (id, result) => {
try {
let sql = `SELECT * FROM masterMaintenanceVisitTodos WHERE templateID = ? ORDER BY rowID ASC`;
let sql = `SELECT * FROM mastermaintenancetodos WHERE templateID = ? ORDER BY rowID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -18,8 +18,9 @@ export const getMasterMaintenanceVisitTodoById = async (id, result) => {
export const updateMasterMaintenanceVisitTodoById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE masterMaintenanceVisitTodos 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) {
@ -33,8 +34,9 @@ export const updateMasterMaintenanceVisitTodoById = async (data, result) => {
// Delete master maintenance visit todo to Database
export const deleteMasterMaintenanceVisitTodoById = async (id, result) => {
try {
let sql = `DELETE FROM masterMaintenanceVisitTodos WHERE primaryID = ?`;
let sql = `DELETE FROM mastermaintenancetodos WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -47,8 +49,9 @@ export const deleteMasterMaintenanceVisitTodoById = async (id, result) => {
// Delete master maintenance visit todo by templateID to Database
export const deleteMasterMaintenanceVisitTodoByTemplateId = async (id, result) => {
try {
let sql = `DELETE FROM masterMaintenanceVisitTodos WHERE templateID = ?`;
let sql = `DELETE FROM mastermaintenancetodos WHERE templateID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -61,7 +64,7 @@ export const deleteMasterMaintenanceVisitTodoByTemplateId = async (id, result) =
// Update all master maintenance visit todos to Database
export const updateMasterMaintenanceVisitTodos = async (data, result) => {
try {
let sql = `UPDATE masterMaintenanceVisitTodos SET rowID = ? WHERE primaryID = ?`;
let sql = `UPDATE mastermaintenancetodos SET rowID = ? WHERE primaryID = ?`;
data.data.forEach(async i => {
let id = i.primaryID;
let rowId = i.rowID;
@ -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 masterMaintenanceVisitTodos(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

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get all master maintenance visits
export const getMasterMaintenanceVisits = async (result) => {
try {
let sql = `SELECT * FROM masterMaintenanceVisits ORDER BY name ASC`;
let sql = `SELECT * FROM mastermaintenancevisits ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -17,7 +17,7 @@ export const getMasterMaintenanceVisits = async (result) => {
//get all selected master maintenance visits by customer
export const getSelectedMasterMaintenanceVisitsByCustomer = async (selected, result) => {
try {
let sql = `SELECT * FROM masterMaintenanceVisits WHERE customer LIKE '%${selected}%' ORDER BY customer ASC`;
let sql = `SELECT * FROM mastermaintenancevisits WHERE LOWER(customer) LIKE '%${selected.toLowerCase()}%' ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -31,7 +31,7 @@ export const getSelectedMasterMaintenanceVisitsByCustomer = async (selected, res
//get all selected master maintenance visits by checklistname
export const getSelectedMasterMaintenanceVisitsByChecklistname = async (selected, result) => {
try {
let sql = `SELECT * FROM masterMaintenanceVisits WHERE name LIKE '%${selected}%' ORDER BY name ASC`;
let sql = `SELECT * FROM mastermaintenancevisits WHERE LOWER(name) LIKE '%${selected.toLowerCase()}%' ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -45,7 +45,7 @@ export const getSelectedMasterMaintenanceVisitsByChecklistname = async (selected
//get single master maintenance visit
export const getMasterMaintenanceVisitById = async (id, result) => {
try {
let sql = `SELECT * FROM masterMaintenanceVisits WHERE checklistID = ?`;
let sql = `SELECT * FROM mastermaintenancevisits WHERE checklistID = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -60,8 +60,9 @@ export const getMasterMaintenanceVisitById = async (id, result) => {
export const updateMasterMaintenanceVisitById = async (data, result) => {
try {
const id = data.checklistID;
let sql = `UPDATE masterMaintenanceVisits SET name = ?, customerID = ? , customer = ?, type = ?, lastView = ?, user = ?, notes = ? WHERE 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) {
@ -74,7 +75,8 @@ export const updateMasterMaintenanceVisitById = async (data, result) => {
//insert master maintenance visit to databased
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])
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) {
@ -87,8 +89,9 @@ export const insertMasterMaintenanceVisit = async (data, result) => {
// Delete master maintenance visit to Database
export const deleteMasterMaintenanceVisitById = async (id, result) => {
try {
let sql = `DELETE FROM masterMaintenanceVisits WHERE checklistID = ?`;
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

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get single master production order todo
export const getMasterProductionOrderTodoById = async (id, result) => {
try {
let sql = `SELECT * FROM masterOrderTodos WHERE templateID = ? ORDER BY rowID ASC`;
let sql = `SELECT * FROM masterordertodos WHERE templateID = ? ORDER BY rowID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -18,8 +18,9 @@ export const getMasterProductionOrderTodoById = async (id, result) => {
export const updateMasterProductionOrderTodoById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE masterOrderTodos SET templateID = ?, asset = ? , task = ?, comment = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.templateID, data.asset, data.task, data.comment, id])
let sql = `UPDATE masterordertodos SET templateID = ?, asset = ? , task = ?, comments = ? 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) {
@ -33,8 +34,9 @@ export const updateMasterProductionOrderTodoById = async (data, result) => {
// Delete master production order todo to Database
export const deleteMasterProductionOrderTodoById = async (id, result) => {
try {
let sql = `DELETE FROM masterOrderTodos WHERE primaryID = ?`;
let sql = `DELETE FROM masterordertodos WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -47,8 +49,9 @@ export const deleteMasterProductionOrderTodoById = async (id, result) => {
// Delete master production order todo by templateID to Database
export const deleteMasterProductionOrderTodoByTemplateId = async (id, result) => {
try {
let sql = `DELETE FROM masterOrderTodos WHERE templateID = ?`;
let sql = `DELETE FROM masterordertodos WHERE templateID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -61,7 +64,7 @@ export const deleteMasterProductionOrderTodoByTemplateId = async (id, result) =>
// Update all master production order todos to Database
export const updateMasterProductionOrderTodos = async (data, result) => {
try {
let sql = `UPDATE masterOrderTodos SET rowID = ? WHERE primaryID = ?`;
let sql = `UPDATE masterordertodos SET rowID = ? WHERE primaryID = ?`;
data.data.forEach(async i => {
let id = i.primaryID;
let rowId = i.rowID;
@ -79,7 +82,8 @@ export const updateMasterProductionOrderTodos = async (data, result) => {
//insert master production order todo to databased
export const insertMasterProductionOrderTodo = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO masterOrderTodos(templateID, rowID, asset, task, comment) VALUES(?, ?, ?, ?, ?)`, [data.templateID, data.rowID, data.asset, data.task, data.comment])
const results = await ownConn.query(`INSERT INTO masterordertodos(templateID, rowID, asset, task, comments) VALUES(?, ?, ?, ?, ?)`, [data.templateID, data.rowID, data.asset, data.task, data.comment])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get all master production orders
export const getMasterProductionOrders = async (result) => {
try {
let sql = `SELECT * FROM masterProductionOrders ORDER BY name ASC`;
let sql = `SELECT * FROM masterproductionorders ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -17,7 +17,7 @@ export const getMasterProductionOrders = async (result) => {
//get all selected master production orders by customer
export const getSelectedMasterProductionOrdersByCustomer = async (selected, result) => {
try {
let sql = `SELECT * FROM masterProductionOrders WHERE customer LIKE '%${selected}%' ORDER BY customer ASC`;
let sql = `SELECT * FROM masterproductionorders WHERE LOWER(customer) LIKE '%${selected.toLowerCase()}%' ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -31,7 +31,7 @@ export const getSelectedMasterProductionOrdersByCustomer = async (selected, resu
//get all selected master production orders by checklistname
export const getSelectedMasterProductionOrdersByChecklistname = async (selected, result) => {
try {
let sql = `SELECT * FROM masterProductionOrders WHERE name LIKE '%${selected}%' ORDER BY name ASC`;
let sql = `SELECT * FROM masterproductionorders WHERE LOWER(name) LIKE '%${selected.toLowerCase()}%' ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -45,7 +45,7 @@ export const getSelectedMasterProductionOrdersByChecklistname = async (selected,
//get single master production order
export const getMasterProductionOrderById = async (id, result) => {
try {
let sql = `SELECT * FROM masterProductionOrders WHERE templateID = ?`;
let sql = `SELECT * FROM masterproductionorders WHERE templateID = ?`;
const results = await ownConn.execute(sql, [id])
result(null, results[0]);
}
@ -60,8 +60,9 @@ export const getMasterProductionOrderById = async (id, result) => {
export const updateMasterProductionOrderById = async (data, result) => {
try {
const id = data.templateID;
let sql = `UPDATE masterProductionOrders SET name = ?, customerID = ? , customer = ?, lastView = ?, user = ?, description = ?, notes = ? WHERE templateID = ?`;
let sql = `UPDATE masterproductionorders SET name = ?, customerID = ? , customer = ?, lastView = ?, user = ?, description = ?, notes = ? WHERE templateID = ?`;
const results = await ownConn.query(sql, [data.name, data.customerID, data.customer, data.lastView, data.user, data.description, data.notes, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -74,7 +75,8 @@ export const updateMasterProductionOrderById = async (data, result) => {
//insert master production order to databased
export const insertMasterProductionOrder = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO masterProductionOrders(name, customerID, customer, lastView, user, description, notes) VALUES(?, ?, ?, ?, ?, ?, ?)`, [data.name, data.customerID, data.customer, data.lastView, data.user, data.description, data.notes])
const results = await ownConn.query(`INSERT INTO masterproductionorders(name, customerID, customer, lastView, user, description, notes) VALUES(?, ?, ?, ?, ?, ?, ?)`, [data.name, data.customerID, data.customer, data.lastView, data.user, data.description, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -87,8 +89,9 @@ export const insertMasterProductionOrder = async (data, result) => {
// Delete master production order to Database
export const deleteMasterProductionOrderById = async (id, result) => {
try {
let sql = `DELETE FROM masterProductionOrders WHERE templateID = ?`;
let sql = `DELETE FROM masterproductionorders WHERE templateID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get single ordering info issue slip
export const getOrderingInfoIssueSlipById = async (id, result) => {
try {
let sql = `SELECT * FROM orderingInfoIssueSlips WHERE issueSlipID = ? ORDER BY primaryID ASC`;
let sql = `SELECT * FROM orderinginfoissueslips WHERE issueSlipID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -18,8 +18,9 @@ export const getOrderingInfoIssueSlipById = async (id, result) => {
export const updateOrderingInfoIssueSlipById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE orderingInfoIssueSlips SET issueSlipID = ?, article = ? , amount = ?, price = ?, comment = ? WHERE 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) {
@ -33,8 +34,9 @@ export const updateOrderingInfoIssueSlipById = async (data, result) => {
// Delete ordering info issue slip to Database
export const deleteOrderingInfoIssueSlipById = async (id, result) => {
try {
let sql = `DELETE FROM orderingInfoIssueSlips WHERE primaryID = ?`;
let sql = `DELETE FROM orderinginfoissueslips WHERE primaryID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -47,8 +49,9 @@ export const deleteOrderingInfoIssueSlipById = async (id, result) => {
// Delete ordering info issue slip by issueSlipID to Database
export const deleteOrderingInfoIssueSlipByIssueSlipId = async (id, result) => {
try {
let sql = `DELETE FROM orderingInfoIssueSlips WHERE issueSlipID = ?`;
let sql = `DELETE FROM orderinginfoissueslips WHERE issueSlipID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -61,7 +64,8 @@ export const deleteOrderingInfoIssueSlipByIssueSlipId = async (id, result) => {
//insert ordering info issue slip to databased
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])
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

@ -3,7 +3,7 @@ import ownConn from "../dbConfig.js";
//get all production orders
export const getProductionOrders = async (result) => {
try {
let sql = `SELECT * FROM productionOrders ORDER BY name ASC`;
let sql = `SELECT * FROM productionorders ORDER BY ticketNumber ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -17,7 +17,7 @@ export const getProductionOrders = async (result) => {
//get all selected production orders by ticketnumber
export const getSelectedProductionOrdersByTicketnumber = async (selected, result) => {
try {
let sql = `SELECT * FROM productionOrders WHERE ticketNumber LIKE '%${selected}%' ORDER BY ticketNumber ASC`;
let sql = `SELECT * FROM productionorders WHERE ticketNumber = ? ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -31,7 +31,7 @@ export const getSelectedProductionOrdersByTicketnumber = async (selected, result
//get all selected production orders by customer
export const getSelectedProductionOrdersByCustomer = async (selected, result) => {
try {
let sql = `SELECT * FROM productionOrders WHERE customer LIKE '%${selected}%' ORDER BY customer ASC`;
let sql = `SELECT * FROM productionorders WHERE LOWER(customer) LIKE '%${selected.toLowerCase()}%' ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -42,10 +42,38 @@ export const getSelectedProductionOrdersByCustomer = async (selected, result) =>
}
};
//get all selected production orders by user
export const getSelectedProductionOrdersByUser = async (selected, result) => {
try {
let sql = `SELECT * FROM productionorders WHERE LOWER(user) LIKE '%${selected.toLowerCase()}%' 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 all selected production orders by template
export const getSelectedProductionOrdersByTemplate = async (selected, result) => {
try {
let sql = `SELECT * FROM productionorders WHERE templateID = ? ORDER BY name ASC`;
const results = await ownConn.execute(sql, [selected])
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get all selected production orders by state
export const getSelectedProductionOrdersByState = async (selected, result) => {
try {
let sql = `SELECT * FROM productionOrders WHERE state LIKE '%${selected}%' ORDER BY state ASC`;
let sql = `SELECT * FROM productionorders WHERE LOWER(state) LIKE '%${selected.toLowerCase()}%' ORDER BY state ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -59,7 +87,7 @@ export const getSelectedProductionOrdersByState = async (selected, result) => {
//get all selected production orders by checklistname
export const getSelectedProductionOrdersByChecklistname = async (selected, result) => {
try {
let sql = `SELECT * FROM productionOrders WHERE name LIKE '%${selected}%' ORDER BY name ASC`;
let sql = `SELECT * FROM productionorders WHERE LOWER(name) LIKE '%${selected.toLowerCase()}%' ORDER BY name ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -73,7 +101,7 @@ export const getSelectedProductionOrdersByChecklistname = async (selected, resul
//get all selected production orders by date of creation
export const getSelectedProductionOrdersByDate = async (selected, result) => {
try {
let sql = `SELECT * FROM productionOrders WHERE creationDate LIKE '%${selected}%' ORDER BY creationDate ASC`;
let sql = `SELECT * FROM productionorders WHERE creationDate LIKE '%${selected}%' ORDER BY creationDate ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -87,8 +115,9 @@ export const getSelectedProductionOrdersByDate = async (selected, result) => {
// Delete production order to Database
export const deleteProductionOrderById = async (id, result) => {
try {
let sql = `DELETE FROM productionOrders WHERE ticketNumber = ?`;
let sql = `DELETE FROM productionorders WHERE ticketNumber = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -101,7 +130,8 @@ export const deleteProductionOrderById = async (id, result) => {
//insert production order to database
export const insertProductionOrder = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO productionOrders(name, templateID, customer, customerID, asset, state, creationDate, completionDate, user, templateDescription, templateNotes, timeSpent, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.name, data.templateID, data.customer, data.customerID, data.asset, data.state, data.creationDate, data.completionDate, data.user, data.templateDescription, data.templateNotes, data.timeSpent, data.notes])
const results = await ownConn.query(`INSERT INTO productionorders(name, templateID, customer, customerID, asset, state, creationDate, completionDate, user, templateDescription, templateNotes, timeSpent, notes) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.name, data.templateID, data.customer, data.customerID, data.asset, data.state, data.creationDate, data.completionDate, data.user, data.templateDescription, data.templateNotes, data.timeSpent, data.notes])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -114,7 +144,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]);
}
@ -128,7 +158,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]);
}
@ -140,11 +170,12 @@ export const getProductionOrderById = async (id, result) => {
};
// Update production order state to Database
export const updateProductionOrderStateById = async (data, result) => {
export const updateProductionOrderById = async (data, result) => {
const id = data.ticketNumber;
try {
let sql = `UPDATE productionOrders SET state = ? WHERE ticketNumber = ?`;
const results = await ownConn.query(sql, [data.state, id])
let sql = `UPDATE productionorders SET name = ?, templateID = ?, customer = ?, customerID = ?, asset = ?, state = ?, creationDate = ?, completionDate = ?, user = ?, templateDescription = ?, templateNotes = ?, timeSpent = ?, notes = ? WHERE ticketNumber = ?`;
const results = await ownConn.query(sql, [data.name, data.templateID, data.customer, data.customerID, data.asset, data.state, data.creationDate, data.completionDate, data.user, data.templateDescription, data.templateNotes, data.timeSpent, data.notes, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -3,7 +3,8 @@ import ownConn from "../dbConfig.js";
//insert production order todo to databased
export const insertProductionOrderTodo = async (data, result) => {
try {
const results = await ownConn.query(`INSERT INTO productionOrderTodos(templateID, step, asset, task, comment, done) VALUES(?, ?, ?, ?, ?, ?)`, [data.templateID, data.step, data.asset, data.task, data.comment, data.done]);
const results = await ownConn.query(`INSERT INTO productionordertodos(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) {
@ -16,7 +17,7 @@ export const insertProductionOrderTodo = async (data, result) => {
//get single production order todo by id
export const getProductionOrderTodosById = async (id, result) => {
try {
let sql = `SELECT * FROM productionOrderTodos WHERE templateID = ? ORDER BY primaryID ASC`;
let sql = `SELECT * FROM productionordertodos WHERE templateID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -27,10 +28,24 @@ export const getProductionOrderTodosById = async (id, result) => {
}
};
//get single production order todo by asset
//get production order todo by asset
export const getProductionOrderTodosByAsset = async (id, result) => {
try {
let sql = `SELECT * FROM productionOrderTodos WHERE asset = ? ORDER BY primaryID ASC`;
let sql = `SELECT * FROM productionordertodos WHERE asset = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
//get production order todo by template
export const getProductionOrderTodosByTemplate = async (id, result) => {
try {
let sql = `SELECT * FROM productionordertodos WHERE templateID = ? ORDER BY primaryID ASC`;
const results = await ownConn.execute(sql, [id])
result(null, results);
}
@ -45,8 +60,9 @@ export const getProductionOrderTodosByAsset = async (id, result) => {
export const updateProductionOrderTodoById = async (data, result) => {
try {
const id = data.primaryID;
let sql = `UPDATE productionOrderTodos SET step = ?, asset = ?, task = ?, comment = ?, done = ? WHERE primaryID = ?`;
let sql = `UPDATE productionordertodos SET step = ?, asset = ?, task = ?, comment = ?, done = ? WHERE primaryID = ?`;
const results = await ownConn.query(sql, [data.step, data.asset, data.task, data.comment, data.done, id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
@ -59,8 +75,9 @@ export const updateProductionOrderTodoById = async (data, result) => {
// Delete production order todos to Database
export const deleteProductionOrderTodosChecklistID = async (id, result) => {
try {
let sql = `DELETE FROM productionOrderTodos WHERE templateID = ?`;
let sql = `DELETE FROM productionordertodos WHERE templateID = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

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) {
@ -73,7 +75,7 @@ export const updateSolutionById = async (data, result) => {
//get all selected solutions by customer
export const getSelectedSolutionsByCustomer = async (selected, result) => {
try {
let sql = `SELECT * FROM solutions WHERE customer LIKE '%${selected}%' ORDER BY customer ASC`;
let sql = `SELECT * FROM solutions WHERE LOWER(customer) LIKE '%${selected.toLowerCase()}%' ORDER BY customer ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -86,7 +88,7 @@ export const getSelectedSolutionsByCustomer = async (selected, result) => {
//get all selected solutions by solution name
export const getSelectedSolutionsBySolutionName = async (selected, result) => {
let sql = `SELECT * FROM solutions WHERE solutionName LIKE '%${selected}%' ORDER BY solutionName ASC`;
let sql = `SELECT * FROM solutions WHERE LOWER(solutionName) LIKE '%${selected.toLowerCase()}%' ORDER BY solutionName ASC`;
try {
const results = await ownConn.execute(sql)
result(null, results);
@ -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 assetName LIKE '%${selected}%' 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) {
@ -115,7 +117,7 @@ export const getSelectedSolutionsByAssetName = async (selected, result) => {
//get all selected solutions by type
export const getSelectedSolutionsByType = async (selected, result) => {
try {
let sql = `SELECT * FROM solutions WHERE type LIKE '%${selected}%' ORDER BY solutionName ASC`;
let sql = `SELECT * FROM solutions WHERE LOWER(type) LIKE '%${selected.toLowerCase()}%' ORDER BY solutionName ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
@ -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

@ -28,12 +28,11 @@ export const getUserById = async (id, result) => {
}
};
// Update user to Database
export const updateUserById = async (data, result) => {
//get all selected users by full name
export const getSelectedUsersByUser = async (selected, result) => {
try {
const id = data.id;
let sql = `UPDATE users SET username = ?, password = ?, fullName = ?, email = ?, phonenumber = ?, address = ?, city = ?, postcode = ?, adminBool = ?, technician1Bool = ?, technician2Bool = ?, technicianMonitoringBool = ?, merchantBool = ?, internBool = ? WHERE id = ?`;
const results = await ownConn.query(sql, [data.username, data.password, data.fullName, data.email, data.phonenumber, data.address, data.city, data.postcode, data.adminBool, data.technician1Bool, data.technician2Bool, data.technicianMonitoringBool, data.merchantBool, data.internBool, id]);
let sql = `SELECT * FROM users WHERE LOWER(fullName) LIKE '%${selected.toLowerCase()}%' ORDER BY fullName ASC`;
const results = await ownConn.execute(sql)
result(null, results);
}
catch (err) {
@ -43,12 +42,28 @@ export const updateUserById = async (data, result) => {
}
};
// Update user to Database
export const updateUserById = async (data, result) => {
try {
const id = data.id;
let sql = `UPDATE users SET username = ?, fullName = ?, email = ?, phonenumber = ?, address = ?, city = ?, postcode = ?, adminBool = ?, technicianBool = ?, readerBool = ?, darkModeBool = ? WHERE id = ?`;
const results = await ownConn.query(sql, [data.username, data.fullName, data.email, data.phonenumber, data.address, data.city, data.postcode, data.adminBool, data.technicianBool, data.readerBool, data.darkModeBool, id]);
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {
// Manage Errors
console.log("SQL error : ", err);
result(err, null);
}
};
// Delete user to Database
export const deleteUserById = async (id, result) => {
try {
let sql = `DELETE FROM users WHERE id = ?`;
const results = await ownConn.query(sql, [id])
results.insertId = results.insertId.toString();
result(null, results);
}
catch (err) {

View File

@ -19,11 +19,13 @@ import {
showSelectedMaintenanceVisitsByCustomer,
showSelectedMaintenanceVisitsByState,
showSelectedMaintenanceVisitsByDate,
showSelectedMaintenanceVisitsByTemplate,
showSelectedMaintenanceVisitsByUser,
deleteMaintenanceVisit,
createMaintenanceVisit,
showMaintenanceVisitByName,
showMaintenanceVisitById,
updateMaintenanceVisitState,
updateMaintenanceVisit,
} from "../controller/maintenanceVisits.js"
import {
@ -32,6 +34,8 @@ import {
showMaintenanceVisitTodosByAsset,
updateMaintenanceVisitTodo,
deleteMaintenanceVisitTodos,
deleteMaintenanceVisitTodosBytemplateId,
showMaintenanceVisitTodosByTemplateId,
} from "../controller/maintenanceVisitTodos.js"
import {
@ -60,17 +64,20 @@ import {
showSelectedProductionOrdersByTicketnumber,
showSelectedProductionOrdersByDate,
showSelectedProductionOrdersByState,
showSelectedProductionOrdersByTemplate,
showSelectedProductionOrdersByUser,
deleteProductionOrder,
createProductionOrder,
showProductionOrderByName,
showProductionOrderById,
updateProductionOrderState,
updateProductionOrder,
} from "../controller/productionOrders.js";
import {
createProductionOrderTodos,
showProductionOrderTodosById,
showProductionOrderTodosByAsset,
showProductionOrderTodosByTemplate,
updateProductionOrderTodo,
deleteProductionOrderTodos,
} from "../controller/productionOrderTodos.js";
@ -106,13 +113,36 @@ import {
deleteCustomer,
} from "../controller/customers.js";
import {
showDepartmentById,
showDepartmentByCustomerId,
updateDepartment,
createDepartment,
showSelectedDepartmentsByName,
deleteDepartment,
showDepartmentByName
} from "../controller/departments.js";
import {
showEmployeeById,
showEmployeeByCustomerId,
showEmployeeByDepartmentId,
updateEmployee,
createEmployee,
showSelectedEmployeesByName,
showSelectedEmployeesByDepartmentName,
deleteEmployee,
} from "../controller/employees.js";
import {
signUp,
updatePasswordById,
login,
showUsers,
showUserById,
updateUser,
deleteUser,
showSelectedUsersByUser,
} from "../controller/users.js";
import * as userMiddleware from "../middleware/users.js";
@ -166,6 +196,8 @@ import {
showIssueById,
updateIssue,
showIssues,
showSelectedIssuesByIssueName,
showSelectedIssuesByState,
} from "../controller/issues.js";
import {
@ -219,8 +251,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)
@ -264,8 +296,8 @@ router.put("/masterProductionOrderTodos", updateMasterProductionOrderTodo);
// Delete master production order todo
router.delete("/masterProductionOrderTodos/:id", deleteMasterProductionOrderTodo);
// Delete master production order todo by customer id
router.delete("/masterProductionOrderTodosByCustomerid/:id", deleteMasterProductionOrderTodoByTemplateIds);
// Delete master production order todo by template id
router.delete("/masterProductionOrderTodosByTemplateid/:id", deleteMasterProductionOrderTodoByTemplateIds);
// Update all master production order todos
router.put("/allMasterProductionOrderTodos", updateAllProductionOrderTodos)
@ -359,6 +391,55 @@ router.post("/customers", createCustomer);
// routes with departments:
//get single department by id
router.get("/department/:id", showDepartmentById);
//get single department by name
router.get("/departmentByName/:id", showSelectedDepartmentsByName);
//get departments by customerid
router.get("/departmentByCustomerID/:id", showDepartmentByCustomerId);
// Update department
router.put("/department", updateDepartment);
// Create New department
router.post("/departments", createDepartment);
//get single department by name
router.get("/departmentName/:id", showDepartmentByName);
// Delete department
router.delete("/departments/:id", deleteDepartment);
// routes with employees:
//get single employee by id
router.get("/employee/:id", showEmployeeById);
//get employees by name
router.get("/employeeByName/:id", showSelectedEmployeesByName);
//get employees by department name
router.get("/employeeByDepartmentName/:id", showSelectedEmployeesByDepartmentName);
//get employees by customerid
router.get("/employeeByCustomerID/:id", showEmployeeByCustomerId);
//get employees by departmentid
router.get("/employeeByDeprtmentID/:id", showEmployeeByDepartmentId);
// Update employee
router.put("/employee", updateEmployee);
// Create New employee
router.post("/employees", createEmployee);
// Delete employee
router.delete("/employees/:id", deleteEmployee);
// routes with config items:
// get all config items
router.get("/configItems", showConfigItems);
@ -405,6 +486,12 @@ router.get("/selectedProductionOrdersByCustomer/:id", showSelectedProductionOrde
//get all production orders by selected state
router.get("/selectedProductionOrdersByState/:id", showSelectedProductionOrdersByState)
//get all production orders by selected template
router.get("/selectedProductionOrdersByTemplate/:id", showSelectedProductionOrdersByTemplate)
//get all production orders by selected user
router.get("/selectedProductionOrdersByUser/:id", showSelectedProductionOrdersByUser)
//get all production orders by selected date
router.get("/selectedProductionOrdersByDate/:id", showSelectedProductionOrdersByDate)
@ -420,9 +507,8 @@ router.get("/productionOrderByName/:id", showProductionOrderByName);
//get single production order by ticketNumber
router.get("/productionOrder/:id", showProductionOrderById);
// Update production order state
router.put("/productionOrderState", updateProductionOrderState);
// Update production order
router.put("/productionOrder", updateProductionOrder);
// routes with production order todos:
@ -435,10 +521,13 @@ router.get("/productionOrderTodos/:id", showProductionOrderTodosById);
//get all production order todos by assetname
router.get("/productionOrderTodosByAsset/:id", showProductionOrderTodosByAsset);
//get all production order todos by template id
router.get("/productionOrderTodosByTemplateID/:id", showProductionOrderTodosByTemplate);
// Update production order todo
router.put("/productionOrderTodos", updateProductionOrderTodo);
// Delete production order todos
// Delete production order todo
router.delete("/productionOrderTodos/:id", deleteProductionOrderTodos);
@ -456,6 +545,12 @@ router.get("/selectedMaintenanceVisitsByDate/:id", showSelectedMaintenanceVisits
//get all maintenance visits by selected customer
router.get("/selectedMaintenanceVisitsByCustomer/:id", showSelectedMaintenanceVisitsByCustomer)
//get all maintenance visits by selected user
router.get("/selectedMaintenanceVisitsByUser/:id", showSelectedMaintenanceVisitsByUser)
//get all maintenance visits by selected template
router.get("/selectedMaintenanceVisitsByTemplate/:id", showSelectedMaintenanceVisitsByTemplate)
//get all maintenance visits by selected state
router.get("/selectedMaintenanceVisitsByState/:id", showSelectedMaintenanceVisitsByState)
@ -471,8 +566,8 @@ router.get("/maintenanceVisitByName/:id", showMaintenanceVisitByName);
//get single maintenance visit by primaryId
router.get("/maintenanceVisit/:id", showMaintenanceVisitById);
// Update maintenance visit state
router.put("/maintenanceVisitState", updateMaintenanceVisitState);
// Update maintenance visit
router.put("/maintenanceVisit", updateMaintenanceVisit);
@ -486,12 +581,18 @@ router.get("/maintenanceVisitTodos/:id", showMaintenanceVisitTodosById);
//get all maintenance visit todos by assetname
router.get("/maintenanceVisitTodosByAsset/:id", showMaintenanceVisitTodosByAsset);
//get all maintenance visit todos by template id
router.get("/maintenanceVisitTodosByTemplateId/:id", showMaintenanceVisitTodosByTemplateId);
// Update maintenance visit todo
router.put("/maintenanceVisitTodos", updateMaintenanceVisitTodo);
// Delete maintenance visit todos
router.delete("/maintenanceVisitTodos/:id", deleteMaintenanceVisitTodos);
// Delete maintenance visit todos by template id
router.delete("/maintenanceVisitTodosByTemplateID/:id", deleteMaintenanceVisitTodosBytemplateId);
// routes with issue slips:
@ -552,6 +653,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);
@ -594,12 +701,18 @@ router.delete("/issueVariantsByIssueSlipId/:id", deleteIssueVariantByIssueSlipId
// sign-up process
router.post('/signUp', userMiddleware.validateRegister, signUp);
// update password process
router.put('/updatePassword', updatePasswordById);
// login process
router.post('/login', login);
// get all users
router.get("/users", showUsers);
// get all users by user
router.get("/selectedUsersByUser/:id", showSelectedUsersByUser)
//get user by id
router.get("/user/:id", showUserById);

86
certs/fullchain.pem Normal file
View File

@ -0,0 +1,86 @@
-----BEGIN CERTIFICATE-----
MIIEJjCCAw6gAwIBAgISBH1fpnN5tMAmG9rSrKXMtWHmMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yNDAyMDcxMTI4MzFaFw0yNDA1MDcxMTI4MzBaMBwxGjAYBgNVBAMT
EXR1ZWl0YXBwLnR1ZWl0LmRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEp/Sf
OcRDk6oMEUZnRMyOpMdVWJB6Q0Hs3Ly9QHoEjCwJaPXo5dRLilcb9cgU7omZYoyN
Tf6ilHAvxGkr/k/saaOCAhUwggIRMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAU
BggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU9GpF
/YlVXjNNI8WDy9HBmmx6JMEwHwYDVR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsU
wsYwVQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vcjMuby5sZW5j
ci5vcmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5pLmxlbmNyLm9yZy8wHAYDVR0R
BBUwE4IRdHVlaXRhcHAudHVlaXQuZGUwEwYDVR0gBAwwCjAIBgZngQwBAgEwggEG
BgorBgEEAdZ5AgQCBIH3BIH0APIAdwA7U3d1Pi25gE6LMFsG/kA7Z9hPw/THvQAN
LXJv4frUFwAAAY2DiovMAAAEAwBIMEYCIQDUiw7jGx4k8y49+QeuGNUX6WciOA0s
Jipwvi+tjOumGgIhAN2jCoI3iQmpAYN3SvfieUPrAgd2X3RfZa0OzW91XYHWAHcA
ouK/1h7eLy8HoNZObTen3GVDsMa1LqLat4r4mm31F9gAAAGNg4qMPQAABAMASDBG
AiEAoA4lggVcXpGHlGLqJwVaKdcTsMEM9hsRaPnwtLeRNnMCIQCMUElVlogieFjP
hroL/raJrPrakqu9qOm0U3OW8aGPGzANBgkqhkiG9w0BAQsFAAOCAQEAFbGv7Omn
OWIW6/9zpasBhxOXNNxz5G1YDKnktgK9qrCius39oexbaxyRCgQj7Y2aVirjHEct
pFkpqdT8oRxOwym3UnTe6en/KqSzahuTLxKsWzvt+zYScEAbdv+ShAycojvuCbcN
NTzZzVbk5iT2GjPyzB+wBEbEILy1NFzf5sHBTsWOnbClidKpUvYgK6wuEoHb6DPP
cfI5OHRU/cOB6rljYZYzz4znhNYuwviBUXEf1qIOfPDxZnM0zrh6eJ4wRXZDdGkn
FQdmweAZn/dUpBEjRNuqSF4tGRKRtKZ3PQBNK35yAI4rFROJquhoQXxJK8XrAYyz
KJl4MTF4Rk5VMQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----

View File

@ -1,24 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEAzCCAuugAwIBAgIUVwDWxw7XeYOG6Y0uziRnZq2qri8wDQYJKoZIhvcNAQEL
BQAwKTELMAkGA1UEBhMCREUxGjAYBgNVBAMMEUxvY2FsaG9zdC1Sb290LUNBMB4X
DTIzMTAxNjA5MDMxMFoXDTI2MDgwNTA5MDMxMFowdzELMAkGA1UEBhMCREUxGzAZ
BgNVBAgMEkJhZGVuLVd1ZXJ0dGVtYmVyZzESMBAGA1UEBwwJVHVlYmluZ2VuMR0w
GwYDVQQKDBRFeGFtcGxlLUNlcnRpZmljYXRlczEYMBYGA1UEAwwPbG9jYWxob3N0
LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm9bmONlkhJ0s
ZT+OQR7di5Ypu1BoSIDd53Lwj4V9ws02ThYZUfFfYnuUmQBoGe1SAbvfTZ3dpLjM
slBqAxz2gxwTWZt5GteTxtmflvKqmAepybOBqAcFKPwMcjreJyuBxYwInwGfEFgG
YyRMH6VmDbC3vdxSz1NHpCkNL5ctfLQ4tkUShJCHPApqRp1F+BSBQVrpUwzIjn33
0whHOE346mK1TRI7Qqriyv482BfNCWdG6e8FhbGF6oIEcs7Y0YTcdxxmYHv/CkWI
/rtqETRpWOn3YVNGD5hKLchplD2ZaYLvFswij9dSbJUR6j0w5OqgmLO4fyyLZNgN
zARg4mQF7wIDAQABo4HUMIHRMB8GA1UdIwQYMBaAFAzjy/XAlhtTipXj30seDdNO
97OVMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMHcGA1UdEQRwMG6CCWxvY2FsaG9z
dIIRdHVlaXRhcHAudHVlaXQuZGWCDmxvY2FsaG9zdDo1MTcyghZ0dWVpdGFwcC50
dWVpdC5kZTo1MTcygg5sb2NhbGhvc3Q6NTE3M4IWdHVlaXRhcHAudHVlaXQuZGU6
NTE3MzAdBgNVHQ4EFgQU7JiUZESlRqvV9kqKqR+I+EdpA7QwDQYJKoZIhvcNAQEL
BQADggEBACvvYNLtaBoyM7Cy5WuaDaZtxbZvBqzORaNbHUqsGr5YLMlPwAoOj2cC
NmeyVX/I8lqZC0vma1UuyXp6v2ykkuAHL+PJrzhJiUb1KDhC8qBtnviaqB4ZNwQ5
m84BAiZGCS62q2vpFU4Ux/deDSiP8/P/cnRMCeN3DRtDumGq7/UBODbJuDw3Dt4U
CT/cLF2gDm40CkCLFyI6mRSxck3LUvsHV05yf31ikuPQ/M5WIcVHtbQ/qavgDMUT
SZmqKTg4NFVJGDhFQV/A0DBqC0qIVkszbrJSCwNTPyVID+jl9ukYoMQ4zjDwrwp5
ScOInLpNHHsAJd2b7V9jEptt7gSE1dk=
-----END CERTIFICATE-----

View File

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCb1uY42WSEnSxl
P45BHt2Llim7UGhIgN3ncvCPhX3CzTZOFhlR8V9ie5SZAGgZ7VIBu99Nnd2kuMyy
UGoDHPaDHBNZm3ka15PG2Z+W8qqYB6nJs4GoBwUo/AxyOt4nK4HFjAifAZ8QWAZj
JEwfpWYNsLe93FLPU0ekKQ0vly18tDi2RRKEkIc8CmpGnUX4FIFBWulTDMiOfffT
CEc4TfjqYrVNEjtCquLK/jzYF80JZ0bp7wWFsYXqggRyztjRhNx3HGZge/8KRYj+
u2oRNGlY6fdhU0YPmEotyGmUPZlpgu8WzCKP11JslRHqPTDk6qCYs7h/LItk2A3M
BGDiZAXvAgMBAAECggEAOatumfYVBSBW6Ab7gSzHZpsEyX0pgj8yHy8BR9NqJTck
1APIjfLpTfwWkwI8A/A3a03XhpUXixgaJBivCoTi0sUGgiAPUngZhzpMnSMjL0yS
sAI+RmyGo9KWVoVjZZJrnSvDmvgSIY25m2G4y/M8z28op9mLSY7zkZPhfc2Ptzg0
HO+SvyfxjZF7hwbblo41GzXuk0L2xxJN4xVfLti2R1yc+R9bdbEmzmgeECeZaHyQ
Y6XacbpafPZpC1bwNTv/0W8BVmXLG1FQo56zSTWOf8yt6gDBA970a++IPWNJzVBs
qbVjaDCHAh+sjgeT0+2tUhInVHUrNTgCXxmjWmYf/QKBgQDWOca4y6tEy5r2bl2F
OVdYYn44QUjccpV9WQ/UGzMfcrPcBxEWOYsddDkIdhK+ES9pU+dg0xjNVUGLkEKF
IuWuUZAtU9048r+xYVTUT1BepTKD9CfZ72dpenfQqUWctT6Pm/fj55NtcowlqXu1
IbbVcKv6sXmEj+FG7nb6olVcLQKBgQC6OnYBHFk4phQf1R7Zj+6khRYQTiy3z5Rh
3gIzQq8YseHsfiQZRVkVI4YM+y9tlCKuiDyD9AnJAm37j5C9FrFTJmuigu5xNok5
zG7Vz08Cm31Vrx/lO/flPDi8CYbjEvWHLu8F64gTiotneMSLy+Jex36A8Ez2dL9N
A/w3z3dQCwKBgEHti/vJKk9Evc8DTiK27+uSfDfB17OIS/tEknt7V3NhMHsRba/C
S87nurmg5Mm7rjSjDr0cmjBvAXn7Do28nKTWEyHwAlAJXPcw9hNUyW4nNvGnDTCj
3dZ3SzJbNcIxgSxfGp334cY4D2tzyk+HLaZoQ3UmczhZs0HKF7GwjcaNAoGBAIej
yQtqEHo4TPQakIu6UAE4hid+KQgAg3z87PFVIp+EAJ/2CGj3n7jL1Pljgtn3SYOB
60HY37+uq1jM6okvHB0KIN+PKgj/xdd5VUkZ49xsUE+2bC7VDOvEfzZGYh7GUlsS
DjproQNKp9rHlbCU4d5Sw4s6e3QO+L8ppe0oiSidAoGBAJCe7594SwX5JUwhdRuC
c42pzlqgzeDFCxVafNG5Qi3myPZjum2RbvJVP7Abc+1OqMnRlHrejJZl/eFOxkiD
baGMW+GneARmuwUGv8GWK4dsG+JNNtGKRh8D14ZzKokXKjcczh2xdnEbaK+6aQVt
HvwvS3sXX44fuJaDd7rTtKkU
-----END PRIVATE KEY-----

5
certs/privkey.pem Normal file
View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgAYAjn8GuqhyMWJyf
Bxt8nTpBWm3S06NgzF1sjJqFijmhRANCAASn9J85xEOTqgwRRmdEzI6kx1VYkHpD
QezcvL1AegSMLAlo9ejl1EuKVxv1yBTuiZlijI1N/qKUcC/EaSv+T+xp
-----END PRIVATE KEY-----

View File

@ -1,8 +1,8 @@
const clientsideConfig = {
// url: 'tueitapp.tueit.de',
// port: 8000,
// later for the server
//url: 'tueitapp.tueit.de',
url: 'localhost',
port: 3000,
};
export default clientsideConfig;
export default clientsideConfig;

View File

@ -1,24 +1,70 @@
<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';
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 modeChanged = computed(() => store.state.updateDarkMode);
const chosenAssetId = computed(() => store.state.chosenAssetId);
const asset = ref({});
const darkMode = ref('');
// 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);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getItemById();
});
</script>
<script>
export default {
name: "AssetSearch",
};
</script>
</script>
<style scoped>
.asset-search {
display: flex;
@ -78,5 +124,4 @@ export default {
background-color: #EBEBEB;
color: #000;
}
</style>
</style>

View File

@ -1,79 +1,127 @@
<template>
<section :class="['client-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Client</div>
<pre :class="['data', darkMode ? 'pre-darkmode' : 'pre-lightmode']">...</pre>
</section>
<section :class="['fixed-customer-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Customer:</div>
<pre :class="['data', darkMode ? 'pre-darkmode' : 'pre-lightmode']">{{ customer.customername }}</pre>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const customer = ref({});
const chosenCustomerId = computed(() => store.state.chosenCustomerId);
const darkMode = ref('');
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
// get customer from id
const getCustomerById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerById/${chosenCustomerId.value}`
);
customer.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getCustomerById();
});
</script>
<script>
export default {
name: "ClientSearch",
name: "ClientSearch",
};
</script>
<style scoped>
.client-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;
.fixed-customer-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;
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
background-color: #fff;
}
.label {
width: 2.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;
width: 4.188em;
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;
color: #FFFFFF;
}
.label-lightmode {
color: #000;
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;
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;
background-color: #212121;
color: #fff;
}
.pre-lightmode {
background-color: #EBEBEB;
color: #000;
background-color: #EBEBEB;
color: #000;
}
</style>
</style>

View File

@ -0,0 +1,153 @@
<template>
<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>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const filtered = computed(() => store.state.filtered);
const filteredTerm = computed(() => store.state.filteredByCustomer);
const customerFilter = ref(store.state.filteredByCustomer);
const darkMode = ref('');
// update filtered term
const updateFilterTerm = () => {
customerFilter.value = filteredTerm.value
}
const checkFiltered = () => {
if (!filtered.value) {
customerFilter.value = ''
filterList();
}
}
// update the filtered term in the store
const filterList = () => {
store.commit('updateFilterbyCustomer', customerFilter.value);
}
watch(filteredTerm, updateFilterTerm)
watch(filtered, checkFiltered)
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
});
</script>
<script>
export default {
name: "CustomerSearch",
};
</script>
<style scoped>
.customer-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: 2.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-customer {
border: none;
margin-left: 1rem;
}
.pre-customer {
margin-left: 1rem;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
</style>

View File

@ -2,31 +2,85 @@
<section :class="['dashboard', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['heading', darkMode ? 'heading-darkmode' : 'heading-lightmode']">My tasks</h2>
<div class="shortcuts">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="maintenance-visits"
value="My Maintenance Visits">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="production-orders"
value="My Production Orders">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="solutions" value="My Solutions">
<nuxt-link to="/maintenanceVisits" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToMVIList()">
<button :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="maintenance-visits">My
Maintenance Visits</button>
</nuxt-link>
<nuxt-link to="/productionOrders" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToPOIList()">
<button :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="production-orders">My
Production Orders</button>
</nuxt-link>
<!-- <input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="solutions"
value="My Solutions">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="issue-slips"
value="My Issue Slips">
value="My Issue Slips"> -->
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const darkMode = ref(true)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const modeChangedLocalstorage = computed(() => store.state.modeDashboard);
const darkMode = ref('');
const loggedInUsername = ref('');
const getSession = async () => {
if (modeChangedLocalstorage.value) {
store.commit('resetModeDashboardChanged');
}
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
const goToMVIList = () => {
store.commit('activateFilteredUserTerm');
store.commit('activateFiltered');
store.commit('changeToInstancelist');
};
const goToPOIList = () => {
store.commit('activateFilteredUserTerm');
store.commit('activateFiltered');
store.commit('changeToInstancelist');
};
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(modeChangedLocalstorage, getSession)
onMounted(async () => {
await getSession();
});
</script>
<script>
export default {
name: "Dashboard",
};
</script>
</script>
<style scoped>
.dashboard {
display: flex;
@ -72,7 +126,8 @@ export default {
gap: 2.5rem;
}
input {
input,
button {
display: flex;
flex-direction: row;
align-items: center;
@ -87,6 +142,10 @@ input {
font: 400 0.875rem/2rem Overpass, sans-serif;
}
button:hover {
cursor: pointer;
}
.input-darkmode {
color: #fff;
background-color: #343434;

View File

@ -0,0 +1,153 @@
<template>
<section :class="['employee-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Employee</div>
<pre v-if="!filtered"
:class="['data', 'pre-customer', darkMode ? 'pre-darkmode' : 'pre-lightmode']">{{ employeeFilter }}</pre>
<input v-if="filtered" v-model="employeeFilter" @change="filterList()"
:class="['data', 'input-customer', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const filtered = computed(() => store.state.filtered);
const filteredTerm = computed(() => store.state.filteredByCustomer);
const employeeFilter = ref(store.state.filteredByCustomer);
const darkMode = ref('');
// update filtered term
const updateFilterTerm = () => {
employeeFilter.value = filteredTerm.value
}
const checkFiltered = () => {
if (!filtered.value) {
employeeFilter.value = ''
filterList();
}
}
// update the filtered term in the store
const filterList = () => {
store.commit('updateFilterbyCustomer', employeeFilter.value);
}
watch(filteredTerm, updateFilterTerm)
watch(filtered, checkFiltered)
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
});
</script>
<script>
export default {
name: "EmployeeSearch",
};
</script>
<style scoped>
.employee-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: 2.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-customer {
border: none;
margin-left: 1rem;
}
.pre-customer {
margin-left: 1rem;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
</style>

View File

@ -0,0 +1,153 @@
<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, onMounted } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const filtered = computed(() => store.state.filtered);
const filteredTerm = computed(() => store.state.filteredByCustomer);
const issueStateFilter = ref(store.state.filteredByCustomer);
const darkMode = ref('');
// 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)
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
});
</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,34 +21,140 @@
<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="showPassword ? 'text' : 'password'" id="password-input" placeholder="*******">
<input v-if="!showPassword" type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
id="show-password-toggle" value="Show" @click="togglePasswordVisibility">
<input v-if="showPassword" type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']"
id="show-password-toggle" value="Hide" @click="togglePasswordVisibility">
</div>
</div>
</div>
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="login-button" value="Login">
<div v-if="isError" class="form-field-error-msg" id="password-field">
<label>
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']"> {{ errorMsg }} </div>
</label>
</div>
<div class="buttons">
<input type="button" :class="[darkMode ? 'button-darkmode' : 'button-lightmode']" id="login-button" value="Login"
@click="handleLogin">
</div>
</form>
</template>
<script setup>
import { ref } from 'vue';
// import { useRouter } from 'vue-router';
import { ref, onBeforeUnmount, onMounted } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../clientsideConfig.js';
import { useStore } from 'vuex';
const darkMode = ref(true)
const store = useStore();
const { signIn } = useAuth()
// const router = useRouter();
const darkMode = ref(true);
const isError = ref(false);
const showPassword = ref(false);
const errorMsg = ref('');
function setItem(item, value) {
if (process.client) {
localStorage.setItem(item, value)
return true
} else {
return false
}
}
const togglePasswordVisibility = () => {
showPassword.value = !showPassword.value;
}
const handleLogin = async () => {
isError.value = false;
errorMsg.value = '';
const username = document.getElementById('username-input').value;
const password = document.getElementById('password-input').value;
//const requestBody = {
const credentials = {
username: username,
password: password,
}
try {
let resBody = await signIn(credentials, { callbackUrl: '/home' })
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/login`);
setItem('logged-in-bool', true);
setItem('logged-in-user-id', response.data.id)
setItem('logged-in-user-username', response.data.username)
setItem('logged-in-user-registered', response.data.registered)
setItem('logged-in-user-lastLogin', response.data.lastLogin)
setItem('logged-in-user-fullName', response.data.fullName)
setItem('logged-in-user-email', response.data.email)
setItem('logged-in-user-phonenumber', response.data.phonenumber)
setItem('logged-in-user-address', response.data.address)
setItem('logged-in-user-city', response.data.city)
setItem('logged-in-user-postcode', response.data.postcode)
setItem('logged-in-user-adminBool', response.data.adminBool)
setItem('logged-in-user-technicianBool', response.data.technicianBool)
setItem('logged-in-user-readerBool', response.data.readerBool)
setItem('logged-in-user-darkMode', response.data.darkModeBool)
store.commit('setLocalStorageChanged');
store.commit('setModeChanged');
store.commit('setModeQuickAccessChanged');
store.commit('setModeDashboardChanged');
store.commit('setModeNavbarChanged');
store.commit('setModeLayoutChanged');
} catch (err) {
console.log(err.response.statusText);
}
} catch (err) {
// handle the error
isError.value = true;
errorMsg.value = 'Username or password is incorrect.';
document.getElementById('password-input').value = '';
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
onMounted(() => {
document.addEventListener('keyup', handleKeyUp);
document.getElementById('username-input').value = '';
document.getElementById('password-input').value = '';
});
onBeforeUnmount(() => {
document.removeEventListener('keyup', handleKeyUp);
});
const handleKeyUp = (event) => {
if (event.key === 'Enter') {
handleLogin();
}
};
</script>
<script>
export default {
name: "LoginForm",
};
</script>
}
</script>
<style scoped>
* {
@ -62,7 +168,8 @@ export default {
align-items: center;
justify-content: center;
width: 31.25rem;
height: 31.25rem;
min-height: 33rem;
height: fit-content;
border-radius: 0.625rem;
padding: 2.5rem 1.875rem;
gap: 1.875rem;
@ -78,6 +185,7 @@ export default {
background-color: #fff;
}
.title-field {
display: flex;
flex-direction: column;
@ -101,23 +209,27 @@ export default {
overflow: hidden;
}
#show-password-toggle:hover {
cursor: pointer;
}
.title {
margin: 0;
letter-spacing: 5%;
letter-spacing: 0.05rem;
white-space: nowrap;
font: 400 1.875rem/1.875rem Overpass, sans-serif;
}
.pre-darkmode,
.title-darkmode {
color: #fff;
color: #ffffff;
}
.pre-lightmode,
.title-lightmode {
color: #000;
color: #000000;
}
.login-field {
display: flex;
flex-direction: column;
@ -127,6 +239,7 @@ export default {
gap: 1.25rem;
}
.form-field {
display: flex;
flex-direction: column;
@ -162,14 +275,6 @@ label {
overflow: hidden;
}
.icon-darkmode>img {
filter: invert(100%);
}
.icon-lightmode>img {
filter: invert(0%);
}
#username-icon>img {
width: auto;
height: 0.9375rem;
@ -180,17 +285,25 @@ label {
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;
color: #ffffff;
}
.label-lightmode {
color: #000;
color: #000000;
}
.input-field {
@ -214,46 +327,76 @@ label {
background-color: #EBEBEB;
}
input[type=text] {
input[type=text],
input[type=password] {
width: 100%;
height: 100%;
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

@ -13,16 +13,49 @@
<script setup>
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const darkMode = ref(true)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const modeChangedLocalstorage = computed(() => store.state.modeQuickAccess);
const darkMode = ref('');
const getSession = async () => {
if (modeChangedLocalstorage.value) {
store.commit('resetModeQuickAccessChanged');
}
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(modeChangedLocalstorage, getSession)
onMounted(async () => {
await getSession();
});
</script>
<script>
export default {
name: "QuickAccess",
};
</script>
</script>
<style scoped>

View File

@ -1,24 +1,87 @@
<template>
<section :class="['template-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<section v-if="notAllInstancesIcon" :class="['template-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Template:</div>
<pre :class="['data', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Template name</pre>
<pre :class="['data', darkMode ? 'pre-darkmode' : 'pre-lightmode']">{{ template.name }}</pre>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const route = useRoute()
const id = computed(() => route)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const template = ref({});
const chosenMVTId = computed(() => store.state.chosenMVTId);
const chosenPOTId = computed(() => store.state.chosenPOTId);
const notAllInstancesIcon = computed(() => store.state.notAllInstancesIcon);
const darkMode = ref('');
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
// get maintenance visit template from id
const getTById = async () => {
if (notAllInstancesIcon.value) {
if (id.value.fullPath == '/maintenanceVisits') {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getMaintenanceVisitTemplate/${chosenMVTId.value}`
);
template.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else if (id.value.fullPath == '/productionOrders') {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getProductionOrderTemplate/${chosenPOTId.value}`
);
template.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getTById();
});
</script>
<script>
export default {
name: "TemplateSearch",
};
</script>
</script>
<style scoped>
.template-search {
display: flex;
@ -78,5 +141,4 @@ export default {
background-color: #EBEBEB;
color: #000;
}
</style>
</style>

View File

@ -1,117 +1,588 @@
<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">
<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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<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
: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
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Supplier offer</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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']">
Customer offer</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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']">
Customer order</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Supplier order</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Ingress</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Egress</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Ingress bill</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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
:class="['Action', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Action-darkmode' : 'Action-lightmode']">
Egress bill</td>
<td
:class="['Date', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Date-darkmode' : 'Date-lightmode']">
<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';
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 modeChanged = computed(() => store.state.updateDarkMode);
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('')
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;
if (newOIs.value.length != 0) {
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,
});
if (newOIs.value.length != 0) {
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);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
getIssueSlipById();
});
</script>
<script>
export default {
name: "Accounting",
};
</script>
</script>
<style scoped>
.accounting-information {
display: flex;
@ -132,6 +603,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;
@ -202,6 +698,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 {
@ -257,4 +788,5 @@ tr#row-2 {
.Comments {
width: 40%;
}</style>
}
</style>

View File

@ -1,31 +1,59 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['asset-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Asset name</h2>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['asset-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
item.assetName }}</h2>
<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>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</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"
@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="location">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Location:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ item.location }}</pre>
<input v-if="editable" v-model="item.location" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="info">
<div class="id-type">
<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>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.primaryID }}</pre>
</div>
<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']"> {{ item.type }}</pre>
<input v-if="editable" v-model="item.type" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="data-field" id="remote-location">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Remote location:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<div class="remoteLocation-state">
<div class="data-field" id="remote-location">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Remote location:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.remoteLocation }}</pre>
<input v-if="editable" v-model="item.remoteLocation" @change="updateConfigItem()"
: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>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.state }}</pre>
<input v-if="editable" v-model="item.state" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
<div class="rectangle-container">
@ -36,40 +64,323 @@
<div class="additional">
<div class="description">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Description:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">...</pre>
<input v-model="item.description" :readonly="!editable" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">
</div>
</div>
<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="item.notes" :readonly="!editable" @change="updateConfigItem()"
: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="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="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">
{{ cust.customername }}
</option>
</select>
</div>
<div class="data-field" id="location">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Location:</pre>
<input v-model="newLocation" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="info">
<div class="id-type">
<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 class="data-field" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<input v-model="newType" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="remoteLocation-state">
<div class="data-field" id="remote-location">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Remote location:</pre>
<input v-model="newRemoteLocation" @change="updateAsset()"
: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>
<input v-model="newState" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
<div class="rectangle-container">
<div :class="['rectangle', darkMode ? 'rectangle-darkmode' : 'rectangle-lightmode']"></div>
</div>
</div>
<div class="asset-data">
<div class="additional">
<div class="description">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Description:</h3>
<input v-model="newDescription" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">
</div>
</div>
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<input v-model="newNotes" @change="updateAsset()"
: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 modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenAssetId = computed(() => store.state.chosenAssetId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('');
const item = ref({});
const customer = ref({});
const configItems = ref([]);
const customers = ref([]);
const newAssetName = ref('');
const newCustomerID = ref('');
const newCustomer = ref('');
const newLocation = ref('');
const newRemoteLocation = ref('');
const newType = ref('');
const newDescription = ref('');
const newNotes = ref('');
const newState = ref('');
// get config item from id
const getItemById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getConfigItem/${chosenAssetId.value}`
);
item.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update asset fields in the store
const updateAsset = () => {
const asset = {
assetName: newAssetName.value,
customerId: newCustomerID.value,
customer: newCustomer.value,
location: newLocation.value,
remoteLocation: newRemoteLocation.value,
type: newType.value,
description: newDescription.value,
notes: newNotes.value,
state: newState.value
};
store.commit('updateAssetComponent', asset);
}
//update data
const updateConfigItem = async () => {
if (item.value.assetName.trim() === "") {
alert("Please add a config item name!");
return;
} else {
var counter = 0;
// check if config item name already exists
configItems.value.forEach(ci => {
if (ci.assetName === item.value.assetName) {
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;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateConfigItem`,
{
primaryID: item.value.primaryID,
assetName: item.value.assetName,
customerID: item.value.customerID,
customer: item.value.customer,
location: item.value.location,
remoteLocation: item.value.remoteLocation,
type: item.value.type,
description: item.value.description,
notes: item.value.notes,
state: item.value.state,
lastView: item.value.lastView,
user: item.value.user,
hardwareBool: item.value.hardwareBool,
model: item.value.model,
serialnumber: item.value.serialnumber,
CPU: item.value.CPU,
RAM: item.value.RAM,
storageConfiguration: item.value.storageConfiguration,
miscellaneous: item.value.miscellaneous,
softwareBool: item.value.softwareBool,
software: item.value.software,
version: item.value.version,
license: item.value.license,
networkBool: item.value.networkBool,
IPv4: item.value.IPv4,
IPv6: item.value.IPv6,
MAC: item.value.MAC,
subnetmask: item.value.subnetmask,
}
)
await getItemById();
} 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 confirmDeleteAsset = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this config item? It cannot be undone!")) {
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);
}
} else {
store.commit('undoDelete');
}
}
}
//get all config items
const getConfigItems = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllConfigItems`);
configItems.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/${item.value.customer}`);
customer.value = response.data;
item.value.customerID = customer.value.customerID;
} catch (err) {
console.log(err.response.statusText);
}
await updateConfigItem();
}
// 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);
}
updateAsset();
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 2000);
}
// include delay to avoid 503 error
const triggerBackendCallsWithSmallDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 500);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(deleteBool, confirmDeleteAsset);
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
triggerBackendCallsWithSmallDelay(getItemById);
triggerBackendCallsWithDelay(getConfigItems);
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "Asset",
};
}
</script>
<style scoped>
.information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 100%;
padding: 1.25rem 1.875rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
@ -83,7 +394,6 @@ export default {
background-color: #fff;
}
.asset-name {
align-self: stretch;
padding: 1rem 0;
@ -93,6 +403,16 @@ export default {
sans-serif;
}
.asset-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-darkmode {
color: #fff;
}
@ -107,11 +427,19 @@ 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;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.data-field#street-name {
width: 70%;
}
@ -133,9 +461,13 @@ export default {
color: #000;
}
.input {
border: none;
}
.data {
display: flex;
flex-direction: row;
overflow-x: auto;
align-items: flex-start;
padding: 0 0.625rem;
border-radius: 0.3125rem;
@ -157,6 +489,9 @@ export default {
.data#notes,
.data#description {
align-self: stretch;
/* width: 45%; */
scrollbar-width: none;
overflow-x: auto;
}
.asset-data {
@ -167,7 +502,7 @@ export default {
align-self: stretch;
}
.client-location,
.customer-location,
.info {
display: flex;
flex-direction: column;
@ -203,7 +538,8 @@ export default {
color: #000;
}
.id-type {
.id-type,
.remoteLocation-state {
display: flex;
flex-direction: row;
align-items: center;
@ -243,4 +579,20 @@ export default {
.rectangle-lightmode {
background-color: #EBEBEB;
}
</style>
.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,37 +1,175 @@
<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">
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Solution', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Solution-darkmode' : 'Solution-lightmode']">
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">
<td
:class="['Solution', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Solution-darkmode' : 'Solution-lightmode']">
...</td>
<td :class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Solution', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Solution-darkmode' : 'Solution-lightmode']">
Solution</th>
<th :class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode']">Type</th>
</tr>
<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']">
<nuxt-link to="/solutions" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-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';
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 modeChanged = computed(() => store.state.updateDarkMode);
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('')
//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);
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
await getItemById();
});
</script>
<script>
export default {
name: "AssetSolutionList",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -54,6 +192,70 @@ 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;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.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;
@ -70,6 +272,10 @@ export default {
gap: 0.625rem;
}
#nuxt-link {
text-decoration: none;
}
.tr-head-darkmode {
border-top: none;
border-bottom: 0.0625rem solid #000000;
@ -168,4 +374,5 @@ th {
.label-lightmode {
color: #000;
}</style>
}
</style>

View File

@ -1,54 +1,155 @@
<template>
<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>
<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">
<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>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
...</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
...</td>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
...</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<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>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr v-for="item in configItemList" :key="item.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']">
<td
:class="['Customer', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Customer-darkmode' : 'Customer-lightmode']">
{{ item.customer }}
</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/assets" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenAsset(item.primaryID)">
{{ item.assetName }}
</nuxt-link>
</td>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
{{ item.type }}</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
{{ item.state }}</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']"> {{ item.user }}</td>
</tr>
</tbody>
</table>
</div>
</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';
// get accesss to the store
const store = useStore()
const modeChanged = computed(() => store.state.updateDarkMode);
const goToChosenAsset = (id) => {
store.commit('setChosenAsset', id);
store.commit('changeToAsset');
};
const customerFilter = computed(() => store.state.filteredByCustomer);
const assetSearchable = computed(() => store.state.searchable);
const assetSearchFilter = ref('');
const darkMode = ref('')
const configItemList = ref([]);
// update search term
const updateSearchTerm = async () => {
assetSearchFilter.value = '';
await getConfigItems();
}
//get all config items
const getConfigItems = async () => {
if (!(customerFilter.value === '')) {
await getFilteredConfigItemsByCustomer();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllConfigItems`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all config items based on the searched customer
const getFilteredConfigItemsByCustomer = async () => {
try {
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);
}
}
//get all config items based on the searched asset name
const searchConfigItem = async () => {
if (assetSearchFilter.value === '') {
await getConfigItems();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedConfigItemsByAsset/${assetSearchFilter.value}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(customerFilter, getConfigItems);
watch(assetSearchable, updateSearchTerm);
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
await getConfigItems();
});
</script>
<script>
export default {
name: "AssetTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -56,13 +157,57 @@ 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);
}
.asset-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-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.div-darkmode {
background-color: #2c2c2c;
}
@ -128,15 +273,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;
}
@ -191,10 +336,34 @@ th {
letter-spacing: 0.05em;
}
.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;
}
.label-darkmode {
color: #FFFFFF;
}
.label-lightmode {
color: #000;
}</style>
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
</style>

View File

@ -1,184 +0,0 @@
<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">
<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="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :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>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
...</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "AssetTableNoClient",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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);
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Name {
width: 50%;
}
.Name-darkmode {
border-right: 0.0625rem solid #000000;
}
.Name-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Type {
width: 20%;
}
.Type-darkmode {
border-right: 0.0625rem solid #000000;
}
.Type-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.State {
width: 20%;
}
.State-darkmode {
border-right: 0.0625rem solid #000000;
}
.State-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.User {
width: 10%;
}
.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;
}
</style>

View File

@ -1,219 +0,0 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['client-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Client name</h2>
<div class="data-field" id="client-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="contact">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Contact:</h3>
<div class="data-field" id="contact-person">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Contact person:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="data-field" id="e-mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">E-Mail:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="data-field" id="phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Phone number:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
</div>
<div class="address">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Address:</h3>
<div class="street-address">
<div class="data-field" id="street-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Street:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="data-field" id="street-no">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">No.:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
</div>
<div class="data-field" id="postal-code">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Postcode:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">City:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
</div>
</div>
<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>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "Client",
};
</script>
<style scoped>
.information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 100%;
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;
}
.client-name {
align-self: stretch;
padding: 1.25rem 0;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.h2-darkmode {
color: #fff;
}
.h2-lightmode {
color: #000;
}
.data-field {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
.data-field#client-id {
padding: 0.625rem 1.875rem;
}
.data-field#street-name {
width: 70%;
}
.data-field#street-no {
width: 30%;
}
.label {
letter-spacing: 5%;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.pre-darkmode {
color: #fff;
}
.pre-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;
background-color: #212121;
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;
}
.data#notes {
align-self: stretch;
}
.client-data {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
align-self: stretch;
padding: 0 0.625rem;
}
.contact,
.address {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 50%;
padding: 1.25rem 0.625rem;
border-radius: 0.3125rem;
}
.area-title {
letter-spacing: 5%;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.h3-darkmode {
color: #fff;
}
.h3-lightmode {
color: #000;
}
.street-address {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
align-self: stretch;
padding: 0 1.875rem 0 0;
gap: 0.625rem;
}
.notes {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
align-self: stretch;
padding: 0.625rem 1.875rem 0.625rem 1.25rem;
}</style>

View File

@ -1,130 +0,0 @@
<template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<table class="data-table" id="client-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>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
...</td>
</tr>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "ClientTable",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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);
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.ID {
width: 40%;
}
.ID-darkmode {
border-right: 0.0625rem solid #000000;
}
.ID-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Name {
width: 60%;
}
</style>

View File

@ -0,0 +1,871 @@
<template>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div>
<h2 v-if="!editable" :class="['customer-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{ cust.customername }}
</h2>
<input v-if="editable" v-model="cust.customername" @change="updateCustomer()"
:class="['data', 'customer-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
</div>
<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']">{{ cust.customerID }}</pre>
</div>
<div class="customer-data">
<div class="contact">
<pre :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Contacts:</pre>
<div class="data-field" id="contact-person">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Contact person:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.contactperson }}</pre>
<input v-if="editable" v-model="cust.contactperson" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="first-e-mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. E-Mail:</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.EMail }}</pre>
<input v-if="editable" v-model="cust.EMail" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="first-phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. Phone number:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.phonenumber }}</pre>
<input v-if="editable" v-model="cust.phonenumber" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
&nbsp;
<div class="data-field" id="second-e-mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. E-Mail:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.secondEMail }}</pre>
<input v-if="editable" v-model="cust.secondEMail" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="second-phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. Phone number:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.secondPhonenumber }}</pre>
<input v-if="editable" v-model="cust.secondPhonenumber" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
&nbsp;
<div class="data-field" id="third-e-mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. E-Mail:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.thirdEMail }}</pre>
<input v-if="editable" v-model="cust.thirdEMail" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="third-phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. Phone number:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.thirdPhonenumber }}</pre>
<input v-if="editable" v-model="cust.thirdPhonenumber" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="address">
<pre :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Addresses:</pre>
<div class="street-address">
<div class="data-field" id="street-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. Street:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.street }}</pre>
<input v-if="editable" v-model="cust.street" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="street-no">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. No.:</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.no }}</pre>
<input v-if="editable" v-model="cust.no" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-city">
<div class="data-field" id="postal-code">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. Postcode:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.postcode }}</pre>
<input v-if="editable" v-model="cust.postcode" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. City:</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.city }}</pre>
<input v-if="editable" v-model="cust.city" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
&nbsp;
<div class="street-address">
<div class="data-field" id="street-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. Street:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.secondStreet }}</pre>
<input v-if="editable" v-model="cust.secondStreet" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="street-no">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. No.:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.secondNo }}</pre>
<input v-if="editable" v-model="cust.secondNo" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-city">
<div class="data-field" id="postal-code">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. Postcode:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.secondPostcode }}</pre>
<input v-if="editable" v-model="cust.secondPostcode" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. City:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.secondCity }}</pre>
<input v-if="editable" v-model="cust.secondCity" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
&nbsp;
<div class="street-address">
<div class="data-field" id="street-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. Street:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.thirdStreet }}</pre>
<input v-if="editable" v-model="cust.thirdStreet" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="street-no">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. No.:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.thirdNo }}</pre>
<input v-if="editable" v-model="cust.thirdNo" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-city">
<div class="data-field" id="postal-code">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. Postcode:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.thirdPostcode }}</pre>
<input v-if="editable" v-model="cust.thirdPostcode" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. City:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ cust.thirdCity }}</pre>
<input v-if="editable" v-model="cust.thirdCity" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="notes">
<pre :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</pre>
<input v-model="cust.notes" :readonly="!editable" @change="updateCustomer()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div>
<input v-model="newCustomername"
:class="['data', 'customer-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
</div>
<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="customer-data">
<div class="contact">
<pre :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Contacts:</pre>
<div class="data-field" id="contact-person">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Contact person:</pre>
<input v-model="newContactperson" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="first-e-mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. E-Mail:</pre>
<input v-model="newEMail" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="first-phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. Phone number:</pre>
<input v-model="newPhonenumber" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
&nbsp;
<div class="data-field" id="second-e-mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. E-Mail:</pre>
<input v-model="newSecondEMail" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="second-phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. Phone number:</pre>
<input v-model="newSecondPhonenumber"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
&nbsp;
<div class="data-field" id="third-e-mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. E-Mail:</pre>
<input v-model="newThirdEMail" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="third-phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. Phone number:</pre>
<input v-model="newThirdPhonenumber"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="address">
<pre :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Addresses:</pre>
<div class="street-address">
<div class="data-field" id="street-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. Street:</pre>
<input v-model="newStreet" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="street-no">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. No.:</pre>
<input v-model="newNo" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-city">
<div class="data-field" id="postal-code">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. Postcode:</pre>
<input v-model="newPostcode" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">1. City:</pre>
<input v-model="newCity" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
&nbsp;
<div class="street-address">
<div class="data-field" id="street-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. Street:</pre>
<input v-model="newSecondStreet" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="street-no">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. No.:</pre>
<input v-model="newSecondNo" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-city">
<div class="data-field" id="postal-code">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. Postcode:</pre>
<input v-model="newSecondPostcode"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">2. City:</pre>
<input v-model="newSecondCity" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
&nbsp;
<div class="street-address">
<div class="data-field" id="street-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. Street:</pre>
<input v-model="newThirdStreet" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="street-no">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. No.:</pre>
<input v-model="newThirdNo" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-city">
<div class="data-field" id="postal-code">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. Postcode:</pre>
<input v-model="newThirdPostcode" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">3. City:</pre>
<input v-model="newThirdCity" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="notes">
<pre :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</pre>
<input v-model="newNotes" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</section>
<section v-if="addBool" id="saveNewItem">
<button :class="[darkMode ? 'saveNewItem-darkmode' : 'saveNewItem-lightmode']" @click="addCustomer()">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 modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenCustomerId = computed(() => store.state.chosenCustomerId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('')
const cust = ref({});
const customers = ref([]);
const newCustomername = ref('');
const newCustomerID = ref('');
const newContactperson = ref('');
const newEMail = ref('');
const newSecondEMail = ref('');
const newThirdEMail = ref('');
const newPhonenumber = ref('');
const newSecondPhonenumber = ref('');
const newThirdPhonenumber = ref('');
const newStreet = ref('');
const newNo = ref('');
const newPostcode = ref('');
const newCity = ref('');
const newSecondStreet = ref('');
const newSecondNo = ref('');
const newSecondPostcode = ref('');
const newSecondCity = ref('');
const newThirdStreet = ref('');
const newThirdNo = ref('');
const newThirdPostcode = ref('');
const newThirdCity = ref('');
const newNotes = ref('');
// get customer from id
const getCustomerById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerById/${chosenCustomerId.value}`
);
cust.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//update data
const updateCustomer = async () => {
if (cust.value.customername.trim() === "") {
alert("Please add a customer name!");
return;
} else {
var counter = 0;
// check if customer name already exists
customers.value.forEach(c => {
if (c.customername === cust.value.customername) {
counter += 1;
}
});
if (counter == 2) {
alert("This customer name already exists. Please choose an unique customer name or modify respectively delete the old one!");
cust.value.customername = '';
return;
}
if (!validateEMail(cust.value.EMail)) {
alert("Please add a valid first email!");
return;
}
if (!validatePhonenumber(cust.value.phonenumber)) {
alert("Please add a valid first phonenumber!");
return;
}
if (!validateEMail(cust.value.secondEMail)) {
alert("Please add a valid second email!");
return;
}
if (!validatePhonenumber(cust.value.secondPhonenumber)) {
alert("Please add a valid second phonenumber!");
return;
}
if (!validateEMail(cust.value.thirdEMail)) {
alert("Please add a valid third email!");
return;
}
if (!validatePhonenumber(cust.value.thirdPhonenumber)) {
alert("Please add a valid third phonenumber!");
return;
}
if (!validatePostcode(cust.value.postcode)) {
alert("Please add a valid first postcode!");
return;
}
if (!validatePostcode(cust.value.secondPostcode)) {
alert("Please add a valid second postcode!");
return;
}
if (!validatePostcode(cust.value.thirdPostcode)) {
alert("Please add a valid third postcode!");
return;
}
if (cust.value.contactperson.trim() === "") {
alert("Please add a contactperson!");
return;
}
if (cust.value.street.trim() === "") {
alert("Please add a first street!");
return;
}
if (cust.value.no.trim() === "") {
alert("Please add a first number!");
return;
}
if (cust.value.city.trim() === "") {
alert("Please add a first city!");
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateCustomer`,
{
customerID: cust.value.customerID,
customername: cust.value.customername,
contactperson: cust.value.contactperson,
EMail: cust.value.EMail,
secondEMail: cust.value.secondEMail,
thirdEMail: cust.value.thirdEMail,
phonenumber: cust.value.phonenumber,
secondPhonenumber: cust.value.secondPhonenumber,
thirdPhonenumber: cust.value.thirdPhonenumber,
street: cust.value.street,
no: cust.value.no,
postcode: cust.value.postcode,
city: cust.value.city,
secondStreet: cust.value.secondStreet,
secondNo: cust.value.secondNo,
secondPostcode: cust.value.secondPostcode,
secondCity: cust.value.secondCity,
thirdStreet: cust.value.thirdStreet,
thirdNo: cust.value.thirdNo,
thirdPostcode: cust.value.thirdPostcode,
thirdCity: cust.value.thirdCity,
notes: cust.value.notes,
}
)
await getCustomerById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
// add new customer
const addCustomer = async () => {
// check if all input data is valid
if (newCustomername.value.trim() === "") {
alert("Please add a customer name!");
return;
} else {
var counter = 0;
// check if customer name already exists
customers.value.forEach(c => {
if (c.customername === newCustomername.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This customer name already exists. Please choose an unique customer name or modify respectively delete the old one!");
return;
}
}
if (!validateEMail(newEMail.value)) {
alert("Please add a valid first email!");
return;
}
if (!validatePhonenumber(newPhonenumber.value)) {
alert("Please add a valid first phonenumber!");
return;
}
if (!validateEMail(newSecondEMail.value)) {
alert("Please add a valid second email!");
return;
}
if (!validatePhonenumber(newSecondPhonenumber.value)) {
alert("Please add a valid second phonenumber!");
return;
}
if (!validateEMail(newThirdEMail.value)) {
alert("Please add a valid third email!");
return;
}
if (!validatePhonenumber(newThirdPhonenumber.value)) {
alert("Please add a valid third phonenumber!");
return;
}
if (!validatePostcode(newPostcode.value)) {
alert("Please add a valid first postcode!");
return;
}
if (!validatePostcode(newSecondPostcode.value)) {
alert("Please add a valid second postcode!");
return;
}
if (!validatePostcode(newThirdPostcode.value)) {
alert("Please add a valid third postcode!");
return;
}
if (newContactperson.value.trim() === "") {
alert("Please add a contactperson!");
return;
}
if (newStreet.value.trim() === "") {
alert("Please add a first street!");
return;
}
if (newNo.value.trim() === "") {
alert("Please add a first number!");
return;
}
if (newCity.value.trim() === "") {
alert("Please add a first city!");
return;
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addCustomer`,
{
customername: newCustomername.value,
contactperson: newContactperson.value,
EMail: newEMail.value,
secondEMail: newSecondEMail.value,
thirdEMail: newThirdEMail.value,
phonenumber: newPhonenumber.value,
secondPhonenumber: newSecondPhonenumber.value,
thirdPhonenumber: newThirdPhonenumber.value,
street: newStreet.value,
no: newNo.value,
postcode: newPostcode.value,
city: newCity.value,
secondStreet: newSecondStreet.value,
secondNo: newSecondNo.value,
secondPostcode: newSecondPostcode.value,
secondCity: newSecondCity.value,
thirdStreet: newThirdStreet.value,
thirdNo: newThirdNo.value,
thirdPostcode: newThirdPostcode.value,
thirdCity: newThirdCity.value,
notes: newNotes.value,
});
store.commit('resetStore');
store.commit('changeToCustomerlist');
} 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 confirmDeleteCustomer = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this customer? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteCustomer/${chosenCustomerId.value}`);
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToCustomerlist');
} catch (err) {
console.log(err.response.statusText);
}
} else {
store.commit('undoDelete');
}
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
// to validate the email address
const validateEMail = (email) => {
const emailRegex = new RegExp(/^[A-Za-z0-9_!#$%&'*+\/=?`{|}~^.-]+@[A-Za-z0-9.-]+$/, "gm");
if (email === "") {
return true
}
return emailRegex.test(email);
}
// to validate the phonenumber
const validatePhonenumber = (number) => {
const mobilephonenumberRegex = new RegExp(/^(((((00|\+){1,2})49([ \-/]?|[ \()/]?))|0)[1]([0-2]|[4-7])([0-9]{1})([ \-/]?|[ \()/]?)([0-9]{8}))$/, "gm");
const landlineRegex = new RegExp(/^0(30|40|69|89|20[12389]|21[24]|228|234|335|340|3[3-9][15]|906|[2-9][1-9]1|3(?:3(?:[0237][127]|0[3-6]|2[89]|3[458]|[46][1246]|7[589]|8[1256]|9[145])|4(?:[2347][135]|[34]7|[69][146]|48|62|76|93)|5(?:[04679][14]|[238][135]|[2469]2|[4789]6|[278]8|63|73|37|29)|6(?:[024689][13]|[03789]5|06|2[2489]|3[1246]|44|47|7[1279]|82|86)|7(?:[236][135]|2[2467]|37|4[145]|62|64|7[1-4])|8(?:[234678]1|3[468]|4[347]|6[035-9]|7[467]|83|86)|9(?:[236][135]|[04689]4|[04789]1|[03468]7|02|09|28|4[369]|6[2689]|73|76|96|98))|3[3-9][0-9]{3}|13[078]|180[235]|18[01]|19[0-9]{3}|[789]00|[2-9][0-9]{3})([0-9]{1,})$/, "gm");
if (number === "") {
return true
}
if (mobilephonenumberRegex.test(number)) {
return true
} else if (landlineRegex.test(number)) {
return true;
}
return false;
}
// to validate the postcode
const validatePostcode = (postcode) => {
const postcodeRegex = new RegExp(/^\d{5}$/);
if (postcode === "") {
return true
}
return postcodeRegex.test(postcode);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(deleteBool, confirmDeleteCustomer);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getCustomerById();
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "Customer",
};
</script>
<style scoped>
.information {
display: flex;
flex-direction: column;
align-items: stretch;
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: #ffffff;
}
.customer-name {
align-self: stretch;
padding: 1rem 0;
margin: 1rem;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.customer-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-darkmode {
color: #fff;
}
.h2-lightmode {
color: #000;
}
.data-field {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
.data-field#customer-id {
padding: 0.625rem 1.875rem;
}
.data-field#street-no {
padding-left: 3.2rem;
}
.label {
letter-spacing: 0.03rem;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
pre {
margin: 0;
}
.pre-darkmode {
color: #ffffff;
}
.pre-lightmode {
color: #000000;
}
.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;
}
.data {
display: flex;
flex-direction: row;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
background-color: #212121;
align-items: center;
justify-content: flex-start;
letter-spacing: 5%;
font: 400 0.75rem/250% Overpass, sans-serif;
}
.data-darkmode {
background-color: #212121;
color: #ffffff;
}
.data-lightmode {
background-color: #ebebeb;
color: #000000;
}
.customer-data {
display: flex;
flex: auto;
flex-direction: row;
padding: 1.25rem 1.875rem;
align-items: center;
justify-content: stretch;
gap: 0.625rem
}
.contact,
.address {
display: flex;
flex: auto;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 0.625rem;
}
.area-title {
letter-spacing: 0.03rem;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.h3-darkmode {
color: #ffffff;
}
.h3-lightmode {
color: #000000;
}
.street-address,
.postcode-city {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
align-self: stretch;
gap: 0.625rem;
}
.notes {
display: flex;
flex-direction: column;
padding: 0.625rem 1.875rem;
align-items: flex-start;
justify-content: center;
gap: 0.625rem;
}
#notes {
align-self: stretch;
}
.input {
border: none;
}
</style>

View File

@ -0,0 +1,433 @@
<template>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['department-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{ dep.name
}}</h2>
<input v-if="editable" v-model="dep.name" @change="updateDepartment()"
:class="['data', 'department-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="data-group">
<div class="data-field" id="id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ dep.primaryID }}</pre>
</div>
<div class="data-field" id="customer-id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ dep.customername }}</pre>
</div>
<div class="data-field" id="head">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Head:</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ dep.head }}</pre>
<input v-if="editable" v-model="dep.head" @change="updateDepartment()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="notes">
<pre :class="['area-title', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Notes:</pre>
<input v-model="dep.notes" :readonly="!editable" @change="updateDepartment()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<input v-model="newName"
:class="['data', 'department-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="data-group">
<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 class="data-field" id="customer-id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ chosenCustomerId }}</pre>
</div>
<div class="data-field" id="head">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Head:</pre>
<input v-model="newHead"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="notes">
<pre :class="['area-title', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Notes:</pre>
<input v-model="newNotes"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</section>
<section v-if="addBool" id="saveNewItem">
<button :class="[darkMode ? 'saveNewItem-darkmode' : 'saveNewItem-lightmode']" @click="addDepartment()">Save</button>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenCustomerId = computed(() => store.state.chosenCustomerId);
const chosenDepartmentId = computed(() => store.state.chosenDepartmentId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('')
const dep = ref({});
const departments = ref({});
const customer = ref({});
const newName = ref('');
const newHead = ref('');
const newNotes = ref('');
// get department from id
const getDepartmentById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getDepartment/${chosenDepartmentId.value}`
);
dep.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//update data
const updateDepartment = async () => {
if (dep.value.name.trim() === "") {
alert("Please add a department name!");
return;
} else {
var counter = 0;
// check if department name already exists
departments.value.forEach(d => {
if (d.name === dep.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This department name already exists. Please choose an unique department name or modify respectively delete the old one!");
dep.value.name = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateDepartment`,
{
primaryID: dep.value.primaryID,
name: dep.value.name,
head: dep.value.head,
notes: dep.value.notes,
}
)
await getDepartmentById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
// add new department
const addDepartment = async () => {
// check if all input data is valid
if (newName.value.trim() === "") {
alert("Please add an department name!");
return;
} else {
var counter = 0;
// check if department name already exists
departments.value.forEach(c => {
if (c.name === newName.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This department name already exists. Please choose an unique department name or modify respectively delete the old one!");
return;
}
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addDepartment`,
{
customerID: chosenCustomerId.value,
customername: customer.value.customername,
name: newName.value,
head: newHead.value,
notes: newNotes.value,
});
store.commit('resetStoreNotCustomer');
store.commit('changeToDepartmentlist');
} catch (err) {
console.log(err.response.statusText);
}
}
// get customer from id
const getCustomerById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerById/${chosenCustomerId.value}`
);
customer.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//get all departments
const getDepartments = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedDepartmentByCustomer/${chosenCustomerId.value}`
);
departments.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
const confirmDeleteDepartment = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this department? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteDepartment/${chosenDepartmentId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStoreNotCustomer');
store.commit('changeToDepartmentlist');
} else {
store.commit('undoDelete');
}
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession);
watch(deleteBool, confirmDeleteDepartment);
onMounted(async () => {
getSession();
await getDepartmentById();
triggerBackendCallsWithDelay(getCustomerById);
triggerBackendCallsWithDelay(getDepartments);
});
</script>
<script>
export default {
name: "CustomerDepartment",
};
</script>
<style scoped>
* {
box-sizing: border-box;
margin: 0;
}
.information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 100%;
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: #ffffff;
}
.input {
border: none;
}
.department-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;
}
.department-name {
align-self: stretch;
padding: 1rem 0;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.h2-darkmode {
color: #fff;
}
.h2-lightmode {
color: #000;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.data-group {
display: flex;
flex: auto;
width: 100%;
flex-direction: row;
padding: 0.625rem 0;
align-items: center;
justify-content: stretch;
}
.data-field {
display: flex;
flex: auto;
width: 30%;
flex-direction: row;
padding: 0.8rem 1.875rem;
align-items: center;
justify-content: flex-start;
gap: 1.25rem;
}
#head {
width: 40%;
}
.label {
letter-spacing: 0.02rem;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.pre-darkmode {
color: #ffffff;
}
.pre-lightmode {
color: #000000;
}
.data {
display: flex;
flex-direction: row;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
background-color: #212121;
align-items: center;
justify-content: flex-start;
letter-spacing: 0.02rem;
font: 400 0.75rem/1.875rem Overpass, sans-serif;
}
.data-darkmode {
background-color: #212121;
color: #ffffff;
}
.data-lightmode {
background-color: #ebebeb;
color: #000000;
}
.notes {
display: flex;
flex: auto;
flex-direction: column;
padding: 1.25rem 1.875rem 0.625rem;
align-items: flex-start;
justify-content: center;
gap: 0.625rem;
width: 50%;
}
.area-title {
letter-spacing: 0.03rem;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
#notes {
align-self: stretch;
}
.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;
}
</style>

View File

@ -0,0 +1,240 @@
<template>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Employees:</div>
<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>
<th
:class="['JobTitle', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'JobTitle-darkmode' : 'JobTitle-lightmode']">
Job Title</th>
<th
:class="['Pronouns', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Pronouns-darkmode' : 'Pronouns-lightmode']">
Pronouns</th>
</tr>
<tr v-for="empl in employees" :key="empl.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenEmployee(empl.primaryID)">
{{ empl.primaryID }}
</nuxt-link>
</td>
<td
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenEmployee(empl.primaryID)">
{{ empl.name }}
</nuxt-link>
</td>
<td
:class="['JobTitle', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'JobTitle-darkmode' : 'JobTitle-lightmode']">
{{ empl.jobTitle }}</td>
<td
:class="['Pronouns', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Pronouns-darkmode' : 'Pronouns-lightmode']">
{{ empl.pronouns }}</td>
</tr>
</table>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const chosenCustomerId = computed(() => store.state.chosenCustomerId);
const chosenDepartmentId = computed(() => store.state.chosenDepartmentId);
const employeesByCustomer = ref([]);
const employees = ref([]);
const darkMode = ref('')
const goToChosenEmployee = (id) => {
store.commit('setChosenCustomerEmployee', id);
store.commit('changeToCustomerEmployee');
};
//get employees by the selected customer
const getEmployees = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedCustEmployeeByCustomer/${chosenCustomerId.value}`);
employeesByCustomer.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
// filter those with the chosen department id
employees.value = employeesByCustomer.value.filter(empl => empl.departmentID === chosenDepartmentId.value);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getEmployees();
});
</script>
<script>
export default {
name: "CustomerDepartmentEmployeeList",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
align-self: stretch;
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: #ffffff;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.label {
padding: 1.25rem 0;
letter-spacing: 0.04rem;
text-decoration-line: underline;
font: 400 1rem/1.875rem Overpass, sans-serif;
}
.label-darkmode {
color: #ffffff;
}
.label-lightmode {
color: #000000;
}
.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;
width: 35%;
padding: 0;
text-align: left;
border-left: none;
letter-spacing: 0.02rem;
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;
border-right: 0.0625rem solid #000000;
}
.th-lightmode,
.td-lightmode {
color: #000000;
border-right: 0.0625rem solid #8e8e8e;
}
.ID {
width: 20%;
}
.Pronouns {
width: 10%;
}
.Pronouns-darkmode {
border-right: none;
}
.Pronouns-lightmode {
border-right: none;
}
</style>

View File

@ -0,0 +1,307 @@
<template>
<section v-if="searchable" :class="['department-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['instanceLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Name</div>
<input v-model="nameSearchFilter" @change="filterDepartmentsByName()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Departments:</div>
<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>
<th
:class="['DHead', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'DHead-darkmode' : 'DHead-lightmode']">
Head</th>
</tr>
<tr v-for="dep in departments" :key="dep.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenDepartment(dep.primaryID)">
{{ dep.primaryID }}
</nuxt-link>
</td>
<td
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenDepartment(dep.primaryID)">
{{ dep.name }}
</nuxt-link>
</td>
<td
:class="['DHead', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'DHead-darkmode' : 'DHead-lightmode']">
{{ dep.head }}</td>
</tr>
</table>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const chosenCustomerId = computed(() => store.state.chosenCustomerId);
const searchable = computed(() => store.state.searchable);
const nameSearchFilter = ref('');
const departments = ref([]);
const darkMode = ref('');
const departmentByName = ref([]);
const goToChosenDepartment = (id) => {
store.commit('setChosenCustomerDepartment', id);
store.commit('changeToDepartment');
};
//get department by the selected customer
const getDepartments = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedDepartmentByCustomer/${chosenCustomerId.value}`);
departments.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update search term
const updateSearchTerm = async () => {
nameSearchFilter.value = '';
await getDepartments();
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
//get all departments based on the searched name
const filterDepartmentsByName = async () => {
if (nameSearchFilter.value === '') {
await getDepartments();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedDepartmentByName/${nameSearchFilter.value}`);
departmentByName.value = response.data;
departments.value = filterObjectsWithMatchingIds(departments.value, departmentByName.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
const filterObjectsWithMatchingIds = (arr1, arr2) => {
return arr1.filter(obj1 => {
return arr2.some(obj2 => obj2.primaryID === obj1.primaryID);
});
};
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(searchable, updateSearchTerm);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getDepartments();
});
</script>
<script>
export default {
name: "CustomerDepartmentList",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
align-self: stretch;
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: #ffffff;
}
.department-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;
}
.input {
border: none;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.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;
}
.instanceLabel {
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 {
padding: 1.25rem 0;
letter-spacing: 0.04rem;
text-decoration-line: underline;
font: 400 1rem/1.875rem Overpass, sans-serif;
}
.label-darkmode {
color: #ffffff;
}
.label-lightmode {
color: #000000;
}
.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;
width: 40%;
padding: 0;
text-align: left;
border-left: none;
letter-spacing: 0.02rem;
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;
border-right: 0.0625rem solid #000000;
}
.th-lightmode,
.td-lightmode {
color: #000000;
border-right: 0.0625rem solid #8e8e8e;
}
.ID {
width: 20%;
}
.DHead {
border-right: none;
}
</style>

View File

@ -0,0 +1,674 @@
<template>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['customer-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{ empl.name }}
</h2>
<input v-if="editable" v-model="empl.name" @change="updateEmployee()"
:class="['data', 'customer-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="data-group" id="personal-data">
<div class="data-group" id="full-name">
<div class="data-field" id="ntitle">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Title/-s:</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.title }}</pre>
<input v-if="editable" v-model="empl.title" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="first-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">First Name/-s:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.firstName }}</pre>
<input v-if="editable" v-model="empl.firstName" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="last-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Last Name/-s:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.lastName }}</pre>
<input v-if="editable" v-model="empl.lastName" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="data-group" id="other">
<div class="data-field" id="id">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.primaryID }}</pre>
</div>
<div class="data-field" id="pronouns">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Pronouns:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.pronouns }}</pre>
<input v-if="editable" v-model="empl.pronouns" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="preferred-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Preferred Name:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.preferredName }}</pre>
<input v-if="editable" v-model="empl.preferredName" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
<div class="data-group" id="employment-data">
<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']">{{ empl.customerID }}</pre>
</div>
<div class="data-field" id="department">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Department:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.department }}</pre>
<select v-if="editable" id="customersDropDownChosenCI" v-model="empl.department" @change="updateDepartmentID()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="depart in departments" :key="depart.primaryID">
{{ depart.name }}
</option>
</select>
</div>
<div class="data-field" id="job-title">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Job Title:</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.jobTitle }}</pre>
<input v-if="editable" v-model="empl.jobTitle" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="data-group" id="contact-data">
<div class="data-field" id="phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Phone No.:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.phonenumber }}</pre>
<input v-if="editable" v-model="empl.phonenumber" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">E-Mail:</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ empl.eMail }}</pre>
<input v-if="editable" v-model="empl.eMail" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="notes">
<pre :class="['area-title', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Notes:</pre>
<input v-model="empl.notes" :readonly="!editable" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<input v-model="newName"
:class="['data', 'customer-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="data-group" id="personal-data">
<div class="data-group" id="full-name">
<div class="data-field" id="ntitle">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Title/-s:</pre>
<input v-model="newTitle" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="first-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">First Name/-s:</pre>
<input v-model="newFirstName" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="last-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Last Name/-s:</pre>
<input v-model="newLastName" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="data-group" id="other">
<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 class="data-field" id="pronouns">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Pronouns:</pre>
<input v-model="newPronouns" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="preferred-name">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Preferred Name:</pre>
<input v-model="newPreferedName" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
<div class="data-group" id="employment-data">
<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']">{{ chosenCustomerId }}</pre>
</div>
<div class="data-field" id="department">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Department:</pre>
<select id="customersDropDownChosenCI" v-model="newDepartment" @change="updateNewDepartmentID()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="depart in departments" :key="depart.primaryID">
{{ depart.name }}
</option>
</select>
</div>
<div class="data-field" id="job-title">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Job Title:</pre>
<input v-model="newJobTitle" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="data-group" id="contact-data">
<div class="data-field" id="phone">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Phone No.:</pre>
<input v-model="newPhonenumber" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="mail">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">E-Mail:</pre>
<input v-model="newEMail" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="notes">
<pre :class="['area-title', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Notes:</pre>
<input v-model="newNotes" :class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="notes">
</div>
</section>
<section v-if="addBool" id="saveNewItem">
<button :class="[darkMode ? 'saveNewItem-darkmode' : 'saveNewItem-lightmode']" @click="addEmployee()">Save</button>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenCustomerId = computed(() => store.state.chosenCustomerId);
const chosenCustomerEmployeeId = computed(() => store.state.chosenCustomerEmployeeId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('')
const empl = ref({});
const department = ref({});
const customer = ref({});
const employees = ref([]);
const departments = ref([]);
const newName = ref('');
const newPronouns = ref('');
const newTitle = ref('');
const newFirstName = ref('');
const newLastName = ref('');
const newPreferedName = ref('');
const newDepartment = ref('');
const newDepartmentID = ref('');
const newJobTitle = ref('');
const newPhonenumber = ref('');
const newEMail = ref('');
const newNotes = ref('');
// get employee from id
const getEmployeeById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustEmployee/${chosenCustomerEmployeeId.value}`
);
empl.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// get customer from id
const getCustomerById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCustomerById/${chosenCustomerId.value}`
);
customer.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//update data
const updateEmployee = async () => {
if (empl.value.name.trim() === "") {
alert("Please add an employee name!");
return;
} else {
var counter = 0;
// check if employee name already exists
employees.value.forEach(e => {
if (e.name === empl.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This employee name already exists. Please choose an unique employee name or modify respectively delete the old one!");
empl.value.name = '';
return;
}
if (empl.value.department.trim() === "") {
alert("Please choose an department!");
return;
}
if (!validateEMail(empl.value.eMail)) {
alert("Please add a valid email!");
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateCustEmployee`,
{
primaryID: empl.value.primaryID,
name: empl.value.name,
pronouns: empl.value.pronouns,
title: empl.value.title,
firstName: empl.value.firstName,
lastName: empl.value.lastName,
preferredName: empl.value.preferredName,
department: empl.value.department,
departmentID: empl.value.departmentID,
jobTitle: empl.value.jobTitle,
phonenumber: empl.value.phonenumber,
eMail: empl.value.eMail,
notes: empl.value.notes,
}
)
await getEmployeeById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
// add new employee
const addEmployee = async () => {
// check if all input data is valid
if (newName.value.trim() === "") {
alert("Please add an employee name!");
return;
} else {
var counter = 0;
// check if employee name already exists
employees.value.forEach(c => {
if (c.name === newName.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This employee name already exists. Please choose an unique employee name or modify respectively delete the old one!");
return;
}
}
if (!validateEMail(newEMail.value)) {
alert("Please add a valid email!");
return;
}
if (newDepartment.value.trim() === "") {
alert("Please choose a department!");
return;
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addCustEmployee`,
{
customerID: chosenCustomerId.value,
customername: customer.value.customername,
name: newName.value,
pronouns: newPronouns.value,
title: newTitle.value,
firstName: newFirstName.value,
lastName: newLastName.value,
preferredName: newPreferedName.value,
department: newDepartment.value,
departmentID: newDepartmentID.value,
jobTitle: newJobTitle.value,
phonenumber: newPhonenumber.value,
eMail: newEMail.value,
notes: newNotes.value,
});
store.commit('resetStoreNotCustomer');
store.commit('changeToCustomerEmployeelist');
} catch (err) {
console.log(err.response.statusText);
}
}
// to validate the email address
const validateEMail = (email) => {
const emailRegex = new RegExp(/^[A-Za-z0-9_!#$%&'*+\/=?`{|}~^.-]+@[A-Za-z0-9.-]+$/, "gm");
if (email === "") {
return true
}
return emailRegex.test(email);
}
//get all employees
const getEmployees = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedCustEmployeeByCustomer/${chosenCustomerEmployeeId.value}`
);
employees.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
const confirmDeleteEmployee = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this employee? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteCustEmployee/${chosenCustomerEmployeeId.value}`);
store.commit('undoDelete');
store.commit('resetStoreNotCustomer');
store.commit('changeToCustomerEmployeelist');
} catch (err) {
console.log(err.response.statusText);
}
} else {
store.commit('undoDelete');
}
}
}
//get all departments
const getDepartments = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedDepartmentByCustomer/${chosenCustomerId.value}`);
departments.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update departmentid if department was changed
const updateDepartmentID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getDprtmntByName/${empl.value.department}`);
department.value = response.data;
empl.value.departmentID = department.value.primaryID;
} catch (err) {
console.log(err.response.statusText);
}
await updateEmployee();
}
// update departmentid if department was changed
const updateNewDepartmentID = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getDprtmntByName/${newDepartment.value}`);
newDepartmentID.value = response.data.primaryID;
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 2000);
}
// include delay to avoid 503 error
const triggerBackendCallsWithSmallDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 500);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(deleteBool, confirmDeleteEmployee);
onMounted(async () => {
getSession();
await getEmployeeById();
triggerBackendCallsWithSmallDelay(getDepartments);
triggerBackendCallsWithDelay(getCustomerById);
triggerBackendCallsWithDelay(getEmployees);
});
</script>
<script>
export default {
name: "CustomerEmployee",
};
</script>
<style scoped>
* {
box-sizing: border-box;
margin: 0;
}
.information {
display: flex;
flex-direction: column;
width: 100%;
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: #ffffff;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.customer-name {
align-self: stretch;
padding: 1rem 0;
margin: 1rem;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.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;
}
.input {
border: none;
}
.customer-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-darkmode {
color: #fff;
}
.h2-lightmode {
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;
}
.data-group {
display: flex;
flex: auto;
width: 100%;
flex-direction: row;
padding: 1.25rem 0;
align-items: center;
justify-content: stretch;
}
#personal-data {
flex-direction: column;
align-items: stretch;
justify-content: center;
gap: 0.625rem;
}
#full-name,
#other {
padding: 0;
}
.data-field {
display: flex;
flex: auto;
width: 20%;
flex-direction: row;
padding: 0.8rem 1.875rem;
align-items: center;
justify-content: flex-start;
gap: 1.25rem;
}
#first-name,
#last-name,
#department,
#job-title,
#phone {
width: 40%;
}
#preferred-name,
#mail {
width: 60%;
}
.label {
letter-spacing: 0.02rem;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.pre-darkmode {
color: #ffffff;
}
.pre-lightmode {
color: #000000;
}
.data {
display: flex;
flex-direction: row;
padding: 0 0.625rem;
border-radius: 0.3125rem;
box-shadow: 0.0625rem 0.0625rem 0.25rem 0rem rgba(0, 0, 0, 0.25) inset;
background-color: #212121;
align-items: center;
justify-content: flex-start;
letter-spacing: 0.02rem;
font: 400 0.75rem/1.875rem Overpass, sans-serif;
}
.data-darkmode {
background-color: #212121;
color: #ffffff;
}
.data-lightmode {
background-color: #ebebeb;
color: #000000;
}
.notes {
display: flex;
flex: auto;
flex-direction: column;
padding: 1.25rem 1.875rem 0.625rem;
align-items: flex-start;
justify-content: center;
gap: 0.625rem;
width: 100%;
}
.area-title {
letter-spacing: 0.03rem;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
#notes {
align-self: stretch;
}
</style>

View File

@ -0,0 +1,362 @@
<template>
<section v-if="searchable" :class="['employee-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['instanceLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Name</div>
<input v-model="nameSearchFilter" @change="filterEmployeesByName()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<section v-if="filtered" :class="['employee-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['instanceLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Department</div>
<input v-model="departmentSearchFilter" @change="filterEmployeesByDepartment()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Employees:</div>
<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>
<th
:class="['Department', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Department-darkmode' : 'Department-lightmode']">
Department / Job Title</th>
<th
:class="['Pronouns', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Pronouns-darkmode' : 'Pronouns-lightmode']">
Pronouns</th>
</tr>
<tr v-for="empl in employees" :key="empl.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenEmployee(empl.primaryID)">
{{ empl.primaryID }}
</nuxt-link>
</td>
<td
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenEmployee(empl.primaryID)">
{{ empl.name }}
</nuxt-link>
</td>
<td
:class="['Department', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Department-darkmode' : 'Department-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenDepartment(empl.departmentID)">
{{ empl.department }}
</nuxt-link>
</td>
<td
:class="['Pronouns', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Pronouns-darkmode' : 'Pronouns-lightmode']">
{{ empl.pronouns }}</td>
</tr>
</table>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const chosenCustomerId = computed(() => store.state.chosenCustomerId);
const searchable = computed(() => store.state.searchable);
const filtered = computed(() => store.state.filtered);
const departmentSearchFilter = ref('');
const nameSearchFilter = ref('');
const employees = ref([]);
const darkMode = ref('')
const employeeByDepartment = ref([]);
const employeeByName = ref([]);
const goToChosenEmployee = (id) => {
store.commit('setChosenCustomerEmployee', id);
store.commit('changeToCustomerEmployee');
};
const goToChosenDepartment = (id) => {
store.commit('setChosenCustomerDepartment', id);
store.commit('changeToDepartment');
};
//get employees by the selected customer
const getEmployees = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedCustEmployeeByCustomer/${chosenCustomerId.value}`);
employees.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update search term
const updateSearchTerm = async () => {
nameSearchFilter.value = '';
await getEmployees();
}
// update filter term
const updateFilterTerm = async () => {
departmentSearchFilter.value = '';
await getEmployees();
}
//get all employees based on the searched name
const filterEmployeesByName = async () => {
if (nameSearchFilter.value === '') {
await getEmployees();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedCustEmployeeByName/${nameSearchFilter.value}`);
employeeByName.value = response.data;
employees.value = filterObjectsWithMatchingIds(employees.value, employeeByName.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all employees based on the searched department
const filterEmployeesByDepartment = async () => {
if (departmentSearchFilter.value === '') {
await getEmployees();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedCustEmployeeByDprtmntName/${departmentSearchFilter.value}`);
employeeByDepartment.value = response.data;
employees.value = filterObjectsWithMatchingIds(employees.value, employeeByDepartment.value);
} catch (err) {
// console.log(err.response.statusText);
console.log(err);
}
}
}
const filterObjectsWithMatchingIds = (arr1, arr2) => {
return arr1.filter(obj1 => {
return arr2.some(obj2 => obj2.primaryID === obj1.primaryID);
});
};
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(searchable, updateSearchTerm);
watch(filtered, updateFilterTerm);
onMounted(async () => {
getSession();
await getEmployees();
});
</script>
<script>
export default {
name: "CustomerEmployeeList",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
align-self: stretch;
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: #ffffff;
}
.label {
padding: 1.25rem 0;
letter-spacing: 0.04rem;
text-decoration-line: underline;
font: 400 1rem/1.875rem Overpass, sans-serif;
}
.label-darkmode {
color: #ffffff;
}
.label-lightmode {
color: #000000;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.employee-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;
}
.input {
border: none;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
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;
}
.instanceLabel {
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;
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;
width: 35%;
padding: 0;
text-align: left;
border-left: none;
letter-spacing: 0.02rem;
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;
border-right: 0.0625rem solid #000000;
}
.th-lightmode,
.td-lightmode {
color: #000000;
border-right: 0.0625rem solid #8e8e8e;
}
.ID {
width: 20%;
}
.Pronouns {
width: 10%;
}
.Pronouns-darkmode {
border-right: none;
}
.Pronouns-lightmode {
border-right: none;
}
</style>

View File

@ -2,29 +2,60 @@
<section :class="['quick-access', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['heading', darkMode ? 'heading-darkmode' : 'heading-lightmode']">Quick Access</h2>
<div class="shortcuts">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="maintenance-visits" value="Maintenance Visits">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="production-orders" value="Production Orders">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="maintenance-visits"
value="Maintenance Visits">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="production-orders"
value="Production Orders">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="issue-slips" value="Assets">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="solutions" value="Solutions">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="issue-slips" value="Issue Slips">
<input :class="[darkMode ? 'input-darkmode' : 'input-lightmode']" type="button" id="issue-slips"
value="Issue Slips">
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const darkMode = ref('')
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
});
</script>
<script>
export default {
name: "Asset",
};
</script>
</script>
<style scoped>
.quick-access {
display: flex;

View File

@ -0,0 +1,290 @@
<template>
<section v-if="customerSearchable"
:class="['customer-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['customerLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Name</div>
<input v-model="customerSearchFilter" @change="searchCustomer()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<section :class="['data', darkMode ? 'section-darkmode' : 'section-lightmode']">
<table class="data-table" id="customer-table">
<tbody>
<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>
</tr>
<tr v-for="cust in customerList" :key="cust.customerID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenCustomer(cust.customerID)">
{{ cust.customerID }}
</nuxt-link>
</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/customers" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenCustomer(cust.customerID)">
{{ cust.customername }}
</nuxt-link>
</td>
</tr>
</tbody>
</table>
</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 modeChanged = computed(() => store.state.updateDarkMode);
const goToChosenCustomer = (id) => {
store.commit('setChosenCustomer', id);
store.commit('changeToCustomer');
};
const darkMode = ref('')
const customerSearchable = computed(() => store.state.searchable);
const customerSearchFilter = ref('');
const customerList = ref([]);
// update search term
const updateSearchTerm = async () => {
customerSearchFilter.value = '';
await getCustomers();
}
//get all customers
const getCustomers = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllCustomers`);
customerList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//get all customers based on the searched customers name
const searchCustomer = async () => {
if (customerSearchFilter.value === '') {
await getCustomers();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedCustomersByName/${customerSearchFilter.value}`);
customerList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(customerSearchable, updateSearchTerm);
onMounted(async () => {
getSession();
await getCustomers();
});
</script>
<script>
export default {
name: "CustomerTable",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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: #ffffff;
}
.customer-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;
}
.input {
border: none;
}
.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;
}
.label-darkmode {
color: #FFFFFF;
}
.label-lightmode {
color: #000;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.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-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000000;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.ID {
width: 40%;
}
.ID-darkmode {
border-right: 0.0625rem solid #000000;
}
.ID-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Name {
width: 60%;
}
</style>

View File

@ -0,0 +1,498 @@
<template>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['employee-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
employee.fullName }}</h2>
<input v-if="editable" v-model="employee.fullName" @change="updateEmpl()"
:class="['data', 'employee-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="employee-data">
<div class="username-registered-lastLogin">
<div class="data-field" id="username">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Username:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ employee.username }}</pre>
</div>
<div class="data-field" id="registered">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Registered:</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ employee.registered }}</pre>
</div>
<div class="data-field" id="lastLogin">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Last login:</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ employee.lastLogin }}</pre>
</div>
</div>
<div class="info">
<div class="city-phonenumber">
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">City:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ employee.city }}</pre>
<input v-if="editable" v-model="employee.city" @change="updateEmpl()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="phonenumber">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Phonenumber:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ employee.phonenumber }}</pre>
<input v-if="editable" v-model="employee.phonenumber" @change="updateEmpl()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-email">
<div class="data-field" id="postcode">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Postcode:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ employee.postcode }}</pre>
<input v-if="editable" v-model="employee.postcode" @change="updateEmpl()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="email">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Email:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ employee.email }}</pre>
<input v-if="editable" v-model="employee.email" @change="updateEmpl()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="address">
<div class="data-field" id="address">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Address:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ employee.address }}</pre>
<input v-if="editable" v-model="employee.address" @change="updateEmpl()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="empty">
&nbsp;
</div>
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<input v-model="newFullName" @change="updateEmployee()"
:class="['data', 'employee-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="employee-data">
<div class="username-registered-lastLogin">
<div class="data-field" id="username">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Username:</pre>
<input v-model="newUsername" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="password">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Password:</pre>
<input v-model="newPassword" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="passwordRepeated">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Password repeated:</pre>
<input v-model="newPasswordRepeated" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="info">
<div class="city-phonenumber">
<div class="data-field" id="city">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">City:</pre>
<input v-model="newCity" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="phonenumber">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Phonenumber:</pre>
<input v-model="newPhonenumber" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-email">
<div class="data-field" id="postcode">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Postcode:</pre>
<input v-model="newPostcode" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="email">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Email:</pre>
<input v-model="newEmail" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="address">
<div class="data-field" id="address">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Address:</pre>
<input v-model="newAddress" @change="updateEmployee()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="empty">
&nbsp;
</div>
</div>
</div>
</div>
</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 modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenEmployeeId = computed(() => store.state.chosenEmployeeId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('');
const employee = ref({});
const newUsername = ref('');
const newPassword = ref('');
const newPasswordRepeated = ref('');
const newFullName = ref('');
const newEmail = ref('');
const newPhonenumber = ref('');
const newAddress = ref('');
const newCity = ref('');
const newPostcode = ref('');
// get employee from id
const getEmployeeById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getEmployee/${chosenEmployeeId.value}`
);
employee.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update employee fields in the store
const updateEmployee = () => {
const employee = {
username: newUsername.value,
password: newPassword.value,
passwordRepeated: newPasswordRepeated.value,
fullName: newFullName.value,
email: newEmail.value,
phonenumber: newPhonenumber.value,
address: newAddress.value,
city: newCity.value,
postcode: newPostcode.value
};
store.commit('updateEmployeeComponent', employee);
}
//update data
const updateEmpl = async () => {
if (employee.value.fullName.trim() === "") {
alert("Please add a name!");
return;
}
if (employee.value.city.trim() === "") {
alert("Please add a city!");
return;
}
if (employee.value.address.trim() === "") {
alert("Please add an address!");
return;
}
if (!validateEMail(employee.value.email)) {
alert("Please add a valid email!");
return;
}
if (!validatePhonenumber(employee.value.phonenumber)) {
alert("Please add a valid phonenumber!");
return;
}
if (!validatePostcode(employee.value.postcode)) {
alert("Please add a valid postcode!");
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateEmployee`,
{
id: employee.value.id,
username: employee.value.username,
fullName: employee.value.fullName,
email: employee.value.email,
phonenumber: employee.value.phonenumber,
address: employee.value.address,
city: employee.value.city,
postcode: employee.value.postcode,
adminBool: employee.value.adminBool,
technicianBool: employee.value.technicianBool,
readerBool: employee.value.readerBool,
}
)
await getEmployeeById();
} catch (err) {
console.log(err.response.statusText);
}
}
const confirmDeleteEmployee = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this employee? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteEmployee/${chosenEmployeeId.value}`);
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToEmployeelist');
} catch (err) {
console.log(err.response.statusText);
}
} else {
store.commit('undoDelete');
}
}
}
// to validate the email address
const validateEMail = (email) => {
const emailRegex = new RegExp(/^[A-Za-z0-9_!#$%&'*+\/=?`{|}~^.-]+@[A-Za-z0-9.-]+$/, "gm");
if (email === "") {
return true
}
return emailRegex.test(email);
}
// to validate the phonenumber
const validatePhonenumber = (number) => {
const mobilephonenumberRegex = new RegExp(/^(((((00|\+){1,2})49([ \-/]?|[ \()/]?))|0)[1]([0-2]|[4-7])([0-9]{1})([ \-/]?|[ \()/]?)([0-9]{8}))$/, "gm");
const landlineRegex = new RegExp(/^0(30|40|69|89|20[12389]|21[24]|228|234|335|340|3[3-9][15]|906|[2-9][1-9]1|3(?:3(?:[0237][127]|0[3-6]|2[89]|3[458]|[46][1246]|7[589]|8[1256]|9[145])|4(?:[2347][135]|[34]7|[69][146]|48|62|76|93)|5(?:[04679][14]|[238][135]|[2469]2|[4789]6|[278]8|63|73|37|29)|6(?:[024689][13]|[03789]5|06|2[2489]|3[1246]|44|47|7[1279]|82|86)|7(?:[236][135]|2[2467]|37|4[145]|62|64|7[1-4])|8(?:[234678]1|3[468]|4[347]|6[035-9]|7[467]|83|86)|9(?:[236][135]|[04689]4|[04789]1|[03468]7|02|09|28|4[369]|6[2689]|73|76|96|98))|3[3-9][0-9]{3}|13[078]|180[235]|18[01]|19[0-9]{3}|[789]00|[2-9][0-9]{3})([0-9]{1,})$/, "gm");
if (number === "") {
return true
}
if (mobilephonenumberRegex.test(number)) {
return true
} else if (landlineRegex.test(number)) {
return true;
}
return false;
}
// to validate the postcode
const validatePostcode = (postcode) => {
const postcodeRegex = new RegExp(/^\d{5}$/);
if (postcode === "") {
return true
}
return postcodeRegex.test(postcode);
}
watch(deleteBool, confirmDeleteEmployee);
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
await getEmployeeById();
});
</script>
<script>
export default {
name: "Employee",
}
</script>
<style scoped>
.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;
}
.employee-name {
align-self: stretch;
padding: 1rem 0;
letter-spacing: 5%;
text-decoration-line: underline;
font: italic 400 1rem/187.5% Overpass, -apple-system, Roboto, Helvetica,
sans-serif;
}
.employee-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-darkmode {
color: #fff;
}
.h2-lightmode {
color: #000;
}
.data-field {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.data-field#street-name {
width: 70%;
}
.data-field#street-no {
width: 30%;
}
.label {
letter-spacing: 5%;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.pre-darkmode {
color: #fff;
}
.pre-lightmode {
color: #000;
}
.input {
border: none;
}
.data {
display: flex;
overflow-x: auto;
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;
}
.data#notes,
.data#description {
align-self: stretch;
/* width: 45%; */
scrollbar-width: none;
overflow-x: auto;
}
.employee-data {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
align-self: stretch;
}
.username-registered-lastLogin,
.info {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 50%;
padding: 0 0;
border-radius: 0.3125rem;
}
.additional {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 50%;
padding: 0rem 0.625rem;
border-radius: 0.3125rem;
}
.area-title {
letter-spacing: 5%;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.h3-darkmode {
color: #fff;
}
.h3-lightmode {
color: #000;
}
.city-phonenumber,
.postcode-email {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
align-self: stretch;
padding: 0 1.875rem 0 0;
gap: 0.625rem;
}
</style>

View File

@ -0,0 +1,510 @@
<template>
<section v-if="!addBool" :class="['group-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']" id="group">Groups:</div>
<div class="asset-data">
<div class="checkbox-container">
<div class="checkbox-group">
<label :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']" for="admin-checkbox">Admin</label>
<input :readonly="!editable" id="admin-checkbox" type="checkbox" v-model="adminBoolean"
@click="toggleAdminBool()">
</div>
<div class="checkbox-group">
<label :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']" for="technician-checkbox">Technician</label>
<input :readonly="!editable" id="technician-checkbox" type="checkbox"
v-model="technicianBoolean" @click="toggleTechnicianBool()">
</div>
<div class="checkbox-group">
<label :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']" for="reader-checkbox">Reader</label>
<input :readonly="!editable" id="reader-checkbox" type="checkbox" v-model="readerBoolean"
@click="toggleReaderBool()">
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['group-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']" id="group">Groups:</div>
<div class="asset-data">
<div class="checkbox-container">
<div class="checkbox-group">
<label :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']" for="admin-checkbox">Admin</label>
<input id="admin-checkbox" type="checkbox" v-model="newAdminBool">
</div>
<div class="checkbox-group">
<label :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']" for="technician-checkbox">Technician</label>
<input id="technician-checkbox" type="checkbox" v-model="newTechnicianBool">
</div>
<div class="checkbox-group">
<label :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']" for="reader-checkbox">Reader</label>
<input id="reader-checkbox" type="checkbox" v-model="newReaderBool">
</div>
</div>
</div>
</section>
<section v-if="addBool" id="saveNewEmployee">
<button :class="[darkMode ? 'saveNewEmployee-darkmode' : 'saveNewEmployee-lightmode']"
@click="addEmployee()">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 modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenEmployeeId = computed(() => store.state.chosenEmployeeId);
const addBool = computed(() => store.state.new);
const newUsernameEmp = computed(() => store.state.newUsernameEmp);
const newPasswordEmp = computed(() => store.state.newPasswordEmp);
const newPasswordRepeatedEmp = computed(() => store.state.newPasswordRepeatedEmp);
const newFullNameEmp = computed(() => store.state.newFullNameEmp);
const newEmailEmp = computed(() => store.state.newEmailEmp);
const newPhonenumberEmp = computed(() => store.state.newPhonenumberEmp);
const newAddressEmp = computed(() => store.state.newAddressEmp);
const newCityEmp = computed(() => store.state.newCityEmp);
const newPostcodeEmp = computed(() => store.state.newPostcodeEmp);
const darkMode = ref('')
const employee = ref({});
const adminBoolean = ref(false);
const technicianBoolean = ref(false);
const readerBoolean = ref(false);
const newAdminBool = ref(false);
const newTechnicianBool = ref(false);
const newReaderBool = ref(false);
const newDarkModeBool = ref(false);
const employees = ref([]);
// get employee from id
const getEmployeeById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getEmployee/${chosenEmployeeId.value}`
);
employee.value = response.data;
if (employee.value.adminBool == 1) {
adminBoolean.value = true;
};
if (employee.value.technicianBool == 1) {
technicianBoolean.value = true;
};
if (employee.value.readerBool == 1) {
readerBoolean.value = true;
};
} catch (err) {
console.log(err.response.statusText);
}
}
}
const toggleTechnicianBool = () => {
technicianBoolean.value = !technicianBoolean.value;
update();
}
const toggleAdminBool = () => {
adminBoolean.value = !adminBoolean.value;
update();
}
const toggleReaderBool = () => {
readerBoolean.value = !readerBoolean.value;
update();
}
//update data
const update = async () => {
if (adminBoolean.value) {
employee.value.adminBool = 1;
} else {
employee.value.adminBool = 0;
}
if (technicianBoolean.value) {
employee.value.technicianBool = 1;
} else {
employee.value.technicianBool = 0;
}
if (readerBoolean.value) {
employee.value.readerBool = 1;
} else {
employee.value.readerBool = 0;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateEmployee`,
{
id: employee.value.id,
username: employee.value.username,
fullName: employee.value.fullName,
email: employee.value.email,
phonenumber: employee.value.phonenumber,
address: employee.value.address,
city: employee.value.city,
postcode: employee.value.postcode,
adminBool: employee.value.adminBool,
technicianBool: employee.value.technicianBool,
readerBool: employee.value.readerBool,
darkModeBool: employee.value.darkModeBool,
}
);
} catch (err) {
console.log(err.response.statusText);
}
await getEmployeeById();
}
// add new employee
const addEmployee = async () => {
// check if all input data is valid
if (newUsernameEmp.value.trim() === "") {
alert("Please add an username!");
return;
} else {
var counter = 0;
// check if the username already exists
employees.value.forEach(empl => {
if (empl.username === newUsernameEmp.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This username already exists. Please choose an unique username or modify respectively delete the old one!");
return;
}
}
if (newPasswordEmp.value.trim() === "") {
alert("Please add a password!");
return;
}
// username min length 5
if (!newUsernameEmp.value || newUsernameEmp.value.length < 5) {
alert("Please choose an username with minimal five characters!");
return
}
// password min 8 chars
if (!newPasswordEmp.value || newPasswordEmp.value.length < 8) {
alert("Please choose a password with minimal eight characters!");
return
}
// password (repeat) must match
if (
!newPasswordRepeatedEmp.value ||
newPasswordEmp.value != newPasswordRepeatedEmp.value
) {
alert("Your passwords don't match.");
return
}
if (newFullNameEmp.value.length === 0) {
alert("Please add a name!");
return;
}
if (newCityEmp.value.length === 0) {
alert("Please add a city!");
return;
}
if (newAddressEmp.value.length === 0) {
alert("Please add an address!");
return;
}
if (!validateEMail(newEmailEmp.value)) {
alert("Please add a valid email!");
return;
}
if (!validatePhonenumber(newPhonenumberEmp.value)) {
alert("Please add a valid phonenumber!");
return;
}
if (!validatePostcode(newPostcodeEmp.value)) {
alert("Please add a valid postcode!");
return;
}
if ((newPhonenumberEmp.value.length === 0) && (newEmailEmp.value.length === 0)) {
alert("Please add a phonenumber or an email!");
return;
}
if (! (newAdminBool.value || newTechnicianBool.value || newReaderBool.value)) {
alert("Please choose at least one group!");
return;
}
try {
let res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/signup`,
{
username: newUsernameEmp.value,
password: newPasswordEmp.value,
password_repeat: newPasswordRepeatedEmp.value,
fullName: newFullNameEmp.value,
email: newEmailEmp.value,
phonenumber: newPhonenumberEmp.value,
address: newAddressEmp.value,
city: newCityEmp.value,
postcode: newPostcodeEmp.value,
adminBool: newAdminBool.value,
technicianBool: newTechnicianBool.value,
readerBool: newReaderBool.value,
darkModeBool: newDarkModeBool.value,
});
store.commit('resetStore');
store.commit('changeToEmployeelist');
} catch (err) {
console.log(err.response.statusText);
}
}
//get all employees
const getEmployees = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllEmployees`);
employees.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// to validate the email address
const validateEMail = (email) => {
const emailRegex = new RegExp(/^[A-Za-z0-9_!#$%&'*+\/=?`{|}~^.-]+@[A-Za-z0-9.-]+$/, "gm");
if (email === "") {
return true
}
return emailRegex.test(email);
}
// to validate the phonenumber
const validatePhonenumber = (number) => {
const mobilephonenumberRegex = new RegExp(/^(((((00|\+){1,2})49([ \-/]?|[ \()/]?))|0)[1]([0-2]|[4-7])([0-9]{1})([ \-/]?|[ \()/]?)([0-9]{8}))$/, "gm");
const landlineRegex = new RegExp(/^0(30|40|69|89|20[12389]|21[24]|228|234|335|340|3[3-9][15]|906|[2-9][1-9]1|3(?:3(?:[0237][127]|0[3-6]|2[89]|3[458]|[46][1246]|7[589]|8[1256]|9[145])|4(?:[2347][135]|[34]7|[69][146]|48|62|76|93)|5(?:[04679][14]|[238][135]|[2469]2|[4789]6|[278]8|63|73|37|29)|6(?:[024689][13]|[03789]5|06|2[2489]|3[1246]|44|47|7[1279]|82|86)|7(?:[236][135]|2[2467]|37|4[145]|62|64|7[1-4])|8(?:[234678]1|3[468]|4[347]|6[035-9]|7[467]|83|86)|9(?:[236][135]|[04689]4|[04789]1|[03468]7|02|09|28|4[369]|6[2689]|73|76|96|98))|3[3-9][0-9]{3}|13[078]|180[235]|18[01]|19[0-9]{3}|[789]00|[2-9][0-9]{3})([0-9]{1,})$/, "gm");
if (number === "") {
return true
}
if (mobilephonenumberRegex.test(number)) {
return true
} else if (landlineRegex.test(number)) {
return true;
}
return false;
}
// to validate the postcode
const validatePostcode = (postcode) => {
const postcodeRegex = new RegExp(/^\d{5}$/);
if (postcode === "") {
return true
}
return postcodeRegex.test(postcode);
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1000);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(() => {
getSession();
triggerBackendCallsWithDelay(getEmployeeById);
triggerBackendCallsWithDelay(getEmployees);
});
</script>
<script>
export default {
name: "EmployeeGroups",
};
</script>
<style scoped>
.group-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;
}
.data-field {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0.8rem 1.875rem;
gap: 1.25rem;
border-radius: 0.625rem;
}
.label {
letter-spacing: 5%;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.div-darkmode {
color: #fff;
}
.div-lightmode {
color: #000;
}
.label#network {
padding-top: 1rem;
padding-bottom: 1rem;
}
.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;
}
.asset-data {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
align-self: stretch;
}
.IPv4-MAC,
.IPv6-subnetmask {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 50%;
padding: 0 0;
border-radius: 0.3125rem;
}
.saveNewEmployee-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);
}
.saveNewEmployee-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);
}
.saveNewEmployee-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.saveNewEmployee-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#saveNewEmployee {
text-align: center;
}
.input {
border: none;
}
.checkbox-container {
padding-bottom: 0.8rem;
display: flex;
justify-content: center;
}
.checkbox-group {
display: flex;
flex-direction: column;
align-items: center;
width: 20rem;
}
.checkbox-group label {
margin-bottom: 5px;
}
.checkbox-group input {
margin-bottom: 10px;
}
.label {
letter-spacing: 5%;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.pre-darkmode {
color: #fff;
}
.pre-lightmode {
color: #000;
}
input[type=checkbox]{
accent-color: #000;
}
</style>

View File

@ -0,0 +1,264 @@
<template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<table class="data-table" id="employeetable">
<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="['Username', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Username-darkmode' : 'Username-lightmode']">
Username</th>
<th :class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode']">ID</th>
</tr>
<tr v-for="u in userList" :key="u.id" :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']">
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/employees" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenEmployee(u.id)">
{{ u.fullName }}
</nuxt-link>
</td>
<td
:class="['Username', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Username-darkmode' : 'Username-lightmode']">
<nuxt-link to="/employees" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenEmployee(u.id)">
{{ u.username }}
</nuxt-link>
</td>
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode']"> {{ u.id }}</td>
</tr>
</tbody>
</table>
</div>
</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';
// get accesss to the store
const store = useStore()
const modeChanged = computed(() => store.state.updateDarkMode);
const goToChosenEmployee = (id) => {
store.commit('setChosenEmployee', id);
store.commit('changeToEmployee');
};
const employeeFilter = computed(() => store.state.filteredByCustomer);
const darkMode = ref('')
const userList = ref([]);
const adminBool = ref(false);
//get all users
const getEmployees = async () => {
if (adminBool.value) {
if (!(employeeFilter.value === '')) {
await getFilteredUsersByUser();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllEmployees`);
userList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
}
//get all users based on the searched user
const getFilteredUsersByUser = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedEmployeesByEmployee/${employeeFilter.value}`);
userList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
watch(employeeFilter, getEmployees);
const getSession = async () => {
const loggedInUserAdminBool = getItem('logged-in-user-adminBool');
if (loggedInUserAdminBool == 0) {
adminBool.value = false;
} else {
adminBool.value = true;
};
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getEmployees();
});
</script>
<script>
export default {
name: "AssetTable",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
align-self: stretch;
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;
}
.input {
border: none;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Name {
width: 40%;
}
.Name-darkmode {
border-right: 0.0625rem solid #000000;
}
.Name-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Username {
width: 35%;
}
.Username-darkmode {
border-right: 0.0625rem solid #000000;
}
.Username-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.ID {
width: 25%;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
</style>

View File

@ -1,25 +1,39 @@
<template>
<section :class="['hardware-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']" id="hardware">Hardware specifications:</div>
<section v-if="hardwareBoolean && !addBool"
:class="['hardware-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']" id="hardware">Hardware specifications:
</div>
<div class="asset-data">
<div class="model-CPU">
<div class="data-field" id="model">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Model:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.model }}</pre>
<input v-if="editable" v-model="item.model" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="CPU">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">CPU:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.CPU }}</pre>
<input v-if="editable" v-model="item.CPU" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="serial-number-RAM">
<div class="data-field" id="serial-number">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Serial number:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.serialnumber }}</pre>
<input v-if="editable" v-model="item.serialnumber" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="RAM">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">RAM:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.RAM }}</pre>
<input v-if="editable" v-model="item.RAM" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
@ -27,41 +41,211 @@
<div class="additional">
<div class="storage-configuration">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Storage configuration:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"
id="storage-configuration">...</pre>
<input v-model="item.storageConfiguration" :readonly="!editable" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"
id="storage-configuration">
</div>
</div>
<div class="additional">
<div class="miscellaneous">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Miscellaneous:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="miscellaneous">...</pre>
<input v-model="item.miscellaneous" :readonly="!editable" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="miscellaneous">
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['hardware-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']" id="hardware">Hardware specifications:
</div>
<div class="asset-data">
<div class="model-CPU">
<div class="data-field" id="model">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Model:</pre>
<input v-model="newModel" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="CPU">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">CPU:</pre>
<input v-model="newCPU" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="serial-number-RAM">
<div class="data-field" id="serial-number">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Serial number:</pre>
<input v-model="newSerialnumber" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="RAM">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">RAM:</pre>
<input v-model="newRAM" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
<div class="asset-data">
<div class="additional">
<div class="storage-configuration">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Storage configuration:</h3>
<input v-model="newStorageConfiguration" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"
id="storage-configuration">
</div>
</div>
<div class="additional">
<div class="miscellaneous">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Miscellaneous:</h3>
<input v-model="newMiscellaneous" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="miscellaneous">
</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 darkMode = ref(true)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenAssetId = computed(() => store.state.chosenAssetId);
const addBool = computed(() => store.state.new);
const newHardwareBool = ref(true);
const newModel = ref('');
const newSerialnumber = ref('');
const newCPU = ref('');
const newRAM = ref('');
const newStorageConfiguration = ref('');
const newMiscellaneous = ref('');
const darkMode = ref('')
const item = ref({});
const hardwareBoolean = ref(false)
// get config item from id
const getItemById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getConfigItem/${chosenAssetId.value}`
);
item.value = response.data;
if (item.value.hardwareBool == 1) {
hardwareBoolean.value = true;
};
} catch (err) {
console.log(err.response.statusText);
}
}
// update hardware fields in the store
const updateAsset = () => {
if (newModel.value.length === 0 && newSerialnumber.value.length === 0 && newCPU.value.length === 0 && newRAM.value.length === 0 && newStorageConfiguration.value.length === 0 && newMiscellaneous.value.length === 0) {
newHardwareBool.value = false
}
const asset = {
hardwareBool: newHardwareBool.value,
model: newModel.value,
serialnumber: newSerialnumber.value,
CPU: newCPU.value,
RAM: newRAM.value,
storageConfig: newStorageConfiguration.value,
miscellaneous: newMiscellaneous.value,
};
store.commit('updateHardwareComponent', asset);
}
//update data
const updateConfigItem = async () => {
if (item.value.model.length === 0 && item.value.serialnumber.length === 0 && item.value.CPU.length === 0 && item.value.RAM.length === 0 && item.value.storageConfiguration.length === 0 && item.value.miscellaneous.length === 0) {
item.value.hardwareBool = 0;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateConfigItem`,
{
primaryID: item.value.primaryID,
assetName: item.value.assetName,
customerID: item.value.customerID,
customer: item.value.customer,
location: item.value.location,
remoteLocation: item.value.remoteLocation,
type: item.value.type,
description: item.value.description,
notes: item.value.notes,
state: item.value.state,
lastView: item.value.lastView,
user: item.value.user,
hardwareBool: item.value.hardwareBool,
model: item.value.model,
serialnumber: item.value.serialnumber,
CPU: item.value.CPU,
RAM: item.value.RAM,
storageConfiguration: item.value.storageConfiguration,
miscellaneous: item.value.miscellaneous,
softwareBool: item.value.softwareBool,
software: item.value.software,
version: item.value.version,
license: item.value.license,
networkBool: item.value.networkBool,
IPv4: item.value.IPv4,
IPv6: item.value.IPv6,
MAC: item.value.MAC,
subnetmask: item.value.subnetmask,
}
);
await getItemById();
} catch (err) {
console.log(err.response.statusText);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getItemById();
});
</script>
<script>
export default {
name: "HardwareSpecifications",
};
</script>
</script>
<style scoped>
.hardware-information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 100%;
padding: 1.25rem 1.875rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
@ -82,7 +266,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;
}
@ -118,6 +302,10 @@ export default {
font: 400 0.75rem/250% Overpass, sans-serif;
}
.input {
border: none;
}
.data-darkmode {
background-color: #212121;
color: #fff;

View File

@ -1,68 +1,292 @@
<template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<section :class="['instance-checklist-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Checklist:</div>
<table class="data-table" id="instance-checklist">
<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', darkMode ? 'Comments-darkmode' : 'Comments-lightmode']">
Comments</th>
<th :class="['Done', darkMode ? 'th-darkmode' : 'th-lightmode']">Done</th>
</tr>
<tr :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>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
...</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
...</td>
<td
:class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Comments-darkmode' : 'Comments-lightmode']">
...</td>
<td :class="['Done', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="checkbox"
:class="[darkMode ? 'checkbox-darkmode' : 'checkbox-lightmode']" /></td>
</tr>
<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', darkMode && !addBool ? 'Comments-darkmode' : '', !darkMode && !addBool ? 'Comments-lightmode' : '']">
Comments</th>
<th v-if="!addBool" :class="['Done', darkMode ? 'th-darkmode' : 'th-lightmode']">Done</th>
</tr>
<tr v-for="todo in poiTodos" :key="todo.primaryID"
:class="['table-row-data', 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
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
{{ todo.asset }}</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
{{ todo.task }}</td>
<td
:class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode && !addBool ? 'Comments-darkmode' : '', !darkMode && !addBool ? 'Comments-lightmode' : '']">
<textarea type="text" v-model="todo.comments" :readonly="!editable" @change="updatePOITodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
</td>
<td v-if="!addBool" :class="['Done', darkMode ? 'td-darkmode' : 'td-lightmode']"><input
@change="toggleTodo(todo)" type="checkbox" v-model="todo.done"
:class="[darkMode ? 'checkbox-darkmode' : 'checkbox-lightmode']" /></td>
</tr>
</tbody>
</table>
</div>
</section>
<section v-if="addBool" id="saveNewPOI">
<button :class="[darkMode ? 'saveNewPOI-darkmode' : 'saveNewPOI-lightmode']" @click="addPOI()">Save</button>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { computed } from 'vue';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const chosenPOTId = computed(() => store.state.chosenPOTId);
const chosenPOIId = computed(() => store.state.chosenPOIId);
const addBool = computed(() => store.state.new);
const newNamePOI = computed(() => store.state.newNamePOI);
const newTemplateIDPOI = computed(() => store.state.newTemplateIDPOI);
const newCustomerIDPOI = computed(() => store.state.newCustomerIDPOI);
const newCustomerPOI = computed(() => store.state.newCustomerPOI);
const newAssetPOI = computed(() => store.state.newAssetPOI);
const newStatePOI = computed(() => store.state.newStatePOI);
const newCreationDatePOI = computed(() => store.state.newCreationDatePOI);
const newCompletionDatePOI = computed(() => store.state.newCompletionDatePOI);
const newUserPOI = computed(() => store.state.newUserPOI);
const newTemplateDescriptionPOI = computed(() => store.state.newTemplateDescriptionPOI);
const newTemplateNotesPOI = computed(() => store.state.newTemplateNotesPOI);
const newTimeSpentPOI = computed(() => store.state.newTimeSpentPOI);
const newNotesPOI = computed(() => store.state.newNotes);
const editable = computed(() => store.state.editable);
const darkMode = ref('');
const poiTodos = ref([]);
const productionOrderInstances = ref([]);
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
// get production order template todos from id
const getPOITodosById = async () => {
if (chosenPOTId.value != -1 && addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosProductionOrderTemplate/${chosenPOTId.value}`
);
poiTodos.value = response.data;
store.commit('updateProductionOrderInstanceTemplateID', chosenPOTId.value)
} catch (err) {
console.log(err.response.statusText);
}
} else if (addBool.value && !(newTemplateIDPOI.value == '')) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosProductionOrderTemplate/${newTemplateIDPOI.value}`
);
poiTodos.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosProductionOrderInstance/${chosenPOIId.value}`
);
const poiTodosComment = response.data;
// change the comment und step field name to comments and rowID
poiTodos.value = poiTodosComment.map(obj => {
const { step: rowID, comment: comments, ...rest } = obj;
return { ...rest, rowID, comments };
});
} catch (err) {
console.log(err.response.statusText);
}
}
poiTodos.value = poiTodos.value.map(obj => ({
// convert 'done' to boolean
...obj,
done: obj.done === "1"
}));
}
const toggleTodo = (todo) => {
let doneInput = false;
doneInput = todo.done;
updatePOITodo(todo, true, doneInput);
}
//update data
const updatePOITodo = async (todo, doneChanged = false, doneInput = false) => {
if (doneChanged) {
todo.done = doneInput;
}
if (todo.done) {
todo.done = 1;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updatePOITodo`,
{
primaryID: todo.primaryID,
step: todo.rowID,
asset: todo.asset,
task: todo.task,
comment: todo.comments,
done: todo.done,
}
);
await getPOITodosById();
} catch (err) {
console.log(err.response.statusText);
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
//get all productionOrder instances
const getProductionOrderInstances = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderInstances`);
productionOrderInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// add new production order instance
const addPOI = async () => {
// check if all input data is valid
if (newNamePOI.value.trim() === "") {
alert("Please add a production order instance name!");
return;
} else {
var counter = 0;
if (!(productionOrderInstances.value.length == null)) {
// check if production order instance name already exists
productionOrderInstances.value.forEach(p => {
if (p.name === newNamePOI.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This production order instance name already exists. Please choose an unique production order instance name or modify respectively delete the old one!");
return;
}
}
}
if (newCustomerPOI.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;
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addPOI`,
{
name: newNamePOI.value,
templateID: newTemplateIDPOI.value,
customerID: newCustomerIDPOI.value,
customer: newCustomerPOI.value,
asset: newAssetPOI.value,
state: newStatePOI.value,
creationDate: dateTime,
completionDate: newCompletionDatePOI.value,
user: newUserPOI.value,
templateDescription: newTemplateDescriptionPOI.value,
templateNotes: newTemplateNotesPOI.value,
timeSpent: newTimeSpentPOI.value,
notes: newNotesPOI.value,
});
store.commit('resetStore');
store.commit('deactivateSearch');
store.commit('changeToInstancelist');
store.commit('seeAllIcon');
poiTodos.value.forEach(async todo => {
try {
const res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addTodoPOI`,
{
templateID: response.data,
step: todo.rowID,
asset: todo.asset,
task: todo.task,
comment: todo.comments,
done: false,
});
} catch (err) {
console.log(err.response.statusText);
}
})
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
watch(modeChanged, getSession)
watch(newTemplateIDPOI, getPOITodosById)
onMounted(async () => {
getSession();
await getPOITodosById();
triggerBackendCallsWithDelay(getProductionOrderInstances);
});
</script>
<script>
export default {
name: "InstanceChecklist",
};
</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 {
@ -80,6 +304,20 @@ export default {
border-collapse: collapse;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.input {
border: none;
}
.table-row {
display: flex;
flex-direction: row;
@ -89,6 +327,50 @@ export default {
gap: 0.625rem;
}
.table-row-data {
display: flex;
flex-direction: row;
align-items: center;
padding: 0.625rem;
gap: 0.625rem;
}
.saveNewPOI-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);
}
.saveNewPOI-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);
}
.saveNewPOI-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.saveNewPOI-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#saveNewPOI {
text-align: center;
}
.tr-head-darkmode {
border-top: none;
border-bottom: 0.0625rem solid #000000;
@ -116,6 +398,10 @@ td {
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
td {
height: 5rem;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
@ -134,11 +420,28 @@ th {
filter: invert(100%);
}
.checkbox-lightmode {
filter: invert(0%);
}
.instance-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;
}
.Step {
width: 7%;
}
@ -209,4 +512,10 @@ th {
.label-lightmode {
color: #000;
}
textarea {
resize: none;
width: 20rem;
height: 5rem;
}
</style>

View File

@ -0,0 +1,532 @@
<template>
<section :class="['instance-checklist-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Checklist:</div>
<table class="data-table" id="instance-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', darkMode && !addBool ? 'Comments-darkmode' : '', !darkMode && !addBool ? 'Comments-lightmode' : '']">
Comments</th>
<th v-if="!addBool" :class="['Done', darkMode ? 'th-darkmode' : 'th-lightmode']">Done</th>
</tr>
<tr v-for="todo in mviTodos" :key="todo.primaryID"
:class="['table-row-data', 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
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
{{ todo.asset }}</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
{{ todo.task }}</td>
<td
:class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode && !addBool ? 'Comments-darkmode' : '', !darkMode && !addBool ? 'Comments-lightmode' : '']">
<textarea type="text" v-model="todo.comments" :readonly="!editable"
@change="updateMVITodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
</td>
<td v-if="!addBool" :class="['Done', darkMode ? 'td-darkmode' : 'td-lightmode']"><input
@change="toggleTodo(todo)" type="checkbox" v-model="todo.done"
:class="[darkMode ? 'checkbox-darkmode' : 'checkbox-lightmode']" /></td>
</tr>
</tbody>
</table>
</section>
<section v-if="addBool" id="saveNewMVI">
<button :class="[darkMode ? 'saveNewMVI-darkmode' : 'saveNewMVI-lightmode']" @click="addMVI()">Save</button>
</section>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
import { computed } from 'vue';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const chosenMVIId = computed(() => store.state.chosenMITId);
const chosenMVTId = computed(() => store.state.chosenMVTId);
const addBool = computed(() => store.state.new);
const newNameMVI = computed(() => store.state.newNameMVI);
const newTemplateIDMVI = computed(() => store.state.newTemplateIDMVI);
const newMaintenanceTypeMVI = computed(() => store.state.newMaintenanceTypeMVI);
const newStateMVI = computed(() => store.state.newStateMVI);
const newCreationDateMVI = computed(() => store.state.newCreationDateMVI);
const newCompletionDateMVI = computed(() => store.state.newCompletionDateMVI);
const newUserMVI = computed(() => store.state.newUserMVI);
const newCustomerIDMVI = computed(() => store.state.newCustomerIDMVI);
const newCustomerMVI = computed(() => store.state.newCustomerMVI);
const newTemplateNotesMVI = computed(() => store.state.newTemplateNotesMVI);
const newTypeMVI = computed(() => store.state.newTypeMVI);
const newTimeSpentMVI = computed(() => store.state.newTimeSpentMVI);
const newNotesMVI = computed(() => store.state.newNotesMVI);
const editable = computed(() => store.state.editable);
const darkMode = ref('');
const mviTodos = ref([]);
const maintenanceVisitInstances = ref([]);
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
// get maintenance visit template todos from id
const getMVITodosById = async () => {
if (chosenMVTId.value != -1 && addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosMaintenanceVisitTemplate/${chosenMVTId.value}`
);
const mviTodosComment = response.data;
// change the commets to comments
mviTodos.value = mviTodosComment.map(obj => {
const { commets: comments, ...rest } = obj;
return { ...rest, comments };
});
store.commit('updateMaintenanceVisitInstanceTemplateID', chosenMVTId.value)
} catch (err) {
console.log(err.response.statusText);
}
} else if (addBool.value && !(newTemplateIDMVI.value == '')) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosMaintenanceVisitTemplate/${newTemplateIDMVI.value}`
);
const mviTodosComment = response.data;
// change the commets to comments
mviTodos.value = mviTodosComment.map(obj => {
const { commets: comments, ...rest } = obj;
return { ...rest, comments };
});
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosMaintenanceVisitInstance/${chosenMVIId.value}`
);
const mviTodosComment = response.data;
// change the comment and step field name to comments and rowID
mviTodos.value = mviTodosComment.map(obj => {
const { step: rowID, comment: comments, ...rest } = obj;
return { ...rest, rowID, comments };
});
} catch (err) {
console.log(err.response.statusText);
}
}
mviTodos.value = mviTodos.value.map(obj => ({
// convert 'done' to boolean
...obj,
done: obj.done === "1"
}));
}
const toggleTodo = (todo) => {
let doneInput = false;
doneInput = todo.done;
updateMVITodo(todo, true, doneInput);
}
//update data
const updateMVITodo = async (todo, doneChanged = false, doneInput = false) => {
if (doneChanged) {
todo.done = doneInput;
}
if (todo.done) {
todo.done = 1;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateMVITodo`,
{
primaryID: todo.primaryID,
step: todo.rowID,
asset: todo.asset,
task: todo.task,
comment: todo.comments,
done: todo.done,
}
);
await getMVITodosById();
} catch (err) {
console.log(err.response.statusText);
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
//get all maintenance visit instances
const getMaintenanceVisitInstances = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllMaintenanceVisitInstances`);
maintenanceVisitInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// add new maintenance visit instance
const addMVI = async () => {
// check if all input data is valid
if (newNameMVI.value.trim() === "") {
alert("Please add a maintenance visit instance name!");
return;
} else {
var counter = 0;
if (!(maintenanceVisitInstances.value.length == null)) {
// check if maintenance visit instance name already exists
maintenanceVisitInstances.value.forEach(m => {
if (m.name === newNameMVI.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This maintenance visit instance name already exists. Please choose an unique maintenance visit instance name or modify respectively delete the old one!");
return;
}
}
}
if (newCustomerMVI.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;
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addMVI`,
{
name: newNameMVI.value,
templateID: newTemplateIDMVI.value,
maintenanceType: newMaintenanceTypeMVI.value,
state: newStateMVI.value,
creationDate: dateTime,
completionDate: newCompletionDateMVI.value,
user: newUserMVI.value,
customerID: newCustomerIDMVI.value,
customer: newCustomerMVI.value,
templateNotes: newTemplateNotesMVI.value,
type: newTypeMVI.value,
timeSpent: newTimeSpentMVI.value,
notes: newNotesMVI.value,
});
store.commit('resetStore');
store.commit('deactivateSearch');
store.commit('changeToInstancelist');
store.commit('seeAllIcon');
mviTodos.value.forEach(async todo => {
try {
const res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addTodoMVI`,
{
templateID: response.data,
step: todo.rowID,
asset: todo.asset,
task: todo.task,
comment: todo.comments,
done: false,
});
} catch (err) {
console.log(err.response.statusText);
}
})
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
watch(modeChanged, getSession)
watch(newTemplateIDMVI, getMVITodosById)
onMounted(async () => {
getSession();
await getMVITodosById();
triggerBackendCallsWithDelay(getMaintenanceVisitInstances);
});
</script>
<script>
export default {
name: "InstanceChecklistMVI",
};
</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;
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.data-table {
width: 100%;
padding: 0 0.625rem;
table-layout: fixed;
border-collapse: collapse;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.input {
border: none;
}
.table-row {
display: flex;
flex-direction: row;
align-items: center;
height: 3.125rem;
padding: 0.625rem;
gap: 0.625rem;
}
.table-row-data {
display: flex;
flex-direction: row;
align-items: center;
padding: 0.625rem;
gap: 0.625rem;
}
.saveNewMVI-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);
}
.saveNewMVI-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);
}
.saveNewMVI-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.saveNewMVI-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#saveNewMVI {
text-align: center;
}
.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;
}
td {
height: 5rem;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.th-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
.checkbox-darkmode {
filter: invert(100%);
}
.checkbox-lightmode {
filter: invert(0%);
}
.instance-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;
}
.Step {
width: 7%;
}
.Step-darkmode {
border-right: 0.0625rem solid #000000;
}
.Step-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Asset {
width: 28%;
}
.Asset-darkmode {
border-right: 0.0625rem solid #000000;
}
.Asset-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Task {
width: 30%;
}
.Task-darkmode {
border-right: 0.0625rem solid #000000;
}
.Task-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Comments {
width: 30%;
}
.Comments-darkmode {
border-right: 0.0625rem solid #000000;
}
.Comments-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Done {
width: 5%;
}
.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;
}
textarea {
resize: none;
width: 20rem;
height: 5rem;
}
</style>

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,213 @@
<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';
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 modeChanged = computed(() => store.state.updateDarkMode);
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('');
const issue = ref({});
const issues = ref([]);
const newName = ref('');
const newType = ref('');
const newState = ref('');
const newAmount = ref('');
const newProperties = ref('');
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
//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);
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
await getIssueById();
triggerBackendCallsWithDelay(getIssues);
});
</script>
<script>
export default {
name: "Issue",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -67,7 +263,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 +308,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,37 @@
<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>
<nuxt-link to="/productionOrders" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenPOI(issueSlip.ticketNo)">
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ issueSlip.ticketNo }}</pre>
</nuxt-link>
</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 +40,299 @@
<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']">Production order:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"></pre>
<select id="ticketNoDropDownChosenCI" v-model="chosenTemplate"
@change="updateIS(chosenTemplate)"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="template in productionOrders" :key="template.templateID">
{{ template.name }}
</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';
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 modeChanged = computed(() => store.state.updateDarkMode);
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('');
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('');
const chosenTemplate = 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);
}
}
}
const goToChosenPOI = (id) => {
store.commit('setChosenPOI', id);
store.commit('changeToInstance');
};
// update issue slip fields in the store
const updateIS = async (newPoiId = -1) => {
let is = {};
if (!(newPoiId == '-1')) {
// Find the object with the selected Name
const selectedObject = productionOrders.value.find(obj => obj.name === newPoiId);
// Get the ticketNumber
newTicketNo.value = selectedObject ? selectedObject.ticketNumber : null;
}
is = {
customerId: newCustomerID.value,
customer: newCustomer.value,
ticketNo: newTicketNo.value,
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 productionOrder instances
const getProductionOrders = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderInstances`);
productionOrders.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);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(deleteBool, confirmDeleteIssueSlip);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getIssueSlipById();
await getProductionOrders();
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "IssueSlip",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -92,7 +378,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 +415,10 @@ export default {
font: 400 0.75rem/250% Overpass, sans-serif;
}
.input {
border: none;
}
.data-darkmode {
background-color: #212121;
color: #fff;
@ -147,7 +437,7 @@ export default {
align-self: stretch;
}
.client,
.customer,
.info {
display: flex;
flex-direction: column;
@ -165,7 +455,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 +483,12 @@ export default {
gap: 0.625rem;
}
.data#notes {
.data#notes,
.data#deliveryAddress {
align-self: stretch;
}
.deliveryAddress,
.notes {
display: flex;
flex-direction: column;
@ -206,4 +498,32 @@ 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;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
</style>

View File

@ -1,44 +1,149 @@
<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">
<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>
<th :class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID
</th>
<th
:class="['TicketNo', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
Ticket No.</th>
<th
:class="['CreationDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
Creation Date</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
...</td>
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td
:class="['TicketNo', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
...</td>
<td
:class="['CreationDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<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
</th>
<th
:class="['TicketNo', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
Ticket No.</th>
<th
:class="['CreationDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
Creation Date</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr v-for="issueSlip in issueSlips" :key="issueSlip.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
: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']">
<nuxt-link to="/issueSlips" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-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>
<td
:class="['CreationDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
{{ issueSlip.creationDate }}</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']"> {{ issueSlip.user }}</td>
</tr>
</tbody>
</table>
</div>
</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';
// get accesss to the store
const store = useStore()
const modeChanged = computed(() => store.state.updateDarkMode);
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('')
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/getSelectedIssueSlipsByClient/${customerFilter.value}`);
issueSlips.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//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);
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getIssueSlips();
});
</script>
<script>
@ -46,9 +151,7 @@ export default {
name: "IssueSlipTable",
};
</script>
<style scoped>
.data {
display: flex;
@ -56,7 +159,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;
@ -71,6 +173,53 @@ export default {
background-color: #fff;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.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;
@ -97,6 +246,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;
}
@ -128,15 +298,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;
}
@ -197,4 +367,5 @@ th {
.label-lightmode {
color: #000;
}</style>
}
</style>

View File

@ -1,182 +0,0 @@
<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">
<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="['TicketNo', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
Ticket No.</th>
<th
:class="['CreationDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
Creation Date</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td
:class="['TicketNo', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
...</td>
<td
:class="['CreationDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "IssueSlipTableNoClient",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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);
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.ID {
width: 47.5%;
}
.ID-darkmode {
border-right: 0.0625rem solid #000000;
}
.ID-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.TicketNo {
width: 23.75%;
}
.TicketNo-darkmode {
border-right: 0.0625rem solid #000000;
}
.TicketNo-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.CreationDate {
width: 23.75%;
}
.CreationDate-darkmode {
border-right: 0.0625rem solid #000000;
}
.CreationDate-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.User {
width: 5%;
}
.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;
}</style>

View File

@ -1,50 +1,152 @@
<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">
<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="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th :class="['Amount', darkMode ? 'th-darkmode' : 'th-lightmode']">Amount</th>
</tr>
<tr :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>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
...</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
...</td>
<td :class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<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="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th :class="['Amount', darkMode ? 'th-darkmode' : 'th-lightmode']">Amount</th>
</tr>
<tr v-for="issue in issues" :key="issue.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
: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', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-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>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
{{ issue.state }}</td>
<td :class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode']">{{ issue.amount }}</td>
</tr>
</tbody>
</table>
</div>
</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';
// get accesss to the store
const store = useStore()
const modeChanged = computed(() => store.state.updateDarkMode);
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('');
const issues = ref([]);
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
// 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/getSelectedIssuesByState/${stateFilter.value}`);
issues.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//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);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getIssues();
});
</script>
<script>
export default {
name: "IssueTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -67,6 +169,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;
@ -74,6 +197,53 @@ export default {
border-collapse: collapse;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.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;
@ -181,4 +351,5 @@ th {
.label-lightmode {
color: #000;
}</style>
}
</style>

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', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@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,174 @@
<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 modeChanged = computed(() => store.state.updateDarkMode);
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);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(deleteBool, confirmDeleteIssueVariant);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getIssueVariantById();
await getIssueById();
triggerBackendCallsWithDelay(getIssueVariants);
});
</script>
<script>
export default {
name: "IssueVariant",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -71,8 +231,6 @@ export default {
background-color: #fff;
}
.issue-variant-name {
align-self: stretch;
padding: 1rem 0;
@ -96,7 +254,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 +309,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 +396,16 @@ export default {
padding: 0.625rem 1.875rem 0.625rem 1.25rem;
padding-top: 0rem;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
</style>

View File

@ -1,74 +1,488 @@
<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">
<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 :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>
<td
:class="['Properties', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Properties-darkmode' : 'Properties-lightmode']">
...</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-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>
</tr>
<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="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', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-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']">
<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']">
<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']">
<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']">
<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';
const darkMode = ref(true)
<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';
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('');
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);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
onMounted(async () => {
getSession();
await getIssueVariantsById();
await 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;
}
@ -88,6 +502,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;
@ -106,6 +578,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;
@ -129,8 +633,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 {
@ -142,7 +696,7 @@ th {
}
.Name {
width: 30%;
width: 20%;
}
.Name-darkmode {
@ -178,7 +732,8 @@ th {
}
.Price {
width: 10%;
width: 25%;
display: flex;
}
.label {
@ -198,4 +753,17 @@ th {
.label-lightmode {
color: #000;
}</style>
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
</style>

View File

@ -1,29 +1,38 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['maintenance-visits-instance-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Instance ID</h2>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['maintenance-visits-instance-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
mvi.name }}</h2>
<input v-if="editable" v-model="mvi.name" @change="updateMVI()"
:class="['data', 'mvi-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<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>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvi.templateID }}</pre>
</div>
<div class="templateId-client-type" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</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']">{{ mvi.customer }}</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>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvi.type }}</pre>
<input v-if="editable" v-model="mvi.type" @change="updateMVI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="maintenance-visits-instance-data">
<div class="additional">
<div class="additionaFl">
<div class="templateNotes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Template notes:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="templateNotes">...</pre>
<pre v-if="!editable" :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"
id="templateNotes">{{ mvi.templateNotes }}</pre>
<input v-if="editable" v-model="mvi.templateNotes" @change="updateMVI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
@ -32,15 +41,126 @@
<div class="data-field" id="info">
<div class="maintenanceType-state-user" id="maintenanceType">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Maintenance type:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvi.maintenanceType }}</pre>
<input v-if="editable" v-model="mvi.maintenanceType" @change="updateMVI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="maintenanceType-state-user" 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']">{{ mvi.state }}</pre>
<input v-if="editable" v-model="mvi.state" @change="updateMVI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="maintenanceType-state-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']">{{ mvi.user }}</pre>
<select v-if="editable" id="assetsDropDownChosenCI" v-model="mvi.user" @change="updateMVI()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="user in userList" :key="user.id">
{{ user.username }}
</option>
</select>
</div>
</div>
<div class="data-field" id="info">
<div class="creationDate-completionDate-timeSpent" id="creationDate">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Creation date:</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvi.creationDate }}</pre>
</div>
<div class="creationDate-completionDate-timeSpent" id="completionDate">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Completion date:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvi.completionDate }}</pre>
<input v-if="editable" v-model="mvi.completionDate" @change="updateMVI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="creationDate-completionDate-timeSpent" id="timeSpent">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Time spent:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ mvi.timeSpent }}</pre>
<input v-if="editable" v-model="mvi.timeSpent" @change="updateMVI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="maintenance-visits-instance-data">
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<input v-model="mvi.notes" :readonly="!editable" @change="updateMVI()"
: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="updateMaintenanceVisitInstance()"
:class="['data', 'mvi-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="maintenance-visits-instance-data">
<div class="instanceInfo">
<div class="data-field" id="info">
<div class="templateId-customer-type" id="templateID">
<pre v-if="mvtSelected"
:class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Template ID:</pre>
<pre v-if="!mvtSelected"
:class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Template name:</pre>
<pre v-if="mvtSelected"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ chosenMVTId }}</pre>
<select v-if="!mvtSelected" id="assetsDropDownChosenCI" v-model="chosenTemplate"
@change="updateMaintenanceVisitInstance(chosenTemplate)"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="template in maintenanceVisitTemplates" :key="template.checklistID">
{{ template.name }}
</option>
</select>
</div>
<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']">{{ mvi.customer }}</pre>
</div>
<div class="templateId-customer-type" id="type">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Type:</pre>
<input v-model="newType" @change="updateMaintenanceVisitInstance()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="maintenance-visits-instance-data">
<div class="additionaFl">
<div class="templateNotes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Template notes:</h3>
<input v-model="newTemplateNotes" @change="updateMaintenanceVisitInstance()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
<div class="maintenance-visits-instance-data">
<div class="instanceInfo">
<div class="data-field" id="info">
<div class="maintenanceType-state-user" id="maintenanceType">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Maintenance type:</pre>
<input v-model="newMaintenanceType" @change="updateMaintenanceVisitInstance()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="maintenanceType-state-user" id="state">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">State:</pre>
<input v-model="newState" @change="updateMaintenanceVisitInstance()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="maintenanceType-state-user" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<select id="assetsDropDownChosenCI" v-model="newUser" @change="updateMaintenanceVisitInstance()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="user in userList" :key="user.id">
{{ user.username }}
</option>
</select>
</div>
</div>
<div class="data-field" id="info">
@ -63,18 +183,299 @@
<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="updateMaintenanceVisitInstance()"
: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 { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const darkMode = ref(true)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenMVIId = computed(() => store.state.chosenMITId);
const chosenMVTId = computed(() => store.state.chosenMVTId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('');
const mvtSelected = ref('');
const mvi = ref({});
const mvt = ref({});
const customers = ref([]);
const newName = ref('');
const newTemplateID = ref('');
const chosenTemplate = ref('');
const newCustomerID = ref('');
const newCustomer = ref('');
const newMaintenanceType = ref('');
const newUser = ref('');
const newState = ref('');
const newNotes = ref('');
const newTemplateNotes = ref('');
const newType = ref('');
const newCreationDate = ref('');
const newCompletionDate = ref('');
const newTimeSpent = ref('');
const maintenanceVisitInstances = ref([]);
const maintenanceVisitTemplates = ref([]);
const userList = 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);
}
}
//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);
}
}
// get maintenance visit template from id
const getMVTById = async () => {
if (chosenMVTId.value == '-1') {
mvtSelected.value = false;
await getMaintenanceVisitTemplates();
} else {
mvtSelected.value = true;
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getMaintenanceVisitTemplate/${chosenMVTId.value}`
);
mvt.value = response.data;
mvi.value.customer = mvt.value.customer;
mvi.value.customerID = mvt.value.customerID;
newCustomer.value = mvt.value.customer;
newCustomerID.value = mvt.value.customerID;
} catch (err) {
console.log(err.response.statusText);
}
}
await getMaintenanceVisitInstances();
}
// get maintenance visit template from id
const getChosenMVTById = async (newMvtId) => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getMaintenanceVisitTemplate/${newMvtId}`
);
mvt.value = response.data;
mvi.value.customer = mvt.value.customer;
mvi.value.customerID = mvt.value.customerID;
newCustomer.value = mvt.value.customer;
newCustomerID.value = mvt.value.customerID;
} catch (err) {
console.log(err.response.statusText);
}
}
const confirmDeleteMVI = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this maintenance visit instance? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteMaintenanceVisitInstance/${chosenMVIId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteTodosMVI/${chosenMVIId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('deactivateSearch');
store.commit('changeToInstancelist');
store.commit('seeAllIcon');
} else {
store.commit('undoDelete');
}
}
}
//get all users
const getUsers = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllEmployees`);
userList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//update data
const updateMVI = async () => {
if (mvi.value.name.trim() === "") {
alert("Please add a maintenance visit instance name!");
return;
} else {
var counter = 0;
// check if maintenance visit instance name already exists
maintenanceVisitInstances.value.forEach(m => {
if (m.name === mvi.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This maintenance visit instance name already exists. Please choose an unique maintenance visit instance name or modify respectively delete the old one!");
mvi.value.name = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateMaintenanceVisitInstance`,
{
primaryID: mvi.value.primaryID,
name: mvi.value.name,
templateID: mvi.value.templateID,
maintenanceType: mvi.value.maintenanceType,
state: mvi.value.state,
creationDate: mvi.value.creationDate,
completionDate: mvi.value.completionDate,
user: mvi.value.user,
customerID: mvi.value.customerID,
customer: mvi.value.customer,
type: mvi.value.type,
templateNotes: mvi.value.templateNotes,
timeSpent: mvi.value.timeSpent,
notes: mvi.value.notes,
}
)
await getMVIById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all maintenance visit instances
const getMaintenanceVisitInstances = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllMaintenanceVisitInstances`);
maintenanceVisitInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update maintenance visit instance fields in the store
const updateMaintenanceVisitInstance = async (newMvtId = -1) => {
let maintenanceVisitInstance = {};
if (mvtSelected.value) {
maintenanceVisitInstance = {
name: newName.value,
templateID: chosenMVTId.value,
maintenanceType: newMaintenanceType.value,
state: newState.value,
creationDate: newCreationDate.value,
completionDate: newCompletionDate.value,
user: newUser.value,
customerID: newCustomerID.value,
customer: newCustomer.value,
templateNotes: newTemplateNotes.value,
type: newType.value,
timeSpent: newTimeSpent.value,
notes: newNotes.value,
};
} else {
if (!(newMvtId == '-1')) {
// Find the object with the selected Name
const selectedObject = maintenanceVisitTemplates.value.find(obj => obj.name === newMvtId);
// Get the templateID
newTemplateID.value = selectedObject ? selectedObject.checklistID : null;
await getChosenMVTById(newTemplateID.value);
}
maintenanceVisitInstance = {
name: newName.value,
templateID: newTemplateID.value,
maintenanceType: newMaintenanceType.value,
state: newState.value,
creationDate: newCreationDate.value,
completionDate: newCompletionDate.value,
user: newUser.value,
customerID: newCustomerID.value,
customer: newCustomer.value,
templateNotes: newTemplateNotes.value,
type: newType.value,
timeSpent: newTimeSpent.value,
notes: newNotes.value,
};
}
store.commit('updateMaintenanceVisitInstanceComponent', maintenanceVisitInstance);
}
// get maintenance visit instance from id
const getMVIById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getMaintenanceVisitInstance/${chosenMVIId.value}`
);
mvi.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(deleteBool, confirmDeleteMVI);
onMounted(async () => {
getSession();
await getMVIById();
await getMVTById();
triggerBackendCallsWithDelay(getUsers);
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
@ -82,8 +483,8 @@ export default {
name: "MaintenanceVisitsInstance",
};
</script>
<style scoped>
.information {
display: flex;
@ -115,6 +516,22 @@ export default {
sans-serif;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.h2-darkmode {
color: #fff;
}
@ -129,14 +546,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;
@ -171,6 +588,36 @@ export default {
font: 400 0.75rem/250% Overpass, sans-serif;
}
.h2-darkmode {
color: #fff;
}
.h2-lightmode {
color: #000;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.input {
border: none;
}
.mvi-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;
}
.data-darkmode {
background-color: #212121;
color: #fff;
@ -240,4 +687,8 @@ export default {
padding: 0.625rem 1.875rem 0.625rem 1.25rem;
padding-top: 0rem;
}
.templateNotes {
padding-left: 1.8rem;
}
</style>

View File

@ -1,60 +1,230 @@
<template>
<section v-if="searchable" :class="['mvi-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['instanceLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Name</div>
<input v-model="nameSearchFilter" @change="filterMVIByName()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<section v-if="filtered" :class="['mvi-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['instanceLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">User</div>
<input v-model="userSearchFilter" @change="filterInstancesByUser()"
: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']">Instances:</div>
<table class="data-table" name="maintenance-visits-instance-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="['MaintenanceType', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'MaintenanceType-darkmode' : 'MaintenanceType-lightmode']">
Maintenance type</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th
:class="['CreationDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
Creation date</th>
<th
:class="['CompletionDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
Completion date</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td
:class="['MaintenanceType', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'MaintenanceType-darkmode' : 'MaintenanceType-lightmode']">
...</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
...</td>
<td
:class="['CreationDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
...</td>
<td
:class="['CompletionDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<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>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th
:class="['CreationDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
Creation date</th>
<th
:class="['CompletionDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
Completion date</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr v-for="instance in maintenanceVisitInstances" :key="instance.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
<nuxt-link to="/maintenanceVisits" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenMVI(instance.primaryID)">
{{ instance.primaryID }}
</nuxt-link>
</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/maintenanceVisits" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenMVI(instance.primaryID)">
{{ instance.name }}
</nuxt-link>
</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
{{ instance.state }}</td>
<td
:class="['CreationDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
{{ instance.creationDate }}</td>
<td
:class="['CompletionDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
{{ instance.completionDate }}</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">{{ instance.user }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const chosenMVTId = computed(() => store.state.chosenMVTId);
const searchable = computed(() => store.state.searchable);
const filtered = computed(() => store.state.filtered);
const notAllInstancesIcon = computed(() => store.state.notAllInstancesIcon);
const filteredUserTerm = computed(() => store.state.filteredUserTerm);
const userSearchFilter = ref('');
const nameSearchFilter = ref('');
const maintenanceVisitInstances = ref([]);
const darkMode = ref('');
const mvt = ref({});
const MVIByUser = ref([]);
const MVIByName = ref([]);
const goToChosenMVI = (id) => {
store.commit('setChosenMIT', id);
store.commit('changeToInstance');
};
//get all maintenance visit instances
const getMaintenanceVisitInstances = async () => {
if (notAllInstancesIcon.value) {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedMVIByMVT/${mvt.value.checklistID}`);
maintenanceVisitInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllMaintenanceVisitInstances`);
maintenanceVisitInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update search term
const updateSearchTerm = async () => {
nameSearchFilter.value = '';
await getMaintenanceVisitInstances();
}
// update filter term
const updateFilterTerm = async () => {
if (filteredUserTerm.value) {
store.commit('activateFiltered');
userSearchFilter.value = getItem('logged-in-user-username');
} else {
userSearchFilter.value = '';
}
await getMaintenanceVisitInstances();
if (filteredUserTerm.value) {
await filterInstancesByUser();
}
}
// get maintenance visit template from id
const getMVTById = async () => {
if (notAllInstancesIcon.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 getMaintenanceVisitInstances();
}
//get all instances based on the searched state
const filterMVIByName = async () => {
if (nameSearchFilter.value === '') {
await getMaintenanceVisitInstances();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedMVIByName/${nameSearchFilter.value}`);
MVIByName.value = response.data;
maintenanceVisitInstances.value = filterObjectsWithMatchingIds(maintenanceVisitInstances.value, MVIByName.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all instances based on the searched user
const filterInstancesByUser = async () => {
if (userSearchFilter.value === '') {
await getMaintenanceVisitInstances();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedMVIByUser/${userSearchFilter.value}`);
MVIByUser.value = response.data;
maintenanceVisitInstances.value = filterObjectsWithMatchingIds(maintenanceVisitInstances.value, MVIByUser.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
const filterObjectsWithMatchingIds = (arr1, arr2) => {
return arr1.filter(obj1 => {
return arr2.some(obj2 => obj2.primaryID === obj1.primaryID);
});
};
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
const getAll = async () => {
store.commit('resetFilterSearch');
await getMaintenanceVisitInstances();
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(searchable, updateSearchTerm);
watch(filtered, updateFilterTerm);
watch(notAllInstancesIcon, getAll);
onMounted(async () => {
getSession();
await getMVTById();
});
</script>
<script>
export default {
name: "MaintenanceVisitsInstanceTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -130,6 +300,28 @@ td {
color: #000;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.mvi-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;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
@ -146,15 +338,15 @@ th {
border-right: 0.0625rem solid #8e8e8e;
}
.MaintenanceType {
.Name {
width: 15%;
}
.MaintenanceType-darkmode {
.Name-darkmode {
border-right: 0.0625rem solid #000000;
}
.MaintenanceType-lightmode {
.Name-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
@ -217,4 +409,50 @@ th {
.label-lightmode {
color: #000;
}
.input {
border: none;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
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;
}
.instanceLabel {
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;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
</style>

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,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="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';
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 modeChanged = computed(() => store.state.updateDarkMode);
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('');
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);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(deleteBool, confirmDeleteMVT);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getMVTById();
triggerBackendCallsWithDelay(getMaintenanceVisitTemplates);
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "MaintenanceVisitsTemplate",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -61,6 +316,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 +335,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 +360,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 +384,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 +425,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 +435,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 +453,7 @@ export default {
align-self: stretch;
}
.client-ID-type-user,
.customer-ID-type-user,
.info {
display: flex;
flex-direction: column;

View File

@ -1,54 +1,158 @@
<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">
<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>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
<th :class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID
</th>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
...</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
...</td>
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<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>
<th
:class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
ID
</th>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr v-for="template in maintenanceVisitTemplates" :key="template.checklistID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
: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']">
<nuxt-link to="/maintenanceVisits" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-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>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
{{ template.type }}</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']"> {{ template.user }}</td>
</tr>
</tbody>
</table>
</div>
</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';
// get accesss to the store
const store = useStore()
const modeChanged = computed(() => store.state.updateDarkMode);
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('');
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/getSelectedMVTsByCustomer/${customerFilter.value}`);
maintenanceVisitTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(searchable, updateSearchTerm);
watch(customerFilter, getMaintenanceVisitTemplates);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getMaintenanceVisitTemplates();
});
</script>
<script>
export default {
name: "MaintenanceVisitsTemplateTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -56,13 +160,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;
}
@ -71,6 +192,44 @@ export default {
background-color: #fff;
}
.input {
border: none;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
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;
}
.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;
@ -78,6 +237,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;
@ -128,15 +299,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;
}

View File

@ -1,183 +0,0 @@
<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">
<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="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID
</th>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :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>
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "MaintenanceVisitsTemplateTableNoClient",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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);
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Name {
width: 50%;
}
.Name-darkmode {
border-right: 0.0625rem solid #000000;
}
.Name-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.ID {
width: 22.5%;
}
.ID-darkmode {
border-right: 0.0625rem solid #000000;
}
.ID-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Type {
width: 22.5%;
}
.Type-darkmode {
border-right: 0.0625rem solid #000000;
}
.Type-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.User {
width: 5%;
}
.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;
}
</style>

View File

@ -1,52 +1,402 @@
<template>
<section :class="['network-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<section v-if="networkBoolean && !addBool"
:class="['network-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']" id="network">Network specifications:</div>
<div class="asset-data">
<div class="IPv4-MAC">
<div class="data-field" id="IPv4">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">IPv4:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ inputIPv4 }}</pre>
<input v-if="editable" v-model="inputIPv4" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="MAC">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">MAC:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.MAC }}</pre>
<input v-if="editable" v-model="item.MAC" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="IPv6-subnetmask">
<div class="data-field" id="IPv6">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">IPv6:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ inputIPv6 }}</pre>
<input v-if="editable" v-model="inputIPv6" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="subnetmask">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Subnetmask:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ item.subnetmask }}</pre>
<input v-if="editable" v-model="item.subnetmask" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</section>
<section v-if="addBool" :class="['network-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']" id="network">Network specifications:</div>
<div class="asset-data">
<div class="IPv4-MAC">
<div class="data-field" id="IPv4">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">IPv4:</pre>
<input v-model="newIPv4" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="MAC">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">MAC:</pre>
<input v-model="newMAC" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="IPv6-subnetmask">
<div class="data-field" id="IPv6">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">IPv6:</pre>
<input v-model="newIPv6" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="subnetmask">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">Subnetmask:</pre>
<input v-model="newSubnetmask" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</section>
<section v-if="addBool" id="saveNewItem">
<button :class="[darkMode ? 'saveNewItem-darkmode' : 'saveNewItem-lightmode']" @click="addItem()">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 darkMode = ref(true)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenAssetId = computed(() => store.state.chosenAssetId);
const addBool = computed(() => store.state.new);
const newAssetName = computed(() => store.state.newAssetName);
const newCustomerID = computed(() => store.state.newCustomerID);
const newCustomer = computed(() => store.state.newCustomer);
const newLocation = computed(() => store.state.newLocation);
const newRemoteLocation = computed(() => store.state.newRemoteLocation);
const newType = computed(() => store.state.newType);
const newDescription = computed(() => store.state.newDescription);
const newNotes = computed(() => store.state.newNotes);
const newState = computed(() => store.state.newState);
const newLastView = computed(() => store.state.newLastView);
const newUser = computed(() => store.state.newUser);
const hardwareBool = computed(() => store.state.hardwareBool);
const newModel = computed(() => store.state.newModel);
const newSerialnumber = computed(() => store.state.newSerialnumber);
const newCPU = computed(() => store.state.newCPU);
const newRAM = computed(() => store.state.newRAM);
const newStorageConfiguration = computed(() => store.state.newStorageConfiguration);
const newMiscellaneous = computed(() => store.state.newMiscellaneous);
const softwareBool = computed(() => store.state.softwareBool);
const newSoftware = computed(() => store.state.newSoftware);
const newVersion = computed(() => store.state.newVersion);
const newLicense = computed(() => store.state.newLicense);
const darkMode = ref('');
const item = ref({});
const networkBoolean = ref(false);
const inputIPv4 = ref('');
const inputIPv6 = ref('');
const newNetworkBool = ref(true);
const newIPv4 = ref('');
const newIPv6 = ref('');
const newMAC = ref('');
const newSubnetmask = ref('');
const configItems = ref([]);
// get config item from id
const getItemById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getConfigItem/${chosenAssetId.value}`
);
item.value = response.data;
if (item.value.networkBool == 1) {
networkBoolean.value = true;
};
if (item.value.IPv4 == null) {
inputIPv4.value = "";
} else {
inputIPv4.value = item.value.IPv4;
}
if (item.value.IPv6 == null) {
inputIPv6.value = "";
} else {
inputIPv6.value = item.value.IPv6;
}
} catch (err) {
console.log(err.response.statusText);
}
}
}
// helper function to validate an IPv4 address
const validateIPv4address = (ipaddress) => {
const ipv4format = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
if (ipv4format.test(ipaddress) || ipaddress === "") {
return true;
} else {
return false;
}
}
// helper function to validate an IPv4 address
const validateIPv6address = (ipaddress) => {
const ipv6format = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/gi;
if (ipv6format.test(ipaddress) || ipaddress === "") {
return true;
} else {
return false;
}
}
//update data
const updateConfigItem = async () => {
if (inputIPv4.value.length === 0 && inputIPv6.value.length === 0 && item.value.MAC.length === 0 && item.value.subnetmask.length === 0) {
item.value.networkBool = 0;
}
if (validateIPv4address(inputIPv4.value)) {
item.value.IPv4 = inputIPv4.value;
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateConfigItem`,
{
primaryID: item.value.primaryID,
assetName: item.value.assetName,
customerID: item.value.customerID,
customer: item.value.customer,
location: item.value.location,
remoteLocation: item.value.remoteLocation,
type: item.value.type,
description: item.value.description,
notes: item.value.notes,
state: item.value.state,
lastView: item.value.lastView,
user: item.value.user,
hardwareBool: item.value.hardwareBool,
model: item.value.model,
serialnumber: item.value.serialnumber,
CPU: item.value.CPU,
RAM: item.value.RAM,
storageConfiguration: item.value.storageConfiguration,
miscellaneous: item.value.miscellaneous,
softwareBool: item.value.softwareBool,
software: item.value.software,
version: item.value.version,
license: item.value.license,
networkBool: item.value.networkBool,
IPv4: item.value.IPv4,
IPv6: item.value.IPv6,
MAC: item.value.MAC,
subnetmask: item.value.subnetmask,
}
);
} catch (err) {
console.log(err.response.statusText);
}
} else {
if (item.value.IPv4 == null) {
inputIPv4.value = "";
} else {
inputIPv4.value = item.value.IPv4;
}
alert("You have entered an invalid IPv4 address, please choose a valid one!");
}
if (validateIPv6address(inputIPv6.value)) {
item.value.IPv6 = inputIPv6.value;
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateConfigItem`,
{
primaryID: item.value.primaryID,
assetName: item.value.assetName,
customerID: item.value.customerID,
customer: item.value.customer,
location: item.value.location,
remoteLocation: item.value.remoteLocation,
type: item.value.type,
description: item.value.description,
notes: item.value.notes,
state: item.value.state,
lastView: item.value.lastView,
user: item.value.user,
hardwareBool: item.value.hardwareBool,
model: item.value.model,
serialnumber: item.value.serialnumber,
CPU: item.value.CPU,
RAM: item.value.RAM,
storageConfiguration: item.value.storageConfiguration,
miscellaneous: item.value.miscellaneous,
softwareBool: item.value.softwareBool,
software: item.value.software,
version: item.value.version,
license: item.value.license,
networkBool: item.value.networkBool,
IPv4: item.value.IPv4,
IPv6: item.value.IPv6,
MAC: item.value.MAC,
subnetmask: item.value.subnetmask,
}
);
} catch (err) {
console.log(err.response.statusText);
}
} else {
if (item.value.IPv6 == null) {
inputIPv6.value = "";
} else {
inputIPv6.value = item.value.IPv6;
}
alert("You have entered an invalid IPv6 address, please choose a valid one!");
}
await getItemById();
}
// add new config item
const addItem = async () => {
if (newIPv4.value.length === 0 && newIPv6.value.length === 0 && newMAC.value.length === 0 && newSubnetmask.value.length === 0) {
newNetworkBool.value = false;
}
// check if all input data is valid
if (newAssetName.value.trim() === "") {
alert("Please add a config item name!");
return;
} else {
var counter = 0;
// check if config item name already exists
configItems.value.forEach(ci => {
if (ci.assetName === newAssetName.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This asset name already exists. Please choose an unique asset name or modify respectively delete the old one!");
return;
}
}
if (newCustomer.value.length === 0) {
alert("Please choose a client!");
return;
}
if (!validateIPv4address(newIPv4.value)) {
alert("Please enter a valid IPv4 address or leave this field empty!");
return;
}
if (!validateIPv6address(newIPv6.value)) {
alert("Please enter a valid IPv6 address or leave this field empty!");
return;
}
try {
const response = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addConfigItem`,
{
assetName: newAssetName.value,
customerID: newCustomerID.value,
customer: newCustomer.value,
location: newLocation.value,
remoteLocation: newRemoteLocation.value,
type: newType.value,
description: newDescription.value,
notes: newNotes.value,
state: newState.value,
lastView: newLastView.value,
user: newUser.value,
hardwareBool: hardwareBool.value,
model: newModel.value,
serialnumber: newSerialnumber.value,
CPU: newCPU.value,
RAM: newRAM.value,
storageConfiguration: newStorageConfiguration.value,
miscellaneous: newMiscellaneous.value,
softwareBool: softwareBool.value,
software: newSoftware.value,
version: newVersion.value,
license: newLicense.value,
networkBool: newNetworkBool.value,
IPv4: newIPv4.value,
IPv6: newIPv6.value,
MAC: newMAC.value,
subnetmask: newSubnetmask.value,
});
store.commit('resetStore');
store.commit('changeToAssetlist');
} catch (err) {
console.log(err.response.statusText);
}
}
//get all config items
const getConfigItems = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllConfigItems`);
configItems.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1000);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(() => {
getSession();
triggerBackendCallsWithDelay(getItemById);
triggerBackendCallsWithDelay(getConfigItems);
});
</script>
<script>
export default {
name: "NetworkSpecifications",
};
</script>
</script>
<style scoped>
.network-information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 100%;
padding: 1.25rem 1.875rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
@ -66,7 +416,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,4 +479,44 @@ export default {
padding: 0 0;
border-radius: 0.3125rem;
}
.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;
}
.input {
border: none;
}
</style>

View File

@ -1,43 +1,308 @@
<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-client">
<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 :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>
<td
:class="['Amount', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Amount-darkmode' : 'Amount-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>
</tr>
<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">
<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="(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']">
<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']">
<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']">
<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';
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 modeChanged = computed(() => store.state.updateDarkMode);
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('');
// 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();
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getOIById();
});
</script>
<script>
@ -45,9 +310,9 @@ export default {
name: "OrderingInformation",
};
</script>
<style scoped>
.ordering-information {
display: flex;
@ -68,6 +333,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;
@ -192,5 +482,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

@ -1,16 +1,19 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['production-orders-instance-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">Instance ID</h2>
<section v-if="!addBool" :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 v-if="!editable" :class="['production-orders-instance-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
poi.name }}</h2>
<input v-if="editable" v-model="poi.name" @change="updatePOI()"
:class="['data', 'poi-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<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>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ poi.templateID }}</pre>
</div>
<div class="templateId-client" id="client">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Client:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</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']"> {{ poi.customer }}</pre>
</div>
</div>
</div>
@ -19,13 +22,132 @@
<div class="additional">
<div class="templateDescription">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Template description:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="templateDescription">...</pre>
<input v-model="poi.templateDescription" :readonly="!editable" @change="updatePOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"
id="templateDescription">
</div>
</div>
<div class="additional">
<div class="templateNotes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Template notes:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="templateNotes">...</pre>
<input v-model="poi.templateNotes" :readonly="!editable" @change="updatePOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="templateNotes">
</div>
</div>
</div>
<div class="production-orders-instance-data">
<div class="instanceInfo">
<div class="data-field-four" id="infoFour">
<div class="ticketNo-asset-state-user" id="ticketNo">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Ticket No.:</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ poi.ticketNumber }}</pre>
</div>
<div class="ticketNo-asset-state-user" id="asset">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Asset:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ poi.asset }}</pre>
<select v-if="editable" id="assetsDropDownChosenCI" v-model="poi.asset" @change="updatePOI()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="asset in assets" :key="asset.primaryID">
{{ asset.assetName }}
</option>
</select>
</div>
<div class="ticketNo-asset-state-user" id="state">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">State:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ poi.state }}</pre>
<input v-if="editable" v-model="poi.state" @change="updatePOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="ticketNo-asset-state-user" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ poi.user }}</pre>
<select v-if="editable" id="assetsDropDownChosenCI" v-model="poi.user" @change="updatePOI()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="user in userList" :key="user.id">
{{ user.username }}
</option>
</select>
</div>
</div>
<div class="data-field" id="info">
<div class="creationDate-completionDate-timeSpent" id="creationDate">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Creation date:</pre>
<pre
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ poi.creationDate }}</pre>
</div>
<div class="creationDate-completionDate-timeSpent" id="completionDate">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Completion date:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ poi.completionDate }}</pre>
<input v-if="editable" v-model="poi.completionDate" @change="updatePOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="creationDate-completionDate-timeSpent" id="timeSpent">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Time spent:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ poi.timeSpent }}</pre>
<input v-if="editable" v-model="poi.timeSpent" @change="updatePOI()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
<div class="production-orders-instance-data">
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<input v-model="poi.notes" :readonly="!editable" @change="updatePOI()"
: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="updateProductionOrderInstance()"
:class="['data', 'poi-name-input', darkMode ? 'h2-darkmode' : 'h2-lightmode', darkMode ? 'h2-input-darkmode' : 'h2-input-lightmode', 'input']">
<div class="production-orders-instance-data">
<div class="instanceInfo">
<div class="data-field" id="info">
<div class="templateId-customer" id="templateID">
<pre v-if="potSelected"
:class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Template ID:</pre>
<pre v-if="!potSelected"
:class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Template name:</pre>
<pre v-if="potSelected"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ chosenPOTId }}</pre>
<select v-if="!potSelected" id="assetsDropDownChosenCI" v-model="chosenTemplate"
@change="updateProductionOrderInstance(chosenTemplate)"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="template in productionOrderTemplates" :key="template.templateID">
{{ template.name }}
</option>
</select>
</div>
<div class="templateId-customer" id="customer">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Customer:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']"> {{ poi.customer }}</pre>
</div>
</div>
</div>
</div>
<div class="production-orders-instance-data">
<div class="additional">
<div class="templateDescription">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Template description:</h3>
<input v-model="newTemplateDescription" @change="updateProductionOrderInstance()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"
id="templateDescription">
</div>
</div>
<div class="additional">
<div class="templateNotes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Template notes:</h3>
<input v-model="newTemplateNotes" @change="updateProductionOrderInstance()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="templateNotes">
</div>
</div>
</div>
@ -38,15 +160,26 @@
</div>
<div class="ticketNo-asset-state-user" id="asset">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Asset:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<select id="assetsDropDownChosenCI" v-model="newAsset" @change="updateProductionOrderInstance()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="asset in assets" :key="asset.primaryID">
{{ asset.assetName }}
</option>
</select>
</div>
<div class="ticketNo-asset-state-user" id="state">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">State:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<input v-model="newState" @change="updateProductionOrderInstance()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="ticketNo-asset-state-user" id="user">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">User:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<select id="assetsDropDownChosenCI" v-model="newUser" @change="updateProductionOrderInstance()"
:class="[darkMode ? 'select-darkmode' : 'select-lightmode']">
<option v-for="user in userList" :key="user.id">
{{ user.username }}
</option>
</select>
</div>
</div>
<div class="data-field" id="info">
@ -69,27 +202,331 @@
<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="updateProductionOrderInstance()"
: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 { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const darkMode = ref(true)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenPOIId = computed(() => store.state.chosenPOIId);
const chosenPOTId = computed(() => store.state.chosenPOTId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('');
const potSelected = ref('');
const poi = ref({});
const pot = ref({});
const customers = ref([]);
const assets = ref([]);
const newName = ref('');
const newTemplateID = ref('');
const chosenTemplate = ref('');
const newCustomerID = ref('');
const newCustomer = ref('');
const newUser = ref('');
const newState = ref('');
const newNotes = ref('');
const newTemplateDescription = ref('');
const newTemplateNotes = ref('');
const newAsset = ref('');
const newCreationDate = ref('');
const newCompletionDate = ref('');
const newTimeSpent = ref('');
const productionOrderInstances = ref([]);
const productionOrderTemplates = ref([]);
const userList = 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);
}
}
//get all productionOrder templates
const getProductionOrderTemplates = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderTemplates`);
productionOrderTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// get production order template from id
const getPOTById = async () => {
if (chosenPOTId.value == '-1') {
potSelected.value = false;
await getProductionOrderTemplates();
} else {
potSelected.value = true;
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getProductionOrderTemplate/${chosenPOTId.value}`
);
pot.value = response.data;
poi.value.customer = pot.value.customer;
poi.value.customerID = pot.value.customerID;
newCustomer.value = pot.value.customer;
newCustomerID.value = pot.value.customerID;
await getConfigItemsFromCustomer();
} catch (err) {
console.log(err.response.statusText);
}
}
await getProductionOrderInstances();
}
// get production order template from id
const getChosenPOTById = async (newPotId) => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getProductionOrderTemplate/${newPotId}`
);
pot.value = response.data;
poi.value.customer = pot.value.customer;
poi.value.customerID = pot.value.customerID;
newCustomer.value = pot.value.customer;
newCustomerID.value = pot.value.customerID;
await getConfigItemsFromCustomer();
} catch (err) {
console.log(err.response.statusText);
}
}
const confirmDeletePOI = async () => {
if (deleteBool.value === true) {
if (confirm("Do you really want to delete this production order instance? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteProductionOrderInstance/${chosenPOIId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteTodosPOI/${chosenPOIId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('deactivateSearch');
store.commit('changeToInstancelist');
store.commit('seeAllIcon');
} else {
store.commit('undoDelete');
}
}
}
//get all users
const getUsers = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllEmployees`);
userList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//update data
const updatePOI = async () => {
if (poi.value.name.trim() === "") {
alert("Please add a production order instance name!");
return;
} else {
var counter = 0;
// check if production order instance name already exists
productionOrderInstances.value.forEach(p => {
if (p.name === poi.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This production order instance name already exists. Please choose an unique production order instance name or modify respectively delete the old one!");
poi.value.name = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateProductionOrderInstance`,
{
ticketNumber: poi.value.ticketNumber,
name: poi.value.name,
templateID: poi.value.templateID,
customerID: poi.value.customerID,
customer: poi.value.customer,
asset: poi.value.asset,
state: poi.value.state,
creationDate: poi.value.creationDate,
completionDate: poi.value.completionDate,
user: poi.value.user,
templateDescription: poi.value.templateDescription,
templateNotes: poi.value.templateNotes,
timeSpent: poi.value.timeSpent,
notes: poi.value.notes,
}
)
await getPOIById();
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all productionOrder instances
const getProductionOrderInstances = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderInstances`);
productionOrderInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// update production order instance fields in the store
const updateProductionOrderInstance = async (newPotId = -1) => {
let productionOrderInstance = {};
if (potSelected.value) {
productionOrderInstance = {
name: newName.value,
templateID: chosenPOTId.value,
customerID: newCustomerID.value,
customer: newCustomer.value,
asset: newAsset.value,
state: newState.value,
creationDate: newCreationDate.value,
completionDate: newCompletionDate.value,
user: newUser.value,
templateDescription: newTemplateDescription.value,
templateNotes: newTemplateNotes.value,
timeSpent: newTimeSpent.value,
notes: newNotes.value,
};
} else {
if (!(newPotId == '-1')) {
// Find the object with the selected Name
const selectedObject = productionOrderTemplates.value.find(obj => obj.name === newPotId);
// Get the templateID
newTemplateID.value = selectedObject ? selectedObject.templateID : null;
await getChosenPOTById(newTemplateID.value);
}
productionOrderInstance = {
name: newName.value,
templateID: newTemplateID.value,
customerID: newCustomerID.value,
customer: newCustomer.value,
asset: newAsset.value,
state: newState.value,
creationDate: newCreationDate.value,
completionDate: newCompletionDate.value,
user: newUser.value,
templateDescription: newTemplateDescription.value,
templateNotes: newTemplateNotes.value,
timeSpent: newTimeSpent.value,
notes: newNotes.value,
};
}
store.commit('updateProductionOrderInstanceComponent', productionOrderInstance);
}
// get production order instance from id
const getPOIById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getProductionOrderInstance/${chosenPOIId.value}`
);
poi.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
//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/${poi.value.customerID}`);
assets.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else if (!(newCustomerID.value == '')) {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getCIFromCustomer/${newCustomerID.value}`);
assets.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession);
watch(deleteBool, confirmDeletePOI);
watch(editable, getConfigItemsFromCustomer);
onMounted(async () => {
getSession();
await getPOIById();
await getPOTById();
triggerBackendCallsWithDelay(getCustomers);
triggerBackendCallsWithDelay(getUsers);
});
</script>
<script>
export default {
name: "ProductionOrdersInstance",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -102,6 +539,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;
}
@ -110,7 +558,13 @@ export default {
background-color: #fff;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.production-orders-instance-name {
align-self: stretch;
@ -129,13 +583,23 @@ export default {
color: #000;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.data-field {
display: flex;
flex-direction: row;
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 +627,7 @@ export default {
}
.creationDate-completionDate-timeSpent,
.templateId-client {
.templateId-customer {
display: flex;
flex-direction: row;
align-items: center;
@ -187,17 +651,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;
@ -239,6 +692,28 @@ export default {
border-radius: 0.3125rem;
}
.h2-darkmode {
color: #fff;
}
.h2-lightmode {
color: #000;
}
.input {
border: none;
}
.poi-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;
}
.additional {
display: flex;
flex-direction: column;
@ -250,8 +725,8 @@ export default {
border-radius: 0.3125rem;
}
div#client {
padding-left: 2.9em;
div#customer {
padding-left: 4.4em;
}
.area-title {
@ -285,4 +760,20 @@ div#client {
padding: 0.625rem 1.875rem 0.625rem 1.25rem;
padding-top: 0rem;
}
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
</style>

View File

@ -1,65 +1,257 @@
<template>
<section v-if="searchable" :class="['poi-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['instanceLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">Name</div>
<input v-model="nameSearchFilter" @change="filterPOIByName()"
:class="['dataInput', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</section>
<section v-if="filtered" :class="['poi-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<div :class="['instanceLabel', darkMode ? 'label-darkmode' : 'label-lightmode']">User</div>
<input v-model="userSearchFilter" @change="filterInstancesByUser()"
: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']">Instances:</div>
<table class="data-table" name="production-orders-instance-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="['TicketNo', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
Ticket No.</th>
<th
:class="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th
:class="['CreationDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
Creation date</th>
<th
:class="['CompletionDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
Completion date</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td
:class="['TicketNo', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
...</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
...</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
...</td>
<td
:class="['CreationDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
...</td>
<td
:class="['CompletionDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['TicketNo', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
Ticket No.</th>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
<th
:class="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['State', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
State</th>
<th
:class="['CreationDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
Creation date</th>
<th
:class="['CompletionDate', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
Completion date</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr v-for="instance in productionOrderInstances" :key="instance.ticketNumber"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['TicketNo', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'TicketNo-darkmode' : 'TicketNo-lightmode']">
<nuxt-link to="/productionOrders" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenPOI(instance.ticketNumber)">
{{ instance.ticketNumber }}
</nuxt-link>
</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
<nuxt-link to="/productionOrders" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenPOI(instance.ticketNumber)">
{{ instance.name }}
</nuxt-link>
</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
<nuxt-link to="/assets" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenAsset(instance.asset)">
{{ instance.asset }}
</nuxt-link>
</td>
<td
:class="['State', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'State-darkmode' : 'State-lightmode']">
{{ instance.state }}</td>
<td
:class="['CreationDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CreationDate-darkmode' : 'CreationDate-lightmode']">
{{ instance.creationDate }}</td>
<td
:class="['CompletionDate', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'CompletionDate-darkmode' : 'CompletionDate-lightmode']">
{{ instance.completionDate }}</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">{{ instance.user }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const chosenPOTId = computed(() => store.state.chosenPOTId);
const searchable = computed(() => store.state.searchable);
const filtered = computed(() => store.state.filtered);
const notAllInstancesIcon = computed(() => store.state.notAllInstancesIcon);
const filteredUserTerm = computed(() => store.state.filteredUserTerm);
const userSearchFilter = ref('');
const nameSearchFilter = ref('');
const productionOrderInstances = ref([]);
const darkMode = ref('');
const pot = ref({});
const POIByUser = ref([]);
const POIByName = ref([]);
const goToChosenPOI = (id) => {
store.commit('setChosenPOI', id);
store.commit('changeToInstance');
};
//get all production order instances
const getProductionOrderInstances = async () => {
if (notAllInstancesIcon.value) {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedPOIsByPOT/${pot.value.templateID}`);
productionOrderInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderInstances`);
productionOrderInstances.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update search term
const updateSearchTerm = async () => {
nameSearchFilter.value = '';
await getProductionOrderInstances();
}
// update filter term
const updateFilterTerm = async () => {
if (filteredUserTerm.value) {
store.commit('activateFiltered');
userSearchFilter.value = getItem('logged-in-user-username');
} else {
userSearchFilter.value = '';
}
await getProductionOrderInstances();
if (filteredUserTerm.value) {
await filterInstancesByUser();
}
}
// get production order template from id
const getPOTById = async () => {
if (notAllInstancesIcon.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getProductionOrderTemplate/${chosenPOTId.value}`
);
pot.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
await getProductionOrderInstances();
}
const goToChosenAsset = async (name) => {
let ci = {}
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedConfigItemsByAsset/${name}`
);
ci = response.data;
} catch (err) {
console.log(err.response.statusText);
}
store.commit('setChosenAsset', ci[0].primaryID);
setTimeout(() => {
}, 1000);
store.commit('changeToAsset');
};
//get all instances based on the searched name
const filterPOIByName = async () => {
if (nameSearchFilter.value === '') {
await getProductionOrderInstances();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedPOIsByName/${nameSearchFilter.value}`);
POIByName.value = response.data;
productionOrderInstances.value = filterObjectsWithMatchingIds(productionOrderInstances.value, POIByName.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all instances based on the searched user
const filterInstancesByUser = async () => {
if (userSearchFilter.value === '') {
await getProductionOrderInstances();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedPOIsByUser/${userSearchFilter.value}`);
POIByUser.value = response.data;
productionOrderInstances.value = filterObjectsWithMatchingIds(productionOrderInstances.value, POIByUser.value);
} catch (err) {
console.log(err.response.statusText);
}
}
}
const filterObjectsWithMatchingIds = (arr1, arr2) => {
return arr1.filter(obj1 => {
return arr2.some(obj2 => obj2.ticketNumber === obj1.ticketNumber);
});
};
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
const getAll = async () => {
store.commit('resetFilterSearch');
await getProductionOrderInstances();
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
watch(searchable, updateSearchTerm);
watch(filtered, updateFilterTerm);
watch(notAllInstancesIcon, getAll);
onMounted(async () => {
getSession();
await getPOTById();
});
</script>
<script>
export default {
name: "ProductionOrdersInstanceTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -139,20 +331,8 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.ID {
width: 15.83%;
}
.ID-darkmode {
border-right: 0.0625rem solid #000000;
}
.ID-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.TicketNo {
width: 15.83%;
width: 12.83%;
}
.TicketNo-darkmode {
@ -163,6 +343,17 @@ th {
border-right: 0.0625rem solid #8e8e8e;
}
.Name {
width: 18.83%;
}
.Name-darkmode {
border-right: 0.0625rem solid #000000;
}
.Name-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Asset {
width: 15.83%;
@ -234,4 +425,73 @@ th {
.label-lightmode {
color: #000;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.poi-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;
}
.input {
border: none;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
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;
}
.instanceLabel {
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;
}
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
</style>

View File

@ -1,11 +1,70 @@
<template>
<section :class="['information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['production-orders-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="['production-orders-template-name', darkMode ? 'h2-darkmode' : 'h2-lightmode']">{{
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>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</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"
@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="ID">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">ID:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ pot.templateID }}</pre>
</div>
</div>
<div class="user">
<div class="data-field" id="empty">
&nbsp;
</div>
<div class="data-field" id="user">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">User:</pre>
<pre v-if="!editable"
:class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">{{ pot.user }}</pre>
<input v-if="editable" v-model="pot.user" @change="updatePOT()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
<div class="production-orders-template-data">
<div class="additional">
<div class="description">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Description:</h3>
<input v-model="pot.description" :readonly="!editable" @change="updatePOT()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">
</div>
</div>
<div class="additional">
<div class="notes">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Notes:</h3>
<input v-model="pot.notes" :readonly="!editable" @change="updatePOT()"
: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="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="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">
{{ cust.customername }}
</option>
</select>
</div>
<div class="data-field" id="ID">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">ID:</pre>
@ -18,7 +77,8 @@
</div>
<div class="data-field" id="user">
<pre :class="['label', darkMode ? 'div-darkmode' : 'div-lightmode']">User:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<input v-model="newUser" @change="updateProductionOrder()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
@ -26,33 +86,227 @@
<div class="additional">
<div class="description">
<h3 :class="['area-title', darkMode ? 'h3-darkmode' : 'h3-lightmode']">Description:</h3>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">...</pre>
<input v-model="newDescription" @change="updateProductionOrder()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">
</div>
</div>
<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="updateProductionOrder()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']" id="description">
</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 modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenPOTId = computed(() => store.state.chosenPOTId);
const deleteBool = computed(() => store.state.deleteBool);
const addBool = computed(() => store.state.new);
const darkMode = ref('');
const pot = ref({});
const customers = ref([]);
const customer = ref({});
const productionOrderTemplates = ref([]);
const newName = ref('');
const newCustomerID = ref('');
const newCustomer = ref('');
const newUser = ref('');
const newDescription = 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);
}
}
const confirmDeletePOT = async () => {
if (deleteBool.value === true) {
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}`);
} catch (err) {
console.log(err.response.statusText);
}
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deleteTodosPOT/${chosenPOTId.value}`);
} catch (err) {
console.log(err.response.statusText);
}
store.commit('undoDelete');
store.commit('resetStore');
store.commit('changeToTemplatelist');
} else {
store.commit('undoDelete');
}
}
}
//get all productionOrder templates
const getProductionOrderTemplates = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderTemplates`);
productionOrderTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
//update data
const updatePOT = async () => {
if (pot.value.name.trim() === "") {
alert("Please add a production order template name!");
return;
} else {
var counter = 0;
// check if production order template name already exists
productionOrderTemplates.value.forEach(p => {
if (p.name === pot.value.name) {
counter += 1;
}
});
if (counter == 2) {
alert("This production order template name already exists. Please choose an unique production order template name or modify respectively delete the old one!");
pot.value.name = '';
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateProductionOrderTemplate`,
{
templateID: pot.value.templateID,
name: pot.value.name,
customerID: pot.value.customerID,
customer: pot.value.customer,
lastView: pot.value.lastView,
user: pot.value.user,
description: pot.value.description,
notes: pot.value.notes,
}
)
await getPOTById();
} 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/${pot.value.customer}`);
customer.value = response.data;
pot.value.customerID = customer.value.customerID;
store.commit('toggleCustomerChanged');
store.commit('toggleCustomerId', pot.value.customerID);
} catch (err) {
console.log(err.response.statusText);
}
await updatePOT();
}
// get production order template from id
const getPOTById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getProductionOrderTemplate/${chosenPOTId.value}`
);
pot.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);
}
updateProductionOrder();
}
// update production order template fields in the store
const updateProductionOrder = () => {
const productionOrderTemplate = {
name: newName.value,
customerId: newCustomerID.value,
customer: newCustomer.value,
user: newUser.value,
description: newDescription.value,
notes: newNotes.value
};
store.commit('updateProductionOrderTemplateComponent', productionOrderTemplate);
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1500);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(deleteBool, confirmDeletePOT);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getPOTById();
await getProductionOrderTemplates();
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "ProductionOrdersTemplate",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -73,7 +327,15 @@ export default {
background-color: #fff;
}
.pot-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;
}
.production-orders-template-name {
align-self: stretch;
@ -84,6 +346,16 @@ export default {
sans-serif;
}
.production-orders-template-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-darkmode {
color: #fff;
}
@ -98,7 +370,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;
}
@ -137,6 +409,18 @@ export default {
color: #000;
}
.h2-input-darkmode {
background-color: #212121;
}
.h2-input-lightmode {
background-color: #EBEBEB;
}
.input {
border: none;
}
.production-orders-template-data {
display: flex;
flex-direction: row;
@ -145,7 +429,23 @@ export default {
align-self: stretch;
}
.client-ID,
.select-lightmode {
border: none;
color: black;
background: #EBEBEB;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.select-darkmode {
border: none;
color: white;
background: #212121;
padding: 0.4rem;
border-radius: 0.3125rem;
}
.customer-ID,
.user {
display: flex;
flex-direction: column;

View File

@ -1,48 +1,164 @@
<template>
<section v-if="searchable" :class="['pot-search', darkMode ? 'section-darkmode' : 'section-lightmode']">
<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>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Last viewed:</div>
<table class="data-table" name="production-orders-template-table">
<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>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
<th :class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID
</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
...</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
...</td>
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<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>
<th
:class="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
ID
</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr v-for="template in productionOrderTemplates" :key="template.templateID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
: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']">
<nuxt-link to="/productionOrders" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-lightmode']"
@click="goToChosenPOT(template.templateID)">
{{ template.name }}
</nuxt-link>
</td>
<td
:class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
{{ template.templateID }}</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']"> {{ template.user }}</td>
</tr>
</tbody>
</table>
</div>
</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';
// get accesss to the store
const store = useStore()
const modeChanged = computed(() => store.state.updateDarkMode);
const goToChosenPOT = (id) => {
store.commit('setChosenPOT', id);
store.commit('changeToTemplate');
};
const customerFilter = computed(() => store.state.filteredByCustomer);
const searchable = computed(() => store.state.searchable);
const potSearchFilter = ref('');
const darkMode = ref('');
const productionOrderTemplates = ref([]);
//get all productionOrder templates
const getProductionOrderTemplates = async () => {
if (!(customerFilter.value === '')) {
await getFilteredPOTByCustomer();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderTemplates`);
productionOrderTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
//get all productionOrder templates based on the searched pot name
const searchPOT = async () => {
if (potSearchFilter.value === '') {
await getProductionOrderTemplates();
} else {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getSelectedPOTsByPOT/${potSearchFilter.value}`);
productionOrderTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
// update search term
const updateSearchTerm = async () => {
potSearchFilter.value = '';
await getProductionOrderTemplates();
}
//get all productionOrder templates based on the searched customer
const getFilteredPOTByCustomer = async () => {
try {
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);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(customerFilter, getProductionOrderTemplates);
watch(searchable, updateSearchTerm);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getProductionOrderTemplates();
});
</script>
<script>
export default {
name: "ProductionOrdersTemplateTable",
};
</script>
</script>
<style scoped>
.section-darkmode {
background-color: #2c2c2c;
}
.section-lightmode {
background-color: #fff;
}
.input {
border: none;
}
.data {
display: flex;
flex-direction: column;
@ -56,6 +172,17 @@ export default {
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
.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;
}
.div-darkmode {
background-color: #2c2c2c;
}
@ -71,6 +198,18 @@ export default {
border-collapse: collapse;
}
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.table-row {
display: flex;
flex-direction: row;
@ -85,6 +224,16 @@ export default {
border-bottom: 0.0625rem solid #000000;
}
.data-darkmode {
background-color: #212121;
color: #fff;
}
.data-lightmode {
background-color: #EBEBEB;
color: #000;
}
.tr-head-lightmode {
border-top: none;
border-bottom: 0.0625rem solid #8e8e8e;
@ -107,6 +256,19 @@ td {
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
.pot-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;
}
.th-darkmode,
.td-darkmode {
color: #ffffff;
@ -121,15 +283,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;
}
@ -179,4 +341,15 @@ th {
.label-lightmode {
color: #000;
}
.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;
}
</style>

View File

@ -1,164 +0,0 @@
<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">
<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="['ID', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">ID
</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :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>
<td :class="['ID', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'ID-darkmode' : 'ID-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "ProductionOrdersTemplateTableNoClient",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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);
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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-darkmode,
.td-darkmode {
color: #ffffff;
}
.th-lightmode,
.td-lightmode {
color: #000;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Name {
width: 50%;
}
.Name-darkmode {
border-right: 0.0625rem solid #000000;
}
.Name-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.ID {
width: 40%;
}
.ID-darkmode {
border-right: 0.0625rem solid #000000;
}
.ID-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.User {
width: 10%;
}
.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;
}
</style>

View File

@ -1,52 +1,223 @@
<template>
<section :class="['software-information', darkMode ? 'section-darkmode' : 'section-lightmode']">
<section v-if="softwareBoolean && !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">
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Software', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Software-darkmode' : 'Software-lightmode']">
Software</th>
<th
:class="['Version', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Version-darkmode' : 'Version-lightmode']">
Version</th>
<th :class="['License', darkMode ? 'th-darkmode' : 'th-lightmode']">License</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Software', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Software-darkmode' : 'Software-lightmode']">
...</td>
<td
:class="['Version', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Version-darkmode' : 'Version-lightmode']">
...</td>
<td :class="['License', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<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="['Software', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Software-darkmode' : 'Software-lightmode']">
Software</th>
<th
:class="['Version', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Version-darkmode' : 'Version-lightmode']">
Version</th>
<th :class="['License', darkMode ? 'th-darkmode' : 'th-lightmode']">License</th>
</tr>
<tr v-if="editable" :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']"
id="row-1">
<td
:class="['Software', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Software-darkmode' : 'Software-lightmode']">
<input type="text" v-model="item.software" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Version', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Version-darkmode' : 'Version-lightmode']">
<input type="text" v-model="item.version" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['License', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="item.license" @change="updateConfigItem()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
<tr v-if="!editable" :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']"
id="row-1">
<td
:class="['Software', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Software-darkmode' : 'Software-lightmode']">
{{ item.software }}</td>
<td
:class="['Version', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Version-darkmode' : 'Version-lightmode']">
{{ item.version }}</td>
<td :class="['License', darkMode ? 'td-darkmode' : 'td-lightmode']">{{ item.license }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<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-customer">
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['Software', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Software-darkmode' : 'Software-lightmode']">
Software</th>
<th
:class="['Version', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Version-darkmode' : 'Version-lightmode']">
Version</th>
<th :class="['License', darkMode ? 'th-darkmode' : 'th-lightmode']">License</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Software', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Software-darkmode' : 'Software-lightmode']">
<input type="text" v-model="newSoftware" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td
:class="['Version', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Version-darkmode' : 'Version-lightmode']">
<input type="text" v-model="newVersion" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['License', darkMode ? 'td-darkmode' : 'td-lightmode']">
<input type="text" v-model="newLicense" @change="updateAsset()"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
</tr>
</tbody>
</table>
</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 modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editable);
const chosenAssetId = computed(() => store.state.chosenAssetId);
const addBool = computed(() => store.state.new);
const newSoftwareBool = ref(true);
const newSoftware = ref('');
const newVersion = ref('');
const newLicense = ref('');
const darkMode = ref('');
const item = ref({});
const softwareBoolean = ref(false)
// get config item from id
const getItemById = async () => {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getConfigItem/${chosenAssetId.value}`
);
item.value = response.data;
if (item.value.softwareBool == 1) {
softwareBoolean.value = true;
};
} catch (err) {
console.log(err.response.statusText);
}
}
// update software fields in the store
const updateAsset = () => {
if (newSoftware.value.length == 0 && newLicense.value.length == 0 && newVersion.value.length == 0) {
newSoftwareBool.value = false
}
const asset = {
softwareBool: newSoftwareBool.value,
software: newSoftware.value,
version: newVersion.value,
license: newLicense.value,
};
store.commit('updateSoftwareComponent', asset);
}
//update data
const updateConfigItem = async () => {
if (item.value.license.length === 0 && item.value.version.length === 0 && item.value.software.length === 0) {
item.value.softwareBool = 0;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateConfigItem`,
{
primaryID: item.value.primaryID,
assetName: item.value.assetName,
customerID: item.value.customerID,
customer: item.value.customer,
location: item.value.location,
remoteLocation: item.value.remoteLocation,
type: item.value.type,
description: item.value.description,
notes: item.value.notes,
state: item.value.state,
lastView: item.value.lastView,
user: item.value.user,
hardwareBool: item.value.hardwareBool,
model: item.value.model,
serialnumber: item.value.serialnumber,
CPU: item.value.CPU,
RAM: item.value.RAM,
storageConfiguration: item.value.storageConfiguration,
miscellaneous: item.value.miscellaneous,
softwareBool: item.value.softwareBool,
software: item.value.software,
version: item.value.version,
license: item.value.license,
networkBool: item.value.networkBool,
IPv4: item.value.IPv4,
IPv6: item.value.IPv6,
MAC: item.value.MAC,
subnetmask: item.value.subnetmask,
}
);
await getItemById();
} catch (err) {
console.log(err);
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getItemById();
});
</script>
<script>
export default {
name: "SoftwareSpecifications",
};
</script>
</script>
<style scoped>
.software-information {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 100%;
padding: 1.25rem 1.875rem;
border-radius: 0.625rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
@ -172,4 +343,30 @@ th {
.License {
width: 25%;
}</style>
}
.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;
}
</style>

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,257 @@
<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 modeChanged = computed(() => store.state.updateDarkMode);
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('');
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);
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(deleteBool, confirmDeleteSolution);
watch(customerChanged, getSolutionById);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getSolutionById();
await getSolutions();
triggerBackendCallsWithDelay(getCustomers);
});
</script>
<script>
export default {
name: "Solution",
};
</script>
</script>
<style scoped>
.information {
display: flex;
@ -83,7 +396,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 +423,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 +508,7 @@ export default {
align-self: stretch;
}
.client-asset,
.customer-asset,
.info {
display: flex;
flex-direction: column;
@ -175,6 +520,10 @@ export default {
border-radius: 0.3125rem;
}
.input {
border: none;
}
.additional {
display: flex;
flex-direction: column;
@ -199,7 +548,7 @@ export default {
color: #000;
}
.type-state {
.type-id {
display: flex;
flex-direction: row;
align-items: center;

View File

@ -1,63 +1,566 @@
<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">
<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 :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<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 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']">
{{ 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']">
...</td>
{{ newStepTodo }}
</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
...</td>
<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']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
<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>
</div>
</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']">
<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 ? 'deleteSolTodos-darkmode' : 'deleteLastSolTodos-lightmode']"
@click="deleteSolTodoFromNewTodos(index)">-</button>
</td>
</tr>
</tbody>
</table>
</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';
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 modeChanged = computed(() => store.state.updateDarkMode);
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('');
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();
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(customerChanged, getSolutionById);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getSolutionTodosById();
await 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;
}
@ -66,6 +569,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;
@ -73,6 +586,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;
@ -82,6 +613,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;
@ -161,6 +708,7 @@ th {
.Comments {
width: 35%;
display: flex;
}
.label {
@ -180,4 +728,55 @@ th {
.label-lightmode {
color: #000;
}</style>
}
.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,55 +1,156 @@
<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">
<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>
<th
:class="['Name', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
Name</th>
<th
:class="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['Client', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Client-darkmode' : 'Client-lightmode']">
...</td>
<td
:class="['Name', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Name-darkmode' : 'Name-lightmode']">
...</td>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
...</td>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<tbody>
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<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>
<th
:class="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr v-for="sol in solutions" :key="sol.primaryID"
:class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
: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']">
<nuxt-link to="/solutions" id="nuxt-link" class="button"
:class="[darkMode ? 'button-darkmode' : 'button-lightmode', darkMode ? 'nuxt-link-darkmode' : 'nuxt-link-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>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
{{ sol.type }}</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']"> {{ sol.user }}</td>
</tr>
</tbody>
</table>
</div>
</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';
// get accesss to the store
const store = useStore()
const modeChanged = computed(() => store.state.updateDarkMode);
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('');
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/getSelectedSolutionsByCustomer/${customerFilter.value}`);
solutions.value = response.data;
} 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}`);
solutions.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(customerFilter, getSolutions);
watch(searchable, updateSearchTerm);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getSolutions();
});
</script>
<script>
export default {
name: "SolutionTable",
};
</script>
</script>
<style scoped>
.data {
display: flex;
@ -57,7 +158,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;
@ -98,6 +198,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;
}
@ -106,6 +232,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;
@ -115,6 +252,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;
@ -129,15 +274,38 @@ th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
.Client {
#nuxt-link {
text-decoration: none;
}
.nuxt-link-darkmode {
color: white;
}
.nuxt-link-lightmode {
color: #000;
}
.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,183 +0,0 @@
<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">
<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="['Asset', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
Asset</th>
<th
:class="['Type', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
Type</th>
<th :class="['User', darkMode ? 'th-darkmode' : 'th-lightmode']">User</th>
</tr>
<tr :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>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
...</td>
<td
:class="['Type', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Type-darkmode' : 'Type-lightmode']">
...</td>
<td :class="['User', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "SolutionTableNoClient",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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);
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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;
}
.Name {
width: 45%;
}
.Name-darkmode {
border-right: 0.0625rem solid #000000;
}
.Name-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Asset {
width: 22.5%;
}
.Asset-darkmode {
border-right: 0.0625rem solid #000000;
}
.Asset-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Type {
width: 22.5%;
}
.Type-darkmode {
border-right: 0.0625rem solid #000000;
}
.Type-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.User {
width: 10%;
}
.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;
}</style>

View File

@ -1,71 +1,555 @@
<template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<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-checkklist">
<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 :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>
<td
:class="['Asset', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Asset-darkmode' : 'Asset-lightmode']">
...</td>
<td
:class="['Task', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Task-darkmode' : 'Task-lightmode']">
...</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">...</td>
</tr>
<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 potTodos" :key="todo.primaryID"
:class="['table-row-data', 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="updatePOTTodo(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="updatePOTTodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']">
</td>
<td :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<textarea type="text" v-model="todo.comments" :readonly="!editable"
@change="updatePOTTodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
<button v-if="editable" :class="[darkMode ? 'deletePOTTodos-darkmode' : 'deletePOTTodos-lightmode']"
@click="deletePOTTodo(todo.primaryID)">-</button>
</td>
</tr>
<tr v-if="editable && addRow" :class="['table-row-data', 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']">
<textarea type="text" v-model="newCommentsTodo"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
<button :class="[darkMode ? 'savePOTTodos-darkmode' : 'savePOTTodos-lightmode']"
@click="addPOTTodo()">Save</button> <button
:class="[darkMode ? 'deleteLastPOTTodos-darkmode' : 'deleteLastPOTTodos-lightmode']"
@click="deleteNewRow()">-</button>
</td>
</tr>
</tbody>
</table>
</div>
</section>
<section v-if="editable && !addBool" id="editPOTTodos">
<button :class="[darkMode ? 'editPOTTodos-darkmode' : 'editPOTTodos-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-checkklist">
<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-data', 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']"> <textarea type="text"
v-model="newT.comments"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
<button :class="[darkMode ? 'deletePOTTodos-darkmode' : 'deletePOTTodos-lightmode']"
@click="deletePOTTodoFromNewTodos(index)">-</button>
</td>
</tr>
</tbody>
</table>
</section>
<section v-if="addBool" id="editPOTTodos">
<button :class="[darkMode ? 'editPOTTodos-darkmode' : 'editPOTTodos-lightmode']"
@click="addRowForNewPOT()">+</button>
</section>
<section v-if="addBool" id="saveNewPOT">
<button :class="[darkMode ? 'saveNewPOT-darkmode' : 'saveNewPOT-lightmode']" @click="addPOT()">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 darkMode = ref(true)
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const addBool = computed(() => store.state.new);
const editable = computed(() => store.state.editable);
const newNamePOT = computed(() => store.state.newNamePOT);
const newCustomerIDPOT = computed(() => store.state.newCustomerIDPOT);
const newCustomerPOT = computed(() => store.state.newCustomerPOT);
const newLastViewPOT = computed(() => store.state.newLastViewPOT);
const newUserPOT = computed(() => store.state.newUserPOT);
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 customerChanged = computed(() => store.state.customerChanged);
const changedCustomerId = computed(() => store.state.changedCustomerId);
const darkMode = ref('');
const addRow = ref(false);
const configItemList = ref([]);
const productionOrderTemplates = ref([]);
const potTodos = ref([])
const pot = 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 deletePOTTodoFromNewTodos = (index) => {
newTodos.splice(index, 1);
newTodos.forEach((todo, i) => {
todo.rowID = i
})
}
// add new production order template
const addPOT = async () => {
// check if all input data is valid
if (newNamePOT.value.trim() === "") {
alert("Please add a production order template name!");
return;
} else {
var counter = 0;
if (!(productionOrderTemplates.value.length == null)) {
// check if production order template name already exists
productionOrderTemplates.value.forEach(pot => {
if (pot.name === newNamePOT.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This production order template name already exists. Please choose an unique production order template name or modify respectively delete the old one!");
return;
}
}
}
if (newCustomerPOT.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/addPOT`,
{
name: newNamePOT.value,
customerID: newCustomerIDPOT.value,
customer: newCustomerPOT.value,
lastView: newLastViewPOT.value,
user: newUserPOT.value,
description: newDescriptionPOT.value,
notes: newNotesPOT.value,
});
store.commit('resetStore');
store.commit('changeToTemplatelist');
newTodos.forEach(async todo => {
try {
const res = await Axios.post(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/addTodoPOT`,
{
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 pot
const addRowForNewPOT = async () => {
if (newCustomerPOT.value.length === 0) {
alert("Please choose a customer first!");
return;
}
await getConfigItemsFromCustomer();
newTodos.push({
templateID: chosenPOTId.value,
rowID: newRowId.value,
asset: '',
task: '',
comments: ''
});
}
//update data
const updatePOTTodo = 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/updatePOTTodo`,
{
primaryID: todo.primaryID,
templateID: todo.templateID,
rowID: todo.rowID,
asset: todo.asset,
task: todo.task,
comments: todo.comments,
}
);
await getPOTById();
} catch (err) {
console.log(err.response.statusText);
}
}
// add new production order template todo
const addPOTTodo = 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/addTodoPOT`,
{
templateID: chosenPOTId.value,
rowID: newStepTodo.value,
asset: newAssetTodo.value,
task: newTaskTodo.value,
comment: newCommentsTodo.value,
});
addRow.value = false;
await getPOTTodosById();
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 production order templates
const getProductionOrderTemplates = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllProductionOrderTemplates`);
productionOrderTemplates.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1000);
}
// get production order template todos from id
const getPOTTodosById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getTodosProductionOrderTemplate/${chosenPOTId.value}`
);
potTodos.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/${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/getCIFromCustomer/${changedCustomerId.value}`);
configItemList.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
if (customerChanged.value) {
store.commit('toggleCustomerChanged');
}
}
// get production order template from id
const getPOTById = async () => {
if (!addBool.value) {
try {
const response = await Axios.get(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getProductionOrderTemplate/${chosenPOTId.value}`
);
pot.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
await getConfigItemsFromCustomer();
}
const deletePOTTodo = async (id) => {
if (confirm("Do you really want to delete this production order template todo? It cannot be undone!")) {
try {
await Axios.delete(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/deletePOTTodo/${id}`);
} catch (err) {
console.log(err.response.statusText);
}
}
await getPOTTodosById();
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
// const inputValue = ref('');
// const widthMachine = computed(() => inputValue.value);
// function handleInput(event) {
// inputValue.value = event.target.value;
// }
// // Textarea height handling
// const textareaValue = ref('');
// const textareaHeight = computed(() => calcHeight(textareaValue.value));
// function handleTextareaInput(event) {
// textareaValue.value = event.target.value;
// }
// function calcHeight(value) {
// const numberOfLineBreaks = (value.match(/\n/g) || []).length;
// // min-height + lines x line-height + padding + border
// const newHeight = 20 + numberOfLineBreaks * 20 + 12 + 2;
// return newHeight;
// }
// const spanElement = ref(null);
// const computedHeight = ref('auto'); // Default height is 'auto'
// // Compute the height of the span element
// const computeSpanHeight = () => {
// if (spanElement.value) {
// computedHeight.value = spanElement.value.offsetHeight + 'px';
// }
// };
// // Watch for changes in the content of the span element
// watch(() => textareaValue.value, () => {
// computeSpanHeight();
// });
watch(customerChanged, getPOTById);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getPOTTodosById();
await getPOTById();
triggerBackendCallsWithDelay(getProductionOrderTemplates);
});
</script>
<script>
export default {
name: "TemplateChecklist",
};
</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 {
/* .data-span {
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;
}
.div-lightmode {
.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;
@ -82,6 +566,14 @@ export default {
gap: 0.625rem;
}
.table-row-data {
display: flex;
flex-direction: row;
align-items: center;
padding: 0.625rem;
gap: 0.625rem;
}
.tr-head-darkmode {
border-top: none;
border-bottom: 0.0625rem solid #000000;
@ -109,6 +601,10 @@ td {
font: 400 0.875rem/1.875rem Overpass, sans-serif;
}
td {
height: 5rem;
}
th {
font: 700 0.875rem/1.875rem Overpass, sans-serif;
}
@ -123,6 +619,16 @@ th {
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%;
}
@ -161,6 +667,7 @@ th {
.Comments {
width: 35%;
display: flex;
}
.label {
@ -180,4 +687,162 @@ th {
.label-lightmode {
color: #000;
}</style>
}
.editPOTTodos-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);
}
.savePOTTodos-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;
height: 2.1rem;
margin-top: 1.5rem;
}
.saveNewPOT-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);
}
.deletePOTTodos-darkmode {
background: #212121;
color: #fff;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 6rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
height: 2.1rem;
margin-top: 1.5rem;
}
.deleteLastPOTTodos-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;
height: 2.1rem;
margin-top: 1.5rem;
}
.editPOTTodos-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;
}
.savePOTTodos-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;
height: 2.1rem;
margin-top: 1.5rem;
}
.deletePOTTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 6rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
height: 2.1rem;
margin-top: 1.5rem;
}
.deleteLastPOTTodos-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;
height: 2.1rem;
margin-top: 1.5rem;
}
.saveNewPOT-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);
}
.deletePOTTodos-darkmode:hover,
.deleteLastPOTTodos-darkmode:hover,
.savePOTTodos-darkmode:hover,
.editPOTTodos-darkmode:hover,
.saveNewPOT-darkmode:hover {
background-color: #444444;
cursor: pointer;
}
.deletePOTTodos-lightmode:hover,
.deleteLastPOTTodos-lightmode:hover,
.savePOTTodos-lightmode:hover,
.editPOTTodos-lightmode:hover,
.saveNewPOT-lightmode:hover {
background-color: #ACACAC;
cursor: pointer;
}
#saveNewPOT {
text-align: center;
}
#editPOTTodos {
text-align: right;
}
textarea {
resize: none;
width: 20rem;
height: 5rem;
}
</style>

View File

@ -0,0 +1,803 @@
<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-data', 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 :class="['Comments', darkMode ? 'td-darkmode' : 'td-lightmode']">
<textarea type="text" v-model="todo.commets" :readonly="!editable" @change="updateMVTTodo(todo)"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
<button v-if="editable"
:class="[darkMode ? 'deleteMvtTodos-darkmode' : 'deleteMvtTodos-lightmode']"
@click="deleteMVTTodo(todo.primaryID)">-</button>
</td>
</tr>
<tr v-if="editable && addRow" :class="['table-row-data', 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']">
<textarea type="text" v-model="newCommentsTodo"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
<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-data', 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']">
<textarea type="text" v-model="newT.comments"
:class="['data', 'input', darkMode ? 'data-darkmode' : 'data-lightmode']"> </textarea>
<button :class="[darkMode ? 'deleteMvtTodos-darkmode' : 'deleteMvtTodos-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';
// import VueInputAutowidth from 'vue-input-autowidth';
// Vue.use(VueInputAutowidth);
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
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('');
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();
}
const getSession = async () => {
const loggedInUserDarkModeBool = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool == 1) {
darkMode.value = true;
} else {
darkMode.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
watch(customerChanged, getMVTById);
watch(modeChanged, getSession)
onMounted(async () => {
getSession();
await getMvtTodosById();
await 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;
}
.table-row-data {
display: flex;
flex-direction: row;
align-items: center;
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;
}
td {
height: 5rem;
}
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: 1rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
height: 2.1rem;
margin-top: 1.5rem;
}
.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: 6rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
height: 2.1rem;
margin-top: 1.5rem;
}
.deleteLastMvtTodos-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;
height: 2.1rem;
margin-top: 1.5rem;
}
.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: 1rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
height: 2.1rem;
margin-top: 1.5rem;
}
.deleteMvtTodos-lightmode {
background: #EBEBEB;
color: #212121;
font: 400 0.875rem/1.875rem Overpass, sans-serif;
border: none;
border-radius: 0.625rem;
margin-left: 6rem;
padding-left: 0.9rem;
padding-right: 0.9rem;
height: 2.1rem;
margin-top: 1.5rem;
}
.deleteLastMvtTodos-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;
height: 2.1rem;
margin-top: 1.5rem;
}
.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;
}
textarea {
resize: none;
width: 20rem;
height: 5rem;
}
</style>

View File

@ -1,33 +1,267 @@
<template>
<section :class="['userAccount', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['heading', darkMode ? 'heading-darkmode' : 'heading-lightmode']">Account:</h2>
<section :class="['userAccount', loggedInUserDarkModeBoolean ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['heading', loggedInUserDarkModeBoolean ? 'heading-darkmode' : 'heading-lightmode']">Account:</h2>
<div class="userData">
<div class="data-field" id="email">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">E-Mail:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<div class="username-email">
<div class="data-field" id="username">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Username:</pre>
<pre v-if="!editable"
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">{{ loggedInUserUsername }}</pre>
<input v-if="editable" v-model="loggedInUserUsername" @change="updateUsername()"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="email">
<pre :class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Email:</pre>
<pre v-if="!editable"
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">{{ loggedInUserEmail }}</pre>
<input v-if="editable" v-model="loggedInUserEmail" @change="updateUser()"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
<input v-if="editable"
:class="[loggedInUserDarkModeBoolean ? 'input-darkmode' : '', !loggedInUserDarkModeBoolean ? 'input-lightmode' : '',]"
type="button" id="changePassword" value="Change Password" @click="changePassword">
</div>
<div class="data-field" id="password">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Password:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">*******</pre>
<div v-if="changePasswordBool && editable" class="password">
<div class="data-field" id="password">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">New Password:</pre>
<input v-if="editable" v-model="loggedInUserNewPassword"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="passwordRepeated">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Repeat:</pre>
<input v-if="editable" v-model="loggedInUserNewPasswordRepeated"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
<input
:class="[loggedInUserDarkModeBoolean ? 'input-darkmode' : '', !loggedInUserDarkModeBoolean ? 'input-lightmode' : '',]"
type="button" id="savePassword" value="Save Password" @click="savePassword">
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editableUser);
const changePasswordBool = ref(false);
const loggedInUserId = ref('');
const loggedInUserUsername = ref('');
const loggedInUserRegistered = ref('');
const loggedInUserLastLogin = ref('');
const loggedInUserFullName = ref('');
const loggedInUserEmail = ref('');
const loggedInUserPhonenumber = ref('');
const loggedInUserAddress = ref('');
const loggedInUserCity = ref('');
const loggedInUserPostcode = ref('');
const loggedInUserAdminBool = ref('');
const loggedInUserTechnicianBool = ref('');
const loggedInUserReaderBool = ref('');
const loggedInUserNewPassword = ref('');
const loggedInUserNewPasswordRepeated = ref('');
const loggedInUserDarkModeBool = ref('');
const loggedInUserDarkModeBoolean = ref('');
const employees = ref([]);
const changePassword = () => {
changePasswordBool.value = !changePasswordBool.value
loggedInUserNewPassword.value = '';
loggedInUserNewPasswordRepeated.value = '';
}
const savePassword = async () => {
// hier weiter machen
if (loggedInUserNewPassword.value.length < 8) {
alert("Please choose a password with minimal eight characters!");
return
}
// password (repeat) must match
if (loggedInUserNewPassword.value != loggedInUserNewPasswordRepeated.value) {
alert("Your passwords don't match.");
return
}
try {
await Axios.put(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updatePasswordEmployee`,
{
id: loggedInUserId.value,
password: loggedInUserNewPassword.value,
}
)
alert("Password successfully updatet!");
changePasswordBool.value = false;
loggedInUserNewPassword.value = '';
loggedInUserNewPasswordRepeated.value = '';
} catch (err) {
console.log(err);
};
}
const getSession = async () => {
loggedInUserId.value = getItem('logged-in-user-id');
loggedInUserUsername.value = getItem('logged-in-user-username');
loggedInUserRegistered.value = getItem('logged-in-user-registered');
loggedInUserLastLogin.value = getItem('logged-in-user-lastLogin');
loggedInUserFullName.value = getItem('logged-in-user-fullName');
loggedInUserEmail.value = getItem('logged-in-user-email');
loggedInUserPhonenumber.value = getItem('logged-in-user-phonenumber');
loggedInUserAddress.value = getItem('logged-in-user-address');
loggedInUserCity.value = getItem('logged-in-user-city');
loggedInUserPostcode.value = getItem('logged-in-user-postcode');
loggedInUserAdminBool.value = getItem('logged-in-user-adminBool');
loggedInUserTechnicianBool.value = getItem('logged-in-user-technicianBool');
loggedInUserReaderBool.value = getItem('logged-in-user-readerBool');
loggedInUserDarkModeBool.value = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool.value == 1) {
loggedInUserDarkModeBoolean.value = true;
} else {
loggedInUserDarkModeBoolean.value = false;
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
const updateUsername = async () => {
if (loggedInUserUsername.value.length < 5) {
alert("Your username must have at least five characters!");
loggedInUserUsername.value = getItem('logged-in-user-username');
return;
}
var counter = 0;
// check if the username already exists
employees.value.forEach(empl => {
if (empl.username === loggedInUserUsername.value) {
counter += 1;
}
});
if (counter == 1) {
alert("This username already exists. Please choose an unique username!");
loggedInUserUsername.value = getItem('logged-in-user-username');
return;
}
await updateUser();
}
//update data
const updateUser = async () => {
if (!validateEMail(loggedInUserEmail.value)) {
alert("Please add a valid email!");
loggedInUserEmail.value = getItem('logged-in-user-email');
return;
}
if ((loggedInUserPhonenumber.value.length === 0) && (loggedInUserEmail.value.length === 0)) {
alert("Please add a phonenumber or an email!");
loggedInUserPhonenumber.value = getItem('logged-in-user-phonenumber');
loggedInUserEmail.value = getItem('logged-in-user-email')
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateEmployee`,
{
id: loggedInUserId.value,
username: loggedInUserUsername.value,
fullName: loggedInUserFullName.value,
email: loggedInUserEmail.value,
phonenumber: loggedInUserPhonenumber.value,
address: loggedInUserAddress.value,
city: loggedInUserCity.value,
postcode: loggedInUserPostcode.value,
adminBool: loggedInUserAdminBool.value,
technicianBool: loggedInUserTechnicianBool.value,
readerBool: loggedInUserReaderBool.value,
darkModeBool: loggedInUserDarkModeBoolean.value,
}
)
setItem('logged-in-user-username', loggedInUserUsername.value)
setItem('logged-in-user-fullName', loggedInUserFullName.value)
setItem('logged-in-user-email', loggedInUserEmail.value)
setItem('logged-in-user-phonenumber', loggedInUserPhonenumber.value)
setItem('logged-in-user-address', loggedInUserAddress.value)
setItem('logged-in-user-city', loggedInUserCity.value)
setItem('logged-in-user-postcode', loggedInUserPostcode.value)
if (loggedInUserDarkModeBoolean.value) {
loggedInUserDarkModeBool.value = 1;
} else {
loggedInUserDarkModeBool.value = 0;
}
setItem('logged-in-user-darkMode', loggedInUserDarkModeBool.value)
getSession();
store.commit('setLocalStorageChanged');
store.commit('toggleUpdateDarkMode');
} catch (err) {
console.log(err.response.statusText);
}
}
// to validate the email address
const validateEMail = (email) => {
const emailRegex = new RegExp(/^[A-Za-z0-9_!#$%&'*+\/=?`{|}~^.-]+@[A-Za-z0-9.-]+$/, "gm");
if (email === "") {
return true
}
return emailRegex.test(email);
}
function setItem(item, value) {
if (process.client) {
localStorage.setItem(item, value)
return true
} else {
return false
}
}
//get all employees
const getEmployees = async () => {
try {
const response = await Axios.get(`https://${clientsideConfig.url}:${clientsideConfig.port}/api/getAllEmployees`);
employees.value = response.data;
} catch (err) {
console.log(err.response.statusText);
}
}
// include delay to avoid 503 error
const triggerBackendCallsWithDelay = async (fetchDataFunc) => {
setTimeout(() => {
fetchDataFunc();
}, 1000);
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
await triggerBackendCallsWithDelay(getEmployees);
});
</script>
<script>
export default {
name: "UserAccount",
};
</script>
</script>
<style scoped>
.userAccount {
display: flex;
@ -53,6 +287,47 @@ export default {
background-color: #fff;
}
.input-darkmode {
color: #fff;
background-color: #212121;
}
input#changePassword:hover,
input#savePassword:hover {
background-color: #454545;
}
.input-lightmode {
color: #212121;
;
background-color: #EBEBEB;
}
.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;
}
.input {
border: none;
}
.heading {
letter-spacing: 5%;
font: 400 1rem/2rem Overpass, sans-serif;
@ -66,9 +341,21 @@ export default {
color: #000;
}
.userData {
.username-email,
.password {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 50%;
padding: 0 1rem;
border-radius: 0.3125rem;
}
.userData {
display: flex;
flex-direction: row;
align-content: center;
gap: 0.625rem
}
@ -99,7 +386,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;
}
@ -137,4 +424,22 @@ export default {
.label {
width: 6.25rem;
}
input#changePassword,
input#savePassword {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 10rem;
height: 2.5rem;
margin-top: 1rem;
border-radius: 0.625rem;
border: none;
text-align: center;
letter-spacing: 5%;
font: 400 0.875rem/2rem Overpass, sans-serif;
margin-right: 1.25rem;
box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25);
}
</style>

View File

@ -1,36 +1,142 @@
<template>
<section :class="['userAppearance', darkMode ? 'section-darkmode' : 'section-lightmode']">
<section :class="['userAppearance', loggedInUserDarkModeBoolean ? 'section-darkmode' : 'section-lightmode']">
<div class="userData">
<div class="data-field" id="mode">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Mode:</pre>
<pre :class="['smallLabel', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Lightmode</pre>
<Toggle v-model="darkMode" id="toggleAppearance" />
<pre :class="['smallLabel', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Darkmode</pre>
<pre :class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Mode:</pre>
<pre
:class="['smallLabel', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Lightmode</pre>
<Toggle v-model="loggedInUserDarkModeBoolean" id="toggleAppearance" />
<pre
:class="['smallLabel', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Darkmode</pre>
</div>
<div class="data-field" id="language">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Language:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<pre :class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Language:</pre>
<pre :class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">...</pre>
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
import Toggle from '@vueform/toggle'
const darkMode = ref(true)
<script setup>
import { ref, onMounted, watch } from 'vue';
import Toggle from '@vueform/toggle';
import { useStore } from 'vuex';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js'
const store = useStore();
const loggedInUserId = ref('');
const loggedInUserUsername = ref('');
const loggedInUserRegistered = ref('');
const loggedInUserLastLogin = ref('');
const loggedInUserFullName = ref('');
const loggedInUserEmail = ref('');
const loggedInUserPhonenumber = ref('');
const loggedInUserAddress = ref('');
const loggedInUserCity = ref('');
const loggedInUserPostcode = ref('');
const loggedInUserAdminBool = ref('');
const loggedInUserTechnicianBool = ref('');
const loggedInUserReaderBool = ref('');
const loggedInUserDarkModeBool = ref('');
const loggedInUserDarkModeBoolean = ref(true);
function setItem(item, value) {
if (process.client) {
localStorage.setItem(item, value)
return true
} else {
return false
}
}
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
//update data
const updateUser = async () => {
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateEmployee`,
{
id: loggedInUserId.value,
username: loggedInUserUsername.value,
fullName: loggedInUserFullName.value,
email: loggedInUserEmail.value,
phonenumber: loggedInUserPhonenumber.value,
address: loggedInUserAddress.value,
city: loggedInUserCity.value,
postcode: loggedInUserPostcode.value,
adminBool: loggedInUserAdminBool.value,
technicianBool: loggedInUserTechnicianBool.value,
readerBool: loggedInUserReaderBool.value,
darkModeBool: loggedInUserDarkModeBoolean.value,
}
)
setItem('logged-in-user-username', loggedInUserUsername.value)
setItem('logged-in-user-fullName', loggedInUserFullName.value)
setItem('logged-in-user-email', loggedInUserEmail.value)
setItem('logged-in-user-phonenumber', loggedInUserPhonenumber.value)
setItem('logged-in-user-address', loggedInUserAddress.value)
setItem('logged-in-user-city', loggedInUserCity.value)
setItem('logged-in-user-postcode', loggedInUserPostcode.value)
if (loggedInUserDarkModeBoolean.value) {
loggedInUserDarkModeBool.value = 1;
} else {
loggedInUserDarkModeBool.value = 0;
}
setItem('logged-in-user-darkMode', loggedInUserDarkModeBool.value)
getSession();
store.commit('setLocalStorageChanged');
store.commit('toggleUpdateDarkMode');
} catch (err) {
console.log(err.response.statusText);
}
}
const getSession = async () => {
loggedInUserId.value = getItem('logged-in-user-id');
loggedInUserUsername.value = getItem('logged-in-user-username');
loggedInUserRegistered.value = getItem('logged-in-user-registered');
loggedInUserLastLogin.value = getItem('logged-in-user-lastLogin');
loggedInUserFullName.value = getItem('logged-in-user-fullName');
loggedInUserEmail.value = getItem('logged-in-user-email');
loggedInUserPhonenumber.value = getItem('logged-in-user-phonenumber');
loggedInUserAddress.value = getItem('logged-in-user-address');
loggedInUserCity.value = getItem('logged-in-user-city');
loggedInUserPostcode.value = getItem('logged-in-user-postcode');
loggedInUserAdminBool.value = getItem('logged-in-user-adminBool');
loggedInUserTechnicianBool.value = getItem('logged-in-user-technicianBool');
loggedInUserReaderBool.value = getItem('logged-in-user-readerBool');
loggedInUserDarkModeBool.value = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool.value == 1) {
loggedInUserDarkModeBoolean.value = true;
} else {
loggedInUserDarkModeBoolean.value = false;
}
}
watch(loggedInUserDarkModeBoolean, updateUser)
onMounted(async () => {
await getSession();
});
</script>
<script>
export default {
name: "UserAppearance",
};
</script>
<style src="@vueform/toggle/themes/default.css"></style>
</script>
<style src="@vueform/toggle/themes/default.css"></style>
<style scoped>
.userAppearance {
display: flex;
@ -70,7 +176,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

@ -1,32 +1,250 @@
<template>
<section :class="['userProfile', darkMode ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['heading', darkMode ? 'heading-darkmode' : 'heading-lightmode']">Profile:</h2>
<section :class="['userProfile', loggedInUserDarkModeBoolean ? 'section-darkmode' : 'section-lightmode']">
<h2 :class="['heading', loggedInUserDarkModeBoolean ? 'heading-darkmode' : 'heading-lightmode']">Profile:</h2>
<div class="userData">
<div class="rectangle-container">
<div :class="['rectangle', darkMode ? 'rectangle-darkmode' : 'rectangle-lightmode']"></div>
<div :class="['rectangle', loggedInUserDarkModeBoolean ? 'rectangle-darkmode' : 'rectangle-lightmode']">
</div>
</div>
<div class="data-field" id="username">
<pre :class="['label', darkMode ? 'pre-darkmode' : 'pre-lightmode']">Username:</pre>
<pre :class="['data', darkMode ? 'data-darkmode' : 'data-lightmode']">...</pre>
<div class="fullname-registered-lastLogin">
<div class="data-field" id="fullName">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Full name:</pre>
<pre v-if="!editable"
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">{{ loggedInUserFullName }}</pre>
<input v-if="editable" v-model="loggedInUserFullName" @change="updateUser()"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="registered">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Registered:</pre>
<pre
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']"> {{ loggedInUserRegistered }}</pre>
</div>
<div class="data-field" id="lastLogin">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Last login:</pre>
<pre
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']"> {{ loggedInUserLastLogin }}</pre>
</div>
</div>
<div class="info">
<div class="city-phonenumber">
<div class="data-field" id="city">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">City:</pre>
<pre v-if="!editable"
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">{{ loggedInUserCity }}</pre>
<input v-if="editable" v-model="loggedInUserCity" @change="updateUser()"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="phonenumber">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Phonenumber:</pre>
<pre v-if="!editable"
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">{{ loggedInUserPhonenumber }}</pre>
<input v-if="editable" v-model="loggedInUserPhonenumber" @change="updateUser()"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
<div class="postcode-address">
<div class="data-field" id="postcode">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Postcode:</pre>
<pre v-if="!editable"
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">{{ loggedInUserPostcode }}</pre>
<input v-if="editable" v-model="loggedInUserPostcode" @change="updateUser()"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
<div class="data-field" id="address">
<pre
:class="['label', loggedInUserDarkModeBoolean ? 'pre-darkmode' : 'pre-lightmode']">Address:</pre>
<pre v-if="!editable"
:class="['data', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">{{ loggedInUserAddress }}</pre>
<input v-if="editable" v-model="loggedInUserAddress" @change="updateUser()"
:class="['data', 'input', loggedInUserDarkModeBoolean ? 'data-darkmode' : 'data-lightmode']">
</div>
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
<script setup>
import { ref, watch, onMounted } from 'vue';
import { useStore } from 'vuex';
import { computed } from 'vue';
import Axios from '../axios.config.js';
import clientsideConfig from '../../clientsideConfig.js';
const store = useStore();
const modeChanged = computed(() => store.state.updateDarkMode);
const editable = computed(() => store.state.editableUser);
const loggedInUserId = ref('');
const loggedInUserUsername = ref('');
const loggedInUserRegistered = ref('');
const loggedInUserLastLogin = ref('');
const loggedInUserFullName = ref('');
const loggedInUserEmail = ref('');
const loggedInUserPhonenumber = ref('');
const loggedInUserAddress = ref('');
const loggedInUserCity = ref('');
const loggedInUserPostcode = ref('');
const loggedInUserAdminBool = ref('');
const loggedInUserTechnicianBool = ref('');
const loggedInUserReaderBool = ref('');
const loggedInUserDarkModeBool = ref('');
const loggedInUserDarkModeBoolean = ref('');
function getItem(item) {
if (process.client) {
return localStorage.getItem(item)
} else {
return undefined
}
}
const getSession = async () => {
loggedInUserId.value = getItem('logged-in-user-id');
loggedInUserUsername.value = getItem('logged-in-user-username');
loggedInUserRegistered.value = getItem('logged-in-user-registered');
loggedInUserLastLogin.value = getItem('logged-in-user-lastLogin');
loggedInUserFullName.value = getItem('logged-in-user-fullName');
loggedInUserEmail.value = getItem('logged-in-user-email');
loggedInUserPhonenumber.value = getItem('logged-in-user-phonenumber');
loggedInUserAddress.value = getItem('logged-in-user-address');
loggedInUserCity.value = getItem('logged-in-user-city');
loggedInUserPostcode.value = getItem('logged-in-user-postcode');
loggedInUserAdminBool.value = getItem('logged-in-user-adminBool');
loggedInUserTechnicianBool.value = getItem('logged-in-user-technicianBool');
loggedInUserReaderBool.value = getItem('logged-in-user-readerBool');
loggedInUserDarkModeBool.value = getItem('logged-in-user-darkMode');
if (loggedInUserDarkModeBool.value == 1) {
loggedInUserDarkModeBoolean.value = true;
} else {
loggedInUserDarkModeBoolean.value = false;
}
}
//update data
const updateUser = async () => {
if (loggedInUserFullName.value.length == 0) {
alert("Please add a valid name!");
loggedInUserFullName.value = getItem('logged-in-user-fullName');
return;
}
if (loggedInUserCity.value.length == 0) {
alert("Please add a city!");
loggedInUserCity.value = getItem('logged-in-user-city');
return;
}
if (loggedInUserAddress.value.length == 0) {
alert("Please add an address!");
loggedInUserAddress.value = getItem('logged-in-user-address');
return;
}
if (!validatePhonenumber(loggedInUserPhonenumber.value)) {
alert("Please add a valid phonenumber!");
loggedInUserPhonenumber.value = getItem('logged-in-user-phonenumber');
return;
}
if (!validatePostcode(loggedInUserPostcode.value)) {
alert("Please add a valid postcode!");
loggedInUserPostcode.value = getItem('logged-in-user-postcode');
return;
}
if ((loggedInUserPhonenumber.value.length == 0) && (loggedInUserEmail.value.length == 0)) {
alert("Please add a phonenumber or an email!");
loggedInUserPhonenumber.value = getItem('logged-in-user-phonenumber');
loggedInUserEmail.value = getItem('logged-in-user-email')
return;
}
try {
await Axios.put(
`https://${clientsideConfig.url}:${clientsideConfig.port}/api/updateEmployee`,
{
id: loggedInUserId.value,
username: loggedInUserUsername.value,
fullName: loggedInUserFullName.value,
email: loggedInUserEmail.value,
phonenumber: loggedInUserPhonenumber.value,
address: loggedInUserAddress.value,
city: loggedInUserCity.value,
postcode: loggedInUserPostcode.value,
adminBool: loggedInUserAdminBool.value,
technicianBool: loggedInUserTechnicianBool.value,
readerBool: loggedInUserReaderBool.value,
darkModeBool: loggedInUserDarkModeBoolean.value,
}
)
setItem('logged-in-user-username', loggedInUserUsername.value)
setItem('logged-in-user-fullName', loggedInUserFullName.value)
setItem('logged-in-user-email', loggedInUserEmail.value)
setItem('logged-in-user-phonenumber', loggedInUserPhonenumber.value)
setItem('logged-in-user-address', loggedInUserAddress.value)
setItem('logged-in-user-city', loggedInUserCity.value)
setItem('logged-in-user-postcode', loggedInUserPostcode.value)
if (loggedInUserDarkModeBoolean.value) {
loggedInUserDarkModeBool.value = 1;
} else {
loggedInUserDarkModeBool.value = 0;
}
setItem('logged-in-user-darkMode', loggedInUserDarkModeBool.value)
getSession();
} catch (err) {
console.log(err.response.statusText);
}
}
function setItem(item, value) {
if (process.client) {
localStorage.setItem(item, value)
return true
} else {
return false
}
}
// to validate the phonenumber
const validatePhonenumber = (number) => {
const mobilephonenumberRegex = new RegExp(/^(((((00|\+){1,2})49([ \-/]?|[ \()/]?))|0)[1]([0-2]|[4-7])([0-9]{1})([ \-/]?|[ \()/]?)([0-9]{8}))$/, "gm");
const landlineRegex = new RegExp(/^0(30|40|69|89|20[12389]|21[24]|228|234|335|340|3[3-9][15]|906|[2-9][1-9]1|3(?:3(?:[0237][127]|0[3-6]|2[89]|3[458]|[46][1246]|7[589]|8[1256]|9[145])|4(?:[2347][135]|[34]7|[69][146]|48|62|76|93)|5(?:[04679][14]|[238][135]|[2469]2|[4789]6|[278]8|63|73|37|29)|6(?:[024689][13]|[03789]5|06|2[2489]|3[1246]|44|47|7[1279]|82|86)|7(?:[236][135]|2[2467]|37|4[145]|62|64|7[1-4])|8(?:[234678]1|3[468]|4[347]|6[035-9]|7[467]|83|86)|9(?:[236][135]|[04689]4|[04789]1|[03468]7|02|09|28|4[369]|6[2689]|73|76|96|98))|3[3-9][0-9]{3}|13[078]|180[235]|18[01]|19[0-9]{3}|[789]00|[2-9][0-9]{3})([0-9]{1,})$/, "gm");
if (number === "") {
return true
}
if (mobilephonenumberRegex.test(number)) {
return true
} else if (landlineRegex.test(number)) {
return true;
}
return false;
}
// to validate the postcode
const validatePostcode = (postcode) => {
const postcodeRegex = new RegExp(/^\d{5}$/);
if (postcode === "") {
return true
}
return postcodeRegex.test(postcode);
}
watch(modeChanged, getSession)
onMounted(async () => {
await getSession();
});
</script>
<script>
export default {
name: "UserProfile",
};
</script>
</script>
<style scoped>
.userProfile {
display: flex;
@ -52,11 +270,19 @@ export default {
background-color: #fff;
}
.input {
border: none;
}
.heading {
letter-spacing: 5%;
font: 400 1rem/2rem Overpass, sans-serif;
}
.div#address.data-field {
padding-left: 3rem;
}
.heading-darkmode {
color: #fff;
}
@ -65,6 +291,18 @@ export default {
color: #000;
}
.fullname-registered-lastLogin,
.info {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
line-height: normal;
width: 50%;
padding: 0 1rem;
border-radius: 0.3125rem;
}
.userData {
display: flex;
flex-direction: row;
@ -74,6 +312,26 @@ export default {
gap: 3.125rem
}
.city-phonenumber {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
align-self: stretch;
padding: 0 1.875rem 0 0;
gap: 0.625rem;
}
.postcode-address {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
align-self: stretch;
padding: 0 1.875rem 0 0;
gap: 0.625rem;
}
.rectangle-container {
display: flex;
}
@ -100,7 +358,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

@ -1,213 +0,0 @@
<template>
<div :class="['data', darkMode ? 'div-darkmode' : 'div-lightmode']">
<div :class="['label', darkMode ? 'label-darkmode' : 'label-lightmode']">Rights:</div>
<table class="data-table" id="user-rights-list">
<tr :class="['table-row', darkMode ? 'tr-head-darkmode' : 'tr-head-lightmode']" id="table-head">
<th
:class="['User', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'User-darkmode' : 'User-lightmode']">
User</th>
<th
:class="['Admin', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Admin-darkmode' : 'Admin-lightmode']">
Admin</th>
<th
:class="['Edit-Delete', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Edit-Delete-darkmode' : 'Edit-Delete-lightmode']">
Edit/Delete</th>
<th
:class="['Create', darkMode ? 'th-darkmode' : 'th-lightmode', darkMode ? 'Create-darkmode' : 'Create-lightmode']">
Create</th>
<th :class="['View', darkMode ? 'th-darkmode' : 'th-lightmode']">View</th>
</tr>
<tr :class="['table-row', darkMode ? 'tr-darkmode' : 'tr-lightmode']" id="row-1">
<td
:class="['User', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'User-darkmode' : 'User-lightmode']">
...</td>
<td
:class="['Admin', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Admin-darkmode' : 'Admin-lightmode']">
<input type="checkbox" :class="[darkMode ? 'checkbox-darkmode' : 'checkbox-lightmode']" />
</td>
<td
:class="['Edit-Delete', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Edit-Delete-darkmode' : 'Edit-Delete-lightmode']">
<input type="checkbox" :class="[darkMode ? 'checkbox-darkmode' : 'checkbox-lightmode']" />
</td>
<td
:class="['Create', darkMode ? 'td-darkmode' : 'td-lightmode', darkMode ? 'Create-darkmode' : 'Create-lightmode']">
<input type="checkbox" :class="[darkMode ? 'checkbox-darkmode' : 'checkbox-lightmode']" />
</td>
<td :class="['View', darkMode ? 'td-darkmode' : 'td-lightmode']"><input type="checkbox"
:class="[darkMode ? 'checkbox-darkmode' : 'checkbox-lightmode']" /></td>
</tr>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue';
const darkMode = ref(true)
</script>
<script>
export default {
name: "UserRightsList",
};
</script>
<style scoped>
.data {
display: flex;
flex-direction: column;
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);
}
.div-darkmode {
background-color: #2c2c2c;
}
.div-lightmode {
background-color: #fff;
}
.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;
}
.checkbox-darkmode {
filter: invert(100%);
}
.checkbox-lightmode {
filter: invert(0%);
}
.User {
width: 50%;
}
.User-darkmode {
border-right: 0.0625rem solid #000000;
}
.User-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Admin {
width: 12.5%;
}
.Admin-darkmode {
border-right: 0.0625rem solid #000000;
}
.Admin-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Edit-Delete {
width: 12.5%;
}
.Edit-Delete-darkmode {
border-right: 0.0625rem solid #000000;
}
.Edit-Delete-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.Create {
width: 12.5%;
}
.Create-darkmode {
border-right: 0.0625rem solid #000000;
}
.Create-lightmode {
border-right: 0.0625rem solid #8e8e8e;
}
.View {
width: 12.5%;
}
.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;
}
</style>

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;
}

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