diff --git a/.github/workflows/monthly_npm_dependency_update.yml b/.github/workflows/monthly_frontend_dependency_update.yml similarity index 100% rename from .github/workflows/monthly_npm_dependency_update.yml rename to .github/workflows/monthly_frontend_dependency_update.yml diff --git a/.github/workflows/notify_migrations_on_pr.yml b/.github/workflows/notify_migrations_on_pr.yml index be861c8b9..6712adf64 100644 --- a/.github/workflows/notify_migrations_on_pr.yml +++ b/.github/workflows/notify_migrations_on_pr.yml @@ -15,4 +15,4 @@ jobs: uses: equinor/armada/.github/workflows/notify_migrations_on_pr.yml@main with: stage_one_workflow_run_id: ${{ github.event.workflow_run.id }} - migration_docs_url: https://github.com/equinor/flotilla/tree/main/backend#Database-model-and-EF-Core + migration_docs_url: https://github.com/equinor/flotilla/tree/main/backend#database-migrations-ef-core diff --git a/.github/workflows/upgrade_package_lock_and_create_PR.yml b/.github/workflows/pnpm_audit_fix_and_create_pr.yml similarity index 100% rename from .github/workflows/upgrade_package_lock_and_create_PR.yml rename to .github/workflows/pnpm_audit_fix_and_create_pr.yml diff --git a/.gitignore b/.gitignore index c2ee2cfd5..4e28ef514 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ frontend/out/ *.log *.vs *.code-workspace -*.editorconfig # Environment variables *.env @@ -17,7 +16,6 @@ frontend/out/ # Backend backend/*/bin backend/*/obj -backend/api/Database/Maps/* backend/backend.sln.DotSettings.user # Broker diff --git a/README.md b/README.md index c6b72eedd..1bb170057 100644 --- a/README.md +++ b/README.md @@ -4,111 +4,101 @@ [![Frontend](https://github.com/equinor/flotilla/actions/workflows/lint_frontend_package.yml/badge.svg)](https://github.com/equinor/flotilla/actions/workflows/lint_frontend_package.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/0b37a44f66044dbc81fff906344b476e)](https://www.codacy.com/gh/equinor/flotilla/dashboard?utm_source=github.com&utm_medium=referral&utm_content=equinor/flotilla&utm_campaign=Badge_Grade) -Flotilla is the main point of access for operators to interact with multiple robots in multiple facilities. -The application consists of a [frontend](frontend) in React, a [backend](backend) in ASP.NET, and a Mosquitto MQTT [Broker](broker). +Flotilla is the main point of access for operators to interact with multiple robots in multiple facilities. +The application consists of a [frontend](frontend) in React, a [backend](backend) in ASP.NET, and a Mosquitto MQTT [broker](broker). -## Deployments - -We currently have 3 environments (Development, Staging, and Production) deployed to AKS under `robotics.equinor.com`. - -| Environment | Deployment | Status | -| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Development | [Frontend](https://flotilla.dev.robotics.equinor.com/)
[Backend](https://flotilla.dev.robotics.equinor.com/api/swagger) | [![Dev](https://github.com/equinor/flotilla/actions/workflows/deploy_to_development.yml/badge.svg)](https://github.com/equinor/flotilla/actions/workflows/deploy_to_development.yml) | -| Staging | [Frontend](https://flotilla.staging.robotics.equinor.com/)
[Backend](https://flotilla.staging.robotics.equinor.com/api/swagger) | [![Staging](https://github.com/equinor/flotilla/actions/workflows/deploy_to_staging.yml/badge.svg)](https://github.com/equinor/flotilla/actions/workflows/deploy_to_staging.yml) | -| Production | [Frontend](https://flotilla.robotics.equinor.com/)
[Backend](https://flotilla.robotics.equinor.com/api/swagger) | [![Production](https://github.com/equinor/flotilla/actions/workflows/promote_to_production.yml/badge.svg)](https://github.com/equinor/flotilla/actions/workflows/promote_to_production.yml) | - -## Setup - -For development, please fork the repository. Then, clone the repository: - -``` -git clone https://github.com/equinor/flotilla -``` - -Please see separate installation guides for the [frontend](frontend), [backend](backend), and [Broker](broker). For the environment setup, either run the script as described below or set it up manually as described in each component's guide. +## Prerequisites -### Automatic environment setup - -Run the [setup.sh](./setup.sh) to automatically set up your dev environment for the components. -This script will ask you for the `Client Secret` for the backend and the `MQTT broker server key` for the MQTT broker. - -## Run with make -Common commands for the project are in Makefiles. See [frontend makefile](./frontend/Makefile), [backend makefile](./backend/Makefile) and [root makefile](./Makefile). -This requires the CLI program `make`. - -Usage: -```bash -make # for example: make run -``` +| Tool | Version | Needed for | +| ------------------------------------------------------------------------------------------------------------ | ------- | -------------------------------- | +| [Docker](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/) | latest | Running the full stack | +| [.NET SDK](https://dotnet.microsoft.com/download) | 10.x | Running the backend directly | +| [Node.js](https://github.com/nodesource/distributions) | 24.x | Running the frontend directly | +| [pnpm](https://pnpm.io/installation) | latest | Frontend package management | +| `make` | any | The shorthand commands below |
-Installation MacOS +Installing make on MacOS ```bash brew install make ``` +
-Installation Windows +Installing make on Windows ```bash choco install make ``` -
-## Run with Docker + -Install [Docker](https://docs.docker.com/engine/install/ubuntu/) and [Docker Compose](https://docs.docker.com/compose/install/). +## Quick start -Build the Docker container: +For development, fork the repository first. Then clone it: -``` -docker compose build +```bash +git clone https://github.com/equinor/flotilla +cd flotilla ``` -Set up a .env file in the backend directory with the following environment variables: +Create the local configuration files: -``` -ASPNETCORE_ENVIRONMENT=Local -Local__DevUserId= -SARA__BaseUrl=https://localhost:8100/ -SARA__Scopes__0= +```bash +./setup.sh ``` -Start Flotilla by running: +The script creates `frontend/.env`, `backend/api/.env`, and `broker/.env` from their `.env.example` files. It prompts you for the **MQTT broker server key**, which is found in our key vault. Everything else can be configured manually afterwards — see [Configuration](#configuration). -``` -docker compose up +Start the full stack: + +```bash +make compose # docker compose up --build ``` -or +| Service | URL | +| ---------------- | --------------------------------------- | +| Frontend | | +| Backend Swagger | | +| Aspire dashboard | | -``` -docker compose up --build -``` +To run a single component instead, see the [frontend](frontend/README.md), [backend](backend/README.md), and [broker](broker/README.md) guides. -### Using the aspire dashboard +## Configuration -The docker-compose contains a container for the aspire dashboard to show telemetry and a opentelemetry collector to filter telemetry. -The aspire dashboard is available at http://localhost:18888 when run via docker compose. +Each component reads its configuration from a `.env` file. The matching `.env.example` file is the source of truth for the available variables. -To spin up only the broker, collector and aspire dashboard use -```bash -docker compose up broker aspire-dashboard otel-collector -``` +| Component | File | Template | Notes | +| --------- | ------------------- | --------------------------- | --------------------------------------------------------------------- | +| Frontend | `frontend/.env` | `frontend/.env.example` | Variables must be prefixed with `VITE_` to reach the application. | +| Backend | `backend/api/.env` | `backend/api/.env.example` | Set `Local__DevUserId` to your own user id for local development. | +| Broker | `broker/.env` | `broker/.env.example` | `TLS_SERVER_KEY` is a secret and is found in our key vault. | + +> **Note on Docker:** `backend/api/.env` is only read when the backend is run directly (`make run`). The backend *container* does not load it — [docker-compose.yml](./docker-compose.yml) sets `ASPNETCORE_ENVIRONMENT=Development` and reads `AZURE_CLIENT_SECRET` from a `.env` file in the repository root, which `setup.sh` does not create. To run the full stack against Azure AD you currently have to add `AZURE_CLIENT_SECRET=...` to a root `.env` yourself. + +## Other make commands -## Connecting to the development database instead of initDb +Common commands are defined in the [root Makefile](./Makefile), the [backend Makefile](./backend/Makefile), and the [frontend Makefile](./frontend/Makefile): -Write in `backend/api/.env`: ```bash -Database__UseInMemoryDatabase=false -Database__PostgreSqlConnectionString=... +make compose # run the full stack in Docker +make broker # run only the MQTT broker +make broker-aspire # run the broker, OpenTelemetry collector, and Aspire dashboard ``` -The database connection string can be found in the keyvault in the development resource group in Azure. -Remember to add your IP address to the accepted IPs for cennecting to the database. + +## Deployments + +We currently have 3 environments (Development, Staging, and Production) deployed to AKS under `robotics.equinor.com`. + +| Environment | Deployment | Status | +| ----------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Development | [Frontend](https://flotilla.dev.robotics.equinor.com/)
[Backend](https://flotilla.dev.robotics.equinor.com/api/swagger) | [![Dev](https://github.com/equinor/flotilla/actions/workflows/deploy_to_development.yml/badge.svg)](https://github.com/equinor/flotilla/actions/workflows/deploy_to_development.yml) | +| Staging | [Frontend](https://flotilla.staging.robotics.equinor.com/)
[Backend](https://flotilla.staging.robotics.equinor.com/api/swagger) | [![Staging](https://github.com/equinor/flotilla/actions/workflows/deploy_to_staging.yml/badge.svg)](https://github.com/equinor/flotilla/actions/workflows/deploy_to_staging.yml) | +| Production | [Frontend](https://flotilla.robotics.equinor.com/)
[Backend](https://flotilla.robotics.equinor.com/api/swagger) | [![Production](https://github.com/equinor/flotilla/actions/workflows/promote_to_production.yml/badge.svg)](https://github.com/equinor/flotilla/actions/workflows/promote_to_production.yml) | ## Contributions Equinor welcomes all kinds of contributions, including code, bug reports, issues, feature requests, and documentation. -Please initiate your contribution by creating an [issue](https://github.com/equinor/isar/issues) or by forking the +Please initiate your contribution by creating an [issue](https://github.com/equinor/flotilla/issues) or by forking the project and making a pull request. Commit messages shall be written according to [this guide](https://cbea.ms/git-commit/). diff --git a/backend/README.md b/backend/README.md index 1136450cd..2b73507b6 100644 --- a/backend/README.md +++ b/backend/README.md @@ -2,9 +2,28 @@ The backend of Flotilla is an ASP.NET application. See the [.NET documentation](https://docs.microsoft.com/en-us/dotnet/fundamentals/) for framework concepts. -For general setup (environment, Docker, database connection), see the [root README](../README.md). +For development conventions and gotchas, see [best_practices.md](./best_practices.md). -## Common commands +## Prerequisites + +- [.NET SDK 10.x](https://dotnet.microsoft.com/download) +- [`dotnet-ef`](https://docs.microsoft.com/en-us/ef/core/cli/dotnet), if you need to work with migrations: + + ```bash + dotnet tool install --global dotnet-ef + ``` + +## Configuration + +The backend reads environment variables from `backend/api/.env`. Create it by running [`setup.sh`](../setup.sh) from the repository root, or by copying the template manually: + +```bash +cp api/.env.example api/.env +``` + +Set `Local__DevUserId` to your own user id for local development. + +## Run Common commands are defined in the [Makefile](./Makefile): @@ -13,26 +32,34 @@ make run # dotnet run --project api make build # dotnet build api make test # dotnet test make format # dotnet csharpier format . -make migration name=AddSomething # create a new EF Core migration ``` -## Database migrations (EF Core) +Swagger is served at . -The database model lives in [`api/Database/Models`](./api/Database/Models) and we use [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) as an O/RM. When changing the model, add a [migration](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/). +To run the backend in Docker together with the rest of the stack, see the [root README](../README.md#quick-start). + +## Connecting to the development database -Install the EF Core CLI once: +By default the backend runs against an in-memory database. To use the development database instead, add the following to `backend/api/.env`: ```bash -dotnet tool install --global dotnet-ef +Database__UseInMemoryDatabase=false +Database__PostgreSqlConnectionString=... ``` +The connection string is found in the key vault in the development resource group in Azure. Remember to add your IP address to the accepted IPs for connecting to the database. + +## Database migrations (EF Core) + +The database model lives in [`api/Database/Models`](./api/Database/Models) and we use [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) as an O/RM. When changing the model, add a [migration](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/). + Create a new migration (make sure you have the latest `main` and that no one else is adding a migration at the same time): ```bash make migration name=AddTableNamePropertyName ``` -This adds files under `backend/api/Migrations` that must be committed. `add` does not modify any database — it only describes the changes. +This adds files under `backend/api/Migrations` that must be committed. Adding a migration does not modify any database — it only describes the changes. To discard a migration you're not happy with: @@ -45,20 +72,12 @@ dotnet ef migrations remove - **Development**: after merging a PR that touches `backend/api/Migrations`, manually run the ["Run database migrations (Development)"](https://github.com/equinor/flotilla/actions/workflows/run_development_migrations.yml) workflow. - **Staging / Production**: applied automatically by the [deploy_to_staging](https://github.com/equinor/flotilla/blob/main/.github/workflows/deploy_to_staging.yml) and [promote_to_production](https://github.com/equinor/flotilla/blob/main/.github/workflows/promote_to_production.yml) workflows. -## Formatting +## Monitoring + +The backend is instrumented with [OpenTelemetry](https://opentelemetry.io/). Traces, metrics, and logs are exported via OTLP to a Grafana-compatible backend. -Formatting rules are defined in the [.editorconfig](../.editorconfig). We use [CSharpier](https://csharpier.com/) to auto-format on save (see [installation](https://csharpier.com/docs/About)). To check formatting locally: +Locally, telemetry can be inspected in the Aspire dashboard at . It is started as part of `make compose`, or on its own together with the broker and the OpenTelemetry collector: ```bash -make format +make broker-aspire ``` - -## SignalR - -We use SignalR to push event updates to the frontend via `SignalRService`. Event names must match what the frontend expects. - -Do **not** await SignalR sends — in the current library version, awaiting from an async thread can cause the thread to silently exit without an exception. Let SignalR run after the current thread completes and ignore the await warning. - -## Monitoring - -The backend is instrumented with [OpenTelemetry](https://opentelemetry.io/). Traces, metrics, and logs are exported via OTLP to a Grafana-compatible backend. Locally, telemetry can be inspected in the Aspire dashboard (see the [root README](../README.md#using-the-aspire-dashboard)). diff --git a/backend/api/Configurations/ConfigurationBuilderExtensions.cs b/backend/api/Configurations/ConfigurationBuilderExtensions.cs index 21727ccd9..f1c1866ea 100644 --- a/backend/api/Configurations/ConfigurationBuilderExtensions.cs +++ b/backend/api/Configurations/ConfigurationBuilderExtensions.cs @@ -2,63 +2,6 @@ { public static class ConfigurationBuilderExtensions { - /// - /// Creates the AZURE_CLIENT_ID and AZURE_TENANT_ID configuration values for the - /// Environment Credentials - /// used by the application when dockerized. - /// - /// - /// - public static void AddAppSettingsEnvironmentVariables(this WebApplicationBuilder builder) - { - string? clientId = builder - .Configuration.GetSection("AzureAd") - .GetValue("ClientId"); - if (clientId is not null) - { - Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientId); - Console.WriteLine("'AZURE_CLIENT_ID' set to " + clientId); - } - - string? tenantId = builder - .Configuration.GetSection("AzureAd") - .GetValue("TenantId"); - if (tenantId is not null) - { - Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantId); - Console.WriteLine("'AZURE_TENANT_ID' set to " + tenantId); - } - } - - /// - /// Creates if don't already exist/sets all the configuration variables present on the .env file for the - /// Environment Credentials - /// used by the application when dockerized. - /// - /// - /// - /// - public static void AddDotEnvironmentVariables( - this WebApplicationBuilder builder, - string filePath - ) - { - if (!File.Exists(filePath)) - return; - - foreach (string line in File.ReadAllLines(filePath)) - { - string[] parts = line.Split('=', StringSplitOptions.RemoveEmptyEntries); - - if (parts.Length == 0 || parts[0].StartsWith('#')) - continue; - - Environment.SetEnvironmentVariable(parts[0], parts[1]); - } - - builder.Configuration.AddEnvironmentVariables(); - } - /// /// Configures the logger used by the application /// diff --git a/backend/api/Configurations/CustomServiceConfigurations.cs b/backend/api/Configurations/CustomServiceConfigurations.cs index 9695cd2aa..234586474 100644 --- a/backend/api/Configurations/CustomServiceConfigurations.cs +++ b/backend/api/Configurations/CustomServiceConfigurations.cs @@ -229,15 +229,57 @@ TokenCredential runtimeCredential ); } - public static TokenCredential CreateCredential(IConfiguration config) + /// + /// Resolves the identity the backend authenticates as. Used by both the Key Vault and the + /// runtime credential so they cannot disagree. Appsettings wins; AZURE_* is only a fallback. + /// In AKS, AZURE_CLIENT_ID is injected from the azure.workload.identity/client-id + /// annotation in robotics-infrastructure, which must match AzureAd:ClientId. + /// + private static (string? TenantId, string? ClientId) ResolveIdentity(IConfiguration config) { - string? tenantId = config["AzureAd:TenantId"]; - string? clientId = config["AzureAd:ClientId"]; - string? clientSecret = config["AzureAd:ClientSecret"]; + return ( + config["AzureAd:TenantId"] ?? config["AZURE_TENANT_ID"], + config["AzureAd:ClientId"] ?? config["AZURE_CLIENT_ID"] + ); + } + + /// + /// Options for the credential that reads Key Vault. It needs its own credential because + /// Key Vault is read before can run — the client secret + /// that method may use is itself stored there. DefaultAzureCredential keeps local + /// development working via az login, pinned to . + /// + public static DefaultAzureCredentialOptions CreateKeyVaultCredentialOptions( + IConfiguration config + ) + { + var (tenantId, clientId) = ResolveIdentity(config); + + var options = new DefaultAzureCredentialOptions(); + + if (!string.IsNullOrWhiteSpace(tenantId)) + options.TenantId = tenantId; - tenantId ??= config["AZURE_TENANT_ID"]; - clientId ??= config["AZURE_CLIENT_ID"]; - clientSecret ??= config["AZURE_CLIENT_SECRET"]; + if (!string.IsNullOrWhiteSpace(clientId)) + options.WorkloadIdentityClientId = clientId; + + return options; + } + + public static TokenCredential CreateCredential(IConfiguration config) + { + var (tenantId, clientId) = ResolveIdentity(config); + string? clientSecret = config["AzureAd:ClientSecret"] ?? config["AZURE_CLIENT_SECRET"]; + + Console.WriteLine( + $"Backend identity: clientId={clientId} (source: " + + ( + config["AzureAd:ClientId"] is not null + ? "appsettings" + : "AZURE_CLIENT_ID environment variable" + ) + + ")" + ); var workloadOptions = new WorkloadIdentityCredentialOptions(); if (!string.IsNullOrWhiteSpace(clientId)) @@ -247,7 +289,7 @@ public static TokenCredential CreateCredential(IConfiguration config) var workloadIdentity = new WorkloadIdentityCredential(workloadOptions); - bool allowUsingClientSecret = config.GetValue("AllowUsingClientSecret"); + bool allowUsingClientSecret = config.GetValue("AzureAd:AllowUsingClientSecret"); if ( allowUsingClientSecret diff --git a/backend/api/Controllers/Models/AnalysisResultDto.cs b/backend/api/Controllers/Models/AnalysisResultDto.cs deleted file mode 100644 index d604ce887..000000000 --- a/backend/api/Controllers/Models/AnalysisResultDto.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Text.Json.Serialization; -using Api.Database.Models; - -namespace Api.Controllers.Models; - -public class AnalysisResultDto -{ - [JsonPropertyName("inspectionId")] - public string InspectionId { get; set; } = ""; - - [JsonPropertyName("analysisType")] - public AnalysisType AnalysisType { get; set; } - - [JsonPropertyName("value")] - public string? Value { get; set; } - - [JsonPropertyName("unit")] - public string? Unit { get; set; } - - [JsonPropertyName("confidence")] - public float? Confidence { get; set; } - - [JsonPropertyName("warning")] - public string? Warning { get; set; } -} diff --git a/backend/api/Database/Models/Pointilla.cs b/backend/api/Database/Models/Pointilla.cs index 4b67c93fe..a24bdf231 100644 --- a/backend/api/Database/Models/Pointilla.cs +++ b/backend/api/Database/Models/Pointilla.cs @@ -16,19 +16,4 @@ public struct PointillaMapResponse public int ZoomMax { get; set; } public int TileSize { get; set; } } - - public struct PointillaMapQuery - { - public string PlantCode { get; set; } - public int FloorId { get; set; } - } - - public struct PointillaMapTilesQuery - { - public string PlantCode { get; set; } - public int FloorId { get; set; } - public int ZoomLevel { get; set; } - public int X { get; set; } - public int Y { get; set; } - } } diff --git a/backend/api/Database/Models/TransformationMatrices.cs b/backend/api/Database/Models/TransformationMatrices.cs deleted file mode 100644 index 8bac495fa..000000000 --- a/backend/api/Database/Models/TransformationMatrices.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Microsoft.EntityFrameworkCore; - -#nullable disable -namespace Api.Database.Models -{ - [Owned] - public class TransformationMatrices - { - // In order to get a pixel coordinate P={p1, p2} from an asset coordinate E={e1, e2}, we need to - // perform the transformation: - // P = CE + D - [Required] - public double C1 { get; set; } - - [Required] - public double C2 { get; set; } - - [Required] - public double D1 { get; set; } - - [Required] - public double D2 { get; set; } - - public TransformationMatrices() - { - C1 = 0; - C2 = 0; - D1 = 0; - D2 = 0; - } - - public TransformationMatrices(TransformationMatrices copy) - { - C1 = copy.C1; - C2 = copy.C2; - D1 = copy.D1; - D2 = copy.D2; - } - - public TransformationMatrices(double[] p1, double[] p2, int imageWidth, int imageHeight) - { - C1 = imageWidth / (p2[0] - p1[0]); - C2 = imageHeight / (p2[1] - p1[1]); - D1 = -(C1 * p1[0]); - D2 = -(C2 * p1[1]); - } - - public List AsMatrix() - { - return - [ - [C1, C2], - [D1, D2], - ]; - } - } -} diff --git a/backend/api/Options/AzureAdOptions.cs b/backend/api/Options/AzureAdOptions.cs index 31fb4efc0..5f94cfb1f 100644 --- a/backend/api/Options/AzureAdOptions.cs +++ b/backend/api/Options/AzureAdOptions.cs @@ -5,6 +5,5 @@ public class AzureAdOptions public string ClientId { get; set; } = ""; public string ClientSecret { get; set; } = ""; public string TenantId { get; set; } = ""; - public string StorageAccount { get; set; } = ""; } } diff --git a/backend/api/Program.cs b/backend/api/Program.cs index ffdbae631..cf0b2691b 100644 --- a/backend/api/Program.cs +++ b/backend/api/Program.cs @@ -30,14 +30,16 @@ builder.Configuration.AddEnvironmentVariables(); if (builder.Configuration.GetSection("KeyVault").GetValue("UseKeyVault")) { - // The ExcludeSharedTokenCacheCredential option is a recommended workaround by Azure for dockerization - // See https://github.com/Azure/azure-sdk-for-net/issues/17052 + // Key Vault is read before the runtime credential exists, so it uses its own credential + // pinned to the same identity. See CustomServiceConfigurations.ResolveIdentity. string? vaultUri = builder.Configuration.GetSection("KeyVault")["VaultUri"]; if (!string.IsNullOrEmpty(vaultUri)) { builder.Configuration.AddAzureKeyVault( new Uri(vaultUri), - new DefaultAzureCredential(new DefaultAzureCredentialOptions()) + new DefaultAzureCredential( + CustomServiceConfigurations.CreateKeyVaultCredentialOptions(builder.Configuration) + ) ); } else diff --git a/backend/api/Services/Models/BlobDownload.cs b/backend/api/Services/Models/BlobDownload.cs deleted file mode 100644 index afe157996..000000000 --- a/backend/api/Services/Models/BlobDownload.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Api.Services.Models -{ - public record BlobDownload(byte[] Content, string? ContentType); -} diff --git a/backend/api/Utilities/Exceptions.cs b/backend/api/Utilities/Exceptions.cs index 241b853fb..bfbd54640 100644 --- a/backend/api/Utilities/Exceptions.cs +++ b/backend/api/Utilities/Exceptions.cs @@ -68,16 +68,12 @@ public class MissionNotFoundException(string message) : Exception(message) { } public class InspectionNotFoundException(string message) : Exception(message) { } - public class InspectionNotAvailableYetException(string message) : Exception(message) { } - public class MissionTaskNotFoundException(string message) : Exception(message) { } public class MissionRunNotFoundException(string message) : Exception(message) { } public class RobotNotFoundException(string message) : Exception(message) { } - public class RobotInformationNotAvailableException(string message) : Exception(message) { } - public class RobotPreCheckFailedException(string message) : Exception(message) { } public class InspectionAreaExistsException(string message) : Exception(message) { } diff --git a/backend/api/Utilities/Extensions.cs b/backend/api/Utilities/Extensions.cs deleted file mode 100644 index 26d56bc8f..000000000 --- a/backend/api/Utilities/Extensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Api.Utilities -{ - public static class MyExtensions - { - public static void Reset(this System.Timers.Timer timer) - { - timer.Stop(); - timer.Start(); - } - } -} diff --git a/backend/api/Utilities/HttpContextExtensions.cs b/backend/api/Utilities/HttpContextExtensions.cs index 60f292909..e421152ba 100644 --- a/backend/api/Utilities/HttpContextExtensions.cs +++ b/backend/api/Utilities/HttpContextExtensions.cs @@ -1,20 +1,7 @@ -using System.Security.Claims; - -namespace Api.Utilities +namespace Api.Utilities { public static class HttpContextExtensions { - public static List GetRequestedRoles(this HttpContext context) - { - return context.User?.Claims.Where(c => c.Type == ClaimTypes.Role).ToList() - ?? new List(); - } - - public static List GetRequestedClaims(this HttpContext context) - { - return context.User?.Claims.ToList() ?? new List(); - } - public static string? GetUserObjectId(this HttpContext context) { return context.User?.FindFirst("oid")?.Value; diff --git a/backend/api/Utilities/ObjectCloner.cs b/backend/api/Utilities/ObjectCloner.cs deleted file mode 100644 index 7352b746d..000000000 --- a/backend/api/Utilities/ObjectCloner.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; - -namespace Api.Utilities -{ - public static class ObjectCopier - { - public static T Clone(T source) - { - string serialized = JsonSerializer.Serialize(source); - return JsonSerializer.Deserialize(serialized)!; - } - } -} diff --git a/backend/api/api.csproj b/backend/api/api.csproj index 143d16636..45b3f2a3c 100644 --- a/backend/api/api.csproj +++ b/backend/api/api.csproj @@ -11,7 +11,6 @@ - @@ -48,11 +47,9 @@ - - diff --git a/backend/api/appsettings.Development.json b/backend/api/appsettings.Development.json index d07ddc6f6..25f56bd40 100644 --- a/backend/api/appsettings.Development.json +++ b/backend/api/appsettings.Development.json @@ -3,9 +3,6 @@ "ClientId": "ea4c7b92-47b3-45fb-bd25-a8070f0c495c", "ClientSecret": "Fill in ASP.NET Secret Manager" }, - "ManagedIdentity": { - "ClientId": "12242230-9788-467d-938e-84caafd25b22" - }, "KeyVault": { "VaultUri": "https://robotics-dev-kv.vault.azure.net/" }, @@ -33,8 +30,7 @@ "User": "FlotillaBackendAuthDev" }, "OpenTelemetry": { - "Enabled": true, - "AzureMonitorExportEnabled": true + "Enabled": true }, "Redis": { "HostName": "robotics-dev-redis.northeurope.redis.azure.net" diff --git a/backend/api/appsettings.Production.json b/backend/api/appsettings.Production.json index 6dcb07352..315a5f3d0 100644 --- a/backend/api/appsettings.Production.json +++ b/backend/api/appsettings.Production.json @@ -3,9 +3,6 @@ "ClientId": "9eb21071-0895-4097-b0d3-dab03c9de8ac", "ClientSecret": "Fill in ASP.NET Secret Manager" }, - "ManagedIdentity": { - "ClientId": "3def0261-2f46-45e1-bd2b-7dc5c52b724f" - }, "KeyVault": { "VaultUri": "https://robotics-prod-kv.vault.azure.net/" }, diff --git a/backend/api/appsettings.Staging.json b/backend/api/appsettings.Staging.json index 91df02a8a..0ccdb7a66 100644 --- a/backend/api/appsettings.Staging.json +++ b/backend/api/appsettings.Staging.json @@ -3,9 +3,6 @@ "ClientId": "d89ab07a-3552-4a1f-9a18-9c819c13f2b8", "ClientSecret": "Fill in ASP.NET Secret Manager" }, - "ManagedIdentity": { - "ClientId": "d5d5ea06-4952-4843-899c-64aeb4e52240" - }, "KeyVault": { "VaultUri": "https://robotics-staging-kv.vault.azure.net/" }, diff --git a/backend/api/appsettings.Test.json b/backend/api/appsettings.Test.json index 31e584f51..a77ca862f 100644 --- a/backend/api/appsettings.Test.json +++ b/backend/api/appsettings.Test.json @@ -7,9 +7,6 @@ "KeyVault": { "UseKeyVault": false }, - "Authorization": { - "Roles": "Test.User" - }, "AllowedHosts": "*", "AllowedOrigins": [ "https://*.equinor.com/", diff --git a/backend/api/appsettings.json b/backend/api/appsettings.json index d493723d4..904b4d24e 100644 --- a/backend/api/appsettings.json +++ b/backend/api/appsettings.json @@ -11,22 +11,12 @@ "Instance": "https://login.microsoftonline.com", "AllowUsingClientSecret": false }, - "BlobStorage": { - "DefaultAuthType": "TokenCredential" - }, - "Echo": { - "BaseUrl": "https://echohubapi.equinor.com/api", - "Scopes": [ - "bf0b2569-e09c-42f0-8095-5a52a873eb7b/.default" - ] - }, "SARA": { "BaseUrl": "", "Scopes": [ "" ] }, - "IsarConnectionTimeout": 15, "Logging": { "LogLevel": { "Default": "Warning", @@ -64,7 +54,6 @@ "https://*.equinor.com/" ], "Database": { - "ConnectionString": "", "InitializeInMemDb": false, "SeedExampleDataPostgres": false, "Timeout": 30, diff --git a/backend/best_practices.md b/backend/best_practices.md new file mode 100644 index 000000000..8bf283d12 --- /dev/null +++ b/backend/best_practices.md @@ -0,0 +1,23 @@ +# Backend best practices + +Conventions and gotchas for working on the Flotilla backend. For installation and how to run the backend, see the [backend README](./README.md). + +## Formatting + +Formatting is handled entirely by [CSharpier](https://csharpier.com/), which is opinionated and takes no configuration. The version is pinned in [.config/dotnet-tools.json](./.config/dotnet-tools.json). We recommend setting it up to format on save (see [installation](https://csharpier.com/docs/About)). To format locally: + +```bash +make format +``` + +CI enforces this — a PR fails if the code is not CSharpier-formatted. + +## SignalR + +We use SignalR to push event updates to the frontend via `SignalRService`. Event names must match what the frontend expects. + +Do **not** await SignalR sends — in the current library version, awaiting from an async thread can cause the thread to silently exit without an exception. Let SignalR run after the current thread completes and ignore the await warning. + +## Migrations + +Any change to the model in [`api/Database/Models`](./api/Database/Models) requires a migration. Avoid adding a migration at the same time as someone else, since migrations are ordered and conflicts have to be resolved by regenerating them. See the [backend README](./README.md#database-migrations-ef-core) for the commands. diff --git a/broker/README.md b/broker/README.md index 980c842ac..a635b8e68 100644 --- a/broker/README.md +++ b/broker/README.md @@ -1,102 +1,35 @@ -# Mosquitto MQTT Broker +# Mosquitto MQTT broker -## Set up the broker +The Flotilla MQTT broker is a [Mosquitto](https://mosquitto.org/) broker with TLS and role-based authentication. -The broker expects a private key for its server x509 certificate used for TLS. -This must be provided through an environment variable called `TLS_BROKER_SERVER_KEY`. -This is a secret and should be treated as such. It can be found in our key vault. +For authentication details, testing, and certificate management, see [best_practices.md](./best_practices.md). -### Automatic environment setup +## Prerequisites -See [Flotilla readme](../README.md#automatic-environment-setup) +- [Docker](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/) -### Manual environment setup +## Configuration -The best way to pass this is to store it in a `.env` file in the broker folder in flotilla, and Docker Compose loads this by default on startup. -See [Using the “--env-file” option](https://docs.docker.com/compose/environment-variables/#using-the---env-file--option) for more information. +The broker expects the private key for its server x509 certificate, used for TLS, in the environment variable `TLS_SERVER_KEY`. This is a secret and should be treated as such — it is found in our key vault. -## Running the broker +Create the configuration by running [`setup.sh`](../setup.sh) from the repository root, which prompts you for the key. Alternatively, copy the template and fill it in manually: -From the flotilla root directory, run the following command: - -``` -docker compose up --build broker +```bash +cp .env.example .env ``` -If the address is already in use, you might have to kill the Mosquitto process `sudo pkill mosquitto`. - -## Authentication - -The broker has been set up with role-based authentication. -The current roles with their permissions per topic are described in the table below. - -| | read | write | -| -------- | ------ | ------ | -| admin | # | # | -| flotilla | isar/# | - | -| isar | isar/# | isar/# | - -To change the password see [this guide](https://mosquitto.org/documentation/authentication-methods/) -on how to manage the [password file](./mosquitto/config/passwd_file). - -To change the roles see [this guide](https://mosquitto.org/documentation/authentication-methods/) -on how to manage the role-based access control. -They are defined in the [access_control file](./mosquitto/config/access_control). - -## Installing broker outside of Docker +Docker Compose loads `broker/.env` by default on startup. See [Using the "--env-file" option](https://docs.docker.com/compose/environment-variables/#using-the---env-file--option) for more information. -To test the dockerized broker, the functions `mosquitto_sub` and `mosquitto_pub` are useful. -To gain access to them on your machine you will need to install the Mosquitto broker. +## Run -### Linux installation +From the repository root: -To install the Mosquitto broker run the following commands: - -``` -sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa -sudo apt-get update -sudo apt-get install mosquitto -sudo apt-get install mosquitto-clients +```bash +make broker # docker compose up broker --build ``` -### Windows installation - -Go to the [official Mosquitto download page](https://mosquitto.org/download/) and download and install the -binaries for Windows. - -Then add the installation folder to your PATH variable for the commands to be available from your terminal. - -### Start non-Docker broker - -If running the broker outside Docker, you will need to manually create the `server-key.pem` file, containing the secret server key mentioned in the [setup section](#set-up-the-broker). -The Mosquitto config file expects this file to be stored in the [mosquitto/config/certs](./mosquitto/config/certs) folder. - -The broker may then be started with: +If the address is already in use, you may have to kill an existing Mosquitto process: +```bash +sudo pkill mosquitto ``` -mosquitto -p 1883 -c mosquitto/config/mosquitto.conf -``` - -## Testing the broker - -To test that the broker functions as expected the `mosquitto_sub` and `mosquitto_pub` tools that are wrapped in the installation may be used. -For access to all topics, you need to use the admin user. -The password for the admin can be found in our key vault. - -For the TLS encryption, you will need to reference the CA certificate. This is not a secret and can be found in [mosquitto/config/certs](./mosquitto/config/certs). - -First, subscribe to a topic: - -``` -mosquitto_sub -t topic_name -u admin -P secret_password --cafile ca-cert.pem -``` - -Then attempt to publish something to the same topic in a different terminal: - -``` -mosquitto_pub -t topic_name -m hei -u admin -P secret_password --cafile ca-cert.pem -``` - -## MQTT Broker Certificates - -If the CA and server certificates have expired, they should be generated by following the steps available on the [utility scripts](https://github.com/equinor/eq_robot_utility_scripts/blob/main/certificates/README.md) repository. diff --git a/broker/best_practices.md b/broker/best_practices.md new file mode 100644 index 000000000..20ddea3d5 --- /dev/null +++ b/broker/best_practices.md @@ -0,0 +1,68 @@ +# Broker best practices + +Reference material for the Flotilla MQTT broker. For installation and how to run the broker, see the [README](./README.md). + +## Authentication + +The broker has been set up with role-based authentication. The current roles with their permissions per topic are described in the table below. + +| | read | write | +| -------- | ------ | ------ | +| admin | # | # | +| flotilla | isar/# | - | +| isar | isar/# | isar/# | + +To change the password see [this guide](https://mosquitto.org/documentation/authentication-methods/) on how to manage the [password file](./mosquitto/config/passwd_file). + +To change the roles see [this guide](https://mosquitto.org/documentation/authentication-methods/) on how to manage the role-based access control. They are defined in the [access_control file](./mosquitto/config/access_control). + +## Installing the broker outside of Docker + +To test the dockerized broker, the functions `mosquitto_sub` and `mosquitto_pub` are useful. To gain access to them on your machine you will need to install the Mosquitto broker. + +### Linux + +```bash +sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa +sudo apt-get update +sudo apt-get install mosquitto +sudo apt-get install mosquitto-clients +``` + +### Windows + +Go to the [official Mosquitto download page](https://mosquitto.org/download/) and download and install the binaries for Windows. + +Then add the installation folder to your PATH variable for the commands to be available from your terminal. + +### Starting a non-Docker broker + +If running the broker outside Docker, you will need to manually create the `server-key.pem` file, containing the secret server key described in the [README](./README.md#configuration). The Mosquitto config file expects this file to be stored in the [mosquitto/config/certs](./mosquitto/config/certs) folder. + +The broker may then be started with: + +```bash +mosquitto -p 1883 -c mosquitto/config/mosquitto.conf +``` + +## Testing the broker + +To test that the broker functions as expected, the `mosquitto_sub` and `mosquitto_pub` tools may be used. For access to all topics, you need to use the admin user. The password for the admin can be found in our key vault. + +For the TLS encryption, you will need to reference the CA certificate. This is not a secret and can be found in [mosquitto/config/certs](./mosquitto/config/certs). + +First, subscribe to a topic: + +```bash +mosquitto_sub -t topic_name -u admin -P secret_password --cafile ca-cert.pem +``` + +Then attempt to publish something to the same topic in a different terminal: + +```bash +mosquitto_pub -t topic_name -m hei -u admin -P secret_password --cafile ca-cert.pem +``` + +## Certificates + +If the CA and server certificates have expired, they should be generated by following the steps available in the [utility scripts](https://github.com/equinor/eq_robot_utility_scripts/blob/main/certificates/README.md) repository. diff --git a/catalog-info.yaml b/catalog-info.yaml index 9d8bd55ca..40665c7c9 100644 --- a/catalog-info.yaml +++ b/catalog-info.yaml @@ -21,13 +21,13 @@ metadata: github.com/project-slug: equinor/flotilla github.com/team-slug: equinor/eq-robot-developer links: - - url: https://shared.dev.aurora.equinor.com/robotics-frontend/ + - url: https://flotilla.dev.robotics.equinor.com/ title: Flotilla Frontend Dev icon: public - - url: https://shared.aurora.equinor.com/robotics-staging-frontend/ + - url: https://flotilla.staging.robotics.equinor.com/ title: Flotilla Frontend Staging icon: public - - url: https://shared.aurora.equinor.com/robotics-prod-frontend/ + - url: https://flotilla.robotics.equinor.com/ title: Flotilla Frontend Prod icon: public spec: @@ -49,13 +49,13 @@ metadata: github.com/project-slug: equinor/flotilla github.com/team-slug: equinor/eq-robot-developer links: - - url: https://shared.dev.aurora.equinor.com/robotics-backend/swagger + - url: https://flotilla.dev.robotics.equinor.com/api/swagger title: Flotilla Backend Dev icon: public - - url: https://shared.aurora.equinor.com/robotics-staging-backend/swagger + - url: https://flotilla.staging.robotics.equinor.com/api/swagger title: Flotilla Backend Staging icon: public - - url: https://shared.aurora.equinor.com/robotics-prod-backend/swagger + - url: https://flotilla.robotics.equinor.com/api/swagger title: Flotilla Backend Prod icon: public spec: diff --git a/frontend/README.md b/frontend/README.md index d6f247ea4..48ca284c8 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,75 +1,47 @@ # Flotilla frontend -This document describes how to run the frontend. For information on best practices related to development, [see the best practices document](./best_practices.md). +The Flotilla frontend is a React application written in TypeScript and built with Vite. -## Setup +For development conventions, folder structure, and formatting, see [best_practices.md](./best_practices.md). -The app uses TypeScript and React. For development, Node v24.x needs to be installed. Installation instructions can be found -[here](https://github.com/nodesource/distributions/blob/master/README.md). +## Prerequisites -The application reads environment variables from the `.env` file in the `frontend` folder. +- [Node.js 24.x](https://github.com/nodesource/distributions) +- [pnpm](https://pnpm.io/installation) -### Automatic environment setup +## Configuration -See [Flotilla readme](../README.md#automatic-environment-setup). +The application reads environment variables from `frontend/.env`. Create it by running [`setup.sh`](../setup.sh) from the repository root, or by copying the template manually: -### Manual environment setup +```bash +cp .env.example .env +``` -As a starting point, make a copy of the `.env.example` file and rename it to `.env`. +Only variables prefixed with `VITE_` are included in the application. They are parsed and defined in [config.ts](./src/config.ts). ## Install -To install the application, navigate to the frontend folder and run the following command: +From the `frontend` folder: -``` +```bash pnpm install --frozen-lockfile ``` ## Run -To start the app, run the following command in the root folder: - +```bash +pnpm dev # or: make run ``` -pnpm dev -``` - -This command runs the app in development mode. Open [http://localhost:3001](http://localhost:3001) to view it in the browser. -The page will reload if you make edits. You will also be able to see any lint errors in the console. +The app is served at in development mode. The page reloads when you make edits, and lint errors appear in the console. -## Run in Docker +To run the frontend in Docker, run the following from the repository root: -To run the frontend in Docker, run the following command in the root folder of Flotilla: - -``` +```bash docker compose up --build frontend ``` -## Authentication - -Authentication is implemented for the frontend following the [official Microsoft tutorial on OAuth2 flow in React](https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react). - -## Formatting - -We use Prettier for formatting. -To test the formatting locally, run: - -``` -pnpm prettier_check -``` - -We recommend installing the [Prettier extension for VS Code](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) -and setting the `format on save` option for VS Code to true. -You can do this by going to `File` -> `Preferences` -> `Settings` and then searching for "Format On Save" and ticking the box. - -## Config - -The application reads custom environment variables from the `.env` file on startup. The variables need to be prefixed with `VITE_` to be included in the application. -These are parsed and defined in [config.ts](./src/config.ts). - -## Run locally with Staging and Prod Databases - -To run locally towards the databases, follow the steps below: +## Run against the Staging or Production backend -1. Change `UseInMemoryDatabase` to `false` in `appsettings.Local` and set `ASPNETCORE_ENVIRONMENT` to the correct environment in `launchSettings.json`. -3. Update `VITE_BACKEND_API_SCOPE` in the `.env` file located in the `frontend` folder. +1. Update `VITE_BACKEND_API_SCOPE` in `frontend/.env` to the scope of the environment you want to target. +2. Point the backend at that environment as well — see the [backend README](../backend/README.md#connecting-to-the-development-database). diff --git a/frontend/best_practices.md b/frontend/best_practices.md index 94654b542..680765cc8 100644 --- a/frontend/best_practices.md +++ b/frontend/best_practices.md @@ -4,6 +4,7 @@ - [Setup](#setup) - [Prettier](#prettier) - [ESLint](#eslint) + - [Authentication](#authentication) - [Folder structure](#folder-structure) - [Components](#react-components) - [React arguments](#react-arguments) @@ -18,34 +19,63 @@ ## Setup -See the [README](./README.md) for more information. +For installation and how to run the frontend, see the [README](./README.md). ### Prettier -We abide by the formatting provided by Prettier. To run it, type -npx prettier --write [path to source] +We abide by the formatting provided by Prettier. To format the code, run: + +```bash +pnpm exec prettier --write src +``` + +To check the formatting without changing anything, run: + +```bash +pnpm prettier_check +``` + +We recommend installing the [Prettier extension for VS Code](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) and enabling `format on save`. You can do this by going to `File` -> `Preferences` -> `Settings`, searching for "Format On Save", and ticking the box. ### ESLint We also avoid any warnings or errors from ESLint before we merge in any code. These warnings appear when compiling the code using -npm run dev + +```bash +pnpm dev +``` + but can also be run with -npx eslint [path to src] + +```bash +pnpm lint +``` + +`make format` runs Prettier, ESLint, and the unused-exports check in one go. + +## Authentication + +Authentication is implemented following the [official Microsoft tutorial on OAuth2 flow in React](https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react). ## Folder structure -The frontend src folder is organized into 6 main folders. - -- Alerts contains code which displays alerts on the top of the page -- Contexts contain react contexts (see [the context section for more information](#contexts)) -- Displays contains visual react components which are used on more than one page -- Header contains code related to the page header -- Pages contains the bulk of the code, as all the code related to the website pages are kept here, if there are no other relevant folders -- Language contains translations between the supported languages for text on the Flotilla web page -- MediaAssets contains the static image files displayed on the page -- Models contains the data models -- Utils contains utility functions which are relevant in several parts of the code +The frontend `src` folder is organized into 8 main folders. + +- `api` contains the clients for the Flotilla backend and SARA, authentication config, and error handling +- `components` contains React components shared across more than one page, grouped into: + - `Alerts` — code which displays alerts at the top of the page + - `Contexts` — React contexts (see [the context section for more information](#contexts)) + - `Dialogs` — modal dialogs + - `Displays` — visual components reused across pages + - `Header` — code related to the page header + - `Styles` — shared styled-components and style constants +- `hooks` contains reusable React hooks +- `language` contains translations between the supported languages for text on the Flotilla web page +- `mediaAssets` contains the static image files displayed on the page +- `models` contains the data models +- `pages` contains the bulk of the code, as all the code related to the website pages is kept here +- `utils` contains utility functions which are relevant in several parts of the code ## Function syntax diff --git a/frontend/package.json b/frontend/package.json index a03d9115b..34b285d0e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,7 +2,6 @@ "name": "flotilla", "version": "0.1.0", "private": true, - "homepage": ".", "type": "module", "dependencies": { "@azure/msal-browser": "^5.18.0", @@ -11,9 +10,7 @@ "@equinor/eds-icons": "^1.5.1", "@equinor/eds-tokens": "^2.3.2", "@microsoft/signalr": "^10.0.11", - "@nevware21/ts-async": "^0.5.5", "@tanstack/react-query": "^5.101.4", - "@types/node": "^25.9.5", "@types/react": "^19.2.18", "@types/react-dom": "^19.2.4", "@vitejs/plugin-react-swc": "^4.3.3", @@ -29,13 +26,11 @@ "react-chartjs-2": "^5.3.1", "react-dom": "^19.2.8", "react-leaflet": "^5.0.0", - "react-modal": "^3.16.3", "react-player": "^3.4.0", "react-router": "^8.3.0", "styled-components": "^6.5.0", "ts-custom-error": "^3.3.1", - "vite": "^7.3.6", - "vite-plugin-svgr": "^4.5.0" + "vite": "^7.3.6" }, "scripts": { "dev": "vite", @@ -45,25 +40,10 @@ "lint": "eslint src", "prettier_check": "prettier --check src" }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, "devDependencies": { "@eslint/js": "^9.39.5", "@types/leaflet": "^1.9.22", - "@types/luxon": "^3.7.3", "@types/react-big-calendar": "^1.16.3", - "@types/react-modal": "^3.16.3", - "@types/styled-components": "^5.1.36", "eslint": "^9.39.5", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.1.1", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 57d262309..c39beace5 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -29,15 +29,9 @@ importers: '@microsoft/signalr': specifier: ^10.0.11 version: 10.0.11 - '@nevware21/ts-async': - specifier: ^0.5.5 - version: 0.5.5 '@tanstack/react-query': specifier: ^5.101.4 version: 5.101.4(react@19.2.8) - '@types/node': - specifier: ^25.9.5 - version: 25.9.5 '@types/react': specifier: ^19.2.18 version: 19.2.18 @@ -83,9 +77,6 @@ importers: react-leaflet: specifier: ^5.0.0 version: 5.0.0(leaflet@1.9.4)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - react-modal: - specifier: ^3.16.3 - version: 3.16.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) react-player: specifier: ^3.4.0 version: 3.4.0(@svta/cml-cta@1.0.6(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0))(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -101,9 +92,6 @@ importers: vite: specifier: ^7.3.6 version: 7.3.6(@types/node@25.9.5) - vite-plugin-svgr: - specifier: ^4.5.0 - version: 4.5.0(rollup@4.62.4)(typescript@5.9.3)(vite@7.3.6(@types/node@25.9.5)) devDependencies: '@eslint/js': specifier: ^9.39.5 @@ -111,18 +99,9 @@ importers: '@types/leaflet': specifier: ^1.9.22 version: 1.9.22 - '@types/luxon': - specifier: ^3.7.3 - version: 3.7.3 '@types/react-big-calendar': specifier: ^1.16.3 version: 1.16.3 - '@types/react-modal': - specifier: ^3.16.3 - version: 3.16.3 - '@types/styled-components': - specifier: ^5.1.36 - version: 5.1.36 eslint: specifier: ^9.39.5 version: 9.39.5 @@ -641,12 +620,6 @@ packages: os: [linux] libc: [glibc] - '@nevware21/ts-async@0.5.5': - resolution: {integrity: sha512-vwqaL05iJPjLeh5igPi8MeeAu10i+Aq7xko1fbo9F5Si6MnVN5505qaV7AhSdk5MCBJVT/UYMk3kgInNjDb4Ig==} - - '@nevware21/ts-utils@0.16.0': - resolution: {integrity: sha512-DDln15VUBSw5JjJlNno1UCSzgAGzHHklm7u695jXDCzwSn7W2F7B2VYHwLLcT1cOWQQBQAJK6e2/Y8oTG+W0Ig==} - '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -688,15 +661,6 @@ packages: '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@rollup/pluginutils@5.4.0': - resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/rollup-android-arm-eabi@4.62.4': resolution: {integrity: sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==} cpu: [arm] @@ -838,74 +802,6 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@svgr/babel-plugin-add-jsx-attribute@8.0.0': - resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': - resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': - resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0': - resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-plugin-svg-dynamic-title@8.0.0': - resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-plugin-svg-em-dimensions@8.0.0': - resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-plugin-transform-react-native-svg@8.1.0': - resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-plugin-transform-svg-component@8.0.0': - resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} - engines: {node: '>=12'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/babel-preset@8.1.0': - resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@svgr/core@8.1.0': - resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} - engines: {node: '>=14'} - - '@svgr/hast-util-to-babel-ast@8.0.0': - resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} - engines: {node: '>=14'} - - '@svgr/plugin-jsx@8.1.0': - resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} - engines: {node: '>=14'} - peerDependencies: - '@svgr/core': '*' - '@svta/cml-608@1.0.2': resolution: {integrity: sha512-ZEJ68330gcLKfvVv6Qifr1HR7+GldDUxzkjqSbqRK7jHtHSLSV1JAyDwlYe8+C7ABuY1bp8MpgJ4/Gg+jl+pLQ==} engines: {node: '>=20'} @@ -1102,11 +998,6 @@ packages: '@types/google_interactive_media_ads_types@3.697.1': resolution: {integrity: sha512-gRjJoPKQRjjTuySHqZe8Pnu6a5B0bKbTUD2ioDLPSWlEuBaAc2p1mzUzy42SCeWkyYffo2Mnv+blUGuvVvx3dQ==} - '@types/hoist-non-react-statics@3.3.7': - resolution: {integrity: sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==} - peerDependencies: - '@types/react': '*' - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1116,9 +1007,6 @@ packages: '@types/leaflet@1.9.22': resolution: {integrity: sha512-h3lhECYEKDasG7LFHu+GiHqAvsgLuQvlJvVZzJDGONo3sEL+wUOqSFLnwkZlK0qVxnxbuGFW8iBlJNYs5wgndA==} - '@types/luxon@3.7.3': - resolution: {integrity: sha512-pE7BSbKHiojpl4v7iEzdfFLXXJaH5RPJxI3Wr4x3HU59l83PJfhcUx4mGPWq245+DCAENAzRF/+ZoYr2tJCe/g==} - '@types/node@25.9.5': resolution: {integrity: sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==} @@ -1133,15 +1021,9 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react-modal@3.16.3': - resolution: {integrity: sha512-xXuGavyEGaFQDgBv4UVm8/ZsG+qxeQ7f77yNrW3n+1J6XAstUy5rYHeIHPh1KzsGc6IkCIdu6lQ2xWzu1jBTLg==} - '@types/react@19.2.18': resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} - '@types/styled-components@5.1.36': - resolution: {integrity: sha512-pGMRNY5G2rNDKEv2DOiFYa7Ft1r0jrhmgBwHhOMzPTgCjO76bCot0/4uEfqj7K0Jf1KdQmDtAuaDk9EAs9foSw==} - '@types/warning@3.0.4': resolution: {integrity: sha512-CqN8MnISMwQbLJXO3doBAV4Yw9hx9/Pyr2rZ78+NfaCnhyRA/nKrpyk6E7mKw17ZOaQdLpK9GiUjrqLzBlN3sg==} @@ -1360,10 +1242,6 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - caniuse-lite@1.0.30001806: resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} @@ -1425,15 +1303,6 @@ packages: cookie-es@3.1.1: resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} - cosmiconfig@8.3.6: - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1521,9 +1390,6 @@ packages: dom-helpers@6.0.1: resolution: {integrity: sha512-IKySryuFwseGkrCA/pIqlwUPOD50w1Lj/B2Yief3vBOP18k5y4t+hTqKh55gULDVeJMRitcozve+g/wVFf4sFQ==} - dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - downshift@9.3.2: resolution: {integrity: sha512-5VD0WZLQDhipWiDU+K5ili3VDhGrXwlvOlSaSG1Cb0eS4XpssxVuoD09JNgju+bAzxB2Wvlwx+FwTE/FNdrqow==} peerDependencies: @@ -1536,17 +1402,10 @@ packages: electron-to-chromium@1.5.401: resolution: {integrity: sha512-H6ViHN68nGYlChEvlIU67fn8O2/tpbWQPwck98yaJmh+08LSvHiydzDQ6oXNccLU3kNRVIRS9A4mA7CG+i6fLQ==} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - entities@8.0.0: resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} engines: {node: '>=20.19.0'} - error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-abstract-get@1.0.0: resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==} engines: {node: '>= 0.4'} @@ -1658,9 +1517,6 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -1680,9 +1536,6 @@ packages: resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} engines: {node: '>=12.0.0'} - exenv@1.2.2: - resolution: {integrity: sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==} - expect-type@1.4.0: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} @@ -1824,9 +1677,6 @@ packages: hls.js@1.6.16: resolution: {integrity: sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA==} - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - html-encoding-sniffer@6.0.0: resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -1875,9 +1725,6 @@ packages: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} @@ -2014,9 +1861,6 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -2049,9 +1893,6 @@ packages: lie@3.1.1: resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - livekit-client@2.21.0: resolution: {integrity: sha512-RBUhPkV/sl1nzl8lokVlK5uATPwn0AlsudCBZXissw/kDl9yz8ac4pNJ43iPpMVoHOeBYH/BZ3vUC1adqa/zFQ==} peerDependencies: @@ -2081,9 +1922,6 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - lru-cache@11.5.2: resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} @@ -2150,9 +1988,6 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-exports-info@1.6.2: resolution: {integrity: sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==} engines: {node: '>= 0.4'} @@ -2222,10 +2057,6 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - parse5@8.0.1: resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} @@ -2243,10 +2074,6 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -2329,12 +2156,6 @@ packages: react-lifecycles-compat@3.0.4: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} - react-modal@3.16.3: - resolution: {integrity: sha512-yCYRJB5YkeQDQlTt17WGAgFJ7jr2QYcWa1SHqZ3PluDmnKJ/7+tVU+E6uKyZ0nODaeEj+xCpK4LcSnKXLMC0Nw==} - peerDependencies: - react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19 - react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19 - react-overlays@5.2.1: resolution: {integrity: sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==} peerDependencies: @@ -2479,9 +2300,6 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2556,9 +2374,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svg-parser@2.0.4: - resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} - symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -2705,11 +2520,6 @@ packages: vimeo-video-element@1.7.2: resolution: {integrity: sha512-7QM7fvSZvTTSq4igxBuO6Gc+0u3Exgk4IaLNixVzilCPzHEf7SN8b6YLXSM5QCs0ineTJI4XjiUCSoIbabHvwg==} - vite-plugin-svgr@4.5.0: - resolution: {integrity: sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==} - peerDependencies: - vite: '>=2.6.0' - vite@7.3.6: resolution: {integrity: sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3358,12 +3168,6 @@ snapshots: '@napi-rs/lzma-linux-x64-gnu@1.5.1': optional: true - '@nevware21/ts-async@0.5.5': - dependencies: - '@nevware21/ts-utils': 0.16.0 - - '@nevware21/ts-utils@0.16.0': {} - '@popperjs/core@2.11.8': {} '@react-aria/utils@3.34.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': @@ -3405,14 +3209,6 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/pluginutils@5.4.0(rollup@4.62.4)': - dependencies: - '@types/estree': 1.0.9 - estree-walker: 2.0.2 - picomatch: 4.0.5 - optionalDependencies: - rollup: 4.62.4 - '@rollup/rollup-android-arm-eabi@4.62.4': optional: true @@ -3490,76 +3286,6 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - - '@svgr/babel-preset@8.1.0(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.7) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.7) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.7) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.7) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.7) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.7) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.7) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.7) - - '@svgr/core@8.1.0(typescript@5.9.3)': - dependencies: - '@babel/core': 7.29.7 - '@svgr/babel-preset': 8.1.0(@babel/core@7.29.7) - camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.9.3) - snake-case: 3.0.4 - transitivePeerDependencies: - - supports-color - - typescript - - '@svgr/hast-util-to-babel-ast@8.0.0': - dependencies: - '@babel/types': 7.29.8 - entities: 4.5.0 - - '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))': - dependencies: - '@babel/core': 7.29.7 - '@svgr/babel-preset': 8.1.0(@babel/core@7.29.7) - '@svgr/core': 8.1.0(typescript@5.9.3) - '@svgr/hast-util-to-babel-ast': 8.0.0 - svg-parser: 2.0.4 - transitivePeerDependencies: - - supports-color - '@svta/cml-608@1.0.2': {} '@svta/cml-cmcd@2.3.2(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0)': @@ -3699,11 +3425,6 @@ snapshots: '@types/google_interactive_media_ads_types@3.697.1': {} - '@types/hoist-non-react-statics@3.3.7(@types/react@19.2.18)': - dependencies: - '@types/react': 19.2.18 - hoist-non-react-statics: 3.3.2 - '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -3712,11 +3433,10 @@ snapshots: dependencies: '@types/geojson': 7946.0.16 - '@types/luxon@3.7.3': {} - '@types/node@25.9.5': dependencies: undici-types: 7.24.6 + optional: true '@types/prop-types@15.7.15': {} @@ -3730,20 +3450,10 @@ snapshots: dependencies: '@types/react': 19.2.18 - '@types/react-modal@3.16.3': - dependencies: - '@types/react': 19.2.18 - '@types/react@19.2.18': dependencies: csstype: 3.2.3 - '@types/styled-components@5.1.36': - dependencies: - '@types/hoist-non-react-statics': 3.3.7(@types/react@19.2.18) - '@types/react': 19.2.18 - csstype: 3.2.3 - '@types/warning@3.0.4': {} '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)': @@ -4033,8 +3743,6 @@ snapshots: callsites@3.1.0: {} - camelcase@6.3.0: {} - caniuse-lite@1.0.30001806: {} castable-video@1.1.16: @@ -4083,15 +3791,6 @@ snapshots: cookie-es@3.1.1: {} - cosmiconfig@8.3.6(typescript@5.9.3): - dependencies: - import-fresh: 3.3.1 - js-yaml: 4.3.1 - parse-json: 5.2.0 - path-type: 4.0.0 - optionalDependencies: - typescript: 5.9.3 - cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -4212,11 +3911,6 @@ snapshots: '@babel/runtime': 7.29.7 csstype: 3.2.3 - dot-case@3.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.8.1 - downshift@9.3.2(react@19.2.8): dependencies: '@babel/runtime': 7.29.7 @@ -4234,14 +3928,8 @@ snapshots: electron-to-chromium@1.5.401: {} - entities@4.5.0: {} - entities@8.0.0: {} - error-ex@1.3.4: - dependencies: - is-arrayish: 0.2.1 - es-abstract-get@1.0.0: dependencies: es-errors: 1.3.0 @@ -4491,8 +4179,6 @@ snapshots: estraverse@5.3.0: {} - estree-walker@2.0.2: {} - estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 @@ -4505,8 +4191,6 @@ snapshots: eventsource@2.0.2: {} - exenv@1.2.2: {} - expect-type@1.4.0: {} fast-deep-equal@3.1.3: {} @@ -4646,10 +4330,6 @@ snapshots: hls.js@1.6.16: {} - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - html-encoding-sniffer@6.0.0: dependencies: '@exodus/bytes': 1.15.1 @@ -4705,8 +4385,6 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 - is-arrayish@0.2.1: {} - is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -4865,8 +4543,6 @@ snapshots: json-buffer@3.0.1: {} - json-parse-even-better-errors@2.3.1: {} - json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} @@ -4899,8 +4575,6 @@ snapshots: dependencies: immediate: 3.0.6 - lines-and-columns@1.2.4: {} - livekit-client@2.21.0(@types/dom-mediacapture-record@1.0.22): dependencies: '@livekit/mutex': 1.1.1 @@ -4934,10 +4608,6 @@ snapshots: dependencies: js-tokens: 4.0.0 - lower-case@2.0.2: - dependencies: - tslib: 2.8.1 - lru-cache@11.5.2: {} lru-cache@5.1.1: @@ -4992,11 +4662,6 @@ snapshots: natural-compare@1.4.0: {} - no-case@3.0.4: - dependencies: - lower-case: 2.0.2 - tslib: 2.8.1 - node-exports-info@1.6.2: dependencies: array.prototype.flatmap: 1.3.3 @@ -5076,13 +4741,6 @@ snapshots: dependencies: callsites: 3.1.0 - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.29.7 - error-ex: 1.3.4 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - parse5@8.0.1: dependencies: entities: 8.0.0 @@ -5095,8 +4753,6 @@ snapshots: path-parse@1.0.7: {} - path-type@4.0.0: {} - pathe@2.0.3: {} picocolors@1.1.1: {} @@ -5193,15 +4849,6 @@ snapshots: react-lifecycles-compat@3.0.4: {} - react-modal@3.16.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8): - dependencies: - exenv: 1.2.2 - prop-types: 15.8.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - react-lifecycles-compat: 3.0.4 - warning: 4.0.3 - react-overlays@5.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: '@babel/runtime': 7.29.7 @@ -5422,11 +5069,6 @@ snapshots: siginfo@2.0.0: {} - snake-case@3.0.4: - dependencies: - dot-case: 3.0.4 - tslib: 2.8.1 - source-map-js@1.2.1: {} spotify-audio-element@1.0.4: {} @@ -5508,8 +5150,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svg-parser@2.0.4: {} - symbol-tree@3.2.4: {} tabbable@6.5.0: {} @@ -5642,7 +5282,8 @@ snapshots: react: 19.2.8 react-lifecycles-compat: 3.0.4 - undici-types@7.24.6: {} + undici-types@7.24.6: + optional: true undici@7.29.0: {} @@ -5672,17 +5313,6 @@ snapshots: '@vimeo/player': 2.29.0 media-played-ranges-mixin: 0.1.0 - vite-plugin-svgr@4.5.0(rollup@4.62.4)(typescript@5.9.3)(vite@7.3.6(@types/node@25.9.5)): - dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.4) - '@svgr/core': 8.1.0(typescript@5.9.3) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) - vite: 7.3.6(@types/node@25.9.5) - transitivePeerDependencies: - - rollup - - supports-color - - typescript - vite@7.3.6(@types/node@25.9.5): dependencies: esbuild: 0.28.1 diff --git a/frontend/src/language/en.json b/frontend/src/language/en.json index 7f80d3dc2..1782bfda8 100644 --- a/frontend/src/language/en.json +++ b/frontend/src/language/en.json @@ -55,10 +55,6 @@ "History": "History", "Stop": "Stop", "Start": "Start", - "North": "North", - "East": "East", - "South": "South", - "West": "West", "Skip button pressed warning text": "You are about to skip the entire mission. If there are no more missions in the queue, the robot will return to the start position.", "Skip button pressed confirmation text": "Are you sure you want to skip the mission?", "Skip mission": "Skip mission", @@ -98,7 +94,6 @@ "Add mission to the queue": "Add mission to the queue", "Not yet performed": "Not yet performed", "Never": "Never", - "Idle": "Idle", "No inspections available": "No inspections available", "Queue mission": "Queue mission", "for": "for", @@ -136,7 +131,6 @@ "Dock banner text": "The robots are driving to the dock and will not run missions. To continue the mission press the 'Dismiss robots from dock' button.", "Dismiss dock banner text": "The robots will continue the missions.", "Completed Tasks": "Completed Tasks", - "Failed to retrieve missions": "Failed to retrieve missions", "Request error": "Request error", "Failed to delete mission from queue": "Failed to delete mission from queue", "Failed to rerun mission": "Failed to rerun mission", @@ -198,7 +192,6 @@ "Detection type": "Detection type", "leak": "Leak", "Inspection report for task": "Inspection report for task", - "Battery is too low to start a mission.": "Battery is too low to start a mission.", "Robot is sent to dock and cannot run missions. Queued missions will run when robot is dismissed from dock.": "Robot is sent to dock and cannot run missions. Queued missions will run when robot is dismissed from dock.", "Queued Missions": "Queued Missions", "Waiting for inspection result": "Waiting for inspection result", @@ -296,14 +289,6 @@ "Confidence": "Confidence", "Value": "Value", "Analysis": "Analysis", - "CO2 consentration: {0}%": "CO2 consentration: {0}%", - "Successful Missions": "Successful Missions", - "Partially Successful Missions": "Partially Successful Missions", - "Failed Missions": "Failed Missions", - "Mission Success Rate": "Mission Success Rate", - "Successful Tasks": "Successful Tasks", - "Failed Tasks": "Failed Tasks", - "Task Success Rate": "Task Success Rate", "Loading installation data": "Loading installation data", "RechargingWithMission": "Recharging", "GoingToRechargingWithMission": "Returning to recharge", diff --git a/frontend/src/language/no.json b/frontend/src/language/no.json index 9d79c184c..6b9c12f85 100644 --- a/frontend/src/language/no.json +++ b/frontend/src/language/no.json @@ -55,10 +55,6 @@ "History": "Historikk", "Stop": "Stopp", "Start": "Start", - "North": "Nord", - "East": "Øst", - "South": "Sør", - "West": "Vest", "Skip button pressed warning text": "Du er i ferd med å hoppe over hele oppdraget. Hvis det ikke er flere oppdrag i kø vil roboten bli sendt tilbake til startposisjonen sin.", "Skip button pressed confirmation text": "Er du sikker på at du vil hoppe over oppdraget?", "Skip mission": "Hopp over oppdraget", @@ -98,7 +94,6 @@ "Add mission to the queue": "Legg til oppdrag i kø", "Not yet performed": "Aldri kjørt", "Never": "Aldri", - "Idle": "Inaktiv", "No inspections available": "Ingen tilgjengelige inspeksjoner", "Queue mission": "Legg oppdraget i kø", "for": "for", @@ -136,7 +131,6 @@ "Dock banner text": "Robotene kjører til ladestasjonene og vil ikke kjøre oppdrag. For å fortsette oppdrag trykk på knappen 'Slipp robotene ut fra ladestasjon'.", "Dismiss dock banner text": "Roboten fortsetter på oppdragene.", "Completed Tasks": "Fullførte oppgaver", - "Failed to retrieve missions": "Kunne ikke hente ut oppdrag", "Request error": "Forespørselsfeil", "Failed to delete mission from queue": "Kunne ikke fjerne oppdrag fra køen", "Failed to rerun mission": "Kunne ikke kjøre oppdraget på nytt", @@ -159,7 +153,7 @@ "INFO": "INFO", "Dock": "Ladestasjon", "Dock successful text": "Robotene er i ladestasjonen og vil ikke kjøre oppdrag. For å fortsette oppdrag trykk på knappen 'Slipp robotene ut fra ladestasjon'.", - "Connection Issues": "Tilkoblings\u00adproblemer", + "Connection Issues": "Tilkoblings­problemer", "Pressure": "Trykk", "Add to queue": "Legg til i kø", "Failed to pause mission on {0}": "Kunne ikke pause oppdrag på robot {0}", @@ -198,7 +192,6 @@ "Detection type": "Deteksjonstype", "leak": "Lekkasje", "Inspection report for task": "Inspeksjonsrapport for oppgave", - "Battery is too low to start a mission.": "Batterinivået er for lavt til å starte oppdrag.", "Robot is sent to dock and cannot run missions. Queued missions will run when robot is dismissed from dock.": "Roboten er sendt til ladestasjon og kan ikke kjøre oppdrag. Oppdrag i kø vil kjøres når roboten slippes ut fra ladestasjon.", "Queued Missions": "Oppdragskø", "Waiting for inspection result": "Venter på inspeksjonsresultat", @@ -296,14 +289,6 @@ "Confidence": "Treffsikkerhet", "Value": "Verdi", "Analysis": "Analyse", - "CO2 consentration: {0}%": "CO2 konsentrasjon: {0}%", - "Successful Missions": "Vellykkede oppdrag", - "Partially Successful Missions": "Delvis vellykkede oppdrag", - "Failed Missions": "Mislykkede oppdrag", - "Mission Success Rate": "Suksessrate for oppdrag", - "Successful Tasks": "Vellykkede oppgaver", - "Failed Tasks": "Mislykkede oppgaver", - "Task Success Rate": "Suksessrate for oppgaver", "Loading installation data": "Laster installasjonsdata", "RechargingWithMission": "Lader", "GoingToRechargingWithMission": "Returnerer for å lade", @@ -318,7 +303,6 @@ "Selected inspection": "Utvalgt inspeksjon", "Selected analysis result": "Utvalgt analyseresultat", "Data View for Constant Level Oilers": "Datavisning for Nivåmåling", - "Analysis result not available": "Analyseresultat ikke tilgjengelig", "Go to data overview": "Gå til dataoversikt", "Latest inspection": "Siste inspeksjon", "Analysis result": "Analyseresultat", diff --git a/frontend/src/mediaAssets/Asset.png b/frontend/src/mediaAssets/Asset.png deleted file mode 100644 index afecff9ce..000000000 Binary files a/frontend/src/mediaAssets/Asset.png and /dev/null differ diff --git a/frontend/src/mediaAssets/taurob_inspector.jpg b/frontend/src/mediaAssets/taurob_inspector.jpg deleted file mode 100644 index fa2c2b013..000000000 Binary files a/frontend/src/mediaAssets/taurob_inspector.jpg and /dev/null differ diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 88f0ebe1c..5b8956159 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -15,7 +15,7 @@ "noEmit": true, "noFallthroughCasesInSwitch": true, "jsx": "react-jsx", - "types": ["vite/client", "vite-plugin-svgr/client"], + "types": ["vite/client"], "baseUrl": "src", "outDir": "out", "sourceMap": true diff --git a/radixconfig.yaml b/radixconfig.yaml deleted file mode 100644 index c02433ce9..000000000 --- a/radixconfig.yaml +++ /dev/null @@ -1,54 +0,0 @@ -apiVersion: radix.equinor.com/v1 -kind: RadixApplication -metadata: - name: flotilla -spec: - build: - secrets: - - TLS_SERVER_KEY - environments: - - name: dev - build: - from: main - - name: qa - - name: prod - components: - - name: frontend - src: frontend - ports: - - name: http - port: 3001 - publicPort: http - environmentConfig: - - environment: dev - variables: - VITE_AI_CONNECTION_STRING: "" - VITE_BACKEND_URL: "https://backend-flotilla-dev.playground.radix.equinor.com" - VITE_BACKEND_API_SCOPE: "api://ea4c7b92-47b3-45fb-bd25-a8070f0c495c/user_impersonation" - VITE_FRONTEND_URL: "https://frontend-flotilla-dev.playground.radix.equinor.com" - VITE_FRONTEND_BASE_ROUTE: "" - VITE_AD_CLIENT_ID: "f5993820-b7e2-4791-886f-f9f5027dc7be" - VITE_AD_TENANT_ID: "3aa4a235-b6e2-48d5-9195-7fcf05b459b0" - VITE_SARA_URL: "http://sara.robotics-analytics-dev.svc.cluster.local:8100" - VITE_SARA_API_SCOPE: "api://dd7e115a-037e-4846-99c4-07561158a9cd/user_impersonation" - - - name: backend - src: backend - ports: - - name: http - port: 8000 - publicPort: http - environmentConfig: - - environment: dev - variables: - Mqtt__Host: "broker" - ASPNETCORE_ENVIRONMENT: "Development" - secrets: - - AZURE_CLIENT_SECRET - - - name: broker - src: broker - ports: - - name: mqtt - port: 1883 - publicPort: mqtt diff --git a/setup.sh b/setup.sh index d387ede2f..a538a7774 100755 --- a/setup.sh +++ b/setup.sh @@ -46,10 +46,10 @@ fi if [ "$backend_abort" != "true" ]; then - echo "Local__DevUserId=$local_dev_username" >> $flotilla_dir/backend/api/.env - echo -e "Added local development username to .env file" + cp $flotilla_dir/backend/api/.env.example $flotilla_dir/backend/api/.env + echo -e "Created backend/api/.env file from backend/api/.env.example" - echo -e "Backup setup - Done!" + echo -e "Backend setup - Done!" echo -e "-----------------------------\n" fi @@ -65,7 +65,7 @@ if [ -f $flotilla_dir/broker/.env ]; then read reply if [ "$reply" = "n" ] || [ "$reply" = "N" ]; then - echo -e "\Broker setup - Aborted!\n" + echo -e "\nBroker setup - Aborted!\n" broker_abort="true" fi fi @@ -86,10 +86,9 @@ if [ "$broker_abort" != "true" ]; then done - echo "TLS_SERVER_KEY='$broker_server_key'" >> $flotilla_dir/broker/.env - echo -e "Added broker server key to .env file" + echo "TLS_SERVER_KEY='$broker_server_key'" > $flotilla_dir/broker/.env + echo -e "Created broker/.env file with the broker server key" - echo -e "Added broker server key to .env file" echo -e "Broker setup - Done!" echo -e "-----------------------------\n" #-----------------------------