Current state

This commit is contained in:
Leon Meier 2023-05-15 00:21:53 +02:00
parent 6344134a9e
commit 1f2eb78333
14 changed files with 124 additions and 72 deletions

View File

@ -25,7 +25,7 @@ generator dbml {
projectName = "AssetFlow"
}
enum Status {
enum itemStatus {
normal
borrowed
stolen
@ -37,12 +37,12 @@ model Item {
SKU String? @unique
amount Int @default(1)
name String
Comment String?
status Status @default(normal) /// TODO: Would it be better to create a separate model for this as well instead of providing several static statuses to choose from(enum)?
comment String?
status itemStatus @default(normal) /// TODO: Would it be better to create a separate model for this as well instead of providing several static statuses to choose from(enum)?
manufacturer String /// TODO: Do we need this as a mandatory field? Probably we can add another model for manufacturer.
manufacturer String
category Category @relation(fields: [categoryId], references: [id])
category itemCategory @relation(fields: [categoryId], references: [id])
categoryId Int
items Item[] @relation("items") /// Item beinhaltet..
@ -68,15 +68,14 @@ model StorageLocation {
model StorageUnit {
id Int @id @default(autoincrement())
name String
street String
houseNumber String
zipCode String
city String
country String
contactInfo contactInfo? @relation(fields: [contactInfoId], references: [id])
contactInfoId Int?
StorageLocation StorageLocation[]
}
model Category {
model itemCategory {
id Int @id @default(autoincrement())
name String @unique
description String?
@ -84,20 +83,24 @@ model Category {
}
/// TODO: Add relationship to StorageUnit, Item and if necessary to StorageLocation.
model Owner {
model contactInfo {
id Int @id @default(autoincrement())
type OwnerType @default(person)
name String
type contactType @default(person)
name String?
lastName String?
street String
houseNumber String
zipCode String
city String
country String
StorageUnit StorageUnit[]
}
enum OwnerType {
enum contactType {
person
customer
company
partner
enemy
}

View File

@ -1,5 +1,5 @@
<%~ E.includeFile("../../partials/head.eta.html", {"title": "Importer - CSV" }) %>
<%~ E.includeFile("../../partials/controls.eta.html", {"active": "SETT_CSV_IMPORT" }) %>
<%~ E.includeFile("../../partials/controls.eta.html", {"active": "SETT_IMPORT_CSV" }) %>
<h1>Import A CSV File</h1>
Upload a CSV file to import into the database. The CSV file must have the following columns:

View File

@ -0,0 +1,27 @@
<%~ E.includeFile("../partials/head.eta.html", {"title": "Settings"}) %> <%~ E.includeFile("../partials/controls.eta.html", {"active": "SETT"}) %>
<h1>Manage your AssetFlow instance</h1>
<div class="container text-center">
<div class="row">
<a class="card col m-2" href="/manage/categories">
<div class="card-body">
<h1 class="card-title"><i class="bi bi-tag"></i></h1>
<p class="card-text">Manage categories</p>
</div>
</a>
<a class="card col m-2" href="/manage/storages">
<div class="card-body">
<h1 class="card-title"><i class="bi bi-box-seam"></i></h1>
<p class="card-text">Manage storages</p>
</div>
</a><a class="card col m-2" href="/manage/import/csv">
<div class="card-body">
<h1 class="card-title"><i class="bi bi-filetype-csv"></i></h1>
<p class="card-text">Import data via CSV</p>
</div>
</a>
</div>
</div>
<%~ E.includeFile("../partials/controlsFoot.eta.html") %> <%~ E.includeFile("../partials/foot.eta.html") %>

View File

@ -1,5 +1,5 @@
<header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 test-white-50" href="#">AssetFlow</a>
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 test-white-50" href="https://shattereddisk.github.io/rickroll/rickroll.mp4">AssetFlow</a>
<button
class="navbar-toggler position-absolute d-md-none collapsed"
type="button"
@ -78,7 +78,7 @@
</ul>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Settings</span>
<a href="/manage/" class="nav-link">Settings</a>
</h6>
<ul class="nav flex-column mb-2">
@ -92,7 +92,9 @@
data-bs-target="#collapseSettingsStorages"
aria-expanded="<%= it.active == 'SETT_STORE' ? 'true' : 'false'%>"
aria-controls="collapseSettingsStorages">
<i class="bi bi-caret-down-fill"></i>
<span class="dropdownIndicator" data-ref-target="#collapseSettingsStorages">
<i class="bi bi-caret-left-fill" ></i>
</span>
<!-- TODO: This little triangle does not care if it is collapsed or not. But it should so -->
</span>
</a>
@ -106,12 +108,25 @@
<a class="nav-link <%= it.active == 'SETT_CAT' ? 'active' : ''%>" href="/manage/categories"><i class="bi bi-tag"></i> Manage categories </a>
</li>
<li class="nav-item">
<a class="nav-link <%= it.active == 'SETT_CSV_IMPORT' ? 'active' : ''%>" href="/manage/import/csv"><i class="bi bi-filetype-csv"></i> CSV Import </a>
</li>
<li class="nav-item">
<a class="nav-link <%= it.active == 'SETT_JSON_IMPORT' ? 'active' : ''%>" href="/manage/import/json"> <i class="bi bi-filetype-json"></i> JSON Import</a>
</li>
<a class="nav-link">
<span
class="<%= it.active == 'SETT_IMPORT' ? 'active' : ''%>"
type="button"
onclick="return false"
data-bs-toggle="collapse"
data-bs-target="#collapseSettingsImport"
aria-expanded="<%= it.active.includes('SETT_IMPORT') ? 'true' : 'false'%>"
aria-controls="collapseSettingsImport">
<i class="bi bi-box-seam"></i> Import
<i class="bi bi-caret-left-fill dropdownIndicator" data-ref-target="#collapseSettingsImport"></i>
<!-- TODO: This little triangle does not care if it is collapsed or not. But it should so -->
</span>
</a>
<div class="collapse <%= it.active.includes('SETT_IMPORT') ? 'show' : ''%>" id="collapseSettingsImport">
<a class="nav-link ms-4 <%= it.active == 'SETT_IMPORT_CSV' ? 'active' : ''%>" href="/manage/import/csv"><i class="bi bi-filetype-csv"></i> CSV Import </a>
<a class="nav-link ms-4 <%= it.active == 'SETT_IMPORT_JSON' ? 'active' : ''%>" href="/manage/import/json"> <i class="bi bi-filetype-json"></i> JSON Import</a>
</div>
</ul>
</div>
</nav>

View File

@ -2,3 +2,4 @@
</div>
</div>
<script src="/js/searchBox.js"></script>
<script src="/js/handleSidebarTriangles.js"></script>

View File

@ -3,7 +3,6 @@ import ConfigHandler from './assets/configHandler';
import express, { Request, Response } from 'express';
import fileUpload from 'express-fileupload';
import { PrismaClient } from '@prisma/client';
import { Status, Category } from '@prisma/client';
import * as eta from 'eta';
import bodyParser from 'body-parser';

View File

@ -1,11 +1,11 @@
import express from 'express';
// Route imports
import setDemoData from './setDemoData.js';
// import setDemoData from './setDemoData.js';
// Router base is '/dev'
const Router = express.Router();
Router.use("/setDemoData", setDemoData)
// Router.use("/setDemoData", setDemoData)
export default Router;

View File

@ -1,27 +0,0 @@
import { Request, Response } from 'express';
import { prisma } from '../../index.js';
import { Status, Category } from '@prisma/client';
export default (req: Request, res: Response) => {
// fill database with demo data
/*
prisma.item
.create({
data: {
SKU: 'ee189749',
Amount: 1,
name: 'Test Item',
manufacturer: 'Test Manufacturer',
category: Category.Other,
status: Status.normal
}
})
.then(() => {
res.send('Demo data added');
})
.catch((err) => {
res.send('Error adding demo data: ' + err);
});*/
res.send('No data was added');
};

View File

@ -5,7 +5,7 @@ export default (req: Request, res: Response) => {
// If method is get, render the page
if (req.method === 'GET') {
// Render the page
prisma.category
prisma.itemCategory
.findMany({})
.then((items) => {
// Count amount of total items
@ -26,7 +26,7 @@ export default (req: Request, res: Response) => {
if(!req.body.editCategoryModalIsEdit) {
console.log('is not edit');
// Save data to category table
prisma.category.create({
prisma.itemCategory.create({
data: {
name: req.body.name,
description: req.body.description,
@ -42,7 +42,7 @@ export default (req: Request, res: Response) => {
});
} else {
// Save data to category table
prisma.category.update({
prisma.itemCategory.update({
where: {
id: parseInt(req.body.editCategoryModalId)
},

View File

@ -2,7 +2,7 @@ import express, { Request, Response } from 'express';
import { prisma, __path, log } from '../../../../index.js';
import { UploadedFile } from 'express-fileupload';
import { parse, transform } from 'csv';
import { Status, Category, PrismaPromise } from '@prisma/client';
import { itemStatus, itemCategory, PrismaPromise } from '@prisma/client';
export default (req: Request, res: Response) => {
// Decide wether its post or get
@ -25,8 +25,9 @@ export default (req: Request, res: Response) => {
records.forEach((record: any) => {
categories.add(record.category);
});
log.db.debug(categories);
// Remove categories that already exists in the database
prisma.category.findMany({
prisma.itemCategory.findMany({
where: {
name: {
in: Array.from(categories)
@ -36,10 +37,10 @@ export default (req: Request, res: Response) => {
values.forEach((value) => {
categories.delete(value.name);
});
const categoryPromises: PrismaPromise<Category>[] = [];
log.db.debug(categories);
const categoryPromises: PrismaPromise<itemCategory>[] = [];
categories.forEach((category: string) => {
const promise = prisma.category.create({
const promise = prisma.itemCategory.create({
data: {
name: category
}
@ -56,7 +57,7 @@ export default (req: Request, res: Response) => {
data: {
name: record.name,
amount: parseInt(record.amount),
Comment: record.comment,
comment: record.comment,
category: {
connect: {
name: record.category
@ -64,8 +65,8 @@ export default (req: Request, res: Response) => {
},
SKU: record.sku,
manufacturer: record.manufacturer,
status: Status.normal,
importedBy: "CSV Import"
status: itemStatus.normal,
importedBy: "CSV_IMPORT"
}
});
listOfPromises.push(promise);

View File

@ -5,13 +5,16 @@ import testRoute from './test.js';
import csvImportRoute from './import/csvImport.js';
import categoryManager from './categoryManager.js';
import storageManager from './storageManager.js';
import startpageRoute from './startpage.js';
// Router base is '/manage'
const Router = express.Router({ strict: false });
Router.use('/test', testRoute);
Router.use('/categories', categoryManager)
Router.use('/storages', storageManager)
Router.use('/import/csv', csvImportRoute);
Router.use('/', startpageRoute);
export default Router;

View File

@ -0,0 +1,7 @@
import express, { Request, Response } from 'express';
import { prisma, __path } from '../../../index.js';
export default (req: Request, res: Response) => {
res.render(__path + '/src/frontend/manage/startpage.eta.html'); //, { items: items });
};

View File

@ -99,3 +99,9 @@ body {
left: 0;
right: 0;
}
.rotate {
transform: rotate(90deg);
color: red;
transition: 1s;
}

View File

@ -0,0 +1,17 @@
const trinagles = $('.dropdownIndicator');
//const containers = $('');
trinagles.each(function () {
var target = $(this.dataset.refTarget);
target.on('show.bs.collapse', function () {
//$(this).parent.addClass('rotate');
// $(this).parent().find('.dropdownIndicator').addClass('rotate');
console.log('show');
});
target.on('hide.bs.collapse', function () {
//$(this).parent.removeClass('rotate');
// $(this).parent().find('.dropdownIndicator').removeClass('rotate');
console.log('hide');
});
// bootstrap.Collapse.getOrCreateInstance(document.querySelector(this.dataset.refTarget))
});