Current state
This commit is contained in:
parent
6344134a9e
commit
1f2eb78333
@ -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
|
||||
}
|
||||
|
@ -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:
|
||||
|
27
src/frontend/manage/startpage.eta.html
Normal file
27
src/frontend/manage/startpage.eta.html
Normal 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") %>
|
@ -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>
|
||||
|
@ -2,3 +2,4 @@
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/searchBox.js"></script>
|
||||
<script src="/js/handleSidebarTriangles.js"></script>
|
@ -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';
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
};
|
@ -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)
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
7
src/routes/frontend/manage/startpage.ts
Normal file
7
src/routes/frontend/manage/startpage.ts
Normal 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 });
|
||||
|
||||
};
|
@ -99,3 +99,9 @@ body {
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.rotate {
|
||||
transform: rotate(90deg);
|
||||
color: red;
|
||||
transition: 1s;
|
||||
}
|
||||
|
17
static/js/handleSidebarTriangles.js
Normal file
17
static/js/handleSidebarTriangles.js
Normal 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))
|
||||
});
|
Loading…
Reference in New Issue
Block a user