FIRST PROTO
This commit is contained in:
parent
7c2d0ae96c
commit
141fc8dd51
18 changed files with 366 additions and 208 deletions
2
main.js
2
main.js
|
|
@ -30,7 +30,7 @@ if (process.platform === 'win32') {
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
async function handleFileOpen() {
|
async function handleFileOpen() {
|
||||||
const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, {properties: ['openDirectory']})
|
const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, {properties: ['openDirectory']})
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
"start": "cross-env NODE_ENV=development webpack serve --hot --host 0.0.0.0 --config=./webpack.dev.config.js --mode development",
|
"start": "cross-env NODE_ENV=development webpack serve --hot --host 0.0.0.0 --config=./webpack.dev.config.js --mode development",
|
||||||
"build": "cross-env NODE_ENV=production webpack --config webpack.build.config.js --mode production",
|
"build": "cross-env NODE_ENV=production webpack --config webpack.build.config.js --mode production",
|
||||||
"package": "npm run build",
|
"package": "npm run build",
|
||||||
"postpackage": "electron-packager ./ --out=./builds"
|
"postpackage": "electron-packager ./ --out=./builds --overwrite"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.10.0",
|
"@emotion/react": "^11.10.0",
|
||||||
|
|
@ -49,7 +49,9 @@
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-async-devtools": "^10.0.1",
|
"react-async-devtools": "^10.0.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-loader-spinner": "^5.3.3",
|
||||||
"react-router-dom": "^6.3.0",
|
"react-router-dom": "^6.3.0",
|
||||||
|
"replace-special-characters": "^1.2.6",
|
||||||
"write-json-file": "^5.0.0",
|
"write-json-file": "^5.0.0",
|
||||||
"xml-parse-from-string": "^1.0.1",
|
"xml-parse-from-string": "^1.0.1",
|
||||||
"xml2js": "^0.4.23"
|
"xml2js": "^0.4.23"
|
||||||
|
|
@ -58,6 +60,7 @@
|
||||||
"@babel/core": "^7.18.10",
|
"@babel/core": "^7.18.10",
|
||||||
"@babel/preset-env": "^7.18.10",
|
"@babel/preset-env": "^7.18.10",
|
||||||
"@babel/preset-react": "^7.18.6",
|
"@babel/preset-react": "^7.18.6",
|
||||||
|
"@electron-forge/plugin-webpack": "^6.0.0-beta.65",
|
||||||
"babel-loader": "^8.2.5",
|
"babel-loader": "^8.2.5",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "^6.7.1",
|
"css-loader": "^6.7.1",
|
||||||
|
|
|
||||||
3
resources/config/config.json
Normal file
3
resources/config/config.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"rootDir": "/home/rbrt/Schreibtisch/marvin"
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
// Config
|
// Config
|
||||||
import config from './config/config.json'
|
import config from '/resources/config/config.json'
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
import createReport from 'docx-templates';
|
import createReport from 'docx-templates';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { mkdir } from 'node:fs/promises';
|
import { mkdir } from 'node:fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import replaceSpecialCharacters from "replace-special-characters";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import ObjektkatalogApi from './ObjektkatalogApi';
|
import ObjektkatalogApi from './ObjektkatalogApi';
|
||||||
|
|
@ -20,7 +21,7 @@ export async function fillTemplate(log, objectData) {
|
||||||
if (objectData.httpStatus === 200) {
|
if (objectData.httpStatus === 200) {
|
||||||
try {
|
try {
|
||||||
// Read template.
|
// Read template.
|
||||||
const template = fs.readFileSync('src/assets/templates/rp-template.docx');
|
const template = fs.readFileSync('resources/templates/rp-template.docx');
|
||||||
// Create report.
|
// Create report.
|
||||||
buffer = await createReport({
|
buffer = await createReport({
|
||||||
template,
|
template,
|
||||||
|
|
@ -57,8 +58,10 @@ export async function fillTemplate(log, objectData) {
|
||||||
// Write document to disk.
|
// Write document to disk.
|
||||||
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
console.log(objectData)
|
const normCharacterTitle = replaceSpecialCharacters(objectData.titel)
|
||||||
fs.writeFileSync(path.join(folderPath, objectData.titel), buffer)
|
const normSpacingTitle = normCharacterTitle.replace(/[^A-Z0-9]+/ig, "_");
|
||||||
|
const filename = objectData.datum + '_' + normSpacingTitle + '.docx'
|
||||||
|
fs.writeFileSync(path.join(folderPath, filename), buffer)
|
||||||
log = {
|
log = {
|
||||||
...log,
|
...log,
|
||||||
status: 'green',
|
status: 'green',
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,21 @@ const {parseString} = require("xml2js");
|
||||||
*/
|
*/
|
||||||
class ObjektkatalogApi {
|
class ObjektkatalogApi {
|
||||||
json;
|
json;
|
||||||
short;
|
|
||||||
raw;
|
raw;
|
||||||
|
receivedData = {
|
||||||
|
datum: '',
|
||||||
|
hersteller: '',
|
||||||
|
herstellungsdatum: '',
|
||||||
|
herstellungsort: '',
|
||||||
|
httpStatus: 500,
|
||||||
|
inventarnummer: '',
|
||||||
|
masse: '',
|
||||||
|
materialTechnik: '',
|
||||||
|
titel: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
visibility;
|
||||||
|
|
||||||
async getData(objectId) {
|
async getData(objectId) {
|
||||||
if (objectId) {
|
if (objectId) {
|
||||||
const response = await fetch('https://objektkatalog.gnm.de/rest_export/' + objectId);
|
const response = await fetch('https://objektkatalog.gnm.de/rest_export/' + objectId);
|
||||||
|
|
@ -41,14 +54,37 @@ class ObjektkatalogApi {
|
||||||
zustandsbeschreibung: responseJson[0]['f54b6da6006ea444c33a348b8c4370a8']
|
zustandsbeschreibung: responseJson[0]['f54b6da6006ea444c33a348b8c4370a8']
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {httpStatus: 404};
|
// No JSON
|
||||||
|
this.receivedData = {
|
||||||
|
...this.receivedData,
|
||||||
|
httpStatus: 404,
|
||||||
|
}
|
||||||
|
this.visibility = false
|
||||||
|
return [this.receivedData, this.visibility]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {httpStatus: response.status};
|
// No response
|
||||||
|
this.receivedData= {
|
||||||
|
...this.receivedData,
|
||||||
|
httpStatus: 404,
|
||||||
|
}
|
||||||
|
this.visibility = false
|
||||||
|
return [this.receivedData, this.visibility]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {httpStatus: 400}
|
// No ObjectId
|
||||||
|
this.receivedData = {
|
||||||
|
...this.receivedData,
|
||||||
|
httpStatus: 500,
|
||||||
}
|
}
|
||||||
|
this.visibility = false
|
||||||
|
return [this.receivedData, this.visibility]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Datum
|
||||||
|
// Default date of today
|
||||||
|
let today = new Date()
|
||||||
|
let todayFormat = today.getFullYear() + '-' + (String(today.getMonth() + 1).padStart(2, '0')) + '-' + String(today.getDate()).padStart(2, '0'); ;
|
||||||
|
|
||||||
// Inventarnummer
|
// Inventarnummer
|
||||||
let inventarnummer;
|
let inventarnummer;
|
||||||
|
|
@ -113,19 +149,22 @@ class ObjektkatalogApi {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.short = {
|
this.receivedData ={
|
||||||
inventarnummer: inventarnummer,
|
...this.receivedData,
|
||||||
|
datum: todayFormat,
|
||||||
titel: titel,
|
titel: titel,
|
||||||
hersteller: hersteller,
|
hersteller: hersteller,
|
||||||
herstellungsort: herstellungsort,
|
herstellungsort: herstellungsort,
|
||||||
herstellungsdatum: herstellungsdatum,
|
herstellungsdatum: herstellungsdatum,
|
||||||
|
inventarnummer: inventarnummer,
|
||||||
materialTechnik: materialTechnik,
|
materialTechnik: materialTechnik,
|
||||||
masse: masse,
|
masse: masse,
|
||||||
httpStatus: 200,
|
httpStatus: 200,
|
||||||
}
|
}
|
||||||
|
this.visibility = true
|
||||||
|
return [this.receivedData, this.visibility]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = ObjektkatalogApi;
|
module.exports = ObjektkatalogApi;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import GnmObject from "../ObjektkatalogApi";
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@import url('https://fonts.googleapis.com/css?family=Roboto');
|
@import url('https://fonts.googleapis.com/css?family=Open+Sans');
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #d5d5d5;
|
color: #d5d5d5;
|
||||||
|
|
@ -9,10 +9,10 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #00152E ;
|
background-color: white ;
|
||||||
color: #d5d5d5;
|
color: #d5d5d5;
|
||||||
font-family: 'Roboto', regular, serif;
|
font-family: 'Open Sans', sans-serif;
|
||||||
font-size: larger;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -26,7 +26,8 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.closed{
|
.closed{
|
||||||
height: 0;
|
height: 0px;
|
||||||
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,13 +48,13 @@ div {
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-button {
|
.edit-button {
|
||||||
background-color: #d5d5d5;
|
background-color: #e30f27;
|
||||||
font-family: roboto, sans-serif;
|
color: #d5d5d5;
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
border-radius: 0 0.4rem 0.4rem 0;
|
|
||||||
border: unset;
|
border: unset;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
height: 1.1rem;
|
height: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-input {
|
.edit-input {
|
||||||
|
|
@ -64,6 +65,12 @@ div {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-full {
|
.flex-full {
|
||||||
flex: 1
|
flex: 1
|
||||||
}
|
}
|
||||||
|
|
@ -88,21 +95,23 @@ input {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-bottom: 2px solid darkred;
|
border-bottom: 2px solid #e30f27;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="date"]::-webkit-calendar-picker-indicator {
|
input[type="date"]::-webkit-calendar-picker-indicator {
|
||||||
color: #d5d5d5;
|
color: black;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-width: thin;
|
border-width: thin;
|
||||||
filter: invert(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
input:focus {
|
input:focus {
|
||||||
background-color: #d5d5d5;
|
background-color: #d5d5d5;
|
||||||
color: #00152E;
|
color: #00152E;
|
||||||
|
font-size: .9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.edit-input:not(:disabled) {
|
input.edit-input:not(:disabled) {
|
||||||
|
|
@ -112,9 +121,9 @@ input.edit-input:not(:disabled) {
|
||||||
|
|
||||||
|
|
||||||
.input-field {
|
.input-field {
|
||||||
background-color: #00152E ;
|
background-color: #f2f2f2 ;
|
||||||
color: #d5d5d5;
|
color: black;
|
||||||
font-size: medium;
|
font-size: .9rem;
|
||||||
font-family: roboto, sans-serif;
|
font-family: roboto, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,19 +139,34 @@ input.edit-input:not(:disabled) {
|
||||||
|
|
||||||
label {
|
label {
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
|
color: #464646;
|
||||||
|
}
|
||||||
|
.loading-icon-canvas {
|
||||||
|
position: absolute;
|
||||||
|
height: 98%;
|
||||||
|
width: 98%;
|
||||||
|
left: 0%;
|
||||||
|
top: 0%;
|
||||||
|
background-color: #555555;
|
||||||
|
opacity: .5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-icon
|
||||||
.log {
|
.log {
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
height: 5em;
|
height: 5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-icon svg {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
.no-overflow {
|
.no-overflow {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: inherit;
|
height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.open {
|
.open {
|
||||||
height: 700px;
|
height: 500px;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
@ -157,7 +181,8 @@ p {
|
||||||
}
|
}
|
||||||
|
|
||||||
.red {
|
.red {
|
||||||
background-color: crimson;
|
background-color: #e30f27;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-box {
|
.round-box {
|
||||||
|
|
@ -172,12 +197,12 @@ select {
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-button {
|
.send-button {
|
||||||
font-family: roboto, sans-serif;
|
background-color: #e30f27;
|
||||||
|
color: white;
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
border-radius: 0.4rem;
|
|
||||||
border: unset;
|
border: unset;
|
||||||
background-color: darkred;
|
|
||||||
color: #d5d5d5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll-y {
|
.scroll-y {
|
||||||
|
|
@ -191,6 +216,18 @@ select {
|
||||||
font-size: .85rem;
|
font-size: .85rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-div {
|
||||||
|
background-color: #d5d5d5;
|
||||||
|
color: black;
|
||||||
|
width: 300px;
|
||||||
|
border-top: none;
|
||||||
|
border-right: none;
|
||||||
|
border-left: none;
|
||||||
|
border-bottom: 0.125rem solid #e30019;
|
||||||
|
border-radius: 0.1875rem;
|
||||||
|
overflow-x: scroll;
|
||||||
|
white-space:nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.sticky-edit {
|
.sticky-edit {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -198,7 +235,7 @@ select {
|
||||||
}
|
}
|
||||||
textarea, textarea:focus, input:focus{
|
textarea, textarea:focus, input:focus{
|
||||||
outline: none;
|
outline: none;
|
||||||
font-size: medium;
|
font-size: .9rem;
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,6 +252,32 @@ textarea.select-folder-field, textarea.select-folder-field:focus, input.select-f
|
||||||
margin-bottom: 0.25em;
|
margin-bottom: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* width */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle */
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #888;
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle on hover */
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.yellow{
|
.yellow{
|
||||||
background-color: goldenrod;
|
background-color: goldenrod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,16 @@ import {DataForm} from "./DataForm";
|
||||||
import {Log} from "./Log"
|
import {Log} from "./Log"
|
||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
|
|
||||||
|
// Modules
|
||||||
|
import ObjektkatalogApi from "../ObjektkatalogApi";
|
||||||
|
|
||||||
// React
|
// React
|
||||||
import { Link } from "react-router-dom";
|
import {NavLink} from "react-router-dom";
|
||||||
import React, {useState} from 'react'
|
import React, {useState} from 'react'
|
||||||
|
|
||||||
// CSS
|
// CSS
|
||||||
import '../assets/css/styles.css'
|
import '../assets/css/styles.css'
|
||||||
import ObjektkatalogApi from "../ObjektkatalogApi";
|
import {LoadingIcon} from "./LoadingIcon";
|
||||||
|
|
||||||
|
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
@ -18,19 +21,19 @@ import ObjektkatalogApi from "../ObjektkatalogApi";
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
const objektkatalogApi = new ObjektkatalogApi();
|
||||||
|
|
||||||
// States
|
// States
|
||||||
|
|
||||||
/* Initialize state of the log.
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
* log: variables fpr logging message.
|
|
||||||
* logClass: for visibility of log <div>.
|
|
||||||
*/
|
|
||||||
const [logState, setLogState] = useState({
|
const [logState, setLogState] = useState({
|
||||||
log: {
|
log: {
|
||||||
status: '',
|
status: '',
|
||||||
message: '',
|
message: '',
|
||||||
code: '',
|
code: '',
|
||||||
tip:'',
|
tip: '',
|
||||||
}, // with message, code, tip
|
}, // with message, code, tip
|
||||||
logClass: 'inactive'
|
logClass: 'inactive'
|
||||||
});
|
});
|
||||||
|
|
@ -38,14 +41,14 @@ export const App = () => {
|
||||||
const [objectData, setObjectData] = useState(
|
const [objectData, setObjectData] = useState(
|
||||||
{
|
{
|
||||||
datum: '',
|
datum: '',
|
||||||
inventarnummer: '',
|
|
||||||
titel: '',
|
|
||||||
hersteller: '',
|
hersteller: '',
|
||||||
herstellungsort: '',
|
|
||||||
herstellungsdatum: '',
|
herstellungsdatum: '',
|
||||||
materialTechnik: '',
|
herstellungsort: '',
|
||||||
masse: '',
|
|
||||||
httpStatus: 500,
|
httpStatus: 500,
|
||||||
|
inventarnummer: '',
|
||||||
|
masse: '',
|
||||||
|
materialTechnik: '',
|
||||||
|
titel: '',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -54,52 +57,70 @@ export const App = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Handler
|
// Handler
|
||||||
async function getDataAndAskForCheckUpClickHandler(e) {
|
const getDataAndAskForCheckUpClickHandler = async (e) => {
|
||||||
|
setIsLoading(true)
|
||||||
// Prevent page reload.
|
// Prevent page reload.
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
|
let objectId = ''
|
||||||
|
objectId = e.target.form.objectId.value
|
||||||
// Get objectId from user input.
|
// Get objectId from user input.
|
||||||
let objectId = document.getElementById('object-id').value
|
|
||||||
|
await setObjectData((prevState) => {
|
||||||
|
return {
|
||||||
|
...prevState,
|
||||||
|
inventarnummer: objectId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (objectId) {
|
if (objectId) {
|
||||||
|
|
||||||
// Get object data from objektkatalog.gnm.de
|
// Get object data from objektkatalog.gnm.de
|
||||||
let objektkatalogApi = new ObjektkatalogApi();
|
const [receivedObjectData, receivedVisibility] = await objektkatalogApi.getData(objectId);
|
||||||
let receivedObjectData = await objektkatalogApi.getData(objectId);
|
if (receivedObjectData.httpStatus !== 200) {
|
||||||
if (receivedObjectData.httpStatus === 404) {
|
await setLogState({
|
||||||
setLogState({
|
|
||||||
log: {
|
log: {
|
||||||
status: 'red',
|
status: 'red',
|
||||||
message: 'Kein Objekt mit dieser Inventarnummer gefunden!',
|
message: 'Kein Objekt mit dieser Inventarnummer gefunden!',
|
||||||
code: '',
|
code: '',
|
||||||
tip:'',
|
tip: '',
|
||||||
}, // with message, code, tip
|
}, // with message, code, tip
|
||||||
logClass: 'active'
|
logClass: 'active'
|
||||||
})
|
})
|
||||||
|
await setCheckUpVisibility(false)
|
||||||
} else {
|
} else {
|
||||||
console.log(receivedObjectData)
|
|
||||||
// Fill and open check up form
|
// Fill and open check up form
|
||||||
setObjectData(receivedObjectData)
|
await setObjectData(receivedObjectData)
|
||||||
setCheckUpVisibility(true)
|
await setCheckUpVisibility(true)
|
||||||
|
await setLogState({
|
||||||
|
log: {
|
||||||
|
status: '',
|
||||||
|
message: '',
|
||||||
|
code: '',
|
||||||
|
tip: '',
|
||||||
|
}, // with message, code, tip
|
||||||
|
logClass: 'inactive'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setLogState({
|
await setLogState({
|
||||||
log: {
|
log: {
|
||||||
status: 'red',
|
status: 'red',
|
||||||
message: 'Bitte Inventarnummer eingeben!',
|
message: 'Bitte Inventarnummer eingeben!',
|
||||||
code: '',
|
code: '',
|
||||||
tip:'',
|
tip: '',
|
||||||
}, // with message, code, tip
|
}, // with message, code, tip
|
||||||
logClass: 'active'
|
logClass: 'active'
|
||||||
})
|
})
|
||||||
|
await setCheckUpVisibility(false)
|
||||||
}
|
}
|
||||||
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header className="App-header">
|
<header className="App-header">
|
||||||
<nav className={"flex justify-content-end"}>
|
<nav className={"flex justify-content-end"}>
|
||||||
<Link to="/settings"><SettingsIcon/></Link>
|
<NavLink className={'nav-icon'} to="/settings"><SettingsIcon/></NavLink>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
|
@ -115,7 +136,12 @@ export const App = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className={"center column flex full justify-content-space-between"}>
|
<div className={"center column flex full justify-content-space-between"}>
|
||||||
<label htmlFor={"object-id"} className={"center cut v-distance"}>Inventarnummer:</label>
|
<label htmlFor={"object-id"} className={"center cut v-distance"}>Inventarnummer:</label>
|
||||||
<input id={"object-id"} type={"text"} className={"center cut input-field"}/>
|
<input
|
||||||
|
id={"object-id"}
|
||||||
|
name="objectId"
|
||||||
|
type={"text"}
|
||||||
|
className={"center cut input-field"}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button className={'send-button center top-distance'} onClick={getDataAndAskForCheckUpClickHandler}>
|
<button className={'send-button center top-distance'} onClick={getDataAndAskForCheckUpClickHandler}>
|
||||||
|
|
@ -124,8 +150,9 @@ export const App = () => {
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<LoadingIcon isLoading={isLoading}/>
|
||||||
<DataForm
|
<DataForm
|
||||||
className={checkUpVisibility ? 'open' : 'closed'}
|
checkUpVisibility={checkUpVisibility}
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
setObjectData={setObjectData}
|
setObjectData={setObjectData}
|
||||||
logState={logState}
|
logState={logState}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,11 @@ import React from 'react'
|
||||||
// Main //
|
// Main //
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
export const DataForm = ({className, objectData, setObjectData, logState, setLogState}) => {
|
export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState, setLogState}) => {
|
||||||
let log;
|
let log;
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
|
|
||||||
const datumChangeHandler = (e) => {
|
const datumChangeHandler = (e) => {
|
||||||
console.log(e.target.form.datum.value)
|
|
||||||
setObjectData((prevState) => {
|
setObjectData((prevState) => {
|
||||||
return {
|
return {
|
||||||
...prevState,
|
...prevState,
|
||||||
|
|
@ -88,7 +86,6 @@ export const DataForm = ({className, objectData, setObjectData, logState, setLog
|
||||||
|
|
||||||
const fillTemplateClickHandler = async (e) => {
|
const fillTemplateClickHandler = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
console.log(objectData, 'parentobjectData')
|
|
||||||
log = await fillTemplate(logState, objectData);
|
log = await fillTemplate(logState, objectData);
|
||||||
// Set new state of log div with message and visibility class
|
// Set new state of log div with message and visibility class
|
||||||
setLogState({
|
setLogState({
|
||||||
|
|
@ -97,12 +94,8 @@ export const DataForm = ({className, objectData, setObjectData, logState, setLog
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default date of today
|
return (<div className={'checkup ' + (checkUpVisibility ? 'open' : 'closed')}>
|
||||||
let today = new Date()
|
<form className={'flex column '}>
|
||||||
let todayFormat = today.getFullYear() + '-' + (String(today.getMonth() + 1).padStart(2, '0')) + '-' + String(today.getDate()).padStart(2, '0'); ;
|
|
||||||
|
|
||||||
return (<div className={'checkup ' + className}>
|
|
||||||
<form className={'flex column no-overflow'}>
|
|
||||||
<div >
|
<div >
|
||||||
<label htmlFor={'template-datum'} >Datum</label>
|
<label htmlFor={'template-datum'} >Datum</label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -110,11 +103,11 @@ export const DataForm = ({className, objectData, setObjectData, logState, setLog
|
||||||
name={"datum"}
|
name={"datum"}
|
||||||
type={"date"}
|
type={"date"}
|
||||||
className={"full input-field"}
|
className={"full input-field"}
|
||||||
defaultValue={todayFormat}
|
defaultValue={objectData.datum}
|
||||||
onChange={datumChangeHandler}
|
onChange={datumChangeHandler}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div >
|
<div>
|
||||||
<label htmlFor={'template-inventarnummer'} >Inventarnummer</label>
|
<label htmlFor={'template-inventarnummer'} >Inventarnummer</label>
|
||||||
<input
|
<input
|
||||||
id={"template-inventarnummer"}
|
id={"template-inventarnummer"}
|
||||||
|
|
|
||||||
6
src/components/Input.js
Normal file
6
src/components/Input.js
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const Input = ({config}) => {
|
||||||
|
return (
|
||||||
|
<span className={'settings-div '}> {config.rootDir} </span>)
|
||||||
|
}
|
||||||
22
src/components/LoadingIcon.js
Normal file
22
src/components/LoadingIcon.js
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import {ThreeDots} from "react-loader-spinner";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const LoadingIcon = ({isLoading}) => {
|
||||||
|
const classes = "loading-icon-canvas flex-center " + (isLoading ? 'active' : 'inactive')
|
||||||
|
return (
|
||||||
|
<div className={classes}>
|
||||||
|
<div className={"loading-icon"}>
|
||||||
|
<ThreeDots
|
||||||
|
height="100"
|
||||||
|
width="100"
|
||||||
|
radius="9"
|
||||||
|
color="#e30019"
|
||||||
|
ariaLabel="three-dots-loading"
|
||||||
|
wrapperStyle={{}}
|
||||||
|
wrapperClassName=""
|
||||||
|
visible={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ export const Log = ({logState, setLogState}) => {
|
||||||
let code;
|
let code;
|
||||||
let tip;
|
let tip;
|
||||||
|
|
||||||
const closeLog = (e, logClass) => {
|
const closeLog = (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setLogState({log: logState.log,
|
setLogState({log: logState.log,
|
||||||
logClass: 'inactive'});
|
logClass: 'inactive'});
|
||||||
|
|
@ -30,7 +30,7 @@ export const Log = ({logState, setLogState}) => {
|
||||||
<div className={'log '}>
|
<div className={'log '}>
|
||||||
<div id={'log-content'} className={classes}>
|
<div id={'log-content'} className={classes}>
|
||||||
<div>
|
<div>
|
||||||
<button onClick={(e) => {closeLog(e)}}>x</button>
|
<button onClick={closeLog}>x</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={'scroll-y flex-full'} style={{maxHeight: 4 + 'em'}}>
|
<div className={'scroll-y flex-full'} style={{maxHeight: 4 + 'em'}}>
|
||||||
<p>{logState.log.message}</p>
|
<p>{logState.log.message}</p>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"rootDir": "/home/rbrt/Dokumente/marvin"
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
import config from '../config/config.json'
|
// Config
|
||||||
|
import configImport from '/resources/config/config.json'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import {Log} from "../components/Log";
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
|
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
|
||||||
import EditIcon from '@mui/icons-material/Edit';
|
|
||||||
|
|
||||||
// Modules
|
|
||||||
const {writeFile} = require('fs');
|
|
||||||
|
|
||||||
// React
|
// React
|
||||||
import React, {useState} from "react";
|
import React, {useState} from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {NavLink} from "react-router-dom";
|
||||||
|
import {Input} from "../components/Input";
|
||||||
|
import EditIcon from "@mui/icons-material/Edit";
|
||||||
|
import {writeFile} from "fs";
|
||||||
|
|
||||||
|
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
@ -17,54 +20,62 @@ import {Link} from "react-router-dom";
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
let rootDir;
|
// States
|
||||||
const [disableButton, setDisableButton] = useState(true)
|
const [config, setConfig] = useState(
|
||||||
|
configImport
|
||||||
|
)
|
||||||
|
|
||||||
async function selectFolderHandler() {
|
const [restart, setRestart] = useState(
|
||||||
return rootDir = await window.openFile();
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
//Functions
|
||||||
|
async function selectFolderHandler(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
const rootDirFromWindow = await window.openFile();
|
||||||
|
setConfig((prevState) => {
|
||||||
|
return {
|
||||||
|
...prevState,
|
||||||
|
rootDir: rootDirFromWindow
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const saveResult = await saveInputClickHandler(rootDirFromWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Handler
|
// Handler
|
||||||
function saveInputClickHandler(rootDir) {
|
async function saveInputClickHandler(rootDirFromWindow) {
|
||||||
if (rootDir) {
|
let config2Safe = {
|
||||||
config.rootDir = rootDir
|
rootDir: rootDirFromWindow
|
||||||
writeFile('src/config/config.json', JSON.stringify(config, null, 2), (error) => {
|
|
||||||
if (error) {
|
|
||||||
console.log('An error has occurred ', error);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
console.log('Data written successfully to disk');
|
if (rootDirFromWindow) {
|
||||||
});
|
let message;
|
||||||
|
await writeFile('resources/config/config.json', JSON.stringify(config2Safe, null, 2), (err) => {
|
||||||
|
if (err) {
|
||||||
|
message = err;
|
||||||
|
} else {
|
||||||
|
message = 'saved file'
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
})
|
||||||
|
setRestart(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header className="App-header">
|
<header className="App-header">
|
||||||
<Link to="/"><ArrowBackIosIcon/></Link>
|
<NavLink className={'nav-icon'} to="/"><ArrowBackIosIcon/></NavLink>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<form>
|
<div className={'full red v-distance'}>Die App muss nach Veränderungen neu gestartet werden!</div>
|
||||||
|
<form onSubmit={selectFolderHandler}>
|
||||||
<label htmlFor={"output-root"}>
|
<label htmlFor={"output-root"}>
|
||||||
Wurzelverzeichnis
|
Wurzelverzeichnis
|
||||||
</label>
|
</label>
|
||||||
<div className="col-sm-10 d-flex align-items-center flex sticky-edit">
|
<div className="col-sm-10 d-flex align-items-center flex sticky-edit">
|
||||||
<input
|
<Input config={config} setConfig={setConfig}/>
|
||||||
id={"root-dir"}
|
<button type="submit" className="edit-button text-end">
|
||||||
className={"form-control select-folder-field edit-input"}
|
|
||||||
defaultValue={config.rootDir}
|
|
||||||
disabled={true}
|
|
||||||
/>
|
|
||||||
<button className="edit-button text-end" onClick={
|
|
||||||
(e) => {
|
|
||||||
console.log(e)
|
|
||||||
e.preventDefault()
|
|
||||||
selectFolderHandler().then((rootDir) => {saveInputClickHandler(rootDir)})
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
<i className="fas fa-edit d-block">
|
<i className="fas fa-edit d-block">
|
||||||
<EditIcon sx={{fontSize: 16}} color={'#d5d5d5'}/>
|
<EditIcon sx={{fontSize: 16}} color={'#d5d5d5'}/>
|
||||||
</i>
|
</i>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
channels: {
|
|
||||||
GET_DATA: 'get_data',
|
|
||||||
},
|
|
||||||
log: {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -20,24 +20,27 @@ module.exports = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.jsx?$/,
|
test: /\.jsx?$/,
|
||||||
use: [{ loader: 'babel-loader' }],
|
use: [{loader: 'babel-loader'}],
|
||||||
include: defaultInclude
|
include: defaultInclude
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(jpe?g|png|gif)$/,
|
test: /\.(jpe?g|png|gif)$/,
|
||||||
use: [{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }],
|
use: [{loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]'}],
|
||||||
include: defaultInclude
|
include: defaultInclude
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(eot|svg|ttf|woff|woff2)$/,
|
test: /\.(eot|svg|ttf|woff|woff2)$/,
|
||||||
use: [{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }],
|
use: [{loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]'}],
|
||||||
include: defaultInclude
|
include: defaultInclude
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
target: 'electron-renderer',
|
target: 'electron-renderer',
|
||||||
plugins: [
|
plugins: [
|
||||||
new HtmlWebpackPlugin({title: 'Marvin'}),
|
new HtmlWebpackPlugin({
|
||||||
|
title: 'Marvin',
|
||||||
|
template: 'src/index.html'
|
||||||
|
}),
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
// Options similar to the same options in webpackOptions.output
|
// Options similar to the same options in webpackOptions.output
|
||||||
// both options are optional
|
// both options are optional
|
||||||
|
|
@ -49,12 +52,14 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
// new MinifyPlugin()
|
// new MinifyPlugin()
|
||||||
],
|
],
|
||||||
|
/*
|
||||||
stats: {
|
stats: {
|
||||||
colors: true,
|
colors: true,
|
||||||
children: false,
|
children: false,
|
||||||
chunks: false,
|
chunks: false,
|
||||||
modules: false
|
modules: false
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: true
|
minimize: true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue