From ba1304d2233d134bafe955a928a718e190170ee0 Mon Sep 17 00:00:00 2001 From: JeremiasBachmann <62874265+JeremiasBachmann@users.noreply.github.com> Date: Sun, 5 Nov 2023 18:54:35 +0100 Subject: [PATCH 1/3] =?UTF-8?q?#59=20Alles=20Material=20l=C3=B6schen=20Fun?= =?UTF-8?q?ktion=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Button um alles Material der Abteilung zu löschen auf der Material Seite der eigenen Abteilung hinzugefügt. Buttons für den Excel Import und Export auf die Material Seite der eigenen Abteilung verschoben. Vorher unter Abteilung => Settings. Kleine visuelle Verbesserungen. --- .../abteilung/settings/AbteilungSettings.tsx | 64 ++----------------- src/components/material/DeleteMaterial.tsx | 41 ++++++++++++ .../settings => material}/ExcelImport.tsx | 35 ++++++++-- src/components/material/ExportMaterial.tsx | 35 ++++++++++ src/components/material/ImportAddMaterial.tsx | 42 ++++++++++++ .../abteilung/material/abteilungMaterials.tsx | 15 +++++ 6 files changed, 168 insertions(+), 64 deletions(-) create mode 100644 src/components/material/DeleteMaterial.tsx rename src/components/{abteilung/settings => material}/ExcelImport.tsx (91%) create mode 100644 src/components/material/ExportMaterial.tsx create mode 100644 src/components/material/ImportAddMaterial.tsx diff --git a/src/components/abteilung/settings/AbteilungSettings.tsx b/src/components/abteilung/settings/AbteilungSettings.tsx index 48a20a1..0f68a26 100644 --- a/src/components/abteilung/settings/AbteilungSettings.tsx +++ b/src/components/abteilung/settings/AbteilungSettings.tsx @@ -5,17 +5,13 @@ import { useNavigate } from 'react-router'; import { Abteilung } from 'types/abteilung.type'; import { useContext, useState } from 'react'; import { firestore, functions } from 'config/firebase/firebase'; -import { abteilungenCollection } from 'config/firebase/collections'; +import { abteilungenCollection, abteilungenMaterialsCollection } from 'config/firebase/collections'; import moduleStyles from '../Abteilung.module.scss' import { ability } from 'config/casl/ability'; import { slugify } from 'util/FormUtil'; import { Can } from 'config/casl/casl'; -import { DeleteOutlined, FileExcelOutlined } from '@ant-design/icons'; +import { DeleteOutlined } from '@ant-design/icons'; import { validateMessages } from 'util/FormValdationMessages'; -import { excelToJson, exportMaterialsToXlsx } from 'util/ExcelUtil'; -import { ExcelImport } from './ExcelImport'; -import { ExcelJson } from 'types/excel.type'; -import {CategorysContext, MaterialsContext, StandorteContext} from '../AbteilungDetails'; export interface AbteilungSettingsProps { abteilung: Abteilung @@ -27,25 +23,8 @@ export const AbteilungSettings = (props: AbteilungSettingsProps) => { const navigate = useNavigate(); - //fetch materials - const materialsContext = useContext(MaterialsContext); - const materials = materialsContext.materials; - const matLoading = materialsContext.loading; - - //fetch categories - const categoriesContext = useContext(CategorysContext); - const categories = categoriesContext.categories; - const catLoading = categoriesContext.loading; - - //fetch categories - const standorteContext = useContext(StandorteContext); - const standorte = standorteContext.standorte; - const standorteLoading = standorteContext.loading; - const [form] = Form.useForm(); const [updateLoading, setUpdateLoading] = useState(false); - const [excelData, setExcelData] = useState(); - const [showImportModal, setShowImportModal] = useState(false); const [slug, setSlug] = useState(abteilung.slug); @@ -225,14 +204,10 @@ export const AbteilungSettings = (props: AbteilungSettingsProps) => { - - - - - - + + delteAbteilung(abteilung)} @@ -241,38 +216,13 @@ export const AbteilungSettings = (props: AbteilungSettingsProps) => { cancelText='Nein' > - - - - - - { - const res = await excelToJson(e); - if(res) { - setExcelData(res) - setShowImportModal(true) - } else { - message.error('Leider ist ein Fehler beim lesen der Datei aufgetreten 2'); - } - }} - /> - - - } diff --git a/src/components/material/DeleteMaterial.tsx b/src/components/material/DeleteMaterial.tsx new file mode 100644 index 0000000..cfa8706 --- /dev/null +++ b/src/components/material/DeleteMaterial.tsx @@ -0,0 +1,41 @@ +import { Button, Popconfirm, message } from 'antd'; +import {Abteilung} from 'types/abteilung.type'; +import { firestore } from 'config/firebase/firebase'; +import { abteilungenCollection, abteilungenMaterialsCollection} from "config/firebase/collections"; +import { DeleteOutlined } from '@ant-design/icons'; +import { useContext, useState } from 'react'; + +export interface DeleteMaterialProps { + abteilung: Abteilung +} + +export const DeleteMaterialButton = (props: DeleteMaterialProps) => { + const { abteilung} = props; + const [updateLoading] = useState(false); + + const delteMaterial = async () => { + await firestore().collection(abteilungenCollection).doc(abteilung.id).collection(abteilungenMaterialsCollection).get().then((snapshot) => { + snapshot.docs.forEach((doc) => { + doc.ref.delete(); + }); + }).then(() => { + message.info(`Alles Material von ${abteilung.name} wurde erfolgreich gelöscht`); + }).catch((ex) => { + message.error(`Es ist ein Fehler aufgetreten: ${ex}`); + }); + } + + return <> + delteMaterial()} + onCancel={() => { }} + okText='Ja' + cancelText='Nein' + > + + + +} \ No newline at end of file diff --git a/src/components/abteilung/settings/ExcelImport.tsx b/src/components/material/ExcelImport.tsx similarity index 91% rename from src/components/abteilung/settings/ExcelImport.tsx rename to src/components/material/ExcelImport.tsx index 926f548..c84d0e7 100644 --- a/src/components/abteilung/settings/ExcelImport.tsx +++ b/src/components/material/ExcelImport.tsx @@ -1,5 +1,5 @@ -import { Button, Col, message, Modal, Row, Select, Spin } from "antd"; -import { abteilungenCategoryCollection, abteilungenCollection } from "config/firebase/collections"; +import { Button, Col, message, Modal, Row, Select, Spin, Popconfirm } from "antd"; +import { abteilungenCategoryCollection, abteilungenMaterialsCollection, abteilungenCollection } from "config/firebase/collections"; import { firestore } from "config/firebase/firebase"; import { useContext, useState } from "react"; import { Abteilung } from "types/abteilung.type"; @@ -7,7 +7,7 @@ import { Categorie } from "types/categorie.types"; import { ExcelJson } from "types/excel.type"; import { Material } from "types/material.types"; import { massImportMaterial } from "util/MaterialUtil"; -import {CategorysContext, StandorteContext} from "../AbteilungDetails"; +import {CategorysContext, StandorteContext} from "components/abteilung/AbteilungDetails"; export interface ExcelImportProps { abteilung: Abteilung @@ -54,6 +54,17 @@ export const ExcelImport = (props: ExcelImportProps) => { return ''; } + const replaceMaterial = async () => { + await firestore().collection(abteilungenCollection).doc(abteilung.id).collection(abteilungenMaterialsCollection).get().then((snapshot) => { + snapshot.docs.forEach((doc) => { + doc.ref.delete(); + }); + prepareMaterial() + }).catch((ex) => { + message.error(`Es ist ein Fehler aufgetreten: ${ex}`); + }); + } + const prepareMaterial = async (): Promise => { const material: Material[] = []; @@ -171,7 +182,6 @@ export const ExcelImport = (props: ExcelImportProps) => { } - //create categories const promieses = newCategories.map(catName => { return firestore().collection(abteilungenCollection).doc(abteilung.id).collection(abteilungenCategoryCollection).add({ name: catName } as Categorie).then(doc => { @@ -228,9 +238,20 @@ export const ExcelImport = (props: ExcelImportProps) => { , - + , + replaceMaterial()} + onCancel={() => { }} + okText='Ja' + cancelText='Nein' + > + + ]} > diff --git a/src/components/material/ExportMaterial.tsx b/src/components/material/ExportMaterial.tsx new file mode 100644 index 0000000..81176ed --- /dev/null +++ b/src/components/material/ExportMaterial.tsx @@ -0,0 +1,35 @@ +import { Button} from 'antd'; +import {Abteilung} from 'types/abteilung.type'; +import { useContext } from 'react'; +import { exportMaterialsToXlsx } from 'util/ExcelUtil'; +import {CategorysContext, MaterialsContext, StandorteContext} from 'components/abteilung/AbteilungDetails'; + +export interface ExportMaterialProps { + abteilung: Abteilung +} + +export const ExportMaterialButton = (props: ExportMaterialProps) => { + const { abteilung} = props; + + //fetch materials + const materialsContext = useContext(MaterialsContext); + const materials = materialsContext.materials; + const matLoading = materialsContext.loading; + + //fetch categories + const categoriesContext = useContext(CategorysContext); + const categories = categoriesContext.categories; + const catLoading = categoriesContext.loading; + + //fetch categories + const standorteContext = useContext(StandorteContext); + const standorte = standorteContext.standorte; + const standorteLoading = standorteContext.loading; + + + return <> + + +} \ No newline at end of file diff --git a/src/components/material/ImportAddMaterial.tsx b/src/components/material/ImportAddMaterial.tsx new file mode 100644 index 0000000..a72586a --- /dev/null +++ b/src/components/material/ImportAddMaterial.tsx @@ -0,0 +1,42 @@ +import { message,Button } from 'antd'; +import {Abteilung} from 'types/abteilung.type'; +import { useState } from 'react'; +import { ExcelJson } from 'types/excel.type'; +import { ExcelImport } from './ExcelImport'; +import { excelToJson } from 'util/ExcelUtil'; +import React from 'react' + +export interface importAddMaterialProps { + abteilung: Abteilung +} + +export const ImportAddMaterialButton = (props: importAddMaterialProps) => { + const { abteilung} = props; + const [excelData, setExcelData] = useState(); + const [showImportModal, setShowImportModal] = useState(false); + const [updateLoading] = useState(false); + let excelInput = React.useRef(null); + + return <> + { + const res = await excelToJson(e); + if(res) { + setExcelData(res) + setShowImportModal(true) + } else { + message.error('Leider ist ein Fehler beim lesen der Datei aufgetreten 2'); + } + }} + /> + + + +} \ No newline at end of file diff --git a/src/views/abteilung/material/abteilungMaterials.tsx b/src/views/abteilung/material/abteilungMaterials.tsx index 549bb17..e603472 100644 --- a/src/views/abteilung/material/abteilungMaterials.tsx +++ b/src/views/abteilung/material/abteilungMaterials.tsx @@ -16,6 +16,9 @@ import moment from 'moment'; import {Material} from 'types/material.types'; import {getAvailableMatCount} from 'util/MaterialUtil'; import {AddStandortButton} from "components/standort/AddStandort"; +import {ImportAddMaterialButton} from 'components/material/ImportAddMaterial'; +import {DeleteMaterialButton} from 'components/material/DeleteMaterial'; +import {ExportMaterialButton} from 'components/material/ExportMaterial'; export type AbteilungMaterialViewProps = { abteilung: Abteilung; @@ -124,6 +127,18 @@ export const AbteilungMaterialView = (props: AbteilungMaterialViewProps) => { + + + + + + + + + + + + { matLoading || catLoading ? From e51dbe4562587acfe6e06b291e58c3b2b1911c9c Mon Sep 17 00:00:00 2001 From: Leo1212 Date: Tue, 7 Nov 2023 00:17:38 +0100 Subject: [PATCH 2/3] added tooltips --- src/components/material/ExcelImport.tsx | 825 ++++++++++++++---------- 1 file changed, 467 insertions(+), 358 deletions(-) diff --git a/src/components/material/ExcelImport.tsx b/src/components/material/ExcelImport.tsx index c84d0e7..6ef29e6 100644 --- a/src/components/material/ExcelImport.tsx +++ b/src/components/material/ExcelImport.tsx @@ -1,5 +1,19 @@ -import { Button, Col, message, Modal, Row, Select, Spin, Popconfirm } from "antd"; -import { abteilungenCategoryCollection, abteilungenMaterialsCollection, abteilungenCollection } from "config/firebase/collections"; +import { + Button, + Col, + message, + Modal, + Row, + Select, + Spin, + Popconfirm, + Tooltip, +} from "antd"; +import { + abteilungenCategoryCollection, + abteilungenMaterialsCollection, + abteilungenCollection, +} from "config/firebase/collections"; import { firestore } from "config/firebase/firebase"; import { useContext, useState } from "react"; import { Abteilung } from "types/abteilung.type"; @@ -7,388 +21,483 @@ import { Categorie } from "types/categorie.types"; import { ExcelJson } from "types/excel.type"; import { Material } from "types/material.types"; import { massImportMaterial } from "util/MaterialUtil"; -import {CategorysContext, StandorteContext} from "components/abteilung/AbteilungDetails"; +import { + CategorysContext, + StandorteContext, +} from "components/abteilung/AbteilungDetails"; export interface ExcelImportProps { - abteilung: Abteilung - excelData: ExcelJson | undefined - showModal: boolean - setShow: (show: boolean) => void + abteilung: Abteilung; + excelData: ExcelJson | undefined; + showModal: boolean; + setShow: (show: boolean) => void; } export const ExcelImport = (props: ExcelImportProps) => { - const { abteilung, excelData, showModal, setShow } = props; - - //fetch categories - const categoriesContext = useContext(CategorysContext); - const standorteContext = useContext(StandorteContext); - - const categories = categoriesContext.categories; - const standorte = standorteContext.standorte; - const catLoading = categoriesContext.loading; - - const [name, setName] = useState(); - const [comment, setComment] = useState(); - const [count, setCount] = useState(); - const [lost, setLost] = useState(); - const [damaged, setDamaged] = useState(); - const [location, setLocation] = useState(); - const [weightInKg, setWeightInKg] = useState(); - const [consumables, setConsumables] = useState(); - const [categorieIds, setCategorieIds] = useState(); - const [standort, setStandort] = useState(); - const [imageUrls, setImageUrls] = useState(); - const [onlyLendInternal, setOnlyLendInternal] = useState(); - - - const findExampleData = (key: string | undefined): string => { - if (!excelData || !key) return ''; - - const index = excelData.headers.findIndex(h => h === key); - - const res = excelData.data.find(data => data[index] !== null); - if (res) { - return res[index] as string; - } - - return ''; + const { abteilung, excelData, showModal, setShow } = props; + + //fetch categories + const categoriesContext = useContext(CategorysContext); + const standorteContext = useContext(StandorteContext); + + const categories = categoriesContext.categories; + const standorte = standorteContext.standorte; + const catLoading = categoriesContext.loading; + + const [name, setName] = useState(); + const [comment, setComment] = useState(); + const [count, setCount] = useState(); + const [lost, setLost] = useState(); + const [damaged, setDamaged] = useState(); + const [location, setLocation] = useState(); + const [weightInKg, setWeightInKg] = useState(); + const [consumables, setConsumables] = useState(); + const [categorieIds, setCategorieIds] = useState(); + const [standort, setStandort] = useState(); + const [imageUrls, setImageUrls] = useState(); + const [onlyLendInternal, setOnlyLendInternal] = useState< + string | undefined + >(); + + const findExampleData = (key: string | undefined): string => { + if (!excelData || !key) return ""; + + const index = excelData.headers.findIndex((h) => h === key); + + const res = excelData.data.find((data) => data[index] !== null); + if (res) { + return res[index] as string; } - const replaceMaterial = async () => { - await firestore().collection(abteilungenCollection).doc(abteilung.id).collection(abteilungenMaterialsCollection).get().then((snapshot) => { - snapshot.docs.forEach((doc) => { - doc.ref.delete(); - }); - prepareMaterial() - }).catch((ex) => { - message.error(`Es ist ein Fehler aufgetreten: ${ex}`); + return ""; + }; + + const replaceMaterial = async () => { + await firestore() + .collection(abteilungenCollection) + .doc(abteilung.id) + .collection(abteilungenMaterialsCollection) + .get() + .then((snapshot) => { + snapshot.docs.forEach((doc) => { + doc.ref.delete(); }); + prepareMaterial(); + }) + .catch((ex) => { + message.error(`Es ist ein Fehler aufgetreten: ${ex}`); + }); + }; + + const prepareMaterial = async (): Promise => { + const material: Material[] = []; + + if (!excelData) return []; + + if (!name) { + message.error("Du musst den Namen des Materials zuordnen."); + console.error("Du musst den Namen des Materials zuordnen."); + return []; } - const prepareMaterial = async (): Promise => { - const material: Material[] = []; - - if (!excelData) return []; - - if (!name) { - message.error('Du musst den Namen des Materials zuordnen.') - console.error('Du musst den Namen des Materials zuordnen.') - return []; + const indexes: { [key: string]: number } = {}; + excelData.headers.forEach((key) => { + indexes[key] = excelData.headers.findIndex((h) => h === key); + }); + + const newCategories: string[] = []; + const newStandorte: string[] = []; + + for (const dataArray of excelData.data) { + const matName: string = dataArray[indexes[name]] as string; + //skip if name is still not found + if (!matName) continue; + const matComment: string | null = comment + ? (dataArray[indexes[comment]] as string) + : null; + const matCount: number = count + ? (dataArray[indexes[count]] as number) + : 1; + const matLost: number = lost ? (dataArray[indexes[lost]] as number) : 0; + const matDamaged: number = damaged + ? (dataArray[indexes[damaged]] as number) + : 0; + const matWeightInKg: number | null = weightInKg + ? (dataArray[indexes[weightInKg]] as number) + : null; + const matConsumablest: boolean = consumables + ? (dataArray[indexes[consumables]] as boolean) + : false; + const matCategorienRaw: string | null = categorieIds + ? (dataArray[indexes[categorieIds]] as string) + : null; + const matStandorteRaw: string | null = standort + ? (dataArray[indexes[standort]] as string) + : null; + const matImageUrlsRaw: string | null = imageUrls + ? (dataArray[indexes[imageUrls]] as string) + : null; + const matonlyLendInternal: boolean = onlyLendInternal + ? (dataArray[indexes[onlyLendInternal]] as boolean) + : false; + + let matCategorieNames: string[] = []; + let matImageUrls: string[] = []; + const materialCategorieIds: string[] = []; + let matStandortNames: string[] = []; + const matStandortIds: string[] = []; + + //string to array of image urls + if (matImageUrlsRaw !== null) { + matImageUrls = matImageUrlsRaw.replaceAll(" ", "").split(","); + } + + if (matCategorienRaw) { + matCategorieNames = matCategorienRaw.replaceAll(" ", "").split(","); + } + + if (matStandorteRaw) { + matStandortNames = matStandorteRaw.replaceAll(" ", "").split(","); + } + + //if cat is set loop through and assign category id + for (const catName of matCategorieNames) { + const placeholderName = "" + catName; + //check if cat already exists + const existingCat = categories.find( + (cat) => cat.name.toLowerCase() === catName.toLowerCase() + ); + if (existingCat) { + materialCategorieIds.push(existingCat.id); + continue; } - - const indexes: { [key: string]: number } = {}; - excelData.headers.forEach(key => { - indexes[key] = excelData.headers.findIndex(h => h === key) - }) - - const newCategories: string[] = []; - const newStandorte: string[] = []; - - for( const dataArray of excelData.data) { - const matName: string = dataArray[indexes[name]] as string; - //skip if name is still not found - if (!matName) continue; - const matComment: string | null = comment ? dataArray[indexes[comment]] as string : null; - const matCount: number = count ? dataArray[indexes[count]] as number : 1; - const matLost: number = lost ? dataArray[indexes[lost]] as number : 0; - const matDamaged: number = damaged ? dataArray[indexes[damaged]] as number : 0; - const matWeightInKg: number | null = weightInKg ? dataArray[indexes[weightInKg]] as number : null; - const matConsumablest: boolean = consumables ? dataArray[indexes[consumables]] as boolean : false; - const matCategorienRaw: string | null = categorieIds ? dataArray[indexes[categorieIds]] as string : null; - const matStandorteRaw: string | null = standort ? dataArray[indexes[standort]] as string : null; - const matImageUrlsRaw: string | null = imageUrls ? dataArray[indexes[imageUrls]] as string : null; - const matonlyLendInternal: boolean = onlyLendInternal ? dataArray[indexes[onlyLendInternal]] as boolean : false; - - let matCategorieNames: string[] = []; - let matImageUrls: string[] = []; - const materialCategorieIds: string[] = []; - let matStandortNames: string[] = []; - const matStandortIds: string[] = []; - - //string to array of image urls - if (matImageUrlsRaw !== null) { - matImageUrls = matImageUrlsRaw.replaceAll(' ', '').split(','); - } - - if (matCategorienRaw) { - matCategorieNames = matCategorienRaw.replaceAll(' ', '').split(','); - } - - if (matStandorteRaw) { - matStandortNames = matStandorteRaw.replaceAll(' ', '').split(','); - } - - - //if cat is set loop through and assign category id - for(const catName of matCategorieNames) { - const placeholderName = '' + catName; - //check if cat already exists - const existingCat = categories.find(cat => cat.name.toLowerCase() === catName.toLowerCase()); - if (existingCat) { - materialCategorieIds.push(existingCat.id) - continue; - } - //check if cat is getting generated - const newCat = newCategories.find(cat => cat.toLowerCase() === catName.toLowerCase()); - if (newCat) { - materialCategorieIds.push(placeholderName); - continue; - } - - //generate new cat - newCategories.push(catName) - - materialCategorieIds.push(placeholderName); - } - - //if ort is set loop through and assign ort id - for(const ortName of matStandortNames) { - const placeholderName = '' + ortName; - //check if ort already exists - const existingOrt = standorte.find(ort => ort.name.toLowerCase() === ortName.toLowerCase()); - if (existingOrt) { - matStandortIds.push(existingOrt.id) - continue; - } - //check if ort is getting generated - const newOrt = newStandorte.find(ort => ort.toLowerCase() === ortName.toLowerCase()); - if (newOrt) { - matStandortIds.push(placeholderName); - continue; - } - - //generate new cat - newStandorte.push(ortName) - - matStandortIds.push(placeholderName); - } - - - const matToAdd = { - name: matName, - comment: matComment, - count: matCount, - lost: matLost, - damaged: matDamaged, - weightInKg: matWeightInKg, - consumables: matConsumablest, - categorieIds: materialCategorieIds, - imageUrls: matImageUrls, - standort: matStandortIds, - onlyLendInternal: matonlyLendInternal - } as Material - - material.push(matToAdd) - + //check if cat is getting generated + const newCat = newCategories.find( + (cat) => cat.toLowerCase() === catName.toLowerCase() + ); + if (newCat) { + materialCategorieIds.push(placeholderName); + continue; } - //create categories - const promieses = newCategories.map(catName => { - return firestore().collection(abteilungenCollection).doc(abteilung.id).collection(abteilungenCategoryCollection).add({ name: catName } as Categorie).then(doc => { - return { - id: doc.id, - name: catName - } as Categorie - }) - }) - - const allCategories = await Promise.all(promieses); - - //assign new catId to matCategorieIds - const materials = material.map(mat => { - const catIdsToSet: string[] = []; - if (mat.categorieIds && mat.categorieIds.length > 0) { - mat.categorieIds.forEach(catPlaceholder => { - const foundCat = allCategories.find(cat => cat.name === catPlaceholder) - if (foundCat) { - catIdsToSet.push(foundCat.id) - } else { - catIdsToSet.push(catPlaceholder) - } - }) - mat.categorieIds = catIdsToSet; - return mat; - } else { - return mat; - } - }) - - try { - await massImportMaterial(abteilung.id, materials) - message.success(`Es wurden erfolgreich ${material.length}/${excelData.data.length} Materialien importiert.`) - setShow(false) - } catch(err) { - message.error(`Es ist ein Fehler aufgetreten ${err}`) - console.error('Es ist ein Fehler aufgetreten', err) + //generate new cat + newCategories.push(catName); + + materialCategorieIds.push(placeholderName); + } + + //if ort is set loop through and assign ort id + for (const ortName of matStandortNames) { + const placeholderName = "" + ortName; + //check if ort already exists + const existingOrt = standorte.find( + (ort) => ort.name.toLowerCase() === ortName.toLowerCase() + ); + if (existingOrt) { + matStandortIds.push(existingOrt.id); + continue; + } + //check if ort is getting generated + const newOrt = newStandorte.find( + (ort) => ort.toLowerCase() === ortName.toLowerCase() + ); + if (newOrt) { + matStandortIds.push(placeholderName); + continue; } - - return materials; + //generate new cat + newStandorte.push(ortName); + + matStandortIds.push(placeholderName); + } + + const matToAdd = { + name: matName, + comment: matComment, + count: matCount, + lost: matLost, + damaged: matDamaged, + weightInKg: matWeightInKg, + consumables: matConsumablest, + categorieIds: materialCategorieIds, + imageUrls: matImageUrls, + standort: matStandortIds, + onlyLendInternal: matonlyLendInternal, + } as Material; + + material.push(matToAdd); } - if (!excelData) { - return <> + //create categories + const promieses = newCategories.map((catName) => { + return firestore() + .collection(abteilungenCollection) + .doc(abteilung.id) + .collection(abteilungenCategoryCollection) + .add({ name: catName } as Categorie) + .then((doc) => { + return { + id: doc.id, + name: catName, + } as Categorie; + }); + }); + + const allCategories = await Promise.all(promieses); + + //assign new catId to matCategorieIds + const materials = material.map((mat) => { + const catIdsToSet: string[] = []; + if (mat.categorieIds && mat.categorieIds.length > 0) { + mat.categorieIds.forEach((catPlaceholder) => { + const foundCat = allCategories.find( + (cat) => cat.name === catPlaceholder + ); + if (foundCat) { + catIdsToSet.push(foundCat.id); + } else { + catIdsToSet.push(catPlaceholder); + } + }); + mat.categorieIds = catIdsToSet; + return mat; + } else { + return mat; + } + }); + + try { + await massImportMaterial(abteilung.id, materials); + message.success( + `Es wurden erfolgreich ${material.length}/${excelData.data.length} Materialien importiert.` + ); + setShow(false); + } catch (err) { + message.error(`Es ist ein Fehler aufgetreten ${err}`); + console.error("Es ist ein Fehler aufgetreten", err); } - return setShow(false)} - footer={[ - , - , - replaceMaterial()} - onCancel={() => { }} - okText='Ja' - cancelText='Nein' + return materials; + }; + + if (!excelData) { + return <>; + } + + return ( + setShow(false)} + footer={[ + , + + + , + replaceMaterial()} + onCancel={() => {}} + okText="Ja" + cancelText="Nein" + > + + - - ]} + Importieren ersetzen + + + , + ]} > - - -

