diff --git a/src/api/Controllers/ImportController.cs b/src/api/Controllers/ImportController.cs
index 5537347b0..92b8733c3 100644
--- a/src/api/Controllers/ImportController.cs
+++ b/src/api/Controllers/ImportController.cs
@@ -47,29 +47,29 @@ public ImportController(BdmsContext context, ILogger logger, L
/// Receives an uploaded JSON file to import one or several (s).
///
/// The of the new (s).
- /// The containing the borehole JSON records that were uploaded.
+ /// The containing the borehole JSON records that were uploaded.
/// The number of the newly created s.
[HttpPost("json")]
[Authorize(Policy = PolicyNames.Viewer)]
[RequestSizeLimit(int.MaxValue)]
[RequestFormLimits(MultipartBodyLengthLimit = MaxFileSize)]
- public async Task> UploadJsonFileAsync(int workgroupId, IFormFile file)
+ public async Task> UploadJsonFileAsync(int workgroupId, IFormFile boreholesFile)
{
// Increase max allowed errors to be able to return more validation errors at once.
ModelState.MaxAllowedErrors = 1000;
logger.LogInformation("Import boreholes json to workgroup with id <{WorkgroupId}>", workgroupId);
- if (file == null || file.Length == 0) return BadRequest("No file uploaded.");
+ if (boreholesFile == null || boreholesFile.Length == 0) return BadRequest("No file uploaded.");
- if (!FileTypeChecker.IsJson(file)) return BadRequest("Invalid file type for borehole JSON.");
+ if (!FileTypeChecker.IsJson(boreholesFile)) return BadRequest("Invalid file type for borehole JSON.");
try
{
List? boreholes;
try
{
- using var stream = file.OpenReadStream();
+ using var stream = boreholesFile.OpenReadStream();
boreholes = await JsonSerializer.DeserializeAsync>(stream, jsonImportOptions).ConfigureAwait(false);
}
catch (JsonException ex)
diff --git a/src/api/Models/Observation.cs b/src/api/Models/Observation.cs
index 07d126157..7e1e362a0 100644
--- a/src/api/Models/Observation.cs
+++ b/src/api/Models/Observation.cs
@@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using System.Text.Json.Serialization;
namespace BDMS.Models;
@@ -107,6 +108,7 @@ public class Observation : IChangeTracking, IIdentifyable
///
/// Gets or sets the 's borehole.
///
+ [JsonIgnore]
public Borehole? Borehole { get; set; }
///
diff --git a/src/client/docs/import.md b/src/client/docs/import.md
index 6e9e92140..75f21fdd1 100644
--- a/src/client/docs/import.md
+++ b/src/client/docs/import.md
@@ -1,8 +1,8 @@
# Bohrdaten importieren
-Mit der Import-Funktion können geologische Bohrdaten aus einer CSV-Datei importiert werden.
+Mit der Import-Funktion können geologische Bohrdaten via CSV oder JSON Dateien importiert werden.
-## Anleitung
+## Anleitung CSV-Import
### Schritt 1: CSV-Datei vorbereiten
@@ -34,7 +34,7 @@ Die CSV-Datei muss den folgenden Anforderungen und dem Format entsprechen, damit
- Die Werte in den Spalten müssen den erwarteten Datentypen entsprechen (z.B. numerisch für Tiefe, Text für Namen, etc.).
-## Bohrloch Datei Format
+## Bohrloch Datei CSV Format
Die zu importierenden Daten müssen gemäss obigen Anforderungen im CSV-Format vorliegen. Die erste Zeile wird als Spaltentitel/Spaltenname interpretiert, die restlichen Zeilen als Daten.
@@ -84,7 +84,7 @@ Koordinaten können in LV95 oder LV03 importiert werden, das räumliche Bezugssy
## Validierung
-### Fehlende Werte
+### CSV-Import: Fehlende Werte
Für jeden bereitgestellten Header CSV-Datei muss für jede Zeile ein entsprechender Wert angegeben werden, oder leer gelassen werden.
@@ -94,6 +94,48 @@ Beim Importprozess der Bohrdaten wird eine Duplikatsvalidierung durchgeführt, u
Duplikate werden nur innerhalb einer Arbeitsgruppe erkannt. Die Duplikaterkennung erfolgt anhand der Koordinaten mit einer Toleranz von +/- 2 Metern und der Gesamttiefe des Bohrlochs.
-## Generelles
+## Anmerkungen
+
+Es ist wichtig zu beachten, dass der Import beim ersten Fehler abgebrochen wird und keine teilweisen Importe stattfinden. Entweder werden alle Daten importiert, oder es findet kein Import statt. Der Import unterstützt keine Updates von bestehenden Daten.
+
+
+## Anleitung JSON-Import
+
+### Schritt 1: JSON-Datei vorbereiten
+
+Zunächst sollte die JSON-Datei den Anforderungen und dem Format entsprechen, wie im Abschnitt [Format und Anforderungen an die JSON-Datei](#format-und-anforderungen-an-die-json-datei) beschrieben.
+
+### Schritt 2: Navigieren zum Import-Bereich
+
+1. In der Webapplikation anmelden.
+2. Unten links auf die Schaltfläche _Importieren_ klicken.
+
+### Schritt 3: Bohrloch JSON-Datei selektieren
+
+1. Schaltfläche _Datei auswählen_ anklicken und die vorbereitete JSON-Datei auswählen.
+2. Unter _Arbeitsgruppe_ die Arbeitsgruppe auswählen, in welche die Bohrdaten importiert werden sollen (neue Arbeitsgruppen können nur als "Admin-User" erstellt werden).
+
+### Schritt 4: Dateien hochladen
+
+1. Import-Prozess mit einem Klick auf _Importieren_ starten.
+2. Warten, bis der Upload abgeschlossen ist und die Daten in der Anwendung verfügbar sind.
+
+## Format und Anforderungen an die JSON-Datei
+
+Die JSON-Datei muss den folgenden Anforderungen entsprechen, damit sie erfolgreich in die Webapplikation importiert werden kann:
+
+- Die Datei muss im JSON-Format vorliegen.
+- Die Datei muss im UTF-8-Format gespeichert sein.
+- Die JSON-Datei muss ein Array von Objekten enthalten. Jedes Objekt entspricht einem Bohrloch. Auch ein einzelnes Bohrloch muss als Array von einem Objekt definiert werden.
+- Die JSON-Datei eines Bohrlochexports kann als valide Vorlage für den Import betrachtet werden.
+
+## Validierung
+
+### Duplikate
+
+Beim Importprozess der Bohrdaten wird eine Duplikatsvalidierung durchgeführt, um sicherzustellen, dass kein Bohrloch mehrmals in der Datei vorhanden ist oder bereits in der Datenbank existiert.
+Duplikate werden nur innerhalb einer Arbeitsgruppe erkannt. Die Duplikaterkennung erfolgt anhand der Koordinaten mit einer Toleranz von +/- 2 Metern und der Gesamttiefe des Bohrlochs.
+
+## Anmerkungen
Es ist wichtig zu beachten, dass der Import beim ersten Fehler abgebrochen wird und keine teilweisen Importe stattfinden. Entweder werden alle Daten importiert, oder es findet kein Import statt. Der Import unterstützt keine Updates von bestehenden Daten.
diff --git a/src/client/public/locale/de/common.json b/src/client/public/locale/de/common.json
index cfa7a1987..fa001f683 100644
--- a/src/client/public/locale/de/common.json
+++ b/src/client/public/locale/de/common.json
@@ -132,7 +132,8 @@
"drilling_mud_type": "Bohrspülung Typ",
"drilling_start_date": "Datum Bohrbeginn",
"dropZoneAttachmentsText": "Datei(en) mit Anhängen hier ablegen oder klicken, um sie hochzuladen",
- "dropZoneBoreholesText": "CSV Datei mit Bohrungen hier ablegen oder klicken, um sie hochzuladen",
+ "dropZoneBoreholeCsvText": "Wählen Sie eine CSV Datei aus",
+ "dropZoneBoreholeJsonText": "Wählen Sie eine JSON Datei aus",
"dropZoneChooseBoreholeFilesFirst": "Wählen Sie zuerst eine CSV Datei mit Bohrungen aus",
"dropZoneDefaultErrorMsg": "Beim Auswählen ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.",
"dropZoneFileToLarge": "Eine oder mehrere Dateien sind zu gross. Max. 200 MB.",
@@ -254,6 +255,7 @@
"identifier_value": "ID Code",
"import": "Importieren",
"importBoreholeAttachment": "Wählen Sie eine oder mehrere Datei(en) aus:",
+ "importBoreholes": "Bohrungen importieren",
"importDate": "Importdatum",
"importedBy": "Importiert von",
"importedData": "Importierte Daten",
diff --git a/src/client/public/locale/en/common.json b/src/client/public/locale/en/common.json
index 0b4161c45..1ed833010 100644
--- a/src/client/public/locale/en/common.json
+++ b/src/client/public/locale/en/common.json
@@ -132,7 +132,8 @@
"drilling_mud_type": "Drilling mud type",
"drilling_start_date": "Drilling date: start",
"dropZoneAttachmentsText": "Drag and drop file(s) with the appendixes here or click to upload",
- "dropZoneBoreholesText": "Drag and drop a CSV file with the boreholes here or click to upload",
+ "dropZoneBoreholeCsvText": "Select a CSV file",
+ "dropZoneBoreholeJsonText": "Select a JSON file",
"dropZoneChooseBoreholeFilesFirst": "First, select a CSV file with boreholes",
"dropZoneDefaultErrorMsg": "An error occurred during the selection. Please try again.",
"dropZoneFileToLarge": "One ore more files are too large. Max. 200 MB.",
@@ -254,6 +255,7 @@
"identifier_value": "ID Code",
"import": "Import",
"importBoreholeAttachment": "Select one or multiple file(s) to upload:",
+ "importBoreholes": "Import boreholes",
"importDate": "Import date",
"importedBy": "Imported by",
"importedData": "Imported data",
diff --git a/src/client/public/locale/fr/common.json b/src/client/public/locale/fr/common.json
index e81e7c5a5..eee908fc3 100644
--- a/src/client/public/locale/fr/common.json
+++ b/src/client/public/locale/fr/common.json
@@ -132,7 +132,8 @@
"drilling_mud_type": "Type de boue de forage",
"drilling_start_date": "Date de début du forage",
"dropZoneAttachmentsText": "Déposez les fichiers avec les annexes ici ou cliquez pour les télécharger",
- "dropZoneBoreholesText": "Déposez le fichier CSV avec les forages ici ou cliquez pour le télécharger",
+ "dropZoneBoreholeCsvText": "Sélectionnez un fichier CSV",
+ "dropZoneBoreholeJsonText": "Sélectionnez un fichier JSON",
"dropZoneChooseBoreholeFilesFirst": "D'abord, sélectionnez un fichier CSV avec les forages",
"dropZoneDefaultErrorMsg": "Une erreur s'est produite lors de la sélection. Veuillez réessayer.",
"dropZoneFileToLarge": "Un ou plusieurs fichiers sont trop volumineux. Max. 200 Mo.",
@@ -254,6 +255,7 @@
"identifier_value": "Code d'ID",
"import": "Importer",
"importBoreholeAttachment": "Sélectionnez un ou plusieurs fichiers à télécharger:",
+ "importBoreholes": "Importer des forages",
"importDate": "Date d'importation",
"importedBy": "Importé par",
"importedData": "Données importées",
diff --git a/src/client/public/locale/it/common.json b/src/client/public/locale/it/common.json
index b3491680e..6b0afb986 100644
--- a/src/client/public/locale/it/common.json
+++ b/src/client/public/locale/it/common.json
@@ -132,7 +132,8 @@
"drilling_mud_type": "Tipo di fango di perforazione",
"drilling_start_date": "Data di inizio della perforazione",
"dropZoneAttachmentsText": "Trascina qui i file con i appendici o clicca per caricarli",
- "dropZoneBoreholesText": "Trascina qui il file CSV con i perforazioni o clicca per caricarlo CSV",
+ "dropZoneBoreholeCsvText": "Seleziona un file CSV",
+ "dropZoneBoreholeJsonText": "Seleziona un file JSON",
"dropZoneChooseBoreholeFilesFirst": "Innanzitutto, seleziona un file CSV con i perforazioni",
"dropZoneDefaultErrorMsg": "Si è verificato un errore durante la selezione. Riprova.",
"dropZoneFileToLarge": "Uno o più file sono troppo grandi. Max. 200 MB.",
@@ -254,6 +255,7 @@
"identifier_value": "Codice di ID",
"import": "Importare",
"importBoreholeAttachment": "Seleziona uno o più file da scaricare:",
+ "importBoreholes": "Importare perforazioni",
"importDate": "Data di importazione",
"importedBy": "Importato da",
"importedData": "Dati importati",
diff --git a/src/client/src/api/borehole.ts b/src/client/src/api/borehole.ts
index 93427af00..7ab4e2fb4 100644
--- a/src/client/src/api/borehole.ts
+++ b/src/client/src/api/borehole.ts
@@ -69,7 +69,7 @@ export const getBoreholeById = async (id: number) => await fetchApiV2(`borehole/
export const exportJsonBoreholes = async (ids: number[] | GridRowSelectionModel) => {
const idsQuery = ids.map(id => `ids=${id}`).join("&");
- return await fetchApiV2(`borehole/json?${idsQuery}`, "GET");
+ return await fetchApiV2(`export/json?${idsQuery}`, "GET");
};
export const updateBorehole = async (borehole: BoreholeV2) => {
@@ -77,10 +77,14 @@ export const updateBorehole = async (borehole: BoreholeV2) => {
};
/* eslint-disable @typescript-eslint/no-explicit-any */
-export const importBoreholes = async (workgroupId: string, combinedFormData: any) => {
+export const importBoreholesCsv = async (workgroupId: string, combinedFormData: any) => {
return await upload(`import?workgroupId=${workgroupId}`, "POST", combinedFormData);
};
+export const importBoreholesJson = async (workgroupId: string, combinedFormData: any) => {
+ return await upload(`import/json?workgroupId=${workgroupId}`, "POST", combinedFormData);
+};
+
export const copyBorehole = async (boreholeId: GridRowSelectionModel, workgroupId: string | null) => {
return await fetchApiV2(`borehole/copy?id=${boreholeId}&workgroupId=${workgroupId}`, "POST");
};
diff --git a/src/client/src/components/export/exportDialog.tsx b/src/client/src/components/export/exportDialog.tsx
index d430ae885..6c65d96b5 100644
--- a/src/client/src/components/export/exportDialog.tsx
+++ b/src/client/src/components/export/exportDialog.tsx
@@ -1,7 +1,7 @@
import { useTranslation } from "react-i18next";
import { Dialog, DialogActions, DialogContent, DialogTitle, Stack, Typography } from "@mui/material";
import { GridRowSelectionModel } from "@mui/x-data-grid";
-import { exportCSVBorehole, getAllBoreholes } from "../../api/borehole.ts";
+import { exportCSVBorehole, exportJsonBoreholes } from "../../api/borehole.ts";
import { downloadData } from "../../utils.ts";
import { CancelButton, ExportButton } from "../buttons/buttons.tsx";
@@ -15,8 +15,8 @@ export const ExportDialog = ({ isExporting, setIsExporting, selectionModel, file
const { t } = useTranslation();
const exportJson = async () => {
- const paginatedResponse = await getAllBoreholes(selectionModel, 1, selectionModel.length);
- const jsonString = JSON.stringify(paginatedResponse.boreholes, null, 2);
+ const exportJsonResponse = await exportJsonBoreholes(selectionModel);
+ const jsonString = JSON.stringify(exportJsonResponse);
downloadData(jsonString, `${fileName}.json`, "application/json");
setIsExporting(false);
};
diff --git a/src/client/src/pages/detail/attachments/fileDropzone.jsx b/src/client/src/pages/detail/attachments/fileDropzone.jsx
index fe93bdd68..8b19a279d 100644
--- a/src/client/src/pages/detail/attachments/fileDropzone.jsx
+++ b/src/client/src/pages/detail/attachments/fileDropzone.jsx
@@ -13,9 +13,10 @@ import { theme } from "../../../AppTheme.ts";
* @param {string} props.defaultText - The default text to display in the dropzone.
* @param {number} props.maxFilesToSelectAtOnce - The maximum number of files that can be selected at once.
* @param {number} props.maxFilesToUpload - The maximum number of files that can be uploaded.
- * @param {boolean} props.restrictAcceptedFileTypeToCsv - Whether to restrict accepted file types to CSV.
+ * @param {Array} props.acceptedFileTypes - The list of accepted file types.
* @param {boolean} props.isDisabled - Whether the dropzone is disabled.
* @param {string} props.dataCy - The data-cy attribute for testing.
+ * @param {Function} props.setFileType - A react SetStateAction to set the file type.
* @returns {JSX.Element} The rendered FileDropzone component.
*/
export const FileDropzone = props => {
@@ -24,21 +25,20 @@ export const FileDropzone = props => {
defaultText,
maxFilesToSelectAtOnce,
maxFilesToUpload,
- restrictAcceptedFileTypeToCsv,
+ acceptedFileTypes,
isDisabled,
dataCy,
+ setFileType,
} = props;
const { t } = useTranslation();
const [files, setFiles] = useState([]);
- const [dropZoneText, setDropZoneText] = useState(null);
+ const [dropZoneText, setDropZoneText] = useState(t(defaultText));
const [dropZoneTextColor, setDropZoneTextColor] = useState(null);
const defaultDropzoneTextColor = isDisabled ? "#9f9f9f" : "#2185d0";
- const initialDropzoneText = isDisabled ? t("dropZoneChooseBoreholeFilesFirst") : t(defaultText);
useEffect(() => {
- setDropZoneText(initialDropzoneText);
setDropZoneTextColor(defaultDropzoneTextColor);
- }, [defaultDropzoneTextColor, initialDropzoneText]);
+ }, [defaultDropzoneTextColor]);
// Set the color of the dropzone text to red and display an error message
const showErrorMsg = useCallback(
@@ -88,17 +88,38 @@ export const FileDropzone = props => {
setDropZoneTextColor(defaultDropzoneTextColor);
setDropZoneText(t(defaultText));
setFiles(prevFiles => [...prevFiles, ...acceptedFiles]);
+
+ if (setFileType) {
+ if (acceptedFileTypes.includes("text/csv")) {
+ setFileType("csv");
+ }
+ if (acceptedFileTypes.includes("application/json")) {
+ setFileType("json");
+ }
+ }
}
},
- [defaultDropzoneTextColor, defaultText, files.length, maxFilesToUpload, showErrorMsg, t],
+ [
+ defaultDropzoneTextColor,
+ defaultText,
+ files.length,
+ maxFilesToUpload,
+ showErrorMsg,
+ t,
+ acceptedFileTypes,
+ setFileType,
+ ],
);
- // Is called when a accepted file is removed.
+ // Is called when an accepted file is removed.
const removeFile = fileToRemove => {
setFiles(prevFiles => prevFiles.filter(file => file !== fileToRemove));
+ if (setFileType) {
+ setFileType("");
+ }
};
- // IS called when the selected/dropped files are rejected
+ // Is called when the selected/dropped files are rejected
const onDropRejected = useCallback(
fileRejections => {
const errorCode = fileRejections[0].errors[0].code;
@@ -113,7 +134,13 @@ export const FileDropzone = props => {
onDropAccepted,
maxFiles: maxFilesToSelectAtOnce || Infinity,
maxSize: 209715200,
- accept: restrictAcceptedFileTypeToCsv ? { "text/csv": [".csv"] } : "*",
+ accept:
+ acceptedFileTypes.length > 0
+ ? acceptedFileTypes.reduce((acc, type) => {
+ acc[type] = [];
+ return acc;
+ }, {})
+ : "*",
noClick: isDisabled,
noKeyboard: isDisabled,
});
diff --git a/src/client/src/pages/detail/form/borehole/geometryImport.jsx b/src/client/src/pages/detail/form/borehole/geometryImport.jsx
index 74c12fe14..ca2879de2 100644
--- a/src/client/src/pages/detail/form/borehole/geometryImport.jsx
+++ b/src/client/src/pages/detail/form/borehole/geometryImport.jsx
@@ -114,7 +114,7 @@ const GeometryImport = ({ boreholeId }) => {
void;
}
-export interface ImportContentProps {
- setSelectedFile: React.Dispatch>;
-}
-
-export interface ImportModalProps extends ImportContentProps {
+export interface ImportModalProps {
modal: boolean;
creating: boolean;
selectedFile: Blob[] | null;
diff --git a/src/client/src/pages/overview/sidePanelContent/importer/importModal.tsx b/src/client/src/pages/overview/sidePanelContent/importer/importModal.tsx
index 47e45a57a..afb577476 100644
--- a/src/client/src/pages/overview/sidePanelContent/importer/importModal.tsx
+++ b/src/client/src/pages/overview/sidePanelContent/importer/importModal.tsx
@@ -1,7 +1,7 @@
-import { useContext } from "react";
+import { useContext, useState } from "react";
import { useTranslation } from "react-i18next";
import { Button, Header, Icon, Modal, Segment } from "semantic-ui-react";
-import { importBoreholes } from "../../../../api/borehole.ts";
+import { importBoreholesCsv, importBoreholesJson } from "../../../../api/borehole.ts";
import { AlertContext } from "../../../../components/alert/alertContext.tsx";
import TranslationText from "../../../../components/legacyComponents/translationText.jsx";
import { capitalizeFirstLetter } from "../../../../utils.ts";
@@ -26,42 +26,52 @@ const ImportModal = ({
}: ImportModalProps) => {
const { showAlert } = useContext(AlertContext);
const { t } = useTranslation();
+ const [fileType, setFileType] = useState(""); // Track file type
+
+ const handleImportResponse = async (response: Response) => {
+ setCreating(false);
+ setModal(false);
+ setUpload(false);
+
+ if (response.ok) {
+ showAlert(`${await response.text()} ${t("boreholesImported")}.`, "success");
+ refresh();
+ } else {
+ const responseBody = await response.json();
+ if (response.status === 400) {
+ if (responseBody.errors) {
+ // If response is of type ValidationProblemDetails, open validation error modal.
+ setErrorsResponse(responseBody);
+ setValidationErrorModal(true);
+ refresh();
+ } else {
+ // If response is of type ProblemDetails, show error message.
+ showAlert(responseBody.detail, "error");
+ }
+ } else if (response.status === 504) {
+ showAlert(t("boreholesImportLongRunning"), "error");
+ } else {
+ showAlert(t("boreholesImportError"), "error");
+ }
+ }
+ };
const handleBoreholeImport = () => {
const combinedFormData = new FormData();
if (selectedFile !== null) {
- selectedFile.forEach((boreholeFile: string | Blob) => {
- combinedFormData.append("boreholesFile", boreholeFile);
+ selectedFile.forEach((file: string | Blob) => {
+ combinedFormData.append("boreholesFile", file);
+ });
+ }
+ if (fileType === "csv") {
+ importBoreholesCsv(workgroup, combinedFormData).then(response => {
+ handleImportResponse(response);
+ });
+ } else {
+ importBoreholesJson(workgroup, combinedFormData).then(response => {
+ handleImportResponse(response);
});
}
- importBoreholes(workgroup, combinedFormData).then(response => {
- setCreating(false);
- setModal(false);
- setUpload(false);
- (async () => {
- if (response.ok) {
- showAlert(`${await response.text()} ${t("boreholesImported")}.`, "success");
- refresh();
- } else {
- const responseBody = await response.json();
- if (response.status === 400) {
- if (responseBody.errors) {
- // If response is of type ValidationProblemDetails, open validation error modal.
- setErrorsResponse(responseBody);
- setValidationErrorModal(true);
- refresh();
- } else {
- // If response is of type ProblemDetails, show error message.
- showAlert(responseBody.detail, "error");
- }
- } else if (response.status === 504) {
- showAlert(t("boreholesImportLongRunning"), "error");
- } else {
- showAlert(t("boreholesImportError"), "error");
- }
- }
- })();
- });
};
const handleFormSubmit = async () => {
@@ -89,7 +99,7 @@ const ImportModal = ({
-
+
{capitalizeFirstLetter(t("workgroup"))}
diff --git a/src/client/src/pages/overview/sidePanelContent/importer/importModalContent.tsx b/src/client/src/pages/overview/sidePanelContent/importer/importModalContent.tsx
index 98430ad7e..dc3717fd7 100644
--- a/src/client/src/pages/overview/sidePanelContent/importer/importModalContent.tsx
+++ b/src/client/src/pages/overview/sidePanelContent/importer/importModalContent.tsx
@@ -1,4 +1,4 @@
-import { useCallback } from "react";
+import React, { useCallback } from "react";
import { useTranslation } from "react-i18next";
import { Box, Stack } from "@mui/material/";
import { downloadCodelistCsv } from "../../../../api/fetchApiV2.js";
@@ -6,8 +6,12 @@ import { StackHalfWidth } from "../../../../components/styledComponents.ts";
import { capitalizeFirstLetter } from "../../../../utils.ts";
import Downloadlink from "../../../detail/attachments/downloadlink.jsx";
import { FileDropzone } from "../../../detail/attachments/fileDropzone.jsx";
-import { ImportContentProps } from "../commons/actionsInterfaces.js";
+interface ImportModalContentProps {
+ setSelectedFile: React.Dispatch>;
+ setFileType: (type: string) => void;
+ fileType: string;
+}
const ExampleHeadings = (headings: string) => {
return (
{
);
};
-const ImportModalContent = ({ setSelectedFile }: ImportContentProps) => {
+const ImportModalContent = ({ setSelectedFile, setFileType, fileType }: ImportModalContentProps) => {
const { t } = useTranslation();
- const handleBoreholeFileChange = useCallback(
- (boreholeFileFromDropzone: Blob[]) => {
- setSelectedFile(boreholeFileFromDropzone);
+ const handleCsvFileChange = useCallback(
+ (csvFileFromDropzone: Blob[]) => {
+ setSelectedFile(csvFileFromDropzone);
+ },
+ [setSelectedFile],
+ );
+ const handleJsonFileChange = useCallback(
+ (jsonFileFromDropzone: Blob[]) => {
+ setSelectedFile(jsonFileFromDropzone);
},
[setSelectedFile],
);
@@ -41,7 +51,15 @@ const ImportModalContent = ({ setSelectedFile }: ImportContentProps) => {
- {capitalizeFirstLetter(t("boreholes"))}
+ {capitalizeFirstLetter(t("importBoreholes"))}
+
+ {"CSV"}
{t("csvFormatExplanation")}
@@ -60,13 +78,28 @@ const ImportModalContent = ({ setSelectedFile }: ImportContentProps) => {
)}
+
+ {"JSON"}
+
+
+
>