diff --git a/docker-compose.yml b/docker-compose.yml index 7d66aa03..481d10bb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -69,8 +69,8 @@ services: volumes: - ./src/Geopilot.Api/Uploads:/uploads - ./src/Geopilot.Api/Persistent:/assets - - ./README.md:/public/info-hilfe.md - - ./LICENSE:/public/nutzungsbestimmungen.md + - ./README.md:/public/info.md + - ./LICENSE:/public/terms-of-use.md extra_hosts: - "localhost:host-gateway" depends_on: diff --git a/src/Geopilot.Api/ContextExtensions.cs b/src/Geopilot.Api/ContextExtensions.cs index 3bf5c15b..d4f7a072 100644 --- a/src/Geopilot.Api/ContextExtensions.cs +++ b/src/Geopilot.Api/ContextExtensions.cs @@ -35,7 +35,7 @@ public static void SeedTestData(this Context context) context.SeedMandates(); context.SeedDeliveries(); context.SeedAssets(); - context.AuthorizeFirstUser(); + context.AddOrganisationsToDefaultUsers(); transaction.Commit(); } @@ -187,15 +187,15 @@ public static void SeedAssets(this Context context) context.SaveChanges(); } - public static void AuthorizeFirstUser(this Context context) + public static void AddOrganisationsToDefaultUsers(this Context context) { - var user = context.Users.OrderBy(u => u.Id).First(); - var organisation = context.Organisations.OrderBy(o => o.Id).First(); - var mandates = context.Mandates.OrderBy(m => m.Id).Skip(1); + var admin = context.Users.Single(user => user.Email == "admin@geopilot.ch"); + var adminOrganisations = context.Organisations.OrderBy(o => o.Id).Skip(1); + admin.Organisations.AddRange(adminOrganisations); - user.IsAdmin = true; - user.Organisations.Add(organisation); - organisation.Mandates.AddRange(mandates); + var user = context.Users.Single(user => user.Email == "user@geopilot.ch"); + var userOrganistions = context.Organisations.OrderBy(o => o.Id).Take(2); + user.Organisations.AddRange(userOrganistions); context.SaveChanges(); } diff --git a/src/Geopilot.Api/Controllers/DeliveryController.cs b/src/Geopilot.Api/Controllers/DeliveryController.cs index 0a318865..f40edcf2 100644 --- a/src/Geopilot.Api/Controllers/DeliveryController.cs +++ b/src/Geopilot.Api/Controllers/DeliveryController.cs @@ -43,6 +43,7 @@ public DeliveryController(ILogger logger, Context context, I [Authorize(Policy = GeopilotPolicies.User)] [SwaggerResponse(StatusCodes.Status201Created, "The delivery was created successfully.")] [SwaggerResponse(StatusCodes.Status400BadRequest, "The server cannot process the request due to invalid or malformed request.", typeof(ValidationProblemDetails), "application/json")] + [SwaggerResponse(StatusCodes.Status401Unauthorized, "The user is not authorized.")] [SwaggerResponse(StatusCodes.Status404NotFound, "The validation job or mandate could not be found.")] [SwaggerResponse(StatusCodes.Status500InternalServerError, "The server encountered an unexpected condition that prevented it from fulfilling the request. Likely there was an error persisting the assets.", typeof(ProblemDetails), "application/json")] public async Task Create(DeliveryRequest declaration) @@ -69,8 +70,14 @@ public async Task Create(DeliveryRequest declaration) if (mandate is null || !mandate.Organisations.SelectMany(u => u.Users).Any(u => u.Id == user.Id)) { - logger.LogTrace("User <{AuthIdentifier}> is not authorized to create a delivery for mandate with id <{MandateId}>.", user.AuthIdentifier, declaration.MandateId); - return NotFound($"Mandate with id <{declaration.MandateId}> not found or user is not authorized."); + logger.LogTrace($"Mandate with id <{declaration.MandateId}> not found."); + return NotFound($"Mandate with id <{declaration.MandateId}> not found."); + } + + if (!mandate.Organisations.SelectMany(u => u.Users).Any(u => u.Id == user.Id)) + { + logger.LogTrace($"User <{user.AuthIdentifier}> is not authorized to create a delivery for mandate with id <{declaration.MandateId}>."); + return Unauthorized($"User is not authorized for mandate with id <{declaration.MandateId}>"); } var precursorDelivery = declaration.PrecursorDeliveryId.HasValue ? diff --git a/src/Geopilot.Api/Controllers/MandateController.cs b/src/Geopilot.Api/Controllers/MandateController.cs index 961ba0fe..c34f27ba 100644 --- a/src/Geopilot.Api/Controllers/MandateController.cs +++ b/src/Geopilot.Api/Controllers/MandateController.cs @@ -50,7 +50,7 @@ public async Task Get( var user = await context.GetUserByPrincipalAsync(User); var mandates = context.MandatesWithIncludes.AsNoTracking(); - if (!user.IsAdmin) + if (!user.IsAdmin || jobId != default) { mandates = mandates.Where(m => m.Organisations.SelectMany(o => o.Users).Any(u => u.Id == user.Id)); } diff --git a/src/Geopilot.Frontend/cypress/e2e/app.cy.js b/src/Geopilot.Frontend/cypress/e2e/app.cy.js index e4dc315b..c8ff4362 100644 --- a/src/Geopilot.Frontend/cypress/e2e/app.cy.js +++ b/src/Geopilot.Frontend/cypress/e2e/app.cy.js @@ -1,5 +1,6 @@ import { isSelectedNavItem, + loadWithoutAuth, loginAsAdmin, loginAsNewUser, loginAsUploader, @@ -11,12 +12,8 @@ import { selectAdminNavItem } from "./helpers/adminHelpers.js"; describe("General app tests", () => { it("shows no login button if auth settings could not be loaded", () => { - cy.visit("/"); - cy.intercept("/api/v1/user/auth", { - statusCode: 200, - body: { authority: "", clientId: "" }, - }); - cy.get('[data-cy="loggedInUser-button"]').should("not.exist"); + loadWithoutAuth(); + cy.get('[data-cy="login-button"]').should("not.exist"); }); it.skip("registers new users and logs them in", () => { diff --git a/src/Geopilot.Frontend/cypress/e2e/delivery.cy.js b/src/Geopilot.Frontend/cypress/e2e/delivery.cy.js new file mode 100644 index 00000000..ecf7f6d8 --- /dev/null +++ b/src/Geopilot.Frontend/cypress/e2e/delivery.cy.js @@ -0,0 +1,440 @@ +import { loadWithoutAuth, loginAsUploader } from "./helpers/appHelpers.js"; +import { clickCancel } from "./helpers/buttonHelpers.js"; +import { hasError, setInput, setSelect, toggleCheckbox } from "./helpers/formHelpers.js"; + +const fileNameExists = (filePath, success) => { + const fileName = filePath.split("/").pop(); + if (success) { + cy.contains(fileName); + } else { + cy.contains(fileName).should("not.exist"); + } +}; + +const addFile = (filePath, success) => { + cy.get('[data-cy="file-dropzone"]').attachFile(filePath, { subjectType: "drag-n-drop" }); + Array.isArray(filePath) ? filePath.forEach(file => fileNameExists(file, success)) : fileNameExists(filePath, success); +}; + +const uploadFile = () => { + cy.get('[data-cy="acceptTermsOfUse-formCheckbox"]').then($checkbox => { + if (!$checkbox.hasClass("Mui-checked")) { + toggleCheckbox("acceptTermsOfUse"); + } + cy.get('[data-cy="upload-button"]').click(); + stepIsLoading("upload"); + }); +}; + +const resetDelivery = activeStep => { + cy.get(`[data-cy="${activeStep}-step"] [data-cy="cancel-button"]`).should("exist"); + clickCancel(`${activeStep}-step`); + stepIsActive("upload"); + stepIsCompleted("upload", false); + stepIsActive("validate", false); + stepIsCompleted("validate", false); + stepIsActive("submit", false); + stepIsCompleted("submit", false); + stepIsActive("done", false); + stepIsCompleted("done", false); + cy.get('[data-cy="upload-button"]').should("be.disabled"); +}; + +const stepIsActive = (stepName, isActive = true) => { + if (isActive) { + cy.get(`[data-cy="${stepName}-step"] .MuiStepLabel-iconContainer.Mui-active`).should("exist"); + } else { + cy.get(`[data-cy="${stepName}-step"] .MuiStepLabel-iconContainer.Mui-active`).should("not.exist"); + } +}; + +const stepIsLoading = (stepName, isLoading = true) => { + if (isLoading) { + cy.get(`[data-cy="${stepName}-step"] [data-cy="stepper-loading"]`).should("exist"); + } else { + cy.get(`[data-cy="${stepName}-step"] [data-cy="stepper-loading"]`).should("not.exist"); + } +}; + +const stepHasError = (stepName, hasError, errorText) => { + if (hasError) { + cy.get(`[data-cy="${stepName}-step"] [data-cy="stepper-error"]`).should("exist"); + cy.get(`[data-cy="${stepName}-step"]`).contains(errorText); + } else { + cy.get(`[data-cy="${stepName}-step"] [data-cy="stepper-error"]`).should("not.exist"); + } +}; + +const stepIsCompleted = (stepName, isCompleted = true) => { + if (isCompleted) { + cy.get(`[data-cy="${stepName}-step"] [data-cy="stepper-completed"]`).should("exist"); + } else { + cy.get(`[data-cy="${stepName}-step"] [data-cy="stepper-completed"]`).should("not.exist"); + } +}; + +const mockUploadSuccess = () => { + cy.intercept({ url: "/api/v1/validation", method: "POST" }, req => { + req.reply({ + statusCode: 201, + body: { + jobId: "d49ba857-5db5-45a0-b838-9d41cc7d8d64", + status: "processing", + validatorResults: { + ilicheck: { + status: "processing", + statusMessage: "Die Datei wird validiert...", + logFiles: {}, + }, + }, + }, + delay: 500, + }); + }).as("upload"); +}; + +const mockValidationSuccess = () => { + cy.intercept({ url: "/api/v1/validation/d49ba857-5db5-45a0-b838-9d41cc7d8d64", method: "GET" }, req => { + req.reply({ + statusCode: 200, + body: { + jobId: "d49ba857-5db5-45a0-b838-9d41cc7d8d64", + status: "completed", + validatorResults: { + ilicheck: { + status: "completed", + statusMessage: "Die Daten sind modellkonform.", + logFiles: { + Log: "log.log", + "Xtf-Log": "log.xtf", + }, + }, + }, + }, + delay: 500, + }); + }).as("validation"); +}; + +const mockMandates = () => { + cy.intercept({ url: "/api/v1/mandate?jobId=d49ba857-5db5-45a0-b838-9d41cc7d8d64", method: "GET" }, req => { + req.reply({ + statusCode: 200, + body: [ + { + id: 1, + name: "Handmade Soft Cheese", + }, + { + id: 5, + name: "Licensed Frozen Towels", + }, + { + id: 9, + name: "Unbranded Wooden Pants", + }, + ], + delay: 500, + }); + }).as("mandates"); +}; + +describe("Delivery tests", () => { + beforeEach(() => { + mockUploadSuccess(); + }); + + it("shows only validation steps if auth settings could not be loaded", () => { + loadWithoutAuth(); + cy.get('[data-cy="upload-step"]').should("exist"); + cy.get('[data-cy="validate-step"]').should("exist"); + cy.get('[data-cy="submit-step"]').should("not.exist"); + cy.get('[data-cy="done-step"]').should("not.exist"); + stepIsActive("upload"); + + // Limit the file types to a few extensions + cy.intercept("/api/v1/validation", { + statusCode: 200, + body: { allowedFileExtensions: [".csv", ".gpkg", ".itf", ".xml", ".xtf", ".zip"] }, + }).as("fileExtensions"); + cy.wait("@fileExtensions"); + cy.contains(".csv, .gpkg, .itf, .xml, .xtf or .zip (max. 200 MB)"); + + addFile("deliveryFiles/invalid-type.png", false); + stepHasError("upload", true, "The file type is not supported"); + + addFile(["deliveryFiles/ilimodels_invalid.xml", "deliveryFiles/ilimodels_valid.xml"], false); + stepHasError("upload", true, "Only one file can be checked at a time"); + + // Cypress doesn't support attaching large files, so we cannot test the file size validation here. + }); + + it("shows validation error: invalid structure", () => { + cy.intercept({ url: "/api/v1/validation/d49ba857-5db5-45a0-b838-9d41cc7d8d64", method: "GET" }, req => { + req.reply({ + statusCode: 200, + body: { + jobId: "b058ad11-7dc2-4456-9099-e525116d7e9b", + status: "completedWithErrors", + validatorResults: { + ilicheck: { + status: "completedWithErrors", + statusMessage: "Die XML-Struktur der Transferdatei ist ungültig.", + logFiles: {}, + }, + }, + }, + delay: 500, + }); + }).as("validation"); + + loginAsUploader(); + addFile("deliveryFiles/ilimodels_invalid.xml", true); + uploadFile(); + cy.wait("@upload"); + stepIsLoading("validate", true); + cy.get('[data-cy="validate-step"]').contains("The file is currently being validated with ilicheck..."); + cy.wait("@validation"); + stepIsLoading("validate", false); + stepHasError("validate", true, "Completed with errors"); + cy.get('[data-cy="validate-step"]').contains("Die XML-Struktur der Transferdatei ist ungültig."); + cy.get('[data-cy="Log-button"').should("not.exist"); + cy.get('[data-cy="Xtf-Log-button"').should("not.exist"); + stepIsActive("submit", false); // Should not be active if validation has errors + }); + + it("shows validation error: not conform", () => { + cy.intercept({ url: "/api/v1/validation/d49ba857-5db5-45a0-b838-9d41cc7d8d64", method: "GET" }, req => { + req.reply({ + statusCode: 200, + body: { + jobId: "d49ba857-5db5-45a0-b838-9d41cc7d8d64", + status: "completedWithErrors", + validatorResults: { + ilicheck: { + status: "completedWithErrors", + statusMessage: "Die Daten sind nicht modellkonform.", + logFiles: { + Log: "log.log", + "Xtf-Log": "log.xtf", + }, + }, + }, + }, + delay: 500, + }); + }).as("validation"); + + loginAsUploader(); + addFile("deliveryFiles/ilimodels_not_conform.xml", true); + uploadFile(); + cy.wait("@upload"); + stepIsLoading("validate", true); + cy.get('[data-cy="validate-step"]').contains("The file is currently being validated with ilicheck..."); + cy.wait("@validation"); + stepIsLoading("validate", false); + stepHasError("validate", true, "Completed with errors"); + cy.get('[data-cy="validate-step"]').contains("Die Daten sind nicht modellkonform."); + cy.get('[data-cy="Log-button"').should("exist"); + cy.get('[data-cy="Xtf-Log-button"').should("exist"); + stepIsActive("submit", false); // Should not be active if validation has errors + }); + + it("can submit a delivery", () => { + mockValidationSuccess(); + mockMandates(); + cy.intercept({ url: "/api/v1/delivery", method: "POST" }, req => { + req.reply({ + statusCode: 201, + body: { + id: 43, + jobId: "d49ba857-5db5-45a0-b838-9d41cc7d8d64", + }, + delay: 500, + }); + }).as("submit"); + + loginAsUploader(); + // All steps are visible + cy.get('[data-cy="upload-step"]').should("exist"); + cy.get('[data-cy="validate-step"]').should("exist"); + cy.get('[data-cy="submit-step"]').should("exist"); + cy.get('[data-cy="done-step"]').should("exist"); + stepIsActive("upload"); + + // All file types are allowed + addFile("deliveryFiles/invalid-type.png", true); + stepHasError("upload", false); + + // Selected file can be removed + cy.get('[data-cy="file-remove-button"]').click(); + cy.contains("invalid-type.png").should("not.exist"); + + // Can upload a file once the terms of use are accepted and the file is valid + cy.get('[data-cy="upload-button"]').should("be.disabled"); + addFile("deliveryFiles/ilimodels_not_conform.xml", true); + cy.get('[data-cy="upload-button"]').should("be.disabled"); + toggleCheckbox("acceptTermsOfUse"); + cy.get('[data-cy="upload-button"]').should("not.be.disabled"); + uploadFile(); + + // Can cancel the upload which will reset the form + resetDelivery("upload"); + cy.contains("ilimodels_not_conform.xml").should("not.exist"); + + // Validation starts automatically after a file is uploaded + addFile("deliveryFiles/ilimodels_not_conform.xml", true); + cy.get('[data-cy="upload-button"]').should("not.be.disabled"); + uploadFile(); + cy.wait("@upload"); + stepIsLoading("upload", false); + stepIsCompleted("upload"); + cy.get('[data-cy="upload-step"]').contains("ilimodels_not_conform.xml"); + stepIsActive("validate"); + stepIsLoading("validate"); + cy.get('[data-cy="validate-step"]').contains("The file is currently being validated with ilicheck..."); + + // Validation can be cancelled + resetDelivery("validate"); + cy.get('[data-cy="upload-step"]').contains("ilimodels_not_conform.xml").should("not.exist"); + + // Submit is active if validation is successful + addFile("deliveryFiles/ilimodels_valid.xml", true); + uploadFile(); + cy.wait("@upload"); + stepIsLoading("validate", true); + cy.get('[data-cy="validate-step"]').contains("The file is currently being validated with ilicheck..."); + cy.wait("@validation"); + stepIsLoading("validate", false); + stepHasError("validate", false); + cy.get('[data-cy="validate-step"]').contains("Die Daten sind modellkonform."); + cy.get('[data-cy="Log-button"').should("exist"); + cy.get('[data-cy="Xtf-Log-button"').should("exist"); + cy.get('[data-cy="validate-step"] [data-cy="cancel-button"]').should("not.exist"); + stepIsCompleted("validate"); + stepIsActive("submit"); + + // Submit can be cancelled, which will return to step 1 with a reset form + resetDelivery("submit"); + + // Add delivery with minimal form + addFile("deliveryFiles/ilimodels_valid.xml", true); + uploadFile(); + cy.wait("@upload"); + cy.wait("@validation"); + stepIsCompleted("validate"); + stepIsActive("submit"); + cy.wait("@mandates"); + + cy.get('[data-cy="createDelivery-button"]').should("be.disabled"); + setSelect("mandate", 1, 4); + cy.get('[data-cy="createDelivery-button"]').should("be.enabled"); + setSelect("mandate", 0); + cy.get('[data-cy="createDelivery-button"]').should("be.disabled"); + hasError("mandate"); + setSelect("mandate", 2); + setSelect("predecessor", 2); + setSelect("predecessor", 0); + hasError("predecessor", false); + cy.get('[data-cy="createDelivery-button"]').should("be.enabled"); + cy.get('[data-cy="createDelivery-button"]').click(); + stepIsLoading("submit"); + + cy.wait("@submit"); + stepIsCompleted("submit"); + stepIsActive("done"); + cy.get('[data-cy="done-step"]').contains("The delivery was completed successfully."); + + // Can restart the delivery process after submitting was successful + cy.get('[data-cy="addAnotherDelivery-button"]').should("exist"); + cy.get('[data-cy="addAnotherDelivery-button"]').click(); + stepIsActive("upload"); + stepIsCompleted("upload", false); + stepIsActive("validate", false); + stepIsCompleted("validate", false); + stepIsActive("submit", false); + stepIsCompleted("submit", false); + stepIsActive("done", false); + stepIsCompleted("done", false); + cy.get('[data-cy="upload-button"]').should("be.disabled"); + + // Add delivery with completed form + addFile("deliveryFiles/ilimodels_valid.xml", true); + uploadFile(); + cy.wait("@upload"); + cy.wait("@validation"); + stepIsCompleted("validate"); + stepIsActive("submit"); + + setSelect("mandate", 1); + setSelect("predecessor", 1); + toggleCheckbox("isPartial"); + setInput("comment", "This is a test comment."); + cy.get('[data-cy="createDelivery-button"]').click(); + stepIsLoading("submit"); + cy.wait("@submit"); + stepIsCompleted("submit"); + stepIsActive("done"); + cy.get('[data-cy="done-step"]').contains("The delivery was completed successfully."); + }); + + it("can log in during the delivery process", () => { + mockValidationSuccess(); + + cy.visit("/"); + cy.get('[data-cy="logIn-button"]').should("exist"); + + cy.get('[data-cy="upload-step"]').should("exist"); + cy.get('[data-cy="validate-step"]').should("exist"); + cy.get('[data-cy="submit-step"]').should("exist"); + cy.get('[data-cy="done-step"]').should("exist"); + stepIsActive("upload"); + + addFile("deliveryFiles/ilimodels_valid.xml", true); + uploadFile(); + cy.wait("@upload").its("response.statusCode").should("eq", 201); + cy.wait("@validation").its("response.statusCode").should("eq", 200); + stepIsCompleted("upload"); + stepIsCompleted("validate"); + stepIsActive("submit"); + cy.get('[data-cy="logInForDelivery-button"]').should("exist"); + }); + + it("correctly extracts error messages from the response", () => { + mockValidationSuccess(); + mockMandates(); + + let currentResponseIndex = 0; + const responses = [ + { statusCode: 500, body: { detail: "Internal Server Error" } }, + { statusCode: 404, body: "Not found" }, + ]; + + cy.intercept({ url: "/api/v1/delivery", method: "POST" }, req => { + const currentResponse = responses[currentResponseIndex]; + req.reply({ + statusCode: currentResponse.statusCode, + body: currentResponse.body, + }); + + currentResponseIndex = (currentResponseIndex + 1) % responses.length; + }).as("deliveryRequest"); + + loginAsUploader(); + addFile("deliveryFiles/ilimodels_valid.xml", true); + uploadFile(); + cy.wait("@upload"); + cy.wait("@validation"); + cy.wait("@mandates"); + + setSelect("mandate", 1); + + cy.get('[data-cy="createDelivery-button"]').click(); + cy.wait("@deliveryRequest").its("response.statusCode").should("eq", 500); + stepHasError("submit", true, "Internal Server Error"); + + cy.get('[data-cy="createDelivery-button"]').click(); + cy.wait("@deliveryRequest").its("response.statusCode").should("eq", 404); + stepHasError("submit", true, "Not found"); + }); +}); diff --git a/src/Geopilot.Frontend/cypress/e2e/helpers/adminHelpers.js b/src/Geopilot.Frontend/cypress/e2e/helpers/adminHelpers.js index 84842ab7..ccb82925 100644 --- a/src/Geopilot.Frontend/cypress/e2e/helpers/adminHelpers.js +++ b/src/Geopilot.Frontend/cypress/e2e/helpers/adminHelpers.js @@ -1,5 +1,9 @@ import { createBaseSelector, isSelectedNavItem } from "./appHelpers.js"; +/** + * Selects an admin navigation item. + * @param item The item to select (delivery-overview, users, mandates, organisations). + */ export const selectAdminNavItem = item => { const selector = createBaseSelector("admin-navigation") + `[data-cy="admin-${item}-nav"]`; cy.get(selector).click(); diff --git a/src/Geopilot.Frontend/cypress/e2e/helpers/appHelpers.js b/src/Geopilot.Frontend/cypress/e2e/helpers/appHelpers.js index 0d25dc56..1761910c 100644 --- a/src/Geopilot.Frontend/cypress/e2e/helpers/appHelpers.js +++ b/src/Geopilot.Frontend/cypress/e2e/helpers/appHelpers.js @@ -2,8 +2,16 @@ export const interceptApiCalls = () => { cy.intercept("/api/v1/user/auth").as("auth"); cy.intercept("/api/v1/version").as("version"); cy.intercept("/api/v1/user/self").as("self"); + cy.intercept("terms-of-use.md", { + statusCode: 200, + fixture: "../fixtures/terms-of-use.md", + }).as("termsOfUse"); }; +/** + * Logs in a user and sets the session token. + * @param user + */ export const login = user => { cy.session( ["login", user], @@ -11,7 +19,7 @@ export const login = user => { cy.intercept("http://localhost:4011/realms/geopilot/protocol/openid-connect/token").as("token"); cy.visit("/"); cy.wait("@version"); - cy.get('[data-cy="login-button"]').click(); + cy.get('[data-cy="logIn-button"]').click(); cy.origin("http://localhost:4011", { args: { user } }, ({ user }) => { cy.get("#username").type(user); cy.get("#password").type("geopilot_password"); @@ -37,32 +45,68 @@ export const login = user => { ); }; +/** + * Logs in with the admin user and navigates to the home page. + */ export const loginAsAdmin = () => { login("admin"); cy.visit("/"); + cy.get('[data-cy="loggedInUser-button"]').should("exist"); }; +/** + * Logs in with the uploader user and navigates to the home page. + */ export const loginAsUploader = () => { login("uploader"); cy.visit("/"); + cy.get('[data-cy="loggedInUser-button"]').should("exist"); + cy.wait("@termsOfUse"); }; +/** + * Logs in with the new user and navigates to the home page. + */ export const loginAsNewUser = () => { login("newuser"); cy.visit("/"); + cy.get('[data-cy="loggedInUser-button"]').should("exist"); }; +/** + * Loads the application without authentication so that no login is available. + */ +export const loadWithoutAuth = () => { + cy.visit("/"); + cy.intercept("/api/v1/user/auth", { + statusCode: 200, + body: { authority: "", clientId: "" }, + }); +}; + +/** + * Logs out the user. + */ export const logout = () => { openToolMenu(); - cy.get('[data-cy="logout-button"]').click(); + cy.get('[data-cy="logOut-button"]').click(); }; +/** + * Selects a language from the language selector. + * @param language The language to select (de, fr, it, en). + */ export const selectLanguage = language => { cy.get('[data-cy="language-selector"]').click({ force: true }); cy.get(`[data-cy="language-${language.toLowerCase()}"]`).click({ force: true }); cy.wait(1000); }; +/** + * Creates a base selector for an element with an optional parent. + * @param {string} parent (optional) The parent of the element. + * @returns {string} The base selector. + */ export const createBaseSelector = parent => { if (parent) { return `[data-cy="${parent}"] `; @@ -71,17 +115,29 @@ export const createBaseSelector = parent => { } }; +/** + * Opens the tool navigation. Requires the user to be logged in. + */ export const openToolMenu = () => { if (!cy.get('[data-cy="tool-navigation"]').should("be.visible")) { cy.get('[data-cy="loggedInUser-button"]').click(); } }; +/** + * Opens the tool navigation to switch between delivery, administation and stac browser. Requires the user to be logged in. + * @param tool The tool to open (delivery, admin, stacBrowser). + */ export const openTool = tool => { openToolMenu(); cy.get(`[data-cy="${tool}-nav"]`).click(); }; +/** + * Checks if a navigation item is selected. + * @param item The item to check. + * @param {string} parent (optional) The parent of the item. + */ export const isSelectedNavItem = (item, parent) => { const selector = createBaseSelector(parent) + `[data-cy="${item}"]`; cy.get(selector).should("have.class", "Mui-selected"); diff --git a/src/Geopilot.Frontend/cypress/e2e/helpers/buttonHelpers.js b/src/Geopilot.Frontend/cypress/e2e/helpers/buttonHelpers.js new file mode 100644 index 00000000..f7b76fcc --- /dev/null +++ b/src/Geopilot.Frontend/cypress/e2e/helpers/buttonHelpers.js @@ -0,0 +1,10 @@ +import { createBaseSelector } from "./appHelpers.js"; + +/** + * Clicks the cancel button. + * @param {string} parent (optional) The parent of the button. + */ +export const clickCancel = parent => { + const selector = createBaseSelector(parent) + '[data-cy="cancel-button"]'; + cy.get(selector).click(); +}; diff --git a/src/Geopilot.Frontend/cypress/e2e/helpers/formHelpers.js b/src/Geopilot.Frontend/cypress/e2e/helpers/formHelpers.js new file mode 100644 index 00000000..cd49124e --- /dev/null +++ b/src/Geopilot.Frontend/cypress/e2e/helpers/formHelpers.js @@ -0,0 +1,86 @@ +import { createBaseSelector } from "./appHelpers"; + +/** + * Checks if a form element has an error. + * @param {string} fieldName The name of the form element. + * @param {boolean} hasError The expected error state. + * @param {string} parent (optional) The parent of the form element. + */ +export const hasError = (fieldName, hasError = true, parent) => { + const selector = createBaseSelector(parent) + `[data-cy^="${fieldName}-form"] .Mui-error`; + if (hasError) { + cy.get(selector).should("exist"); + } else { + cy.get(selector).should("not.exist"); + } +}; + +/** + * Sets the value for an input form element. + * @param {string} fieldName The name of the input field. + * @param {string} value The text to type into the input field. + * @param {string} parent (optional) The parent of the form element. + */ +export const setInput = (fieldName, value, parent) => { + const selector = createBaseSelector(parent) + `[data-cy="${fieldName}-formInput"]`; + cy.get(selector) + .click() + .then(() => { + cy.focused().clear(); + cy.get(selector).type(value, { + delay: 10, + }); + }); +}; + +/** + * Opens the dropdown for a select form element. + * @param {string} selector The selector for the form element. + */ +export const openDropdown = selector => { + cy.get(selector).find('[role="combobox"]').click(); +}; + +/** + * Selects an option from a dropdown. + * @param {number} index The index of the option to select. + */ +export const selectDropdownOption = index => { + cy.get('.MuiPaper-elevation [role="listbox"]').find('[role="option"]').eq(index).click(); +}; + +/** + * Evaluates the number of options in a dropdown. + * @param {number} length The expected number of options in the dropdown. + */ +export const evaluateDropdownOptionsLength = length => { + cy.get('.MuiPaper-elevation [role="listbox"]').should($listbox => { + expect($listbox.find('[role="option"]')).to.have.length(length); + }); +}; + +/** + * Sets the value for a select form element. + * @param {string} fieldName The name of the select field. + * @param {number} index The index of the option to select. + * @param {number} expected (optional) The expected number of options in the dropdown. + * @param {string} parent (optional) The parent of the form element. + */ +export const setSelect = (fieldName, index, expected, parent) => { + const selector = createBaseSelector(parent) + `[data-cy="${fieldName}-formSelect"]`; + openDropdown(selector); + if (expected != null) { + evaluateDropdownOptionsLength(expected); + } + selectDropdownOption(index); +}; + +/** + * Toggles the checkbox for a checkbox form element. + * @param {string} fieldName The name of the checkbox field. + * @param {string} parent (optional) The parent of the form element. + */ +export const toggleCheckbox = (fieldName, parent) => { + const selector = createBaseSelector(parent) + `[data-cy="${fieldName}-formCheckbox"]`; + cy.get(selector).click(); +}; diff --git a/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_invalid.xml b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_invalid.xml new file mode 100644 index 00000000..15d8651a --- /dev/null +++ b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_invalid.xml @@ -0,0 +1,1361 @@ + + + + + + ... ... + + + + + + IliRepository09 +ili2_3asdfasdf + + obsolete/IliRepository09-20120220_o0.ili +2009-11-19 + + mailto:info@interlis.ch +https://www.interlis.ch + + b2bd836d761de6a1324e3a6c3f7d3650 ... + + ili2_3 + + obsolete/IliRepository09-20120220_o1.ili +2009-12-01 + + 2009-11-19 +mailto:info@interlis.ch + + https://www.interlis.ch +d4ca2847fee23bcc4332918394e4830b ... + + IliSite09 +ili2_3 +2009-11-19 + + mailto:info@interlis.ch +https://www.interlis.ch + + 6fa61b0163bbafa5df541fc86b142948 ... + + IlisMeta07 +ili2_3 + + obsolete/IlisMeta07_o0.ili +2008-02-07 +http://interlis.ch + + mailto:info@interlis.ch +http://www.interlis.ch + + c5d11adfe45b53d3962bc376f7dc8616 ... + + AbstractSymbology +ili2_2 + + obsolete/AbstractSymbology-20200218_o0.ili +2003-03-18 + + mailto:info@interlis.ch +https://www.interlis.ch + + bcdd38ff69b6e9aa62302a4c1536310f ... + + CoordSys +ili2_2 + + obsolete/CoordSys-20151123_o0.ili +2003-03-18 + + mailto:info@interlis.ch +https://www.interlis.ch + + d8b5aa87bf3f9ded17caeb5a0cbffd7c ... + + RoadsExdm2ben_10 +ili2_2 + + refhb22/RoadsExdm2ben-20030226.ili +2003-02-26 + + mailto:info@interlis.ch +https://www.interlis.ch + + cfa0cfda12d0d1b1911944682b32e89d ... + + RoadsExdm2ien_10 +ili2_2 + + obsolete/RoadsExdm2ien-20170404_o0.ili +2003-02-26 + + + RoadsExdm2ben_10 ... ... + + mailto:info@interlis.ch +https://www.interlis.ch + + df7aa897a7a3800d4e0abeb9ad710cbd ... + + RoadsExgm2ien_10 +ili2_2 + + refhb22/RoadsExgm2ien-20030226.ili +2003-02-26 + + + RoadsExdm2ben_10 ... + + RoadsExdm2ien_10 ... + + StandardSymbology ... ... + + mailto:info@interlis.ch +https://www.interlis.ch + + 15911c80234a512b78cbdea1b51c9ea7 ... + + StandardSymbology +ili2_2 + + obsolete/StandardSymbology-20160120_o0.ili +2003-03-18 + + + AbstractSymbology ... ... + + mailto:info@interlis.ch +https://www.interlis.ch + + 223ff253d6b352f9a6b6b0e6686bfbcb ... + + Time +ili2_2 + + obsolete/Time-20170412_o0.ili +2003-03-18 + + + Units ... ... + + mailto:info@interlis.ch +https://www.interlis.ch + + f6201ebafb641f2e78893ab6919dd9cc ... + + Units +ili2_2 + + obsolete/Units-20120219_o0.ili +2003-03-18 + + mailto:info@interlis.ch +https://www.interlis.ch + + 71a8ccd32bb3dd51f1e666aa833d58f4 ... + + AbstractSymbology +ili2_3 + + obsolete/AbstractSymbology-20200219_o0.ili +2005-06-16 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +be66beba06650e6083ea009aca792ecb ... + + CoordSys +ili2_3 + + obsolete/CoordSys-20151124_o0.ili +2005-06-16 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +520e0544a9833f216b7d84ba7c89262c ... + + RoadsExdm2ben +ili2_3 + + refhb23/RoadsExdm2ben-20050616.ili +2005-06-16 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +33b3b2c8d518061b8f01168cd1ee65a1 ... + + RoadsExdm2ien +ili2_3 + + obsolete/RoadsExdm2ien-20170405_o0.ili +2005-06-16 + + + RoadsExdm2ben ... ... + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +7862b3381dc90d857ed7f8e28a20bd41 ... + + RoadsExgm2ien +ili2_3 + + refhb23/RoadsExgm2ien-20050616.ili +2005-06-16 + + + RoadsExdm2ien ... + + StandardSymbology ... + + RoadsExdm2ben ... ... + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +c207c14dade2c4b857b6b4151e66bc10 ... + + StandardSymbology +ili2_3 + + obsolete/StandardSymbology-20160121_o0.ili +2005-06-16 + + + AbstractSymbology ... ... + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +b712287b7269242ffe0ab6d4d63448a3 ... + + Time +ili2_3 + + obsolete/Time-20200219_o0.ili +2005-06-16 + + + Units ... ... + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +3d3bd4f8367a5bc1ba3395f0e1cf882c ... + + Units +ili2_3 + + obsolete/Units-20120220_o0.ili +2005-06-16 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +66ad28cb2d65ffacdee360c6f4f6cb69 ... + + GM03Core +ili2_2 + + obsolete/GM03_V23_o0.ili +2005-04-15 +2005-04-15 + + + Units ... + + CodeISO ... ... + + mailto:info@interlis.ch +http://www.geocat.ch + + 719211af31d874eafb20fcc1af5cce25 ... + + GM03Comprehensive +ili2_2 + + geocat.ch/GM03_V23.ili +2005-04-15 +2005-04-15 + + + GM03Core ... + + Units ... + + CodeISO ... ... + + mailto:info@interlis.ch +http://www.geocat.ch + + 99c34fcc6409d7effe3892dd7ee2204c ... + + CodeISO +ili2_2 + + geocat.ch/CodeISO.ili +2005-04-15 +2005-04-15 + + mailto:info@interlis.ch +http://www.geocat.ch + + 5f1ca062b739f7c034b03477344da9b2 ... + + GM03_2Core +ili2_3 + + obsolete/GM03_2_o0.ili +20081211 +2008-12-11 + + + CodeISO ... + + Units ... ... + + http://www.kogis.ch +mailto:geocat@swisstopo.ch + + https://www.geocat.ch +656111cd9083881f2fecce0a3f308814 ... + + GM03_2Comprehensive +ili2_3 + + geocat.ch/GM03_2.ili +20081211 +2008-12-11 + + + Units ... + + CodeISO ... + + GM03_2Core ... ... + + http://www.kogis.ch +mailto:geocat@swisstopo.ch + + https://www.geocat.ch +1dc1e126ac75b9f6c69774485861a1dc ... + + CodeISO +ili2_3 + + geocat.ch/CodeISO_2.ili +20060808 +2006-08-08 + + http://www.kogis.ch +mailto:geocat@swisstopo.ch + + https://www.geocat.ch +00bc9fa4a6e6b885dc42490853178be3 ... + + GM03_2_1Core +ili2_3 + + obsolete/GM03_2_1_o0.ili +20130121 +2013-05-14 + + + Units ... + + CodeISO ... ... + + http://www.kogis.ch +mailto:geocat@swisstopo.ch + + https://www.geocat.ch +1c326df8e57bf403993c3788d00c7351 ... + + GM03_2_1Comprehensive +ili2_3 + + geocat.ch/GM03_2_1.ili +20130121 +2013-05-14 + + + Units ... + + CodeISO ... + + GM03_2_1Core ... ... + + http://www.kogis.ch +mailto:geocat@swisstopo.ch + + https://www.geocat.ch +ca8c7a94a827ff7566c5da800169ce64 ... + + IlisMeta07 +ili2_3 + + obsolete/IlisMeta07_o1.ili +2008-08-29 +2008-08-29 + + 2008-02-07 +http://interlis.ch + + mailto:info@interlis.ch +http://www.interlis.ch + + 2f476c335784de2fdcc27dd3e27ebcd8 ... + + Units +ili2_3 + + refhb23/Units-20120220.ili +2012-02-20 +2012-02-20 + + 2005-06-16 +http://www.interlis.ch/models + + mailto:info@interlis.ch +https://www.interlis.ch + + e2a198a0599581673d55bbc2c968a9f8 ... + + IlisMeta07 +ili2_3 + + obsolete/IlisMeta07_o2.ili +2011-12-22 +2011-12-22 + + 2008-08-29 +http://interlis.ch + + mailto:info@interlis.ch +http://www.interlis.ch + + 6d0346598e55c35dfe8e19a7c9c55bd5 ... + + IliRepository09 +ili2_3 + + core/IliRepository09-20120220.ili +2012-02-20 +2012-02-20 + + 2009-12-01 +mailto:info@interlis.ch + + https://www.interlis.ch +562cd4f06241c815a42fc5a92d340829 ... + + StandardSymbology +ili2_2 + + obsolete/StandardSymbology-20160120_o1.ili +2015-04-01 + + 2015-04-01 + + + AbstractSymbology ... ... + + 2003-03-18 +mailto:info@interlis.ch + + https://www.interlis.ch +8c32ce70641aae3f16904655bb6cc248 ... + + StandardSymbology +ili2_3 + + obsolete/StandardSymbology-20160121_o1.ili +2015-04-02 + + + AbstractSymbology ... ... + + 2005-06-16 +http://www.interlis.ch/models + + mailto:info@interlis.ch +http://www.interlis.ch + + 43a1d5c8d92d2f47a75f60d10cc35977 ... + + GM03Core +ili2_2 + + geocat.ch/GM03_V23.ili +2015-12-04 +2015-12-04 + + + Units ... + + CodeISO ... ... + + 2005-04-15 +mailto:geocat@swisstopo.ch + + http://www.geocat.ch +99c34fcc6409d7effe3892dd7ee2204c ... + + GM03_2Core +ili2_3 + + geocat.ch/GM03_2.ili +2015-12-04 +2015-12-04 + + + CodeISO ... + + Units ... ... + + 20081211 +http://www.kogis.ch + + mailto:geocat@swisstopo.ch +http://www.geocat.ch + + 1dc1e126ac75b9f6c69774485861a1dc ... + + GM03_2_1Core +ili2_3 + + geocat.ch/GM03_2_1.ili +2015-12-04 +2015-12-04 + + + Units ... + + CodeISO ... ... + + 20130121 +http://www.kogis.ch + + mailto:geocat@swisstopo.ch +http://www.geocat.ch + + ca8c7a94a827ff7566c5da800169ce64 ... + + CoordSys +ili2_3 + + refhb23/CoordSys-20151124.ili +2015-11-24 +2016-01-21 + + 2005-06-16 +http://www.interlis.ch/models + + mailto:info@interlis.ch +https://www.interlis.ch + + 56943b1a4277052f63a2ca401b1feabe ... + + INTERLIS_ext +ili2_3 + + obsolete/INTERLIS_ext_o0.ili +2016-02-11 +2016-02-12 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + http://www.interlis.ch +2f8d49c2dd6cd1bd2eacc6c652d8a865 ... + + StandardSymbology +ili2_3 + + refhb23/StandardSymbology-20160121.ili +2016-01-21 + + 2016-03-03 + + + AbstractSymbology ... ... + + 2015-04-02 +http://www.interlis.ch/models + + mailto:info@interlis.ch +https://www.interlis.ch + + ad21e1e4ae96465b4e30fd1815589158 ... + + INTERLIS_ext +ili2_3 + + refhb23/INTERLIS_ext.ili +2016-05-30 +2016-05-30 + + 2016-02-11 +http://www.interlis.ch/models + + mailto:info@interlis.ch +https://www.interlis.ch + + 56bef86426384cd3122963508e797a25 ... + + IliVErrors +ili2_3 + + tools/IliVErrors.ili +2016-06-10 +2017-01-12 + + mailto:info@interlis.ch +https://www.interlis.ch + + b41ab92753368ad32890d04bc77cc47f ... + + RoadsExdm2ien_10 +ili2_2 + + refhb22/RoadsExdm2ien-20170404.ili +2017-04-05 +2017-04-05 + + + RoadsExdm2ben_10 ... ... + + 2003-02-26 +mailto:info@interlis.ch + + https://www.interlis.ch +4b1341515b81821259048ba2bf1648a8 ... + + RoadsExdm2ien +ili2_3 + + refhb23/RoadsExdm2ien-20170405.ili +2017-04-05 +2017-04-05 + + + RoadsExdm2ben ... ... + + 2005-06-16 +http://www.interlis.ch/models + + mailto:info@interlis.ch +https://www.interlis.ch + + 83a4a01f18f184d74d86e07d27d59a80 ... + + CoordSys +ili2_2 + + refhb22/CoordSys-20151123.ili +2015-11-23 +2017-04-10 + + 2003-03-18 +mailto:info@interlis.ch + + https://www.interlis.ch +5e12919a0dff1fb23dd0d92a4873748d ... + + StandardSymbology +ili2_2 + + refhb22/StandardSymbology-20160120.ili +2016-01-20 + + 2017-04-10 + + + AbstractSymbology ... ... + + 2015-04-01 +mailto:info@interlis.ch + + https://www.interlis.ch +34f535881a0d89639be4d4db656ef929 ... + + Units +ili2_2 + + refhb22/Units-20120219.ili +2012-02-19 +2017-04-10 + + 2003-03-18 +mailto:info@interlis.ch + + https://www.interlis.ch +ce2f5833386b6b8b5acceef87f0b492a ... + + Time +ili2_2 + + refhb22/Time-20170412.ili +2017-04-12 +2017-04-13 + + + Units ... ... + + 2003-03-18 +mailto:info@interlis.ch + + https://www.interlis.ch +196c9799ac39d9f05d95e96cbdf0e481 ... + + Time +ili2_3 + + obsolete/Time-20200219_o1.ili +2017-04-13 +2017-04-13 + + + Units ... ... + + 2005-06-16 +http://www.interlis.ch/models + + mailto:info@interlis.ch +http://www.interlis.ch + + 26ed79dec1e50e4326707930ef39adf3 ... + + Base +ili2_3 + + obsolete/Base_d-20140418_o0.ili +2014-04-18 +2017-08-24 + + + Units ... ... + + http://www.sia.ch/405 + +true +8497f27210dad68925150cb64e1d3b77 + ... + + Base_f +ili2_3 + + obsolete/Base_f-20140418_o0.ili +2014-04-18 +2017-08-24 + + + Base ... + + Units ... ... + + http://www.sia.ch/405 + +true +1f553bf4281aed032194e25672039b58 + ... + + SIA405_Base +ili2_3 + + obsolete/SIA405_Base_d-20140618_o0.ili +2014-06-18 + + 2017-08-24 + + + Base ... + + Units ... ... + + http://www.sia.ch/405 + +true +56cd4835a84d4bd5a5d95f8f07562eef + ... + + SIA405_Base_f +ili2_3 + + obsolete/SIA405_Base_f-20140618_o0.ili +2014-06-18 + + 2017-08-24 + + + SIA405_Base ... + + Base_f ... + + Units ... ... + + http://www.sia.ch/405 + +true +ab96e29ea01edbc8784b6ed49eed4cd1 + ... + + Base_LV95 +ili2_3 + + obsolete/Base_d-20140418_o0.ili +2014-04-18 +2017-10-23 + + + Units ... ... + + http://www.sia.ch/405 + +true +8497f27210dad68925150cb64e1d3b77 + ... + + Base_f_MN95 +ili2_3 + + obsolete/Base_f-20140418_o0.ili +2014-04-18 +2017-10-23 + + + Base_LV95 ... + + Units ... ... + + http://www.sia.ch/405 + +true +1f553bf4281aed032194e25672039b58 + ... + + SIA405_Base_LV95 +ili2_3 + + obsolete/SIA405_Base_d-20140618_o0.ili +2014-06-18 + + 2017-10-23 + + + Base_LV95 ... + + Units ... ... + + http://www.sia.ch/405 + +true +56cd4835a84d4bd5a5d95f8f07562eef + ... + + SIA405_Base_f_MN95 +ili2_3 + + obsolete/SIA405_Base_f-20140618_o0.ili +2014-06-18 + + 2017-10-23 + + + SIA405_Base_LV95 ... + + Base_f_MN95 ... + + Units ... ... + + http://www.sia.ch/405 + +true +ab96e29ea01edbc8784b6ed49eed4cd1 + ... + + Math +ili2_3 +refhb23/Math.ili + + 2018-11-19 +2019-03-27 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +bf0b6f23197f0e2f1e743959e5656984 ... + + Text +ili2_3 +refhb23/Text.ili + + 2018-11-19 +2019-03-27 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +163637b12e86ab81ec50937e74c76fee ... + + DatasetIdx16 +ili2_3 + + obsolete/DatasetIdx16_o0.ili +2018-11-21 +2019-05-08 + + mailto:ce@eisenhutinformatik.ch +mailto:info@interlis.ch + + https://www.interlis.ch +b71b1c4aca1eb705fdba9f9ea31adbd8 ... + + AbstractSymbology +ili2_2 + + refhb22/AbstractSymbology-20200218.ili +2020-02-18 + + 2020-02-19 +2003-03-18 + + mailto:info@interlis.ch +https://www.interlis.ch + + 041975acceac2dc5b05aaef45fa5b828 ... + + AbstractSymbology +ili2_3 + + refhb23/AbstractSymbology-20200219.ili +2020-02-19 + + 2020-02-20 +2005-06-16 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +29032727ca547415e221845a95ebe9f2 ... + + Time +ili2_3 + + refhb23/Time-20200219.ili +2020-02-19 +2020-02-20 + + + Units ... ... + + 2017-04-13 +http://www.interlis.ch/models + + mailto:info@interlis.ch +https://www.interlis.ch + + db2a04f9162426e342dac0972461ba1b ... + + IliRepository20 +ili2_3 + + obsolete/IliRepository20_o0.ili +2020-01-15 +2020-04-01 + + http://models.interlis.ch/core +mailto:info@interlis.ch + + https://www.interlis.ch +46cba395b5412de0232619a99cecb65c ... + + IliRepository20 +ili2_3 + + core/IliRepository20.ili +2020-04-17 +2020-04-17 + + 2020-01-15 +http://models.interlis.ch/core + + mailto:info@interlis.ch +https://www.interlis.ch + + 5c2699ee9bd2c394f1bba7cd0cf7d9a2 ... + + IlisMeta07 +ili2_3 + + obsolete/IlisMeta07_o3.ili +2020-04-24 +2020-04-24 + + 2011-12-22 +http://interlis.ch + + mailto:info@interlis.ch +https://www.interlis.ch + + 331299bb82ddaef9a5d9c964dbd5a88c ... + + IlisMeta07 +ili2_3 + + obsolete/IlisMeta07_o4.ili +2022-04-28 +2022-05-02 + + 2020-04-24 +http://models.interlis.ch + + mailto:info@interlis.ch +https://www.interlis.ch + + 99da764fd9e771dbf8ef4a753631ee78 ... + + DatasetIdx16 +ili2_3 + + core/DatasetIdx16.ili +2022-10-10 +2022-10-10 + + 2018-11-21 +mailto:ce@eisenhutinformatik.ch + + mailto:info@interlis.ch +https://www.interlis.ch + + 4e95b5e19264cc388ce5296e79e63b24 ... + + IlisMeta07 +ili2_3 + + core/IlisMeta07.ili +2022-10-10 +2022-10-10 + + 2022-04-28 +http://models.interlis.ch + + mailto:info@interlis.ch +https://www.interlis.ch + + 71f3d2744d650b1d36f3a3aa3a9796eb ... + + MinimalRuntimeSystem01 +ili2_3 + + tools/MinimalRuntimeSystem01.ili +2018-06-05 +2024-01-04 + + mailto:info@interlis.ch +https://www.interlis.ch + + 5050cf73cc8c931dfa388fd207a96a18 ... ... + + + + + AbstractSymbology +ili2_4 + + refhb24/AbstractSymbology.ili +2020-02-20 +en + + 2020-02-20 +http://www.interlis.ch/models/refhb24 + + mailto:info@interlis.ch +https://www.interlis.ch + + 1da81c8764c7fce8e896e7aa36e2d499 ... + + CoordSys +ili2_4 + + refhb24/CoordSys.ili +2014-07-09 +en + + 2020-02-20 +http://www.interlis.ch/models/refhb24 + + mailto:info@interlis.ch +https://www.interlis.ch + + 17fef0e7bbf5645ff63ab563eadebb63 ... + + RoadsExdm2ben +ili2_4 + + refhb24/RoadsExdm2ben.ili +2014-07-09 +en + + 2020-02-20 +http://www.interlis.ch/models/refhb24 + + mailto:info@interlis.ch +https://www.interlis.ch + + 97808718c84b90d6ff7536bcea0cc4ea ... + + RoadsExdm2ien +ili2_4 + + refhb24/RoadsExdm2ien.ili +2014-07-09 +en + + 2020-02-20 + + + RoadsExdm2ben ... ... + + http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch + + https://www.interlis.ch +7104f7d0cd39b99f2718756e05b205be ... + + RoadsExgm2ien +ili2_4 + + refhb24/RoadsExgm2ien.ili +2014-07-09 +en + + 2020-02-20 + + + RoadsExdm2ben ... + + RoadsExdm2ien ... + + StandardSymbology ... ... + + http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch + + https://www.interlis.ch +7f521116d0291fdf280da0482a380cce ... + + StandardSymbology +ili2_4 + + refhb24/StandardSymbology.ili +2016-01-21 +en + + 2020-02-20 + + + AbstractSymbology ... ... + + http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch + + https://www.interlis.ch +ae386646d46d5eba1b931ef9047a10ab ... + + Time +ili2_4 +refhb24/Time.ili + + 2020-02-20 +en +2020-02-20 + + + Units ... ... + + http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch + + https://www.interlis.ch +3fa23c502fab9f7461921975180e2082 ... + + Units +ili2_4 +refhb24/Units.ili + + 2014-07-09 +en +2020-02-20 + + http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch + + https://www.interlis.ch +822579b7bd802a6718cebf0cc1f5d85c ... + + IlisMeta16 +ili2_4 + + obsolete/IlisMeta16_o0.ili +2022-06-17 +en + + 2022-07-06 +http://models.interlis.ch + + mailto:info@interlis.ch +https://www.interlis.ch + + 65d978432fcb32e1d177458f8a900a72 ... + + IlisMeta16 +ili2_4 + + core/IlisMeta16.ili +2022-10-10 +en + + 2022-10-10 +2022-06-17 + + http://models.interlis.ch +mailto:info@interlis.ch + + https://www.interlis.ch +f3e7fd3cb7be0cd7a7b67b55b2c64c31 ... + + Math_V2 +ili2_4 +refhb24/Math_V2.ili + + 2023-05-25 +2023-05-26 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +293d2b12049c218600c27941c9a89eb0 ... + + Text_V2 +ili2_4 +refhb24/Text_V2.ili + + 2023-05-25 +2023-05-26 + + http://www.interlis.ch/models +mailto:info@interlis.ch + + https://www.interlis.ch +f7626667624b0e603769c658b8fc1122 ... + ... ... ... diff --git a/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_not_conform.xml b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_not_conform.xml new file mode 100644 index 00000000..99617d3f --- /dev/null +++ b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_not_conform.xml @@ -0,0 +1,1373 @@ +asdfasdfasdfasdfa +asdfasdfasdfasdfa + + + + + +... + +... + + + + + + +IliRepository09 +ili2_3 +obsolete/IliRepository09-20120220_o0.ili +2009-11-19 +mailto:info@interlis.ch +https://www.interlis.ch +b2bd836d761de6a1324e3a6c3f7d3650 +... + + +IliRepository09 +ili2_3 +obsolete/IliRepository09-20120220_o1.ili +2009-12-01 +2009-11-19 +mailto:info@interlis.ch +https://www.interlis.ch +d4ca2847fee23bcc4332918394e4830b +... + + +IliSite09 +ili2_3 +core/IliSite09-20091119.ili +2009-11-19 +mailto:info@interlis.ch +https://www.interlis.ch +6fa61b0163bbafa5df541fc86b142948 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o0.ili +2008-02-07 +http://interlis.ch +mailto:info@interlis.ch +http://www.interlis.ch +c5d11adfe45b53d3962bc376f7dc8616 +... + + +AbstractSymbology +ili2_2 +obsolete/AbstractSymbology-20200218_o0.ili +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +bcdd38ff69b6e9aa62302a4c1536310f +... + + +CoordSys +ili2_2 +obsolete/CoordSys-20151123_o0.ili +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +d8b5aa87bf3f9ded17caeb5a0cbffd7c +... + + +RoadsExdm2ben_10 +ili2_2 +refhb22/RoadsExdm2ben-20030226.ili +2003-02-26 +mailto:info@interlis.ch +https://www.interlis.ch +cfa0cfda12d0d1b1911944682b32e89d +... + + +RoadsExdm2ien_10 +ili2_2 +obsolete/RoadsExdm2ien-20170404_o0.ili +2003-02-26 + + +RoadsExdm2ben_10 +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +df7aa897a7a3800d4e0abeb9ad710cbd +... + + +RoadsExgm2ien_10 +ili2_2 +refhb22/RoadsExgm2ien-20030226.ili +2003-02-26 + + +RoadsExdm2ben_10 +... + + +RoadsExdm2ien_10 +... + + +StandardSymbology +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +15911c80234a512b78cbdea1b51c9ea7 +... + + +StandardSymbology +ili2_2 +obsolete/StandardSymbology-20160120_o0.ili +2003-03-18 + + +AbstractSymbology +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +223ff253d6b352f9a6b6b0e6686bfbcb +... + + +Time +ili2_2 +obsolete/Time-20170412_o0.ili +2003-03-18 + + +Units +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +f6201ebafb641f2e78893ab6919dd9cc +... + + +Units +ili2_2 +obsolete/Units-20120219_o0.ili +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +71a8ccd32bb3dd51f1e666aa833d58f4 +... + + +AbstractSymbology +ili2_3 +obsolete/AbstractSymbology-20200219_o0.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +be66beba06650e6083ea009aca792ecb +... + + +CoordSys +ili2_3 +obsolete/CoordSys-20151124_o0.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +520e0544a9833f216b7d84ba7c89262c +... + + +RoadsExdm2ben +ili2_3 +refhb23/RoadsExdm2ben-20050616.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +33b3b2c8d518061b8f01168cd1ee65a1 +... + + +RoadsExdm2ien +ili2_3 +obsolete/RoadsExdm2ien-20170405_o0.ili +2005-06-16 + + +RoadsExdm2ben +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +7862b3381dc90d857ed7f8e28a20bd41 +... + + +RoadsExgm2ien +ili2_3 +refhb23/RoadsExgm2ien-20050616.ili +2005-06-16 + + +RoadsExdm2ien +... + + +StandardSymbology +... + + +RoadsExdm2ben +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +c207c14dade2c4b857b6b4151e66bc10 +... + + +StandardSymbology +ili2_3 +obsolete/StandardSymbology-20160121_o0.ili +2005-06-16 + + +AbstractSymbology +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +b712287b7269242ffe0ab6d4d63448a3 +... + + +Time +ili2_3 +obsolete/Time-20200219_o0.ili +2005-06-16 + + +Units +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +3d3bd4f8367a5bc1ba3395f0e1cf882c +... + + +Units +ili2_3 +obsolete/Units-20120220_o0.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +66ad28cb2d65ffacdee360c6f4f6cb69 +... + + +GM03Core +ili2_2 +obsolete/GM03_V23_o0.ili +2005-04-15 +2005-04-15 + + +Units +... + + +CodeISO +... + +... + +mailto:info@interlis.ch +http://www.geocat.ch +719211af31d874eafb20fcc1af5cce25 +... + + +GM03Comprehensive +ili2_2 +geocat.ch/GM03_V23.ili +2005-04-15 +2005-04-15 + + +GM03Core +... + + +Units +... + + +CodeISO +... + +... + +mailto:info@interlis.ch +http://www.geocat.ch +99c34fcc6409d7effe3892dd7ee2204c +... + + +CodeISO +ili2_2 +geocat.ch/CodeISO.ili +2005-04-15 +2005-04-15 +mailto:info@interlis.ch +http://www.geocat.ch +5f1ca062b739f7c034b03477344da9b2 +... + + +GM03_2Core +ili2_3 +obsolete/GM03_2_o0.ili +20081211 +2008-12-11 + + +CodeISO +... + + +Units +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +656111cd9083881f2fecce0a3f308814 +... + + +GM03_2Comprehensive +ili2_3 +geocat.ch/GM03_2.ili +20081211 +2008-12-11 + + +Units +... + + +CodeISO +... + + +GM03_2Core +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +1dc1e126ac75b9f6c69774485861a1dc +... + + +CodeISO +ili2_3 +geocat.ch/CodeISO_2.ili +20060808 +2006-08-08 +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +00bc9fa4a6e6b885dc42490853178be3 +... + + +GM03_2_1Core +ili2_3 +obsolete/GM03_2_1_o0.ili +20130121 +2013-05-14 + + +Units +... + + +CodeISO +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +1c326df8e57bf403993c3788d00c7351 +... + + +GM03_2_1Comprehensive +ili2_3 +geocat.ch/GM03_2_1.ili +20130121 +2013-05-14 + + +Units +... + + +CodeISO +... + + +GM03_2_1Core +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +ca8c7a94a827ff7566c5da800169ce64 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o1.ili +2008-08-29 +2008-08-29 +2008-02-07 +http://interlis.ch +mailto:info@interlis.ch +http://www.interlis.ch +2f476c335784de2fdcc27dd3e27ebcd8 +... + + +Units +ili2_3 +refhb23/Units-20120220.ili +2012-02-20 +2012-02-20 +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +e2a198a0599581673d55bbc2c968a9f8 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o2.ili +2011-12-22 +2011-12-22 +2008-08-29 +http://interlis.ch +mailto:info@interlis.ch +http://www.interlis.ch +6d0346598e55c35dfe8e19a7c9c55bd5 +... + + +IliRepository09 +ili2_3 +core/IliRepository09-20120220.ili +2012-02-20 +2012-02-20 +2009-12-01 +mailto:info@interlis.ch +https://www.interlis.ch +562cd4f06241c815a42fc5a92d340829 +... + + +StandardSymbology +ili2_2 +obsolete/StandardSymbology-20160120_o1.ili +2015-04-01 +2015-04-01 + + +AbstractSymbology +... + +... + +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +8c32ce70641aae3f16904655bb6cc248 +... + + +StandardSymbology +ili2_3 +obsolete/StandardSymbology-20160121_o1.ili +2015-04-02 + + +AbstractSymbology +... + +... + +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +http://www.interlis.ch +43a1d5c8d92d2f47a75f60d10cc35977 +... + + +GM03Core +ili2_2 +geocat.ch/GM03_V23.ili +2015-12-04 +2015-12-04 + + +Units +... + + +CodeISO +... + +... + +2005-04-15 +mailto:geocat@swisstopo.ch +http://www.geocat.ch +99c34fcc6409d7effe3892dd7ee2204c +... + + +GM03_2Core +ili2_3 +geocat.ch/GM03_2.ili +2015-12-04 +2015-12-04 + + +CodeISO +... + + +Units +... + +... + +20081211 +http://www.kogis.ch +mailto:geocat@swisstopo.ch +http://www.geocat.ch +1dc1e126ac75b9f6c69774485861a1dc +... + + +GM03_2_1Core +ili2_3 +geocat.ch/GM03_2_1.ili +2015-12-04 +2015-12-04 + + +Units +... + + +CodeISO +... + +... + +20130121 +http://www.kogis.ch +mailto:geocat@swisstopo.ch +http://www.geocat.ch +ca8c7a94a827ff7566c5da800169ce64 +... + + +CoordSys +ili2_3 +refhb23/CoordSys-20151124.ili +2015-11-24 +2016-01-21 +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +56943b1a4277052f63a2ca401b1feabe +... + + +INTERLIS_ext +ili2_3 +obsolete/INTERLIS_ext_o0.ili +2016-02-11 +2016-02-12 +http://www.interlis.ch/models +mailto:info@interlis.ch +http://www.interlis.ch +2f8d49c2dd6cd1bd2eacc6c652d8a865 +... + + +StandardSymbology +ili2_3 +refhb23/StandardSymbology-20160121.ili +2016-01-21 +2016-03-03 + + +AbstractSymbology +... + +... + +2015-04-02 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +ad21e1e4ae96465b4e30fd1815589158 +... + + +INTERLIS_ext +ili2_3 +refhb23/INTERLIS_ext.ili +2016-05-30 +2016-05-30 +2016-02-11 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +56bef86426384cd3122963508e797a25 +... + + +IliVErrors +ili2_3 +tools/IliVErrors.ili +2016-06-10 +2017-01-12 +mailto:info@interlis.ch +https://www.interlis.ch +b41ab92753368ad32890d04bc77cc47f +... + + +RoadsExdm2ien_10 +ili2_2 +refhb22/RoadsExdm2ien-20170404.ili +2017-04-05 +2017-04-05 + + +RoadsExdm2ben_10 +... + +... + +2003-02-26 +mailto:info@interlis.ch +https://www.interlis.ch +4b1341515b81821259048ba2bf1648a8 +... + + +RoadsExdm2ien +ili2_3 +refhb23/RoadsExdm2ien-20170405.ili +2017-04-05 +2017-04-05 + + +RoadsExdm2ben +... + +... + +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +83a4a01f18f184d74d86e07d27d59a80 +... + + +CoordSys +ili2_2 +refhb22/CoordSys-20151123.ili +2015-11-23 +2017-04-10 +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +5e12919a0dff1fb23dd0d92a4873748d +... + + +StandardSymbology +ili2_2 +refhb22/StandardSymbology-20160120.ili +2016-01-20 +2017-04-10 + + +AbstractSymbology +... + +... + +2015-04-01 +mailto:info@interlis.ch +https://www.interlis.ch +34f535881a0d89639be4d4db656ef929 +... + + +Units +ili2_2 +refhb22/Units-20120219.ili +2012-02-19 +2017-04-10 +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +ce2f5833386b6b8b5acceef87f0b492a +... + + +Time +ili2_2 +refhb22/Time-20170412.ili +2017-04-12 +2017-04-13 + + +Units +... + +... + +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +196c9799ac39d9f05d95e96cbdf0e481 +... + + +Time +ili2_3 +obsolete/Time-20200219_o1.ili +2017-04-13 +2017-04-13 + + +Units +... + +... + +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +http://www.interlis.ch +26ed79dec1e50e4326707930ef39adf3 +... + + +Base +ili2_3 +obsolete/Base_d-20140418_o0.ili +2014-04-18 +2017-08-24 + + +Units +... + +... + +http://www.sia.ch/405 + +true +8497f27210dad68925150cb64e1d3b77 +... + + +Base_f +ili2_3 +obsolete/Base_f-20140418_o0.ili +2014-04-18 +2017-08-24 + + +Base +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +1f553bf4281aed032194e25672039b58 +... + + +SIA405_Base +ili2_3 +obsolete/SIA405_Base_d-20140618_o0.ili +2014-06-18 +2017-08-24 + + +Base +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +56cd4835a84d4bd5a5d95f8f07562eef +... + + +SIA405_Base_f +ili2_3 +obsolete/SIA405_Base_f-20140618_o0.ili +2014-06-18 +2017-08-24 + + +SIA405_Base +... + + +Base_f +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +ab96e29ea01edbc8784b6ed49eed4cd1 +... + + +Base_LV95 +ili2_3 +obsolete/Base_d-20140418_o0.ili +2014-04-18 +2017-10-23 + + +Units +... + +... + +http://www.sia.ch/405 + +true +8497f27210dad68925150cb64e1d3b77 +... + + +Base_f_MN95 +ili2_3 +obsolete/Base_f-20140418_o0.ili +2014-04-18 +2017-10-23 + + +Base_LV95 +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +1f553bf4281aed032194e25672039b58 +... + + +SIA405_Base_LV95 +ili2_3 +obsolete/SIA405_Base_d-20140618_o0.ili +2014-06-18 +2017-10-23 + + +Base_LV95 +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +56cd4835a84d4bd5a5d95f8f07562eef +... + + +SIA405_Base_f_MN95 +ili2_3 +obsolete/SIA405_Base_f-20140618_o0.ili +2014-06-18 +2017-10-23 + + +SIA405_Base_LV95 +... + + +Base_f_MN95 +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +ab96e29ea01edbc8784b6ed49eed4cd1 +... + + +Math +ili2_3 +refhb23/Math.ili +2018-11-19 +2019-03-27 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +bf0b6f23197f0e2f1e743959e5656984 +... + + +Text +ili2_3 +refhb23/Text.ili +2018-11-19 +2019-03-27 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +163637b12e86ab81ec50937e74c76fee +... + + +DatasetIdx16 +ili2_3 +obsolete/DatasetIdx16_o0.ili +2018-11-21 +2019-05-08 +mailto:ce@eisenhutinformatik.ch +mailto:info@interlis.ch +https://www.interlis.ch +b71b1c4aca1eb705fdba9f9ea31adbd8 +... + + +AbstractSymbology +ili2_2 +refhb22/AbstractSymbology-20200218.ili +2020-02-18 +2020-02-19 +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +041975acceac2dc5b05aaef45fa5b828 +... + + +AbstractSymbology +ili2_3 +refhb23/AbstractSymbology-20200219.ili +2020-02-19 +2020-02-20 +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +29032727ca547415e221845a95ebe9f2 +... + + +Time +ili2_3 +refhb23/Time-20200219.ili +2020-02-19 +2020-02-20 + + +Units +... + +... + +2017-04-13 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +db2a04f9162426e342dac0972461ba1b +... + + +IliRepository20 +ili2_3 +obsolete/IliRepository20_o0.ili +2020-01-15 +2020-04-01 +http://models.interlis.ch/core +mailto:info@interlis.ch +https://www.interlis.ch +46cba395b5412de0232619a99cecb65c +... + + +IliRepository20 +ili2_3 +core/IliRepository20.ili +2020-04-17 +2020-04-17 +2020-01-15 +http://models.interlis.ch/core +mailto:info@interlis.ch +https://www.interlis.ch +5c2699ee9bd2c394f1bba7cd0cf7d9a2 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o3.ili +2020-04-24 +2020-04-24 +2011-12-22 +http://interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +331299bb82ddaef9a5d9c964dbd5a88c +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o4.ili +2022-04-28 +2022-05-02 +2020-04-24 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +99da764fd9e771dbf8ef4a753631ee78 +... + + +DatasetIdx16 +ili2_3 +core/DatasetIdx16.ili +2022-10-10 +2022-10-10 +2018-11-21 +mailto:ce@eisenhutinformatik.ch +mailto:info@interlis.ch +https://www.interlis.ch +4e95b5e19264cc388ce5296e79e63b24 +... + + +IlisMeta07 +ili2_3 +core/IlisMeta07.ili +2022-10-10 +2022-10-10 +2022-04-28 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +71f3d2744d650b1d36f3a3aa3a9796eb +... + + +MinimalRuntimeSystem01 +ili2_3 +tools/MinimalRuntimeSystem01.ili +2018-06-05 +2024-01-04 +mailto:info@interlis.ch +https://www.interlis.ch +5050cf73cc8c931dfa388fd207a96a18 +... + +... + + + + + +AbstractSymbology +ili2_4 +refhb24/AbstractSymbology.ili +2020-02-20 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +1da81c8764c7fce8e896e7aa36e2d499 +... + + +CoordSys +ili2_4 +refhb24/CoordSys.ili +2014-07-09 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +17fef0e7bbf5645ff63ab563eadebb63 +... + + +RoadsExdm2ben +ili2_4 +refhb24/RoadsExdm2ben.ili +2014-07-09 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +97808718c84b90d6ff7536bcea0cc4ea +... + + +RoadsExdm2ien +ili2_4 +refhb24/RoadsExdm2ien.ili +2014-07-09 +en +2020-02-20 + + +RoadsExdm2ben +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +7104f7d0cd39b99f2718756e05b205be +... + + +RoadsExgm2ien +ili2_4 +refhb24/RoadsExgm2ien.ili +2014-07-09 +en +2020-02-20 + + +RoadsExdm2ben +... + + +RoadsExdm2ien +... + + +StandardSymbology +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +7f521116d0291fdf280da0482a380cce +... + + +StandardSymbology +ili2_4 +refhb24/StandardSymbology.ili +2016-01-21 +en +2020-02-20 + + +AbstractSymbology +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +ae386646d46d5eba1b931ef9047a10ab +... + + +Time +ili2_4 +refhb24/Time.ili +2020-02-20 +en +2020-02-20 + + +Units +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +3fa23c502fab9f7461921975180e2082 +... + + +Units +ili2_4 +refhb24/Units.ili +2014-07-09 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +822579b7bd802a6718cebf0cc1f5d85c +... + + +IlisMeta16 +ili2_4 +obsolete/IlisMeta16_o0.ili +2022-06-17 +en +2022-07-06 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +65d978432fcb32e1d177458f8a900a72 +... + + +IlisMeta16 +ili2_4 +core/IlisMeta16.ili +2022-10-10 +en +2022-10-10 +2022-06-17 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +f3e7fd3cb7be0cd7a7b67b55b2c64c31 +... + + +Math_V2 +ili2_4 +refhb24/Math_V2.ili +2023-05-25 +2023-05-26 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +293d2b12049c218600c27941c9a89eb0 +... + + +Text_V2 +ili2_4 +refhb24/Text_V2.ili +2023-05-25 +2023-05-26 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +f7626667624b0e603769c658b8fc1122 +... + +... + +... + +... + diff --git a/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_valid.xml b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_valid.xml new file mode 100644 index 00000000..bf957428 --- /dev/null +++ b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/ilimodels_valid.xml @@ -0,0 +1,1371 @@ + + + + + +... + +... + + + + + + +IliRepository09 +ili2_3 +obsolete/IliRepository09-20120220_o0.ili +2009-11-19 +mailto:info@interlis.ch +https://www.interlis.ch +b2bd836d761de6a1324e3a6c3f7d3650 +... + + +IliRepository09 +ili2_3 +obsolete/IliRepository09-20120220_o1.ili +2009-12-01 +2009-11-19 +mailto:info@interlis.ch +https://www.interlis.ch +d4ca2847fee23bcc4332918394e4830b +... + + +IliSite09 +ili2_3 +core/IliSite09-20091119.ili +2009-11-19 +mailto:info@interlis.ch +https://www.interlis.ch +6fa61b0163bbafa5df541fc86b142948 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o0.ili +2008-02-07 +http://interlis.ch +mailto:info@interlis.ch +http://www.interlis.ch +c5d11adfe45b53d3962bc376f7dc8616 +... + + +AbstractSymbology +ili2_2 +obsolete/AbstractSymbology-20200218_o0.ili +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +bcdd38ff69b6e9aa62302a4c1536310f +... + + +CoordSys +ili2_2 +obsolete/CoordSys-20151123_o0.ili +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +d8b5aa87bf3f9ded17caeb5a0cbffd7c +... + + +RoadsExdm2ben_10 +ili2_2 +refhb22/RoadsExdm2ben-20030226.ili +2003-02-26 +mailto:info@interlis.ch +https://www.interlis.ch +cfa0cfda12d0d1b1911944682b32e89d +... + + +RoadsExdm2ien_10 +ili2_2 +obsolete/RoadsExdm2ien-20170404_o0.ili +2003-02-26 + + +RoadsExdm2ben_10 +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +df7aa897a7a3800d4e0abeb9ad710cbd +... + + +RoadsExgm2ien_10 +ili2_2 +refhb22/RoadsExgm2ien-20030226.ili +2003-02-26 + + +RoadsExdm2ben_10 +... + + +RoadsExdm2ien_10 +... + + +StandardSymbology +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +15911c80234a512b78cbdea1b51c9ea7 +... + + +StandardSymbology +ili2_2 +obsolete/StandardSymbology-20160120_o0.ili +2003-03-18 + + +AbstractSymbology +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +223ff253d6b352f9a6b6b0e6686bfbcb +... + + +Time +ili2_2 +obsolete/Time-20170412_o0.ili +2003-03-18 + + +Units +... + +... + +mailto:info@interlis.ch +https://www.interlis.ch +f6201ebafb641f2e78893ab6919dd9cc +... + + +Units +ili2_2 +obsolete/Units-20120219_o0.ili +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +71a8ccd32bb3dd51f1e666aa833d58f4 +... + + +AbstractSymbology +ili2_3 +obsolete/AbstractSymbology-20200219_o0.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +be66beba06650e6083ea009aca792ecb +... + + +CoordSys +ili2_3 +obsolete/CoordSys-20151124_o0.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +520e0544a9833f216b7d84ba7c89262c +... + + +RoadsExdm2ben +ili2_3 +refhb23/RoadsExdm2ben-20050616.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +33b3b2c8d518061b8f01168cd1ee65a1 +... + + +RoadsExdm2ien +ili2_3 +obsolete/RoadsExdm2ien-20170405_o0.ili +2005-06-16 + + +RoadsExdm2ben +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +7862b3381dc90d857ed7f8e28a20bd41 +... + + +RoadsExgm2ien +ili2_3 +refhb23/RoadsExgm2ien-20050616.ili +2005-06-16 + + +RoadsExdm2ien +... + + +StandardSymbology +... + + +RoadsExdm2ben +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +c207c14dade2c4b857b6b4151e66bc10 +... + + +StandardSymbology +ili2_3 +obsolete/StandardSymbology-20160121_o0.ili +2005-06-16 + + +AbstractSymbology +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +b712287b7269242ffe0ab6d4d63448a3 +... + + +Time +ili2_3 +obsolete/Time-20200219_o0.ili +2005-06-16 + + +Units +... + +... + +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +3d3bd4f8367a5bc1ba3395f0e1cf882c +... + + +Units +ili2_3 +obsolete/Units-20120220_o0.ili +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +66ad28cb2d65ffacdee360c6f4f6cb69 +... + + +GM03Core +ili2_2 +obsolete/GM03_V23_o0.ili +2005-04-15 +2005-04-15 + + +Units +... + + +CodeISO +... + +... + +mailto:info@interlis.ch +http://www.geocat.ch +719211af31d874eafb20fcc1af5cce25 +... + + +GM03Comprehensive +ili2_2 +geocat.ch/GM03_V23.ili +2005-04-15 +2005-04-15 + + +GM03Core +... + + +Units +... + + +CodeISO +... + +... + +mailto:info@interlis.ch +http://www.geocat.ch +99c34fcc6409d7effe3892dd7ee2204c +... + + +CodeISO +ili2_2 +geocat.ch/CodeISO.ili +2005-04-15 +2005-04-15 +mailto:info@interlis.ch +http://www.geocat.ch +5f1ca062b739f7c034b03477344da9b2 +... + + +GM03_2Core +ili2_3 +obsolete/GM03_2_o0.ili +20081211 +2008-12-11 + + +CodeISO +... + + +Units +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +656111cd9083881f2fecce0a3f308814 +... + + +GM03_2Comprehensive +ili2_3 +geocat.ch/GM03_2.ili +20081211 +2008-12-11 + + +Units +... + + +CodeISO +... + + +GM03_2Core +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +1dc1e126ac75b9f6c69774485861a1dc +... + + +CodeISO +ili2_3 +geocat.ch/CodeISO_2.ili +20060808 +2006-08-08 +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +00bc9fa4a6e6b885dc42490853178be3 +... + + +GM03_2_1Core +ili2_3 +obsolete/GM03_2_1_o0.ili +20130121 +2013-05-14 + + +Units +... + + +CodeISO +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +1c326df8e57bf403993c3788d00c7351 +... + + +GM03_2_1Comprehensive +ili2_3 +geocat.ch/GM03_2_1.ili +20130121 +2013-05-14 + + +Units +... + + +CodeISO +... + + +GM03_2_1Core +... + +... + +http://www.kogis.ch +mailto:geocat@swisstopo.ch +https://www.geocat.ch +ca8c7a94a827ff7566c5da800169ce64 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o1.ili +2008-08-29 +2008-08-29 +2008-02-07 +http://interlis.ch +mailto:info@interlis.ch +http://www.interlis.ch +2f476c335784de2fdcc27dd3e27ebcd8 +... + + +Units +ili2_3 +refhb23/Units-20120220.ili +2012-02-20 +2012-02-20 +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +e2a198a0599581673d55bbc2c968a9f8 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o2.ili +2011-12-22 +2011-12-22 +2008-08-29 +http://interlis.ch +mailto:info@interlis.ch +http://www.interlis.ch +6d0346598e55c35dfe8e19a7c9c55bd5 +... + + +IliRepository09 +ili2_3 +core/IliRepository09-20120220.ili +2012-02-20 +2012-02-20 +2009-12-01 +mailto:info@interlis.ch +https://www.interlis.ch +562cd4f06241c815a42fc5a92d340829 +... + + +StandardSymbology +ili2_2 +obsolete/StandardSymbology-20160120_o1.ili +2015-04-01 +2015-04-01 + + +AbstractSymbology +... + +... + +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +8c32ce70641aae3f16904655bb6cc248 +... + + +StandardSymbology +ili2_3 +obsolete/StandardSymbology-20160121_o1.ili +2015-04-02 + + +AbstractSymbology +... + +... + +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +http://www.interlis.ch +43a1d5c8d92d2f47a75f60d10cc35977 +... + + +GM03Core +ili2_2 +geocat.ch/GM03_V23.ili +2015-12-04 +2015-12-04 + + +Units +... + + +CodeISO +... + +... + +2005-04-15 +mailto:geocat@swisstopo.ch +http://www.geocat.ch +99c34fcc6409d7effe3892dd7ee2204c +... + + +GM03_2Core +ili2_3 +geocat.ch/GM03_2.ili +2015-12-04 +2015-12-04 + + +CodeISO +... + + +Units +... + +... + +20081211 +http://www.kogis.ch +mailto:geocat@swisstopo.ch +http://www.geocat.ch +1dc1e126ac75b9f6c69774485861a1dc +... + + +GM03_2_1Core +ili2_3 +geocat.ch/GM03_2_1.ili +2015-12-04 +2015-12-04 + + +Units +... + + +CodeISO +... + +... + +20130121 +http://www.kogis.ch +mailto:geocat@swisstopo.ch +http://www.geocat.ch +ca8c7a94a827ff7566c5da800169ce64 +... + + +CoordSys +ili2_3 +refhb23/CoordSys-20151124.ili +2015-11-24 +2016-01-21 +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +56943b1a4277052f63a2ca401b1feabe +... + + +INTERLIS_ext +ili2_3 +obsolete/INTERLIS_ext_o0.ili +2016-02-11 +2016-02-12 +http://www.interlis.ch/models +mailto:info@interlis.ch +http://www.interlis.ch +2f8d49c2dd6cd1bd2eacc6c652d8a865 +... + + +StandardSymbology +ili2_3 +refhb23/StandardSymbology-20160121.ili +2016-01-21 +2016-03-03 + + +AbstractSymbology +... + +... + +2015-04-02 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +ad21e1e4ae96465b4e30fd1815589158 +... + + +INTERLIS_ext +ili2_3 +refhb23/INTERLIS_ext.ili +2016-05-30 +2016-05-30 +2016-02-11 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +56bef86426384cd3122963508e797a25 +... + + +IliVErrors +ili2_3 +tools/IliVErrors.ili +2016-06-10 +2017-01-12 +mailto:info@interlis.ch +https://www.interlis.ch +b41ab92753368ad32890d04bc77cc47f +... + + +RoadsExdm2ien_10 +ili2_2 +refhb22/RoadsExdm2ien-20170404.ili +2017-04-05 +2017-04-05 + + +RoadsExdm2ben_10 +... + +... + +2003-02-26 +mailto:info@interlis.ch +https://www.interlis.ch +4b1341515b81821259048ba2bf1648a8 +... + + +RoadsExdm2ien +ili2_3 +refhb23/RoadsExdm2ien-20170405.ili +2017-04-05 +2017-04-05 + + +RoadsExdm2ben +... + +... + +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +83a4a01f18f184d74d86e07d27d59a80 +... + + +CoordSys +ili2_2 +refhb22/CoordSys-20151123.ili +2015-11-23 +2017-04-10 +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +5e12919a0dff1fb23dd0d92a4873748d +... + + +StandardSymbology +ili2_2 +refhb22/StandardSymbology-20160120.ili +2016-01-20 +2017-04-10 + + +AbstractSymbology +... + +... + +2015-04-01 +mailto:info@interlis.ch +https://www.interlis.ch +34f535881a0d89639be4d4db656ef929 +... + + +Units +ili2_2 +refhb22/Units-20120219.ili +2012-02-19 +2017-04-10 +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +ce2f5833386b6b8b5acceef87f0b492a +... + + +Time +ili2_2 +refhb22/Time-20170412.ili +2017-04-12 +2017-04-13 + + +Units +... + +... + +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +196c9799ac39d9f05d95e96cbdf0e481 +... + + +Time +ili2_3 +obsolete/Time-20200219_o1.ili +2017-04-13 +2017-04-13 + + +Units +... + +... + +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +http://www.interlis.ch +26ed79dec1e50e4326707930ef39adf3 +... + + +Base +ili2_3 +obsolete/Base_d-20140418_o0.ili +2014-04-18 +2017-08-24 + + +Units +... + +... + +http://www.sia.ch/405 + +true +8497f27210dad68925150cb64e1d3b77 +... + + +Base_f +ili2_3 +obsolete/Base_f-20140418_o0.ili +2014-04-18 +2017-08-24 + + +Base +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +1f553bf4281aed032194e25672039b58 +... + + +SIA405_Base +ili2_3 +obsolete/SIA405_Base_d-20140618_o0.ili +2014-06-18 +2017-08-24 + + +Base +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +56cd4835a84d4bd5a5d95f8f07562eef +... + + +SIA405_Base_f +ili2_3 +obsolete/SIA405_Base_f-20140618_o0.ili +2014-06-18 +2017-08-24 + + +SIA405_Base +... + + +Base_f +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +ab96e29ea01edbc8784b6ed49eed4cd1 +... + + +Base_LV95 +ili2_3 +obsolete/Base_d-20140418_o0.ili +2014-04-18 +2017-10-23 + + +Units +... + +... + +http://www.sia.ch/405 + +true +8497f27210dad68925150cb64e1d3b77 +... + + +Base_f_MN95 +ili2_3 +obsolete/Base_f-20140418_o0.ili +2014-04-18 +2017-10-23 + + +Base_LV95 +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +1f553bf4281aed032194e25672039b58 +... + + +SIA405_Base_LV95 +ili2_3 +obsolete/SIA405_Base_d-20140618_o0.ili +2014-06-18 +2017-10-23 + + +Base_LV95 +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +56cd4835a84d4bd5a5d95f8f07562eef +... + + +SIA405_Base_f_MN95 +ili2_3 +obsolete/SIA405_Base_f-20140618_o0.ili +2014-06-18 +2017-10-23 + + +SIA405_Base_LV95 +... + + +Base_f_MN95 +... + + +Units +... + +... + +http://www.sia.ch/405 + +true +ab96e29ea01edbc8784b6ed49eed4cd1 +... + + +Math +ili2_3 +refhb23/Math.ili +2018-11-19 +2019-03-27 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +bf0b6f23197f0e2f1e743959e5656984 +... + + +Text +ili2_3 +refhb23/Text.ili +2018-11-19 +2019-03-27 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +163637b12e86ab81ec50937e74c76fee +... + + +DatasetIdx16 +ili2_3 +obsolete/DatasetIdx16_o0.ili +2018-11-21 +2019-05-08 +mailto:ce@eisenhutinformatik.ch +mailto:info@interlis.ch +https://www.interlis.ch +b71b1c4aca1eb705fdba9f9ea31adbd8 +... + + +AbstractSymbology +ili2_2 +refhb22/AbstractSymbology-20200218.ili +2020-02-18 +2020-02-19 +2003-03-18 +mailto:info@interlis.ch +https://www.interlis.ch +041975acceac2dc5b05aaef45fa5b828 +... + + +AbstractSymbology +ili2_3 +refhb23/AbstractSymbology-20200219.ili +2020-02-19 +2020-02-20 +2005-06-16 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +29032727ca547415e221845a95ebe9f2 +... + + +Time +ili2_3 +refhb23/Time-20200219.ili +2020-02-19 +2020-02-20 + + +Units +... + +... + +2017-04-13 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +db2a04f9162426e342dac0972461ba1b +... + + +IliRepository20 +ili2_3 +obsolete/IliRepository20_o0.ili +2020-01-15 +2020-04-01 +http://models.interlis.ch/core +mailto:info@interlis.ch +https://www.interlis.ch +46cba395b5412de0232619a99cecb65c +... + + +IliRepository20 +ili2_3 +core/IliRepository20.ili +2020-04-17 +2020-04-17 +2020-01-15 +http://models.interlis.ch/core +mailto:info@interlis.ch +https://www.interlis.ch +5c2699ee9bd2c394f1bba7cd0cf7d9a2 +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o3.ili +2020-04-24 +2020-04-24 +2011-12-22 +http://interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +331299bb82ddaef9a5d9c964dbd5a88c +... + + +IlisMeta07 +ili2_3 +obsolete/IlisMeta07_o4.ili +2022-04-28 +2022-05-02 +2020-04-24 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +99da764fd9e771dbf8ef4a753631ee78 +... + + +DatasetIdx16 +ili2_3 +core/DatasetIdx16.ili +2022-10-10 +2022-10-10 +2018-11-21 +mailto:ce@eisenhutinformatik.ch +mailto:info@interlis.ch +https://www.interlis.ch +4e95b5e19264cc388ce5296e79e63b24 +... + + +IlisMeta07 +ili2_3 +core/IlisMeta07.ili +2022-10-10 +2022-10-10 +2022-04-28 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +71f3d2744d650b1d36f3a3aa3a9796eb +... + + +MinimalRuntimeSystem01 +ili2_3 +tools/MinimalRuntimeSystem01.ili +2018-06-05 +2024-01-04 +mailto:info@interlis.ch +https://www.interlis.ch +5050cf73cc8c931dfa388fd207a96a18 +... + +... + + + + + +AbstractSymbology +ili2_4 +refhb24/AbstractSymbology.ili +2020-02-20 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +1da81c8764c7fce8e896e7aa36e2d499 +... + + +CoordSys +ili2_4 +refhb24/CoordSys.ili +2014-07-09 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +17fef0e7bbf5645ff63ab563eadebb63 +... + + +RoadsExdm2ben +ili2_4 +refhb24/RoadsExdm2ben.ili +2014-07-09 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +97808718c84b90d6ff7536bcea0cc4ea +... + + +RoadsExdm2ien +ili2_4 +refhb24/RoadsExdm2ien.ili +2014-07-09 +en +2020-02-20 + + +RoadsExdm2ben +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +7104f7d0cd39b99f2718756e05b205be +... + + +RoadsExgm2ien +ili2_4 +refhb24/RoadsExgm2ien.ili +2014-07-09 +en +2020-02-20 + + +RoadsExdm2ben +... + + +RoadsExdm2ien +... + + +StandardSymbology +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +7f521116d0291fdf280da0482a380cce +... + + +StandardSymbology +ili2_4 +refhb24/StandardSymbology.ili +2016-01-21 +en +2020-02-20 + + +AbstractSymbology +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +ae386646d46d5eba1b931ef9047a10ab +... + + +Time +ili2_4 +refhb24/Time.ili +2020-02-20 +en +2020-02-20 + + +Units +... + +... + +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +3fa23c502fab9f7461921975180e2082 +... + + +Units +ili2_4 +refhb24/Units.ili +2014-07-09 +en +2020-02-20 +http://www.interlis.ch/models/refhb24 +mailto:info@interlis.ch +https://www.interlis.ch +822579b7bd802a6718cebf0cc1f5d85c +... + + +IlisMeta16 +ili2_4 +obsolete/IlisMeta16_o0.ili +2022-06-17 +en +2022-07-06 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +65d978432fcb32e1d177458f8a900a72 +... + + +IlisMeta16 +ili2_4 +core/IlisMeta16.ili +2022-10-10 +en +2022-10-10 +2022-06-17 +http://models.interlis.ch +mailto:info@interlis.ch +https://www.interlis.ch +f3e7fd3cb7be0cd7a7b67b55b2c64c31 +... + + +Math_V2 +ili2_4 +refhb24/Math_V2.ili +2023-05-25 +2023-05-26 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +293d2b12049c218600c27941c9a89eb0 +... + + +Text_V2 +ili2_4 +refhb24/Text_V2.ili +2023-05-25 +2023-05-26 +http://www.interlis.ch/models +mailto:info@interlis.ch +https://www.interlis.ch +f7626667624b0e603769c658b8fc1122 +... + +... + +... + +... + diff --git a/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/invalid-type.png b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/invalid-type.png new file mode 100644 index 00000000..fd592bad Binary files /dev/null and b/src/Geopilot.Frontend/cypress/fixtures/deliveryFiles/invalid-type.png differ diff --git a/src/Geopilot.Frontend/cypress/support/e2e.js b/src/Geopilot.Frontend/cypress/support/e2e.js index 99be6bd3..a114b078 100644 --- a/src/Geopilot.Frontend/cypress/support/e2e.js +++ b/src/Geopilot.Frontend/cypress/support/e2e.js @@ -1,4 +1,5 @@ import { interceptApiCalls } from "../e2e/helpers/appHelpers"; +import "cypress-file-upload"; Cypress.on("uncaught:exception", () => { return false; diff --git a/src/Geopilot.Frontend/package-lock.json b/src/Geopilot.Frontend/package-lock.json index 3ec4f7b8..a83c5378 100644 --- a/src/Geopilot.Frontend/package-lock.json +++ b/src/Geopilot.Frontend/package-lock.json @@ -14,6 +14,7 @@ "@mui/material": "^5.16.0", "@mui/x-data-grid": "^7.9.0", "bootstrap": "^5.3.3", + "date-fns": "^2.30.0", "dayjs": "^1.11.11", "i18next": "^23.11.5", "i18next-browser-languagedetector": "^8.0.0", @@ -23,6 +24,7 @@ "react-bootstrap": "^2.10.4", "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", + "react-hook-form": "^7.52.2", "react-i18next": "^14.1.2", "react-icons": "^5.2.1", "react-markdown": "^9.0.1", @@ -39,6 +41,7 @@ "@typescript-eslint/parser": "^7.15.0", "@vitejs/plugin-react": "^4.3.1", "cypress": "^13.13.0", + "cypress-file-upload": "^5.0.8", "cypress-vite": "^1.5.0", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", @@ -80,30 +83,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -134,11 +137,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -148,14 +151,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -172,40 +175,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", @@ -219,16 +188,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -238,9 +206,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -259,21 +227,10 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "engines": { "node": ">=6.9.0" } @@ -287,22 +244,22 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -323,9 +280,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -364,9 +324,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -375,31 +335,28 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -408,11 +365,11 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -479,15 +436,15 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", @@ -497,47 +454,47 @@ } }, "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", - "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } }, "node_modules/@emotion/hash": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", "dependencies": { - "@emotion/memoize": "^0.8.1" + "@emotion/memoize": "^0.9.0" } }, "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "node_modules/@emotion/react": { - "version": "11.11.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", - "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.3", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { @@ -550,33 +507,33 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", - "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", - "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.1.tgz", + "integrity": "sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.0", "csstype": "^3.0.2" } }, "node_modules/@emotion/sheet": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, "node_modules/@emotion/styled": { - "version": "11.11.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", - "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/is-prop-valid": "^1.2.2", - "@emotion/serialize": "^1.1.4", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1" + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" }, "peerDependencies": { "@emotion/react": "^11.0.0-rc.0", @@ -589,27 +546,27 @@ } }, "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" }, "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", @@ -1084,40 +1041,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@floating-ui/core": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", - "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", - "dependencies": { - "@floating-ui/utils": "^0.2.4" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", - "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.4" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", - "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -1205,9 +1128,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -1218,50 +1141,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", - "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@floating-ui/react-dom": "^2.0.8", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "@popperjs/core": "^2.11.8", - "clsx": "^2.1.0", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.0.tgz", - "integrity": "sha512-8SLffXYPRVpcZx5QzxNE8fytTqzp+IuU3deZbQWg/vSaTlDpR5YVrQ4qQtXTi5cRdhOufV5INylmwlKK+//nPw==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", + "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.0.tgz", - "integrity": "sha512-6ISoOhkp9w5gD0PEW9JklrcbyARDkFWNTBdwXZ1Oy5IGlyu9B0zG0hnUIe4H17IaF1Vgj6C8VI+v4tkSdK0veg==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz", + "integrity": "sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==", "dependencies": { "@babel/runtime": "^7.23.9" }, @@ -1284,21 +1176,21 @@ } }, "node_modules/@mui/material": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.0.tgz", - "integrity": "sha512-DbR1NckTLpjt9Zut9EGQ70th86HfN0BYQgyYro6aXQrNfjzSwe3BJS1AyBQ5mJ7TdL6YVRqohfukxj9JlqZZUg==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", + "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.40", - "@mui/core-downloads-tracker": "^5.16.0", - "@mui/system": "^5.16.0", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.16.0", + "@mui/core-downloads-tracker": "^5.16.7", + "@mui/system": "^5.16.7", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1", - "react-is": "^18.2.0", + "react-is": "^18.3.1", "react-transition-group": "^4.4.5" }, "engines": { @@ -1328,12 +1220,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.0.tgz", - "integrity": "sha512-sYpubkO1MZOnxNyVOClrPNOTs0MfuRVVnAvCeMaOaXt6GimgQbnUcshYv2pSr6PFj+Mqzdff/FYOBceK8u5QgA==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", + "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.0", + "@mui/utils": "^5.16.6", "prop-types": "^15.8.1" }, "engines": { @@ -1354,9 +1246,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", - "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", + "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.11.0", @@ -1385,15 +1277,15 @@ } }, "node_modules/@mui/system": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.0.tgz", - "integrity": "sha512-9YbkC2m3+pNumAvubYv+ijLtog6puJ0fJ6rYfzfLCM47pWrw3m+30nXNM8zMgDaKL6vpfWJcCXm+LPaWBpy7sw==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", + "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.0", - "@mui/styled-engine": "^5.15.14", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.16.0", + "@mui/private-theming": "^5.16.6", + "@mui/styled-engine": "^5.16.6", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1424,11 +1316,11 @@ } }, "node_modules/@mui/types": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", - "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", + "version": "7.2.16", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.16.tgz", + "integrity": "sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==", "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -1437,14 +1329,16 @@ } }, "node_modules/@mui/utils": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.0.tgz", - "integrity": "sha512-kLLi5J1xY+mwtUlMb8Ubdxf4qFAA1+U7WPBvjM/qQ4CIwLCohNb0sHo1oYPufjSIH/Z9+dhVxD7dJlfGjd1AVA==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", "dependencies": { "@babel/runtime": "^7.23.9", - "@types/prop-types": "^15.7.11", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "react-is": "^18.3.1" }, "engines": { "node": ">=12.0.0" @@ -1464,14 +1358,14 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.9.0.tgz", - "integrity": "sha512-RkrVD+tfcR/h3j2p2uqohxA00C5tCJIV5gb5+2ap8XdM0Y8XMF81bB8UADWenU5W83UTErWvtU7n4gCl7hJO9g==", - "dependencies": { - "@babel/runtime": "^7.24.7", - "@mui/system": "^5.16.0", - "@mui/utils": "^5.16.0", - "@mui/x-internals": "7.9.0", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.14.0.tgz", + "integrity": "sha512-ddVtvFXmENHADHzO0TGV2dzUQflexsXMbxEKMq3rBmgJ9QyeiZWBEwzgDps1CzqU5vi9QyDACCcPyoAuL6t3tQ==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/system": "^5.16.7", + "@mui/utils": "^5.16.6", + "@mui/x-internals": "7.14.0", "clsx": "^2.1.1", "prop-types": "^15.8.1", "reselect": "^4.1.8" @@ -1484,18 +1378,28 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } } }, "node_modules/@mui/x-internals": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.9.0.tgz", - "integrity": "sha512-RJRrM6moaDZ8S11gDt8OKVclKm2v9khpIyLkpenNze+tT4dQYoU3liW5P2t31hA4Na/T6JQKNosB4qmB2TYfZw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.14.0.tgz", + "integrity": "sha512-+qWIHLgt2vgH6bKmf7IwRvS86UbZRWKAdDY/yTQJaqzCzyesUvQhD+WRxe1kpdCK8UE061S9/Ju7hLkM4kjRNA==", "dependencies": { - "@babel/runtime": "^7.24.7", - "@mui/utils": "^5.16.0" + "@babel/runtime": "^7.25.0", + "@mui/utils": "^5.16.6" }, "engines": { "node": ">=14.0.0" @@ -1565,9 +1469,9 @@ } }, "node_modules/@react-aria/ssr": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz", - "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.5.tgz", + "integrity": "sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==", "dependencies": { "@swc/helpers": "^0.5.0" }, @@ -1575,13 +1479,13 @@ "node": ">= 12" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@remix-run/router": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.1.tgz", - "integrity": "sha512-mCOMec4BKd6BRGBZeSnGiIgwsbLGp3yhVqAD8H+PxiRNEHgDpZb8J1TnrSDlg97t0ySKMQJTHCWBCmBpSmkF6Q==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.1.tgz", + "integrity": "sha512-S45oynt/WH19bHbIXjtli6QmwNYvaz+vtnubvNpNDvUOoA/OWh6j1OikIP3G+v5GHdxyC6EXoChG3HgYGEUfcg==", "engines": { "node": ">=14.0.0" } @@ -1598,9 +1502,9 @@ } }, "node_modules/@restart/ui": { - "version": "1.6.9", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.9.tgz", - "integrity": "sha512-mUbygUsJcRurjZCt1f77gg4DpheD1D+Sc7J3JjAkysUj7t8m4EBJVOqWC9788Qtbc69cJ+HlJc6jBguKwS8Mcw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.8.0.tgz", + "integrity": "sha512-xJEOXUOTmT4FngTmhdjKFRrVVF0hwCLNPdatLCHkyS4dkiSK12cEu1Y0fjxktjJrdst9jJIc5J6ihMJCoWEN/g==", "dependencies": { "@babel/runtime": "^7.21.0", "@popperjs/core": "^2.11.6", @@ -1626,9 +1530,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz", + "integrity": "sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==", "cpu": [ "arm" ], @@ -1639,9 +1543,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz", + "integrity": "sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==", "cpu": [ "arm64" ], @@ -1652,9 +1556,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz", + "integrity": "sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==", "cpu": [ "arm64" ], @@ -1665,9 +1569,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz", + "integrity": "sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==", "cpu": [ "x64" ], @@ -1678,9 +1582,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz", + "integrity": "sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==", "cpu": [ "arm" ], @@ -1691,9 +1595,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz", + "integrity": "sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==", "cpu": [ "arm" ], @@ -1704,9 +1608,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz", + "integrity": "sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==", "cpu": [ "arm64" ], @@ -1717,9 +1621,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz", + "integrity": "sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==", "cpu": [ "arm64" ], @@ -1730,9 +1634,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz", + "integrity": "sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==", "cpu": [ "ppc64" ], @@ -1743,9 +1647,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz", + "integrity": "sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==", "cpu": [ "riscv64" ], @@ -1756,9 +1660,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz", + "integrity": "sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==", "cpu": [ "s390x" ], @@ -1769,9 +1673,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz", + "integrity": "sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==", "cpu": [ "x64" ], @@ -1782,9 +1686,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz", + "integrity": "sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==", "cpu": [ "x64" ], @@ -1795,9 +1699,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz", + "integrity": "sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==", "cpu": [ "arm64" ], @@ -1808,9 +1712,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz", + "integrity": "sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==", "cpu": [ "ia32" ], @@ -1821,9 +1725,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz", + "integrity": "sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==", "cpu": [ "x64" ], @@ -1834,9 +1738,9 @@ ] }, "node_modules/@swc/helpers": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", - "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz", + "integrity": "sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==", "dependencies": { "tslib": "^2.4.0" } @@ -1931,13 +1835,13 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", + "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", "dev": true, "optional": true, "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/parse-json": { @@ -1951,9 +1855,9 @@ "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", + "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1990,9 +1894,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", - "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", + "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", "dependencies": { "@types/react": "*" } @@ -2015,9 +1919,9 @@ "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==" }, "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/@types/warning": { "version": "3.0.3", @@ -2035,16 +1939,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", - "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/type-utils": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -2068,15 +1972,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", - "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { @@ -2096,13 +2000,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", - "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2113,13 +2017,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", - "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2140,9 +2044,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", - "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2153,13 +2057,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", - "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2181,15 +2085,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", - "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2203,12 +2107,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", - "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2492,18 +2396,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", @@ -2576,9 +2468,9 @@ } }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true }, "node_modules/asynckit": { @@ -2629,9 +2521,9 @@ } }, "node_modules/aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", "dev": true }, "node_modules/babel-plugin-macros": { @@ -2756,9 +2648,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -2775,10 +2667,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2865,9 +2757,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", - "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", + "version": "1.0.30001653", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz", + "integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==", "dev": true, "funding": [ { @@ -3205,13 +3097,13 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cypress": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.0.tgz", - "integrity": "sha512-ou/MQUDq4tcDJI2FsPaod2FZpex4kpIK43JJlcBgWrX8WX7R/05ZxGTuxedOuZBfxjZxja+fbijZGyxiLP6CFA==", + "version": "13.14.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.14.0.tgz", + "integrity": "sha512-r0+nhd033x883YL6068futewUsl02Q7rWiinyAAIBDW/OOTn+UMILWgNuCiY3vtJjd53efOqq5R9dctQk/rKiw==", "dev": true, "hasInstallScript": true, "dependencies": { - "@cypress/request": "^3.0.0", + "@cypress/request": "^3.0.1", "@cypress/xvfb": "^1.2.4", "@types/sinonjs__fake-timers": "8.1.1", "@types/sizzle": "^2.3.2", @@ -3261,6 +3153,18 @@ "node": "^16.0.0 || ^18.0.0 || >=20.0.0" } }, + "node_modules/cypress-file-upload": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz", + "integrity": "sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g==", + "dev": true, + "engines": { + "node": ">=8.2.1" + }, + "peerDependencies": { + "cypress": ">3.0.0" + } + }, "node_modules/cypress-vite": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/cypress-vite/-/cypress-vite-1.5.0.tgz", @@ -3422,15 +3326,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dependencies": { "ms": "2.1.2" }, @@ -3588,9 +3507,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.818", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz", - "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==", "dev": true }, "node_modules/emoji-regex": { @@ -3913,13 +3832,13 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" + "synckit": "^0.9.1" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -3943,35 +3862,35 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", - "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", + "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", "dev": true, "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { @@ -3987,9 +3906,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.7.tgz", - "integrity": "sha512-yrj+KInFmwuQS2UQcg1SF83ha1tuHC1jMQbRNyuWtlEzzKRDgAl7L4Yp4NlDUZTZNlWvHEzOtJhMi40R7JxcSw==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.11.tgz", + "integrity": "sha512-wrAKxMbVr8qhXTtIKfXqAn5SAtRZt0aXxe5P23Fh4pUAdC6XEsybGLB8P0PI4j1yYqOgUEUlzKAGDfo7rJOjcw==", "dev": true, "peerDependencies": { "eslint": ">=7" @@ -4232,9 +4151,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -5028,9 +4947,9 @@ } }, "node_modules/i18next": { - "version": "23.11.5", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz", - "integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==", + "version": "23.14.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.14.0.tgz", + "integrity": "sha512-Y5GL4OdA8IU2geRrt2+Uc1iIhsjICdHZzT9tNwQ3TVqdNzgxHToGCKf/TPRP80vTCAP6svg2WbbJL+Gx5MFQVA==", "funding": [ { "type": "individual", @@ -5058,9 +4977,9 @@ } }, "node_modules/i18next-http-backend": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.2.tgz", - "integrity": "sha512-+K8HbDfrvc1/2X8jpb7RLhI9ZxBDpx3xogYkQwGKlWAUXLSEGXzgdt3EcUjLlBCdMwdQY+K+EUF6oh8oB6rwHw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.6.1.tgz", + "integrity": "sha512-rCilMAnlEQNeKOZY1+x8wLM5IpYOj10guGvEpeC59tNjj6MMreLIjIW8D1RclhD3ifLwn6d/Y9HEM1RUE6DSog==", "dependencies": { "cross-fetch": "4.0.0" } @@ -5086,9 +5005,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -5314,9 +5233,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dependencies": { "hasown": "^2.0.2" }, @@ -6209,9 +6128,9 @@ } }, "node_modules/mdast-util-mdx-jsx": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", - "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -6223,7 +6142,6 @@ "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, @@ -6750,9 +6668,9 @@ ] }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { "braces": "^3.0.3", @@ -6876,9 +6794,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "node_modules/nopt": { @@ -7021,23 +6939,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -7218,9 +7119,9 @@ } }, "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, "node_modules/parse-json": { "version": "5.2.0", @@ -7368,9 +7269,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -7608,10 +7509,25 @@ "react": ">= 16.8 || 18.0.0" } }, + "node_modules/react-hook-form": { + "version": "7.53.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.0.tgz", + "integrity": "sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, "node_modules/react-i18next": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz", - "integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==", + "version": "14.1.3", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.3.tgz", + "integrity": "sha512-wZnpfunU6UIAiJ+bxwOiTmBOAaB14ha97MjOEnLGac2RJ+h/maIYXZuTHlmyqQVX1UVHmU1YDTQ5vxLmwfXTjw==", "dependencies": { "@babel/runtime": "^7.23.9", "html-parse-stringify": "^3.0.1" @@ -7630,9 +7546,9 @@ } }, "node_modules/react-icons": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", - "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", "peerDependencies": { "react": "*" } @@ -7694,11 +7610,11 @@ } }, "node_modules/react-router": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.24.1.tgz", - "integrity": "sha512-PTXFXGK2pyXpHzVo3rR9H7ip4lSPZZc0bHG5CARmj65fTT6qG7sTngmb6lcYu1gf3y/8KxORoy9yn59pGpCnpg==", + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.1.tgz", + "integrity": "sha512-kIwJveZNwp7teQRI5QmwWo39A5bXRyqpH0COKKmPnyD2vBvDwgFXSqDUYtt1h+FEyfnE8eXr7oe0MxRzVwCcvQ==", "dependencies": { - "@remix-run/router": "1.17.1" + "@remix-run/router": "1.19.1" }, "engines": { "node": ">=14.0.0" @@ -7708,12 +7624,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.24.1.tgz", - "integrity": "sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==", + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.1.tgz", + "integrity": "sha512-veut7m41S1fLql4pLhxeSW3jlqs+4MtjRLj0xvuCEXsxusJCbs6I8yn9BxzzDX2XDgafrccY6hwjmd/bL54tFw==", "dependencies": { - "@remix-run/router": "1.17.1", - "react-router": "6.24.1" + "@remix-run/router": "1.19.1", + "react-router": "6.26.1" }, "engines": { "node": ">=14.0.0" @@ -7985,9 +7901,9 @@ } }, "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.1.tgz", + "integrity": "sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -8000,22 +7916,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", + "@rollup/rollup-android-arm-eabi": "4.21.1", + "@rollup/rollup-android-arm64": "4.21.1", + "@rollup/rollup-darwin-arm64": "4.21.1", + "@rollup/rollup-darwin-x64": "4.21.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.1", + "@rollup/rollup-linux-arm-musleabihf": "4.21.1", + "@rollup/rollup-linux-arm64-gnu": "4.21.1", + "@rollup/rollup-linux-arm64-musl": "4.21.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.1", + "@rollup/rollup-linux-riscv64-gnu": "4.21.1", + "@rollup/rollup-linux-s390x-gnu": "4.21.1", + "@rollup/rollup-linux-x64-gnu": "4.21.1", + "@rollup/rollup-linux-x64-musl": "4.21.1", + "@rollup/rollup-win32-arm64-msvc": "4.21.1", + "@rollup/rollup-win32-ia32-msvc": "4.21.1", + "@rollup/rollup-win32-x64-msvc": "4.21.1", "fsevents": "~2.3.2" } }, @@ -8121,9 +8037,9 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -8342,9 +8258,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true }, "node_modules/spdx-ranges": { @@ -8429,6 +8345,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -8525,17 +8451,17 @@ } }, "node_modules/style-to-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", - "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.7.tgz", + "integrity": "sha512-uSjr59G5u6fbxUfKbb8GcqMGT3Xs9v5IbPkjb0S16GyOeBLAzSRK0CixBv5YrYvzO6TDLzIS6QCn78tkqWngPw==", "dependencies": { "inline-style-parser": "0.2.3" } }, "node_modules/styled-components": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.11.tgz", - "integrity": "sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.12.tgz", + "integrity": "sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA==", "dependencies": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", @@ -8559,6 +8485,24 @@ "react-dom": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/styled-components/node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, "node_modules/styled-components/node_modules/stylis": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", @@ -8597,9 +8541,9 @@ } }, "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "dependencies": { "@pkgr/core": "^0.1.0", @@ -8751,9 +8695,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -8871,9 +8815,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8913,9 +8857,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "optional": true }, @@ -8961,19 +8905,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -9120,12 +9051,11 @@ } }, "node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "dependencies": { "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, "funding": { @@ -9147,14 +9077,14 @@ } }, "node_modules/vite": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", - "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz", + "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "postcss": "^8.4.41", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -9173,6 +9103,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -9190,6 +9121,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -9221,9 +9155,9 @@ } }, "node_modules/vite/node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "dev": true, "funding": [ { @@ -9310,13 +9244,13 @@ } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", "dev": true, "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", "is-finalizationregistry": "^1.0.2", @@ -9325,8 +9259,8 @@ "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" diff --git a/src/Geopilot.Frontend/package.json b/src/Geopilot.Frontend/package.json index 396daca5..74744252 100644 --- a/src/Geopilot.Frontend/package.json +++ b/src/Geopilot.Frontend/package.json @@ -20,6 +20,7 @@ "@mui/material": "^5.16.0", "@mui/x-data-grid": "^7.9.0", "bootstrap": "^5.3.3", + "date-fns": "^2.30.0", "dayjs": "^1.11.11", "i18next": "^23.11.5", "i18next-browser-languagedetector": "^8.0.0", @@ -29,6 +30,7 @@ "react-bootstrap": "^2.10.4", "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", + "react-hook-form": "^7.52.2", "react-i18next": "^14.1.2", "react-icons": "^5.2.1", "react-markdown": "^9.0.1", @@ -45,6 +47,7 @@ "@typescript-eslint/parser": "^7.15.0", "@vitejs/plugin-react": "^4.3.1", "cypress": "^13.13.0", + "cypress-file-upload": "^5.0.8", "cypress-vite": "^1.5.0", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", diff --git a/src/Geopilot.Frontend/public/locale/de/common.json b/src/Geopilot.Frontend/public/locale/de/common.json index 617036ae..2ce462a3 100644 --- a/src/Geopilot.Frontend/public/locale/de/common.json +++ b/src/Geopilot.Frontend/public/locale/de/common.json @@ -1,14 +1,17 @@ { "about": "Über", + "addAnotherDelivery": "Weitere Lieferung hinzufügen", "addMandate": "Mandat hinzufügen", "addOrganisation": "Organisation hinzufügen", "administration": "Administration", - "appSubTitle": "Online Validierung & Lieferung von Geodaten", + "and": "und", "bugTracking": "Bugtracking", "cancel": "Abbrechen", + "clickToUpload": "Zum Hochladen klicken", "close": "Schliessen", "codeLicenseInfo": "Der Code steht unter der MIT Lizenz im Github Repository zur Verfügung. Falls Ihnen Bugs begegnen, können Sie dort einen Issue eröffnen.", "comment": "Kommentar", + "completedWithErrors": "Mit Fehlern abgeschlossen", "contentNotFound": "Ups, nichts gefunden!", "createDelivery": "Lieferung erstellen", "createDeliveryFailed": "Bei der Lieferung ist ein unbekannter Fehler aufgetreten, bitte versuchen Sie es mit einer neuen Validierung.", @@ -18,27 +21,31 @@ "deleteDeliveryConfirmationTitle": "Möchten Sie die Daten der Lieferung wirklich löschen?", "deleteDelivery_one": "{{count}} Lieferung löschen", "deleteDelivery_other": "{{count}} Lieferungen löschen", + "deliver": "Daten liefern", "deliveredBy": "Geliefert von", "delivery": "Lieferung", + "deliveryCompleted": "Die Lieferung wurde erfolgreich abgeschlossen.", "deliveryDate": "Lieferdatum", "deliveryOverview": "Lieferübersicht", "deliveryOverviewDeleteError": "Beim Löschen ist ein Fehler aufgetreten: {{error}}", "deliveryOverviewDeleteIdError": "Beim Löschen der Lieferung mit ID {{id}} ist ein Fehler aufgetreten.", "deliveryOverviewDeleteIdNotExistError": "Die Lieferung mit der ID {{id}} existiert nicht und kann daher nicht gelöscht werden.", "deliveryOverviewLoadingError": "Beim Laden der Lieferungen ist ein Fehler aufgetreten: {{error}}", + "deliveryTitle": "Online Validierung & Lieferung von Geodaten", "development": "Entwicklung", "disconnect": "Verbindungen trennen", + "done": "Fertig", "downloadLogTooltip": "-Datei herunterladen", - "dropZoneDefaultText": "{{fileDescription}} hier ablegen oder klicken um vom lokalen Dateisystem auszuwählen.", - "dropZoneErrorChooseFile": "Bitte wählen Sie eine Datei (max. 200MB)", - "dropZoneErrorChooseFileOfType": "Bitte wählen Sie eine Datei (max. 200MB) mit einer der folgenden Dateiendungen: {{acceptedFileTypesText}}", - "dropZoneErrorFileTooLarge": "Die ausgewählte Datei ist über 200MB gross. Bitte wählen Sie eine kleinere Datei oder erstellen Sie eine ZIP-Datei.", - "dropZoneErrorNotSupported": "Der Dateityp wird nicht unterstützt. {{genericError}}", - "dropZoneErrorTooManyFiles": "Es kann nur eine Datei aufs Mal geprüft werden.", + "dragAndDrop": "Drag & Drop", "edit": "Bearbeiten", "email": "E-Mail", "errors": "Fehler", + "failed": "Fehlgeschlagen", "file": "Datei", + "fileDropzoneErrorChooseFile": "Bitte wählen Sie eine gültige Datei aus", + "fileDropzoneErrorFileTooLarge": "Die ausgewählte Datei ist über 200MB gross", + "fileDropzoneErrorNotSupported": "Der Dateityp wird nicht unterstützt", + "fileDropzoneErrorTooManyFiles": "Es kann nur eine Datei aufs Mal geprüft werden", "fileTypes": "Formate", "fileTypesLoadingError": "Beim Laden der Formate ist ein Fehler aufgetreten: {{error}}", "help": "Hilfe", @@ -47,6 +54,7 @@ "info": "Info", "invalidContentType": "Ungültiger Antworttyp", "isAdmin": "Ist Admin", + "isPartialDelivery": "Ist Teillieferung", "latitude": "Breite", "licenseInformation": "Lizenzinformationen", "licenses": "Lizenzen", @@ -63,6 +71,7 @@ "mandatesLoadingError": "Beim Laden der Mandate ist ein Fehler aufgetreten: {{error}}", "name": "Name", "noErrors": "Keine Fehler", + "or": "oder", "organisationDisconnectMessage": "Die Organisation wird von allen Mandaten und Benutzer:innen getrennt. Diese Aktion kann nicht rückgängig gemacht werden.", "organisationDisconnectTitle": "Möchten Sie die Organisation wirklich inaktiv setzen?", "organisationSaveError": "Beim Speichern der Organisation ist ein Fehler aufgetreten: {{error}}", @@ -71,14 +80,16 @@ "predecessor": "Vorgänger", "privacyPolicy": "Datenschutz", "reset": "Aktuelle Änderungen zurücksetzen", + "resetDelivery": "Lieferung zurücksetzen", "save": "Speichern", "spatialExtent": "Räumliche Ausdehnung", "spatialExtentIncompleteMessage": "Es müssen entweder alle Felder leer oder alle abgefüllt sein. Möchten Sie die aktuellen Änderungen zurücksetzen?", "spatialExtentIncompleteTitle": "Ungültige räumliche Ausdehnung", "stacBrowser": "STAC Browser", "termsOfUse": "Nutzungsbestimmungen", - "termsOfUseAcceptance": "Ich akzeptiere die .", + "termsOfUseAcceptance": "Ich akzeptiere die Nutzungsbestimmungen.", "type": "Typ", + "upload": "Hochladen", "uploadFile": "{{fileName}} hochladen...", "uploadNotSuccessful": "Der Upload war nicht erfolgreich. Die Validierung wurde abgebrochen.", "userDisconnectMessage": "Der Benutzer wird von allen Organisationen getrennt. Diese Aktion kann nicht rückgängig gemacht werden.", @@ -88,6 +99,7 @@ "users": "Benutzer:innen", "usersLoadingError": "Beim Laden der Benutzer:innen ist ein Fehler aufgetreten: {{error}}", "validate": "Validieren", + "validationIsRunning": "Die Datei wird gerade mit {{validators}} validiert...", "version": "Version", "versionInformation": "Versionsinformationen" } diff --git a/src/Geopilot.Frontend/public/locale/en/common.json b/src/Geopilot.Frontend/public/locale/en/common.json index 9533ed89..cc4dda1e 100644 --- a/src/Geopilot.Frontend/public/locale/en/common.json +++ b/src/Geopilot.Frontend/public/locale/en/common.json @@ -1,14 +1,17 @@ { "about": "About", + "addAnotherDelivery": "Add another delivery", "addMandate": "Add mandate", "addOrganisation": "Add organisation", "administration": "Administration", - "appSubTitle": "Online validation & delivery of geodata", + "and": "and", "bugTracking": "bug tracking", "cancel": "Cancel", + "clickToUpload": "Click to upload", "close": "Close", "codeLicenseInfo": "The code is available under the MIT license in the Github repository. If you encounter bugs, you can open a issue there.", "comment": "Comment", + "completedWithErrors": "Completed with errors", "contentNotFound": "Oops, nothing found!", "createDelivery": "Create delivery", "createDeliveryFailed": "An unknown error occurred during delivery, please try a new validation.", @@ -18,27 +21,31 @@ "deleteDeliveryConfirmationTitle": "Do you really want to delete the delivery data?", "deleteDelivery_one": "Delete {{count}} delivery", "deleteDelivery_other": "Delete {{count}} deliveries", + "deliver": "Deliver data", "deliveredBy": "Delivered by", "delivery": "Delivery", + "deliveryCompleted": "The delivery was completed successfully.", "deliveryDate": "Delivery date", "deliveryOverview": "Delivery overview", "deliveryOverviewDeleteError": "An error occurred while deleting the delivery: {{error}}", "deliveryOverviewDeleteIdError": "An error occurred while deleting the delivery with the ID {{id}}", "deliveryOverviewDeleteIdNotExistError": "The delivery with the ID {{id}} does not exist and therefore cannot be deleted.", "deliveryOverviewLoadError": "An error occurred while loading the deliveries: {{error}}", + "deliveryTitle": "Online validation & delivery of geodata", "development": "Development", "disconnect": "Disconnect", + "done": "Done", "downloadLogTooltip": "Download log file", - "dropZoneDefaultText": "Drop {{fileDescription}} here or click to select from local file system.", - "dropZoneErrorChooseFile": "Please choose a file (max. 200MB)", - "dropZoneErrorChooseFileOfType": "Please choose a file (max. 200MB) with one of the following file extensions: {{acceptedFileTypesText}}", - "dropZoneErrorFileTooLarge": "The selected file is larger than 200MB. Please choose a smaller file or create a ZIP file.", - "dropZoneErrorNotSupported": "The file type is not supported. {{genericError}}", - "dropZoneErrorTooManyFiles": "Only one file can be checked at a time.", + "dragAndDrop": "drag and drop", "edit": "Edit", "email": "Email", "errors": "Errors", + "failed": "Failed", "file": "File", + "fileDropzoneErrorChooseFile": "Please choose a valid file", + "fileDropzoneErrorFileTooLarge": "The selected file is larger than 200MB", + "fileDropzoneErrorNotSupported": "The file type is not supported", + "fileDropzoneErrorTooManyFiles": "Only one file can be checked at a time", "fileTypes": "Formats", "fileTypesLoadingError": "An error occurred while loading the formats: {{error}}", "help": "Help", @@ -47,6 +54,7 @@ "info": "Info", "invalidContentType": "Invalid response type", "isAdmin": "Is Admin", + "isPartialDelivery": "Is partial delivery", "latitude": "Latitude", "licenseInformation": "License information", "licenses": "Licenses", @@ -63,6 +71,7 @@ "mandatesLoadingError": "An error occurred while loading the mandates: {{error}}", "name": "Name", "noErrors": "No Errors", + "or": "or", "organisationDisconnectMessage": "This will remove all connections to mandates and users, and cannot be undone.", "organisationDisconnectTitle": "Do you really want to disconnect the organisation?", "organisationSaveError": "An error occurred while saving the organisation: {{error}}", @@ -71,14 +80,16 @@ "predecessor": "Predecessor", "privacyPolicy": "Privacy policy", "reset": "Reset current changes", + "resetDelivery": "Reset delivery", "save": "Save", "spatialExtent": "Spatial extent", "spatialExtentIncompleteMessage": "All fields must either be empty or filled in. Would you like to reset the current changes?", "spatialExtentIncompleteTitle": "Invalid spatial extent", "stacBrowser": "STAC Browser", "termsOfUse": "Terms of use", - "termsOfUseAcceptance": "I accept the .", + "termsOfUseAcceptance": "I accept the terms of use.", "type": "Type", + "upload": "Upload", "uploadFile": "Upload {{fileName}}...", "uploadNotSuccessful": "The upload was not successful. Validation has been aborted.", "userDisconnectMessage": "This will remove all connections to organisations and cannot be undone.", @@ -88,6 +99,7 @@ "users": "Users", "usersLoadingError": "An error occurred while loading the users: {{error}}", "validate": "Validate", + "validationIsRunning": "The file is currently being validated with {{validators}}...", "version": "Version", "versionInformation": "Version information" } diff --git a/src/Geopilot.Frontend/public/locale/fr/common.json b/src/Geopilot.Frontend/public/locale/fr/common.json index 99b9bd55..8b1a3da4 100644 --- a/src/Geopilot.Frontend/public/locale/fr/common.json +++ b/src/Geopilot.Frontend/public/locale/fr/common.json @@ -1,14 +1,17 @@ { "about": "À propos", + "addAnotherDelivery": "Ajouter une autre livraison", "addMandate": "Ajouter un mandat", "addOrganisation": "Ajouter une organisation", "administration": "Administration", - "appSubTitle": "Validation en ligne et livraison de données géographiques", + "and": "et", "bugTracking": "Suivi des bugs", "cancel": "Annuler", + "clickToUpload": "Cliquer pour télécharger", "close": "Fermer", "codeLicenseInfo": "Le code est disponible sous la licence MIT dans le référentiel GitHub. Si vous rencontrez des bugs, vous pouvez ouvrir un problème là-bas.", "comment": "Commentaire", + "completedWithErrors": "Terminé avec des erreurs", "contentNotFound": "Oups, rien n'a été trouvé!", "createDelivery": "Créer une livraison", "createDeliveryFailed": "Une erreur inconnue s'est produite lors de la livraison. Veuillez réessayer avec une nouvelle validation.", @@ -18,27 +21,31 @@ "deleteDeliveryConfirmationTitle": "Voulez-vous vraiment supprimer les données de la livraison?", "deleteDelivery_one": "Supprimer {{count}} livraison", "deleteDelivery_other": "Supprimer {{count}} livraisons", + "deliver": "Livrer les données", "deliveredBy": "Livré par", "delivery": "Livraison", + "deliveryCompleted": "La livraison a été effectuée avec succès.", "deliveryDate": "Date de livraison", "deliveryOverview": "Aperçu des livraisons", "deliveryOverviewDeleteError": "Une erreur s'est produite lors de la suppression: {{error}}", "deliveryOverviewDeleteIdError": "Une erreur s'est produite lors de la suppression de la livraison avec l'ID {{id}}.", "deliveryOverviewDeleteIdNotExistError": "La livraison avec l'ID {{id}} n'existe pas et ne peut donc pas être supprimée.", "deliveryOverviewLoadingError": "Une erreur s'est produite lors du chargement des livraisons: {{error}}", + "deliveryTitle": "Validation en ligne et livraison de données géographiques", "development": "Développement", "disconnect": "Déconnecter", + "done": "Terminé", "downloadLogTooltip": "Télécharger le fichier -", - "dropZoneDefaultText": "Déposez ou cliquez ici pour sélectionner un {{fileDescription}} à partir du système de fichiers local.", - "dropZoneErrorChooseFile": "Veuillez sélectionner un fichier (max. 200 Mo)", - "dropZoneErrorChooseFileOfType": "Veuillez sélectionner un fichier (max. 200 Mo) avec l'une des extensions de fichier suivantes : {{acceptedFileTypesText}}", - "dropZoneErrorFileTooLarge": "Le fichier sélectionné est supérieur à 200 Mo. Veuillez sélectionner un fichier plus petit ou créer un fichier ZIP.", - "dropZoneErrorNotSupported": "Le type de fichier n'est pas pris en charge. {{genericError}}", - "dropZoneErrorTooManyFiles": "Seul un fichier peut être vérifié à la fois.", + "dragAndDrop": "glisser et poser", "edit": "Éditer", "email": "E-mail", "errors": "Erreurs", + "failed": "Échoué", "file": "Fichier", + "fileDropzoneErrorChooseFile": "Veuillez sélectionner un fichier valide", + "fileDropzoneErrorFileTooLarge": "Le fichier sélectionné est supérieur à 200 Mo", + "fileDropzoneErrorNotSupported": "Le type de fichier n'est pas pris en charge", + "fileDropzoneErrorTooManyFiles": "Seul un fichier peut être vérifié à la fois", "fileTypes": "Formats", "fileTypesLoadingError": "Une erreur s'est produite lors du chargement des formats: {{error}}", "help": "Aide", @@ -47,6 +54,7 @@ "info": "Info", "invalidContentType": "Type de réponse non valide", "isAdmin": "Est administrateur", + "isPartialDelivery": "La livraison partielle est-elle", "latitude": "Latitude", "licenseInformation": "Informations sur la licence", "licenses": "Licences", @@ -63,6 +71,7 @@ "mandatesLoadingError": "Une erreur s'est produite lors du chargement des mandats: {{error}}", "name": "Nom", "noErrors": "Pas d'erreurs", + "or": "ou", "organisationDisconnectMessage": "Cette action supprime toutes les connexions avec les mandats et les utilisateurs. Cette action ne peut pas être annulée.", "organisationDisconnectTitle": "Voulez-vous vraiment déconnecter l'organisation?", "organisationSaveError": "Une erreur s'est produite lors de l'enregistrement de l'organisation: {{error}}", @@ -71,14 +80,16 @@ "predecessor": "Prédécesseur", "privacyPolicy": "Politique de confidentialité", "reset": "Réinitialiser les modifications en cours", + "resetDelivery": "Réinitialiser la livraison", "save": "Sauver", "spatialExtent": "Étendue spatiale", "spatialExtentIncompleteMessage": "Tous les champs doivent être soit vides, soit tous remplis. Vous souhaitez réinitialiser les modifications en cours?", "spatialExtentIncompleteTitle": "Étendue spatiale non valide", "stacBrowser": "Navigateur STAC", "termsOfUse": "Conditions d'utilisation", - "termsOfUseAcceptance": "J'accepte les .", + "termsOfUseAcceptance": "J'accepte les conditions d'utilisation.", "type": "Type", + "upload": "Télécharger", "uploadFile": "Télécharger {{fileName}}...", "uploadNotSuccessful": "Le téléchargement n'a pas réussi. La validation a été annulée.", "userDisconnectMessage": "Cet utilisateur sera déconnecté de toutes les organisations. Cette action ne peut pas être annulée.", @@ -88,6 +99,7 @@ "users": "Utilisateurs", "usersLoadingError": "Une erreur s'est produite lors du chargement des utilisateurs: {{error}}", "validate": "Valider", + "validationIsRunning": "Le fichier est en cours de validation avec {{validators}}...", "version": "Version", "versionInformation": "Informations sur la version" } diff --git a/src/Geopilot.Frontend/public/locale/it/common.json b/src/Geopilot.Frontend/public/locale/it/common.json index 51785a95..ca5a3e3f 100644 --- a/src/Geopilot.Frontend/public/locale/it/common.json +++ b/src/Geopilot.Frontend/public/locale/it/common.json @@ -1,14 +1,17 @@ { "about": "Informazioni", + "addAnotherDelivery": "Aggiungere un'altra consegna", "addMandate": "Aggiungi mandato", "addOrganisation": "Aggiungi organizzazione", "administration": "Amministrazione", - "appSubTitle": "Validazione online e consegna di dati geografici", + "and": "e", "bugTracking": "Tracciamento bug", "cancel": "Annulla", + "clickToUpload": "Clicca per caricare", "close": "Chiudi", "codeLicenseInfo": "Il codice è disponibile sotto la licenza MIT nel repository di GitHub. Se trovi dei bug, puoi aprire un Issue lì.", "comment": "Commento", + "completedWithErrors": "Completato con errori", "contentNotFound": "Ops, non è stato trovato nulla!", "createDelivery": "Crea consegna", "createDeliveryFailed": "Si è verificato un errore sconosciuto durante la consegna, prova a fare una nuova validazione.", @@ -18,27 +21,31 @@ "deleteDeliveryConfirmationTitle": "Vuoi davvero eliminare i dati della consegna?", "deleteDelivery_one": "Elimina {{count}} consegna", "deleteDelivery_other": "Elimina {{count}} consegne", + "deliver": "Consegna dati", "deliveredBy": "Consegnato da", "delivery": "Consegna", + "deliveryCompleted": "La consegna è stata completata con successo.", "deliveryDate": "Data di consegna", "deliveryOverview": "Panoramica consegne", "deliveryOverviewDeleteError": "Si è verificato un errore durante l'eliminazione: {{error}}", "deliveryOverviewDeleteIdError": "Si è verificato un errore durante l'eliminazione della consegna con ID {{id}}.", "deliveryOverviewDeleteIdNotExistError": "La consegna con ID {{id}} non esiste e non può essere eliminata.", "deliveryOverviewLoadingError": "Si è verificato un errore durante il caricamento delle consegne: {{error}}", + "deliveryTitle": "Validazione online e consegna di dati geografici", "development": "Sviluppo", "disconnect": "Disconnessione", + "done": "Fatto", "downloadLogTooltip": "Scarica file -", - "dropZoneDefaultText": "Trascina qui {{fileDescription}} o clicca per selezionare dal file system locale.", - "dropZoneErrorChooseFile": "Seleziona un file (max. 200MB)", - "dropZoneErrorChooseFileOfType": "Seleziona un file (max. 200MB) con una delle seguenti estensioni: {{acceptedFileTypesText}}", - "dropZoneErrorFileTooLarge": "Il file selezionato è troppo grande (oltre 200MB). Seleziona un file più piccolo o crea un file ZIP.", - "dropZoneErrorNotSupported": "Tipo di file non supportato. {{genericError}}", - "dropZoneErrorTooManyFiles": "Puoi verificare solo un file alla volta.", + "dragAndDrop": "drag and drop", "edit": "Modifica", "email": "E-mail", "errors": "Errori", + "failed": "Fallito", "file": "File", + "fileDropzoneErrorChooseFile": "Seleziona un file valido", + "fileDropzoneErrorFileTooLarge": "Il file selezionato è troppo grande (oltre 200MB)", + "fileDropzoneErrorNotSupported": "Tipo di file non supportato", + "fileDropzoneErrorTooManyFiles": "Puoi verificare solo un file alla volta", "fileTypes": "Formati", "fileTypesLoadingError": "Si è verificato un errore durante il caricamento dei formati: {{error}}", "help": "Aiuto", @@ -47,6 +54,7 @@ "info": "Informazioni", "invalidContentType": "Tipo di risposta non valido", "isAdmin": "È amministratore", + "isPartialDelivery": "È una consegna parziale", "latitude": "Latitudine", "licenseInformation": "Informazioni sulla licenza", "licenses": "Licenze", @@ -63,6 +71,7 @@ "mandatesLoadingError": "Si è verificato un errore durante il caricamento dei mandati: {{error}}", "name": "Nome", "noErrors": "Nessun errore", + "or": "o", "organisationDisconnectMessage": "Questa operazione rimuove tutti i collegamenti ai mandati e agli utenti, e non può essere annullata.", "organisationDisconnectTitle": "Volete davvero scollegare l'organizzazione?", "organisationSaveError": "Si è verificato un errore durante il salvataggio dell'organizzazione: {{error}}", @@ -71,14 +80,16 @@ "predecessor": "Predecessore", "privacyPolicy": "Informativa sulla privacy", "reset": "Ripristino delle modifiche correnti", + "resetDelivery": "Ripristino la consegna", "save": "Salvare", "spatialExtent": "Misura spaziale", "spatialExtentIncompleteMessage": "Tutti i campi devono essere vuoti o compilati. Volete ripristinare le modifiche correnti?", "spatialExtentIncompleteTitle": "Misura spaziale non valida", "stacBrowser": "Browser STAC", "termsOfUse": "Termini di utilizzo", - "termsOfUseAcceptance": "Accetto i .", + "termsOfUseAcceptance": "Accetto i Termini di utilizzo.", "type": "Tipo", + "upload": "Caricare", "uploadFile": "Carica {{fileName}}...", "uploadNotSuccessful": "Caricamento non riuscito. La validazione è stata interrotta.", "userDisconnectMessage": "Questa operazione rimuove tutti i collegamenti alle organizzazioni e non può essere annullata.", @@ -87,7 +98,8 @@ "userSaveError": "Si è verificato un errore durante il salvataggio dell'utente: {{error}}", "users": "Utenti", "usersLoadingError": "Si è verificato un errore durante il caricamento degli utenti: {{error}}", - "validate": "Valida", + "validate": "Validare", + "validationIsRunning": "Il file è in corso di validazione con {{validators}}...", "version": "Versione", "versionInformation": "Informazioni sulla versione" } diff --git a/src/Geopilot.Frontend/src/api/apiContext.tsx b/src/Geopilot.Frontend/src/api/apiContext.tsx index 98f48b93..05d158ae 100644 --- a/src/Geopilot.Frontend/src/api/apiContext.tsx +++ b/src/Geopilot.Frontend/src/api/apiContext.tsx @@ -27,8 +27,15 @@ export const ApiProvider: FC = ({ children }) => { throw new ApiError(t("invalidContentType", { contentType: responseContentType })); } } else { - const errorResponse = await response.json(); - throw new ApiError(errorResponse.detail, response.status); + let errorResponse; + const clonedResponse = response.clone(); + try { + const errorObject = await clonedResponse.json(); + errorResponse = errorObject.detail; + } catch (e) { + errorResponse = await response.text(); + } + throw new ApiError(errorResponse, response.status); } } catch (error) { if (options.errorMessageLabel) { diff --git a/src/Geopilot.Frontend/src/api/apiInterfaces.ts b/src/Geopilot.Frontend/src/api/apiInterfaces.ts index 5453355f..d5bb38b2 100644 --- a/src/Geopilot.Frontend/src/api/apiInterfaces.ts +++ b/src/Geopilot.Frontend/src/api/apiInterfaces.ts @@ -61,3 +61,26 @@ export interface User { organisations: Organisation[] | number[]; deliveries: Delivery[]; } + +export interface ValidationSettings { + allowedFileExtensions: string[]; +} + +export enum ValidationStatus { + Processing = "processing", + Completed = "completed", + CompletedWithErrors = "completedWithErrors", + Failed = "failed", +} + +export interface ValidatorResult { + status: string; + statusMessage: string; + logFiles: Record; +} + +export interface ValidationResponse { + jobId: string; + status: ValidationStatus; + validatorResults: Record; +} diff --git a/src/Geopilot.Frontend/src/app.tsx b/src/Geopilot.Frontend/src/app.tsx index 6e0cd4ce..02b64fe3 100644 --- a/src/Geopilot.Frontend/src/app.tsx +++ b/src/Geopilot.Frontend/src/app.tsx @@ -14,6 +14,7 @@ import Footer from "./pages/footer/footer"; import { PrivacyPolicy } from "./pages/footer/privacyPolicy.tsx"; import { About } from "./pages/footer/about.tsx"; import { Imprint } from "./pages/footer/imprint.tsx"; +import { DeliveryProvider } from "./pages/delivery/deliveryContext.tsx"; export const App: FC = () => { const [isSubMenuOpen, setIsSubMenuOpen] = useState(false); @@ -30,7 +31,14 @@ export const App: FC = () => { - } /> + + + + } + /> {isAdmin ? ( <> } /> diff --git a/src/Geopilot.Frontend/src/appContext.tsx b/src/Geopilot.Frontend/src/appContext.tsx index cc70f1fd..07ceca68 100644 --- a/src/Geopilot.Frontend/src/appContext.tsx +++ b/src/Geopilot.Frontend/src/appContext.tsx @@ -1,6 +1,6 @@ import { I18nextProvider } from "react-i18next"; import i18n from "./i18n"; -import { ThemeProvider } from "@mui/material"; +import { GlobalStyles, ThemeProvider } from "@mui/material"; import { PromptProvider } from "./components/prompt/promptContext.tsx"; import { Prompt } from "./components/prompt/prompt.tsx"; import { AlertProvider } from "./components/alert/alertContext.tsx"; @@ -62,6 +62,15 @@ export const AppContext = () => { return ( + diff --git a/src/Geopilot.Frontend/src/appInterfaces.ts b/src/Geopilot.Frontend/src/appInterfaces.ts index ed11dc98..6cfc612a 100644 --- a/src/Geopilot.Frontend/src/appInterfaces.ts +++ b/src/Geopilot.Frontend/src/appInterfaces.ts @@ -8,14 +8,3 @@ export enum Language { export interface TranslationFunction { (key: string): string; } - -export type ModalContentType = "markdown" | "raw"; - -export interface Validation { - allowedFileExtensions: string[]; -} - -export interface ErrorResponse { - status: string; - detail: string; -} diff --git a/src/Geopilot.Frontend/src/appTheme.ts b/src/Geopilot.Frontend/src/appTheme.ts index 4dba2805..556e8993 100644 --- a/src/Geopilot.Frontend/src/appTheme.ts +++ b/src/Geopilot.Frontend/src/appTheme.ts @@ -4,79 +4,127 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; export const geopilotTheme = createTheme({ palette: { primary: { - main: "#3A6060", - hover: "#3A60600A", + main: "#124A4F", + inactive: "#124A4F99", + hover: "#124A4F0D", contrastText: "#ffffff", }, secondary: { main: "#00ff97", - hover: "#00ff970A", + inactive: "#00ff9799", + hover: "#00ff970D", contrastText: "#000", }, + success: { + main: "#4caf51", + hover: "#4caf510D", + }, warning: { main: "#fd9903", + hover: "#fd99030D", }, error: { main: "#e53835", - }, - success: { - main: "#4caf51", + hover: "#e538350D", }, }, typography: { fontFamily: "NeoGeo, sans-serif", body1: { - fontSize: "14px", + fontSize: "16px", + letterSpacing: "0.05em", }, body2: { fontSize: "14px", + letterSpacing: "0.05em", + }, + caption: { + letterSpacing: "0.1em", + }, + button: { + fontSize: "16px", + letterSpacing: "0.05em", }, h1: { fontSize: "28px", fontWeight: 600, + letterSpacing: "0.05em", marginTop: "1rem", marginBottom: "0.5rem", }, h2: { fontSize: "24px", fontWeight: 600, + letterSpacing: "0.05em", marginTop: "1rem", marginBottom: "0.5rem", }, h3: { fontSize: "20px", fontWeight: 600, + letterSpacing: "0.05em", marginTop: "1rem", marginBottom: "0.5rem", }, h4: { fontSize: "18px", fontWeight: 600, + letterSpacing: "0.05em", marginTop: "1rem", marginBottom: "0.5rem", }, h5: { fontSize: "16px", fontWeight: 600, + letterSpacing: "0.05em", marginTop: "1rem", marginBottom: "0.5rem", }, h6: { fontSize: "14px", fontWeight: 600, + letterSpacing: "0.05em", marginTop: "1rem", marginBottom: "0.5rem", }, }, components: { + MuiTypography: { + styleOverrides: { + root: { + "&.Mui-disabled": { + opacity: "60%", + cursor: "default", + }, + }, + }, + }, MuiAvatar: { styleOverrides: { root: { - backgroundColor: "#3A6060", + backgroundColor: "#124A4F", color: "#ffffff", }, }, }, + MuiFormControl: { + styleOverrides: { + root: { + "& .MuiFilledInput-root": { + backgroundColor: "rgba(0,0,0,0.04)", + }, + "& .MuiFilledInput-root:hover:not(.Mui-disabled, .Mui-error):before": { + borderColor: "#124A4F", + }, + "& .MuiFilledInput-root:not(.Mui-error):before": { + borderColor: "#124A4F", + }, + "& .MuiFilledInput-root:not(.Mui-error):after": { + borderColor: "#124A4F", + }, + }, + }, + }, MuiSelect: { defaultProps: { IconComponent: ExpandMoreIcon, @@ -87,6 +135,45 @@ export const geopilotTheme = createTheme({ disableRipple: true, }, }, + MuiButton: { + styleOverrides: { + root: { + fontWeight: "500", + borderRadius: "4px", + boxShadow: "none", + "&:hover": { + boxShadow: "none", + }, + "&.Mui-disabled": { + "&.MuiButton-text": { + backgroundColor: "transparent", + color: "#124A4F99", + }, + "&.MuiButton-contained": { + backgroundColor: "#124A4F99", + color: "#ffffff", + }, + "&.MuiButton-outlined": { + backgroundColor: "transparent", + color: "#124A4F99", + borderColor: "#124A4F99", + }, + }, + }, + }, + }, + MuiIconButton: { + styleOverrides: { + root: { + "&:hover, &.Mui-focusVisible, &:active, &:focus, &:focus-visible": { + backgroundColor: "rgba(0, 0, 0, 0.0)", + }, + "& .MuiTouchRipple-root": { + display: "none", + }, + }, + }, + }, MuiAppBar: { styleOverrides: { root: { @@ -106,5 +193,26 @@ export const geopilotTheme = createTheme({ }, }, }, + MuiStepLabel: { + styleOverrides: { + label: { + fontSize: "16px", + letterSpacing: "0.05em", + "&.Mui-active": { + fontWeight: 600, + }, + "&.Mui-completed": { + fontWeight: 600, + }, + }, + }, + }, + MuiStepContent: { + styleOverrides: { + root: { + padding: "24px 0 0 40px", + }, + }, + }, }, }); diff --git a/src/Geopilot.Frontend/src/components/adminGrid/adminGrid.tsx b/src/Geopilot.Frontend/src/components/adminGrid/adminGrid.tsx index 564d75b9..dda2f6b4 100644 --- a/src/Geopilot.Frontend/src/components/adminGrid/adminGrid.tsx +++ b/src/Geopilot.Frontend/src/components/adminGrid/adminGrid.tsx @@ -1,5 +1,4 @@ import { FC, useEffect, useState } from "react"; -import Button from "@mui/material/Button"; import AddIcon from "@mui/icons-material/Add"; import { DataGrid, @@ -23,6 +22,7 @@ import { TransformToMultiSelectColumn, } from "../dataGrid/dataGridMultiSelectColumn"; import { IsGridSpatialExtentColDef, TransformToSpatialExtentColumn } from "../dataGrid/dataGridSpatialExtentColumn"; +import { BaseButton } from "../buttons.tsx"; export const AdminGrid: FC = ({ addLabel, data, columns, onSave, onDisconnect, disableRow }) => { const { t } = useTranslation(); @@ -191,15 +191,14 @@ export const AdminGrid: FC = ({ addLabel, data, columns, onSave, return ( <> {!!addLabel && ( - + onClick={addRow} + label={addLabel} + /> )} ({ @@ -11,7 +11,7 @@ export const AlertContext = createContext({ closeAlert: () => {}, }); -export const AlertProvider: FC = ({ children }) => { +export const AlertProvider: FC = ({ children }) => { const [currentAlert, setCurrentAlert] = useState(); const [alerts, setAlerts] = useState([]); diff --git a/src/Geopilot.Frontend/src/components/alert/alertInterfaces.ts b/src/Geopilot.Frontend/src/components/alert/alertInterfaces.ts index 8f6690b1..d11a6b2c 100644 --- a/src/Geopilot.Frontend/src/components/alert/alertInterfaces.ts +++ b/src/Geopilot.Frontend/src/components/alert/alertInterfaces.ts @@ -1,4 +1,3 @@ -import { ReactNode } from "react"; import { AlertColor } from "@mui/material"; export interface AlertContextInterface { @@ -15,7 +14,3 @@ export interface AlertOptions { severity?: AlertColor; allowAutoHide?: boolean; } - -export interface AlertProviderProps { - children: ReactNode; -} diff --git a/src/Geopilot.Frontend/src/components/appSettings/appSettingsContext.tsx b/src/Geopilot.Frontend/src/components/appSettings/appSettingsContext.tsx index beb1dd18..fc6f54a4 100644 --- a/src/Geopilot.Frontend/src/components/appSettings/appSettingsContext.tsx +++ b/src/Geopilot.Frontend/src/components/appSettings/appSettingsContext.tsx @@ -4,6 +4,7 @@ import { useApi } from "../../api"; import { ContentType } from "../../api/apiInterfaces.ts"; export const AppSettingsContext = createContext({ + initialized: false, version: undefined, clientSettings: undefined, termsOfUse: undefined, @@ -11,16 +12,22 @@ export const AppSettingsContext = createContext({ export const AppSettingsProvider: FC = ({ children }) => { const { fetchApi } = useApi(); - const [clientSettings, setClientSettings] = useState(); - const [backendVersion, setBackendVersion] = useState(""); - const [termsOfUse, setTermsOfUse] = useState(); + const [clientSettings, setClientSettings] = useState(); + const [backendVersion, setBackendVersion] = useState(); + const [termsOfUse, setTermsOfUse] = useState(); useEffect(() => { - fetchApi("client-settings.json").then(setClientSettings); - fetchApi("/api/v1/version").then(version => { - setBackendVersion(version.split("+")[0]); - }); - fetchApi("terms-of-use.md", { responseType: ContentType.Markdown }).then(setTermsOfUse); + fetchApi("client-settings.json") + .then(setClientSettings) + .catch(() => setClientSettings(null)); + fetchApi("/api/v1/version") + .then(version => { + setBackendVersion(version.split("+")[0]); + }) + .catch(() => setBackendVersion(null)); + fetchApi("terms-of-use.md", { responseType: ContentType.Markdown }) + .then(setTermsOfUse) + .catch(() => setTermsOfUse(null)); }, [fetchApi]); useEffect(() => { @@ -58,6 +65,7 @@ export const AppSettingsProvider: FC = ({ children }) => { return ( useContext(AppSettingsContext); diff --git a/src/Geopilot.Frontend/src/components/buttons.tsx b/src/Geopilot.Frontend/src/components/buttons.tsx new file mode 100644 index 00000000..1e93a6a9 --- /dev/null +++ b/src/Geopilot.Frontend/src/components/buttons.tsx @@ -0,0 +1,31 @@ +import { ButtonProps as MuiButtonProps } from "@mui/material/Button"; +import * as React from "react"; +import { forwardRef } from "react"; +import { Button } from "@mui/material"; +import { useTranslation } from "react-i18next"; +import CancelOutlinedIcon from "@mui/icons-material/CancelOutlined"; + +export interface ButtonProps extends MuiButtonProps { + onClick: () => void; + label?: string; + icon?: React.ReactNode; +} + +export const BaseButton = forwardRef((props, ref) => { + const { t } = useTranslation(); + return ( + + ); +}); + +export const CancelButton = forwardRef((props, ref) => { + return } />; +}); diff --git a/src/Geopilot.Frontend/src/components/dataGrid/dataGridSpatialExtentPopoverContent.tsx b/src/Geopilot.Frontend/src/components/dataGrid/dataGridSpatialExtentPopoverContent.tsx index 7a20368e..28a3b739 100644 --- a/src/Geopilot.Frontend/src/components/dataGrid/dataGridSpatialExtentPopoverContent.tsx +++ b/src/Geopilot.Frontend/src/components/dataGrid/dataGridSpatialExtentPopoverContent.tsx @@ -2,6 +2,7 @@ import { ChangeEvent, FC } from "react"; import { Coordinate } from "../../api/apiInterfaces"; import { useTranslation } from "react-i18next"; import { Box, Button, TextField } from "@mui/material"; +import { FlexRowEndBox, FlexRowSpaceBetweenBox } from "../styledComponents.ts"; interface SpatialExtentPopoverContentProps { spatialExtent: Coordinate[]; @@ -22,7 +23,7 @@ export const DataGridSpatialExtentPopoverContent: FC ( - + - + ); return ( @@ -58,11 +59,11 @@ export const DataGridSpatialExtentPopoverContent: FC{t("spatialExtent")} {renderCoordinateRow(0)} {renderCoordinateRow(1)} -
+ -
+
); }; diff --git a/src/Geopilot.Frontend/src/components/fileDropzone.tsx b/src/Geopilot.Frontend/src/components/fileDropzone.tsx new file mode 100644 index 00000000..9eb2957d --- /dev/null +++ b/src/Geopilot.Frontend/src/components/fileDropzone.tsx @@ -0,0 +1,155 @@ +import { CSSProperties, FC, useCallback, useEffect, useMemo, useState } from "react"; +import { IconButton, Link, Typography } from "@mui/material"; +import ClearIcon from "@mui/icons-material/Clear"; +import { FileRejection, useDropzone } from "react-dropzone"; +import { useTranslation } from "react-i18next"; +import { geopilotTheme } from "../appTheme"; +import { FlexRowBox } from "./styledComponents.ts"; + +interface FileDropzoneProps { + selectedFile?: File; + setSelectedFile: (file: File | undefined) => void; + fileExtensions?: string[]; + disabled?: boolean; + setFileError: (error: string | undefined) => void; +} + +export const FileDropzone: FC = ({ + selectedFile, + setSelectedFile, + fileExtensions, + disabled, + setFileError, +}) => { + const { t } = useTranslation(); + const [acceptsAllFileTypes, setAcceptsAllFileTypes] = useState(true); + const [error, setError] = useState(); + + useEffect(() => { + setFileError(error); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [error]); + + useEffect(() => { + setAcceptsAllFileTypes(!fileExtensions || fileExtensions?.includes(".*")); + }, [fileExtensions]); + + const getAcceptedFileTypesText = useCallback(() => { + return acceptsAllFileTypes + ? "" + : (fileExtensions?.length ?? 0) > 1 + ? `${fileExtensions!.slice(0, -1).join(", ")} ${t("or")} ${fileExtensions!.slice(-1)}` + : fileExtensions?.join(", ") ?? ""; + }, [acceptsAllFileTypes, fileExtensions, t]); + + const onDrop = useCallback( + (acceptedFiles: File[], fileRejections: FileRejection[]) => { + if (error) { + setError(undefined); + } + if (fileRejections.length > 0) { + let errorMessage: string; + const errorCode = fileRejections[0].errors[0].code; + + switch (errorCode) { + case "file-invalid-type": + errorMessage = t("fileDropzoneErrorNotSupported"); + break; + case "too-many-files": + errorMessage = t("fileDropzoneErrorTooManyFiles"); + break; + case "file-too-large": + errorMessage = t("fileDropzoneErrorFileTooLarge"); + break; + default: + errorMessage = t("fileDropzoneErrorChooseFile"); + break; + } + + setError(errorMessage); + } else { + setSelectedFile(acceptedFiles[0]); + } + }, + [error, t, setSelectedFile], + ); + + const { getRootProps, getInputProps } = useDropzone({ + onDrop, + maxFiles: 1, + maxSize: 209715200, + accept: acceptsAllFileTypes + ? undefined + : { + "application/x-geopilot-files": fileExtensions ?? [], + }, + disabled, + }); + + const handleRemove = () => { + if (!disabled) { + setSelectedFile(undefined); + } + }; + + const style = useMemo( + () => ({ + display: "flex", + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + minHeight: "100px", + padding: "20px", + border: `2px dashed`, + borderColor: disabled + ? geopilotTheme.palette.primary.inactive + : error + ? geopilotTheme.palette.error.main + : geopilotTheme.palette.primary.main, + borderRadius: "4px", + backgroundColor: error ? geopilotTheme.palette.error.hover : geopilotTheme.palette.primary.hover, + outline: "none", + transition: "border .24s ease-in-out", + cursor: disabled ? "default" : "pointer", + }), + [disabled, error], + ); + + return ( +
+ + {!selectedFile ? ( + <> + + {t("clickToUpload")} +   + {t("or")} {t("dragAndDrop")} + + {fileExtensions && fileExtensions.length > 0 && ( + + {getAcceptedFileTypesText()} (max. 200 MB) + + )} + + ) : ( + + + {selectedFile?.name} + + { + e.stopPropagation(); + handleRemove(); + }}> + + + + )} +
+ ); +}; diff --git a/src/Geopilot.Frontend/src/components/form/form.ts b/src/Geopilot.Frontend/src/components/form/form.ts new file mode 100644 index 00000000..108b85b6 --- /dev/null +++ b/src/Geopilot.Frontend/src/components/form/form.ts @@ -0,0 +1,36 @@ +import { FieldError, FieldErrorsImpl } from "react-hook-form/dist/types/errors"; +import { Merge } from "react-hook-form"; + +export const getFormFieldError = ( + fieldName: string | undefined, + errors: FieldError | Merge | undefined, +) => { + if (!fieldName || !errors) { + return false; + } + + const fieldNameElements = fieldName ? fieldName.split(".") : []; + let currentElement = errors; + for (let i = 0; i < fieldNameElements.length; i++) { + // @ts-expect-error - we know that currentElement either has a key of fieldNameElements[i] or it doesn't, + // which is what we're checking for + currentElement = currentElement[fieldNameElements[i]]; + if (!currentElement) { + break; + } + } + return !!currentElement; +}; + +export enum FormValueType { + Text = "text", + Number = "number", + Date = "date", + DateTime = "datetime-local", + Boolean = "boolean", + Domain = "domain", +} + +export { FormInput } from "./formInput"; +export { FormSelect } from "./formSelect"; +export { FormCheckbox } from "./formCheckbox"; diff --git a/src/Geopilot.Frontend/src/components/form/formCheckbox.tsx b/src/Geopilot.Frontend/src/components/form/formCheckbox.tsx new file mode 100644 index 00000000..22fb6f42 --- /dev/null +++ b/src/Geopilot.Frontend/src/components/form/formCheckbox.tsx @@ -0,0 +1,33 @@ +import { Checkbox, FormControlLabel, SxProps } from "@mui/material"; +import { useTranslation } from "react-i18next"; +import { useFormContext } from "react-hook-form"; +import { FC, ReactNode } from "react"; + +export interface FormCheckboxProps { + fieldName: string; + label: string | ReactNode; + checked: boolean; + disabled?: boolean; + sx?: SxProps; + validation?: object; +} + +export const FormCheckbox: FC = ({ fieldName, label, checked, disabled, sx, validation }) => { + const { t } = useTranslation(); + const { register } = useFormContext(); + + return ( + + } + label={typeof label === "string" ? t(label) : label} + /> + ); +}; diff --git a/src/Geopilot.Frontend/src/components/form/formField.tsx b/src/Geopilot.Frontend/src/components/form/formField.tsx new file mode 100644 index 00000000..cc4c17fd --- /dev/null +++ b/src/Geopilot.Frontend/src/components/form/formField.tsx @@ -0,0 +1,25 @@ +import { ForwardedRef, forwardRef } from "react"; +import { SxProps, TextField } from "@mui/material"; + +interface FormFieldProps { + sx?: SxProps; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [key: string]: any; +} + +export const FormField = forwardRef((props: FormFieldProps, ref: ForwardedRef) => { + return ( + + ); +}); diff --git a/src/Geopilot.Frontend/src/components/form/formInput.tsx b/src/Geopilot.Frontend/src/components/form/formInput.tsx new file mode 100644 index 00000000..078c8854 --- /dev/null +++ b/src/Geopilot.Frontend/src/components/form/formInput.tsx @@ -0,0 +1,86 @@ +import { useTranslation } from "react-i18next"; +import { useFormContext } from "react-hook-form"; +import { FormValueType, getFormFieldError } from "./form"; +import { FormField } from "./formField"; +import { FC } from "react"; +import { InputProps, SxProps } from "@mui/material"; +import { isValid } from "date-fns"; + +export interface FormInputProps { + fieldName: string; + label: string; + required?: boolean; + disabled?: boolean; + type?: FormValueType; + multiline?: boolean; + rows?: number; + value?: string | number; + sx?: SxProps; + inputProps?: InputProps; + onUpdate?: (value: string) => void; +} + +export const FormInput: FC = ({ + fieldName, + label, + required, + disabled, + type, + multiline, + rows, + value, + sx, + inputProps, + onUpdate, +}) => { + const { t } = useTranslation(); + const { formState, register, setValue } = useFormContext(); + + const getDefaultValue = (value: string | number | undefined) => { + if (value == undefined) { + return ""; + } else if (type === FormValueType.DateTime) { + // re-format from 'YYYY-MM-DDTHH:mm:ss.sssZ' to 'YYYY-MM-DDTHH:mm'. + return (value as string).slice(0, 16); + } else { + return value; + } + }; + + return ( + { + if (value === "") { + return true; + } + if (type === FormValueType.Date || type === FormValueType.DateTime) { + const date = new Date(value); + return isValid(date) && date.getFullYear() > 1800 && date.getFullYear() < 3000; + } + return true; + }, + onChange: e => { + setValue(fieldName, e.target.value, { shouldValidate: true }); + if (onUpdate) { + onUpdate(e.target.value); + } + }, + })} + defaultValue={getDefaultValue(value)} + disabled={disabled || false} + data-cy={fieldName + "-formInput"} + InputLabelProps={{ shrink: true }} + InputProps={{ ...inputProps }} + /> + ); +}; diff --git a/src/Geopilot.Frontend/src/components/form/formSelect.tsx b/src/Geopilot.Frontend/src/components/form/formSelect.tsx new file mode 100644 index 00000000..b9077f31 --- /dev/null +++ b/src/Geopilot.Frontend/src/components/form/formSelect.tsx @@ -0,0 +1,94 @@ +import { MenuItem, SxProps } from "@mui/material"; +import { useTranslation } from "react-i18next"; +import { Controller, useFormContext } from "react-hook-form"; +import { getFormFieldError } from "./form"; +import { FormField } from "./formField"; +import { FC } from "react"; + +export interface FormSelectProps { + fieldName: string; + label: string; + required?: boolean; + disabled?: boolean; + selected?: number[]; + values?: FormSelectValue[]; + sx?: SxProps; + onUpdate?: (value: number) => void; +} + +export interface FormSelectValue { + key: number; + name: string; +} + +export interface FormSelectMenuItem { + key: number; + value?: number; + label: string; + italic?: boolean; +} + +export const FormSelect: FC = ({ + fieldName, + label, + required, + disabled, + selected, + values, + sx, + onUpdate, +}) => { + const { t } = useTranslation(); + const { control } = useFormContext(); + + const menuItems: FormSelectMenuItem[] = []; + menuItems.push({ key: 0, value: undefined, label: t("reset"), italic: true }); + + if (values) { + values.forEach(value => { + menuItems.push({ + key: value.key, + value: value.key, + label: value.name, + }); + }); + } + + return ( + { + if (onUpdate) { + onUpdate(e.target.value); + } + }, + }} + render={({ field, formState }) => ( + + {menuItems.map(item => ( + + {item.italic ? {item.label} : item.label} + + ))} + + )} + /> + ); +}; diff --git a/src/Geopilot.Frontend/src/components/header/header.tsx b/src/Geopilot.Frontend/src/components/header/header.tsx index 73d14865..b27f20b4 100644 --- a/src/Geopilot.Frontend/src/components/header/header.tsx +++ b/src/Geopilot.Frontend/src/components/header/header.tsx @@ -5,7 +5,6 @@ import { AppBar, Avatar, Box, - Button, Divider, Drawer, IconButton, @@ -24,6 +23,8 @@ import { useAppSettings } from "../appSettings/appSettingsInterface"; import { useGeopilotAuth } from "../../auth"; import { LanguagePopup } from "./languagePopup"; import MenuIcon from "@mui/icons-material/Menu"; +import { FlexColumnSpaceBetweenBox, FlexRowBox } from "../styledComponents.ts"; +import { BaseButton } from "../buttons.tsx"; interface HeaderProps { openSubMenu: () => void; @@ -59,7 +60,7 @@ const Header: FC = ({ openSubMenu }) => { flexDirection: "row", justifyContent: "space-between", }}> - + {hasSubMenu ? ( = ({ openSubMenu }) => { )} - - + + {enabled && (user ? ( @@ -133,27 +128,24 @@ const Header: FC = ({ openSubMenu }) => { ) : ( <> - + label="logIn" + /> ))} - + - @@ -208,15 +200,8 @@ const Header: FC = ({ openSubMenu }) => { )} - - + } label="logOut" /> + ); diff --git a/src/Geopilot.Frontend/src/pages/footer/markdownContent.tsx b/src/Geopilot.Frontend/src/components/markdownContent.tsx similarity index 81% rename from src/Geopilot.Frontend/src/pages/footer/markdownContent.tsx rename to src/Geopilot.Frontend/src/components/markdownContent.tsx index 5d1b7a23..5d532880 100644 --- a/src/Geopilot.Frontend/src/pages/footer/markdownContent.tsx +++ b/src/Geopilot.Frontend/src/components/markdownContent.tsx @@ -8,19 +8,21 @@ import { Typography } from "@mui/material"; interface MarkdownContentProps { content: string; + routeHash?: string; } -export const MarkdownContent: FC = ({ content }) => { +export const MarkdownContent: FC = ({ content, routeHash }) => { return ( rehypeExternalLinks({ target: "_blank" })]} components={{ - h1: props => , + h1: props => , h2: props => , h3: props => , h4: props => , h5: props => , h6: props => , + p: props => , }}> {content} diff --git a/src/Geopilot.Frontend/src/components/styledComponents.ts b/src/Geopilot.Frontend/src/components/styledComponents.ts index c7840404..3b2d9914 100644 --- a/src/Geopilot.Frontend/src/components/styledComponents.ts +++ b/src/Geopilot.Frontend/src/components/styledComponents.ts @@ -1,32 +1,56 @@ import { Box } from "@mui/material"; import { styled } from "@mui/system"; -export const AppBox = styled(Box)({ +export const FlexBox = styled(Box)({ display: "flex", + gap: "10px", +}); + +export const FlexRowBox = styled(FlexBox)({ + flexDirection: "row", + alignItems: "center", + flexWrap: "wrap", +}); + +export const FlexRowSpaceBetweenBox = styled(FlexRowBox)({ + justifyContent: "space-between", +}); + +export const FlexRowCenterBox = styled(FlexRowBox)({ + justifyContent: "center", +}); + +export const FlexRowEndBox = styled(FlexRowBox)({ + justifyContent: "flex-end", +}); + +export const FlexColumnBox = styled(FlexBox)({ flexDirection: "column", +}); + +export const FlexColumnSpaceBetweenBox = styled(FlexColumnBox)({ + justifyContent: "space-between", +}); + +export const AppBox = styled(FlexColumnBox)({ height: "100vh", }); -export const LayoutBox = styled(Box)({ +export const LayoutBox = styled(FlexColumnBox)({ marginTop: "60px", flex: "1 1 100%", - display: "flex", - flexDirection: "column", minHeight: "calc(100vh - 60px)", }); -export const PageContentBox = styled(Box)({ +export const PageContentBox = styled(FlexColumnBox)({ padding: "20px", flex: "1 1 100%", - display: "flex", - flexDirection: "column", alignItems: "center", }); -export const CenteredBox = styled(Box)({ +export const CenteredBox = styled(FlexColumnBox)({ margin: "40px 0", width: "100%", + height: "100%", maxWidth: "1000px", - display: "flex", - flexDirection: "column", }); diff --git a/src/Geopilot.Frontend/src/index.css b/src/Geopilot.Frontend/src/index.css index e422b4a7..e69de29b 100644 --- a/src/Geopilot.Frontend/src/index.css +++ b/src/Geopilot.Frontend/src/index.css @@ -1,8 +0,0 @@ -body, p, h1, h2, h3, h4, h5, h6, em, strong, small, mark, del, ins, sub, sup, blockquote, q, ul, ol, li, a, img, table, tr, td, th, video, audio, iframe, form, input, textarea, button, header, footer, section, article, nav, aside, figure, figcaption { - font-family: 'NeoGeo', "system-ui", sans-serif; - letter-spacing: 0.05em; -} - -body, p, span { - font-size: 14px; -} diff --git a/src/Geopilot.Frontend/src/mui.theme.d.ts b/src/Geopilot.Frontend/src/mui.theme.d.ts index 751a18de..124cc68f 100644 --- a/src/Geopilot.Frontend/src/mui.theme.d.ts +++ b/src/Geopilot.Frontend/src/mui.theme.d.ts @@ -5,30 +5,41 @@ declare module "@mui/material/styles" { palette: { primary: { main: string; + inactive: string; hover: string; contrastText: string; }; secondary: { main: string; + inactive: string; hover: string; contrastText: string; }; success: { main: string; + hover: string; }; warning: { main: string; + hover: string; }; error: { main: string; + hover: string; }; }; components: { + MuiTypography: object; MuiAvatar: object; + MuiFormControl: object; MuiSelect: object; MuiButtonBase: object; + MuiButton: object; + MuiIconButton: object; MuiAppBar: object; MuiDataGrid: object; + MuiStepLabel: object; + MuiStepContent: object; }; } // allow configuration using `createTheme` @@ -36,30 +47,41 @@ declare module "@mui/material/styles" { palette?: { primary: { main: string; + inactive: string; hover: string; contrastText: string; }; secondary: { main: string; + inactive: string; hover: string; contrastText: string; }; success: { main: string; + hover: string; }; warning: { main: string; + hover: string; }; error: { main: string; + hover: string; }; }; components?: { + MuiTypography: object; MuiAvatar: object; + MuiFormControl: object; MuiSelect: object; MuiButtonBase: object; + MuiButton: object; + MuiIconButton: object; MuiAppBar: object; MuiDataGrid: object; + MuiStepLabel: object; + MuiStepContent: object; }; } export function createTheme(options?: CustomThemeOptions): CustomTheme; diff --git a/src/Geopilot.Frontend/src/pages/admin/admin.tsx b/src/Geopilot.Frontend/src/pages/admin/admin.tsx index db222d26..ae2ec413 100644 --- a/src/Geopilot.Frontend/src/pages/admin/admin.tsx +++ b/src/Geopilot.Frontend/src/pages/admin/admin.tsx @@ -3,6 +3,7 @@ import { Box, Divider, Drawer, List, ListItem, ListItemButton, ListItemText, Typ import { FC } from "react"; import { Outlet, useNavigate } from "react-router-dom"; import { useAppSettings } from "../../components/appSettings/appSettingsInterface.ts"; +import { FlexRowBox } from "../../components/styledComponents.ts"; interface AdminProps { isSubMenuOpen: boolean; @@ -98,7 +99,7 @@ const Admin: FC = ({ isSubMenuOpen, setIsSubMenuOpen }) => { "& .MuiDrawer-paper": { width: drawerWidth, boxSizing: "border-box" }, }}> <> - + {clientSettings?.application?.logo && ( = ({ isSubMenuOpen, setIsSubMenuOpen }) => { {clientSettings?.application?.name} )} - + {drawerContent} diff --git a/src/Geopilot.Frontend/src/pages/admin/deliveryOverview.tsx b/src/Geopilot.Frontend/src/pages/admin/deliveryOverview.tsx index 991a808d..5445bb74 100644 --- a/src/Geopilot.Frontend/src/pages/admin/deliveryOverview.tsx +++ b/src/Geopilot.Frontend/src/pages/admin/deliveryOverview.tsx @@ -2,13 +2,14 @@ import { useContext, useEffect, useState } from "react"; import DeleteOutlinedIcon from "@mui/icons-material/DeleteOutlined"; import { useTranslation } from "react-i18next"; import { DataGrid, GridRowSelectionModel } from "@mui/x-data-grid"; -import { Box, Button } from "@mui/material"; +import { Button } from "@mui/material"; import { useGeopilotAuth } from "../../auth"; import { PromptContext } from "../../components/prompt/promptContext"; import { AlertContext } from "../../components/alert/alertContext"; import { ApiError, Delivery } from "../../api/apiInterfaces"; import { TranslationFunction } from "../../appInterfaces"; import { useApi } from "../../api"; +import { FlexRowCenterBox } from "../../components/styledComponents.ts"; const useTranslatedColumns = (t: TranslationFunction) => { return [ @@ -109,7 +110,7 @@ export const DeliveryOverview = () => { hideFooterSelectedRowCount /> {selectedRows.length > 0 && ( - + - + )} ); diff --git a/src/Geopilot.Frontend/src/pages/delivery/delivery.tsx b/src/Geopilot.Frontend/src/pages/delivery/delivery.tsx index 9e80c0af..ba6490fe 100644 --- a/src/Geopilot.Frontend/src/pages/delivery/delivery.tsx +++ b/src/Geopilot.Frontend/src/pages/delivery/delivery.tsx @@ -1,7 +1,60 @@ -import { Box } from "@mui/material"; +import { Box, Step, StepContent, StepLabel, Stepper, Typography } from "@mui/material"; +import { useTranslation } from "react-i18next"; +import { CenteredBox } from "../../components/styledComponents.ts"; +import { StepperIcon } from "./stepperIcon.tsx"; +import { styled } from "@mui/system"; +import { DeliveryContext } from "./deliveryContext.tsx"; +import { useContext } from "react"; + +const DeliveryContainer = styled(Box)(({ theme }) => ({ + backgroundColor: theme.palette.primary.hover, + border: `1px solid ${theme.palette.primary.main}`, + borderRadius: "4px", + padding: "40px", + flex: 1, +})); const Delivery = () => { - return Delivery; + const { t } = useTranslation(); + const { steps, activeStep, isLoading } = useContext(DeliveryContext); + + const isOpen = (stepIndex: number, keepOpen?: boolean) => + activeStep === stepIndex || (activeStep >= stepIndex && keepOpen); + const isCompleted = (stepIndex: number) => activeStep > stepIndex; + + return ( + + {t("deliveryTitle")} + + + {Array.from(steps.entries()).map(([key, step], index) => { + if (step) { + return ( + + ( + + )}> + {t(step.label)} + {step.labelAddition && step.labelAddition.length > 0 && ( + {` - ${t(step.labelAddition || "")}`} + )}{" "} + {step.error && ` - ${step.error}`} + + {step.content} + + ); + } + })} + + + + ); }; export default Delivery; diff --git a/src/Geopilot.Frontend/src/pages/delivery/deliveryCompleted.tsx b/src/Geopilot.Frontend/src/pages/delivery/deliveryCompleted.tsx new file mode 100644 index 00000000..da7be631 --- /dev/null +++ b/src/Geopilot.Frontend/src/pages/delivery/deliveryCompleted.tsx @@ -0,0 +1,19 @@ +import { DeliveryContext } from "./deliveryContext.tsx"; +import { useContext } from "react"; +import { FlexRowSpaceBetweenBox } from "../../components/styledComponents.ts"; +import { Typography } from "@mui/material"; +import { useTranslation } from "react-i18next"; +import AddIcon from "@mui/icons-material/Add"; +import { BaseButton } from "../../components/buttons.tsx"; + +export const DeliveryCompleted = () => { + const { t } = useTranslation(); + const { resetDelivery } = useContext(DeliveryContext); + + return ( + + {t("deliveryCompleted")} + resetDelivery()} icon={} variant="outlined" label="addAnotherDelivery" /> + + ); +}; diff --git a/src/Geopilot.Frontend/src/pages/delivery/deliveryContext.tsx b/src/Geopilot.Frontend/src/pages/delivery/deliveryContext.tsx new file mode 100644 index 00000000..e6eff6d0 --- /dev/null +++ b/src/Geopilot.Frontend/src/pages/delivery/deliveryContext.tsx @@ -0,0 +1,237 @@ +import { DeliveryContextInterface, DeliveryStep, DeliveryStepEnum, DeliverySubmitData } from "./deliveryInterfaces.tsx"; +import { createContext, FC, PropsWithChildren, useCallback, useEffect, useState } from "react"; +import { useApi } from "../../api"; +import { ApiError, ValidationResponse, ValidationStatus } from "../../api/apiInterfaces.ts"; +import { DeliveryUpload } from "./deliveryUpload.tsx"; +import { DeliveryValidation } from "./deliveryValidation.tsx"; +import { DeliverySubmit } from "./deliverySubmit.tsx"; +import { useGeopilotAuth } from "../../auth"; +import { DeliveryCompleted } from "./deliveryCompleted.tsx"; +import { useTranslation } from "react-i18next"; + +export const DeliveryContext = createContext({ + steps: new Map(), + activeStep: 0, + isActiveStep: () => false, + setStepError: () => {}, + selectedFile: undefined, + setSelectedFile: () => {}, + validationResponse: undefined, + isLoading: false, + uploadFile: () => {}, + validateFile: () => {}, + submitDelivery: () => {}, + resetDelivery: () => {}, +}); + +export const DeliveryProvider: FC = ({ children }) => { + const { t } = useTranslation(); + const [activeStep, setActiveStep] = useState(0); + const [isLoading, setIsLoading] = useState(false); + const [selectedFile, setSelectedFile] = useState(); + const [validationResponse, setValidationResponse] = useState(); + const [isValidating, setIsValidating] = useState(false); + const [abortControllers, setAbortControllers] = useState([]); + const { fetchApi } = useApi(); + const { enabled } = useGeopilotAuth(); + const [steps, setSteps] = useState>( + new Map([ + [DeliveryStepEnum.Upload, { label: "upload", content: }], + [ + DeliveryStepEnum.Validate, + { + label: "validate", + keepOpen: true, + content: , + }, + ], + ]), + ); + + useEffect(() => { + if (enabled) { + setSteps(prevSteps => { + const newSteps = new Map(prevSteps); + + if (!newSteps.has(DeliveryStepEnum.Submit)) { + newSteps.set(DeliveryStepEnum.Submit, { + label: "deliver", + content: , + }); + } + if (!newSteps.has(DeliveryStepEnum.Done)) { + newSteps.set(DeliveryStepEnum.Done, { + label: "done", + content: , + }); + } + return newSteps; + }); + } + }, [enabled]); + + const isActiveStep = (step: DeliveryStepEnum) => { + const stepKeys = Array.from(steps.keys()); + return activeStep === stepKeys.indexOf(step); + }; + + const setStepError = (key: DeliveryStepEnum, error: string | undefined) => { + setSteps(prevSteps => { + const newSteps = new Map(prevSteps); + const step = newSteps.get(key); + if (step) { + step.error = error; + } + return newSteps; + }); + }; + + const continueToNextStep = useCallback(() => { + setAbortControllers([]); + if (activeStep < steps.size - 1) { + setActiveStep(activeStep + 1); + } + }, [activeStep, steps]); + + const handleApiError = (error: ApiError, key: DeliveryStepEnum) => { + if (error?.message && !error?.message?.includes("AbortError")) { + setStepError(key, error.message); + } + }; + + const uploadFile = () => { + if (selectedFile) { + const abortController = new AbortController(); + setAbortControllers(prevControllers => [...(prevControllers || []), abortController]); + setIsLoading(true); + const formData = new FormData(); + formData.append("file", selectedFile, selectedFile.name); + fetchApi("/api/v1/validation", { + method: "POST", + body: formData, + signal: abortController.signal, + }) + .then(response => { + setValidationResponse(response); + setSteps(prevSteps => { + const newSteps = new Map(prevSteps); + const step = newSteps.get(DeliveryStepEnum.Upload); + if (step) { + step.labelAddition = selectedFile.name; + } + return newSteps; + }); + continueToNextStep(); + }) + .catch((error: ApiError) => { + handleApiError(error, DeliveryStepEnum.Upload); + }) + .finally(() => setIsLoading(false)); + } + }; + + const getValidationStatus = useCallback(() => { + const abortController = new AbortController(); + setAbortControllers(prevControllers => [...(prevControllers || []), abortController]); + fetchApi(`/api/v1/validation/${validationResponse?.jobId}`, { + method: "GET", + signal: abortController.signal, + }) + .then(response => { + setValidationResponse(response); + }) + .catch((error: ApiError) => { + handleApiError(error, DeliveryStepEnum.Validate); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [validationResponse?.jobId]); + + const validateFile = () => { + if (validationResponse?.status === ValidationStatus.Processing && !isLoading) { + setIsLoading(true); + setIsValidating(true); + getValidationStatus(); + } + }; + + const submitDelivery = (data: DeliverySubmitData) => { + setIsLoading(true); + if (steps.get(DeliveryStepEnum.Submit)?.error) { + setStepError(DeliveryStepEnum.Submit, undefined); + } + const abortController = new AbortController(); + setAbortControllers(prevControllers => [...(prevControllers || []), abortController]); + fetchApi("/api/v1/delivery", { + method: "POST", + body: JSON.stringify({ + JobId: validationResponse?.jobId, + MandateId: data.mandate, + PartialDelivery: data.isPartial, + PrecursorDeliveryId: data.predecessor, + Comment: data.comment, + }), + signal: abortController.signal, + }) + .then(() => { + continueToNextStep(); + }) + .catch((error: ApiError) => { + handleApiError(error, DeliveryStepEnum.Submit); + }) + .finally(() => setIsLoading(false)); + }; + + const resetDelivery = () => { + abortControllers.forEach(controller => controller.abort()); + setAbortControllers([]); + setIsLoading(false); + setIsValidating(false); + setSelectedFile(undefined); + setValidationResponse(undefined); + setActiveStep(0); + setSteps(prevSteps => { + const newSteps = new Map(prevSteps); + newSteps.forEach(step => { + step.labelAddition = undefined; + step.error = undefined; + }); + return newSteps; + }); + }; + + useEffect(() => { + if (validationResponse && isValidating && abortControllers.length > 0) { + if (validationResponse.status === ValidationStatus.Processing) { + setTimeout(getValidationStatus, 2000); + } else { + setIsValidating(false); + setIsLoading(false); + if (validationResponse.status === ValidationStatus.Completed) { + continueToNextStep(); + } else { + setStepError(DeliveryStepEnum.Validate, t(validationResponse.status)); + } + } + } + }, [abortControllers.length, continueToNextStep, getValidationStatus, isValidating, t, validationResponse]); + + return ( + + {children} + + ); +}; diff --git a/src/Geopilot.Frontend/src/pages/delivery/deliveryInterfaces.tsx b/src/Geopilot.Frontend/src/pages/delivery/deliveryInterfaces.tsx new file mode 100644 index 00000000..2bafa07d --- /dev/null +++ b/src/Geopilot.Frontend/src/pages/delivery/deliveryInterfaces.tsx @@ -0,0 +1,39 @@ +import { ReactNode } from "react"; +import { ValidationResponse } from "../../api/apiInterfaces.ts"; + +export enum DeliveryStepEnum { + Upload = "upload", + Validate = "validate", + Submit = "submit", + Done = "done", +} + +export interface DeliveryStep { + label: string; + labelAddition?: string; + error?: string; + keepOpen?: boolean; + content: ReactNode; +} + +export interface DeliverySubmitData { + mandate: number; + isPartial: boolean; + predecessor: number; + comment: string; +} + +export interface DeliveryContextInterface { + steps: Map; + activeStep: number; + isActiveStep: (step: DeliveryStepEnum) => boolean; + setStepError: (key: DeliveryStepEnum, error: string | undefined) => void; + selectedFile?: File; + setSelectedFile: (file: File | undefined) => void; + validationResponse?: ValidationResponse; + isLoading: boolean; + uploadFile: () => void; + validateFile: () => void; + submitDelivery: (data: DeliverySubmitData) => void; + resetDelivery: () => void; +} diff --git a/src/Geopilot.Frontend/src/pages/delivery/deliverySubmit.tsx b/src/Geopilot.Frontend/src/pages/delivery/deliverySubmit.tsx new file mode 100644 index 00000000..9a225d3f --- /dev/null +++ b/src/Geopilot.Frontend/src/pages/delivery/deliverySubmit.tsx @@ -0,0 +1,91 @@ +import { DeliveryContext } from "./deliveryContext.tsx"; +import { useContext, useEffect, useState } from "react"; +import { useGeopilotAuth } from "../../auth"; +import LoginIcon from "@mui/icons-material/Login"; +import { FlexColumnBox, FlexRowEndBox, FlexRowSpaceBetweenBox } from "../../components/styledComponents.ts"; +import { FieldValues, FormProvider, useForm } from "react-hook-form"; +import { FormCheckbox, FormInput, FormSelect } from "../../components/form/form.ts"; +import SendIcon from "@mui/icons-material/Send"; +import { Delivery, Mandate } from "../../api/apiInterfaces.ts"; +import { useApi } from "../../api"; +import { DeliverySubmitData } from "./deliveryInterfaces.tsx"; +import { BaseButton, CancelButton } from "../../components/buttons.tsx"; + +export const DeliverySubmit = () => { + const { enabled, user, login } = useGeopilotAuth(); + const formMethods = useForm({ mode: "all" }); + const { fetchApi } = useApi(); + const { validationResponse, isLoading, submitDelivery, resetDelivery } = useContext(DeliveryContext); + const [mandates, setMandates] = useState([]); + const [previousDeliveries, setPreviousDeliveries] = useState([]); + + useEffect(() => { + if (validationResponse?.jobId && user) { + fetchApi("/api/v1/mandate?" + new URLSearchParams({ jobId: validationResponse.jobId })).then( + setMandates, + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [validationResponse, user]); + + useEffect(() => { + const mandateId = formMethods.getValues()["mandate"]; + if (mandateId) { + fetchApi("/api/v1/delivery?" + new URLSearchParams({ mandateId: mandateId })).then( + setPreviousDeliveries, + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [formMethods.getValues()["mandate"]]); + + const submitForm = (data: FieldValues) => { + if (data["predecessor"] === "") { + data["predecessor"] = null; + } + submitDelivery(data as DeliverySubmitData); + }; + + return enabled && user ? ( + +
+ + + a.name.localeCompare(b.name)) + .map(mandate => ({ key: mandate.id, name: mandate.name }))} + /> + ({ key: delivery.id, name: delivery.date.toLocaleString() }))} + /> + + + + + + + + + resetDelivery()} disabled={isLoading} /> + } + label="createDelivery" + disabled={!formMethods.formState.isValid || isLoading} + onClick={() => formMethods.handleSubmit(submitForm)()} + /> + + +
+
+ ) : ( + + resetDelivery()} /> + } label="logInForDelivery" /> + + ); +}; diff --git a/src/Geopilot.Frontend/src/pages/delivery/deliveryUpload.tsx b/src/Geopilot.Frontend/src/pages/delivery/deliveryUpload.tsx new file mode 100644 index 00000000..ac821110 --- /dev/null +++ b/src/Geopilot.Frontend/src/pages/delivery/deliveryUpload.tsx @@ -0,0 +1,81 @@ +import { FileDropzone } from "../../components/fileDropzone.tsx"; +import { useContext, useEffect, useState } from "react"; +import { ValidationSettings } from "../../api/apiInterfaces.ts"; +import { useApi } from "../../api"; +import { FormProvider, useForm } from "react-hook-form"; +import { FlexColumnBox, FlexRowSpaceBetweenBox } from "../../components/styledComponents.ts"; +import { Trans } from "react-i18next"; +import { Link } from "@mui/material"; +import CloudUploadOutlinedIcon from "@mui/icons-material/CloudUploadOutlined"; +import { FormCheckbox } from "../../components/form/form.ts"; +import { useAppSettings } from "../../components/appSettings/appSettingsInterface.ts"; +import { DeliveryContext } from "./deliveryContext.tsx"; +import { DeliveryStepEnum } from "./deliveryInterfaces.tsx"; +import { BaseButton, CancelButton } from "../../components/buttons.tsx"; + +export const DeliveryUpload = () => { + const [validationSettings, setValidationSettings] = useState(); + const { initialized, termsOfUse } = useAppSettings(); + const { fetchApi } = useApi(); + const formMethods = useForm({ mode: "all" }); + const { setStepError, selectedFile, setSelectedFile, isLoading, uploadFile, resetDelivery } = + useContext(DeliveryContext); + + useEffect(() => { + if (!validationSettings) { + fetchApi("/api/v1/validation").then(setValidationSettings); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [validationSettings]); + + const submitForm = () => { + uploadFile(); + }; + + return ( + initialized && ( + +
+ + { + setStepError(DeliveryStepEnum.Upload, error); + }} + /> + + , + }} + /> + } + checked={!termsOfUse} + disabled={isLoading} + validation={{ required: true }} + sx={{ visibility: termsOfUse ? "visible" : "hidden" }} + /> + {isLoading ? ( + resetDelivery()} /> + ) : ( + formMethods.handleSubmit(submitForm)()} + icon={} + label="upload" + /> + )} + + +
+
+ ) + ); +}; diff --git a/src/Geopilot.Frontend/src/pages/delivery/deliveryValidation.tsx b/src/Geopilot.Frontend/src/pages/delivery/deliveryValidation.tsx new file mode 100644 index 00000000..cddfe700 --- /dev/null +++ b/src/Geopilot.Frontend/src/pages/delivery/deliveryValidation.tsx @@ -0,0 +1,75 @@ +import { DeliveryContext } from "./deliveryContext.tsx"; +import { useContext, useEffect, useMemo } from "react"; +import { FlexColumnBox, FlexRowBox, FlexRowSpaceBetweenBox } from "../../components/styledComponents.ts"; +import { Typography } from "@mui/material"; +import { useTranslation } from "react-i18next"; +import FileDownloadIcon from "@mui/icons-material/FileDownload"; +import { DeliveryStepEnum } from "./deliveryInterfaces.tsx"; +import { BaseButton, CancelButton } from "../../components/buttons.tsx"; + +export const DeliveryValidation = () => { + const { t } = useTranslation(); + const { isActiveStep, validationResponse, isLoading, validateFile, resetDelivery } = useContext(DeliveryContext); + + const isActive = useMemo(() => isActiveStep(DeliveryStepEnum.Validate), [isActiveStep]); + + useEffect(() => { + validateFile(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const getValidationKeysString = () => { + if (!validationResponse?.validatorResults) return ""; + const keys = Object.keys(validationResponse.validatorResults); + if (keys.length <= 1) return keys.join(", "); + return keys.slice(0, -1).join(", ") + " " + t("and") + " " + keys[keys.length - 1]; + }; + + const download = (fileName: string) => { + if (!validationResponse) return; + const url = `/api/v1/validation/${validationResponse.jobId}/files/${fileName}`; + const anchor = document.createElement("a"); + anchor.href = url; + anchor.download = fileName; + document.body.appendChild(anchor); + anchor.click(); + document.body.removeChild(anchor); + }; + + return ( + + {isLoading ? ( + {t("validationIsRunning", { validators: getValidationKeysString() })} + ) : ( + + {validationResponse?.validatorResults && + Object.keys(validationResponse.validatorResults).map(key => ( + + + {key} + + + {validationResponse.validatorResults[key].statusMessage} + + {validationResponse.validatorResults[key].logFiles && + Object.keys(validationResponse.validatorResults[key].logFiles).map((logFileKey, index) => ( + { + download(validationResponse.validatorResults[key].logFiles[logFileKey]); + }} + icon={} + label={logFileKey} + /> + ))} + + + + ))} + + )} + {isActive && resetDelivery()} />} + + ); +}; diff --git a/src/Geopilot.Frontend/src/pages/delivery/stepperIcon.tsx b/src/Geopilot.Frontend/src/pages/delivery/stepperIcon.tsx new file mode 100644 index 00000000..8253c2e6 --- /dev/null +++ b/src/Geopilot.Frontend/src/pages/delivery/stepperIcon.tsx @@ -0,0 +1,51 @@ +import { CircularProgress, StepIconProps } from "@mui/material"; +import { FC } from "react"; +import { FlexRowCenterBox } from "../../components/styledComponents.ts"; +import WarningIcon from "@mui/icons-material/Warning"; +import { geopilotTheme } from "../../appTheme.ts"; +import CheckIcon from "@mui/icons-material/Check"; + +interface StepperIconProps { + index: number; + stepIconProps: StepIconProps; + isLoading?: boolean; +} + +export const StepperIcon: FC = ({ index, stepIconProps, isLoading }) => { + return ( + + {stepIconProps.error ? ( + + ) : ( + <> + + {stepIconProps.completed ? : index + 1} + + {stepIconProps.active && isLoading && ( + + )} + + )} + + ); +}; diff --git a/src/Geopilot.Frontend/src/pages/footer/about.tsx b/src/Geopilot.Frontend/src/pages/footer/about.tsx index fc32d2b9..523670a2 100644 --- a/src/Geopilot.Frontend/src/pages/footer/about.tsx +++ b/src/Geopilot.Frontend/src/pages/footer/about.tsx @@ -2,10 +2,11 @@ import { Trans, useTranslation } from "react-i18next"; import { useEffect, useState } from "react"; import { useApi } from "../../api"; import { Typography } from "@mui/material"; -import { MarkdownContent } from "./markdownContent.tsx"; +import { MarkdownContent } from "../../components/markdownContent.tsx"; import { useAppSettings } from "../../components/appSettings/appSettingsInterface.ts"; import { ContentType } from "../../api/apiInterfaces.ts"; import { CenteredBox } from "../../components/styledComponents.ts"; +import { useLocation } from "react-router-dom"; interface PackageList { [packageName: string]: PackageDetails; @@ -33,6 +34,7 @@ export const About = () => { const [licenseInfoCustom, setLicenseInfoCustom] = useState(); const { fetchApi } = useApi(); const { version, clientSettings, termsOfUse } = useAppSettings(); + const { hash } = useLocation(); useEffect(() => { fetchApi("info.md", { responseType: ContentType.Markdown }).then(setInfo); @@ -40,15 +42,32 @@ export const About = () => { fetchApi("licenses.custom.json", { responseType: ContentType.Json }).then(setLicenseInfoCustom); }, [fetchApi]); + useEffect(() => { + const scrollToHash = () => { + if (hash) { + const id = hash.substring(1); + const element = document.getElementById(id); + if (element) window.scrollTo({ top: element.offsetTop - 64, behavior: "smooth" }); + } + }; + + // Run after initial render + setTimeout(scrollToHash, 0); + + scrollToHash(); + }, [hash, info, termsOfUse, licenseInfo, licenseInfoCustom, version]); + return ( - {info && } - {termsOfUse && } - {t("versionInformation")} + {info && } + {termsOfUse && } + + {t("versionInformation")} +

geopilot {clientSettings?.application?.name}: {version}

- + {t("development")} & {t("bugTracking")}

@@ -63,7 +82,11 @@ export const About = () => { }} />

- {(licenseInfo || licenseInfoCustom) && {t("licenseInformation")}} + {(licenseInfo || licenseInfoCustom) && ( + + {t("licenseInformation")} + + )} {licenseInfoCustom && Object.keys(licenseInfoCustom).map(key => (
diff --git a/src/Geopilot.Frontend/src/pages/footer/footer.tsx b/src/Geopilot.Frontend/src/pages/footer/footer.tsx index 4467a876..c9826f6c 100644 --- a/src/Geopilot.Frontend/src/pages/footer/footer.tsx +++ b/src/Geopilot.Frontend/src/pages/footer/footer.tsx @@ -1,6 +1,7 @@ -import { Box, Button } from "@mui/material"; +import { Button } from "@mui/material"; import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; +import { FlexRowCenterBox } from "../../components/styledComponents.ts"; const Footer = () => { const { t } = useTranslation(); @@ -10,14 +11,10 @@ const Footer = () => { const marginLeft = isAdminRoute ? "250px" : "0"; return ( - { }}> {t("about")} - + ); }; diff --git a/src/Geopilot.Frontend/src/pages/footer/imprint.tsx b/src/Geopilot.Frontend/src/pages/footer/imprint.tsx index ecc25204..6cb6db41 100644 --- a/src/Geopilot.Frontend/src/pages/footer/imprint.tsx +++ b/src/Geopilot.Frontend/src/pages/footer/imprint.tsx @@ -2,7 +2,7 @@ import { Typography } from "@mui/material"; import { useTranslation } from "react-i18next"; import { useEffect, useState } from "react"; import { useApi } from "../../api"; -import { MarkdownContent } from "./markdownContent.tsx"; +import { MarkdownContent } from "../../components/markdownContent.tsx"; import { ContentType } from "../../api/apiInterfaces.ts"; import { CenteredBox } from "../../components/styledComponents.ts"; diff --git a/src/Geopilot.Frontend/src/pages/footer/privacyPolicy.tsx b/src/Geopilot.Frontend/src/pages/footer/privacyPolicy.tsx index f72fe16c..6fce3174 100644 --- a/src/Geopilot.Frontend/src/pages/footer/privacyPolicy.tsx +++ b/src/Geopilot.Frontend/src/pages/footer/privacyPolicy.tsx @@ -2,7 +2,7 @@ import { Typography } from "@mui/material"; import { useTranslation } from "react-i18next"; import { useEffect, useState } from "react"; import { useApi } from "../../api"; -import { MarkdownContent } from "./markdownContent.tsx"; +import { MarkdownContent } from "../../components/markdownContent.tsx"; import { ContentType } from "../../api/apiInterfaces.ts"; import { CenteredBox } from "../../components/styledComponents.ts";