Name*:

- { - name &&

{`Beispiel: ${findExampleData(name)}`}

- } - - - - - -

Bemerkung:

- { - comment &&

{`Beispiel: ${findExampleData(comment)}`}

- } - - - - - -

Standort:

- { - standort &&

{`Beispiel: ${findExampleData(standort)}`}

- } - - - - - -

Anzahl:

- { - count &&

{`Beispiel: ${findExampleData(count)}`}

- } - - - - - -

Verloren:

- { - lost &&

{`Beispiel: ${findExampleData(lost)}`}

- } - - - - - -

Beschädigt:

- { - damaged &&

{`Beispiel: ${findExampleData(damaged)}`}

- } - - - - - -

Gewicht in Kg:

- { - weightInKg &&

{`Beispiel: ${findExampleData(weightInKg)}`}

- } - - - - - -

Ist Verbrauchsmaterial:

- { - consumables &&

{`Beispiel: ${findExampleData(consumables)}`}

- } - - - - - -

Katergorien:

- { - categorieIds &&

{`Beispiel: ${findExampleData(categorieIds)}`}

- } - - - - - -

Bilder:

- { - imageUrls &&

{`Beispiel: ${findExampleData(imageUrls)}`}

- } - - - - - -

Nur Intern ausleihbar:

- { - onlyLendInternal &&

{`Beispiel: ${findExampleData(onlyLendInternal)}`}

- } - - - - - - { - catLoading && - } -
+ + +

Name*:

+ {name &&

{`Beispiel: ${findExampleData(name)}`}

} + + + + + +

Bemerkung:

+ {comment &&

{`Beispiel: ${findExampleData(comment)}`}

} + + + + + +

Standort:

+ {standort &&

{`Beispiel: ${findExampleData(standort)}`}

} + + + + + +

Anzahl:

+ {count &&

{`Beispiel: ${findExampleData(count)}`}

} + + + + + +

Verloren:

+ {lost &&

{`Beispiel: ${findExampleData(lost)}`}

} + + + + + +

Beschädigt:

+ {damaged &&

{`Beispiel: ${findExampleData(damaged)}`}

} + + + + + +

Gewicht in Kg:

+ {weightInKg &&

{`Beispiel: ${findExampleData(weightInKg)}`}

} + + + + + +

Ist Verbrauchsmaterial:

+ {consumables &&

{`Beispiel: ${findExampleData(consumables)}`}

} + + + + + +

Katergorien:

+ {categorieIds && ( +

{`Beispiel: ${findExampleData(categorieIds)}`}

+ )} + + + + + +

Bilder:

+ {imageUrls &&

{`Beispiel: ${findExampleData(imageUrls)}`}

} + + + + + +

Nur Intern ausleihbar:

+ {onlyLendInternal && ( +

{`Beispiel: ${findExampleData(onlyLendInternal)}`}

+ )} + + + + + + {catLoading && } +
-} + ); +}; export interface ExcelImportSelectProps { - options: string[] - selected: string | undefined - setSelected: (option: string) => void + options: string[]; + selected: string | undefined; + setSelected: (option: string) => void; } const ExcelImportSelect = (props: ExcelImportSelectProps) => { - - const { options, selected, setSelected } = props; - - const { Option } = Select; - - return { + if (!option) return false; + return ( + (option.children as any).toLowerCase().indexOf(input.toLowerCase()) >= + 0 + ); + }} + style={{ width: "100%" }} > - - { - options.map(o => ) - } + + {options.map((o) => ( + + ))} -} \ No newline at end of file + ); +}; From 3aa32f5d1c5cdb4ff22c4df9e2de4ef0bceabc86 Mon Sep 17 00:00:00 2001 From: Jan Preisig Date: Wed, 29 Nov 2023 14:12:19 +0100 Subject: [PATCH 3/3] #59 clear input field before opening fileselection --- src/components/material/ImportAddMaterial.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/material/ImportAddMaterial.tsx b/src/components/material/ImportAddMaterial.tsx index a72586a..5df3883 100644 --- a/src/components/material/ImportAddMaterial.tsx +++ b/src/components/material/ImportAddMaterial.tsx @@ -17,6 +17,12 @@ export const ImportAddMaterialButton = (props: importAddMaterialProps) => { const [updateLoading] = useState(false); let excelInput = React.useRef(null); + function clearFileInput() { + if (excelInput.current?.value) { + excelInput.current.value = ''; + } + } + return <> { message.error('Leider ist ein Fehler beim lesen der Datei aufgetreten 2'); } }} + onClick={clearFileInput} />