diff --git a/Docker/Dockerfile.api b/Docker/Dockerfile.api new file mode 100644 index 0000000..36b667d --- /dev/null +++ b/Docker/Dockerfile.api @@ -0,0 +1,39 @@ +# MyOffice API (Kestrel :8080) — build from repo root: +# docker build -f Docker/Dockerfile.api -t myoffice-api . +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +WORKDIR /src + +COPY MyOffice.sln ./ +COPY MyOffice.Core/MyOffice.Core.csproj MyOffice.Core/ +COPY MyOffice.Shared/MyOffice.Shared.csproj MyOffice.Shared/ +COPY MyOffice.Data.Models/MyOffice.Data.Models.csproj MyOffice.Data.Models/ +COPY MyOffice.DbContext/MyOffice.DbContext.csproj MyOffice.DbContext/ +COPY MyOffice.Data.Repositories/MyOffice.Data.Repositories.csproj MyOffice.Data.Repositories/ +COPY MyOffice.Services/MyOffice.Services.csproj MyOffice.Services/ +COPY MyOffice.Migration.Sqlite/MyOffice.Migrations.Sqlite.csproj MyOffice.Migration.Sqlite/ +COPY MyOffice.Migration.Postgres/MyOffice.Migrations.Postgres.csproj MyOffice.Migration.Postgres/ +COPY MyOffice.Web/MyOffice.Web.csproj MyOffice.Web/ + +RUN dotnet restore MyOffice.Web/MyOffice.Web.csproj + +COPY MyOffice.Core/ MyOffice.Core/ +COPY MyOffice.Shared/ MyOffice.Shared/ +COPY MyOffice.Data.Models/ MyOffice.Data.Models/ +COPY MyOffice.DbContext/ MyOffice.DbContext/ +COPY MyOffice.Data.Repositories/ MyOffice.Data.Repositories/ +COPY MyOffice.Services/ MyOffice.Services/ +COPY MyOffice.Migration.Sqlite/ MyOffice.Migration.Sqlite/ +COPY MyOffice.Migration.Postgres/ MyOffice.Migration.Postgres/ +COPY MyOffice.Web/ MyOffice.Web/ + +RUN dotnet publish MyOffice.Web/MyOffice.Web.csproj -c Release -o /app/publish --no-restore + +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final +WORKDIR /app +COPY --from=build /app/publish . + +ENV ASPNETCORE_ENVIRONMENT=Docker +ENV ASPNETCORE_URLS=http://+:8080 +EXPOSE 8080 + +ENTRYPOINT ["dotnet", "MyOffice.Web.dll"] diff --git a/Docker/Dockerfile.web b/Docker/Dockerfile.web new file mode 100644 index 0000000..01c4231 --- /dev/null +++ b/Docker/Dockerfile.web @@ -0,0 +1,34 @@ +# MyOffice SPA (nginx :80) — build from repo root: +# docker build -f Docker/Dockerfile.web --build-arg API_PUBLIC_URL=http://localhost:32081 -t myoffice-web . +FROM node:20-alpine AS build +WORKDIR /src + +ARG API_PUBLIC_URL=http://localhost:32081 + +COPY MyOffice.SPA/package.json MyOffice.SPA/package-lock.json MyOffice.SPA/.npmrc ./ +RUN npm ci + +COPY MyOffice.SPA/ ./ + +# environment.ts is gitignored locally — stub + docker env with public API URL (host port). +RUN cp src/environments/environment.sample.ts src/environments/environment.ts \ + && printf '%s\n' \ + 'export const environment = {' \ + ' production: true,' \ + " apiUrl: '${API_PUBLIC_URL}'," \ + " identityServer: '${API_PUBLIC_URL}/'," \ + " allowedUrls: ['${API_PUBLIC_URL}']," \ + ' requireHttps: false,' \ + ' externalLogins: {' \ + " google: { clientId: '' }," \ + " auth0: { clientId: '', domain: '' }" \ + ' }' \ + '};' \ + > src/environments/environment.docker.ts \ + && npm run build -- --configuration docker --output-path /out \ + && if [ -d /out/browser ]; then cp -a /out/browser/. /out/ && rm -rf /out/browser; fi + +FROM nginx:1.27-alpine AS final +COPY Docker/nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /out /usr/share/nginx/html +EXPOSE 80 diff --git a/Docker/README.md b/Docker/README.md new file mode 100644 index 0000000..194e667 --- /dev/null +++ b/Docker/README.md @@ -0,0 +1,57 @@ +# MyOffice Docker demo + +| Service | Default host port | Notes | +|------------|-------------------|--------------------------------| +| `web` | **32080** | Angular SPA (nginx) | +| `api` | **32081** | ASP.NET Core + OpenIddict | +| `pgadmin` | **32082** | pgAdmin 4 | +| `postgres` | *(none)* | Internal only (`postgres:5432`) | + +Empty Postgres is migrated and filled with demo users on API startup. + +## Commands + +```powershell +.\build.ps1 # defaults :32080 / :32081 / :32082 +.\build.ps1 32080 32081 32082 # override front, back, pgAdmin +.\build.ps1 up # build + recreate containers +.\build.ps1 rebuild # --no-cache images + recreate (picks up API/CORS code) +.\build.ps1 reset # wipe DB volumes + rebuild (new seed / password user_UAH) +.\build.ps1 down +.\build.ps1 logs +``` + +Linux/macOS: `./build.sh` (same commands) + +**Important:** demo users are seeded only into an empty DB. Changing password in code does nothing until you run `.\build.ps1 reset` (clears `data/demo/postgres`). + +Custom ports rebuild the SPA so `apiUrl` / OIDC point at the chosen backend host port, and set `FrontEnd:Host` + CORS for the frontend origin. + +## URLs & logins + +Defaults (`.\build.ps1`): + +| App | URL | Login | +|-----|-----|--------| +| Frontend | http://localhost:32080 | `user_UAH@user_UAH.userUAH` / `user_UAH` | +| Backend | http://localhost:32081 | — | +| pgAdmin | http://localhost:32082 | `admin@example.com` / `admin` | + +Postgres is auto-registered in pgAdmin as server **myoffice** (host `postgres`, user/db/password `myoffice`) — no manual setup. +If the server is missing after an older run: `.\build.ps1 reset` (or delete `data/demo/pgadmin`). + +## Data folders + +Bind mounts next to the compose file (gitignored under `Docker/data/`): + +| Host path | Container | +|-----------|-----------| +| `Docker/data/demo/postgres` | `/var/lib/postgresql/data` | +| `Docker/data/demo/pgadmin` | `/var/lib/pgadmin` | + +Stop/start keeps these folders. Wipe with `.\build.ps1 reset` or delete the folders manually. + +## Notes + +- API uses `ASPNETCORE_ENVIRONMENT=Docker`, ephemeral OpenIddict keys, HTTP allowed. +- Changing front/back ports rebuilds the SPA so API/OIDC URLs match. diff --git a/Docker/build.ps1 b/Docker/build.ps1 new file mode 100644 index 0000000..f7103c6 --- /dev/null +++ b/Docker/build.ps1 @@ -0,0 +1,158 @@ +# Build and start the MyOffice demo stack (SPA + API + Postgres + pgAdmin). +# Usage: +# .\build.ps1 # front 32080, back 32081, pgAdmin 32082 +# .\build.ps1 32080 32081 32082 # override ports +# .\build.ps1 build | up | down | logs +# .\build.ps1 rebuild # --no-cache images + recreate containers +# .\build.ps1 reset # wipe ./data/demo/*, rebuild, start (new demo passwords) + +$ErrorActionPreference = 'Stop' +$here = Split-Path -Parent $MyInvocation.MyCommand.Path +Set-Location $here + +$composeFile = 'docker-compose.demo.yml' +$knownActions = @('build', 'up', 'down', 'logs', 'all', 'rebuild', 'reset') + +function Test-Port([string]$value) { + return $value -match '^\d{1,5}$' -and [int]$value -ge 1 -and [int]$value -le 65535 +} + +function Format-Origin([string]$port) { + if ($port -eq '80') { return 'http://localhost' } + return "http://localhost:$port" +} + +function Show-UpInfo { + param([string]$FrontOrigin, [string]$ApiPublicUrl, [string]$PgAdminUrl) + Write-Host '' + Write-Host 'Demo is up:' + Write-Host " Frontend $FrontOrigin" + Write-Host " Backend $ApiPublicUrl" + Write-Host " pgAdmin $PgAdminUrl (admin@example.com / admin; DB auto-connected)" + Write-Host ' Postgres internal host=postgres user/pass/db=myoffice' + Write-Host '' + Write-Host 'Demo logins: user_UAH@user_UAH.userUAH / user_UAH (also USD, EUR)' +} + +function Invoke-DockerCompose { + param([Parameter(ValueFromRemainingArguments = $true)][string[]]$ComposeArgs) + # Docker writes progress to stderr; with ErrorAction Stop that aborts the script. + $prev = $ErrorActionPreference + $ErrorActionPreference = 'Continue' + try { + & docker compose -f $composeFile @ComposeArgs + if ($LASTEXITCODE -ne 0) { + throw "docker compose failed with exit code $LASTEXITCODE" + } + } + finally { + $ErrorActionPreference = $prev + } +} + +# Parse: [action] [frontPort] [backPort] [pgAdminPort] +# Numeric args arrive as Int32 — always normalize to string first. +$action = 'all' +$frontPort = '32080' +$backPort = '32081' +$pgAdminPort = '32082' +$rest = @($args | ForEach-Object { "$_" }) + +if ($rest.Count -gt 0 -and $knownActions -contains $rest[0].ToLowerInvariant()) { + $action = $rest[0].ToLowerInvariant() + $rest = @($rest | Select-Object -Skip 1) +} +elseif ($rest.Count -gt 0 -and (Test-Port $rest[0])) { + $action = 'all' +} + +if ($rest.Count -ge 1) { + if (-not (Test-Port $rest[0])) { + Write-Error "Invalid front port '$($rest[0])'. Example: .\build.ps1 32080 32081 32082" + } + $frontPort = [string]$rest[0] +} +if ($rest.Count -ge 2) { + if (-not (Test-Port $rest[1])) { + Write-Error "Invalid back port '$($rest[1])'. Example: .\build.ps1 32080 32081 32082" + } + $backPort = [string]$rest[1] +} +if ($rest.Count -ge 3) { + if (-not (Test-Port $rest[2])) { + Write-Error "Invalid pgAdmin port '$($rest[2])'. Example: .\build.ps1 32080 32081 32082" + } + $pgAdminPort = [string]$rest[2] +} +if ($rest.Count -gt 3 -and $action -ne 'down' -and $action -ne 'logs') { + Write-Error 'Too many arguments. Usage: .\build.ps1 [build|up|down|logs|rebuild|reset] [frontPort] [backPort] [pgAdminPort]' +} + +$frontOrigin = Format-Origin $frontPort +$apiPublicUrl = "http://localhost:$backPort" +$pgAdminUrl = Format-Origin $pgAdminPort + +$env:MYOFFICE_WEB_PORT = $frontPort +$env:MYOFFICE_API_PORT = $backPort +$env:MYOFFICE_PGADMIN_PORT = $pgAdminPort +$env:MYOFFICE_FRONTEND_HOST = $frontOrigin +$env:MYOFFICE_API_PUBLIC_URL = $apiPublicUrl +$env:MYOFFICE_CORS_0 = $frontOrigin +$env:MYOFFICE_CORS_1 = if ($frontPort -eq '80') { 'http://127.0.0.1' } else { "http://127.0.0.1:$frontPort" } + +# Avoid stale compose env / cached layers leaving old API code running. +$env:COMPOSE_DOCKER_CLI_BUILD = '1' +$env:DOCKER_BUILDKIT = '1' + +switch ($action) { + 'build' { + Invoke-DockerCompose build + } + 'up' { + New-Item -ItemType Directory -Path (Join-Path $here 'data\demo\postgres') -Force | Out-Null + New-Item -ItemType Directory -Path (Join-Path $here 'data\demo\pgadmin') -Force | Out-Null + Invoke-DockerCompose up -d --build --force-recreate --remove-orphans + Show-UpInfo $frontOrigin $apiPublicUrl $pgAdminUrl + } + 'down' { + Invoke-DockerCompose down + } + 'logs' { + Invoke-DockerCompose logs -f + } + 'rebuild' { + Write-Host 'Rebuilding images with --no-cache (api + web)...' + Invoke-DockerCompose build --no-cache --pull + Invoke-DockerCompose up -d --force-recreate --remove-orphans + Show-UpInfo $frontOrigin $apiPublicUrl $pgAdminUrl + } + 'reset' { + Write-Host 'Stopping stack and wiping ./data/demo/postgres and ./data/demo/pgadmin...' + Invoke-DockerCompose down + foreach ($dir in @('data\demo\postgres', 'data\demo\pgadmin')) { + $path = Join-Path $here $dir + if (Test-Path $path) { + Remove-Item -LiteralPath $path -Recurse -Force + } + New-Item -ItemType Directory -Path $path -Force | Out-Null + } + # Drop old named volumes if they still exist from earlier setups. + docker volume rm myoffice-demo_myoffice_pgdata myoffice-demo_myoffice_pgadmin 2>$null | Out-Null + Write-Host 'Rebuilding images with --no-cache...' + Invoke-DockerCompose build --no-cache --pull + Invoke-DockerCompose up -d --force-recreate --remove-orphans + Show-UpInfo $frontOrigin $apiPublicUrl $pgAdminUrl + Write-Host '' + Write-Host 'DB was reset. Login with password user_UAH (not user1_UAH).' + Write-Host 'Data folders: Docker\data\demo\postgres , Docker\data\demo\pgadmin' + } + 'all' { + New-Item -ItemType Directory -Path (Join-Path $here 'data\demo\postgres') -Force | Out-Null + New-Item -ItemType Directory -Path (Join-Path $here 'data\demo\pgadmin') -Force | Out-Null + Invoke-DockerCompose up -d --build --force-recreate --remove-orphans + Show-UpInfo $frontOrigin $apiPublicUrl $pgAdminUrl + } + default { + Write-Error "Unknown action '$action'. Use: build, up, down, logs, rebuild, reset, or no args." + } +} diff --git a/Docker/build.sh b/Docker/build.sh new file mode 100644 index 0000000..5d5ed25 --- /dev/null +++ b/Docker/build.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env sh +# Build and start the MyOffice demo stack (SPA + API + Postgres + pgAdmin). +# Usage: +# ./build.sh # front 32080, back 32081, pgAdmin 32082 +# ./build.sh 32080 32081 32082 # override ports +# ./build.sh build | up | down | logs +# ./build.sh rebuild # --no-cache images + recreate containers +# ./build.sh reset # wipe DB volumes, rebuild, start + +set -eu +cd "$(dirname "$0")" + +COMPOSE_FILE=docker-compose.demo.yml +ACTION=all +FRONT_PORT=32080 +BACK_PORT=32081 +PGADMIN_PORT=32082 + +is_port() { + echo "$1" | grep -Eq '^[0-9]{1,5}$' && [ "$1" -ge 1 ] && [ "$1" -le 65535 ] +} + +origin_for() { + if [ "$1" = "80" ]; then + echo "http://localhost" + else + echo "http://localhost:$1" + fi +} + +show_up_info() { + echo "" + echo "Demo is up:" + echo " Frontend $1" + echo " Backend $2" + echo " pgAdmin $3 (admin@example.com / admin; DB auto-connected)" + echo " Postgres internal host=postgres user/pass/db=myoffice" + echo "" + echo "Demo logins: user_UAH@user_UAH.userUAH / user_UAH (also USD, EUR)" +} + +if [ "${1:-}" = "build" ] || [ "${1:-}" = "up" ] || [ "${1:-}" = "down" ] || [ "${1:-}" = "logs" ] || [ "${1:-}" = "all" ] || [ "${1:-}" = "rebuild" ] || [ "${1:-}" = "reset" ]; then + ACTION=$1 + shift +fi + +if [ "${1:-}" != "" ]; then + is_port "$1" || { echo "Invalid front port '$1'. Example: ./build.sh 32080 32081 32082" >&2; exit 1; } + FRONT_PORT=$1 + shift +fi + +if [ "${1:-}" != "" ]; then + is_port "$1" || { echo "Invalid back port '$1'. Example: ./build.sh 32080 32081 32082" >&2; exit 1; } + BACK_PORT=$1 + shift +fi + +if [ "${1:-}" != "" ]; then + is_port "$1" || { echo "Invalid pgAdmin port '$1'. Example: ./build.sh 32080 32081 32082" >&2; exit 1; } + PGADMIN_PORT=$1 + shift +fi + +if [ "${1:-}" != "" ] && [ "$ACTION" != "down" ] && [ "$ACTION" != "logs" ]; then + echo "Too many arguments. Usage: ./build.sh [build|up|down|logs|rebuild|reset] [frontPort] [backPort] [pgAdminPort]" >&2 + exit 1 +fi + +FRONT_ORIGIN=$(origin_for "$FRONT_PORT") +API_PUBLIC_URL="http://localhost:$BACK_PORT" +PGADMIN_URL=$(origin_for "$PGADMIN_PORT") + +export MYOFFICE_WEB_PORT=$FRONT_PORT +export MYOFFICE_API_PORT=$BACK_PORT +export MYOFFICE_PGADMIN_PORT=$PGADMIN_PORT +export MYOFFICE_FRONTEND_HOST=$FRONT_ORIGIN +export MYOFFICE_API_PUBLIC_URL=$API_PUBLIC_URL +export MYOFFICE_CORS_0=$FRONT_ORIGIN +if [ "$FRONT_PORT" = "80" ]; then + export MYOFFICE_CORS_1=http://127.0.0.1 +else + export MYOFFICE_CORS_1="http://127.0.0.1:$FRONT_PORT" +fi + +export COMPOSE_DOCKER_CLI_BUILD=1 +export DOCKER_BUILDKIT=1 + +case "$ACTION" in + build) + docker compose -f "$COMPOSE_FILE" build + ;; + up) + mkdir -p data/demo/postgres data/demo/pgadmin + docker compose -f "$COMPOSE_FILE" up -d --build --force-recreate --remove-orphans + show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" + ;; + down) + docker compose -f "$COMPOSE_FILE" down + ;; + logs) + docker compose -f "$COMPOSE_FILE" logs -f + ;; + rebuild) + echo "Rebuilding images with --no-cache (api + web)..." + docker compose -f "$COMPOSE_FILE" build --no-cache --pull + docker compose -f "$COMPOSE_FILE" up -d --force-recreate --remove-orphans + show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" + ;; + reset) + echo "Stopping stack and wiping ./data/demo/postgres and ./data/demo/pgadmin..." + docker compose -f "$COMPOSE_FILE" down + rm -rf data/demo/postgres data/demo/pgadmin + mkdir -p data/demo/postgres data/demo/pgadmin + docker volume rm myoffice-demo_myoffice_pgdata myoffice-demo_myoffice_pgadmin 2>/dev/null || true + echo "Rebuilding images with --no-cache..." + docker compose -f "$COMPOSE_FILE" build --no-cache --pull + docker compose -f "$COMPOSE_FILE" up -d --force-recreate --remove-orphans + show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" + echo "" + echo "DB was reset. Login with password user_UAH (not user1_UAH)." + echo "Data folders: Docker/data/demo/postgres , Docker/data/demo/pgadmin" + ;; + all) + mkdir -p data/demo/postgres data/demo/pgadmin + docker compose -f "$COMPOSE_FILE" up -d --build --force-recreate --remove-orphans + show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" + ;; + *) + echo "Unknown action '$ACTION'. Use: build, up, down, logs, rebuild, reset, or no args." >&2 + exit 1 + ;; +esac diff --git a/Docker/dc-postgres-pgadmin.yml b/Docker/dc-postgres-pgadmin.yml new file mode 100644 index 0000000..e841c27 --- /dev/null +++ b/Docker/dc-postgres-pgadmin.yml @@ -0,0 +1,27 @@ +services: + postgres: + image: postgres:17 + container_name: postgres + restart: unless-stopped + environment: + POSTGRES_DB: appdb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - "5432:5432" + volumes: + - ./data/postgres:/var/lib/postgresql/data + + pgadmin: + image: dpage/pgadmin4:latest + container_name: pgadmin + restart: unless-stopped + environment: + PGADMIN_DEFAULT_EMAIL: admin@example.com + PGADMIN_DEFAULT_PASSWORD: admin + ports: + - "5433:80" + volumes: + - ./data/pgadmin:/var/lib/pgadmin + depends_on: + - postgres diff --git a/Docker/docker-compose.demo.yml b/Docker/docker-compose.demo.yml new file mode 100644 index 0000000..615990b --- /dev/null +++ b/Docker/docker-compose.demo.yml @@ -0,0 +1,96 @@ +# Demo stack: SPA + API + Postgres (internal) + pgAdmin. +# Ports from env / build.ps1: +# MYOFFICE_WEB_PORT (32080), MYOFFICE_API_PORT (32081), MYOFFICE_PGADMIN_PORT (32082) +name: myoffice-demo + +services: + postgres: + image: postgres:17 + container_name: myoffice-postgres + restart: unless-stopped + environment: + POSTGRES_DB: myoffice + POSTGRES_USER: myoffice + POSTGRES_PASSWORD: myoffice + volumes: + # Host path (next to this compose file): ./data/demo/postgres + - ./data/demo/postgres:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U myoffice -d myoffice"] + interval: 5s + timeout: 5s + retries: 12 + networks: + - myoffice + + pgadmin: + image: dpage/pgadmin4:9 + container_name: myoffice-pgadmin + restart: unless-stopped + # Strip CRLF (Windows checkouts) then create pgpass (0600) and run image entrypoint. + entrypoint: + - /bin/sh + - -c + - sed 's/\r$//' /pgadmin-entrypoint.sh > /tmp/pgadmin-entrypoint.sh && exec /bin/sh /tmp/pgadmin-entrypoint.sh + environment: + PGADMIN_DEFAULT_EMAIL: admin@example.com + PGADMIN_DEFAULT_PASSWORD: admin + PGADMIN_CONFIG_SERVER_MODE: "False" + PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False" + ports: + - "${MYOFFICE_PGADMIN_PORT:-32082}:80" + volumes: + # Host path: ./data/demo/pgadmin + - ./data/demo/pgadmin:/var/lib/pgadmin + - ./pgadmin/servers.json:/pgadmin4/servers.json:ro + - ./pgadmin/entrypoint.sh:/pgadmin-entrypoint.sh:ro + depends_on: + postgres: + condition: service_healthy + networks: + - myoffice + + api: + build: + context: .. + dockerfile: Docker/Dockerfile.api + image: myoffice-api:demo + container_name: myoffice-api + restart: unless-stopped + ports: + - "${MYOFFICE_API_PORT:-32081}:8080" + environment: + ASPNETCORE_ENVIRONMENT: Docker + ASPNETCORE_URLS: http://+:8080 + DatabaseProvider: npgsql + ConnectionStrings__npgsql: Host=postgres;Port=5432;Database=myoffice;Username=myoffice;Password=myoffice + FrontEnd__Host: ${MYOFFICE_FRONTEND_HOST:-http://localhost:32080} + Cors__AllowedOrigins__0: ${MYOFFICE_CORS_0:-http://localhost:32080} + Cors__AllowedOrigins__1: ${MYOFFICE_CORS_1:-http://127.0.0.1:32080} + OpenIddict__UseEphemeralKeys: "true" + OpenIddict__AllowHttp: "true" + depends_on: + postgres: + condition: service_healthy + networks: + - myoffice + + web: + build: + context: .. + dockerfile: Docker/Dockerfile.web + args: + API_PUBLIC_URL: ${MYOFFICE_API_PUBLIC_URL:-http://localhost:32081} + image: myoffice-web:demo + container_name: myoffice-web + restart: unless-stopped + ports: + - "${MYOFFICE_WEB_PORT:-32080}:80" + depends_on: + - api + networks: + - myoffice + +networks: + myoffice: + driver: bridge diff --git a/Docker/nginx.conf b/Docker/nginx.conf new file mode 100644 index 0000000..7f03e5f --- /dev/null +++ b/Docker/nginx.conf @@ -0,0 +1,17 @@ +server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + + gzip on; + gzip_types text/plain text/css application/javascript application/json image/svg+xml; + + location / { + try_files $uri $uri/ /index.html; + } + + location = /index.html { + add_header Cache-Control "no-cache"; + } +} diff --git a/Docker/pgadmin/entrypoint.sh b/Docker/pgadmin/entrypoint.sh new file mode 100644 index 0000000..74df87e --- /dev/null +++ b/Docker/pgadmin/entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Create pgpass inside the container (mode 0600). Bind-mounted files from Windows +# cannot satisfy pgAdmin's permission check. +set -eu + +PASSFILE=/var/lib/pgadmin/pgpass +printf '%s\n' 'postgres:5432:*:myoffice:myoffice' > "$PASSFILE" +chown 5050:0 "$PASSFILE" 2>/dev/null || true +chmod 600 "$PASSFILE" + +exec /entrypoint.sh "$@" diff --git a/Docker/pgadmin/servers.json b/Docker/pgadmin/servers.json new file mode 100644 index 0000000..6107165 --- /dev/null +++ b/Docker/pgadmin/servers.json @@ -0,0 +1,14 @@ +{ + "Servers": { + "1": { + "Name": "myoffice", + "Group": "Servers", + "Host": "postgres", + "Port": 5432, + "MaintenanceDB": "myoffice", + "Username": "myoffice", + "SSLMode": "prefer", + "PassFile": "/var/lib/pgadmin/pgpass" + } + } +} diff --git a/MyOffice.Core/Error.cs b/MyOffice.Core/Error.cs deleted file mode 100644 index 48cf996..0000000 --- a/MyOffice.Core/Error.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace MyOffice.Core; - -public class Error -{ - private Exception? _exception; - - public Error(string message) - { - Message = message; - } - - public Error(Exception exception): this(exception.GetType().Name) - { - _exception = exception; - } - - public Error(string message, Exception exception): this(message) - { - _exception = exception; - } - - public string Message { get; private set;} -} \ No newline at end of file diff --git a/MyOffice.Core/Exec.cs b/MyOffice.Core/Exec.cs deleted file mode 100644 index 3f929c3..0000000 --- a/MyOffice.Core/Exec.cs +++ /dev/null @@ -1,106 +0,0 @@ -namespace MyOffice.Core; - -public enum GeneralExecStatus -{ - success, - failure, - not_found, - forbidden -} - -public class Exec : Exec - where TResult : class -{ - public Exec(TResult result, GeneralExecStatus status) : base(result, status) - { - } - - public Exec(GeneralExecStatus status) : base(status) - { - } - - public Exec() : base(GeneralExecStatus.success) - { - } - - public new Exec Set(GeneralExecStatus status) - { - Status = status; - - return this; - } - - public new Exec Set(TResult? result) - { - Result = result; - Status = result == null ? GeneralExecStatus.failure : GeneralExecStatus.success; - - return this; - } -} - -public class Exec - where TResult : class - where TStatus : Enum -{ - public static Exec Start(TResult result, TStatus status) - { - return new Exec(result, status); - } - - public static Exec Start(TStatus status) - { - return new Exec(status); - } - - public static Exec StartSuccess() - { - return new Exec(GeneralExecStatus.success); - } - - public static Exec StartFailure() - { - return new Exec(GeneralExecStatus.failure); - } - - public static Exec StartNotFound() - { - return new Exec(GeneralExecStatus.not_found); - } - - public Exec(TResult result, TStatus status) - { - Result = result; - Status = status; - } - - public Exec(TStatus status) - { - Status = status; - } - - public TResult? Result { get; internal set; } - public TStatus Status { get; internal set; } - - public Exec Set(TResult result, TStatus status) - { - Result = result; - Status = status; - - return this; - } - - public Exec Set(TStatus status) - { - Status = status; - - return this; - } - - public Exec Set(TResult result) - { - Result = result; - - return this; - } -} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/BoolExtensions.cs b/MyOffice.Core/Extensions/BoolExtensions.cs deleted file mode 100644 index 8639085..0000000 --- a/MyOffice.Core/Extensions/BoolExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace MyOffice.Core.Extensions; - -public static class BoolExtensions -{ - public static string ToLowerCase(this bool value) - { - return value.ToString().ToLower(); - } - - public static string? ToLowerCase(this bool? value) - { - return value == null ? null : value.ToString()?.ToLower(); - } -} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/ClaimsExtensions.cs b/MyOffice.Core/Extensions/ClaimsExtensions.cs deleted file mode 100644 index af77327..0000000 --- a/MyOffice.Core/Extensions/ClaimsExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace MyOffice.Core.Extensions; - -using System.Security.Claims; - -public static class ClaimsExtensions -{ - public static string? GetValue(this IEnumerable claims, string type) - { - return claims.FirstOrDefault(x => x.Type.Equals(type, StringComparison.OrdinalIgnoreCase))?.Value; - } - - public static string? GetValue(this IEnumerable claims, string[] types) - { - return claims.FirstOrDefault(x => types.Any(z => x.Type.Equals(z, StringComparison.OrdinalIgnoreCase)))?.Value; - } - - public static string? GetEmail(this IEnumerable claims) - { - return GetValue(claims, new[] { ClaimTypes.Email, "email" }); - } - - public static string? GetNameIdentifier(this IEnumerable claims) - { - return GetValue(claims, ClaimTypes.NameIdentifier); - } - - public static string? GetSID(this IEnumerable claims) - { - return GetValue(claims, "sid"); - } -} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/DateTimeExtensions.cs b/MyOffice.Core/Extensions/DateTimeExtensions.cs deleted file mode 100644 index 8b22231..0000000 --- a/MyOffice.Core/Extensions/DateTimeExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MyOffice.Core.Extensions; - -public static class DateTimeExtensions -{ - public static DateTime StartOfDay(this DateTime dateTime) - { - return dateTime.Date; - } - - public static DateTime EndOfDay(this DateTime dateTime) - { - return dateTime.AddDays(1).AddTicks(-1); - } - - public static DateTime ToUtc(this DateTime dateTime) - { - return new DateTime(dateTime.Ticks, DateTimeKind.Utc); - } -} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/GuidExtensions.cs b/MyOffice.Core/Extensions/GuidExtensions.cs deleted file mode 100644 index 6a95e4a..0000000 --- a/MyOffice.Core/Extensions/GuidExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MyOffice.Core.Extensions; - -public static class GuidExtensions -{ - public static bool EqualsString(this Guid guid, string str) - { - return guid.ToString().EqualsIgnoreCase(str); - } - - public static string ToShort(this Guid guid) - { - return guid.ToString("N"); - } - - public static string? ToShort(this Guid? guid) - { - return guid?.ToString("N"); - } -} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/StringExtensions.cs b/MyOffice.Core/Extensions/StringExtensions.cs deleted file mode 100644 index eca1473..0000000 --- a/MyOffice.Core/Extensions/StringExtensions.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace MyOffice.Core.Extensions; - -using Microsoft.Extensions.Logging; - -public static class StringExtensions -{ - public static bool IsMissing(this string? str) - { - return str == null || string.IsNullOrEmpty(str) || string.IsNullOrEmpty(str.Trim()); - } - - public static bool IsPresent(this string? str) - { - return !IsMissing(str); - } - - public static string? NullIfEmpty(this string? str) - { - return IsMissing(str) ? null : str; - } - - public static bool EqualsIgnoreCase(this string? str, string? value) - { - return str != null && str.Equals(value, StringComparison.OrdinalIgnoreCase); - } - - public static string? SafeTrim(this string? str) - { - return str == null ? str : str!.Trim(); - } - - public static string? MaxOf(this string? str, int maxLength) - { - if (str == null) - { - return null; - } - - if (str.Length < maxLength) - { - return str; - } - - return str.Substring(0, maxLength); - } - - public static bool AsBool(this string? str, bool defaultValue = false) - { - return true.ToString().Equals(str, StringComparison.OrdinalIgnoreCase) || defaultValue; - } - - public static Guid AsGuid(this string str) - { - return Guid.Parse(str); - } - - public static Guid? AsGuidNull(this string? str) - { - if (Guid.TryParse(str, out var guid)) - { - return guid; - } - return null; - } -} \ No newline at end of file diff --git a/MyOffice.Core/Helpers/JsonHelper.cs b/MyOffice.Core/Helpers/JsonHelper.cs deleted file mode 100644 index 100f7bc..0000000 --- a/MyOffice.Core/Helpers/JsonHelper.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace MyOffice.Core.Helpers -{ - using System.Text.Json; - using System.Text.Json.Serialization; - - public static class JsonHelper - { - public static string ToJson(this object entity, JsonSerializerOptions? options = null) - { - options ??= new JsonSerializerOptions - { - MaxDepth = 0, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - ReferenceHandler = ReferenceHandler.IgnoreCycles, - WriteIndented = true, - }; - return JsonSerializer.Serialize(entity, options); - } - } - - /*public class CustomIgnoreReferenceHandler : ReferenceHandler - { - //public CustomIgnoreReferenceHandler() => HandlingStrategy = ReferenceHandlingStrategy.IgnoreCycles; - public CustomIgnoreReferenceHandler() - { - new HandlingStrategy { } = true; - } - - public override ReferenceResolver CreateResolver() => new IgnoreReferenceResolver(); - }*/ -} diff --git a/MyOffice.Core/Helpers/RandomizationHelper.cs b/MyOffice.Core/Helpers/RandomizationHelper.cs deleted file mode 100644 index f240a4f..0000000 --- a/MyOffice.Core/Helpers/RandomizationHelper.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace MyOffice.Core.Helpers; - -using MyOffice.Core.Extensions; - -public class RandomizationHelper -{ - public static string Generate(int length) - { - var result = ""; - - while(result.Length < length) - { - result += Guid.NewGuid().ToShort(); - } - - return result.Substring(0, length); - } -} diff --git a/MyOffice.Core/Identity/IExternalProviderValidator.cs b/MyOffice.Core/Identity/IExternalProviderValidator.cs deleted file mode 100644 index d74d303..0000000 --- a/MyOffice.Core/Identity/IExternalProviderValidator.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace MyOffice.Core.Identity; - -using System; -using System.Diagnostics.Contracts; - -public interface IExternalProviderValidator -{ - string Provider { get; } - public bool IsConfigured { get; } - - Task ValidateAsync(string token); -} - -public class ExternalProviderValidatorResult -{ - public static ExternalProviderValidatorResult Failed() - { - return new ExternalProviderValidatorResult(); - } - - public static ExternalProviderValidatorResult Success(string email, bool emailVerified, string externalId, - string? fullName) - { - return new ExternalProviderValidatorResult(email, emailVerified, externalId, fullName); - } - - public ExternalProviderValidatorResult() - { - IsSuccessed = false; - } - - public ExternalProviderValidatorResult(string email, bool emailVerified, string externalId, string? fullName) : - this() - { - Email = email; - EmailVerified = emailVerified; - IsSuccessed = true; - ExternalId = externalId; - FullName = fullName; - } - - public bool IsSuccessed { get; } - public string? Email { get; } - public bool EmailVerified { get; } - public string? ExternalId { get; } - public string? FullName { get; } -} \ No newline at end of file diff --git a/MyOffice.Core/Interfaces/IDataModel.cs b/MyOffice.Core/Interfaces/IDataModel.cs deleted file mode 100644 index 586eae7..0000000 --- a/MyOffice.Core/Interfaces/IDataModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyOffice.Core; - -public interface IDataModel -{ - -} diff --git a/MyOffice.Core/Interfaces/IDataModelDto.cs b/MyOffice.Core/Interfaces/IDataModelDto.cs deleted file mode 100644 index 073a84b..0000000 --- a/MyOffice.Core/Interfaces/IDataModelDto.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyOffice.Core; - -public interface IDataModelDto where TSource : IDataModel -{ - -} diff --git a/MyOffice.Core/MyOffice.Core.csproj b/MyOffice.Core/MyOffice.Core.csproj deleted file mode 100644 index 13dc371..0000000 --- a/MyOffice.Core/MyOffice.Core.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - - diff --git a/MyOffice.Data.Models/Accounts/Account.cs b/MyOffice.Data.Models/Accounts/Account.cs deleted file mode 100644 index 9048af0..0000000 --- a/MyOffice.Data.Models/Accounts/Account.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace MyOffice.Data.Models.Accounts; - -using Currencies; -using MyOffice.Core; -using MyOffice.Data.Models.Users; - -public class Account: IDataModel -{ - public Guid Id { get; set; } - public string CurrencyGlobalId { get; set; } = null!; - public CurrencyGlobal? CurrencyGlobal { get; set; } - public Guid? OwnerId { get; set; } - public User? Owner { get; set; } - public string Name { get; set; } = null!; - public IEnumerable? AccessRights { get; set; } - public IEnumerable? Motions { get; set; } - public IEnumerable? Categories { get; set; } - public IEnumerable? Invites { get; set; } -} - -public class AccountDetailed: IDataModel -{ - public Account Account { get; set; } = null!; - public decimal TotalPlus { get; set; } - public decimal TotalMinus { get; set; } - public decimal Rest => TotalPlus - TotalMinus; -} - -public class AccountSimple -{ - public Guid Id { get; set; } - public string Name { get; set; } = null!; - public AccountAccessTypeEnum Type { get; set; } - public string? CurrencyName { get; set; } - public string? CurrencyShortName { get; set; } - public decimal? CurrencyRate { get; set; } - public int? CurrencyQuantity { get; set; } - public decimal? TotalPlus { get; set; } - public decimal? TotalMinus { get; set; } - public decimal? Balance { get; set; } -} - -public class MotionTotalSimple -{ - public Guid? Id { get; set; } - public string Name { get; set; } = null!; - public string CurrencyId { get; set; } = null!; - public string CurrencyName { get; set; } = null!; - public decimal CurrencyRate { get; set; } - public decimal Amount { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Accounts/AccountAccess.cs b/MyOffice.Data.Models/Accounts/AccountAccess.cs deleted file mode 100644 index 0d1aeb3..0000000 --- a/MyOffice.Data.Models/Accounts/AccountAccess.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace MyOffice.Data.Models.Accounts; - -using MyOffice.Data.Models.Users; - -public enum AccountAccessTypeEnum -{ - balance, - credit, - external, - other, -} - -public class AccountAccess -{ - public int Id { get; set; } - public Guid AccountId { get; set; } - public Account? Account { get; set; } - public Guid UserId { get; set; } - public User? User { get; set; } - public Guid OwnerId { get; set; } - public User? Owner { get; set; } - - public bool IsAllowRead { get; set; } - public bool IsAllowWrite { get; set; } - public bool IsAllowManage { get; set; } - public AccountAccessTypeEnum Type { get; set; } - public string? Name { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Accounts/AccountAccessInvite.cs b/MyOffice.Data.Models/Accounts/AccountAccessInvite.cs deleted file mode 100644 index 0827695..0000000 --- a/MyOffice.Data.Models/Accounts/AccountAccessInvite.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Data.Models.Accounts; - -using Users; - -public class AccountAccessInvite -{ - public Guid Id { get; set; } - public Guid UserId { get; set; } - public User? User { get; set; } - public Guid AccountId { get; set; } - public Account? Account { get; set; } - public DateTime CreatedOn { get; set; } - public DateTime? AcceptedOn { get; set; } - public DateTime? RejectedOn { get; set; } - public string Email { get; set; } = null!; - public bool IsAllowWrite { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Accounts/AccountAccountCategory.cs b/MyOffice.Data.Models/Accounts/AccountAccountCategory.cs deleted file mode 100644 index 3ede78a..0000000 --- a/MyOffice.Data.Models/Accounts/AccountAccountCategory.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Data.Models.Accounts; - -public class AccountAccountCategory -{ - public int Id { get; set; } - public Guid AccountId { get; set; } - public Account Account { get; set; } = null!; - public Guid CategoryId { get; set; } - public AccountCategory Category { get; set; } = null!; -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Accounts/AccountCategory.cs b/MyOffice.Data.Models/Accounts/AccountCategory.cs deleted file mode 100644 index dc445b9..0000000 --- a/MyOffice.Data.Models/Accounts/AccountCategory.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MyOffice.Data.Models.Accounts; - -using MyOffice.Data.Models.Users; - -public class AccountCategory -{ - public Guid Id { get; set; } - public Guid UserId { get; set; } - public User? User { get; set; } - public string Name { get; set; } = null!; - public IEnumerable? Accounts { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Accounts/Domain/AccountWithRate.cs b/MyOffice.Data.Models/Accounts/Domain/AccountWithRate.cs deleted file mode 100644 index e5d2504..0000000 --- a/MyOffice.Data.Models/Accounts/Domain/AccountWithRate.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Data.Models.Accounts.Domain; - -using Currencies; - -public class AccountWithRate -{ - public Account Account { get; set; } = null!; - public Currency? Currency { get; set; } - public CurrencyRate? Rate { get; set; } -} diff --git a/MyOffice.Data.Models/Accounts/Motion.cs b/MyOffice.Data.Models/Accounts/Motion.cs deleted file mode 100644 index 1439e8d..0000000 --- a/MyOffice.Data.Models/Accounts/Motion.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace MyOffice.Data.Models.Accounts; - -using Items; - -/// -/// Account motion -/// DateTime: 2023-01-01, Account: 'Debit card', Item.ItemGlobal: 'Primary salary', AmountPlus: 5000 -/// -public class Motion -{ - public Guid Id { get; set; } - public DateTime CreatedOn { get; set; } - public DateTime DateTime { get; set; } - public Guid AccountId { get; set; } - public Account Account { get; set; } = null!; - public int ItemId { get; set; } - public Item Item { get; set; } = null!; - public string? Description { get; set; } - public decimal AmountPlus { get; set; } - public decimal AmountMinus { get; set; } - public DateTime? DeletedOn { get; set; } -} diff --git a/MyOffice.Data.Models/Currencies/Currency.cs b/MyOffice.Data.Models/Currencies/Currency.cs deleted file mode 100644 index c8cd254..0000000 --- a/MyOffice.Data.Models/Currencies/Currency.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace MyOffice.Data.Models.Currencies; - -using MyOffice.Data.Models.Users; - -public class Currency -{ - public Guid Id { get; set; } - public string CurrencyGlobalId { get; set; } = null!; - public CurrencyGlobal? CurrencyGlobal { get; set; } - public Guid UserId { get; set; } - public User? User { get; set; } - - public string Name { get; set; } = null!; - public string ShortName { get; set; } = null!; - public IEnumerable? Rates { get; set; } - - public int? CurrentRateId { get; set; } - public CurrencyRate? CurrentRate { get; set; } - - public bool IsPrimary { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Currencies/CurrencyGlobal.cs b/MyOffice.Data.Models/Currencies/CurrencyGlobal.cs deleted file mode 100644 index 78ea67e..0000000 --- a/MyOffice.Data.Models/Currencies/CurrencyGlobal.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace MyOffice.Data.Models.Currencies; - -using MyOffice.Data.Models.Accounts; - -public enum CurrencyGlobalIdEnum -{ - UAH, - USD, - EUR, - GBP, - RUB, - BTC, - ETH, - TON, - OTHER, -} - -public class CurrencyGlobal -{ - public string Id { get; set; } = null!; - public string Name { get; set; } = null!; - public string Symbol { get; set; } = null!; - public int DefaultQuantity { get; set; } - public IEnumerable? Currencies { get; set; } - public IEnumerable? Accounts { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Currencies/CurrencyRate.cs b/MyOffice.Data.Models/Currencies/CurrencyRate.cs deleted file mode 100644 index 8d20bbe..0000000 --- a/MyOffice.Data.Models/Currencies/CurrencyRate.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MyOffice.Data.Models.Currencies; - -public class CurrencyRate -{ - public int Id { get; set; } - public Guid CurrencyId { get; set; } - public Currency? Currency { get; set; } - public DateTime DateTime { get; set; } - public int Quantity { get; set; } - public decimal Rate { get; set; } - public IEnumerable? Currencies { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Items/Item.cs b/MyOffice.Data.Models/Items/Item.cs deleted file mode 100644 index 17cb931..0000000 --- a/MyOffice.Data.Models/Items/Item.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace MyOffice.Data.Models.Items; - -using MyOffice.Data.Models.Accounts; - -/// -/// User 'Item' linked to global item -/// ItemGlobal: 'Primary salary', ItemCategory: 'Incomes' -/// -public class Item -{ - public int Id { get; set; } - /// - /// UnCategorized category is CategoryId = UserId - /// - public Guid CategoryId { get; set; } - public ItemCategory? Category { get; set; } - public Guid ItemGlobalId { get; set; } - public ItemGlobal ItemGlobal { get; set; } = null!; - public List? Motions { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Items/ItemCategory.cs b/MyOffice.Data.Models/Items/ItemCategory.cs deleted file mode 100644 index f368199..0000000 --- a/MyOffice.Data.Models/Items/ItemCategory.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace MyOffice.Data.Models.Items; - -using MyOffice.Data.Models.Users; - -public class ItemCategory -{ - public Guid Id { get; set; } - public Guid UserId { get; set; } - public User User { get; set; } = null!; - public string Name { get; set; } = null!; - public List Items { get; set; } = null!; - public bool IsInternal { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Items/ItemGlobal.cs b/MyOffice.Data.Models/Items/ItemGlobal.cs deleted file mode 100644 index 420d19b..0000000 --- a/MyOffice.Data.Models/Items/ItemGlobal.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace MyOffice.Data.Models.Items; - -public class ItemGlobal -{ - public Guid Id { get; set; } - public string Name { get; set; } = null!; - public IEnumerable Items { get; set; } = null!; -} \ No newline at end of file diff --git a/MyOffice.Data.Models/MyOffice.Data.Models.csproj b/MyOffice.Data.Models/MyOffice.Data.Models.csproj deleted file mode 100644 index 34cd07d..0000000 --- a/MyOffice.Data.Models/MyOffice.Data.Models.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - - diff --git a/MyOffice.Data.Models/Notifications/EmailTemplate.cs b/MyOffice.Data.Models/Notifications/EmailTemplate.cs deleted file mode 100644 index 4b17ef2..0000000 --- a/MyOffice.Data.Models/Notifications/EmailTemplate.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Data.Models.Notifications; - -public enum EmailTemplateEnum -{ - PasswordRestore, -} - -public class EmailTemplate -{ - public string Id { get; set; } - public DateTime CreatedOn { get; set; } - public string Description { get; set; } - public string Subject { get; set; } - public string Sender { get; set; } - public string SenderName { get; set; } - public string Template { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Users/User.cs b/MyOffice.Data.Models/Users/User.cs deleted file mode 100644 index 2246452..0000000 --- a/MyOffice.Data.Models/Users/User.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace MyOffice.Data.Models.Users; - -using Accounts; -using Currencies; -using Items; - -public class User -{ - public User() - { - CurrencyId = "USD"; - } - - public Guid Id { get; set; } - public string UserName { get; set; } = null!; - public string Email { get; set; } = null!; - public string PasswordHash { get; set; } = null!; - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? FullName { get; set; } - public string? Phone { get; set; } - public bool IsEmailConfirmed { get; set; } - public IEnumerable? UserClaims { get; set; } - - public string CurrencyId { get; set; } - public CurrencyGlobal? Currency { get; set; } - public IEnumerable? Currencies { get; set; } - public IEnumerable? AccountAccess { get; set; } - public IEnumerable? AccountMotions { get; set; } - public IEnumerable? AccountCategories { get; set; } - public IEnumerable? ItemCategories { get; set; } - public IEnumerable? Accounts { get; set; } - public IEnumerable? AccountAccessOwners { get; set; } - public IEnumerable? AccountAccessInvites { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Users/UserExternal.cs b/MyOffice.Data.Models/Users/UserExternal.cs deleted file mode 100644 index b86f5df..0000000 --- a/MyOffice.Data.Models/Users/UserExternal.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MyOffice.Data.Models.Users; - -public class UserExternal -{ - public int Id { get; set; } - public DateTime CreatedOn { get; set; } - public Guid UserId { get; set; } - public User User { get; set; } = null!; - public string ExternalId { get; set; } = null!; - public string Email { get; set; } = null!; - public string Provider { get; set; } = null!; -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Verifications/VerificationCode.cs b/MyOffice.Data.Models/Verifications/VerificationCode.cs deleted file mode 100644 index 272f823..0000000 --- a/MyOffice.Data.Models/Verifications/VerificationCode.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace MyOffice.Data.Models.Verifications; - -using MyOffice.Data.Models.Users; - -public class VerificationCode -{ - public int Id { get; set; } - public Guid UserId { get; set; } - public User? User { get; set; } - public string Code { get; set; } = null!; - public string DestinationType { get; set; } = null!; - public string Destination { get; set; } = null!; - public DateTime CreatedOn { get; set; } - public DateTime ExpiresOn { get; set; } - public DateTime? VerifiedOn { get; set; } - public string Template { get; set; } = null!; - public string? Metadata { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Verifications/VerificationCodeTemplateEnum.cs b/MyOffice.Data.Models/Verifications/VerificationCodeTemplateEnum.cs deleted file mode 100644 index 96096a0..0000000 --- a/MyOffice.Data.Models/Verifications/VerificationCodeTemplateEnum.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MyOffice.Data.Models.Verifications; - -public enum VerificationCodeTemplateEnum -{ - password_restore, - email_confirm, -} diff --git a/MyOffice.Data.Models/Verifications/VerificationCodeTypeEnum.cs b/MyOffice.Data.Models/Verifications/VerificationCodeTypeEnum.cs deleted file mode 100644 index 642a403..0000000 --- a/MyOffice.Data.Models/Verifications/VerificationCodeTypeEnum.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MyOffice.Data.Models.Verifications; - -public enum VerificationCodeTypeEnum -{ - email, - phone, -} diff --git a/MyOffice.Data.Repositories/Account/AccountAccessInviteRepository.cs b/MyOffice.Data.Repositories/Account/AccountAccessInviteRepository.cs deleted file mode 100644 index 967d7cd..0000000 --- a/MyOffice.Data.Repositories/Account/AccountAccessInviteRepository.cs +++ /dev/null @@ -1,81 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Microsoft.EntityFrameworkCore; -using Models.Accounts; -using MyOffice.Data.Repositories; -using MyOffice.DbContext; - -public class AccountAccessInviteRepository : AppRepository, IAccountAccessInviteRepository -{ - public AccountAccessInviteRepository(AppDbContext context) : base(context) - { - } - - public AccountAccessInvite? Get(Guid userId, string email) - { - return _context.AccountAccessInvites - .FirstOrDefault(x => x.UserId == userId - && x.Email == email - && !x.AcceptedOn.HasValue - && !x.RejectedOn.HasValue - ); - } - - public async Task GetAsync(Guid userId, string email, CancellationToken cancellationToken = default) - { - return await _context.AccountAccessInvites - .FirstOrDefaultAsync(x => x.UserId == userId - && x.Email == email - && !x.AcceptedOn.HasValue - && !x.RejectedOn.HasValue, - cancellationToken); - } - - public bool Add(AccountAccessInvite invite) - { - return AddBase(invite) > 0; - } - - public async Task AddAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(invite, cancellationToken) > 0; - } - - public bool Update(AccountAccessInvite invite) - { - return UpdateBase(invite) > 0; - } - - public async Task UpdateAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(invite, cancellationToken) > 0; - } - - public IEnumerable GetActive(string email) - { - return _context - .AccountAccessInvites - .Include(x => x.Account) - .Where(x => x.Email == email && !x.AcceptedOn.HasValue && !x.RejectedOn.HasValue); - - } - - public async Task> GetActiveAsync(string email, CancellationToken cancellationToken = default) - { - return await _context - .AccountAccessInvites - .Include(x => x.Account) - .Where(x => x.Email == email && !x.AcceptedOn.HasValue && !x.RejectedOn.HasValue) - .ToListAsync(cancellationToken); - } - - public AccountAccessInvite? Get(Guid id) - { - return _context.AccountAccessInvites.FirstOrDefault(x => x.Id == id); - } - - public async Task GetAsync(Guid id, CancellationToken cancellationToken = default) - { - return await _context.AccountAccessInvites.FirstOrDefaultAsync(x => x.Id == id, cancellationToken); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/AccountAccessRepository.cs b/MyOffice.Data.Repositories/Account/AccountAccessRepository.cs deleted file mode 100644 index be14bbe..0000000 --- a/MyOffice.Data.Repositories/Account/AccountAccessRepository.cs +++ /dev/null @@ -1,42 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Models.Accounts; -using MyOffice.Data.Repositories; -using MyOffice.DbContext; - -public class AccountAccessRepository : AppRepository, IAccountAccessRepository -{ - public AccountAccessRepository(AppDbContext context) : base(context) - { - } - - public bool Add(AccountAccess accountAccess) - { - return AddBase(accountAccess) > 0; - } - - public async Task AddAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(accountAccess, cancellationToken) > 0; - } - - public bool Update(AccountAccess accountAccess) - { - return UpdateBase(accountAccess) > 0; - } - - public async Task UpdateAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(accountAccess, cancellationToken) > 0; - } - - public bool Delete(AccountAccess accountAccess) - { - return RemoveBase(accountAccess) > 0; - } - - public async Task DeleteAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default) - { - return await RemoveBaseAsync(accountAccess, cancellationToken) > 0; - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/AccountAccountCategoryRepository.cs b/MyOffice.Data.Repositories/Account/AccountAccountCategoryRepository.cs deleted file mode 100644 index 9fdbf54..0000000 --- a/MyOffice.Data.Repositories/Account/AccountAccountCategoryRepository.cs +++ /dev/null @@ -1,55 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Microsoft.EntityFrameworkCore; -using Models.Accounts; -using MyOffice.DbContext; - -public class AccountAccountCategoryRepository : AppRepository, IAccountAccountCategoryRepository -{ - public AccountAccountCategoryRepository(AppDbContext context) : base(context) - { - } - - public List Get(Guid userId, Guid accountId, Guid categoryId) - { - return _context.AccountAccountCategories - .Include(x => x.Account) - .Include(x => x.Category) - .Where(x => x.AccountId == accountId && x.CategoryId == categoryId && x.Category.UserId == userId) - .ToList(); - } - - public async Task> GetAsync( - Guid userId, - Guid accountId, - Guid categoryId, - CancellationToken cancellationToken = default - ) - { - return await _context.AccountAccountCategories - .Include(x => x.Account) - .Include(x => x.Category) - .Where(x => x.AccountId == accountId && x.CategoryId == categoryId && x.Category.UserId == userId) - .ToListAsync(cancellationToken); - } - - public bool Remove(AccountAccountCategory accountAccountCategory) - { - return RemoveBase(accountAccountCategory) > 0; - } - - public async Task RemoveAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default) - { - return await RemoveBaseAsync(accountAccountCategory, cancellationToken) > 0; - } - - public bool Add(AccountAccountCategory accountAccountCategory) - { - return AddBase(accountAccountCategory) > 0; - } - - public async Task AddAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(accountAccountCategory, cancellationToken) > 0; - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/AccountCategoryRepository.cs b/MyOffice.Data.Repositories/Account/AccountCategoryRepository.cs deleted file mode 100644 index f1ec7e1..0000000 --- a/MyOffice.Data.Repositories/Account/AccountCategoryRepository.cs +++ /dev/null @@ -1,73 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Microsoft.EntityFrameworkCore; -using Models.Accounts; -using MyOffice.Data.Repositories; -using MyOffice.DbContext; - -public class AccountCategoryRepository : AppRepository, IAccountCategoryRepository -{ - public AccountCategoryRepository(AppDbContext context) : base(context) - { - } - - public List GetAll(Guid userId) - { - return _context.AccountCategories - .Include(x => x.Accounts) - .Where(x => x.UserId == userId) - .ToList(); - } - - public async Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default) - { - return await _context.AccountCategories - .Include(x => x.Accounts) - .Where(x => x.UserId == userId) - .ToListAsync(cancellationToken); - } - - public bool Add(AccountCategory accountCategory) - { - return AddBase(accountCategory) > 0; - } - - public async Task AddAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(accountCategory, cancellationToken) > 0; - } - - public AccountCategory? Get(Guid userId, Guid id) - { - return _context.AccountCategories - .Include(x => x.Accounts) - .FirstOrDefault(x => x.Id == id && x.UserId == userId); - } - - public async Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default) - { - return await _context.AccountCategories - .Include(x => x.Accounts) - .FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, cancellationToken); - } - - public bool Update(AccountCategory accountCategory) - { - return UpdateBase(accountCategory) > 0; - } - - public async Task UpdateAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(accountCategory, cancellationToken) > 0; - } - - public bool Remove(AccountCategory accountCategory) - { - return RemoveBase(accountCategory) > 0; - } - - public async Task RemoveAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default) - { - return await RemoveBaseAsync(accountCategory, cancellationToken) > 0; - } -} diff --git a/MyOffice.Data.Repositories/Account/AccountRepository.cs b/MyOffice.Data.Repositories/Account/AccountRepository.cs deleted file mode 100644 index f09eaf4..0000000 --- a/MyOffice.Data.Repositories/Account/AccountRepository.cs +++ /dev/null @@ -1,641 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using Models.Accounts; -using MyOffice.Data.Models.Accounts.Domain; -using MyOffice.Data.Models.Currencies; -using MyOffice.Data.Repositories; -using MyOffice.DbContext; - -public class AccountRepository : AppRepository, IAccountRepository -{ - private readonly ILogger _logger; - - public AccountRepository( - AppDbContext context, - ILogger logger - ) : base(context) - { - _logger = logger; - } - - public List GetAll(Guid userId) - { - return _context.Accounts! - .Include(x => x.CurrencyGlobal) - // categories created with current user - .Include(x => x.Categories!.Where(c => c.Category.UserId == userId))! - .ThenInclude(x => x.Category) - // access rights created with current user - .Include(x => x.AccessRights!.Where(a => a.OwnerId == userId))! - .ThenInclude(x => x.User) - // require only one motions to check if can to delete account - .Include(x => x.Motions!.Take(1))! - // only accounts with access to current user - .Where(x => x.AccessRights!.Any(a => a.UserId == userId)) - .ToList(); - } - - public async Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default) - { - return await _context.Accounts! - .Include(x => x.CurrencyGlobal) - // categories created with current user - .Include(x => x.Categories!.Where(c => c.Category.UserId == userId))! - .ThenInclude(x => x.Category) - // access rights created with current user - .Include(x => x.AccessRights!.Where(a => a.OwnerId == userId))! - .ThenInclude(x => x.User) - // require only one motions to check if can to delete account - .Include(x => x.Motions!.Take(1))! - // only accounts with access to current user - .Where(x => x.AccessRights!.Any(a => a.UserId == userId)) - .ToListAsync(cancellationToken); - } - - public List GetByCategory(Guid userId, Guid categoryId) - { - return _context.Accounts! - .Include(x => x.CurrencyGlobal) - .Include(x => x.Categories)! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - .Include(x => x.Motions)! - .Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId)) - .ToList(); - } - - public async Task> GetByCategoryAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default) - { - return await _context.Accounts! - .Include(x => x.CurrencyGlobal) - .Include(x => x.Categories)! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - .Include(x => x.Motions)! - .Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId)) - .ToListAsync(cancellationToken); - } - - public List GetByCategoryDetailed(Guid userId, Guid categoryId) - { - return _context.Accounts! - .Include(x => x.CurrencyGlobal) - .Include(x => x.Categories)! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - .Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId)) - .Select(x => new AccountDetailed - { - Account = x, - TotalPlus = x.Motions!.Sum(m => m.AmountPlus), - TotalMinus = x.Motions!.Sum(m => m.AmountMinus), - }) - .ToList(); - } - - public Task> GetByCategoryDetailedAsync( - Guid userId, - Guid categoryId, - CancellationToken cancellationToken = default - ) - { - return _context.Accounts! - .Include(x => x.CurrencyGlobal) - .Include(x => x.Categories)! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - .Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId)) - .Select(x => new AccountDetailed - { - Account = x, - TotalPlus = x.Motions!.Sum(m => m.AmountPlus), - TotalMinus = x.Motions!.Sum(m => m.AmountMinus), - }) - .ToListAsync(cancellationToken); - } - - public AccountDetailed? GetByIdDetailed(Guid userId, Guid id) - { - return _context.Accounts! - .Include(x => x.CurrencyGlobal) - .Include(x => x.Categories)! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - .Where(x => x.Id == id && x.AccessRights!.Any(a => a.UserId == userId)) - .Select(x => new AccountDetailed - { - Account = x, - TotalPlus = x.Motions!.Sum(m => m.AmountPlus), - TotalMinus = x.Motions!.Sum(m => m.AmountMinus), - }) - .FirstOrDefault(); - } - - public Task GetByIdDetailedAsync( - Guid userId, - Guid id, - CancellationToken cancellationToken = default - ) - { - return _context.Accounts! - .Include(x => x.CurrencyGlobal) - .Include(x => x.Categories)! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - .Where(x => x.Id == id && x.AccessRights!.Any(a => a.UserId == userId)) - .Select(x => new AccountDetailed - { - Account = x, - TotalPlus = x.Motions!.Sum(m => m.AmountPlus), - TotalMinus = x.Motions!.Sum(m => m.AmountMinus), - }) - .FirstOrDefaultAsync(cancellationToken); - } - - public bool Add(Account account) - { - return AddBase(account) > 0; - } - - public async Task AddAsync(Account account, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(account, cancellationToken) > 0; - } - - public bool Delete(Account account) - { - return RemoveBase(account) > 0; - } - - public async Task DeleteAsync(Account account, CancellationToken cancellationToken = default) - { - return await RemoveBaseAsync(account, cancellationToken) > 0; - } - - public Account? Get(Guid userId, Guid id) - { - return _context.Accounts! - .Include(x => x.Categories!.Where(c => c.Category.UserId == userId))! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - //.Include(x => x.Motions)! - .FirstOrDefault(x => x.Id == id && x.AccessRights!.Any(r => r.UserId == userId)); - } - - public Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default) - { - return _context.Accounts! - .Include(x => x.Categories!.Where(c => c.Category.UserId == userId))! - .ThenInclude(x => x.Category) - .Include(x => x.AccessRights)! - .ThenInclude(x => x.User) - .FirstOrDefaultAsync( - x => x.Id == id && x.AccessRights!.Any(r => r.UserId == userId), - cancellationToken); - } - - public bool Update(Account account) - { - return UpdateBase(account) > 0; - } - - public async Task UpdateAsync(Account account, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(account, cancellationToken) > 0; - } - - public bool Remove(Account account) - { - return RemoveBase(account) > 0; - } - - public List FindAccounts(Guid userId, string term) - { - return _context.Accounts - .Where(x => x.AccessRights!.Any(a => a.UserId == userId)) - .Where(x => x.Name.ToLower().Contains(term.ToLower())) - .ToList(); - } - - public async Task> FindAccountsAsync(Guid userId, string term, CancellationToken cancellationToken = default) - { - return await _context.Accounts - .Where(x => x.AccessRights!.Any(a => a.UserId == userId)) - .Where(x => x.Name.ToLower().Contains(term.ToLower())) - .ToListAsync(cancellationToken); - } - - public List GetAccountsWithRate(Guid userId, DateTime date) - { - var accounts = _context.Accounts - .Where(x => x.AccessRights!.Any(a => a.UserId == userId)) - .ToList(); - - var currencyIds = accounts - .Select(x => x.CurrencyGlobalId) - .ToList(); - - var rates = _context.CurrencyRates - .Include(x => x.Currency) - .Where(x => x.Currency!.UserId == userId) - .Where(x => x.DateTime <= date) - .Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId)) - .GroupBy(x => x.Currency!.CurrencyGlobalId) - .Select(x => x.OrderByDescending(r => r.DateTime).First()) - .ToList(); - - return accounts - .Select(account => - { - var rate = rates.FirstOrDefault(rate => rate.Currency!.CurrencyGlobalId == account.CurrencyGlobalId); - - var result = new AccountWithRate - { - Account = account, - Currency = rate?.Currency, - Rate = rate, - }; - - return result; - }) - .ToList(); - } - - public List GetRestAtDate(Guid userId, DateTime date) - { - return _context.AccountAccesses! - .Where(x => x.UserId == userId) - .Include(x => x.Account!) - .ThenInclude(x => x.CurrencyGlobal!) - .ThenInclude(x => x.Currencies!) - .ThenInclude(x => x.CurrentRate!) - .Include(x => x.Account) - .ThenInclude(x => x!.Motions) - .Select(x => new - { - Id = x.AccountId, - Name = x.Account!.Name, - Type = x.Type, - Currency = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId), - CurrentRate = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId)!.CurrentRate, - Plus = x.Account.Motions! - .Where(x => !x.DeletedOn.HasValue) - .Sum(m => m.AmountPlus), - Minus = x.Account.Motions! - .Where(x => !x.DeletedOn.HasValue) - .Sum(m => m.AmountMinus), - }) - .ToList() - .Select(x => new AccountSimple - { - Id = x.Id, - Name = x.Name, - Type = x.Type, - CurrencyName = x.Currency?.Name, - CurrencyShortName = x.Currency?.ShortName, - CurrencyRate = x.CurrentRate?.Rate, - CurrencyQuantity = x.CurrentRate?.Quantity, - TotalMinus = x.Minus, - TotalPlus = x.Plus, - Balance = x.Plus - x.Minus, - }) - .ToList(); - } - - public List GetIncomeByCategories(Guid userId, DateTime from, DateTime to) - { - var accounts = GetAccountsWithRate(userId, to); - var accountIds = accounts.Select(x => x.Account.Id); - - return _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => accountIds.Contains(x.AccountId)) - .Where(x => !x.Item.Category!.IsInternal) - .GroupBy(x => new - { - Id = x.Item.CategoryId, - Name = x.Item.Category!.Name, - IsUserCategory = x.Item.Category!.UserId == userId, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .ToList() - .Select(x => new MotionTotalSimple - { - Id = x.Key.IsUserCategory ? x.Key.Id : userId, - Name = x.Key.Name, - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Amount = x.Sum(a => a.AmountPlus), - }) - .ToList(); - } - - public List GetIncomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to) - { - return _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => x.Item.Category!.UserId == userId) - .Where(x => x.Item.CategoryId == categoryId) - .Where(x => !x.Item.Category!.IsInternal) - .Where(x => x.Item.Category!.UserId == userId) - .GroupBy(x => new - { - Id = x.Item.ItemGlobalId, - Name = x.Item.ItemGlobal!.Name, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .Select(x => new MotionTotalSimple - { - Name = x.Key.Name, - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Amount = x.Sum(a => a.AmountPlus), - }) - .ToList(); - } - - - public List GetOutcomeByCategories(Guid userId, DateTime from, DateTime to) - { - var accounts = GetAccountsWithRate(userId, to); - var accountIds = accounts.Select(x => x.Account.Id); - - return _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => accountIds.Contains(x.AccountId)) - .Where(x => !x.Item.Category!.IsInternal) - .GroupBy(x => new - { - Id = x.Item.CategoryId, - Name = x.Item.Category!.Name, - IsUserCategory = x.Item.Category!.UserId == userId, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .Select(x => new MotionTotalSimple - { - Id = x.Key.IsUserCategory ? x.Key.Id : userId, - Name = x.Key.IsUserCategory ? x.Key.Name : "UnCategorized", - //Name = x.Key.Name, - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Amount = x.Sum(a => a.AmountMinus), - }).ToList(); - } - - - public List GetOutcomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to) - { - var accounts = GetAccountsWithRate(userId, to); - var accountIds = accounts.Select(x => x.Account.Id); - - return _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => accountIds.Contains(x.AccountId)) - .Where(x => !x.Item.Category!.IsInternal) - .Where(x => x.Item.CategoryId == categoryId) - .GroupBy(x => new - { - Id = x.Item.ItemGlobalId, - Name = x.Item.ItemGlobal!.Name, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .Select(x => new MotionTotalSimple - { - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Name = x.Key.Name, - Amount = x.Sum(a => a.AmountMinus), - }) - .ToList(); - } - - public async Task> GetAccountsWithRateAsync( - Guid userId, - DateTime date, - CancellationToken cancellationToken = default - ) - { - var accounts = await _context.Accounts - .Where(x => x.AccessRights!.Any(a => a.UserId == userId)) - .ToListAsync(cancellationToken); - - var currencyIds = accounts - .Select(x => x.CurrencyGlobalId) - .ToList(); - - var rates = await _context.CurrencyRates - .Include(x => x.Currency) - .Where(x => x.Currency!.UserId == userId) - .Where(x => x.DateTime <= date) - .Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId)) - .GroupBy(x => x.Currency!.CurrencyGlobalId) - .Select(x => x.OrderByDescending(r => r.DateTime).First()) - .ToListAsync(cancellationToken); - - return accounts - .Select(account => - { - var rate = rates.FirstOrDefault(r => r.Currency!.CurrencyGlobalId == account.CurrencyGlobalId); - return new AccountWithRate - { - Account = account, - Currency = rate?.Currency, - Rate = rate, - }; - }) - .ToList(); - } - - public async Task> GetRestAtDateAsync( - Guid userId, - DateTime date, - CancellationToken cancellationToken = default - ) - { - var rows = await _context.AccountAccesses! - .Where(x => x.UserId == userId) - .Include(x => x.Account!) - .ThenInclude(x => x.CurrencyGlobal!) - .ThenInclude(x => x.Currencies!) - .ThenInclude(x => x.CurrentRate!) - .Include(x => x.Account) - .ThenInclude(x => x!.Motions) - .Select(x => new - { - Id = x.AccountId, - Name = x.Account!.Name, - Type = x.Type, - Currency = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId), - CurrentRate = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId)!.CurrentRate, - Plus = x.Account.Motions! - .Where(m => !m.DeletedOn.HasValue) - .Sum(m => m.AmountPlus), - Minus = x.Account.Motions! - .Where(m => !m.DeletedOn.HasValue) - .Sum(m => m.AmountMinus), - }) - .ToListAsync(cancellationToken); - - return rows - .Select(x => new AccountSimple - { - Id = x.Id, - Name = x.Name, - Type = x.Type, - CurrencyName = x.Currency?.Name, - CurrencyShortName = x.Currency?.ShortName, - CurrencyRate = x.CurrentRate?.Rate, - CurrencyQuantity = x.CurrentRate?.Quantity, - TotalMinus = x.Minus, - TotalPlus = x.Plus, - Balance = x.Plus - x.Minus, - }) - .ToList(); - } - - public async Task> GetIncomeByCategoriesAsync( - Guid userId, - DateTime from, - DateTime to, - CancellationToken cancellationToken = default - ) - { - var accounts = await GetAccountsWithRateAsync(userId, to, cancellationToken); - var accountIds = accounts.Select(x => x.Account.Id).ToList(); - - var groups = await _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => accountIds.Contains(x.AccountId)) - .Where(x => !x.Item.Category!.IsInternal) - .GroupBy(x => new - { - Id = x.Item.CategoryId, - Name = x.Item.Category!.Name, - IsUserCategory = x.Item.Category!.UserId == userId, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .ToListAsync(cancellationToken); - - return groups - .Select(x => new MotionTotalSimple - { - Id = x.Key.IsUserCategory ? x.Key.Id : userId, - Name = x.Key.Name, - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Amount = x.Sum(a => a.AmountPlus), - }) - .ToList(); - } - - public Task> GetIncomeByCategoryAsync( - Guid userId, - Guid categoryId, - DateTime from, - DateTime to, - CancellationToken cancellationToken = default - ) - { - return _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => x.Item.Category!.UserId == userId) - .Where(x => x.Item.CategoryId == categoryId) - .Where(x => !x.Item.Category!.IsInternal) - .Where(x => x.Item.Category!.UserId == userId) - .GroupBy(x => new - { - Id = x.Item.ItemGlobalId, - Name = x.Item.ItemGlobal!.Name, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .Select(x => new MotionTotalSimple - { - Name = x.Key.Name, - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Amount = x.Sum(a => a.AmountPlus), - }) - .ToListAsync(cancellationToken); - } - - public async Task> GetOutcomeByCategoriesAsync( - Guid userId, - DateTime from, - DateTime to, - CancellationToken cancellationToken = default - ) - { - var accounts = await GetAccountsWithRateAsync(userId, to, cancellationToken); - var accountIds = accounts.Select(x => x.Account.Id).ToList(); - - return await _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => accountIds.Contains(x.AccountId)) - .Where(x => !x.Item.Category!.IsInternal) - .GroupBy(x => new - { - Id = x.Item.CategoryId, - Name = x.Item.Category!.Name, - IsUserCategory = x.Item.Category!.UserId == userId, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .Select(x => new MotionTotalSimple - { - Id = x.Key.IsUserCategory ? x.Key.Id : userId, - Name = x.Key.IsUserCategory ? x.Key.Name : "UnCategorized", - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Amount = x.Sum(a => a.AmountMinus), - }) - .ToListAsync(cancellationToken); - } - - public async Task> GetOutcomeByCategoryAsync( - Guid userId, - Guid categoryId, - DateTime from, - DateTime to, - CancellationToken cancellationToken = default - ) - { - var accounts = await GetAccountsWithRateAsync(userId, to, cancellationToken); - var accountIds = accounts.Select(x => x.Account.Id).ToList(); - - return await _context.Motions - .Where(x => x.DateTime >= from && x.DateTime <= to) - .Where(x => accountIds.Contains(x.AccountId)) - .Where(x => !x.Item.Category!.IsInternal) - .Where(x => x.Item.CategoryId == categoryId) - .GroupBy(x => new - { - Id = x.Item.ItemGlobalId, - Name = x.Item.ItemGlobal!.Name, - CurrencyId = x.Account.CurrencyGlobalId, - CurrencyName = x.Account.CurrencyGlobal!.Name, - }) - .Select(x => new MotionTotalSimple - { - CurrencyId = x.Key.CurrencyId, - CurrencyName = x.Key.CurrencyName, - Name = x.Key.Name, - Amount = x.Sum(a => a.AmountMinus), - }) - .ToListAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/IAccountAccessInviteRepository.cs b/MyOffice.Data.Repositories/Account/IAccountAccessInviteRepository.cs deleted file mode 100644 index ac0a50c..0000000 --- a/MyOffice.Data.Repositories/Account/IAccountAccessInviteRepository.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Models.Accounts; - -public interface IAccountAccessInviteRepository -{ - AccountAccessInvite? Get(Guid userId, string email); - Task GetAsync(Guid userId, string email, CancellationToken cancellationToken = default); - IEnumerable GetActive(string email); - Task> GetActiveAsync(string email, CancellationToken cancellationToken = default); - AccountAccessInvite? Get(Guid id); - Task GetAsync(Guid id, CancellationToken cancellationToken = default); - bool Add(AccountAccessInvite invite); - Task AddAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default); - bool Update(AccountAccessInvite invite); - Task UpdateAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/IAccountAccessRepository.cs b/MyOffice.Data.Repositories/Account/IAccountAccessRepository.cs deleted file mode 100644 index 47e7c95..0000000 --- a/MyOffice.Data.Repositories/Account/IAccountAccessRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Models.Accounts; - -public interface IAccountAccessRepository -{ - bool Add(AccountAccess accountAccess); - Task AddAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default); - bool Update(AccountAccess accountAccess); - Task UpdateAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default); - bool Delete(AccountAccess accountAccess); - Task DeleteAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/IAccountAccountCategoryRepository.cs b/MyOffice.Data.Repositories/Account/IAccountAccountCategoryRepository.cs deleted file mode 100644 index 1f2d59c..0000000 --- a/MyOffice.Data.Repositories/Account/IAccountAccountCategoryRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Models.Accounts; - -public interface IAccountAccountCategoryRepository -{ - List Get(Guid userId, Guid accountId, Guid categoryId); - Task> GetAsync(Guid userId, Guid accountId, Guid categoryId, CancellationToken cancellationToken = default); - bool Remove(AccountAccountCategory accountAccountCategory); - Task RemoveAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default); - bool Add(AccountAccountCategory accountAccountCategory); - Task AddAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/IAccountCategoryRepository.cs b/MyOffice.Data.Repositories/Account/IAccountCategoryRepository.cs deleted file mode 100644 index 24903f2..0000000 --- a/MyOffice.Data.Repositories/Account/IAccountCategoryRepository.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Models.Accounts; - -public interface IAccountCategoryRepository -{ - List GetAll(Guid userId); - Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default); - bool Add(AccountCategory accountCategory); - Task AddAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default); - AccountCategory? Get(Guid userId, Guid id); - Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default); - bool Update(AccountCategory accountCategory); - Task UpdateAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default); - bool Remove(AccountCategory accountCategory); - Task RemoveAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default); -} diff --git a/MyOffice.Data.Repositories/Account/IAccountyRepository.cs b/MyOffice.Data.Repositories/Account/IAccountyRepository.cs deleted file mode 100644 index 5d7345d..0000000 --- a/MyOffice.Data.Repositories/Account/IAccountyRepository.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Models.Accounts; - -public interface IAccountRepository -{ - List GetAll(Guid userId); - Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default); - List GetByCategory(Guid userId, Guid categoryId); - Task> GetByCategoryAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default); - List GetByCategoryDetailed(Guid userId, Guid categoryId); - Task> GetByCategoryDetailedAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default); - AccountDetailed? GetByIdDetailed(Guid userId, Guid id); - Task GetByIdDetailedAsync(Guid userId, Guid id, CancellationToken cancellationToken = default); - bool Add(Account account); - Task AddAsync(Account account, CancellationToken cancellationToken = default); - bool Delete(Account account); - Task DeleteAsync(Account account, CancellationToken cancellationToken = default); - Account? Get(Guid userId, Guid id); - Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default); - bool Update(Account account); - Task UpdateAsync(Account account, CancellationToken cancellationToken = default); - bool Remove(Account account); - List FindAccounts(Guid userId, string term); - Task> FindAccountsAsync(Guid userId, string term, CancellationToken cancellationToken = default); - - List GetRestAtDate(Guid userId, DateTime date); - Task> GetRestAtDateAsync(Guid userId, DateTime date, CancellationToken cancellationToken = default); - List GetIncomeByCategories(Guid userId, DateTime from, DateTime to); - Task> GetIncomeByCategoriesAsync(Guid userId, DateTime from, DateTime to, CancellationToken cancellationToken = default); - List GetIncomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to); - Task> GetIncomeByCategoryAsync(Guid userId, Guid categoryId, DateTime from, DateTime to, CancellationToken cancellationToken = default); - List GetOutcomeByCategories(Guid userId, DateTime from, DateTime to); - Task> GetOutcomeByCategoriesAsync(Guid userId, DateTime from, DateTime to, CancellationToken cancellationToken = default); - List GetOutcomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to); - Task> GetOutcomeByCategoryAsync(Guid userId, Guid categoryId, DateTime from, DateTime to, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Account/IMotionRepository.cs b/MyOffice.Data.Repositories/Account/IMotionRepository.cs deleted file mode 100644 index 2cc664d..0000000 --- a/MyOffice.Data.Repositories/Account/IMotionRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Models.Accounts; - -public interface IMotionRepository -{ - Task AddAsync(Motion motion, CancellationToken cancellationToken = default); - Task> GetByAccountAsync(Guid accountId, DateTime dateFrom, DateTime dateTo, CancellationToken cancellationToken = default); - Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default); - Task UpdateAsync(Motion motion, CancellationToken cancellationToken = default); - Task RemoveAsync(Motion motion, CancellationToken cancellationToken = default); -} diff --git a/MyOffice.Data.Repositories/Account/MotionRepository.cs b/MyOffice.Data.Repositories/Account/MotionRepository.cs deleted file mode 100644 index 3d2ceb5..0000000 --- a/MyOffice.Data.Repositories/Account/MotionRepository.cs +++ /dev/null @@ -1,55 +0,0 @@ -namespace MyOffice.Data.Repositories.Account; - -using Microsoft.EntityFrameworkCore; -using Models.Accounts; -using MyOffice.DbContext; - -public class MotionRepository : AppRepository, IMotionRepository -{ - public MotionRepository(AppDbContext context) : base(context) - { - } - - public async Task AddAsync(Motion motion, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(motion, cancellationToken) > 0; - } - - public async Task> GetByAccountAsync( - Guid accountId, - DateTime dateFrom, - DateTime dateTo, - CancellationToken cancellationToken = default - ) - { - return await _context - .Motions - .Include(x => x.Item) - .ThenInclude(x => x.ItemGlobal) - .Where(x => x.AccountId == accountId && x.DateTime >= dateFrom && x.DateTime <= dateTo) - .OrderByDescending(x => x.DateTime) - .ThenByDescending(x => x.CreatedOn) - .ToListAsync(cancellationToken); - } - - public async Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default) - { - return await _context - .Motions - .Include(x => x.Item) - .ThenInclude(x => x.ItemGlobal) - .FirstOrDefaultAsync( - x => x.Account!.AccessRights!.Any(a => a.UserId == userId) && x.Id == id, - cancellationToken); - } - - public async Task UpdateAsync(Motion motion, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(motion, cancellationToken) > 0; - } - - public async Task RemoveAsync(Motion motion, CancellationToken cancellationToken = default) - { - return await RemoveBaseAsync(motion, cancellationToken) > 0; - } -} diff --git a/MyOffice.Data.Repositories/AppRepository.cs b/MyOffice.Data.Repositories/AppRepository.cs deleted file mode 100644 index 84e7481..0000000 --- a/MyOffice.Data.Repositories/AppRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Data.Repositories; - -using DbContext; - -public class AppRepository : RepositoryBase where TEntity : class -{ - public AppRepository(AppDbContext context) : base(context) - { - } -} diff --git a/MyOffice.Data.Repositories/Currency/CurrencyGlobalRepository.cs b/MyOffice.Data.Repositories/Currency/CurrencyGlobalRepository.cs deleted file mode 100644 index 1eda5bf..0000000 --- a/MyOffice.Data.Repositories/Currency/CurrencyGlobalRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace MyOffice.Data.Repositories.Currency; - -using Microsoft.EntityFrameworkCore; -using Models.Currencies; -using MyOffice.DbContext; - -public class CurrencyGlobalRepository : AppRepository, ICurrencyGlobalRepository -{ - public CurrencyGlobalRepository(AppDbContext context) : base(context) - { - } - - public List GetAll() - { - return _context.CurrencyGlobals.ToList(); - } - - public async Task> GetAllAsync(CancellationToken cancellationToken = default) - { - return await _context.CurrencyGlobals.ToListAsync(cancellationToken); - } -} diff --git a/MyOffice.Data.Repositories/Currency/CurrencyRateRepository.cs b/MyOffice.Data.Repositories/Currency/CurrencyRateRepository.cs deleted file mode 100644 index 72b43be..0000000 --- a/MyOffice.Data.Repositories/Currency/CurrencyRateRepository.cs +++ /dev/null @@ -1,115 +0,0 @@ -namespace MyOffice.Data.Repositories.Currency; - -using System.Xml.Schema; -using Microsoft.EntityFrameworkCore; -using Models.Currencies; -using MyOffice.DbContext; - -public class CurrencyRateRepository : AppRepository, ICurrencyRateRepository -{ - public CurrencyRateRepository(AppDbContext context) : base(context) - { - } - - public List GetLastRates(Guid currencyId, DateTime? before = null, int count = 1) - { - before = before ?? DateTime.UtcNow; - - return _context.CurrencyRates - .Where(x => x.CurrencyId == currencyId) - .Where(x => x.DateTime <= before) - .OrderByDescending(x => x.DateTime) - .ThenByDescending(x => x.Id) - .Take(count) - .ToList(); - } - - public async Task> GetLastRatesAsync( - Guid currencyId, - DateTime? before = null, - int count = 1, - CancellationToken cancellationToken = default) - { - before ??= DateTime.UtcNow; - - return await _context.CurrencyRates - .Where(x => x.CurrencyId == currencyId) - .Where(x => x.DateTime <= before) - .OrderByDescending(x => x.DateTime) - .ThenByDescending(x => x.Id) - .Take(count) - .ToListAsync(cancellationToken); - } - - public Dictionary GetLastRates(Guid userId, List currencyIds, DateTime? before = null) - { - return _context.CurrencyRates - .Include(x => x.Currency) - .Include(x => x.Currency!.CurrencyGlobal) - .Where(x => x.DateTime <= before) - .Where(x => x.Currency!.UserId == userId) - .Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId)) - .GroupBy(x => new - { - x.Currency!.CurrencyGlobalId - }, (key, g) => new - { - key.CurrencyGlobalId, - rate = g.OrderByDescending(x => x.DateTime).First() - }) - .ToDictionary(x => x.CurrencyGlobalId, x => x.rate); - } - - public async Task> GetLastRatesAsync( - Guid userId, - List currencyIds, - DateTime? before = null, - CancellationToken cancellationToken = default - ) - { - var rows = await _context.CurrencyRates - .Include(x => x.Currency) - .Include(x => x.Currency!.CurrencyGlobal) - .Where(x => x.DateTime <= before) - .Where(x => x.Currency!.UserId == userId) - .Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId)) - .GroupBy(x => new - { - x.Currency!.CurrencyGlobalId - }, (key, g) => new - { - key.CurrencyGlobalId, - rate = g.OrderByDescending(x => x.DateTime).First() - }) - .ToListAsync(cancellationToken); - - return rows.ToDictionary(x => x.CurrencyGlobalId, x => x.rate); - } - - public bool AddRate(CurrencyRate currencyRate) - { - return this.AddBase(currencyRate) > 0; - } - - public async Task AddRateAsync(CurrencyRate currencyRate, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(currencyRate, cancellationToken) > 0; - } - - public List GetAtDate(Guid currencyId, DateTime date) - { - return _context.CurrencyRates - .Where(x => x.CurrencyId == currencyId && x.DateTime == date) - .ToList(); - } - - public async Task> GetAtDateAsync( - Guid currencyId, - DateTime date, - CancellationToken cancellationToken = default) - { - return await _context.CurrencyRates - .Where(x => x.CurrencyId == currencyId && x.DateTime == date) - .ToListAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Currency/CurrencyRepository.cs b/MyOffice.Data.Repositories/Currency/CurrencyRepository.cs deleted file mode 100644 index 77d12bb..0000000 --- a/MyOffice.Data.Repositories/Currency/CurrencyRepository.cs +++ /dev/null @@ -1,102 +0,0 @@ -namespace MyOffice.Data.Repositories.Currency; - -using Microsoft.EntityFrameworkCore; -using Models.Currencies; -using MyOffice.Data.Repositories; -using MyOffice.DbContext; - -public class CurrencyRepository : AppRepository, ICurrencyRepository -{ - public CurrencyRepository(AppDbContext context) : base(context) - { - } - - public List GetAll(Guid userId) - { - return _context.Currencies - .Include(x => x.CurrencyGlobal) - .Where(x => x.UserId == userId) - .ToList(); - } - - public async Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default) - { - return await _context.Currencies - .Include(x => x.CurrencyGlobal) - .Where(x => x.UserId == userId) - .ToListAsync(cancellationToken); - } - - public Currency? Get(Guid userId, Guid id) - { - return _context - .Currencies - .Include(x => x.CurrencyGlobal) - .FirstOrDefault(x => x.Id == id && x.UserId == userId); - } - - public async Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default) - { - return await _context - .Currencies - .Include(x => x.CurrencyGlobal) - .FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, cancellationToken); - } - - public Currency? GetByGlobalCurrency(Guid userId, string globalCurrencyId) - { - return _context.Currencies.FirstOrDefault(x => x.UserId == userId && x.CurrencyGlobalId == globalCurrencyId); - } - - public async Task GetByGlobalCurrencyAsync( - Guid userId, - string globalCurrencyId, - CancellationToken cancellationToken = default) - { - return await _context.Currencies.FirstOrDefaultAsync( - x => x.UserId == userId && x.CurrencyGlobalId == globalCurrencyId, - cancellationToken); - } - - public bool Add(Currency currency) - { - return AddBase(currency) > 0; - } - - public async Task AddAsync(Currency currency, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(currency, cancellationToken) > 0; - } - - public bool Update(Currency currency) - { - return UpdateBase(currency) > 0; - } - - public async Task UpdateAsync(Currency currency, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(currency, cancellationToken) > 0; - } - - public bool Remove(Currency currency) - { - return RemoveBase(currency) > 0; - } - - public async Task RemoveAsync(Currency currency, CancellationToken cancellationToken = default) - { - return await RemoveBaseAsync(currency, cancellationToken) > 0; - } - - public List GetPrimaries(Guid userId) - { - return _context.Currencies.Where(x => x.UserId == userId && x.IsPrimary).ToList(); - } - - public async Task> GetPrimariesAsync(Guid userId, CancellationToken cancellationToken = default) - { - return await _context.Currencies - .Where(x => x.UserId == userId && x.IsPrimary) - .ToListAsync(cancellationToken); - } -} diff --git a/MyOffice.Data.Repositories/Currency/ICurrencyGlobalRepository.cs b/MyOffice.Data.Repositories/Currency/ICurrencyGlobalRepository.cs deleted file mode 100644 index e2b75ce..0000000 --- a/MyOffice.Data.Repositories/Currency/ICurrencyGlobalRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MyOffice.Data.Repositories.Currency; - -using Models.Currencies; - -public interface ICurrencyGlobalRepository -{ - List GetAll(); - Task> GetAllAsync(CancellationToken cancellationToken = default); -} diff --git a/MyOffice.Data.Repositories/Currency/ICurrencyRateRepository.cs b/MyOffice.Data.Repositories/Currency/ICurrencyRateRepository.cs deleted file mode 100644 index d54bb0e..0000000 --- a/MyOffice.Data.Repositories/Currency/ICurrencyRateRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MyOffice.Data.Repositories.Currency; - -using Models.Currencies; - -public interface ICurrencyRateRepository -{ - List GetLastRates(Guid currencyId, DateTime? before = null, int count = 1); - Task> GetLastRatesAsync(Guid currencyId, DateTime? before = null, int count = 1, CancellationToken cancellationToken = default); - Dictionary GetLastRates(Guid userId, List currencyIds, DateTime? before = null); - Task> GetLastRatesAsync( - Guid userId, - List currencyIds, - DateTime? before = null, - CancellationToken cancellationToken = default); - bool AddRate(CurrencyRate currencyRate); - Task AddRateAsync(CurrencyRate currencyRate, CancellationToken cancellationToken = default); - List GetAtDate(Guid currencyId, DateTime date); - Task> GetAtDateAsync(Guid currencyId, DateTime date, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Currency/ICurrencyRepository.cs b/MyOffice.Data.Repositories/Currency/ICurrencyRepository.cs deleted file mode 100644 index ebb3ce1..0000000 --- a/MyOffice.Data.Repositories/Currency/ICurrencyRepository.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace MyOffice.Data.Repositories.Currency; - -using Models.Currencies; - -public interface ICurrencyRepository -{ - List GetAll(Guid userId); - Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default); - Currency? Get(Guid userId, Guid id); - Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default); - Currency? GetByGlobalCurrency(Guid userId, string globalCurrencyId); - Task GetByGlobalCurrencyAsync(Guid userId, string globalCurrencyId, CancellationToken cancellationToken = default); - bool Add(Currency currency); - Task AddAsync(Currency currency, CancellationToken cancellationToken = default); - bool Update(Currency currency); - Task UpdateAsync(Currency currency, CancellationToken cancellationToken = default); - bool Remove(Currency currency); - Task RemoveAsync(Currency currency, CancellationToken cancellationToken = default); - List GetPrimaries(Guid userId); - Task> GetPrimariesAsync(Guid userId, CancellationToken cancellationToken = default); -} diff --git a/MyOffice.Data.Repositories/Item/IItemCategoryRepository.cs b/MyOffice.Data.Repositories/Item/IItemCategoryRepository.cs deleted file mode 100644 index ced8cea..0000000 --- a/MyOffice.Data.Repositories/Item/IItemCategoryRepository.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using MyOffice.Data.Models.Items; - -public interface IItemCategoryRepository -{ - List GetAll(Guid userId); - Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default); - bool Add(ItemCategory accountCategory); - Task AddAsync(ItemCategory accountCategory, CancellationToken cancellationToken = default); - ItemCategory? Get(Guid userId, Guid id); - Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default); - bool Update(ItemCategory accountCategory); - Task UpdateAsync(ItemCategory accountCategory, CancellationToken cancellationToken = default); - bool Remove(ItemCategory accountCategory); - Task RemoveAsync(ItemCategory accountCategory, CancellationToken cancellationToken = default); -} diff --git a/MyOffice.Data.Repositories/Item/IItemGlobalRepository.cs b/MyOffice.Data.Repositories/Item/IItemGlobalRepository.cs deleted file mode 100644 index 1dcd4a8..0000000 --- a/MyOffice.Data.Repositories/Item/IItemGlobalRepository.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using MyOffice.Data.Models.Items; - -public interface IItemGlobalRepository -{ - ItemGlobal? Get(Guid id); - ItemGlobal? GetByName(string name); - Task GetByNameAsync(string name, CancellationToken cancellationToken = default); - bool Add(ItemGlobal itemGlobal); - Task AddAsync(ItemGlobal itemGlobal, CancellationToken cancellationToken = default); - List GetAvailableToUser(Guid userId); - Task> GetAvailableToUserAsync(Guid userId, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Item/IItemRepository.cs b/MyOffice.Data.Repositories/Item/IItemRepository.cs deleted file mode 100644 index 2f98f3a..0000000 --- a/MyOffice.Data.Repositories/Item/IItemRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using MyOffice.Data.Models.Items; - -public interface IItemRepository -{ - List GetAll(Guid userId); - Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default); - List GetByCategory(Guid userId, Guid categoryId); - Task> GetByCategoryAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default); - Item? GetByGlobal(Guid userId, Guid globalItemId); - Task GetByGlobalAsync(Guid userId, Guid globalItemId, CancellationToken cancellationToken = default); - bool Add(Item item); - Task AddAsync(Item item, CancellationToken cancellationToken = default); - bool Update(Item item); - Task UpdateAsync(Item item, CancellationToken cancellationToken = default); - List Find(Guid userId, string term, int limit); - Task> FindAsync(Guid userId, string term, int limit, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Item/ItemCategoryRepository.cs b/MyOffice.Data.Repositories/Item/ItemCategoryRepository.cs deleted file mode 100644 index 74bae1d..0000000 --- a/MyOffice.Data.Repositories/Item/ItemCategoryRepository.cs +++ /dev/null @@ -1,72 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using Microsoft.EntityFrameworkCore; -using MyOffice.Data.Models.Items; -using MyOffice.DbContext; - -public class ItemCategoryRepository : AppRepository, IItemCategoryRepository -{ - public ItemCategoryRepository(AppDbContext context) : base(context) - { - } - - public List GetAll(Guid userId) - { - return _context.ItemCategories - .Include(x => x.Items) - .Where(x => x.UserId == userId) - .ToList(); - } - - public async Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default) - { - return await _context.ItemCategories - .Include(x => x.Items) - .Where(x => x.UserId == userId) - .ToListAsync(cancellationToken); - } - - public bool Add(ItemCategory itemCategory) - { - return AddBase(itemCategory) > 0; - } - - public async Task AddAsync(ItemCategory itemCategory, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(itemCategory, cancellationToken) > 0; - } - - public ItemCategory? Get(Guid userId, Guid id) - { - return _context.ItemCategories - .Include(x => x.Items) - .FirstOrDefault(x => x.Id == id && x.UserId == userId); - } - - public async Task GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default) - { - return await _context.ItemCategories - .Include(x => x.Items) - .FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, cancellationToken); - } - - public bool Update(ItemCategory itemCategory) - { - return UpdateBase(itemCategory) > 0; - } - - public async Task UpdateAsync(ItemCategory itemCategory, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(itemCategory, cancellationToken) > 0; - } - - public bool Remove(ItemCategory itemCategory) - { - return RemoveBase(itemCategory) > 0; - } - - public async Task RemoveAsync(ItemCategory itemCategory, CancellationToken cancellationToken = default) - { - return await RemoveBaseAsync(itemCategory, cancellationToken) > 0; - } -} diff --git a/MyOffice.Data.Repositories/Item/ItemGlobalRepository.cs b/MyOffice.Data.Repositories/Item/ItemGlobalRepository.cs deleted file mode 100644 index 1f57d46..0000000 --- a/MyOffice.Data.Repositories/Item/ItemGlobalRepository.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using Microsoft.EntityFrameworkCore; -using MyOffice.Data.Models.Items; -using MyOffice.DbContext; - -public class ItemGlobalRepository : AppRepository, IItemGlobalRepository -{ - public ItemGlobalRepository(AppDbContext context) : base(context) - { - } - - public ItemGlobal? Get(Guid id) - { - return _context.ItemGlobals.FirstOrDefault(x => x.Id == id); - } - - public ItemGlobal? GetByName(string name) - { - return _context.ItemGlobals.FirstOrDefault(x => x.Name == name); - } - - public Task GetByNameAsync(string name, CancellationToken cancellationToken = default) - { - return _context.ItemGlobals.FirstOrDefaultAsync(x => x.Name == name, cancellationToken); - } - - public bool Add(ItemGlobal itemGlobal) - { - return AddBase(itemGlobal) > 0; - } - - public async Task AddAsync(ItemGlobal itemGlobal, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(itemGlobal, cancellationToken) > 0; - } - - public List GetAvailableToUser(Guid userId) - { - return _context.Motions - .Include(x => x.Item) - .ThenInclude(x => x.ItemGlobal) - .ThenInclude(x => x.Items) - .ThenInclude(x => x.Category) - .Where(x => x.Account.AccessRights!.Any(a => a.UserId == userId)) - .Where(x => x.Item.ItemGlobal.Items.All(g => g.Category!.UserId != userId)) - .Select(x => x.Item.ItemGlobal) - .GroupBy(x => x.Id) - .Select(x => x.First()) - .ToList(); - } - - public async Task> GetAvailableToUserAsync( - Guid userId, - CancellationToken cancellationToken = default) - { - return await _context.Motions - .Include(x => x.Item) - .ThenInclude(x => x.ItemGlobal) - .ThenInclude(x => x.Items) - .ThenInclude(x => x.Category) - .Where(x => x.Account.AccessRights!.Any(a => a.UserId == userId)) - .Where(x => x.Item.ItemGlobal.Items.All(g => g.Category!.UserId != userId)) - .Select(x => x.Item.ItemGlobal) - .GroupBy(x => x.Id) - .Select(x => x.First()) - .ToListAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Item/ItemRepository.cs b/MyOffice.Data.Repositories/Item/ItemRepository.cs deleted file mode 100644 index ed0bb82..0000000 --- a/MyOffice.Data.Repositories/Item/ItemRepository.cs +++ /dev/null @@ -1,121 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using Microsoft.EntityFrameworkCore; -using MyOffice.Data.Models.Items; -using MyOffice.DbContext; - -public class ItemRepository : AppRepository, IItemRepository -{ - public ItemRepository(AppDbContext context) : base(context) - { - } - - public List GetAll(Guid userId) - { - return _context.Items - .Include(x => x.Motions) - .Include(x => x.Category) - .Include(x => x.ItemGlobal) - .Where(x => x.Category!.UserId == userId) - .ToList(); - } - - public async Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default) - { - return await _context.Items - .Include(x => x.Motions) - .Include(x => x.Category) - .Include(x => x.ItemGlobal) - .Where(x => x.Category!.UserId == userId) - .ToListAsync(cancellationToken); - } - - public List GetByCategory(Guid userId, Guid categoryId) - { - return _context.Items - .Include(x => x.Motions) - .Include(x => x.Category) - .Include(x => x.ItemGlobal) - .Where(x => x.Category!.UserId == userId && x.CategoryId == categoryId) - .ToList(); - } - - public async Task> GetByCategoryAsync( - Guid userId, - Guid categoryId, - CancellationToken cancellationToken = default) - { - return await _context.Items - .Include(x => x.Motions) - .Include(x => x.Category) - .Include(x => x.ItemGlobal) - .Where(x => x.Category!.UserId == userId && x.CategoryId == categoryId) - .ToListAsync(cancellationToken); - } - - public Item? GetByGlobal(Guid userId, Guid globalItemId) - { - return _context.Items - .Include(x => x.Motions) - .Include(x => x.Category) - .Include(x => x.ItemGlobal) - .FirstOrDefault(x => x.Category!.UserId == userId && x.ItemGlobalId == globalItemId); - } - - public Task GetByGlobalAsync(Guid userId, Guid globalItemId, CancellationToken cancellationToken = default) - { - return _context.Items - .Include(x => x.Motions) - .Include(x => x.Category) - .Include(x => x.ItemGlobal) - .FirstOrDefaultAsync( - x => x.Category!.UserId == userId && x.ItemGlobalId == globalItemId, - cancellationToken); - } - - public bool Update(Item item) - { - return base.UpdateBase(item) > 0; - } - - public async Task UpdateAsync(Item item, CancellationToken cancellationToken = default) - { - return await UpdateBaseAsync(item, cancellationToken) > 0; - } - - public bool Add(Item item) - { - return base.AddBase(item) > 0; - } - - public async Task AddAsync(Item item, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(item, cancellationToken) > 0; - } - - public List Find(Guid userId, string term, int limit) - { - return _context - .Items - .Include(x => x.ItemGlobal) - .Where(x => x.Category!.UserId == userId && x.ItemGlobal.Name.ToLower().Contains(term.ToLower())) - .OrderByDescending(x => x!.Motions!.Count()) - .Take(limit) - .ToList(); - } - - public async Task> FindAsync( - Guid userId, - string term, - int limit, - CancellationToken cancellationToken = default) - { - return await _context - .Items - .Include(x => x.ItemGlobal) - .Where(x => x.Category!.UserId == userId && x.ItemGlobal.Name.ToLower().Contains(term.ToLower())) - .OrderByDescending(x => x!.Motions!.Count()) - .Take(limit) - .ToListAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/MyOffice.Data.Repositories.csproj b/MyOffice.Data.Repositories/MyOffice.Data.Repositories.csproj deleted file mode 100644 index 0d17979..0000000 --- a/MyOffice.Data.Repositories/MyOffice.Data.Repositories.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - diff --git a/MyOffice.Data.Repositories/Notifications/EmailTemplateRepository.cs b/MyOffice.Data.Repositories/Notifications/EmailTemplateRepository.cs deleted file mode 100644 index 40addda..0000000 --- a/MyOffice.Data.Repositories/Notifications/EmailTemplateRepository.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using MyOffice.Data.Models.Notifications; -using MyOffice.DbContext; - -public class EmailTemplateRepository : AppRepository, IEmailTemplateRepository -{ - public EmailTemplateRepository(AppDbContext context) : base(context) - { - } - - public EmailTemplate? Get(EmailTemplateEnum emailTemplate) - { - var emailTemplateStr = emailTemplate.ToString(); - return _context.EmailTemplates.FirstOrDefault(x => x.Id == emailTemplateStr); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Notifications/IEmailTemplateRepository.cs b/MyOffice.Data.Repositories/Notifications/IEmailTemplateRepository.cs deleted file mode 100644 index 65849f2..0000000 --- a/MyOffice.Data.Repositories/Notifications/IEmailTemplateRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using MyOffice.Data.Models.Notifications; - -public interface IEmailTemplateRepository -{ - EmailTemplate? Get(EmailTemplateEnum emailTemplate); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/RepositoryBase.cs b/MyOffice.Data.Repositories/RepositoryBase.cs deleted file mode 100644 index c265ef0..0000000 --- a/MyOffice.Data.Repositories/RepositoryBase.cs +++ /dev/null @@ -1,108 +0,0 @@ -namespace MyOffice.Data.Repositories; - -using Microsoft.EntityFrameworkCore; -using DbContext; - -public class RepositoryBase where TEntity : class -{ - protected readonly AppDbContext _context; - - protected RepositoryBase( - AppDbContext context - ) - { - _context = context; - } - - protected async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - try - { - return await _context.SaveChangesAsync(cancellationToken); - } - catch (DbUpdateException updateException) - { - throw updateException; - } - } - - protected int SaveChanges() - { - try - { - return _context.SaveChanges(); - } - catch (DbUpdateException updateException) - { - throw updateException; - } - } - - - protected async Task GetBaseAsync(Guid id) - { - return await _context.Set().FindAsync(id); - } - - protected TEntity? GetBase(Guid id) - { - return _context.Set().Find(id); - } - - protected int AddBase(TEntity entity) - { - _context.Entry(entity).State = EntityState.Added; - - var result = SaveChanges(); - - _context.Entry(entity).State = EntityState.Detached; - return result; - } - - protected async Task AddBaseAsync(TEntity entity, CancellationToken cancellationToken = default) - { - _context.Entry(entity).State = EntityState.Added; - var result = await SaveChangesAsync(cancellationToken); - _context.Entry(entity).State = EntityState.Detached; - return result; - } - - protected int RemoveBase(TEntity entity) - { - _context.Set().Remove(entity); - - _context.Entry(entity).State = EntityState.Deleted; - - var result = SaveChanges(); - - _context.Entry(entity).State = EntityState.Detached; - return result; - } - - protected async Task RemoveBaseAsync(TEntity entity, CancellationToken cancellationToken = default) - { - _context.Set().Remove(entity); - _context.Entry(entity).State = EntityState.Deleted; - var result = await SaveChangesAsync(cancellationToken); - _context.Entry(entity).State = EntityState.Detached; - return result; - } - - protected int UpdateBase(TEntity entity) - { - _context.Entry(entity).State = EntityState.Modified; - - var result = SaveChanges(); - - _context.Entry(entity).State = EntityState.Detached; - return result; - } - - protected async Task UpdateBaseAsync(TEntity entity, CancellationToken cancellationToken = default) - { - _context.Entry(entity).State = EntityState.Modified; - var result = await SaveChangesAsync(cancellationToken); - _context.Entry(entity).State = EntityState.Detached; - return result; - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/IUserExternalRepository.cs b/MyOffice.Data.Repositories/Users/IUserExternalRepository.cs deleted file mode 100644 index 738f029..0000000 --- a/MyOffice.Data.Repositories/Users/IUserExternalRepository.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace MyOffice.Data.Repositories.Users; - -using Models.Users; - -public interface IUserExternalRepository -{ - int AddUserExternal(UserExternal external); - Task AddUserExternalAsync(UserExternal external, CancellationToken cancellationToken = default); - - Task> GetUserExternalsByUserIdAsync(Guid userId); - - Task GetByUserIdAsync(Guid userId, string provider); - UserExternal? GetByUserId(Guid userId, string provider); - - UserExternal? GetByExternalId(string externalId, string provider); - Task GetByExternalIdAsync(string externalId, string provider); - - void RemoveUserExternal(UserExternal userExternal); - Task RemoveUserExternalAsync(UserExternal userExternal, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/IUserRepository.cs b/MyOffice.Data.Repositories/Users/IUserRepository.cs deleted file mode 100644 index 9d47ac1..0000000 --- a/MyOffice.Data.Repositories/Users/IUserRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace MyOffice.Data.Repositories.Users; - -using MyOffice.Data.Models.Users; - -public interface IUserRepository -{ - Task GetUserAsync(Guid id); - User? GetUser(Guid id); - - Task GetByUserUserNameAsync(string userName); - User? GetByUserUserName(string userName); - - int AddUser(User user); - int UpdateUser(User user); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/UserExternalRepository.cs b/MyOffice.Data.Repositories/Users/UserExternalRepository.cs deleted file mode 100644 index 5fd1ad8..0000000 --- a/MyOffice.Data.Repositories/Users/UserExternalRepository.cs +++ /dev/null @@ -1,108 +0,0 @@ -namespace MyOffice.Data.Repositories.Users; - -using MyOffice.Data.Models.Users; -using Repositories; -using Microsoft.EntityFrameworkCore; -using MyOffice.DbContext; - -public class UserExternalRepository : AppRepository, IUserExternalRepository -{ - public UserExternalRepository(AppDbContext context) : base(context) - { - } - - public int AddUserExternal(UserExternal userExternal) - { - return AddBase(userExternal); - } - - public async Task AddUserExternalAsync(UserExternal userExternal, CancellationToken cancellationToken = default) - { - return await AddBaseAsync(userExternal, cancellationToken); - } - - public async Task AddUserExternalsAsync(IEnumerable claims) - { - _context.AddRange(claims); - return await SaveChangesAsync(); - } - - - public async Task> GetUserExternalsByUserNameAsync(string userName) - { - return await _context - .UserClaims - .Where(x => x.User.UserName == userName) - .Include(x => x.User) - .ToListAsync(); - } - - public async Task> GetUserExternalsByUserIdAsync(Guid userId) - { - return await _context - .UserClaims - .Where(x => x.UserId == userId) - .Include(x => x.User) - .ToListAsync(); - } - - public List GetUserExternalsByUser(Guid userId) - { - return _context - .UserClaims - .Where(x => x.UserId == userId) - .Include(x => x.User) - .ToList(); - } - - public List GetUserExternalsByUserName(string userName) - { - return _context - .UserClaims - .Where(x => x.User.UserName == userName) - .Include(x => x.User) - .ToList(); - } - - public async Task GetByUserIdAsync(Guid userId, string provider) - { - return await _context - .UserClaims - .Include(x => x.User) - .FirstOrDefaultAsync(x => x.UserId == userId && x.Provider == provider); - } - - public UserExternal? GetByUserId(Guid userId, string provider) - { - return _context - .UserClaims - .Include(x => x.User) - .FirstOrDefault(x => x.UserId == userId && x.Provider == provider); - } - - public UserExternal? GetByExternalId(string externalId, string provider) - { - return _context - .UserClaims - .Include(x => x.User) - .FirstOrDefault(x => x.ExternalId == externalId && x.Provider == provider); - } - - public Task GetByExternalIdAsync(string externalId, string provider) - { - return _context - .UserClaims - .Include(x => x.User) - .FirstOrDefaultAsync(x => x.ExternalId == externalId && x.Provider == provider); - } - - public void RemoveUserExternal(UserExternal userExternal) - { - RemoveBase(userExternal); - } - - public async Task RemoveUserExternalAsync(UserExternal userExternal, CancellationToken cancellationToken = default) - { - await RemoveBaseAsync(userExternal, cancellationToken); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/UserRepository.cs b/MyOffice.Data.Repositories/Users/UserRepository.cs deleted file mode 100644 index 76aae6b..0000000 --- a/MyOffice.Data.Repositories/Users/UserRepository.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace MyOffice.Data.Repositories.Users; - -using MyOffice.Data.Models.Users; -using Repositories; -using Microsoft.EntityFrameworkCore; -using MyOffice.DbContext; - -public class UserRepository : AppRepository, IUserRepository -{ - public UserRepository(AppDbContext context) : base(context) - { - } - - public async Task GetUserAsync(Guid id) - { - return await GetBaseAsync(id); - } - - public User? GetUser(Guid id) - { - return GetBase(id); - } - - public async Task GetByUserUserNameAsync(string userName) - { - return await _context.Users.FirstOrDefaultAsync(x => x.UserName == userName); - } - - public User? GetByUserUserName(string userName) - { - return _context.Users.FirstOrDefault(x => x.UserName == userName); - } - - public int AddUser(User user) - { - return AddBase(user); - } - - public int UpdateUser(User user) - { - return UpdateBase(user); - } -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Verifications/IVerificationCodeRepository.cs b/MyOffice.Data.Repositories/Verifications/IVerificationCodeRepository.cs deleted file mode 100644 index 4c07131..0000000 --- a/MyOffice.Data.Repositories/Verifications/IVerificationCodeRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using MyOffice.Data.Models.Verifications; - -namespace MyOffice.Data.Repositories.Item; - - -public interface IVerificationCodeRepository -{ - VerificationCode? GetByCode(string code); - bool Add(VerificationCode entity); - bool Update(VerificationCode entity); -} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Verifications/VerificationCodeRepository.cs b/MyOffice.Data.Repositories/Verifications/VerificationCodeRepository.cs deleted file mode 100644 index 796a8cd..0000000 --- a/MyOffice.Data.Repositories/Verifications/VerificationCodeRepository.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace MyOffice.Data.Repositories.Item; - -using Microsoft.EntityFrameworkCore; -using MyOffice.Data.Models.Verifications; -using MyOffice.DbContext; - -public class VerificationCodeRepository : AppRepository, IVerificationCodeRepository -{ - public VerificationCodeRepository(AppDbContext context) : base(context) - { - } - - public bool Add(VerificationCode entity) - { - return AddBase(entity) > 0; - } - - public bool Update(VerificationCode entity) - { - return UpdateBase(entity) > 0; - } - - public VerificationCode? GetByCode(string code) - { - return _context.Verifications.FirstOrDefault(x => x.Code == code); - } -} \ No newline at end of file diff --git a/MyOffice.DbContext/AppDbContext.cs b/MyOffice.DbContext/AppDbContext.cs deleted file mode 100644 index eb14445..0000000 --- a/MyOffice.DbContext/AppDbContext.cs +++ /dev/null @@ -1,335 +0,0 @@ -namespace MyOffice.DbContext; - -using Data.Models.Accounts; -using Data.Models.Currencies; -using Data.Models.Items; -using Microsoft.EntityFrameworkCore; -using Data.Models.Users; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.Data.Models.Verifications; -using MyOffice.Data.Models.Notifications; - -public enum AppDbContextProvidersEnum -{ - sqlite, - mssql, - npgsql -} - -public class AppDbContext : DbContext -{ - private readonly AppDbContextProvidersEnum _provider; - - private readonly Dictionary _noCaseCollation = new() - { - { AppDbContextProvidersEnum.sqlite, "NOCASE" }, - { AppDbContextProvidersEnum.npgsql, "my_ci_collation" } - }; - - public AppDbContext(AppDbContextProvidersEnum provider, DbContextOptions options) : base(options) - { - _provider = provider; - ConfigureChangeTracker(); - } - - public AppDbContext(DbContextOptions options, ConnectionConfiguration connection) : base(options) - { - _provider = Enum.Parse(connection.Provider, ignoreCase: true); - ConfigureChangeTracker(); - } - - private void ConfigureChangeTracker() - { - // Match historical repository behavior (manual EntityState updates). - ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; - ChangeTracker.AutoDetectChangesEnabled = false; - } - - public DbSet Users { get; set; } = null!; - public DbSet UserClaims { get; set; } = null!; - - public DbSet CurrencyGlobals { get; set; } = null!; - public DbSet Currencies { get; set; } = null!; - public DbSet CurrencyRates { get; set; } = null!; - public DbSet AccountCategories { get; set; } = null!; - public DbSet Accounts { get; set; } = null!; - public DbSet AccountAccountCategories { get; set; } = null!; - public DbSet AccountAccesses { get; set; } = null!; - public DbSet AccountAccessInvites { get; set; } = null!; - - public DbSet ItemCategories { get; set; } = null!; - public DbSet ItemGlobals { get; set; } = null!; - public DbSet Items { get; set; } = null!; - public DbSet Motions { get; set; } = null!; - - public DbSet Verifications { get; set; } = null!; - public DbSet EmailTemplates { get; set; } = null!; - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - var noCaseCollation = _noCaseCollation[_provider]; - - if (_provider == AppDbContextProvidersEnum.npgsql) - { - modelBuilder.HasCollation("my_ci_collation", "en-u-ks-primary", "icu", false); - } - - /* NOCASE PROPERTIES */ - modelBuilder.Entity() - .Property(x => x.UserName) - .UseCollation(noCaseCollation); - - modelBuilder.Entity() - .Property(x => x.Email) - .UseCollation(noCaseCollation); - - modelBuilder.Entity() - .Property(x => x.Provider) - .UseCollation(noCaseCollation); - - modelBuilder.Entity() - .Property(x => x.Email) - .UseCollation(noCaseCollation); - - - modelBuilder.Entity() - .HasOne(x => x.User) - .WithMany(x => x.UserClaims) - .HasForeignKey(x => x.UserId); - - UserCreating(modelBuilder); - CurrencyCreating(modelBuilder); - AccountCreating(modelBuilder); - MotionsCreating(modelBuilder); - VerificationsCreating(modelBuilder); - EmailTemplateCreating(modelBuilder); - - modelBuilder.UseOpenIddict(); - - base.OnModelCreating(modelBuilder); - } - - private void VerificationsCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.User) - .WithMany() - .HasForeignKey(x => x.UserId); - } - - private void EmailTemplateCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity() - .HasKey(x => x.Id); - } - - private void UserCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity() - .HasOne(x => x.Currency) - .WithMany() - .HasForeignKey(x => x.CurrencyId); - } - - private void CurrencyCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.CurrencyGlobal) - .WithMany(x => x.Currencies) - .HasForeignKey(x => x.CurrencyGlobalId); - - modelBuilder.Entity() - .HasOne(x => x.User) - .WithMany(x => x.Currencies) - .HasForeignKey(x => x.UserId); - - modelBuilder.Entity() - .HasOne(x => x.Currency) - .WithMany(x => x.Rates) - .HasForeignKey(x => x.CurrencyId); - - modelBuilder.Entity() - .HasOne(x => x.CurrentRate) - .WithMany(x => x.Currencies) - .HasForeignKey(x => x.CurrentRateId); - } - - private void AccountCreating(ModelBuilder modelBuilder) - { - #region Account - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.CurrencyGlobal) - .WithMany(x => x.Accounts) - .HasForeignKey(x => x.CurrencyGlobalId); - - modelBuilder.Entity() - .HasOne(x => x.Owner) - .WithMany(x => x.Accounts) - .HasForeignKey(x => x.OwnerId); - - #endregion Account - - #region AccountAccess - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.Account) - .WithMany(x => x.AccessRights) - .HasForeignKey(x => x.AccountId); - - modelBuilder.Entity() - .HasOne(x => x.User) - .WithMany(x => x.AccountAccess) - .HasForeignKey(x => x.UserId); - - modelBuilder.Entity() - .HasOne(x => x.Owner) - .WithMany(x => x.AccountAccessOwners) - .HasForeignKey(x => x.OwnerId); - - modelBuilder - .Entity() - .Property(d => d.Type) - .HasConversion(new EnumToStringConverter()); - - modelBuilder.Entity() - .HasIndex(p => new { p.AccountId, p.UserId }) - .IsUnique(); - - modelBuilder.Entity() - .HasIndex(p => new { p.AccountId, p.OwnerId }) - .IsUnique(); - - #endregion AccountAccess - - #region AccountAccessInvite - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.User) - .WithMany(x => x.AccountAccessInvites) - .HasForeignKey(x => x.UserId); - - modelBuilder.Entity() - .HasOne(x => x.Account) - .WithMany(x => x.Invites) - .HasForeignKey(x => x.AccountId); - - #endregion AccountAccessInvite - - #region Motion - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.Account) - .WithMany(x => x.Motions) - .HasForeignKey(x => x.AccountId); - - #endregion Motion - - #region AccountCategory - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.User) - .WithMany(x => x.AccountCategories) - .HasForeignKey(x => x.UserId); - - #endregion AccountCategory - - #region AccountAccountCategory - - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.Account) - .WithMany(x => x.Categories) - .HasForeignKey(x => x.AccountId); - - modelBuilder.Entity() - .HasOne(x => x.Category) - .WithMany(x => x.Accounts) - .HasForeignKey(x => x.CategoryId); - - modelBuilder.Entity() - .HasIndex(p => new { p.AccountId, p.CategoryId }) - .IsUnique(); - - modelBuilder.Entity() - .HasOne(x => x.Category) - .WithMany(x => x.Accounts) - .HasForeignKey(x => x.CategoryId); - - #endregion AccountAccountCategory - } - - private void MotionsCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity() - .HasKey(x => x.Id); - modelBuilder.Entity() - .HasKey(x => x.Id); - modelBuilder.Entity() - .HasKey(x => x.Id); - modelBuilder.Entity() - .HasKey(x => x.Id); - - modelBuilder.Entity() - .HasOne(x => x.User) - .WithMany(x => x.ItemCategories) - .HasForeignKey(x => x.UserId); - - modelBuilder.Entity() - .HasOne(x => x.Category) - .WithMany(x => x.Items) - .HasForeignKey(x => x.CategoryId); - - modelBuilder.Entity() - .HasOne(x => x.ItemGlobal) - .WithMany(x => x.Items) - .HasForeignKey(x => x.ItemGlobalId); - - modelBuilder.Entity() - .HasOne(x => x.Item) - .WithMany(x => x.Motions) - .HasForeignKey(x => x.ItemId); - - modelBuilder.Entity() - .HasOne(x => x.Account) - .WithMany(x => x.Motions) - .HasForeignKey(x => x.AccountId); - - modelBuilder.Entity() - .Property(x => x.AmountMinus) - .HasPrecision(18, 6); - - modelBuilder.Entity() - .Property(x => x.AmountPlus) - .HasPrecision(18, 6); - } -} \ No newline at end of file diff --git a/MyOffice.DbContext/AppDbContextFactory.cs b/MyOffice.DbContext/AppDbContextFactory.cs deleted file mode 100644 index 3362587..0000000 --- a/MyOffice.DbContext/AppDbContextFactory.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace MyOffice.DbContext; - -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; - -public class AppDbContextFactory : IDesignTimeDbContextFactory -{ - public static AppDbContextFactory Instance = new(); - - public AppDbContext CreateDbContext() - { - return CreateDbContext(null); - } - - public AppDbContext CreateDbContext(string[]? args) - { - var connection = RepositoryInitializer.ConnectionString; - if (connection is null) - { - connection = new ConnectionConfiguration( - args?[0] ?? "npgsql", - args?[1] ?? string.Empty); - } - - var builder = new DbContextOptionsBuilder(); - DbContextServiceCollectionExtensions.ConfigureDbContextOptions(builder, connection); - - if (!Enum.TryParse(connection?.Provider ?? args?[0] ?? "", ignoreCase: true, out var providerEnum)) - throw new InvalidOperationException($"No such provider: [{connection?.Provider}]"); - - var db = new AppDbContext(providerEnum, builder.Options); - db.ChangeTracker.AutoDetectChangesEnabled = false; - db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; - - return db; - } -} \ No newline at end of file diff --git a/MyOffice.DbContext/DatabaseBootstrapper.cs b/MyOffice.DbContext/DatabaseBootstrapper.cs deleted file mode 100644 index 9e27209..0000000 --- a/MyOffice.DbContext/DatabaseBootstrapper.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace MyOffice.DbContext; - -using Data.Models.Currencies; -using Microsoft.EntityFrameworkCore; - -/// -/// Migrate and seed using a DI-scoped (not the design-time factory). -/// -public static class DatabaseBootstrapper -{ - public static async Task InitializeAsync(AppDbContext db, CancellationToken cancellationToken = default) - { - await db.Database.MigrateAsync(cancellationToken); - await PrefillAsync(db, cancellationToken); - await DemoDataSeeder.SeedIfEmptyAsync(db, cancellationToken); - await UpdateCurrentRatesAsync(db, cancellationToken); - } - - private static async Task PrefillAsync(AppDbContext dbContext, CancellationToken cancellationToken) - { - var predefinedCurrencyGlobals = new List - { - new() { Id = CurrencyGlobalIdEnum.UAH.ToString(), DefaultQuantity = 1, Symbol = "₴", Name = "Ukrainian hryvnias" }, - new() { Id = CurrencyGlobalIdEnum.USD.ToString(), DefaultQuantity = 1, Symbol = "$", Name = "US Dollar" }, - new() { Id = CurrencyGlobalIdEnum.EUR.ToString(), DefaultQuantity = 1, Symbol = "€", Name = "Euros" }, - new() { Id = CurrencyGlobalIdEnum.GBP.ToString(), DefaultQuantity = 1, Symbol = "£", Name = "British pounds sterling" }, - new() { Id = CurrencyGlobalIdEnum.RUB.ToString(), DefaultQuantity = 10, Symbol = "₽", Name = "Russia Ruble" }, - new() { Id = CurrencyGlobalIdEnum.BTC.ToString(), DefaultQuantity = 10, Symbol = "btc", Name = "Bitcoin" }, - new() { Id = CurrencyGlobalIdEnum.ETH.ToString(), DefaultQuantity = 10, Symbol = "eth", Name = "Ethereum" }, - new() { Id = CurrencyGlobalIdEnum.TON.ToString(), DefaultQuantity = 10, Symbol = "ton", Name = "TON" }, - new() { Id = CurrencyGlobalIdEnum.OTHER.ToString(), DefaultQuantity = 1, Symbol = "", Name = "Other" }, - }; - - var currencyGlobals = await dbContext.CurrencyGlobals.ToListAsync(cancellationToken); - foreach (var predefined in predefinedCurrencyGlobals) - { - if (currencyGlobals.All(x => x.Id != predefined.Id)) - { - dbContext.CurrencyGlobals.Add(predefined); - } - } - - await dbContext.SaveChangesAsync(cancellationToken); - } - - private static async Task UpdateCurrentRatesAsync(AppDbContext dbContext, CancellationToken cancellationToken) - { - var lastRates = await dbContext.CurrencyRates - .Include(x => x.Currency) - .GroupBy(x => new { x.CurrencyId }, - (key, g) => g.Where(x => x.DateTime <= DateTime.UtcNow).OrderByDescending(x => x.DateTime).First()) - .ToListAsync(cancellationToken); - - var currencies = await dbContext.Currencies.ToListAsync(cancellationToken); - foreach (var currency in currencies) - { - var rate = lastRates.FirstOrDefault(x => x.CurrencyId == currency.Id); - if (rate != null) - { - currency.CurrentRateId = rate.Id; - dbContext.Attach(currency).State = EntityState.Modified; - } - } - - await dbContext.SaveChangesAsync(cancellationToken); - } -} diff --git a/MyOffice.DbContext/DbContextServiceCollectionExtensions.cs b/MyOffice.DbContext/DbContextServiceCollectionExtensions.cs deleted file mode 100644 index 42e111c..0000000 --- a/MyOffice.DbContext/DbContextServiceCollectionExtensions.cs +++ /dev/null @@ -1,50 +0,0 @@ -namespace MyOffice.DbContext; - -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; - -public static class DbContextServiceCollectionExtensions -{ - public static IServiceCollection AddAppDbContext( - this IServiceCollection services, - ConnectionConfiguration connection - ) - { - services.AddSingleton(connection); - - services.AddDbContext((_, options) => - { - ConfigureDbContextOptions(options, connection); - }); - - return services; - } - - public static void ConfigureDbContextOptions( - DbContextOptionsBuilder options, - ConnectionConfiguration connection - ) - { - if (!Enum.TryParse(connection.Provider, ignoreCase: true, out var provider)) - throw new InvalidOperationException($"No such provider: [{connection.Provider}]"); - - switch (provider) - { - case AppDbContextProvidersEnum.npgsql: - options.UseNpgsql(connection.ConnectionString, x => - x.MigrationsAssembly("MyOffice.Migrations.Postgres")); - break; - case AppDbContextProvidersEnum.sqlite: - options.UseSqlite(connection.ConnectionString, x => - x.MigrationsAssembly("MyOffice.Migrations.Sqlite")); - break; - default: - throw new NotSupportedException($"No such provider: [{connection.Provider}]"); - } - -#if DEBUG - options.EnableSensitiveDataLogging(); - options.EnableDetailedErrors(); -#endif - } -} diff --git a/MyOffice.DbContext/DemoDataSeeder.cs b/MyOffice.DbContext/DemoDataSeeder.cs deleted file mode 100644 index bfc9b06..0000000 --- a/MyOffice.DbContext/DemoDataSeeder.cs +++ /dev/null @@ -1,292 +0,0 @@ -namespace MyOffice.DbContext; - -using Data.Models.Accounts; -using Data.Models.Currencies; -using Data.Models.Items; -using Data.Models.Users; -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; - -/// -/// Fills an empty database with three demo users (UAH/USD/EUR) and sample catalog data. -/// -public static class DemoDataSeeder -{ - private static readonly PasswordHasher PasswordHasher = new(); - - private static readonly string[] CurrencyCodes = ["UAH", "USD", "EUR"]; - - private static readonly (string Code, string Email, string Password, string FirstName)[] Users = - [ - ("UAH", "user_UAH@user_UAH.userUAH", "user_UAH", "User UAH"), - ("USD", "user_USD@user_USD.userUSD", "user_USD", "User USD"), - ("EUR", "user_EUR@user_EUR.userEUR", "user_EUR", "User EUR"), - ]; - - /// 1 USD = 42 UAH, 1 EUR = 50 UAH. - private const decimal UsdInUah = 42m; - private const decimal EurInUah = 50m; - - public static async Task SeedIfEmptyAsync(AppDbContext db, CancellationToken cancellationToken = default) - { - if (await db.Users.AnyAsync(cancellationToken)) - { - return; - } - - // AppDbContext defaults to NoTracking; seeding needs identity values and graph inserts. - var previousTracking = db.ChangeTracker.QueryTrackingBehavior; - var previousDetect = db.ChangeTracker.AutoDetectChangesEnabled; - db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll; - db.ChangeTracker.AutoDetectChangesEnabled = true; - - try - { - var yearStart = new DateTime(DateTime.UtcNow.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc); - var rng = new Random(2026); - - foreach (var (code, email, password, firstName) in Users) - { - await SeedUserAsync(db, code, email, password, firstName, yearStart, rng, cancellationToken); - } - - await db.SaveChangesAsync(cancellationToken); - } - finally - { - db.ChangeTracker.QueryTrackingBehavior = previousTracking; - db.ChangeTracker.AutoDetectChangesEnabled = previousDetect; - db.ChangeTracker.Clear(); - } - } - - private static async Task SeedUserAsync( - AppDbContext db, - string homeCurrency, - string email, - string password, - string firstName, - DateTime rateDate, - Random rng, - CancellationToken cancellationToken) - { - var ua = homeCurrency == "UAH"; - var userId = Guid.NewGuid(); - - var user = new User - { - Id = userId, - UserName = email, - Email = email, - PasswordHash = PasswordHasher.HashPassword(new object(), password), - FirstName = firstName, - FullName = firstName, - IsEmailConfirmed = true, - CurrencyId = homeCurrency, - }; - db.Users.Add(user); - - var currencies = new Dictionary(StringComparer.Ordinal); - foreach (var code in CurrencyCodes) - { - var currency = new Currency - { - Id = Guid.NewGuid(), - UserId = userId, - CurrencyGlobalId = code, - Name = CurrencyDisplayName(code, ua), - ShortName = code, - IsPrimary = code == homeCurrency, - }; - db.Currencies.Add(currency); - db.CurrencyRates.Add(new CurrencyRate - { - CurrencyId = currency.Id, - DateTime = rateDate, - Quantity = 1, - Rate = RateInHome(code, homeCurrency), - }); - currencies[code] = currency; - } - - // UnCategorized convention: category Id == user Id - db.ItemCategories.Add(new ItemCategory - { - Id = userId, - UserId = userId, - Name = ua ? "Без категорії" : "UnCategorized", - Items = [], - IsInternal = true, - }); - - var accountCategoryDefs = ua - ? new (string Key, string Name)[] { ("CASH", "Готівка"), ("BANK", "Банк"), ("DEPOSIT", "Депозит") } - : [("CASH", "CASH"), ("BANK", "BANK"), ("DEPOSIT", "DEPOSIT")]; - - var accounts = new List(); - foreach (var (key, name) in accountCategoryDefs) - { - var category = new AccountCategory - { - Id = Guid.NewGuid(), - UserId = userId, - Name = name, - }; - db.AccountCategories.Add(category); - - foreach (var code in CurrencyCodes) - { - var account = new Account - { - Id = Guid.NewGuid(), - OwnerId = userId, - CurrencyGlobalId = code, - Name = $"{name} {code}", - }; - db.Accounts.Add(account); - db.AccountAccountCategories.Add(new AccountAccountCategory - { - AccountId = account.Id, - CategoryId = category.Id, - }); - db.AccountAccesses.Add(new AccountAccess - { - AccountId = account.Id, - UserId = userId, - OwnerId = userId, - IsAllowRead = true, - IsAllowWrite = true, - IsAllowManage = true, - Type = AccountAccessTypeEnum.balance, - }); - accounts.Add(account); - } - } - - var incomeCategory = new ItemCategory - { - Id = Guid.NewGuid(), - UserId = userId, - Name = ua ? "Доходи" : "INCOME", - Items = [], - }; - var outcomeCategory = new ItemCategory - { - Id = Guid.NewGuid(), - UserId = userId, - Name = ua ? "Витрати" : "OUTCOME", - Items = [], - }; - db.ItemCategories.AddRange(incomeCategory, outcomeCategory); - - var incomeNames = ua - ? new[] { "Готівка", "Офіс" } - : ["CASH", "OFFICE"]; - var outcomeNames = ua - ? new[] - { - "Товари", "Бензин", "Steam", "Продукти", "Кафе", - "Оренда", "Комунальні", "Інтернет", "Зв'язок", "Розваги", - } - : [ - "Goods", "Petrol", "Steam", "Groceries", "Cafe", - "Rent", "Utilities", "Internet", "Mobile", "Entertainment", - ]; - - var incomeItems = await AddItemsAsync(db, incomeCategory.Id, incomeNames, cancellationToken); - var outcomeItems = await AddItemsAsync(db, outcomeCategory.Id, outcomeNames, cancellationToken); - - await db.SaveChangesAsync(cancellationToken); - - SeedMotions(db, accounts, incomeItems, outcomeItems, rng, count: 100); - } - - private static async Task> AddItemsAsync( - AppDbContext db, - Guid categoryId, - IEnumerable names, - CancellationToken cancellationToken) - { - var items = new List(); - foreach (var name in names) - { - var global = db.ItemGlobals.Local.FirstOrDefault(x => x.Name == name) - ?? await db.ItemGlobals.FirstOrDefaultAsync(x => x.Name == name, cancellationToken); - if (global == null) - { - global = new ItemGlobal { Id = Guid.NewGuid(), Name = name }; - db.ItemGlobals.Add(global); - } - - var item = new Item - { - CategoryId = categoryId, - ItemGlobalId = global.Id, - }; - db.Items.Add(item); - items.Add(item); - } - - return items; - } - - private static void SeedMotions( - AppDbContext db, - List accounts, - List incomeItems, - List outcomeItems, - Random rng, - int count) - { - var now = DateTime.UtcNow; - var from = now.AddMonths(-3); - - for (var i = 0; i < count; i++) - { - var isIncome = rng.Next(2) == 0; - var item = isIncome - ? incomeItems[rng.Next(incomeItems.Count)] - : outcomeItems[rng.Next(outcomeItems.Count)]; - var account = accounts[rng.Next(accounts.Count)]; - var days = (now - from).TotalDays; - var when = from.AddDays(rng.NextDouble() * days); - var amount = Math.Round((decimal)(rng.NextDouble() * (isIncome ? 4500 : 700) + (isIncome ? 200 : 20)), 2); - - db.Motions.Add(new Motion - { - Id = Guid.NewGuid(), - AccountId = account.Id, - ItemId = item.Id, - DateTime = when, - CreatedOn = when, - Description = isIncome ? "Demo income" : "Demo expense", - AmountPlus = isIncome ? amount : 0, - AmountMinus = isIncome ? 0 : amount, - }); - } - } - - private static decimal RateInHome(string currencyCode, string homeCurrency) - { - static decimal InUah(string code) => code switch - { - "UAH" => 1m, - "USD" => UsdInUah, - "EUR" => EurInUah, - _ => 1m, - }; - - return InUah(currencyCode) / InUah(homeCurrency); - } - - private static string CurrencyDisplayName(string code, bool ua) => (code, ua) switch - { - ("UAH", true) => "Гривня", - ("USD", true) => "Долар США", - ("EUR", true) => "Євро", - ("UAH", _) => "Ukrainian hryvnia", - ("USD", _) => "US Dollar", - ("EUR", _) => "Euro", - _ => code, - }; -} diff --git a/MyOffice.DbContext/MyOffice.DbContext.csproj b/MyOffice.DbContext/MyOffice.DbContext.csproj deleted file mode 100644 index b7225cb..0000000 --- a/MyOffice.DbContext/MyOffice.DbContext.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - diff --git a/MyOffice.DbContext/RepositoryInitializer.cs b/MyOffice.DbContext/RepositoryInitializer.cs deleted file mode 100644 index 868d5a9..0000000 --- a/MyOffice.DbContext/RepositoryInitializer.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace MyOffice.DbContext; - -using Microsoft.Extensions.DependencyInjection; - -public record ConnectionConfiguration(string Provider, string ConnectionString); - -public static class RepositoryInitializer -{ - /// - /// Registers DbContext DI. Migrate/seed runs via DatabaseInitializerHostedService. - /// remains for design-time . - /// - public static void Initialize( - IServiceCollection services, - ConnectionConfiguration connectionString - ) - { - ConnectionString = connectionString; - services.AddAppDbContext(connectionString); - } - - public static ConnectionConfiguration ConnectionString { get; internal set; } = null!; -} diff --git a/MyOffice.Migration.Postgres/AppDbContextFactoryPostgres.cs b/MyOffice.Migration.Postgres/AppDbContextFactoryPostgres.cs deleted file mode 100644 index 93d1748..0000000 --- a/MyOffice.Migration.Postgres/AppDbContextFactoryPostgres.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace MyOffice.Migrations.Postgres; - -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; -using Microsoft.Extensions.Configuration; -using MyOffice.DbContext; -using MyOffice.Shared; - -public class AppDbContextFactoryPostgres : IDesignTimeDbContextFactory -{ - public AppDbContext CreateDbContext(string[]? args) - { - var builder = new DbContextOptionsBuilder(); - - var sharedConfiguration = SharedConfiguration.Build(); - var connectionString = - args?.FirstOrDefault() - ?? sharedConfiguration.GetConnectionString("npgsql"); - - builder.UseNpgsql(connectionString, b => b.MigrationsAssembly("MyOffice.Migrations.Postgres")); - - var db = new AppDbContext(AppDbContextProvidersEnum.npgsql, builder.Options); - db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; - - return db; - } -} \ No newline at end of file diff --git a/MyOffice.Migration.Postgres/Migrations/20230621190024_Init.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230621190024_Init.Designer.cs deleted file mode 100644 index 2c41f26..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230621190024_Init.Designer.cs +++ /dev/null @@ -1,608 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230621190024_Init")] - partial class Init - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Motions.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.Item", b => - { - b.HasOne("MyOffice.Data.Models.Motions.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Motions.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230621190024_Init.cs b/MyOffice.Migration.Postgres/Migrations/20230621190024_Init.cs deleted file mode 100644 index 47a3398..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230621190024_Init.cs +++ /dev/null @@ -1,445 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class Init : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterDatabase() - .Annotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False"); - - migrationBuilder.CreateTable( - name: "CurrencyGlobals", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - Name = table.Column(type: "text", nullable: false), - Symbol = table.Column(type: "text", nullable: false), - DefaultQuantity = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CurrencyGlobals", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "ItemGlobals", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - Name = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ItemGlobals", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Accounts", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - CurrencyGlobalId = table.Column(type: "text", nullable: false), - Name = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Accounts", x => x.Id); - table.ForeignKey( - name: "FK_Accounts_CurrencyGlobals_CurrencyGlobalId", - column: x => x.CurrencyGlobalId, - principalTable: "CurrencyGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Users", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - UserName = table.Column(type: "text", nullable: false, collation: "my_ci_collation"), - Email = table.Column(type: "text", nullable: false, collation: "my_ci_collation"), - PasswordHash = table.Column(type: "text", nullable: false), - FirstName = table.Column(type: "text", nullable: true), - LastName = table.Column(type: "text", nullable: true), - FullName = table.Column(type: "text", nullable: true), - Phone = table.Column(type: "text", nullable: true), - IsEmailConfirmed = table.Column(type: "boolean", nullable: false), - CurrencyId = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Users", x => x.Id); - table.ForeignKey( - name: "FK_Users_CurrencyGlobals_CurrencyId", - column: x => x.CurrencyId, - principalTable: "CurrencyGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AccountAccesses", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - AccountId = table.Column(type: "uuid", nullable: false), - UserId = table.Column(type: "uuid", nullable: false), - IsAllowRead = table.Column(type: "boolean", nullable: false), - IsAllowWrite = table.Column(type: "boolean", nullable: false), - IsAllowManage = table.Column(type: "boolean", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountAccesses", x => x.Id); - table.ForeignKey( - name: "FK_AccountAccesses_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AccountAccesses_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AccountCategories", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - UserId = table.Column(type: "uuid", nullable: false), - Name = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountCategories", x => x.Id); - table.ForeignKey( - name: "FK_AccountCategories_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Currencies", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - CurrencyGlobalId = table.Column(type: "text", nullable: false), - UserId = table.Column(type: "uuid", nullable: false), - Name = table.Column(type: "text", nullable: false), - ShortName = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Currencies", x => x.Id); - table.ForeignKey( - name: "FK_Currencies_CurrencyGlobals_CurrencyGlobalId", - column: x => x.CurrencyGlobalId, - principalTable: "CurrencyGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Currencies_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "ItemCategories", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - UserId = table.Column(type: "uuid", nullable: false), - Name = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ItemCategories", x => x.Id); - table.ForeignKey( - name: "FK_ItemCategories_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "UserClaims", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - CreatedOn = table.Column(type: "timestamp with time zone", nullable: false), - UserId = table.Column(type: "uuid", nullable: false), - ExternalId = table.Column(type: "text", nullable: false), - Email = table.Column(type: "text", nullable: false, collation: "my_ci_collation"), - Provider = table.Column(type: "text", nullable: false, collation: "my_ci_collation") - }, - constraints: table => - { - table.PrimaryKey("PK_UserClaims", x => x.Id); - table.ForeignKey( - name: "FK_UserClaims_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AccountAccountCategories", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - AccountId = table.Column(type: "uuid", nullable: false), - CategoryId = table.Column(type: "uuid", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountAccountCategories", x => x.Id); - table.ForeignKey( - name: "FK_AccountAccountCategories_AccountCategories_CategoryId", - column: x => x.CategoryId, - principalTable: "AccountCategories", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AccountAccountCategories_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "CurrencyRates", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - CurrencyId = table.Column(type: "uuid", nullable: false), - DateTime = table.Column(type: "timestamp with time zone", nullable: false), - Quantity = table.Column(type: "integer", nullable: false), - Rate = table.Column(type: "numeric", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CurrencyRates", x => x.Id); - table.ForeignKey( - name: "FK_CurrencyRates_Currencies_CurrencyId", - column: x => x.CurrencyId, - principalTable: "Currencies", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Items", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - CategoryId = table.Column(type: "uuid", nullable: false), - ItemGlobalId = table.Column(type: "uuid", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Items", x => x.Id); - table.ForeignKey( - name: "FK_Items_ItemCategories_CategoryId", - column: x => x.CategoryId, - principalTable: "ItemCategories", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Items_ItemGlobals_ItemGlobalId", - column: x => x.ItemGlobalId, - principalTable: "ItemGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Motions", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - CreatedOn = table.Column(type: "timestamp with time zone", nullable: false), - DateTime = table.Column(type: "timestamp with time zone", nullable: false), - AccountId = table.Column(type: "uuid", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - Description = table.Column(type: "text", nullable: true), - AmountPlus = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false), - AmountMinus = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false), - UserId = table.Column(type: "uuid", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Motions", x => x.Id); - table.ForeignKey( - name: "FK_Motions_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Motions_Items_ItemId", - column: x => x.ItemId, - principalTable: "Items", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Motions_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id"); - }); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_AccountId", - table: "AccountAccesses", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_UserId", - table: "AccountAccesses", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccountCategories_AccountId", - table: "AccountAccountCategories", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccountCategories_CategoryId", - table: "AccountAccountCategories", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountCategories_UserId", - table: "AccountCategories", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_CurrencyGlobalId", - table: "Accounts", - column: "CurrencyGlobalId"); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_CurrencyGlobalId", - table: "Currencies", - column: "CurrencyGlobalId"); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_UserId", - table: "Currencies", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_CurrencyRates_CurrencyId", - table: "CurrencyRates", - column: "CurrencyId"); - - migrationBuilder.CreateIndex( - name: "IX_ItemCategories_UserId", - table: "ItemCategories", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Items_CategoryId", - table: "Items", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_Items_ItemGlobalId", - table: "Items", - column: "ItemGlobalId"); - - migrationBuilder.CreateIndex( - name: "IX_Motions_AccountId", - table: "Motions", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_Motions_ItemId", - table: "Motions", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_Motions_UserId", - table: "Motions", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_UserClaims_UserId", - table: "UserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Users_CurrencyId", - table: "Users", - column: "CurrencyId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AccountAccesses"); - - migrationBuilder.DropTable( - name: "AccountAccountCategories"); - - migrationBuilder.DropTable( - name: "CurrencyRates"); - - migrationBuilder.DropTable( - name: "Motions"); - - migrationBuilder.DropTable( - name: "UserClaims"); - - migrationBuilder.DropTable( - name: "AccountCategories"); - - migrationBuilder.DropTable( - name: "Currencies"); - - migrationBuilder.DropTable( - name: "Accounts"); - - migrationBuilder.DropTable( - name: "Items"); - - migrationBuilder.DropTable( - name: "ItemCategories"); - - migrationBuilder.DropTable( - name: "ItemGlobals"); - - migrationBuilder.DropTable( - name: "Users"); - - migrationBuilder.DropTable( - name: "CurrencyGlobals"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230627044606_IsInternal.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230627044606_IsInternal.Designer.cs deleted file mode 100644 index 529060a..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230627044606_IsInternal.Designer.cs +++ /dev/null @@ -1,611 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230627044606_IsInternal")] - partial class IsInternal - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230627044606_IsInternal.cs b/MyOffice.Migration.Postgres/Migrations/20230627044606_IsInternal.cs deleted file mode 100644 index 65fe3c4..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230627044606_IsInternal.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class IsInternal : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "IsInternal", - table: "ItemCategories", - type: "boolean", - nullable: false, - defaultValue: false); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "IsInternal", - table: "ItemCategories"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230720190103_PrimaryCurrencyDeletedMotion.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230720190103_PrimaryCurrencyDeletedMotion.Designer.cs deleted file mode 100644 index 5a7e7a5..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230720190103_PrimaryCurrencyDeletedMotion.Designer.cs +++ /dev/null @@ -1,617 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230720190103_PrimaryCurrencyDeletedMotion")] - partial class PrimaryCurrencyDeletedMotion - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230720190103_PrimaryCurrencyDeletedMotion.cs b/MyOffice.Migration.Postgres/Migrations/20230720190103_PrimaryCurrencyDeletedMotion.cs deleted file mode 100644 index 8dbcb2d..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230720190103_PrimaryCurrencyDeletedMotion.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class PrimaryCurrencyDeletedMotion : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "DeletedOn", - table: "Motions", - type: "timestamp with time zone", - nullable: true); - - migrationBuilder.AddColumn( - name: "IsPrimary", - table: "Currencies", - type: "boolean", - nullable: false, - defaultValue: false); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "DeletedOn", - table: "Motions"); - - migrationBuilder.DropColumn( - name: "IsPrimary", - table: "Currencies"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721175243_CurrentRate.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230721175243_CurrentRate.Designer.cs deleted file mode 100644 index 70a3adf..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721175243_CurrentRate.Designer.cs +++ /dev/null @@ -1,631 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230721175243_CurrentRate")] - partial class CurrentRate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("CurrentRateId1") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId1"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany() - .HasForeignKey("CurrentRateId1"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721175243_CurrentRate.cs b/MyOffice.Migration.Postgres/Migrations/20230721175243_CurrentRate.cs deleted file mode 100644 index c7aef90..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721175243_CurrentRate.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class CurrentRate : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "CurrentRateId", - table: "Currencies", - type: "integer", - nullable: true); - - migrationBuilder.AddColumn( - name: "CurrentRateId1", - table: "Currencies", - type: "integer", - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_CurrentRateId1", - table: "Currencies", - column: "CurrentRateId1"); - - migrationBuilder.AddForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId1", - table: "Currencies", - column: "CurrentRateId1", - principalTable: "CurrencyRates", - principalColumn: "Id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId1", - table: "Currencies"); - - migrationBuilder.DropIndex( - name: "IX_Currencies_CurrentRateId1", - table: "Currencies"); - - migrationBuilder.DropColumn( - name: "CurrentRateId", - table: "Currencies"); - - migrationBuilder.DropColumn( - name: "CurrentRateId1", - table: "Currencies"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721180304_CurrentRateRemove.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230721180304_CurrentRateRemove.Designer.cs deleted file mode 100644 index 71d3381..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721180304_CurrentRateRemove.Designer.cs +++ /dev/null @@ -1,617 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230721180304_CurrentRateRemove")] - partial class CurrentRateRemove - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721180304_CurrentRateRemove.cs b/MyOffice.Migration.Postgres/Migrations/20230721180304_CurrentRateRemove.cs deleted file mode 100644 index 30b99ec..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721180304_CurrentRateRemove.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class CurrentRateRemove : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId1", - table: "Currencies"); - - migrationBuilder.DropIndex( - name: "IX_Currencies_CurrentRateId1", - table: "Currencies"); - - migrationBuilder.DropColumn( - name: "CurrentRateId", - table: "Currencies"); - - migrationBuilder.DropColumn( - name: "CurrentRateId1", - table: "Currencies"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "CurrentRateId", - table: "Currencies", - type: "integer", - nullable: true); - - migrationBuilder.AddColumn( - name: "CurrentRateId1", - table: "Currencies", - type: "integer", - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_CurrentRateId1", - table: "Currencies", - column: "CurrentRateId1"); - - migrationBuilder.AddForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId1", - table: "Currencies", - column: "CurrentRateId1", - principalTable: "CurrencyRates", - principalColumn: "Id"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721180851_CurrentRateV2.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230721180851_CurrentRateV2.Designer.cs deleted file mode 100644 index aa4d8f7..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721180851_CurrentRateV2.Designer.cs +++ /dev/null @@ -1,633 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230721180851_CurrentRateV2")] - partial class CurrentRateV2 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721180851_CurrentRateV2.cs b/MyOffice.Migration.Postgres/Migrations/20230721180851_CurrentRateV2.cs deleted file mode 100644 index e7bb75c..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721180851_CurrentRateV2.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class CurrentRateV2 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "CurrentRateId", - table: "Currencies", - type: "integer", - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_CurrentRateId", - table: "Currencies", - column: "CurrentRateId"); - - migrationBuilder.AddForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId", - table: "Currencies", - column: "CurrentRateId", - principalTable: "CurrencyRates", - principalColumn: "Id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId", - table: "Currencies"); - - migrationBuilder.DropIndex( - name: "IX_Currencies_CurrentRateId", - table: "Currencies"); - - migrationBuilder.DropColumn( - name: "CurrentRateId", - table: "Currencies"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721200424_AccountType.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230721200424_AccountType.Designer.cs deleted file mode 100644 index af69953..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721200424_AccountType.Designer.cs +++ /dev/null @@ -1,636 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230721200424_AccountType")] - partial class AccountType - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Type") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230721200424_AccountType.cs b/MyOffice.Migration.Postgres/Migrations/20230721200424_AccountType.cs deleted file mode 100644 index c29a649..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230721200424_AccountType.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccountType : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Type", - table: "Accounts", - type: "integer", - nullable: false, - defaultValue: 0); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Type", - table: "Accounts"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230722051335_AccountType2.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230722051335_AccountType2.Designer.cs deleted file mode 100644 index 2c92520..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230722051335_AccountType2.Designer.cs +++ /dev/null @@ -1,637 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230722051335_AccountType2")] - partial class AccountType2 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230722051335_AccountType2.cs b/MyOffice.Migration.Postgres/Migrations/20230722051335_AccountType2.cs deleted file mode 100644 index 09ff120..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230722051335_AccountType2.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccountType2 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Type", - table: "AccountAccesses", - type: "text", - nullable: false, - defaultValue: ""); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Type", - table: "AccountAccesses"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230722052053_AccountOwner.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230722052053_AccountOwner.Designer.cs deleted file mode 100644 index d81cbe5..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230722052053_AccountOwner.Designer.cs +++ /dev/null @@ -1,650 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230722052053_AccountOwner")] - partial class AccountOwner - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230722052053_AccountOwner.cs b/MyOffice.Migration.Postgres/Migrations/20230722052053_AccountOwner.cs deleted file mode 100644 index 277a90e..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230722052053_AccountOwner.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccountOwner : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "OwnerId", - table: "Accounts", - type: "uuid", - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_OwnerId", - table: "Accounts", - column: "OwnerId"); - - migrationBuilder.AddForeignKey( - name: "FK_Accounts_Users_OwnerId", - table: "Accounts", - column: "OwnerId", - principalTable: "Users", - principalColumn: "Id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Accounts_Users_OwnerId", - table: "Accounts"); - - migrationBuilder.DropIndex( - name: "IX_Accounts_OwnerId", - table: "Accounts"); - - migrationBuilder.DropColumn( - name: "OwnerId", - table: "Accounts"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230725054028_Collation.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230725054028_Collation.Designer.cs deleted file mode 100644 index b92d8a3..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230725054028_Collation.Designer.cs +++ /dev/null @@ -1,652 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230725054028_Collation")] - partial class Collation - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230725054028_Collation.cs b/MyOffice.Migration.Postgres/Migrations/20230725054028_Collation.cs deleted file mode 100644 index 7b07646..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230725054028_Collation.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class Collation : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Name", - table: "ItemGlobals", - type: "text", - nullable: false, - collation: "my_ci_collation", - oldClrType: typeof(string), - oldType: "text"); - - migrationBuilder.AlterColumn( - name: "Name", - table: "Accounts", - type: "text", - nullable: false, - collation: "my_ci_collation", - oldClrType: typeof(string), - oldType: "text"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Name", - table: "ItemGlobals", - type: "text", - nullable: false, - oldClrType: typeof(string), - oldType: "text", - oldCollation: "my_ci_collation"); - - migrationBuilder.AlterColumn( - name: "Name", - table: "Accounts", - type: "text", - nullable: false, - oldClrType: typeof(string), - oldType: "text", - oldCollation: "my_ci_collation"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230725061203_CollationR.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230725061203_CollationR.Designer.cs deleted file mode 100644 index 5bbd3dd..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230725061203_CollationR.Designer.cs +++ /dev/null @@ -1,651 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230725061203_CollationR")] - partial class CollationR - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230725061203_CollationR.cs b/MyOffice.Migration.Postgres/Migrations/20230725061203_CollationR.cs deleted file mode 100644 index ce688f3..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230725061203_CollationR.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class CollationR : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Name", - table: "Accounts", - type: "text", - nullable: false, - oldClrType: typeof(string), - oldType: "text", - oldCollation: "my_ci_collation"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Name", - table: "Accounts", - type: "text", - nullable: false, - collation: "my_ci_collation", - oldClrType: typeof(string), - oldType: "text"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230725061910_CollationR2.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230725061910_CollationR2.Designer.cs deleted file mode 100644 index f45afe7..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230725061910_CollationR2.Designer.cs +++ /dev/null @@ -1,650 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230725061910_CollationR2")] - partial class CollationR2 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230725061910_CollationR2.cs b/MyOffice.Migration.Postgres/Migrations/20230725061910_CollationR2.cs deleted file mode 100644 index d544478..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230725061910_CollationR2.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class CollationR2 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Name", - table: "ItemGlobals", - type: "text", - nullable: false, - oldClrType: typeof(string), - oldType: "text", - oldCollation: "my_ci_collation"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Name", - table: "ItemGlobals", - type: "text", - nullable: false, - collation: "my_ci_collation", - oldClrType: typeof(string), - oldType: "text"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230726160638_AccessOwner.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230726160638_AccessOwner.Designer.cs deleted file mode 100644 index 4e0b046..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230726160638_AccessOwner.Designer.cs +++ /dev/null @@ -1,663 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230726160638_AccessOwner")] - partial class AccessOwner - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230726160638_AccessOwner.cs b/MyOffice.Migration.Postgres/Migrations/20230726160638_AccessOwner.cs deleted file mode 100644 index 5b12a91..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230726160638_AccessOwner.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccessOwner : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "OwnerId", - table: "AccountAccesses", - type: "uuid", - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_OwnerId", - table: "AccountAccesses", - column: "OwnerId"); - - migrationBuilder.AddForeignKey( - name: "FK_AccountAccesses_Users_OwnerId", - table: "AccountAccesses", - column: "OwnerId", - principalTable: "Users", - principalColumn: "Id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_AccountAccesses_Users_OwnerId", - table: "AccountAccesses"); - - migrationBuilder.DropIndex( - name: "IX_AccountAccesses_OwnerId", - table: "AccountAccesses"); - - migrationBuilder.DropColumn( - name: "OwnerId", - table: "AccountAccesses"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230726161226_AccessOwner2.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230726161226_AccessOwner2.Designer.cs deleted file mode 100644 index 0615901..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230726161226_AccessOwner2.Designer.cs +++ /dev/null @@ -1,665 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230726161226_AccessOwner2")] - partial class AccessOwner2 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230726161226_AccessOwner2.cs b/MyOffice.Migration.Postgres/Migrations/20230726161226_AccessOwner2.cs deleted file mode 100644 index 457656b..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230726161226_AccessOwner2.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccessOwner2 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_AccountAccesses_Users_OwnerId", - table: "AccountAccesses"); - - migrationBuilder.AlterColumn( - name: "OwnerId", - table: "AccountAccesses", - type: "uuid", - nullable: false, - defaultValue: new Guid("00000000-0000-0000-0000-000000000000"), - oldClrType: typeof(Guid), - oldType: "uuid", - oldNullable: true); - - migrationBuilder.AddForeignKey( - name: "FK_AccountAccesses_Users_OwnerId", - table: "AccountAccesses", - column: "OwnerId", - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_AccountAccesses_Users_OwnerId", - table: "AccountAccesses"); - - migrationBuilder.AlterColumn( - name: "OwnerId", - table: "AccountAccesses", - type: "uuid", - nullable: true, - oldClrType: typeof(Guid), - oldType: "uuid"); - - migrationBuilder.AddForeignKey( - name: "FK_AccountAccesses_Users_OwnerId", - table: "AccountAccesses", - column: "OwnerId", - principalTable: "Users", - principalColumn: "Id"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230728172249_AccountAccessInvites.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230728172249_AccountAccessInvites.Designer.cs deleted file mode 100644 index a5d9362..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230728172249_AccountAccessInvites.Designer.cs +++ /dev/null @@ -1,695 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230728172249_AccountAccessInvites")] - partial class AccountAccessInvites - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230728172249_AccountAccessInvites.cs b/MyOffice.Migration.Postgres/Migrations/20230728172249_AccountAccessInvites.cs deleted file mode 100644 index 46bed99..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230728172249_AccountAccessInvites.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccountAccessInvites : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Name", - table: "AccountAccesses", - type: "text", - nullable: true); - - migrationBuilder.CreateTable( - name: "AccountAccessInvites", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - CreatedOn = table.Column(type: "timestamp with time zone", nullable: false), - AcceptedOn = table.Column(type: "timestamp with time zone", nullable: true), - RejectedOn = table.Column(type: "timestamp with time zone", nullable: true), - Email = table.Column(type: "text", nullable: false), - IsAllowWrite = table.Column(type: "boolean", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountAccessInvites", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AccountAccessInvites"); - - migrationBuilder.DropColumn( - name: "Name", - table: "AccountAccesses"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230728181916_AccountAccessInvites2.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230728181916_AccountAccessInvites2.Designer.cs deleted file mode 100644 index 247cc3b..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230728181916_AccountAccessInvites2.Designer.cs +++ /dev/null @@ -1,713 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230728181916_AccountAccessInvites2")] - partial class AccountAccessInvites2 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230728181916_AccountAccessInvites2.cs b/MyOffice.Migration.Postgres/Migrations/20230728181916_AccountAccessInvites2.cs deleted file mode 100644 index 30b2752..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230728181916_AccountAccessInvites2.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccountAccessInvites2 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "UserId", - table: "AccountAccessInvites", - type: "uuid", - nullable: false, - defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccessInvites_UserId", - table: "AccountAccessInvites", - column: "UserId"); - - migrationBuilder.AddForeignKey( - name: "FK_AccountAccessInvites_Users_UserId", - table: "AccountAccessInvites", - column: "UserId", - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_AccountAccessInvites_Users_UserId", - table: "AccountAccessInvites"); - - migrationBuilder.DropIndex( - name: "IX_AccountAccessInvites_UserId", - table: "AccountAccessInvites"); - - migrationBuilder.DropColumn( - name: "UserId", - table: "AccountAccessInvites"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230728192017_AccountAccessInvites3.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230728192017_AccountAccessInvites3.Designer.cs deleted file mode 100644 index 4574f4d..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230728192017_AccountAccessInvites3.Designer.cs +++ /dev/null @@ -1,728 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230728192017_AccountAccessInvites3")] - partial class AccountAccessInvites3 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230728192017_AccountAccessInvites3.cs b/MyOffice.Migration.Postgres/Migrations/20230728192017_AccountAccessInvites3.cs deleted file mode 100644 index 7f22a0c..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230728192017_AccountAccessInvites3.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccountAccessInvites3 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "AccountId", - table: "AccountAccessInvites", - type: "uuid", - nullable: false, - defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccessInvites_AccountId", - table: "AccountAccessInvites", - column: "AccountId"); - - migrationBuilder.AddForeignKey( - name: "FK_AccountAccessInvites_Accounts_AccountId", - table: "AccountAccessInvites", - column: "AccountId", - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_AccountAccessInvites_Accounts_AccountId", - table: "AccountAccessInvites"); - - migrationBuilder.DropIndex( - name: "IX_AccountAccessInvites_AccountId", - table: "AccountAccessInvites"); - - migrationBuilder.DropColumn( - name: "AccountId", - table: "AccountAccessInvites"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230804145453_AccountAccesUnique.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230804145453_AccountAccesUnique.Designer.cs deleted file mode 100644 index 2015f55..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230804145453_AccountAccesUnique.Designer.cs +++ /dev/null @@ -1,729 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20230804145453_AccountAccesUnique")] - partial class AccountAccesUnique - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("CategoryId"); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20230804145453_AccountAccesUnique.cs b/MyOffice.Migration.Postgres/Migrations/20230804145453_AccountAccesUnique.cs deleted file mode 100644 index 7b3f55d..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20230804145453_AccountAccesUnique.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class AccountAccesUnique : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - name: "IX_AccountAccesses_AccountId", - table: "AccountAccesses"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_AccountId_UserId", - table: "AccountAccesses", - columns: new[] { "AccountId", "UserId" }, - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - name: "IX_AccountAccesses_AccountId_UserId", - table: "AccountAccesses"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_AccountId", - table: "AccountAccesses", - column: "AccountId"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20231217163807_acc_cat_unique.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20231217163807_acc_cat_unique.Designer.cs deleted file mode 100644 index 445508f..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20231217163807_acc_cat_unique.Designer.cs +++ /dev/null @@ -1,730 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20231217163807_acc_cat_unique")] - partial class acccatunique - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20231217163807_acc_cat_unique.cs b/MyOffice.Migration.Postgres/Migrations/20231217163807_acc_cat_unique.cs deleted file mode 100644 index fe91a77..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20231217163807_acc_cat_unique.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class acccatunique : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - name: "IX_AccountAccountCategories_AccountId", - table: "AccountAccountCategories"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccountCategories_AccountId_CategoryId", - table: "AccountAccountCategories", - columns: new[] { "AccountId", "CategoryId" }, - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - name: "IX_AccountAccountCategories_AccountId_CategoryId", - table: "AccountAccountCategories"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccountCategories_AccountId", - table: "AccountAccountCategories", - column: "AccountId"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20231217185452_acc_access_unique.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20231217185452_acc_access_unique.Designer.cs deleted file mode 100644 index 86bbaf1..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20231217185452_acc_access_unique.Designer.cs +++ /dev/null @@ -1,733 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20231217185452_acc_access_unique")] - partial class accaccessunique - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "OwnerId") - .IsUnique(); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20231217185452_acc_access_unique.cs b/MyOffice.Migration.Postgres/Migrations/20231217185452_acc_access_unique.cs deleted file mode 100644 index ef3eb44..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20231217185452_acc_access_unique.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class accaccessunique : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_AccountId_OwnerId", - table: "AccountAccesses", - columns: new[] { "AccountId", "OwnerId" }, - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - name: "IX_AccountAccesses_AccountId_OwnerId", - table: "AccountAccesses"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20240107073407_VerificationCode.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20240107073407_VerificationCode.Designer.cs deleted file mode 100644 index 57a8887..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20240107073407_VerificationCode.Designer.cs +++ /dev/null @@ -1,790 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20240107073407_VerificationCode")] - partial class VerificationCode - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "OwnerId") - .IsUnique(); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Code") - .IsRequired() - .HasColumnType("text"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Destination") - .IsRequired() - .HasColumnType("text"); - - b.Property("DestinationType") - .IsRequired() - .HasColumnType("text"); - - b.Property("ExpiresOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Metadata") - .HasColumnType("text"); - - b.Property("Template") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.Property("VerifiedOn") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("Verifications"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20240107073407_VerificationCode.cs b/MyOffice.Migration.Postgres/Migrations/20240107073407_VerificationCode.cs deleted file mode 100644 index 0dfbe47..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20240107073407_VerificationCode.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class VerificationCode : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Verifications", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - UserId = table.Column(type: "uuid", nullable: false), - Code = table.Column(type: "text", nullable: false), - DestinationType = table.Column(type: "text", nullable: false), - Destination = table.Column(type: "text", nullable: false), - CreatedOn = table.Column(type: "timestamp with time zone", nullable: false), - ExpiresOn = table.Column(type: "timestamp with time zone", nullable: false), - VerifiedOn = table.Column(type: "timestamp with time zone", nullable: true), - Template = table.Column(type: "text", nullable: false), - Metadata = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Verifications", x => x.Id); - table.ForeignKey( - name: "FK_Verifications_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_Verifications_UserId", - table: "Verifications", - column: "UserId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Verifications"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20240107075033_VerificationCode2.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20240107075033_VerificationCode2.Designer.cs deleted file mode 100644 index afd56e5..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20240107075033_VerificationCode2.Designer.cs +++ /dev/null @@ -1,790 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20240107075033_VerificationCode2")] - partial class VerificationCode2 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "7.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "OwnerId") - .IsUnique(); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Code") - .IsRequired() - .HasColumnType("text"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Destination") - .IsRequired() - .HasColumnType("text"); - - b.Property("DestinationType") - .IsRequired() - .HasColumnType("text"); - - b.Property("ExpiresOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Metadata") - .HasColumnType("text"); - - b.Property("Template") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.Property("VerifiedOn") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("Verifications"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20240107075033_VerificationCode2.cs b/MyOffice.Migration.Postgres/Migrations/20240107075033_VerificationCode2.cs deleted file mode 100644 index 05f4374..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20240107075033_VerificationCode2.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class VerificationCode2 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20260717093113_OpenIddict.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20260717093113_OpenIddict.Designer.cs deleted file mode 100644 index 91858ec..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20260717093113_OpenIddict.Designer.cs +++ /dev/null @@ -1,1067 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20260717093113_OpenIddict")] - partial class OpenIddict - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "10.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "OwnerId") - .IsUnique(); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Notifications.EmailTemplate", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .IsRequired() - .HasColumnType("text"); - - b.Property("Sender") - .IsRequired() - .HasColumnType("text"); - - b.Property("SenderName") - .IsRequired() - .HasColumnType("text"); - - b.Property("Subject") - .IsRequired() - .HasColumnType("text"); - - b.Property("Template") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("EmailTemplates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Code") - .IsRequired() - .HasColumnType("text"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Destination") - .IsRequired() - .HasColumnType("text"); - - b.Property("DestinationType") - .IsRequired() - .HasColumnType("text"); - - b.Property("ExpiresOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Metadata") - .HasColumnType("text"); - - b.Property("Template") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.Property("VerifiedOn") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("Verifications"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ClientId") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("ClientSecret") - .HasColumnType("text"); - - b.Property("ClientType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ConsentType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("DisplayName") - .HasColumnType("text"); - - b.Property("DisplayNames") - .HasColumnType("text"); - - b.Property("JsonWebKeySet") - .HasColumnType("text"); - - b.Property("Permissions") - .HasColumnType("text"); - - b.Property("PostLogoutRedirectUris") - .HasColumnType("text"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("RedirectUris") - .HasColumnType("text"); - - b.Property("Requirements") - .HasColumnType("text"); - - b.Property("Settings") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("ClientId") - .IsUnique(); - - b.ToTable("OpenIddictApplications", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationId") - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("Scopes") - .HasColumnType("text"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("character varying(400)"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictAuthorizations", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreScope", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Descriptions") - .HasColumnType("text"); - - b.Property("DisplayName") - .HasColumnType("text"); - - b.Property("DisplayNames") - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("Resources") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("OpenIddictScopes", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationId") - .HasColumnType("text"); - - b.Property("AuthorizationId") - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpirationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Payload") - .HasColumnType("text"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("RedemptionDate") - .HasColumnType("timestamp with time zone"); - - b.Property("ReferenceId") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("character varying(400)"); - - b.Property("Type") - .HasMaxLength(150) - .HasColumnType("character varying(150)"); - - b.HasKey("Id"); - - b.HasIndex("AuthorizationId"); - - b.HasIndex("ReferenceId") - .IsUnique(); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictTokens", (string)null); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Authorizations") - .HasForeignKey("ApplicationId"); - - b.Navigation("Application"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Tokens") - .HasForeignKey("ApplicationId"); - - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", "Authorization") - .WithMany("Tokens") - .HasForeignKey("AuthorizationId"); - - b.Navigation("Application"); - - b.Navigation("Authorization"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Navigation("Authorizations"); - - b.Navigation("Tokens"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Navigation("Tokens"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/20260717093113_OpenIddict.cs b/MyOffice.Migration.Postgres/Migrations/20260717093113_OpenIddict.cs deleted file mode 100644 index 684ef30..0000000 --- a/MyOffice.Migration.Postgres/Migrations/20260717093113_OpenIddict.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - /// - public partial class OpenIddict : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "EmailTemplates", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - CreatedOn = table.Column(type: "timestamp with time zone", nullable: false), - Description = table.Column(type: "text", nullable: false), - Subject = table.Column(type: "text", nullable: false), - Sender = table.Column(type: "text", nullable: false), - SenderName = table.Column(type: "text", nullable: false), - Template = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_EmailTemplates", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictApplications", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - ApplicationType = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - ClientId = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - ClientSecret = table.Column(type: "text", nullable: true), - ClientType = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - ConcurrencyToken = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - ConsentType = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - DisplayName = table.Column(type: "text", nullable: true), - DisplayNames = table.Column(type: "text", nullable: true), - JsonWebKeySet = table.Column(type: "text", nullable: true), - Permissions = table.Column(type: "text", nullable: true), - PostLogoutRedirectUris = table.Column(type: "text", nullable: true), - Properties = table.Column(type: "text", nullable: true), - RedirectUris = table.Column(type: "text", nullable: true), - Requirements = table.Column(type: "text", nullable: true), - Settings = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictApplications", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictScopes", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - ConcurrencyToken = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - Description = table.Column(type: "text", nullable: true), - Descriptions = table.Column(type: "text", nullable: true), - DisplayName = table.Column(type: "text", nullable: true), - DisplayNames = table.Column(type: "text", nullable: true), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - Properties = table.Column(type: "text", nullable: true), - Resources = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictScopes", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictAuthorizations", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - ApplicationId = table.Column(type: "text", nullable: true), - ConcurrencyToken = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - CreationDate = table.Column(type: "timestamp with time zone", nullable: true), - Properties = table.Column(type: "text", nullable: true), - Scopes = table.Column(type: "text", nullable: true), - Status = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - Subject = table.Column(type: "character varying(400)", maxLength: 400, nullable: true), - Type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictAuthorizations", x => x.Id); - table.ForeignKey( - name: "FK_OpenIddictAuthorizations_OpenIddictApplications_Application~", - column: x => x.ApplicationId, - principalTable: "OpenIddictApplications", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictTokens", - columns: table => new - { - Id = table.Column(type: "text", nullable: false), - ApplicationId = table.Column(type: "text", nullable: true), - AuthorizationId = table.Column(type: "text", nullable: true), - ConcurrencyToken = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - CreationDate = table.Column(type: "timestamp with time zone", nullable: true), - ExpirationDate = table.Column(type: "timestamp with time zone", nullable: true), - Payload = table.Column(type: "text", nullable: true), - Properties = table.Column(type: "text", nullable: true), - RedemptionDate = table.Column(type: "timestamp with time zone", nullable: true), - ReferenceId = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - Status = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - Subject = table.Column(type: "character varying(400)", maxLength: 400, nullable: true), - Type = table.Column(type: "character varying(150)", maxLength: 150, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictTokens", x => x.Id); - table.ForeignKey( - name: "FK_OpenIddictTokens_OpenIddictApplications_ApplicationId", - column: x => x.ApplicationId, - principalTable: "OpenIddictApplications", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_OpenIddictTokens_OpenIddictAuthorizations_AuthorizationId", - column: x => x.AuthorizationId, - principalTable: "OpenIddictAuthorizations", - principalColumn: "Id"); - }); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictApplications_ClientId", - table: "OpenIddictApplications", - column: "ClientId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictAuthorizations_ApplicationId_Status_Subject_Type", - table: "OpenIddictAuthorizations", - columns: new[] { "ApplicationId", "Status", "Subject", "Type" }); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictScopes_Name", - table: "OpenIddictScopes", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictTokens_ApplicationId_Status_Subject_Type", - table: "OpenIddictTokens", - columns: new[] { "ApplicationId", "Status", "Subject", "Type" }); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictTokens_AuthorizationId", - table: "OpenIddictTokens", - column: "AuthorizationId"); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictTokens_ReferenceId", - table: "OpenIddictTokens", - column: "ReferenceId", - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "EmailTemplates"); - - migrationBuilder.DropTable( - name: "OpenIddictScopes"); - - migrationBuilder.DropTable( - name: "OpenIddictTokens"); - - migrationBuilder.DropTable( - name: "OpenIddictAuthorizations"); - - migrationBuilder.DropTable( - name: "OpenIddictApplications"); - } - } -} diff --git a/MyOffice.Migration.Postgres/Migrations/AppDbContextModelSnapshot.cs b/MyOffice.Migration.Postgres/Migrations/AppDbContextModelSnapshot.cs deleted file mode 100644 index 7ffe0d0..0000000 --- a/MyOffice.Migration.Postgres/Migrations/AppDbContextModelSnapshot.cs +++ /dev/null @@ -1,1064 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace MyOffice.Migrations.Postgres.Migrations -{ - [DbContext(typeof(AppDbContext))] - partial class AppDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") - .HasAnnotation("ProductVersion", "10.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("IsAllowManage") - .HasColumnType("boolean"); - - b.Property("IsAllowRead") - .HasColumnType("boolean"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("OwnerId") - .HasColumnType("uuid"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "OwnerId") - .IsUnique(); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AcceptedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("IsAllowWrite") - .HasColumnType("boolean"); - - b.Property("RejectedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountId") - .HasColumnType("uuid"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("CurrentRateId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("DefaultQuantity") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CurrencyId") - .HasColumnType("uuid"); - - b.Property("DateTime") - .HasColumnType("timestamp with time zone"); - - b.Property("Quantity") - .HasColumnType("integer"); - - b.Property("Rate") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CategoryId") - .HasColumnType("uuid"); - - b.Property("ItemGlobalId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("IsInternal") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Notifications.EmailTemplate", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .IsRequired() - .HasColumnType("text"); - - b.Property("Sender") - .IsRequired() - .HasColumnType("text"); - - b.Property("SenderName") - .IsRequired() - .HasColumnType("text"); - - b.Property("Subject") - .IsRequired() - .HasColumnType("text"); - - b.Property("Template") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("EmailTemplates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("FirstName") - .HasColumnType("text"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("IsEmailConfirmed") - .HasColumnType("boolean"); - - b.Property("LastName") - .HasColumnType("text"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("text"); - - b.Property("Phone") - .HasColumnType("text"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("text") - .UseCollation("my_ci_collation"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Code") - .IsRequired() - .HasColumnType("text"); - - b.Property("CreatedOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Destination") - .IsRequired() - .HasColumnType("text"); - - b.Property("DestinationType") - .IsRequired() - .HasColumnType("text"); - - b.Property("ExpiresOn") - .HasColumnType("timestamp with time zone"); - - b.Property("Metadata") - .HasColumnType("text"); - - b.Property("Template") - .IsRequired() - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("uuid"); - - b.Property("VerifiedOn") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("Verifications"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ClientId") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("ClientSecret") - .HasColumnType("text"); - - b.Property("ClientType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ConsentType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("DisplayName") - .HasColumnType("text"); - - b.Property("DisplayNames") - .HasColumnType("text"); - - b.Property("JsonWebKeySet") - .HasColumnType("text"); - - b.Property("Permissions") - .HasColumnType("text"); - - b.Property("PostLogoutRedirectUris") - .HasColumnType("text"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("RedirectUris") - .HasColumnType("text"); - - b.Property("Requirements") - .HasColumnType("text"); - - b.Property("Settings") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("ClientId") - .IsUnique(); - - b.ToTable("OpenIddictApplications", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationId") - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("Scopes") - .HasColumnType("text"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("character varying(400)"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictAuthorizations", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreScope", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Descriptions") - .HasColumnType("text"); - - b.Property("DisplayName") - .HasColumnType("text"); - - b.Property("DisplayNames") - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("Resources") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("OpenIddictScopes", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationId") - .HasColumnType("text"); - - b.Property("AuthorizationId") - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpirationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Payload") - .HasColumnType("text"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("RedemptionDate") - .HasColumnType("timestamp with time zone"); - - b.Property("ReferenceId") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("character varying(400)"); - - b.Property("Type") - .HasMaxLength(150) - .HasColumnType("character varying(150)"); - - b.HasKey("Id"); - - b.HasIndex("AuthorizationId"); - - b.HasIndex("ReferenceId") - .IsUnique(); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictTokens", (string)null); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Authorizations") - .HasForeignKey("ApplicationId"); - - b.Navigation("Application"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Tokens") - .HasForeignKey("ApplicationId"); - - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", "Authorization") - .WithMany("Tokens") - .HasForeignKey("AuthorizationId"); - - b.Navigation("Application"); - - b.Navigation("Authorization"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Navigation("Authorizations"); - - b.Navigation("Tokens"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Navigation("Tokens"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Postgres/MyOffice.Migrations.Postgres.csproj b/MyOffice.Migration.Postgres/MyOffice.Migrations.Postgres.csproj deleted file mode 100644 index 23915d8..0000000 --- a/MyOffice.Migration.Postgres/MyOffice.Migrations.Postgres.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net10.0 - enable - enable - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - diff --git a/MyOffice.Migration.Sqlite/AppDbContextFactorySqlite.cs b/MyOffice.Migration.Sqlite/AppDbContextFactorySqlite.cs deleted file mode 100644 index 47d8c45..0000000 --- a/MyOffice.Migration.Sqlite/AppDbContextFactorySqlite.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace MyOffice.Migrations.Sqlite; - -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; -using Microsoft.Extensions.Configuration; -using MyOffice.DbContext; -using MyOffice.Shared; - -public class AppDbContextFactorySqlite : IDesignTimeDbContextFactory -{ - public AppDbContext CreateDbContext(string[]? args) - { - var builder = new DbContextOptionsBuilder(); - - var sharedConfiguration = SharedConfiguration.Build(); - var connectionString = - args?.FirstOrDefault() - ?? sharedConfiguration.GetConnectionString("sqlite"); - - builder.UseSqlite(connectionString, b => b.MigrationsAssembly("MyOffice.Migrations.Sqlite")); - - var db = new AppDbContext(AppDbContextProvidersEnum.sqlite, builder.Options); - db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; - - return db; - } -} \ No newline at end of file diff --git a/MyOffice.Migration.Sqlite/Migrations/20260717093158_OpenIddict.Designer.cs b/MyOffice.Migration.Sqlite/Migrations/20260717093158_OpenIddict.Designer.cs deleted file mode 100644 index 2074f6a..0000000 --- a/MyOffice.Migration.Sqlite/Migrations/20260717093158_OpenIddict.Designer.cs +++ /dev/null @@ -1,1049 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; - -#nullable disable - -namespace MyOffice.Migrations.Sqlite.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20260717093158_OpenIddict")] - partial class OpenIddict - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "10.0.10"); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("OwnerId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("IsAllowManage") - .HasColumnType("INTEGER"); - - b.Property("IsAllowRead") - .HasColumnType("INTEGER"); - - b.Property("IsAllowWrite") - .HasColumnType("INTEGER"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("OwnerId") - .HasColumnType("TEXT"); - - b.Property("Type") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "OwnerId") - .IsUnique(); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("AcceptedOn") - .HasColumnType("TEXT"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("IsAllowWrite") - .HasColumnType("INTEGER"); - - b.Property("RejectedOn") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("CategoryId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("TEXT"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("DateTime") - .HasColumnType("TEXT"); - - b.Property("DeletedOn") - .HasColumnType("TEXT"); - - b.Property("Description") - .HasColumnType("TEXT"); - - b.Property("ItemId") - .HasColumnType("INTEGER"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("CurrentRateId") - .HasColumnType("INTEGER"); - - b.Property("IsPrimary") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("DefaultQuantity") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CurrencyId") - .HasColumnType("TEXT"); - - b.Property("DateTime") - .HasColumnType("TEXT"); - - b.Property("Quantity") - .HasColumnType("INTEGER"); - - b.Property("Rate") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CategoryId") - .HasColumnType("TEXT"); - - b.Property("ItemGlobalId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("IsInternal") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Notifications.EmailTemplate", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Description") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Sender") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("SenderName") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Subject") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Template") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("EmailTemplates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.Property("FirstName") - .HasColumnType("TEXT"); - - b.Property("FullName") - .HasColumnType("TEXT"); - - b.Property("IsEmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LastName") - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Phone") - .HasColumnType("TEXT"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Code") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Destination") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("DestinationType") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("ExpiresOn") - .HasColumnType("TEXT"); - - b.Property("Metadata") - .HasColumnType("TEXT"); - - b.Property("Template") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.Property("VerifiedOn") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("Verifications"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ApplicationType") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("ClientId") - .HasMaxLength(100) - .HasColumnType("TEXT"); - - b.Property("ClientSecret") - .HasColumnType("TEXT"); - - b.Property("ClientType") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("ConsentType") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("DisplayName") - .HasColumnType("TEXT"); - - b.Property("DisplayNames") - .HasColumnType("TEXT"); - - b.Property("JsonWebKeySet") - .HasColumnType("TEXT"); - - b.Property("Permissions") - .HasColumnType("TEXT"); - - b.Property("PostLogoutRedirectUris") - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("RedirectUris") - .HasColumnType("TEXT"); - - b.Property("Requirements") - .HasColumnType("TEXT"); - - b.Property("Settings") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("ClientId") - .IsUnique(); - - b.ToTable("OpenIddictApplications", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ApplicationId") - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("CreationDate") - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("Scopes") - .HasColumnType("TEXT"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("TEXT"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictAuthorizations", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreScope", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("Description") - .HasColumnType("TEXT"); - - b.Property("Descriptions") - .HasColumnType("TEXT"); - - b.Property("DisplayName") - .HasColumnType("TEXT"); - - b.Property("DisplayNames") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("Resources") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("OpenIddictScopes", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ApplicationId") - .HasColumnType("TEXT"); - - b.Property("AuthorizationId") - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("CreationDate") - .HasColumnType("TEXT"); - - b.Property("ExpirationDate") - .HasColumnType("TEXT"); - - b.Property("Payload") - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("RedemptionDate") - .HasColumnType("TEXT"); - - b.Property("ReferenceId") - .HasMaxLength(100) - .HasColumnType("TEXT"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("TEXT"); - - b.Property("Type") - .HasMaxLength(150) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AuthorizationId"); - - b.HasIndex("ReferenceId") - .IsUnique(); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictTokens", (string)null); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Authorizations") - .HasForeignKey("ApplicationId"); - - b.Navigation("Application"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Tokens") - .HasForeignKey("ApplicationId"); - - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", "Authorization") - .WithMany("Tokens") - .HasForeignKey("AuthorizationId"); - - b.Navigation("Application"); - - b.Navigation("Authorization"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Navigation("Authorizations"); - - b.Navigation("Tokens"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Navigation("Tokens"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Sqlite/Migrations/20260717093158_OpenIddict.cs b/MyOffice.Migration.Sqlite/Migrations/20260717093158_OpenIddict.cs deleted file mode 100644 index a014ddc..0000000 --- a/MyOffice.Migration.Sqlite/Migrations/20260717093158_OpenIddict.cs +++ /dev/null @@ -1,747 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace MyOffice.Migrations.Sqlite.Migrations -{ - /// - public partial class OpenIddict : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "CurrencyGlobals", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - Name = table.Column(type: "TEXT", nullable: false), - Symbol = table.Column(type: "TEXT", nullable: false), - DefaultQuantity = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CurrencyGlobals", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "EmailTemplates", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - CreatedOn = table.Column(type: "TEXT", nullable: false), - Description = table.Column(type: "TEXT", nullable: false), - Subject = table.Column(type: "TEXT", nullable: false), - Sender = table.Column(type: "TEXT", nullable: false), - SenderName = table.Column(type: "TEXT", nullable: false), - Template = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_EmailTemplates", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "ItemGlobals", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - Name = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ItemGlobals", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictApplications", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - ApplicationType = table.Column(type: "TEXT", maxLength: 50, nullable: true), - ClientId = table.Column(type: "TEXT", maxLength: 100, nullable: true), - ClientSecret = table.Column(type: "TEXT", nullable: true), - ClientType = table.Column(type: "TEXT", maxLength: 50, nullable: true), - ConcurrencyToken = table.Column(type: "TEXT", maxLength: 50, nullable: true), - ConsentType = table.Column(type: "TEXT", maxLength: 50, nullable: true), - DisplayName = table.Column(type: "TEXT", nullable: true), - DisplayNames = table.Column(type: "TEXT", nullable: true), - JsonWebKeySet = table.Column(type: "TEXT", nullable: true), - Permissions = table.Column(type: "TEXT", nullable: true), - PostLogoutRedirectUris = table.Column(type: "TEXT", nullable: true), - Properties = table.Column(type: "TEXT", nullable: true), - RedirectUris = table.Column(type: "TEXT", nullable: true), - Requirements = table.Column(type: "TEXT", nullable: true), - Settings = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictApplications", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictScopes", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - ConcurrencyToken = table.Column(type: "TEXT", maxLength: 50, nullable: true), - Description = table.Column(type: "TEXT", nullable: true), - Descriptions = table.Column(type: "TEXT", nullable: true), - DisplayName = table.Column(type: "TEXT", nullable: true), - DisplayNames = table.Column(type: "TEXT", nullable: true), - Name = table.Column(type: "TEXT", maxLength: 200, nullable: true), - Properties = table.Column(type: "TEXT", nullable: true), - Resources = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictScopes", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Users", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - UserName = table.Column(type: "TEXT", nullable: false, collation: "NOCASE"), - Email = table.Column(type: "TEXT", nullable: false, collation: "NOCASE"), - PasswordHash = table.Column(type: "TEXT", nullable: false), - FirstName = table.Column(type: "TEXT", nullable: true), - LastName = table.Column(type: "TEXT", nullable: true), - FullName = table.Column(type: "TEXT", nullable: true), - Phone = table.Column(type: "TEXT", nullable: true), - IsEmailConfirmed = table.Column(type: "INTEGER", nullable: false), - CurrencyId = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Users", x => x.Id); - table.ForeignKey( - name: "FK_Users_CurrencyGlobals_CurrencyId", - column: x => x.CurrencyId, - principalTable: "CurrencyGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictAuthorizations", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - ApplicationId = table.Column(type: "TEXT", nullable: true), - ConcurrencyToken = table.Column(type: "TEXT", maxLength: 50, nullable: true), - CreationDate = table.Column(type: "TEXT", nullable: true), - Properties = table.Column(type: "TEXT", nullable: true), - Scopes = table.Column(type: "TEXT", nullable: true), - Status = table.Column(type: "TEXT", maxLength: 50, nullable: true), - Subject = table.Column(type: "TEXT", maxLength: 400, nullable: true), - Type = table.Column(type: "TEXT", maxLength: 50, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictAuthorizations", x => x.Id); - table.ForeignKey( - name: "FK_OpenIddictAuthorizations_OpenIddictApplications_ApplicationId", - column: x => x.ApplicationId, - principalTable: "OpenIddictApplications", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "AccountCategories", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - UserId = table.Column(type: "TEXT", nullable: false), - Name = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountCategories", x => x.Id); - table.ForeignKey( - name: "FK_AccountCategories_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Accounts", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - CurrencyGlobalId = table.Column(type: "TEXT", nullable: false), - OwnerId = table.Column(type: "TEXT", nullable: true), - Name = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Accounts", x => x.Id); - table.ForeignKey( - name: "FK_Accounts_CurrencyGlobals_CurrencyGlobalId", - column: x => x.CurrencyGlobalId, - principalTable: "CurrencyGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Accounts_Users_OwnerId", - column: x => x.OwnerId, - principalTable: "Users", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "ItemCategories", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - UserId = table.Column(type: "TEXT", nullable: false), - Name = table.Column(type: "TEXT", nullable: false), - IsInternal = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ItemCategories", x => x.Id); - table.ForeignKey( - name: "FK_ItemCategories_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "UserClaims", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CreatedOn = table.Column(type: "TEXT", nullable: false), - UserId = table.Column(type: "TEXT", nullable: false), - ExternalId = table.Column(type: "TEXT", nullable: false), - Email = table.Column(type: "TEXT", nullable: false, collation: "NOCASE"), - Provider = table.Column(type: "TEXT", nullable: false, collation: "NOCASE") - }, - constraints: table => - { - table.PrimaryKey("PK_UserClaims", x => x.Id); - table.ForeignKey( - name: "FK_UserClaims_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Verifications", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - UserId = table.Column(type: "TEXT", nullable: false), - Code = table.Column(type: "TEXT", nullable: false), - DestinationType = table.Column(type: "TEXT", nullable: false), - Destination = table.Column(type: "TEXT", nullable: false), - CreatedOn = table.Column(type: "TEXT", nullable: false), - ExpiresOn = table.Column(type: "TEXT", nullable: false), - VerifiedOn = table.Column(type: "TEXT", nullable: true), - Template = table.Column(type: "TEXT", nullable: false), - Metadata = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Verifications", x => x.Id); - table.ForeignKey( - name: "FK_Verifications_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "OpenIddictTokens", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - ApplicationId = table.Column(type: "TEXT", nullable: true), - AuthorizationId = table.Column(type: "TEXT", nullable: true), - ConcurrencyToken = table.Column(type: "TEXT", maxLength: 50, nullable: true), - CreationDate = table.Column(type: "TEXT", nullable: true), - ExpirationDate = table.Column(type: "TEXT", nullable: true), - Payload = table.Column(type: "TEXT", nullable: true), - Properties = table.Column(type: "TEXT", nullable: true), - RedemptionDate = table.Column(type: "TEXT", nullable: true), - ReferenceId = table.Column(type: "TEXT", maxLength: 100, nullable: true), - Status = table.Column(type: "TEXT", maxLength: 50, nullable: true), - Subject = table.Column(type: "TEXT", maxLength: 400, nullable: true), - Type = table.Column(type: "TEXT", maxLength: 150, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OpenIddictTokens", x => x.Id); - table.ForeignKey( - name: "FK_OpenIddictTokens_OpenIddictApplications_ApplicationId", - column: x => x.ApplicationId, - principalTable: "OpenIddictApplications", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_OpenIddictTokens_OpenIddictAuthorizations_AuthorizationId", - column: x => x.AuthorizationId, - principalTable: "OpenIddictAuthorizations", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "AccountAccesses", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - AccountId = table.Column(type: "TEXT", nullable: false), - UserId = table.Column(type: "TEXT", nullable: false), - OwnerId = table.Column(type: "TEXT", nullable: false), - IsAllowRead = table.Column(type: "INTEGER", nullable: false), - IsAllowWrite = table.Column(type: "INTEGER", nullable: false), - IsAllowManage = table.Column(type: "INTEGER", nullable: false), - Type = table.Column(type: "TEXT", nullable: false), - Name = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountAccesses", x => x.Id); - table.ForeignKey( - name: "FK_AccountAccesses_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AccountAccesses_Users_OwnerId", - column: x => x.OwnerId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AccountAccesses_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AccountAccessInvites", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - UserId = table.Column(type: "TEXT", nullable: false), - AccountId = table.Column(type: "TEXT", nullable: false), - CreatedOn = table.Column(type: "TEXT", nullable: false), - AcceptedOn = table.Column(type: "TEXT", nullable: true), - RejectedOn = table.Column(type: "TEXT", nullable: true), - Email = table.Column(type: "TEXT", nullable: false), - IsAllowWrite = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountAccessInvites", x => x.Id); - table.ForeignKey( - name: "FK_AccountAccessInvites_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AccountAccessInvites_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AccountAccountCategories", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - AccountId = table.Column(type: "TEXT", nullable: false), - CategoryId = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountAccountCategories", x => x.Id); - table.ForeignKey( - name: "FK_AccountAccountCategories_AccountCategories_CategoryId", - column: x => x.CategoryId, - principalTable: "AccountCategories", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AccountAccountCategories_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Items", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CategoryId = table.Column(type: "TEXT", nullable: false), - ItemGlobalId = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Items", x => x.Id); - table.ForeignKey( - name: "FK_Items_ItemCategories_CategoryId", - column: x => x.CategoryId, - principalTable: "ItemCategories", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Items_ItemGlobals_ItemGlobalId", - column: x => x.ItemGlobalId, - principalTable: "ItemGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Motions", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - CreatedOn = table.Column(type: "TEXT", nullable: false), - DateTime = table.Column(type: "TEXT", nullable: false), - AccountId = table.Column(type: "TEXT", nullable: false), - ItemId = table.Column(type: "INTEGER", nullable: false), - Description = table.Column(type: "TEXT", nullable: true), - AmountPlus = table.Column(type: "TEXT", precision: 18, scale: 6, nullable: false), - AmountMinus = table.Column(type: "TEXT", precision: 18, scale: 6, nullable: false), - DeletedOn = table.Column(type: "TEXT", nullable: true), - UserId = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Motions", x => x.Id); - table.ForeignKey( - name: "FK_Motions_Accounts_AccountId", - column: x => x.AccountId, - principalTable: "Accounts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Motions_Items_ItemId", - column: x => x.ItemId, - principalTable: "Items", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Motions_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "Currencies", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false), - CurrencyGlobalId = table.Column(type: "TEXT", nullable: false), - UserId = table.Column(type: "TEXT", nullable: false), - Name = table.Column(type: "TEXT", nullable: false), - ShortName = table.Column(type: "TEXT", nullable: false), - CurrentRateId = table.Column(type: "INTEGER", nullable: true), - IsPrimary = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Currencies", x => x.Id); - table.ForeignKey( - name: "FK_Currencies_CurrencyGlobals_CurrencyGlobalId", - column: x => x.CurrencyGlobalId, - principalTable: "CurrencyGlobals", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Currencies_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "CurrencyRates", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CurrencyId = table.Column(type: "TEXT", nullable: false), - DateTime = table.Column(type: "TEXT", nullable: false), - Quantity = table.Column(type: "INTEGER", nullable: false), - Rate = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CurrencyRates", x => x.Id); - table.ForeignKey( - name: "FK_CurrencyRates_Currencies_CurrencyId", - column: x => x.CurrencyId, - principalTable: "Currencies", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_AccountId_OwnerId", - table: "AccountAccesses", - columns: new[] { "AccountId", "OwnerId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_AccountId_UserId", - table: "AccountAccesses", - columns: new[] { "AccountId", "UserId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_OwnerId", - table: "AccountAccesses", - column: "OwnerId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccesses_UserId", - table: "AccountAccesses", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccessInvites_AccountId", - table: "AccountAccessInvites", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccessInvites_UserId", - table: "AccountAccessInvites", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccountCategories_AccountId_CategoryId", - table: "AccountAccountCategories", - columns: new[] { "AccountId", "CategoryId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AccountAccountCategories_CategoryId", - table: "AccountAccountCategories", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_AccountCategories_UserId", - table: "AccountCategories", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_CurrencyGlobalId", - table: "Accounts", - column: "CurrencyGlobalId"); - - migrationBuilder.CreateIndex( - name: "IX_Accounts_OwnerId", - table: "Accounts", - column: "OwnerId"); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_CurrencyGlobalId", - table: "Currencies", - column: "CurrencyGlobalId"); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_CurrentRateId", - table: "Currencies", - column: "CurrentRateId"); - - migrationBuilder.CreateIndex( - name: "IX_Currencies_UserId", - table: "Currencies", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_CurrencyRates_CurrencyId", - table: "CurrencyRates", - column: "CurrencyId"); - - migrationBuilder.CreateIndex( - name: "IX_ItemCategories_UserId", - table: "ItemCategories", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Items_CategoryId", - table: "Items", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_Items_ItemGlobalId", - table: "Items", - column: "ItemGlobalId"); - - migrationBuilder.CreateIndex( - name: "IX_Motions_AccountId", - table: "Motions", - column: "AccountId"); - - migrationBuilder.CreateIndex( - name: "IX_Motions_ItemId", - table: "Motions", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_Motions_UserId", - table: "Motions", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictApplications_ClientId", - table: "OpenIddictApplications", - column: "ClientId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictAuthorizations_ApplicationId_Status_Subject_Type", - table: "OpenIddictAuthorizations", - columns: new[] { "ApplicationId", "Status", "Subject", "Type" }); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictScopes_Name", - table: "OpenIddictScopes", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictTokens_ApplicationId_Status_Subject_Type", - table: "OpenIddictTokens", - columns: new[] { "ApplicationId", "Status", "Subject", "Type" }); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictTokens_AuthorizationId", - table: "OpenIddictTokens", - column: "AuthorizationId"); - - migrationBuilder.CreateIndex( - name: "IX_OpenIddictTokens_ReferenceId", - table: "OpenIddictTokens", - column: "ReferenceId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_UserClaims_UserId", - table: "UserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Users_CurrencyId", - table: "Users", - column: "CurrencyId"); - - migrationBuilder.CreateIndex( - name: "IX_Verifications_UserId", - table: "Verifications", - column: "UserId"); - - migrationBuilder.AddForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId", - table: "Currencies", - column: "CurrentRateId", - principalTable: "CurrencyRates", - principalColumn: "Id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Currencies_Users_UserId", - table: "Currencies"); - - migrationBuilder.DropForeignKey( - name: "FK_Currencies_CurrencyGlobals_CurrencyGlobalId", - table: "Currencies"); - - migrationBuilder.DropForeignKey( - name: "FK_Currencies_CurrencyRates_CurrentRateId", - table: "Currencies"); - - migrationBuilder.DropTable( - name: "AccountAccesses"); - - migrationBuilder.DropTable( - name: "AccountAccessInvites"); - - migrationBuilder.DropTable( - name: "AccountAccountCategories"); - - migrationBuilder.DropTable( - name: "EmailTemplates"); - - migrationBuilder.DropTable( - name: "Motions"); - - migrationBuilder.DropTable( - name: "OpenIddictScopes"); - - migrationBuilder.DropTable( - name: "OpenIddictTokens"); - - migrationBuilder.DropTable( - name: "UserClaims"); - - migrationBuilder.DropTable( - name: "Verifications"); - - migrationBuilder.DropTable( - name: "AccountCategories"); - - migrationBuilder.DropTable( - name: "Accounts"); - - migrationBuilder.DropTable( - name: "Items"); - - migrationBuilder.DropTable( - name: "OpenIddictAuthorizations"); - - migrationBuilder.DropTable( - name: "ItemCategories"); - - migrationBuilder.DropTable( - name: "ItemGlobals"); - - migrationBuilder.DropTable( - name: "OpenIddictApplications"); - - migrationBuilder.DropTable( - name: "Users"); - - migrationBuilder.DropTable( - name: "CurrencyGlobals"); - - migrationBuilder.DropTable( - name: "CurrencyRates"); - - migrationBuilder.DropTable( - name: "Currencies"); - } - } -} diff --git a/MyOffice.Migration.Sqlite/Migrations/AppDbContextModelSnapshot.cs b/MyOffice.Migration.Sqlite/Migrations/AppDbContextModelSnapshot.cs deleted file mode 100644 index 6364200..0000000 --- a/MyOffice.Migration.Sqlite/Migrations/AppDbContextModelSnapshot.cs +++ /dev/null @@ -1,1046 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using MyOffice.DbContext; - -#nullable disable - -namespace MyOffice.Migrations.Sqlite.Migrations -{ - [DbContext(typeof(AppDbContext))] - partial class AppDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "10.0.10"); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("OwnerId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("IsAllowManage") - .HasColumnType("INTEGER"); - - b.Property("IsAllowRead") - .HasColumnType("INTEGER"); - - b.Property("IsAllowWrite") - .HasColumnType("INTEGER"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("OwnerId") - .HasColumnType("TEXT"); - - b.Property("Type") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("UserId"); - - b.HasIndex("AccountId", "OwnerId") - .IsUnique(); - - b.HasIndex("AccountId", "UserId") - .IsUnique(); - - b.ToTable("AccountAccesses"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("AcceptedOn") - .HasColumnType("TEXT"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("IsAllowWrite") - .HasColumnType("INTEGER"); - - b.Property("RejectedOn") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("UserId"); - - b.ToTable("AccountAccessInvites"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("CategoryId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("AccountId", "CategoryId") - .IsUnique(); - - b.ToTable("AccountAccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AccountCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("AccountId") - .HasColumnType("TEXT"); - - b.Property("AmountMinus") - .HasPrecision(18, 6) - .HasColumnType("TEXT"); - - b.Property("AmountPlus") - .HasPrecision(18, 6) - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("DateTime") - .HasColumnType("TEXT"); - - b.Property("DeletedOn") - .HasColumnType("TEXT"); - - b.Property("Description") - .HasColumnType("TEXT"); - - b.Property("ItemId") - .HasColumnType("INTEGER"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AccountId"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserId"); - - b.ToTable("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CurrencyGlobalId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("CurrentRateId") - .HasColumnType("INTEGER"); - - b.Property("IsPrimary") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("ShortName") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyGlobalId"); - - b.HasIndex("CurrentRateId"); - - b.HasIndex("UserId"); - - b.ToTable("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("DefaultQuantity") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Symbol") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("CurrencyGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CurrencyId") - .HasColumnType("TEXT"); - - b.Property("DateTime") - .HasColumnType("TEXT"); - - b.Property("Quantity") - .HasColumnType("INTEGER"); - - b.Property("Rate") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("CurrencyRates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CategoryId") - .HasColumnType("TEXT"); - - b.Property("ItemGlobalId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("ItemGlobalId"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("IsInternal") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ItemCategories"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("ItemGlobals"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Notifications.EmailTemplate", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Description") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Sender") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("SenderName") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Subject") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Template") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("EmailTemplates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CurrencyId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.Property("FirstName") - .HasColumnType("TEXT"); - - b.Property("FullName") - .HasColumnType("TEXT"); - - b.Property("IsEmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LastName") - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Phone") - .HasColumnType("TEXT"); - - b.Property("UserName") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.HasKey("Id"); - - b.HasIndex("CurrencyId"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.Property("ExternalId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Provider") - .IsRequired() - .HasColumnType("TEXT") - .UseCollation("NOCASE"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("UserClaims"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Code") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("CreatedOn") - .HasColumnType("TEXT"); - - b.Property("Destination") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("DestinationType") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("ExpiresOn") - .HasColumnType("TEXT"); - - b.Property("Metadata") - .HasColumnType("TEXT"); - - b.Property("Template") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.Property("VerifiedOn") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("Verifications"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ApplicationType") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("ClientId") - .HasMaxLength(100) - .HasColumnType("TEXT"); - - b.Property("ClientSecret") - .HasColumnType("TEXT"); - - b.Property("ClientType") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("ConsentType") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("DisplayName") - .HasColumnType("TEXT"); - - b.Property("DisplayNames") - .HasColumnType("TEXT"); - - b.Property("JsonWebKeySet") - .HasColumnType("TEXT"); - - b.Property("Permissions") - .HasColumnType("TEXT"); - - b.Property("PostLogoutRedirectUris") - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("RedirectUris") - .HasColumnType("TEXT"); - - b.Property("Requirements") - .HasColumnType("TEXT"); - - b.Property("Settings") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("ClientId") - .IsUnique(); - - b.ToTable("OpenIddictApplications", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ApplicationId") - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("CreationDate") - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("Scopes") - .HasColumnType("TEXT"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("TEXT"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictAuthorizations", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreScope", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("Description") - .HasColumnType("TEXT"); - - b.Property("Descriptions") - .HasColumnType("TEXT"); - - b.Property("DisplayName") - .HasColumnType("TEXT"); - - b.Property("DisplayNames") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("Resources") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("OpenIddictScopes", (string)null); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("ApplicationId") - .HasColumnType("TEXT"); - - b.Property("AuthorizationId") - .HasColumnType("TEXT"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("CreationDate") - .HasColumnType("TEXT"); - - b.Property("ExpirationDate") - .HasColumnType("TEXT"); - - b.Property("Payload") - .HasColumnType("TEXT"); - - b.Property("Properties") - .HasColumnType("TEXT"); - - b.Property("RedemptionDate") - .HasColumnType("TEXT"); - - b.Property("ReferenceId") - .HasMaxLength(100) - .HasColumnType("TEXT"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("TEXT"); - - b.Property("Type") - .HasMaxLength(150) - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("AuthorizationId"); - - b.HasIndex("ReferenceId") - .IsUnique(); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictTokens", (string)null); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Accounts") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("Accounts") - .HasForeignKey("OwnerId"); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("AccessRights") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "Owner") - .WithMany("AccountAccessOwners") - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccess") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Owner"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Invites") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountAccessInvites") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Categories") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category") - .WithMany("Accounts") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Account"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("AccountCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b => - { - b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account") - .WithMany("Motions") - .HasForeignKey("AccountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.Item", "Item") - .WithMany("Motions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Users.User", null) - .WithMany("AccountMotions") - .HasForeignKey("UserId"); - - b.Navigation("Account"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal") - .WithMany("Currencies") - .HasForeignKey("CurrencyGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate") - .WithMany("Currencies") - .HasForeignKey("CurrentRateId"); - - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("Currencies") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("CurrencyGlobal"); - - b.Navigation("CurrentRate"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency") - .WithMany("Rates") - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category") - .WithMany("Items") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal") - .WithMany("Items") - .HasForeignKey("ItemGlobalId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - - b.Navigation("ItemGlobal"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("ItemCategories") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency") - .WithMany() - .HasForeignKey("CurrencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Currency"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany("UserClaims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b => - { - b.HasOne("MyOffice.Data.Models.Users.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Authorizations") - .HasForeignKey("ApplicationId"); - - b.Navigation("Application"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreToken", b => - { - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Tokens") - .HasForeignKey("ApplicationId"); - - b.HasOne("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", "Authorization") - .WithMany("Tokens") - .HasForeignKey("AuthorizationId"); - - b.Navigation("Application"); - - b.Navigation("Authorization"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b => - { - b.Navigation("AccessRights"); - - b.Navigation("Categories"); - - b.Navigation("Invites"); - - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b => - { - b.Navigation("Accounts"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b => - { - b.Navigation("Rates"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b => - { - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b => - { - b.Navigation("Currencies"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b => - { - b.Navigation("Motions"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => - { - b.Navigation("AccountAccess"); - - b.Navigation("AccountAccessInvites"); - - b.Navigation("AccountAccessOwners"); - - b.Navigation("AccountCategories"); - - b.Navigation("AccountMotions"); - - b.Navigation("Accounts"); - - b.Navigation("Currencies"); - - b.Navigation("ItemCategories"); - - b.Navigation("UserClaims"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b => - { - b.Navigation("Authorizations"); - - b.Navigation("Tokens"); - }); - - modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Navigation("Tokens"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/MyOffice.Migration.Sqlite/MyOffice.Migrations.Sqlite.csproj b/MyOffice.Migration.Sqlite/MyOffice.Migrations.Sqlite.csproj deleted file mode 100644 index b5732ca..0000000 --- a/MyOffice.Migration.Sqlite/MyOffice.Migrations.Sqlite.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - diff --git a/MyOffice.SPA/.editorconfig b/MyOffice.SPA/.editorconfig deleted file mode 100644 index f99379e..0000000 --- a/MyOffice.SPA/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -# Editor configuration, see https://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = tabs -indent_size = 4 -insert_final_newline = true -trim_trailing_whitespace = true - -[*.ts] -quote_type = single - -[*.md] -max_line_length = off -trim_trailing_whitespace = false diff --git a/MyOffice.SPA/.eslintrc.json b/MyOffice.SPA/.eslintrc.json deleted file mode 100644 index 99d2907..0000000 --- a/MyOffice.SPA/.eslintrc.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "root": true, - "ignorePatterns": [ - "projects/**/*" - ], - "overrides": [ - { - "files": [ - "*.ts" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@angular-eslint/recommended", - "plugin:@angular-eslint/template/process-inline-templates" - ], - "rules": { - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "app", - "style": "camelCase" - } - ], - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "app", - "style": "kebab-case" - } - ] - } - }, - { - "files": [ - "*.html" - ], - "extends": [ - "plugin:@angular-eslint/template/recommended" - ], - "rules": {} - } - ] -} diff --git a/MyOffice.SPA/.gitignore b/MyOffice.SPA/.gitignore deleted file mode 100644 index 0711527..0000000 --- a/MyOffice.SPA/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. - -# Compiled output -/dist -/tmp -/out-tsc -/bazel-out - -# Node -/node_modules -npm-debug.log -yarn-error.log - -# IDEs and editors -.idea/ -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# Visual Studio Code -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -.history/* - -# Miscellaneous -/.angular/cache -.sass-cache/ -/connect.lock -/coverage -/libpeerconnection.log -testem.log -/typings - -# System files -.DS_Store -Thumbs.db diff --git a/MyOffice.SPA/.npmrc b/MyOffice.SPA/.npmrc deleted file mode 100644 index e9ee3cb..0000000 --- a/MyOffice.SPA/.npmrc +++ /dev/null @@ -1 +0,0 @@ -legacy-peer-deps=true \ No newline at end of file diff --git a/MyOffice.SPA/MyOffice.SPA.esproj b/MyOffice.SPA/MyOffice.SPA.esproj deleted file mode 100644 index 37d6a55..0000000 --- a/MyOffice.SPA/MyOffice.SPA.esproj +++ /dev/null @@ -1,44 +0,0 @@ - - - b02d9868-26cb-4e98-95d8-7286bf255f89 - - - npm start - false - Jasmine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MyOffice.SPA/README.md b/MyOffice.SPA/README.md deleted file mode 100644 index 747ce2e..0000000 --- a/MyOffice.SPA/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# MyOffice - -This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.0.6. - -## Development server - -Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. - -## Code scaffolding - -Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. - -## Build - -Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. - -## Running unit tests - -Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). - -## Running end-to-end tests - -Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. - -## Further help - -To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/MyOffice.SPA/angular.json b/MyOffice.SPA/angular.json deleted file mode 100644 index 9ad369d..0000000 --- a/MyOffice.SPA/angular.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "projects", - "projects": { - "MyOffice": { - "projectType": "application", - "schematics": {}, - "root": "", - "sourceRoot": "src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:application", - "options": { - "outputPath": "dist/angular-template", - "index": "src/index.html", - "browser": "src/main.ts", - "polyfills": ["src/polyfills.ts"], - "tsConfig": "tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "src/favicon.ico", - "src/assets", - "src/silent-refresh.html" - ], - "styles": [ - "@angular/material/prebuilt-themes/indigo-pink.css", - "./node_modules/bootstrap/dist/css/bootstrap.min.css", - "src/assets/scss/style.scss", - "src/assets/scss/theme/all-themes.scss", - "src/styles.scss" - ], - "stylePreprocessorOptions": { - "includePaths": ["node_modules/"] - }, - "scripts": [ - ] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "1mb", - "maximumError": "3mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], - "outputHashing": "all" - }, - "docker": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "1mb", - "maximumError": "3mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.docker.ts" - } - ], - "outputHashing": "all" - }, - "proxmox": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "1mb", - "maximumError": "3mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.proxmox.ts" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "MyOffice:build:production" - }, - "development": { - "buildTarget": "MyOffice:build:development" - } - }, - "defaultConfiguration": "development", - "options": { - "proxyConfig": "src/proxy.conf.js", - "port": 4300, - "open": false - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "MyOffice:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - ], - "scripts": [] - } - } - } - } - }, - "cli": { - "analytics": false - } -} diff --git a/MyOffice.SPA/aspnetcore-https.js b/MyOffice.SPA/aspnetcore-https.js deleted file mode 100644 index 81a924e..0000000 --- a/MyOffice.SPA/aspnetcore-https.js +++ /dev/null @@ -1,36 +0,0 @@ -// This script sets up HTTPS for the application using the ASP.NET Core HTTPS certificate -const fs = require('fs'); -const spawn = require('child_process').spawn; -const path = require('path'); - -const baseFolder = - process.env.APPDATA !== undefined && process.env.APPDATA !== '' - ? `${process.env.APPDATA}/ASP.NET/https` - : `${process.env.HOME}/.aspnet/https`; - -const certificateArg = process.argv.map(arg => arg.match(/--name=(?.+)/i)).filter(Boolean)[0]; -const certificateName = certificateArg ? certificateArg.groups.value : process.env.npm_package_name; - -if (!certificateName) { - console.error( - 'Invalid certificate name. Run this script in the context of an npm/yarn script or pass --name=<> explicitly.'); - process.exit(-1); -} - -const certFilePath = path.join(baseFolder, `${certificateName}.pem`); -const keyFilePath = path.join(baseFolder, `${certificateName}.key`); - -if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) { - spawn('dotnet', - [ - 'dev-certs', - 'https', - '--export-path', - certFilePath, - '--format', - 'Pem', - '--no-password', - ], - { stdio: 'inherit', }) - .on('exit', (code) => process.exit(code)); -} diff --git a/MyOffice.SPA/karma.conf.js b/MyOffice.SPA/karma.conf.js deleted file mode 100644 index b5ce0eb..0000000 --- a/MyOffice.SPA/karma.conf.js +++ /dev/null @@ -1,45 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function(config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') - ], - client: { - jasmine: { - // you can add configuration options for Jasmine here - // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html - // for example, you can disable the random execution with `random: false` - // or set a specific seed with `seed: 4321` - - }, - clearContext: false // leave Jasmine Spec Runner output visible in browser - }, - jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces - }, - coverageReporter: { - dir: require('path').join(__dirname, './coverage/angular-template'), - subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true - }); -}; diff --git a/MyOffice.SPA/nuget.config b/MyOffice.SPA/nuget.config deleted file mode 100644 index 04437b9..0000000 --- a/MyOffice.SPA/nuget.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/MyOffice.SPA/package.json b/MyOffice.SPA/package.json deleted file mode 100644 index 92dfe34..0000000 --- a/MyOffice.SPA/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-template", - "version": "0.0.0", - "scripts": { - "ng": "node --disable-warning=DEP0060 ./node_modules/@angular/cli/bin/ng.js", - "start": "node --disable-warning=DEP0060 ./node_modules/@angular/cli/bin/ng.js serve", - "start-ssl": "node --disable-warning=DEP0060 ./node_modules/@angular/cli/bin/ng.js serve --ssl --ssl-cert %APPDATA%\\ASP.NET\\https\\%npm_package_name%.pem --ssl-key %APPDATA%\\ASP.NET\\https\\%npm_package_name%.key", - "build": "node --disable-warning=DEP0060 ./node_modules/@angular/cli/bin/ng.js build", - "watch": "node --disable-warning=DEP0060 ./node_modules/@angular/cli/bin/ng.js build --watch --configuration development", - "test": "node --disable-warning=DEP0060 ./node_modules/@angular/cli/bin/ng.js test" - }, - "private": true, - "dependencies": { - "@abacritt/angularx-social-login": "^2.1.0", - "@angular/animations": "^18.2.14", - "@angular/cdk": "^18.2.14", - "@angular/common": "^18.2.14", - "@angular/compiler": "^18.2.14", - "@angular/core": "^18.2.14", - "@angular/forms": "^18.2.14", - "@angular/material": "^18.2.14", - "@angular/platform-browser": "^18.2.14", - "@angular/platform-browser-dynamic": "^18.2.14", - "@angular/router": "^18.2.14", - "@auth0/auth0-angular": "2.2.3", - "@ngx-loading-bar/core": "^6.0.2", - "@ngx-loading-bar/http-client": "^6.0.2", - "@ngx-loading-bar/router": "^6.0.2", - "@ngx-translate/core": "^14.0.0", - "@ngx-translate/http-loader": "^7.0.0", - "@popperjs/core": "^2.11.6", - "angular-animations": "^0.11.0", - "angular-feather": "^6.5.0", - "angular-oauth2-oidc": "^18.0.0", - "apexcharts": "^3.37.0", - "bootstrap": "^5.2.3", - "lodash": "^4.17.21", - "moment": "^2.29.4", - "ng-apexcharts": "^1.11.0", - "ngx-currency": "^4.0.0", - "ngx-mask": "^18.0.4", - "ngx-scrollbar": "^13.0.3", - "rxjs": "~7.8.0", - "subsink": "^1.0.2", - "sweetalert2": "^11.4.8", - "tslib": "^2.3.0", - "xlsx": "^0.18.5", - "zone.js": "^0.14.10" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^18.2.14", - "@angular-eslint/builder": "^18.4.3", - "@angular-eslint/eslint-plugin": "^18.4.3", - "@angular-eslint/eslint-plugin-template": "^18.4.3", - "@angular-eslint/schematics": "^18.4.3", - "@angular-eslint/template-parser": "^18.4.3", - "@angular/cli": "^18.2.14", - "@angular/compiler-cli": "^18.2.14", - "@types/jasmine": "~4.3.0", - "@types/lodash": "^4.14.196", - "@typescript-eslint/eslint-plugin": "5.48.2", - "@typescript-eslint/parser": "5.48.2", - "eslint": "^8.33.0", - "jasmine-core": "~4.5.0", - "karma": "~6.4.0", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.0.0", - "typescript": "^5.5.4" - }, - "overrides": { - "@auth0/auth0-spa-js": "2.1.3" - } -} diff --git a/MyOffice.SPA/src/app/api-routes.ts b/MyOffice.SPA/src/app/api-routes.ts deleted file mode 100644 index d795b5c..0000000 --- a/MyOffice.SPA/src/app/api-routes.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { environment } from '../environments/environment'; - -const api = (environment.apiUrl ?? '').replace(/\/$/, ''); - -export class ApiRoutes { - static UserRegister = `${api}/api/user/register`; - static UserLogin = `${api}/api/user/login`; - static UserProfile = `${api}/api/user/profile`; - static UserAttach = `${api}/api/user/attach`; - static UserDeattach = `${api}/api/user/deattach`; - - static GeneralCurrencies = `${api}/api/general/currencies`; - static SettingsCurrencies = `${api}/api/settings/currencies`; - static SettingsCurrency = `${api}/api/settings/currencies/:id`; - static SettingsCurrenciesRate = `${api}/api/settings/currencies/:id/rate`; - - static SettingsAccountCategories = `${api}/api/settings/account-categories`; - static SettingsAccountCategory = `${api}/api/settings/account-categories/:id`; - - static SettingsAccounts = `${api}/api/settings/accounts`; - static SettingsAccount = `${api}/api/settings/accounts/:id`; - static SettingsAccountAccesses = `${api}/api/settings/accounts/:id/access`; - static SettingsAccountAccess = `${api}/api/settings/accounts/:id/access/:access`; - static SettingsAccountAccountCategory = `${api}/api/settings/accounts/:id/category/:categoryId`; - static SettingsAccountInvites = `${api}/api/settings/accounts/invites`; - static SettingsAccountInviteAccept = `${api}/api/settings/accounts/invites/:id/accept`; - static SettingsAccountInviteReject = `${api}/api/settings/accounts/invites/:id/reject`; - - static SettingsItemCategories = `${api}/api/settings/item-categories`; - static SettingsItemCategory = `${api}/api/settings/item-categories/:id`; - - static SettingsItems = `${api}/api/settings/items`; - static SettingsItem = `${api}/api/settings/items/:id`; - - static Accounts = `${api}/api/accounts`; - static Account = `${api}/api/accounts/:id`; - - static Motions = `${api}/api/accounts/:id/motions`; - static Motion = `${api}/api/accounts/:id/motions/:motionId`; - - static Items = `${api}/api/items`; - - static Dashboard = `${api}/api/dashboard`; - static DashboardIncome = `${api}/api/dashboard/income`; - static DashboardOutcome = `${api}/api/dashboard/outcome`; -} diff --git a/MyOffice.SPA/src/app/app-routing.module.ts b/MyOffice.SPA/src/app/app-routing.module.ts deleted file mode 100644 index 6e21dbb..0000000 --- a/MyOffice.SPA/src/app/app-routing.module.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { Page404Component } from './authentication/page404/page404.component'; -import { AuthGuard } from './core/guard/auth.guard'; -import { AuthLayoutComponent } from './layout/app-layout/auth-layout/auth-layout.component'; -import { MainLayoutComponent } from './layout/app-layout/main-layout/main-layout.component'; - -const routes: Routes = [ - { - path: '', - component: MainLayoutComponent, - canActivate: [AuthGuard], - children: [ - { path: '', redirectTo: '/authentication/signin', pathMatch: 'full' }, - { - path: 'dashboard', - loadChildren: () => - import('./dashboard/dashboard.module').then((m) => m.DashboardModule), - }, - ], - }, - { - path: 'authentication', - component: AuthLayoutComponent, - loadChildren: () => - import('./authentication/authentication.module').then( - (m) => m.AuthenticationModule - ), - }, - { - path: '', - component: MainLayoutComponent, - canActivate: [AuthGuard], - loadChildren: () => - import('./pages/pages.module').then( - (m) => m.PagesModule - ), - }, - { path: '**', component: Page404Component }, -]; - -@NgModule({ - imports: [RouterModule.forRoot(routes, {})], - exports: [RouterModule], -}) -export class AppRoutingModule { -} diff --git a/MyOffice.SPA/src/app/app.component.html b/MyOffice.SPA/src/app/app.component.html deleted file mode 100644 index 7e31ebd..0000000 --- a/MyOffice.SPA/src/app/app.component.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/MyOffice.SPA/src/app/app.component.scss b/MyOffice.SPA/src/app/app.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/app.component.spec.ts b/MyOffice.SPA/src/app/app.component.spec.ts deleted file mode 100644 index 39d0388..0000000 --- a/MyOffice.SPA/src/app/app.component.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', - () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - RouterTestingModule - ], - declarations: [ - AppComponent - ], - }).compileComponents(); - }); - - it('should create the app', - () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have as title 'spire'`, - () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('spire'); - }); - - it('should render title', - () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('.content span')?.textContent).toContain('spire app is running!'); - }); - }); diff --git a/MyOffice.SPA/src/app/app.component.ts b/MyOffice.SPA/src/app/app.component.ts deleted file mode 100644 index 06e14b7..0000000 --- a/MyOffice.SPA/src/app/app.component.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { Event, Router, RouterOutlet, NavigationStart, NavigationEnd } from '@angular/router'; -import { PageLoaderComponent } from './layout/page-loader/page-loader.component'; - -@Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], - standalone: true, - imports: [RouterOutlet, PageLoaderComponent], -}) -export class AppComponent { - currentUrl!: string; - private readonly destroyRef = inject(DestroyRef); - - constructor(public _router: Router) { - this._router.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((routerEvent: Event) => { - if (routerEvent instanceof NavigationStart) { - this.currentUrl = routerEvent.url.substring( - routerEvent.url.lastIndexOf('/') + 1 - ); - } - if (routerEvent instanceof NavigationEnd) { - /* empty */ - } - window.scrollTo(0, 0); - }); - } -} diff --git a/MyOffice.SPA/src/app/app.config.ts b/MyOffice.SPA/src/app/app.config.ts deleted file mode 100644 index 4fd0b7f..0000000 --- a/MyOffice.SPA/src/app/app.config.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ApplicationConfig, importProvidersFrom } from '@angular/core'; -import { LocationStrategy, HashLocationStrategy } from '@angular/common'; -import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -// libs -import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; -import { TranslateHttpLoader } from '@ngx-translate/http-loader'; -import { LoadingBarRouterModule } from '@ngx-loading-bar/router'; -import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'; -import { NgScrollbarModule } from 'ngx-scrollbar'; - -// app -import { CoreModule } from './core/core.module'; -import { AppRoutingModule } from './app-routing.module'; -import { ErrorInterceptor } from './core/interceptor/error.interceptor'; -import { UpdateDateHttpInterceptor } from './core/interceptor/update.date.http.interceptor '; - -export function createTranslateLoader(http: HttpClient) { - return new TranslateHttpLoader(http, 'assets/i18n/', '.json'); -} - -export const appConfig: ApplicationConfig = { - providers: [ - importProvidersFrom( - BrowserAnimationsModule, - AppRoutingModule, - LoadingBarHttpClientModule, - LoadingBarRouterModule, - NgScrollbarModule, - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useFactory: createTranslateLoader, - deps: [HttpClient], - }, - }), - // core & shared - CoreModule, - ), - { provide: LocationStrategy, useClass: HashLocationStrategy }, - // Bearer tokens: angular-oauth2-oidc resourceServer (AuthModuleConfig.sendAccessToken) - { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, - { provide: HTTP_INTERCEPTORS, useClass: UpdateDateHttpInterceptor, multi: true }, - provideHttpClient(withInterceptorsFromDi()), - ], -}; diff --git a/MyOffice.SPA/src/app/authentication/authentication-routing.module.ts b/MyOffice.SPA/src/app/authentication/authentication-routing.module.ts deleted file mode 100644 index ad46f3d..0000000 --- a/MyOffice.SPA/src/app/authentication/authentication-routing.module.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { SigninComponent } from './signin/signin.component'; -import { SignupComponent } from './signup/signup.component'; -import { ForgotPasswordComponent } from './forgot-password/forgot-password.component'; -import { LockedComponent } from './locked/locked.component'; -import { Page404Component } from './page404/page404.component'; -import { Page500Component } from './page500/page500.component'; - -const routes: Routes = [ - { - path: '', - redirectTo: 'signin', - pathMatch: 'full', - }, - { - path: 'signin', - component: SigninComponent, - }, - { - path: 'signup', - component: SignupComponent, - }, - { - path: 'forgot-password', - component: ForgotPasswordComponent, - }, - { - path: 'locked', - component: LockedComponent, - }, - { - path: 'page404', - component: Page404Component, - }, - { - path: 'page500', - component: Page500Component, - }, -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class AuthenticationRoutingModule { -} diff --git a/MyOffice.SPA/src/app/authentication/authentication.module.ts b/MyOffice.SPA/src/app/authentication/authentication.module.ts deleted file mode 100644 index 0886973..0000000 --- a/MyOffice.SPA/src/app/authentication/authentication.module.ts +++ /dev/null @@ -1,50 +0,0 @@ -// angular -import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatIconModule } from '@angular/material/icon'; -import { MatButtonModule } from '@angular/material/button'; - -// libs -import { GoogleSigninButtonModule } from '@abacritt/angularx-social-login'; - -// app -import { AuthenticationRoutingModule } from './authentication-routing.module'; -import { Page500Component } from './page500/page500.component'; -import { Page404Component } from './page404/page404.component'; -import { SigninComponent } from './signin/signin.component'; -import { SignupComponent } from './signup/signup.component'; -import { LockedComponent } from './locked/locked.component'; -import { ForgotPasswordComponent } from './forgot-password/forgot-password.component'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - ReactiveFormsModule, - AuthenticationRoutingModule, - MatFormFieldModule, - MatInputModule, - MatIconModule, - MatButtonModule, - GoogleSigninButtonModule, - ], - declarations: [ - Page500Component, - Page404Component, - SigninComponent, - SignupComponent, - LockedComponent, - ForgotPasswordComponent, - ], - providers: [ - ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA - ] -}) -export class AuthenticationModule { -} diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.html b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.html deleted file mode 100644 index 68d6049..0000000 --- a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.html +++ /dev/null @@ -1,45 +0,0 @@ -
-
-
-
-
-
-
-
-
-

Reset Password

- -
-
-
- - Enter your registered email address. - - - Email - - mail - - Please enter a valid email address - - -
-
-
- -
-
- -
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.scss b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.spec.ts b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.spec.ts deleted file mode 100644 index cc3bdc0..0000000 --- a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ForgotPasswordComponent } from './forgot-password.component'; -describe('ForgotPasswordComponent', - () => { - let component: ForgotPasswordComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ForgotPasswordComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(ForgotPasswordComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.ts b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.ts deleted file mode 100644 index eaac269..0000000 --- a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; -import { - FormBuilder, - FormControl, - FormGroup, - Validators, -} from '@angular/forms'; - -type ForgotPasswordForm = { - email: FormControl; -}; - -@Component({ - selector: 'app-forgot-password', - templateUrl: './forgot-password.component.html', - styleUrls: ['./forgot-password.component.scss'], -}) -export class ForgotPasswordComponent implements OnInit { - authForm!: FormGroup; - submitted = false; - returnUrl!: string; - - constructor( - private formBuilder: FormBuilder, - private route: ActivatedRoute, - private router: Router - ) { - } - - ngOnInit() { - this.authForm = this.formBuilder.group({ - email: [ - '', - [Validators.required, Validators.email, Validators.minLength(5)], - ], - }); - // get return url from route parameters or default to '/' - this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; - } - - get f() { - return this.authForm.controls; - } - - onSubmit() { - this.submitted = true; - // stop here if form is invalid - if (this.authForm.invalid) { - return; - } else { - this.router.navigate(['/dashboard/rests']); - } - } -} diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.html b/MyOffice.SPA/src/app/authentication/locked/locked.component.html deleted file mode 100644 index a0db47e..0000000 --- a/MyOffice.SPA/src/app/authentication/locked/locked.component.html +++ /dev/null @@ -1,58 +0,0 @@ -
-
-
-
-
-
-
-
-
-
-
-
- User -
-
- - {{userFullName}} - -
-

- Locked -

-
-
-
- - Enter your password here. - - - Password - - - {{hide ? 'visibility_off' : 'visibility'}} - - - Password is required - - -
-
-
- -
- -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.scss b/MyOffice.SPA/src/app/authentication/locked/locked.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.spec.ts b/MyOffice.SPA/src/app/authentication/locked/locked.component.spec.ts deleted file mode 100644 index 88664c6..0000000 --- a/MyOffice.SPA/src/app/authentication/locked/locked.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { LockedComponent } from './locked.component'; -describe('LockedComponent', - () => { - let component: LockedComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [LockedComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(LockedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.ts b/MyOffice.SPA/src/app/authentication/locked/locked.component.ts deleted file mode 100644 index 92a034a..0000000 --- a/MyOffice.SPA/src/app/authentication/locked/locked.component.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { AuthService } from 'src/app/core/service/auth.service'; - -type LockedForm = { - password: FormControl; -}; - -@Component({ - selector: 'app-locked', - templateUrl: './locked.component.html', - styleUrls: ['./locked.component.scss'], -}) -export class LockedComponent implements OnInit { - authForm!: FormGroup; - submitted = false; - userImg!: string; - userFullName!: string; - hide = true; - - constructor( - private formBuilder: FormBuilder, - private router: Router, - private authService: AuthService - ) { - } - - ngOnInit() { - this.authForm = this.formBuilder.group({ - password: ['', Validators.required], - }); - - this.userImg = this.authService.currentUserValue.img || 'assets/images/user/admin.jpg'; - - this.userFullName = - this.authService.currentUserValue.firstName + - ' ' + - this.authService.currentUserValue.lastName; - } - - get f() { - return this.authForm.controls; - } - - onSubmit() { - this.submitted = true; - // stop here if form is invalid - if (this.authForm.invalid) { - return; - } else { - this.router.navigate(['/dashboard/rests']); - } - } -} diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.html b/MyOffice.SPA/src/app/authentication/page404/page404.component.html deleted file mode 100644 index 29e5aeb..0000000 --- a/MyOffice.SPA/src/app/authentication/page404/page404.component.html +++ /dev/null @@ -1,37 +0,0 @@ -
-
-
-
-
-
-
-
-
-
- - 404 - - - Looks Like You're Lost - - - The Page You Are Looking For Not Available! - -
- -
- -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.scss b/MyOffice.SPA/src/app/authentication/page404/page404.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.spec.ts b/MyOffice.SPA/src/app/authentication/page404/page404.component.spec.ts deleted file mode 100644 index f4a6b82..0000000 --- a/MyOffice.SPA/src/app/authentication/page404/page404.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { Page404Component } from './page404.component'; - -describe('Page404Component', - () => { - let component: Page404Component; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [Page404Component], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(Page404Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.ts b/MyOffice.SPA/src/app/authentication/page404/page404.component.ts deleted file mode 100644 index f3ba68c..0000000 --- a/MyOffice.SPA/src/app/authentication/page404/page404.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-page404', - templateUrl: './page404.component.html', - styleUrls: ['./page404.component.scss'], -}) -export class Page404Component { - constructor() { - // constructor - } -} diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.html b/MyOffice.SPA/src/app/authentication/page500/page500.component.html deleted file mode 100644 index ce00254..0000000 --- a/MyOffice.SPA/src/app/authentication/page500/page500.component.html +++ /dev/null @@ -1,34 +0,0 @@ -
-
-
-
-
-
-
-
-
-
- - 500 - - - Oops, Something went wrong. Please try after some times. - -
- -
- -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.scss b/MyOffice.SPA/src/app/authentication/page500/page500.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.spec.ts b/MyOffice.SPA/src/app/authentication/page500/page500.component.spec.ts deleted file mode 100644 index adaba77..0000000 --- a/MyOffice.SPA/src/app/authentication/page500/page500.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { Page500Component } from './page500.component'; - -describe('Page500Component', - () => { - let component: Page500Component; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [Page500Component], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(Page500Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.ts b/MyOffice.SPA/src/app/authentication/page500/page500.component.ts deleted file mode 100644 index 589f767..0000000 --- a/MyOffice.SPA/src/app/authentication/page500/page500.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-page500', - templateUrl: './page500.component.html', - styleUrls: ['./page500.component.scss'], -}) -export class Page500Component { - constructor() { - // constructor - } -} diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.html b/MyOffice.SPA/src/app/authentication/signin/signin.component.html deleted file mode 100644 index 5493ecf..0000000 --- a/MyOffice.SPA/src/app/authentication/signin/signin.component.html +++ /dev/null @@ -1,114 +0,0 @@ -
-
-
-
-
-
-
-
-
-

-
Welcome to ase.com.ua
-
angular/asp.net core template
-

- - -
-
-
- - Email - - mail - - Email is required - - -
-
-
-
- - Password - - - - {{hide ? 'visibility_off' : 'visibility'}} - - - - Password is required - - -
-
-
-
- -
- Forgot Password? -
- -
{{error}}
- -
-
- -
-
-
- - -
-
-
-
-
diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.scss b/MyOffice.SPA/src/app/authentication/signin/signin.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.spec.ts b/MyOffice.SPA/src/app/authentication/signin/signin.component.spec.ts deleted file mode 100644 index 639f76b..0000000 --- a/MyOffice.SPA/src/app/authentication/signin/signin.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { SigninComponent } from './signin.component'; - -describe('SigninComponent', - () => { - let component: SigninComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [SigninComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(SigninComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.ts b/MyOffice.SPA/src/app/authentication/signin/signin.component.ts deleted file mode 100644 index 374e5d3..0000000 --- a/MyOffice.SPA/src/app/authentication/signin/signin.component.ts +++ /dev/null @@ -1,117 +0,0 @@ -// angular -import { Component, OnInit } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; - -// libs -import { SocialAuthService } from '@abacritt/angularx-social-login'; - -// app -import { AuthService } from 'src/app/core/service/auth.service'; -import { UnsubscribeOnDestroyAdapter } from 'src/app/shared/UnsubscribeOnDestroyAdapter'; -import { getSafeRedirectUrl } from 'src/app/core/utils/safe-redirect'; -import { environment } from '../../../environments/environment'; - -type SigninForm = { - username: FormControl; - password: FormControl; -}; - -@Component({ - selector: 'app-signin', - templateUrl: './signin.component.html', - styleUrls: ['./signin.component.scss'], -}) -export class SigninComponent extends UnsubscribeOnDestroyAdapter -implements OnInit { - authForm!: FormGroup; - submitted = false; - loading = false; - error?= ''; - hide = true; - allowGoogle: boolean; - allowAuth: boolean; - - constructor( - private formBuilder: FormBuilder, - private router: Router, - private route: ActivatedRoute, - private authService: AuthService, - ) { - super(); - - this.allowGoogle = !!(environment.externalLogins && - environment.externalLogins.google && - environment.externalLogins.google.clientId); - - this.allowAuth = !!(environment.externalLogins && - environment.externalLogins.auth0 && - environment.externalLogins.auth0.clientId); - } - - ngOnInit() { - this.authForm = this.formBuilder.group({ - username: ['', Validators.required], - password: ['', Validators.required], - }); - - this.subs.sink = this.authService.isAuthenticated$.subscribe(isAuthenticated => { - if (isAuthenticated) { - this.router.navigate([this.getRedirect() || '/dashboard/rests']); - } - }); - } - - onSubmit() { - if (this.authForm.invalid) { - this.error = 'Username and Password not valid!'; - return; - } - - this.submitted = true; - this.loading = true; - this.error = ''; - - var user = { - username: this.authForm.controls.username.value!, - password: this.authForm.controls.password.value! - }; - - this.subs.sink = this.authService - .login(user) - .subscribe({ - next: (resp) => { - if (!resp.success) { - this.error = 'Invalid Login'; - if (!resp.success && resp.error?.code === 'invalid_grant') { - this.error = 'Invalid username or password'; - } - this.submitted = false; - this.loading = false; - } - }, - error: (error) => { - this.error = 'Invalid username or password'; - this.submitted = false; - this.loading = false; - }, - }); - } - - loginAuth0() { - this.subs.sink = this.authService.loginAuth0().subscribe(resp => { - if (!resp.success) { - this.error = 'Invalid login'; - } - }); - } - - private getRedirect(): string | undefined { - const raw = this.route.snapshot.queryParams['r'] as string | undefined; - if (!raw) { - return undefined; - } - const safe = getSafeRedirectUrl(raw, ''); - return safe || undefined; - } -} diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.html b/MyOffice.SPA/src/app/authentication/signup/signup.component.html deleted file mode 100644 index e9eb396..0000000 --- a/MyOffice.SPA/src/app/authentication/signup/signup.component.html +++ /dev/null @@ -1,128 +0,0 @@ -
-
-
-
-
-
-
-
-
-

Sign Up

- -
-
-
- - Email - - mail - - Please enter a valid email address - - -
-
-
-
- - Password - - - - {{hide ? 'visibility_off' : 'visibility'}} - - - - Password is required - - - Password must be at least 8 characters - - - Use upper, lower, digit and special character - - -
-
-
-
- - Confirm Password - - - - {{chide ? 'visibility_off' : 'visibility'}} - - - - Confirm Password is required - - -
-
-
-
- Passwords do not match -
-
-
-
- {{error.description}} -
-
-
-
- - Already Registered? - - Login - - -
-
-
- -
-
- - -
-
-
-
-
diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.scss b/MyOffice.SPA/src/app/authentication/signup/signup.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.spec.ts b/MyOffice.SPA/src/app/authentication/signup/signup.component.spec.ts deleted file mode 100644 index e43607c..0000000 --- a/MyOffice.SPA/src/app/authentication/signup/signup.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { SignupComponent } from './signup.component'; - -describe('SignupComponent', - () => { - let component: SignupComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [SignupComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(SignupComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.ts b/MyOffice.SPA/src/app/authentication/signup/signup.component.ts deleted file mode 100644 index ceb5d1a..0000000 --- a/MyOffice.SPA/src/app/authentication/signup/signup.component.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Component, DestroyRef, inject, OnInit } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { Router, ActivatedRoute } from '@angular/router'; -import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { GeneralErrorModel } from '../../core/models/general-error.model'; -import { AuthService } from '../../core/service/auth.service'; - -type SignupForm = { - email: FormControl; - password: FormControl; - cpassword: FormControl; -}; - -@Component({ - selector: 'app-signup', - templateUrl: './signup.component.html', - styleUrls: ['./signup.component.scss'], -}) -export class SignupComponent implements OnInit { - authForm!: FormGroup; - submitted = false; - returnUrl!: string; - hide = true; - chide = true; - generalError?: GeneralErrorModel; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private formBuilder: FormBuilder, - private route: ActivatedRoute, - private router: Router, - private authService: AuthService - ) { - - } - - ngOnInit() { - this.authForm = this.formBuilder.group({ - email: ['', [Validators.required, Validators.email, Validators.minLength(5)]], - password: [ - '', - [ - Validators.required, - Validators.minLength(8), - Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).+$/), - ], - ], - cpassword: ['', Validators.required], - }, { - validators: (group: AbstractControl) => { - const password = group.get('password')?.value; - const confirm = group.get('cpassword')?.value; - return password && confirm && password !== confirm - ? { passwordMismatch: true } - : null; - }, - }); - // get return url from route parameters or default to '/' - this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; - } - - get f() { - return this.authForm.controls; - } - - onSubmit() { - this.submitted = true; - // stop here if form is invalid - if (this.authForm.invalid) { - return; - } - - if (this.authForm.hasError('passwordMismatch')) { - return; - } - - this.authService.register({ - username: this.authForm.get('email')!.value!, - password: this.authForm.get('password')!.value!, - confirmPassword: this.authForm.get('cpassword')!.value!, - }).pipe(takeUntilDestroyed(this.destroyRef)).subscribe( - resp => { - if (!resp.succeeded) { - this.generalError = resp as GeneralErrorModel; - return; - } - - // Auto sign-in with email+password after successful register - this.authService.login({ - username: this.authForm.get('email')!.value!, - password: this.authForm.get('password')!.value!, - }).pipe(takeUntilDestroyed(this.destroyRef)).subscribe(login => { - if (login.success) { - this.router.navigate([this.returnUrl || '/dashboard/rests']); - } else { - this.router.navigate(['authentication/signin']); - } - }); - }, - err => { - this.generalError = err.error as GeneralErrorModel; - } - ); - } - - loginAuth0() { - this.authService.loginAuth0() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - }); - } -} diff --git a/MyOffice.SPA/src/app/config.external-login.ts b/MyOffice.SPA/src/app/config.external-login.ts deleted file mode 100644 index bccd451..0000000 --- a/MyOffice.SPA/src/app/config.external-login.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { SocialAuthServiceConfig } from '@abacritt/angularx-social-login'; -import { GoogleLoginProvider } from '@abacritt/angularx-social-login'; -import { FacebookLoginProvider } from '@abacritt/angularx-social-login'; -import { MicrosoftLoginProvider } from '@abacritt/angularx-social-login'; - -import { environment } from '../environments/environment'; - -export class ExternalLoginConfig { - - static readonly GOOGLE = 'google'; - static readonly AUTH0 = 'auth0'; - static readonly FACEBOOK = 'facebook'; - static readonly MICROSOFT = 'microsoft'; - - static getConfiguredProviders() { - return [ - { - provider: ExternalLoginConfig.GOOGLE, - name: 'Google', - }, - { - provider: ExternalLoginConfig.AUTH0, - name: 'Auth0', - }, - /*{ - provider: ExternalLoginConfig.FACEBOOK, - name: "FaceBook", - }, - { - provider: ExternalLoginConfig.MICROSOFT, - name: "Microsoft", - },*/ - ]; - } - - static getSocialConfig(): SocialAuthServiceConfig { - var providers = []; - - if (environment.externalLogins && - environment.externalLogins.google && - environment.externalLogins.google.clientId - ) { - providers.push({ - id: GoogleLoginProvider.PROVIDER_ID, - provider: new GoogleLoginProvider( - environment.externalLogins.google.clientId, - { scopes: 'email', } - ) - }); - } - return { - autoLogin: false, - providers: providers, - onError: (err) => { - console.error(err); - } - }; - } - - static getAuth0Config() { - return { - clientId: environment.externalLogins.auth0.clientId, - domain: environment.externalLogins.auth0.domain, - }; - } -} diff --git a/MyOffice.SPA/src/app/config.oidc.ts b/MyOffice.SPA/src/app/config.oidc.ts deleted file mode 100644 index 292097b..0000000 --- a/MyOffice.SPA/src/app/config.oidc.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { AuthConfig } from 'angular-oauth2-oidc'; -import { OAuthModuleConfig } from 'angular-oauth2-oidc'; - -import { environment } from '../environments/environment'; - -/** Public origin for same-origin deploys when environment URLs are left empty. */ -function publicOrigin(): string { - return window.location.origin; -} - -function resolveIdentityServer(): string { - const configured = (environment.identityServer ?? '').trim(); - if (configured) { - return configured.endsWith('/') ? configured : `${configured}/`; - } - return `${publicOrigin()}/`; -} - -function resolveAllowedUrls(): string[] { - const configured = environment.allowedUrls ?? []; - if (configured.length > 0) { - return configured; - } - const origin = publicOrigin(); - const api = (environment.apiUrl ?? '').trim().replace(/\/$/, ''); - return api ? [origin, api] : [origin]; -} - -export const AuthCodeFlowConfig: AuthConfig = { - // Url of the Identity Provider - issuer: resolveIdentityServer(), - // Local/Docker HTTP demos can set environment.requireHttps = false. - requireHttps: (environment as { requireHttps?: boolean }).requireHttps ?? environment.production, - strictDiscoveryDocumentValidation: - (environment as { requireHttps?: boolean }).requireHttps ?? environment.production, - - // URL of the SPA to redirect the user to after login - redirectUri: window.location.origin + '/', - // Password/external grants issue refresh tokens; no cookie session for iframe silent refresh. - useSilentRefresh: false, - sessionChecksEnabled: false, - timeoutFactor: 0.75, - - clientId: 'angulartemplate_spa', - - // Authorization Code + PKCE for interactive OIDC; email/password still uses ROPC (see docs/AUTH.md). - responseType: 'code', - disablePKCE: false, - - // offline_access → refresh_token (used by setupAutomaticSilentRefresh) - scope: 'openid profile email api offline_access', - - showDebugInformation: !environment.production, -}; - -export const AuthModuleConfig: OAuthModuleConfig = { - resourceServer: { - allowedUrls: resolveAllowedUrls(), - sendAccessToken: true, - } -}; diff --git a/MyOffice.SPA/src/app/config/config.service.ts b/MyOffice.SPA/src/app/config/config.service.ts deleted file mode 100644 index 01aa1b5..0000000 --- a/MyOffice.SPA/src/app/config/config.service.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Injectable } from '@angular/core'; -import { InConfiguration } from '../core/models/config.interface'; - -@Injectable({ - providedIn: 'root', -}) -export class ConfigService { - configData!: InConfiguration; - - constructor() { - this.setConfigData(); - } - - setConfigData() { - this.configData = { - layout: { - rtl: false, // options: true & false - variant: 'light', // options: light & dark - theme_color: 'white', // options: white, black, purple, blue, cyan, green, orange - logo_bg_color: 'white', // options: white, black, purple, blue, cyan, green, orange - sidebar: { - collapsed: false, // options: true & false - backgroundColor: 'light', // options: light & dark - }, - }, - }; - } -} diff --git a/MyOffice.SPA/src/app/config/ui.config.ts b/MyOffice.SPA/src/app/config/ui.config.ts deleted file mode 100644 index d379726..0000000 --- a/MyOffice.SPA/src/app/config/ui.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** Placement of Cancel/Save (and similar) actions in Material dialogs. */ -export type ModalButtonsPosition = 'top' | 'bottom'; - -export const UI_CONFIG = { - /** Dialog action buttons: `top` (next to title) or `bottom` (under content). */ - modal_buttons: 'top' as ModalButtonsPosition, -}; diff --git a/MyOffice.SPA/src/app/core/core.module.ts b/MyOffice.SPA/src/app/core/core.module.ts deleted file mode 100644 index af58986..0000000 --- a/MyOffice.SPA/src/app/core/core.module.ts +++ /dev/null @@ -1,63 +0,0 @@ -// angular -import { NgModule } from '@angular/core'; -import { Optional } from '@angular/core'; -import { SkipSelf } from '@angular/core'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { APP_INITIALIZER } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -// libs -import { OAuthModule, OAuthModuleConfig, OAuthStorage } from 'angular-oauth2-oidc'; -import { AuthConfig } from 'angular-oauth2-oidc'; -import { AuthModule } from '@auth0/auth0-angular'; -import { SocialLoginModule } from '@abacritt/angularx-social-login'; - -// app -import { AuthGuard } from './guard/auth.guard'; -import { RightSidebarService } from './service/rightsidebar.service'; -import { AuthService, authAppInitializerFactory } from './service/auth.service'; -import { DirectionService } from './service/direction.service'; -import { throwIfAlreadyLoaded } from './guard/module-import.guard'; -import { OidcHelperService } from './service/oidc-helper.service'; -import { AuthCodeFlowConfig, AuthModuleConfig } from '../config.oidc'; -import { SubjectExtensions } from './extensions/general.extensions'; -import { ExternalLoginConfig } from '../config.external-login'; -import { AccountCategoryService } from '../services/account.category.service'; -import { AccountService } from '../services/account.service'; - -export function storageFactory(): OAuthStorage { - return localStorage; -} - -@NgModule({ - declarations: [], - imports: [ - CommonModule, - SocialLoginModule, - OAuthModule.forRoot(), - AuthModule.forRoot(ExternalLoginConfig.getAuth0Config()), - ], - providers: [ - { provide: APP_INITIALIZER, useFactory: authAppInitializerFactory, deps: [AuthService], multi: true }, - { provide: AuthConfig, useValue: AuthCodeFlowConfig }, - { provide: OAuthModuleConfig, useValue: AuthModuleConfig }, - { provide: OAuthStorage, useFactory: storageFactory }, - { provide: 'SocialAuthServiceConfig', useValue: ExternalLoginConfig.getSocialConfig() }, - RightSidebarService, - AuthGuard, - AuthService, - DirectionService, - OidcHelperService, - SubjectExtensions, - AccountCategoryService, - AccountService, - ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA - ] -}) -export class CoreModule { - constructor(@Optional() @SkipSelf() parentModule: CoreModule) { - throwIfAlreadyLoaded(parentModule, 'CoreModule'); - } -} diff --git a/MyOffice.SPA/src/app/core/extensions/general.extensions.ts b/MyOffice.SPA/src/app/core/extensions/general.extensions.ts deleted file mode 100644 index 515c2db..0000000 --- a/MyOffice.SPA/src/app/core/extensions/general.extensions.ts +++ /dev/null @@ -1,42 +0,0 @@ -// angular -import { ActivatedRoute } from '@angular/router'; - -// libs -import { BehaviorSubject, Observable, Subject, of, throwError, from, combineLatest } from 'rxjs'; - -import { getSafeRedirectUrl } from '../utils/safe-redirect'; - -export { } - -declare global { - interface RouterExtensions { - addDays(days: number): Date; - } - } - -export class ExActivatedRoute extends ActivatedRoute { - - getCurrentRoute(): string { - const raw = this.snapshot.queryParams['r'] as string | undefined; - return getSafeRedirectUrl(raw); - } -} - -interface Action { - (item: T): void; -} - -interface Func { - (item: T): TResult; -} - -export class SubjectExtensions { - - static start(start: Action>): Subject { - var result = new Subject(); - - start(result); - - return result; - } -} diff --git a/MyOffice.SPA/src/app/core/extensions/router.extensions.ts b/MyOffice.SPA/src/app/core/extensions/router.extensions.ts deleted file mode 100644 index ed347f0..0000000 --- a/MyOffice.SPA/src/app/core/extensions/router.extensions.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ActivatedRoute } from '@angular/router'; -import { getSafeRedirectUrl } from '../utils/safe-redirect'; - -export { } - -declare global { - interface RouterExtensions { - addDays(days: number): Date; - } - } - -export class ExActivatedRoute extends ActivatedRoute { - - getCurrentRoute(): string { - const raw = this.snapshot.queryParams['r'] as string | undefined; - return getSafeRedirectUrl(raw); - } -} diff --git a/MyOffice.SPA/src/app/core/guard/auth.guard.ts b/MyOffice.SPA/src/app/core/guard/auth.guard.ts deleted file mode 100644 index ce462cb..0000000 --- a/MyOffice.SPA/src/app/core/guard/auth.guard.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; - -import { AuthService } from '../service/auth.service'; - -@Injectable({ - providedIn: 'root', -}) -export class AuthGuard { - constructor( - private authService: AuthService, - private router: Router - ) { - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { - if (this.authService.isAuthenticated) { - return true; - } - this.router.navigate(['/authentication/signin'], { queryParams: { r: encodeURIComponent(state.url) } }); - return false; - } -} diff --git a/MyOffice.SPA/src/app/core/guard/module-import.guard.ts b/MyOffice.SPA/src/app/core/guard/module-import.guard.ts deleted file mode 100644 index 3526a01..0000000 --- a/MyOffice.SPA/src/app/core/guard/module-import.guard.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CoreModule } from '../core.module'; - -export function throwIfAlreadyLoaded( - parentModule: CoreModule, - moduleName: string -) { - if (parentModule) { - throw new Error( - `${moduleName} has already been loaded. Import ${moduleName} modules in the AppModule only.` - ); - } -} diff --git a/MyOffice.SPA/src/app/core/interceptor/error.interceptor.ts b/MyOffice.SPA/src/app/core/interceptor/error.interceptor.ts deleted file mode 100644 index 33c54b4..0000000 --- a/MyOffice.SPA/src/app/core/interceptor/error.interceptor.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { AuthService } from '../service/auth.service'; -import { Injectable } from '@angular/core'; -import { Router } from '@angular/router'; -import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; -import { Observable, throwError } from 'rxjs'; -import { catchError } from 'rxjs/operators'; - -@Injectable() -export class ErrorInterceptor implements HttpInterceptor { - constructor( - private authenticationService: AuthService, - private router: Router - ) {} - - intercept( - request: HttpRequest, - next: HttpHandler - ): Observable> { - return next.handle(request).pipe( - catchError((err) => { - if (err.status === 401) { - const returnUrl = this.router.url; - this.authenticationService.logout(); - void this.router.navigate(['/authentication/signin'], { - queryParams: returnUrl && returnUrl !== '/' - ? { r: returnUrl } - : undefined, - }); - } - - let error = err.error || err.message || err.statusText; - - if (!error) { - console.log('not parsed error', err); - } - return throwError(() => error); - }) - ); - } -} diff --git a/MyOffice.SPA/src/app/core/interceptor/fake-backend.ts b/MyOffice.SPA/src/app/core/interceptor/fake-backend.ts deleted file mode 100644 index 9b64489..0000000 --- a/MyOffice.SPA/src/app/core/interceptor/fake-backend.ts +++ /dev/null @@ -1,101 +0,0 @@ -/*import { Injectable } from '@angular/core'; -import { - HttpRequest, - HttpResponse, - HttpHandler, - HttpEvent, - HttpInterceptor, - HTTP_INTERCEPTORS, -} from '@angular/common/http'; -import { Observable, of, throwError } from 'rxjs'; -import { mergeMap } from 'rxjs/operators'; -import { UserModel } from '../models/user.model'; - -const users: UserModel[] = [ - { - id: 'fake-user', - img: 'assets/images/user/admin.jpg', - username: 'admin@software.com', - //password: 'admin@123', - firstName: 'Sarah', - lastName: 'Smith', - token: 'admin-token', - }, -]; - -@Injectable() -export class FakeBackendInterceptor implements HttpInterceptor { - intercept( - request: HttpRequest, - next: HttpHandler - ): Observable> { - const { url, method, headers, body } = request; - // wrap in delayed observable to simulate server api call - return of(null).pipe(mergeMap(handleRoute)); - - function handleRoute() { - switch (true) { - case url.endsWith('/authenticate') && method === 'POST': - return authenticate(); - default: - // pass through any requests not handled above - return next.handle(request); - } - } - - // route functions - - function authenticate() { - const { username, password } = body; - const user = users.find( - (x) => x.username === username && x.password === password - ); - if (!user) { - return error('Username or password is incorrect'); - } - return ok({ - id: user.id, - username: user.username, - img: user.img, - firstName: user.firstName, - lastName: user.lastName, - token: user.token, - }); - } - - // helper functions - - function ok(body?: { - id: string; - username: string; - img?: string; - firstName?: string; - lastName?: string; - token?: string; - }) { - return of(new HttpResponse({ status: 200, body })); - } - - function error(message: string) { - return throwError({ error: { message } }); - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function unauthorized() { - return throwError({ status: 401, error: { message: 'Unauthorised' } }); - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function isLoggedIn() { - return headers.get('Authorization') === 'Bearer fake-jwt-token'; - } - } -} - -export const fakeBackendProvider = { - // use fake backend in place of Http service for backend-less development - provide: HTTP_INTERCEPTORS, - useClass: FakeBackendInterceptor, - multi: true, -}; -*/ diff --git a/MyOffice.SPA/src/app/core/interceptor/update.date.http.interceptor .ts b/MyOffice.SPA/src/app/core/interceptor/update.date.http.interceptor .ts deleted file mode 100644 index 594334e..0000000 --- a/MyOffice.SPA/src/app/core/interceptor/update.date.http.interceptor .ts +++ /dev/null @@ -1,42 +0,0 @@ -// angular -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { HttpInterceptor } from '@angular/common/http'; -import { HttpRequest } from '@angular/common/http'; -import { HttpHandler } from '@angular/common/http'; -import { HttpEvent } from '@angular/common/http'; - -// libs -import moment from 'moment'; - - -@Injectable() -export class UpdateDateHttpInterceptor implements HttpInterceptor { - - intercept(request: HttpRequest, next: HttpHandler): Observable> { - if (request.method === 'POST' || request.method === 'PUT') { - this.shiftDates(request.body); - } - - return next.handle(request); - } - - shiftDates(body: any) { - if (body === null || body === undefined) { - return body; - } - - if (typeof body !== 'object') { - return body; - } - - for (const key of Object.keys(body)) { - const value = body[key]; - if (value instanceof Date) { - body[key] = moment(value).utcOffset(0, true).format(); - } else if (typeof value === 'object') { - this.shiftDates(value); - } - } - } -} diff --git a/MyOffice.SPA/src/app/core/models/config.interface.ts b/MyOffice.SPA/src/app/core/models/config.interface.ts deleted file mode 100644 index fea99e3..0000000 --- a/MyOffice.SPA/src/app/core/models/config.interface.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface InConfiguration { - layout: { - rtl: boolean; - variant: string; - theme_color: string; - logo_bg_color: string; - sidebar: { - collapsed: boolean; - backgroundColor: string; - }; - }; -} diff --git a/MyOffice.SPA/src/app/core/models/general-error.model.ts b/MyOffice.SPA/src/app/core/models/general-error.model.ts deleted file mode 100644 index 2cbcb47..0000000 --- a/MyOffice.SPA/src/app/core/models/general-error.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface GeneralErrorModel { - //succeeded?: boolean; - code?: string; - description?: string; - errors?: GeneralErrorModel[]; -} diff --git a/MyOffice.SPA/src/app/core/models/general-result.model.ts b/MyOffice.SPA/src/app/core/models/general-result.model.ts deleted file mode 100644 index 5f3950d..0000000 --- a/MyOffice.SPA/src/app/core/models/general-result.model.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GeneralErrorModel } from './general-error.model'; - -export interface GeneralResultModel { - success: boolean; - error?: GeneralErrorModel; - data?: any; -} diff --git a/MyOffice.SPA/src/app/core/models/login.model.ts b/MyOffice.SPA/src/app/core/models/login.model.ts deleted file mode 100644 index 2de9c3c..0000000 --- a/MyOffice.SPA/src/app/core/models/login.model.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface LoginModel { - username: string; - password: string; -} diff --git a/MyOffice.SPA/src/app/core/models/register.model.ts b/MyOffice.SPA/src/app/core/models/register.model.ts deleted file mode 100644 index ab84657..0000000 --- a/MyOffice.SPA/src/app/core/models/register.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface RegisterModel { - username: string; - password: string; - confirmPassword: string; -} diff --git a/MyOffice.SPA/src/app/core/models/selectable.model.spec.ts b/MyOffice.SPA/src/app/core/models/selectable.model.spec.ts deleted file mode 100644 index 1c4ee7b..0000000 --- a/MyOffice.SPA/src/app/core/models/selectable.model.spec.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { SelectableModel } from './selectable.model'; - -describe('SelectableModel', () => { - it('should create an instance', () => { - expect(new SelectableModel()).toBeTruthy(); - }); -}); diff --git a/MyOffice.SPA/src/app/core/models/selectable.model.ts b/MyOffice.SPA/src/app/core/models/selectable.model.ts deleted file mode 100644 index bba11c1..0000000 --- a/MyOffice.SPA/src/app/core/models/selectable.model.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface ISelectableModel { - model: T; - selected: boolean; -} diff --git a/MyOffice.SPA/src/app/core/models/user-profile.model.ts b/MyOffice.SPA/src/app/core/models/user-profile.model.ts deleted file mode 100644 index ce03098..0000000 --- a/MyOffice.SPA/src/app/core/models/user-profile.model.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface UserProfileModel { - id: string; - email?: string; - phone?: string; - firstName?: string; - lastName?: string; - fullName?: string; - currency?: string; -} diff --git a/MyOffice.SPA/src/app/core/models/user.model.ts b/MyOffice.SPA/src/app/core/models/user.model.ts deleted file mode 100644 index 7a9298e..0000000 --- a/MyOffice.SPA/src/app/core/models/user.model.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface UserModel { - id: string; - userName: string; - img?: string; - firstName?: string; - lastName?: string; - email?: string; - //token?: string; -} diff --git a/MyOffice.SPA/src/app/core/service/auth.service.spec.ts b/MyOffice.SPA/src/app/core/service/auth.service.spec.ts deleted file mode 100644 index 9b6666e..0000000 --- a/MyOffice.SPA/src/app/core/service/auth.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { AuthService } from './auth.service'; - -describe('AuthService', - () => { - let service: AuthService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(AuthService); - }); - - it('should be created', - () => { - expect(service).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/core/service/auth.service.ts b/MyOffice.SPA/src/app/core/service/auth.service.ts deleted file mode 100644 index 2e19184..0000000 --- a/MyOffice.SPA/src/app/core/service/auth.service.ts +++ /dev/null @@ -1,266 +0,0 @@ -// angular -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Router } from '@angular/router'; -import { ActivatedRoute } from '@angular/router'; - -// libs -import { BehaviorSubject } from 'rxjs'; -import { Observable } from 'rxjs'; -import { Subject } from 'rxjs'; -import { of } from 'rxjs'; -import { throwError } from 'rxjs'; -import { from } from 'rxjs'; -import { filter, map, switchMap } from 'rxjs/operators'; -import { catchError } from 'rxjs/operators'; -import { AuthService as Auth0Service } from '@auth0/auth0-angular'; - -import { SocialAuthService } from '@abacritt/angularx-social-login'; -import { GoogleLoginProvider } from '@abacritt/angularx-social-login'; - -// app -import { OidcHelperService } from './oidc-helper.service'; -import { UserModel } from '../models/user.model'; -import { ApiRoutes } from '../../api-routes'; -import { RegisterModel } from '../models/register.model'; -import { LoginModel } from '../models/login.model'; -import { UserProfileModel } from '../models/user-profile.model'; -import { GeneralResultModel } from '../models/general-result.model'; -import { getSafeRedirectUrl } from '../utils/safe-redirect'; -import { SubjectExtensions } from '../extensions/general.extensions'; - -export function authAppInitializerFactory(authService: AuthService): () => Promise { - if (window.location.href.indexOf('/silent-refresh.html') !== -1) { - return () => Promise.resolve(); - } - return () => authService.runInitialLoginSequence(); -} - -@Injectable({ - providedIn: 'root', -}) -export class AuthService { - private currentUserSubject: BehaviorSubject; - currentUser$: Observable; - - private isAuthenticatedSubject$ = new BehaviorSubject(false); - isAuthenticated$ = this.isAuthenticatedSubject$.asObservable(); - - constructor( - private http: HttpClient, - private router: Router, - private route: ActivatedRoute, - private oidcHelperService: OidcHelperService, - private auth0Service: Auth0Service, - private externalAuthService: SocialAuthService, - ) { - this.currentUserSubject = new BehaviorSubject({} as UserModel); - this.currentUser$ = this.currentUserSubject.asObservable(); - - // on external social login - this.externalAuthService.authState.subscribe((user) => { - if (user?.idToken) { - oidcHelperService.loginByExternalLogin('google', user.idToken); - } - }); - - this.oidcHelperService.isDoneLoading$ - .pipe( - filter(isDone => isDone), - switchMap(() => this.oidcHelperService.isAuthenticated$) - ) - .subscribe(authState => { - let redirectUrl = this.getRedirect(); - if (authState.isAuthenticated) { - this.oidcHelperService.loadUserProfile().then(e => { - let resp = (e as any).info; - let userProfile = { - id: resp.id, - email: resp.email, - phone: resp.phone, - firstName: resp.firstName, - lastName: resp.lastName, - fullName: resp.fullName, - }; - - this.setCurrentUserValue(userProfile.id, userProfile); - - if (authState.action === AuthenticatedActionEnum.loggedIn) { - this.router.navigate([redirectUrl || '/dashboard/rests']); - } - }); - } - }); - } - - setCurrentUserValue(id: string, profile?: UserProfileModel) { - this.currentUserSubject.next({ - id: id, - img: 'assets/images/user/admin.jpg', - userName: profile?.email || '', - firstName: profile?.firstName || '', - lastName: profile?.lastName || '', - }); - } - - get currentUserValue(): UserModel { - return this.currentUserSubject.value; - } - - login(loginModel: LoginModel): Subject { - return SubjectExtensions.start(subject => { - this.oidcHelperService - .login(loginModel.username, loginModel.password) - .subscribe(resp => { - if (resp.access_token) { - this.isAuthenticatedSubject$.next(true); - } - subject.next({ success: !!(resp.access_token) }); - }, - err => { - subject.next({ success: false, error: err.error }); - }); - }); - } - - logout() { - this.currentUserSubject.next({} as UserModel); - this.isAuthenticatedSubject$.next(false); - this.oidcHelperService.logout(); - - return of({ success: false }); - } - - register(registerModel: RegisterModel): Observable { - return this.http - .post(ApiRoutes.UserRegister, registerModel) - .pipe( - map(resp => resp), - catchError(error => { - return throwError(error); - }) - ); - } - - runInitialLoginSequence() { - return this.oidcHelperService.runInitialLoginSequence(); - } - - get isAuthenticated(): boolean { - return this.oidcHelperService.hasValidAccessToken(); - } - - getAccessToken() { - return this.oidcHelperService.getAccessToken(); - } - - loginGoogle(redirectUrl?: string): Observable { - return from(this.externalAuthService.signIn(GoogleLoginProvider.PROVIDER_ID)); - } - - attachGoogle(): Observable { - var result = new Subject(); - - /*this.externalAuthService.signIn(GoogleLoginProvider.PROVIDER_ID).then(function (resp) { - //console.log('attachGoogle', resp); - //return result.next(resp); - //this.attach(idToken.__raw, result); - });*/ - - return result; - } - - loginAuth0(): Observable { - return SubjectExtensions.start((subject) => { - var subs = this.auth0Service.idTokenClaims$.subscribe(token => { - if (token && token?.__raw) { - subs.unsubscribe(); - - this.oidcHelperService.loginByExternalLogin('auth0', token.__raw).subscribe(login => { - if (login.success) { - this.isAuthenticatedSubject$.next(true); - } - subject.next({ success: login.success, error: login.error }); - }); - } else { - //subject.next({ success: false, error: { description: 'Login failed' } }); - } - }); - - this.auth0Service.getAccessTokenWithPopup().subscribe(popupToken => { - if (!popupToken) { - this.auth0Service.getAccessTokenSilently().subscribe(silently => { - }); - } - }); - }); - } - - attachAuth0(): Observable { - return SubjectExtensions.start((subject) => { - var subs = this.auth0Service.idTokenClaims$.subscribe(token => { - if (token && token?.__raw) { - subs.unsubscribe(); - - this.attach(token?.__raw).subscribe( - (resp) => subject.next({ success: true, data: token?.__raw }), - (err) => subject.next({ success: false, data: err }) - ); - } else { - subject.next({ success: false, data: 'Failed' }); - } - }); - - this.auth0Service.getAccessTokenWithPopup().subscribe(popupToken => { - if (!popupToken) { - this.auth0Service.getAccessTokenSilently().subscribe(silently => { - }); - } - }); - }); - } - - deattach(provider: string): Observable { - return this.http - .post(ApiRoutes.UserDeattach, { provider: provider }) - .pipe( - catchError(error => throwError(() => error)) - ); - } - - private attach(token: string): Observable { - return this.http.post(ApiRoutes.UserAttach, { - provider: 'auth0', - token: token, - }); - } - - private getRedirect(): string | undefined { - const raw = this.route.snapshot.queryParams['r'] as string | undefined; - if (!raw) { - return undefined; - } - const safe = getSafeRedirectUrl(raw, ''); - return safe || undefined; - } -} - -export enum AuthenticatedActionEnum { - init, - update, - loggedIn, - loggedOff, -} - -export interface IAuthenticatedState { - isAuthenticated: boolean, - action: AuthenticatedActionEnum, - redirectUrl?: string, -} - -export enum StateEnum { - undefined, - inited, - completed, - failed, -} diff --git a/MyOffice.SPA/src/app/core/service/direction.service.ts b/MyOffice.SPA/src/app/core/service/direction.service.ts deleted file mode 100644 index 9acd559..0000000 --- a/MyOffice.SPA/src/app/core/service/direction.service.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; - -@Injectable() -export class DirectionService { - private data = new BehaviorSubject(''); - currentData = this.data.asObservable(); - - constructor() { - //constructor - } - - updateDirection(item: string) { - this.data.next(item); - } -} diff --git a/MyOffice.SPA/src/app/core/service/language.service.ts b/MyOffice.SPA/src/app/core/service/language.service.ts deleted file mode 100644 index 27a17cc..0000000 --- a/MyOffice.SPA/src/app/core/service/language.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Injectable } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; - -@Injectable({ - providedIn: 'root', -}) -export class LanguageService { - languages: string[] = ['en', 'es', 'de', 'ua']; - - constructor(public translate: TranslateService) { - let browserLang: string; - translate.addLangs(this.languages); - - if (localStorage.getItem('lang')) { - browserLang = localStorage.getItem('lang') as string; - } else { - browserLang = translate.getBrowserLang() as string; - } - translate.use(browserLang.match(/en|es|de|ua/) ? browserLang : 'en'); - } - - setLanguage(lang: string) { - this.translate.use(lang); - localStorage.setItem('lang', lang); - } -} diff --git a/MyOffice.SPA/src/app/core/service/oidc-helper.service.ts b/MyOffice.SPA/src/app/core/service/oidc-helper.service.ts deleted file mode 100644 index 0626ca4..0000000 --- a/MyOffice.SPA/src/app/core/service/oidc-helper.service.ts +++ /dev/null @@ -1,252 +0,0 @@ -// angular -import { Injectable } from '@angular/core'; -import { Router } from '@angular/router'; -import { OAuthService } from 'angular-oauth2-oidc'; -import { OAuthErrorEvent } from 'angular-oauth2-oidc'; - -// libs -import { filter, map } from 'rxjs/operators'; -import { Subject, Observable, BehaviorSubject, from } from 'rxjs'; - -// app -import { GeneralResultModel } from '../models/general-result.model'; - -@Injectable() -export class OidcHelperService { - private isAuthenticatedSubject$ = new BehaviorSubject({ - isAuthenticated: false, - action: AuthenticatedActionEnum.init - }); - isAuthenticated$ = this.isAuthenticatedSubject$.asObservable(); - - private isDoneLoadingFailed = false; - private isDoneLoadingSubject$ = new BehaviorSubject(false); - isDoneLoading$ = this.isDoneLoadingSubject$.asObservable(); - - constructor( - private oauthService: OAuthService, - private router: Router, - ) { - this.oauthService.oidc = false; - - // all events handler - this.oauthService.events.subscribe(event => { - if (event instanceof OAuthErrorEvent) { - console.error('OAuthErrorEvent Object:', event); - if (event.type === 'discovery_document_validation_error') { - this.isDoneLoadingFailed = true; - this.setIsAuthenticatedSubject$(false, AuthenticatedActionEnum.update); - } - } else { - var hasValidAccessToken = this.hasValidAccessToken(); - var isAuthenticated = this.isAuthenticatedSubject$.getValue().isAuthenticated; - if (isAuthenticated !== hasValidAccessToken) { - this.setIsAuthenticatedSubject$(hasValidAccessToken, AuthenticatedActionEnum.update); - } - } - }); - - // This is tricky, as it might cause race conditions (where access_token is set in another - // tab before everything is said and done there. - // TODO: Improve this setup. See: https://github.com/jeroenheijmans/sample-angular-oauth2-oidc-with-auth-guards/issues/2 - window.addEventListener('storage', - (event) => { - // The `key` is `null` if the event was caused by `.clear()` - if (event.key !== 'access_token' && event.key !== null) { - return; - } - - console.warn( - 'Noticed changes to access_token (most likely from another tab), updating isAuthenticated'); - this.setIsAuthenticatedSubject$(this.hasValidAccessToken(), AuthenticatedActionEnum.update); - - if (!this.hasValidAccessToken()) { - console.log('storage access_token updated !this.hasValidAccessToken()'); - this.logout(); - this.navigateToLoginPage(); - } - }); - - // init login stata - this.setIsAuthenticatedSubject$(this.hasValidAccessToken(), AuthenticatedActionEnum.update); - - // TODO: some time receive 'message' with data 'error' == 'session_error'' - /*window.addEventListener('message', e => { - console.log('message', e);; - if (e.origin === 'https://dev-w08xm0pi.us.auth0.com') { - console.log('message stopPropagation');; - e.stopPropagation(); - } - }); - this.oauthService.events.subscribe(x => { - console.log('events', x); - });*/ - this.oauthService.events - .pipe(filter(e => ['session_terminated', 'session_error'].includes(e.type))) - .subscribe(e => { - console.log('events session_terminated', e, this.hasValidAccessToken()); - this.navigateToLoginPage(); - }); - - this.oauthService.setupAutomaticSilentRefresh(); - } - - private setIsAuthenticatedSubject$( - isAuthenticated: boolean, - action: AuthenticatedActionEnum - ) { - var state = this.isAuthenticatedSubject$.getValue(); - if (state.isAuthenticated !== isAuthenticated || state.action !== action - ) { - this.isAuthenticatedSubject$.next({ isAuthenticated, action }); - } - } - - private navigateToLoginPage() { - this.router.navigateByUrl('/authentication/signin'); - } - - logout() { - this.oauthService.logOut(true); - } - - refresh() { - const refreshToken = this.oauthService.getRefreshToken(); - if (refreshToken) { - this.oauthService.refreshToken(); - } - } - - hasValidAccessToken() { - return this.oauthService.hasValidAccessToken(); - } - - getAccessToken() { - return this.oauthService.getAccessToken(); - } - - login(username: string, password: string) { - //return this.oauthService.fetchTokenUsingPasswordFlow(username, password); - return from(this.oauthService.fetchTokenUsingPasswordFlow(username, password)); - } - - loginByExternalLogin( - provider: string, - token: string, - redirectUrl?: string - ): Observable { - var result = new Subject(); - - let params = { - token: token, - provider: provider, - }; - this.oauthService - .fetchTokenUsingGrant('external', params) - .then(x => { - this.setIsAuthenticatedSubject$(this.hasValidAccessToken(), AuthenticatedActionEnum.loggedIn); - result.next({ success: true }); - }) - .catch(err => { - result.next({ success: false, error: { code: err, description: err } }); - }); - - return result; - } - - loadUserProfile(): Promise { - return this.oauthService.loadUserProfile(); - } - - runInitialLoginSequence(): Promise { - if (location.hash) { - //console.log('Encountered hash fragment, plotting as table...'); - //console.table(location.hash.substr(1).split('&').map(kvp => kvp.split('='))); - } - if (this.isDoneLoadingFailed) { - return new Promise(resolve => setTimeout(() => resolve(), 1500)); - } - // 0. LOAD CONFIG: - // First we have to check to see how the IdServer is - // currently configured: - return this.oauthService.loadDiscoveryDocument() - - // For demo purposes, we pretend the previous call was very slow - .then(() => { - new Promise(resolve => setTimeout(() => resolve(), 1500)); - }) - - // 1. HASH LOGIN: - // Try to log in via hash fragment after redirect back - // from IdServer from initImplicitFlow: - .then(() => { - this.oauthService.tryLogin(); - }) - .then(() => { - if (this.hasValidAccessToken()) { - return Promise.resolve(); - } - - // Refresh via refresh_token (no /connect/authorize cookie session). - const refreshToken = this.oauthService.getRefreshToken(); - if (!refreshToken) { - return Promise.resolve(); - } - - return this.oauthService.refreshToken() - .then(() => Promise.resolve()) - .catch(result => { - const error = - result?.reason?.error ?? - result?.params?.error ?? - result?.error; - const softErrors = [ - 'interaction_required', - 'login_required', - 'account_selection_required', - 'consent_required', - 'access_denied', - 'invalid_grant', - ]; - - if (error && softErrors.indexOf(error) >= 0) { - console.warn('Token refresh needs user login.', error); - return Promise.resolve(); - } - - return Promise.reject(result); - }); - }) - .then(() => { - this.isDoneLoadingSubject$.next(true); - - // Check for the strings 'undefined' and 'null' just to be sure. Our current - // login(...) should never have this, but in case someone ever calls - // initImplicitFlow(undefined | null) this could happen. - if (this.oauthService.state && - this.oauthService.state !== 'undefined' && - this.oauthService.state !== 'null') { - let stateUrl = this.oauthService.state; - if (stateUrl.startsWith('/') === false) { - stateUrl = decodeURIComponent(stateUrl); - } - console.log(`There was state of ${this.oauthService.state}, so we are sending you to: ${stateUrl}`); - this.router.navigateByUrl(stateUrl); - } - }) - .catch(() => this.isDoneLoadingSubject$.next(true)); - } -} - -export enum AuthenticatedActionEnum { - init, - update, - loggedIn, - loggedOff, -} - -export interface IAuthenticatedState { - isAuthenticated: boolean, - action: AuthenticatedActionEnum, - redirectUrl?: string, -} diff --git a/MyOffice.SPA/src/app/core/service/rightsidebar.service.ts b/MyOffice.SPA/src/app/core/service/rightsidebar.service.ts deleted file mode 100644 index 7b5d47b..0000000 --- a/MyOffice.SPA/src/app/core/service/rightsidebar.service.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; - -@Injectable() -export class RightSidebarService { - private sidebarSubject: BehaviorSubject = new BehaviorSubject(false); - sidebarState = this.sidebarSubject.asObservable(); - - setRightSidebar = (value: boolean) => { - this.sidebarSubject.next(value); - }; - - constructor() { - //constructor - } -} diff --git a/MyOffice.SPA/src/app/core/utils/safe-redirect.spec.ts b/MyOffice.SPA/src/app/core/utils/safe-redirect.spec.ts deleted file mode 100644 index 4e295e0..0000000 --- a/MyOffice.SPA/src/app/core/utils/safe-redirect.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { getSafeRedirectUrl } from './safe-redirect'; - -describe('getSafeRedirectUrl', () => { - it('returns fallback when raw is empty', () => { - expect(getSafeRedirectUrl(null)).toBe('/dashboard/rests'); - expect(getSafeRedirectUrl(undefined)).toBe('/dashboard/rests'); - expect(getSafeRedirectUrl('')).toBe('/dashboard/rests'); - }); - - it('allows relative in-app paths', () => { - expect(getSafeRedirectUrl('/accounts')).toBe('/accounts'); - expect(getSafeRedirectUrl('%2Fdashboard%2Frests')).toBe('/dashboard/rests'); - }); - - it('blocks open redirects', () => { - expect(getSafeRedirectUrl('//evil.com')).toBe('/dashboard/rests'); - expect(getSafeRedirectUrl('https://evil.com')).toBe('/dashboard/rests'); - expect(getSafeRedirectUrl('http://evil.com')).toBe('/dashboard/rests'); - expect(getSafeRedirectUrl('/path?next=https://evil.com')).toBe('/dashboard/rests'); - }); -}); - diff --git a/MyOffice.SPA/src/app/core/utils/safe-redirect.ts b/MyOffice.SPA/src/app/core/utils/safe-redirect.ts deleted file mode 100644 index 90bb5ac..0000000 --- a/MyOffice.SPA/src/app/core/utils/safe-redirect.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Only allow in-app relative paths (blocks open redirects via ?r=). - */ -export function getSafeRedirectUrl( - raw: string | null | undefined, - fallback = '/dashboard/rests' -): string { - if (!raw) { - return fallback; - } - - let url: string; - try { - url = decodeURIComponent(raw).trim(); - } catch { - return fallback; - } - - if (!url.startsWith('/') || url.startsWith('//') || url.includes('://')) { - return fallback; - } - - return url; -} diff --git a/MyOffice.SPA/src/app/core/validators/atleastone.validator.ts b/MyOffice.SPA/src/app/core/validators/atleastone.validator.ts deleted file mode 100644 index 8968db7..0000000 --- a/MyOffice.SPA/src/app/core/validators/atleastone.validator.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - FormGroup, - ValidationErrors, - ValidatorFn, - Validators, -} from '@angular/forms'; - -export const atLeastOne = (validator: ValidatorFn, controls: string[] = []) => ( - group: FormGroup, -): ValidationErrors | null => { - if (!controls) { - controls = Object.keys(group.controls); - } - - const hasAtLeastOne = group && group.controls && controls - .some(k => !validator(group.controls[k])); - - return hasAtLeastOne ? null : { - atLeastOne: true, - }; -}; diff --git a/MyOffice.SPA/src/app/core/validators/atleastonenumber.validator.ts b/MyOffice.SPA/src/app/core/validators/atleastonenumber.validator.ts deleted file mode 100644 index 49cdcb2..0000000 --- a/MyOffice.SPA/src/app/core/validators/atleastonenumber.validator.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - FormGroup, - ValidationErrors, - ValidatorFn, - Validators, -} from '@angular/forms'; - -export const atLeastOneNumber = (validator: ValidatorFn, controls: string[] = []) => - (group: FormGroup,): ValidationErrors | null => { - - if (!controls) { - controls = Object.keys(group.controls); - } - - const hasAtLeastOne = group && group.controls && controls - .some(k => { - var v = group.controls[k].value; - return !!(v && !isNaN(v) && parseFloat(v) !== 0 && !validator(group.controls[k])); - }); - - return hasAtLeastOne ? null : { - atLeastOne: true, - }; - }; diff --git a/MyOffice.SPA/src/app/dashboard/dashboard-routing.module.ts b/MyOffice.SPA/src/app/dashboard/dashboard-routing.module.ts deleted file mode 100644 index d53cfa3..0000000 --- a/MyOffice.SPA/src/app/dashboard/dashboard-routing.module.ts +++ /dev/null @@ -1,37 +0,0 @@ -// angular -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; - -// app -import { Page404Component } from '../authentication/page404/page404.component'; -import { Dashboard2Component } from './dashboard2/dashboard2.component'; -import { DashboardIncomeComponent } from './income/dashboard.component'; -import { DashboardOutcomeComponent } from './outcome/dashboard.component'; - -const routes: Routes = [ - { - path: '', - redirectTo: 'rests', - pathMatch: 'full', - }, - { - path: 'rests', - component: Dashboard2Component, - }, - { - path: 'income', - component: DashboardIncomeComponent, - }, - { - path: 'outcome', - component: DashboardOutcomeComponent, - }, - { path: '**', component: Page404Component }, -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class DashboardRoutingModule { -} diff --git a/MyOffice.SPA/src/app/dashboard/dashboard.module.ts b/MyOffice.SPA/src/app/dashboard/dashboard.module.ts deleted file mode 100644 index 6c769a5..0000000 --- a/MyOffice.SPA/src/app/dashboard/dashboard.module.ts +++ /dev/null @@ -1,55 +0,0 @@ -// angular -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { DecimalPipe } from '@angular/common'; - -// libs -import { NgScrollbarModule } from 'ngx-scrollbar'; -import { MatIconModule } from '@angular/material/icon'; -import { MatButtonModule } from '@angular/material/button'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { DragDropModule } from '@angular/cdk/drag-drop'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { NgApexchartsModule } from 'ng-apexcharts'; -import { TranslateModule } from '@ngx-translate/core'; -import { MAT_DATE_LOCALE } from '@angular/material/core'; - -// app -import { DashboardRoutingModule } from './dashboard-routing.module'; -import { Dashboard2Component } from './dashboard2/dashboard2.component'; -import { DashboardIncomeComponent } from './income/dashboard.component'; -import { DashboardOutcomeComponent } from './outcome/dashboard.component'; -import { ComponentsModule } from 'src/app/shared/components/components.module'; -import { SharedModule } from '../shared/shared.module'; - -@NgModule({ - declarations: [ - Dashboard2Component, - DashboardIncomeComponent, - DashboardOutcomeComponent, - ], - imports: [ - CommonModule, - DashboardRoutingModule, - NgApexchartsModule, - NgScrollbarModule, - MatIconModule, - MatButtonModule, - MatMenuModule, - MatTooltipModule, - MatCheckboxModule, - DragDropModule, - MatProgressBarModule, - ComponentsModule, - SharedModule, - TranslateModule, - ], - providers: [ - { provide: MAT_DATE_LOCALE, useValue: 'en-GB' }, - DecimalPipe, - ] -}) -export class DashboardModule { -} diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.html b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.html deleted file mode 100644 index 919b567..0000000 --- a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.html +++ /dev/null @@ -1,103 +0,0 @@ -
-
-
- - -
- -
- -
-
-
-
-
-
{{'BALANCE' | translate}}
-
-

{{dashboardModel?.balance | number: '0.2-2'}}

-
-
-
-
- -
-
-
-
-
-
{{'DEBIT.BALANCE' | translate}}
-

-
-

{{dashboardModel?.balanceDebit | number: '0.2-2'}}

-
-
-
-
- -
-
-
-
-
-
{{'CREDIT.BALANCE' | translate}}
-
-

{{dashboardModel?.balanceCredit | number: '0.2-2'}}

-
-
-
-
-
- -
- -
-
-
-

{{'CURRENT.BALANCE' | translate}}

- - - - - - -
-
-
- - -
-
- - - - - - - - - - - - - - - - - - -
{{item.name}}{{item.balance | number: '1.2'}} ({{item.currencyShortName}}){{item.balanceAtRate | number: '1.2'}}
{{'OTHER' | translate}}{{top10BalanceOther | number: '1.2'}}
{{'TOTAL' | translate}}{{top10BalanceTotal | number: '1.2'}}
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.scss b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.spec.ts b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.spec.ts deleted file mode 100644 index 00dd7f9..0000000 --- a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { Dashboard2Component } from './dashboard2.component'; - -describe('Dashboard2Component', - () => { - let component: Dashboard2Component; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [Dashboard2Component] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(Dashboard2Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.ts b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.ts deleted file mode 100644 index 1f8dc52..0000000 --- a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.ts +++ /dev/null @@ -1,155 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { OnInit } from '@angular/core'; -import { ViewChild } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { DecimalPipe } from '@angular/common'; - -// libs -import { - ApexAxisChartSeries, - ApexChart, - ApexXAxis, - ApexDataLabels, - ApexStroke, - ApexMarkers, - ApexYAxis, - ApexGrid, - ApexTitleSubtitle, - ApexTooltip, - ApexLegend, - ApexFill, - ApexResponsive, - ApexNonAxisChartSeries, -} from 'ng-apexcharts'; -import { ChartComponent } from "ng-apexcharts"; - -// app -import { ApiRoutes } from '../../api-routes'; -import { DashboardModel } from '../../model/dashboard.model'; -import { DashboardRestModel } from '../../model/dashboard.model'; - -export type ChartOptions = { - series: ApexAxisChartSeries; - series2: ApexNonAxisChartSeries; - chart: ApexChart; - xaxis: ApexXAxis; - stroke: ApexStroke; - dataLabels: ApexDataLabels; - markers: ApexMarkers; - colors: string[]; - yaxis: ApexYAxis; - grid: ApexGrid; - legend: ApexLegend; - tooltip: ApexTooltip; - fill: ApexFill; - title: ApexTitleSubtitle; - responsive: ApexResponsive[]; - labels: string[]; -}; - -@Component({ - selector: 'app-dashboard2', - templateUrl: './dashboard2.component.html', - styleUrls: ['./dashboard2.component.scss'], -}) -export class Dashboard2Component implements OnInit { - - @ViewChild("chart") chart!: ChartComponent; - public pieChartOptions!: Partial; - top10Balance?: DashboardRestModel[]; - top10BalanceOther?: number; - top10BalanceTotal?: number; - dashboardModel?: DashboardModel; - - private readonly destroyRef = inject(DestroyRef); - - // color: ["#3FA7DC", "#F6A025", "#9BC311"], - constructor( - private httpClient: HttpClient, - private _decimalPipe: DecimalPipe - ) { - - } - - ngOnInit() { - this.httpClient - .get(ApiRoutes.Dashboard) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - data.incomeChange = this.calcChanges(data.incomeLast, data.incomePrevious); - data.outcomeChange = this.calcChanges(data.outcomeLast, data.outcomePrevious); - - var labels = []; - var series2: number[] = []; - for (var i = 0; i < data.balanceRests.length; i++) { - let item = data.balanceRests[i]; - labels.push(item.name); - series2.push(item.balanceAtRate); - } - - this.balanceChart(labels, series2); - - this.top10Balance = data.balanceRests - .filter(x => x.balanceAtRate > 0) - .sort(x => x.balanceAtRate) - .slice(0, 10); - - this.top10BalanceTotal = data.balanceRests.reduce((sum, current) => sum + current.balanceAtRate, 0); - this.top10BalanceOther = this.top10Balance.reduce((sum, current) => sum + current.balanceAtRate, 0); - this.top10BalanceOther = this.top10BalanceTotal - this.top10BalanceOther; - - this.dashboardModel = data; - }); - } - - private calcChanges(newValue: number, oldValue: number): number { - if (newValue > oldValue) { - return (newValue - oldValue) / oldValue * 100; - } - else if (newValue < oldValue) { - return (oldValue - newValue) / oldValue * 100; - } - - return 0; - } - - private balanceChart(labels: string[], series2: number[]) { - var self = this; - - this.pieChartOptions = { - labels: labels, - series2: series2, - chart: { - type: 'donut', - width: 600, - height: 600, - }, - legend: { - show: true, - }, - dataLabels: { - enabled: false, - }, - responsive: [{ - breakpoint: 480, - options: { - legend: { - position: 'bottom' - } - }, - }], - tooltip: { - x: { - show: false, - }, - y: { - formatter: function (value, series) { - return self._decimalPipe.transform(value, '1.2-2') || ""; - } - } - } - }; - } -} diff --git a/MyOffice.SPA/src/app/dashboard/income/dashboard.component.html b/MyOffice.SPA/src/app/dashboard/income/dashboard.component.html deleted file mode 100644 index 0a55e51..0000000 --- a/MyOffice.SPA/src/app/dashboard/income/dashboard.component.html +++ /dev/null @@ -1,70 +0,0 @@ -
-
-
- - -
- -
-
-
-
-

{{'PERIOD' | translate}}

-
-
-
- -
-
-
-
-
- -
- -
-
-
-

{{'INCOME' | translate}}

- - - - - - -
-
-
- - -
-
- - - - - - - - - - - - - -
{{item.name}}{{item.valueRaw | number: '1.2'}}{{item.value | number: '1.2'}}
{{'TOTAL' | translate}}{{total | number: '1.2'}}
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/dashboard/income/dashboard.component.scss b/MyOffice.SPA/src/app/dashboard/income/dashboard.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/dashboard/income/dashboard.component.spec.ts b/MyOffice.SPA/src/app/dashboard/income/dashboard.component.spec.ts deleted file mode 100644 index 00dd7f9..0000000 --- a/MyOffice.SPA/src/app/dashboard/income/dashboard.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { Dashboard2Component } from './dashboard2.component'; - -describe('Dashboard2Component', - () => { - let component: Dashboard2Component; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [Dashboard2Component] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(Dashboard2Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/dashboard/income/dashboard.component.ts b/MyOffice.SPA/src/app/dashboard/income/dashboard.component.ts deleted file mode 100644 index 26848e5..0000000 --- a/MyOffice.SPA/src/app/dashboard/income/dashboard.component.ts +++ /dev/null @@ -1,146 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { OnInit } from '@angular/core'; -import { ViewChild } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { HttpParams } from '@angular/common/http'; -import { DecimalPipe } from '@angular/common'; - -// libs -import { - ChartComponent, - ApexAxisChartSeries, - ApexTitleSubtitle, - ApexDataLabels, - ApexChart, - ApexPlotOptions, - ApexLegend -} from "ng-apexcharts"; -import moment from 'moment'; - -// app -import { ApiRoutes } from '../../api-routes'; -import { DashboardInOutModel } from '../../model/dashboard.model'; - -export type ChartOptions = { - series: ApexAxisChartSeries; - chart: ApexChart; - dataLabels: ApexDataLabels; - title: ApexTitleSubtitle; - plotOptions: ApexPlotOptions; - legend: ApexLegend; -}; - -@Component({ - selector: 'app-dashboard-income', - templateUrl: './dashboard.component.html', - styleUrls: ['./dashboard.component.scss'], -}) -export class DashboardIncomeComponent implements OnInit { - - @ViewChild("chart") chart!: ChartComponent; - public chartOptions!: Partial; - dashboardModel?: DashboardInOutModel; - total?: number; - public dateFrom: Date = moment(new Date).add(-30, 'days').toDate(); - public dateTo: Date = moment(new Date).add(0, 'days').toDate(); - - colors: string[] = ["#fd7f6f", "#7eb0d5", "#b2e061", "#bd7ebe", "#ffb55a", "#ffee65", "#beb9db", "#fdcce5", "#8bd3c7"]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - private _decimalPipe: DecimalPipe - ) { - - } - - ngOnInit() { - this.loadData(); - } - - onChangePeriod(dates: Date[]) { - this.dateFrom = dates[0]; - this.dateTo = dates[1]; - this.loadData(); - } - - loadData(update?: boolean, category?: string) { - let params = new HttpParams() - .set('from', moment(this.dateFrom).format('YYYY-MM-DD')) - .set('to', moment(this.dateTo).format('YYYY-MM-DD')) - .set('category', category || '') - ; - - this.httpClient - .get(ApiRoutes.DashboardIncome, { params: params }) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dashboardModel = response; - - var series = response.data.map(x => ({ - x: x.name + '(' + (this._decimalPipe.transform(x.value, '1.2-2') || "") + ')', - y: x.value - })); - var min = Math.min(...response.data.map(x => x.value)); - var max = Math.max(...response.data.map(x => x.value)); - var step = max / 10; - var ranges = []; - for (var i = 0; i < this.colors.length; i++) { - ranges.push({ - from: i === 0 ? min : step * i, - to: i === this.colors.length - 1 ? max + 10 : step * (i + 1), - color: this.colors[this.colors.length - i - 1], - }); - } - - this.total = response.data.reduce((sum, current) => sum + current.value, 0); - - if (update) { - this.chart.updateSeries([{ - data: series - }]); - } else { - this.setChartOptions(series, ranges); - } - }); - } - - onRightClick(event?: Event) { - event?.preventDefault(); - this.loadData(true); - } - - private setChartOptions(data: any[], ranges: any[]) { - var self = this; - - this.chartOptions = { - series: [{ - data: data - }], - chart: { - type: 'treemap', - width: 600, - height: 600, - events: { - click: function (event, chartContext, config) { - var data = self.dashboardModel!.data[config.dataPointIndex]; - self.loadData(true, data.id); - } - } - }, - plotOptions: { - treemap: { - enableShades: true, - shadeIntensity: 0.5, - reverseNegativeShade: true, - colorScale: { - ranges: ranges - } - } - }, - }; - } -} diff --git a/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.html b/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.html deleted file mode 100644 index d372db6..0000000 --- a/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.html +++ /dev/null @@ -1,72 +0,0 @@ -
-
-
- - -
- -
-
-
-
-

{{'PERIOD' | translate}}

-
-
-
- -
-
-
-
-
- -
- -
-
-
-

{{'OUTCOME' | translate}}

- -
-
- - -
- - - - - - - - - - - - - -
{{item.name}}{{item.valueRaw | number: '1.2'}}{{item.value | number: '1.2'}}
{{'TOTAL' | translate}}{{total | number: '1.2'}}
-
-
-
-
-
- - -
-
diff --git a/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.scss b/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.spec.ts b/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.spec.ts deleted file mode 100644 index 00dd7f9..0000000 --- a/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { Dashboard2Component } from './dashboard2.component'; - -describe('Dashboard2Component', - () => { - let component: Dashboard2Component; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [Dashboard2Component] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(Dashboard2Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.ts b/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.ts deleted file mode 100644 index 6db6b1c..0000000 --- a/MyOffice.SPA/src/app/dashboard/outcome/dashboard.component.ts +++ /dev/null @@ -1,145 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { OnInit } from '@angular/core'; -import { ViewChild } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { HttpParams } from '@angular/common/http'; -import { DecimalPipe } from '@angular/common'; - -// libs -import { - ChartComponent, - ApexAxisChartSeries, - ApexTitleSubtitle, - ApexDataLabels, - ApexChart, - ApexPlotOptions, - ApexLegend -} from "ng-apexcharts"; -import moment from 'moment'; - -// app -import { ApiRoutes } from '../../api-routes'; -import { DashboardInOutModel } from '../../model/dashboard.model'; - -export type ChartOptions = { - series: ApexAxisChartSeries; - chart: ApexChart; - dataLabels: ApexDataLabels; - title: ApexTitleSubtitle; - plotOptions: ApexPlotOptions; - legend: ApexLegend; -}; - -@Component({ - selector: 'app-dashboard-outcome', - templateUrl: './dashboard.component.html', - styleUrls: ['./dashboard.component.scss'], -}) -export class DashboardOutcomeComponent implements OnInit { - - @ViewChild("chart") chart!: ChartComponent; - public chartOptions!: Partial; - dashboardModel?: DashboardInOutModel; - total?: number; - public dateFrom: Date = moment(new Date).add(-30, 'days').toDate(); - public dateTo: Date = moment(new Date).add(0, 'days').toDate(); - - colors: string[] = ["#fd7f6f", "#7eb0d5", "#b2e061", "#bd7ebe", "#ffb55a", "#ffee65", "#beb9db", "#fdcce5", "#8bd3c7"]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - private _decimalPipe: DecimalPipe - ) { - } - - ngOnInit() { - this.loadData(); - } - - onChangePeriod(dates: Date[]) { - this.dateFrom = dates[0]; - this.dateTo = dates[1]; - this.loadData(); - } - - onRightClick(event?: Event) { - event?.preventDefault(); - this.loadData(true); - } - - private loadData(update?: boolean, category?: string) { - let params = new HttpParams() - .set('from', moment(this.dateFrom).format('YYYY-MM-DD')) - .set('to', moment(this.dateTo).format('YYYY-MM-DD')) - .set('category', category || '') - ; - - this.httpClient - .get(ApiRoutes.DashboardOutcome, { params: params }) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dashboardModel = response; - - var series = response.data.map(x => ({ - x: x.name + ' (' + (this._decimalPipe.transform(x.value, '1.2-2') || '') + ')', - y: x.value - })); - var min = Math.min(...response.data.map(x => x.value)); - var max = Math.max(...response.data.map(x => x.value)); - var step = max / 10; - var ranges = []; - for (var i = 0; i < this.colors.length; i++) { - ranges.push({ - from: i === 0 ? min : step * i, - to: i === this.colors.length - 1 ? max + 10 : step * (i + 1), - color: this.colors[this.colors.length - i - 1], - }); - } - - this.total = response.data.reduce((sum, current) => sum + current.value, 0); - - if (update) { - this.chart.updateSeries([{ - data: series - }]); - } else { - this.setChartOptions(series, ranges); - } - }); - } - - private setChartOptions(data: any[], ranges: any[]) { - var self = this; - - this.chartOptions = { - series: [{ - data: data - }], - chart: { - type: 'treemap', - width: 600, - height: 600, - events: { - click: function (event, chartContext, config) { - var data = self.dashboardModel!.data[config.dataPointIndex]; - self.loadData(true, data.id); - } - } - }, - plotOptions: { - treemap: { - enableShades: true, - shadeIntensity: 0.5, - reverseNegativeShade: true, - colorScale: { - ranges: ranges - } - } - }, - }; - } -} diff --git a/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.html b/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.html deleted file mode 100644 index d1c5fa2..0000000 --- a/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
- -
diff --git a/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.ts b/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.ts deleted file mode 100644 index f700c55..0000000 --- a/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { BidiModule, Direction } from '@angular/cdk/bidi'; -import { Component, DestroyRef, Inject, inject, Renderer2 } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { RouterOutlet } from '@angular/router'; -import { InConfiguration } from 'src/app/core/models/config.interface'; -import { DirectionService } from 'src/app/core/service/direction.service'; -import { ConfigService } from 'src/app/config/config.service'; -import { DOCUMENT } from '@angular/common'; - -@Component({ - selector: 'app-auth-layout', - templateUrl: './auth-layout.component.html', - styleUrls: [], - standalone: true, - imports: [BidiModule, RouterOutlet], -}) -export class AuthLayoutComponent { - direction!: Direction; - config!: InConfiguration; - private readonly destroyRef = inject(DestroyRef); - - constructor( - @Inject(DOCUMENT) private document: Document, - private directoryService: DirectionService, - private configService: ConfigService, - private renderer: Renderer2 - ) { - this.config = this.configService.configData; - this.directoryService.currentData - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe((currentData) => { - if (currentData) { - this.direction = currentData === 'ltr' ? 'ltr' : 'rtl'; - } else { - if (localStorage.getItem('isRtl')) { - if (localStorage.getItem('isRtl') === 'true') { - this.direction = 'rtl'; - } else if (localStorage.getItem('isRtl') === 'false') { - this.direction = 'ltr'; - } - } else { - if (this.config) { - if (this.config.layout.rtl === true) { - this.direction = 'rtl'; - localStorage.setItem('isRtl', 'true'); - } else { - this.direction = 'ltr'; - localStorage.setItem('isRtl', 'false'); - } - } - } - } - }); - - // set theme on startup - if (localStorage.getItem('theme')) { - this.renderer.removeClass(this.document.body, this.config.layout.variant); - this.renderer.addClass( - this.document.body, - localStorage.getItem('theme') as string - ); - } else { - this.renderer.addClass(this.document.body, this.config.layout.variant); - } - } -} diff --git a/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.html b/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.html deleted file mode 100644 index 74b91bd..0000000 --- a/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.html +++ /dev/null @@ -1,6 +0,0 @@ - - - -
- -
diff --git a/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.ts b/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.ts deleted file mode 100644 index b77f5eb..0000000 --- a/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { BidiModule, Direction } from '@angular/cdk/bidi'; -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { RouterOutlet } from '@angular/router'; -import { InConfiguration } from 'src/app/core/models/config.interface'; -import { DirectionService } from 'src/app/core/service/direction.service'; -import { ConfigService } from 'src/app/config/config.service'; -import { HeaderComponent } from '../../header/header.component'; -import { SidebarComponent } from '../../sidebar/sidebar.component'; -import { RightSidebarComponent } from '../../right-sidebar/right-sidebar.component'; - -@Component({ - selector: 'app-main-layout', - templateUrl: './main-layout.component.html', - styleUrls: [], - standalone: true, - imports: [BidiModule, RouterOutlet, HeaderComponent, SidebarComponent, RightSidebarComponent], -}) -export class MainLayoutComponent { - direction!: Direction; - config!: InConfiguration; - private readonly destroyRef = inject(DestroyRef); - - constructor( - private directoryService: DirectionService, - private configService: ConfigService - ) { - this.config = this.configService.configData; - this.directoryService.currentData - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe((currentData) => { - if (currentData) { - this.direction = currentData === 'ltr' ? 'ltr' : 'rtl'; - } else { - if (localStorage.getItem('isRtl')) { - if (localStorage.getItem('isRtl') === 'true') { - this.direction = 'rtl'; - } else if (localStorage.getItem('isRtl') === 'false') { - this.direction = 'ltr'; - } - } else { - if (this.config) { - if (this.config.layout.rtl === true) { - this.direction = 'rtl'; - localStorage.setItem('isRtl', 'true'); - } else { - this.direction = 'ltr'; - localStorage.setItem('isRtl', 'false'); - } - } - } - } - }); - } -} diff --git a/MyOffice.SPA/src/app/layout/header/header.component.html b/MyOffice.SPA/src/app/layout/header/header.component.html deleted file mode 100644 index d381862..0000000 --- a/MyOffice.SPA/src/app/layout/header/header.component.html +++ /dev/null @@ -1,179 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/layout/header/header.component.scss b/MyOffice.SPA/src/app/layout/header/header.component.scss deleted file mode 100644 index 8b13789..0000000 --- a/MyOffice.SPA/src/app/layout/header/header.component.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/layout/header/header.component.spec.ts b/MyOffice.SPA/src/app/layout/header/header.component.spec.ts deleted file mode 100644 index 4cff7eb..0000000 --- a/MyOffice.SPA/src/app/layout/header/header.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { HeaderComponent } from './header.component'; -describe('HeaderComponent', - () => { - let component: HeaderComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [HeaderComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(HeaderComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/layout/header/header.component.ts b/MyOffice.SPA/src/app/layout/header/header.component.ts deleted file mode 100644 index c5bbdbe..0000000 --- a/MyOffice.SPA/src/app/layout/header/header.component.ts +++ /dev/null @@ -1,264 +0,0 @@ -// angular -import { DOCUMENT } from '@angular/common'; -import { Component } from '@angular/core'; -import { Inject } from '@angular/core'; -import { ElementRef } from '@angular/core'; -import { OnInit } from '@angular/core'; -import { Renderer2 } from '@angular/core'; -import { AfterViewInit } from '@angular/core'; -import { Router } from '@angular/router'; - -// libs -import { NgScrollbarModule } from 'ngx-scrollbar'; - -// app -import { ConfigService } from 'src/app/config/config.service'; -import { InConfiguration } from 'src/app/core/models/config.interface'; -import { AuthService } from 'src/app/core/service/auth.service'; -import { LanguageService } from 'src/app/core/service/language.service'; -import { UnsubscribeOnDestroyAdapter } from 'src/app/shared/UnsubscribeOnDestroyAdapter'; -import { SharedModule } from 'src/app/shared/shared.module'; - -interface Notifications { - message: string; - time: string; - icon: string; - color: string; - status: string; -} - -@Component({ - selector: 'app-header', - templateUrl: './header.component.html', - styleUrls: ['./header.component.scss'], - standalone: true, - imports: [SharedModule, NgScrollbarModule], -}) -export class HeaderComponent extends UnsubscribeOnDestroyAdapter implements OnInit, AfterViewInit { - - config!: InConfiguration; - - userImg?: string; - userName?: string; - - homePage?: string; - isNavbarCollapsed = true; - flagvalue: string | string[] | undefined; - countryName: string | string[] = []; - langStoreValue?: string; - defaultFlag?: string; - isOpenSidebar?: boolean; - docElement: HTMLElement | undefined; - isFullScreen = false; - - constructor( - @Inject(DOCUMENT) private document: Document, - private renderer: Renderer2, - public elementRef: ElementRef, - private configService: ConfigService, - private authService: AuthService, - private router: Router, - public languageService: LanguageService - ) { - super(); - - this.subs.sink = this.authService.currentUser$.subscribe(() => { - this.setUser(); - }); - } - - listLang = [ - { text: 'English', flag: 'assets/images/flags/us.jpg', lang: 'en' }, - { text: 'Spanish', flag: 'assets/images/flags/spain.jpg', lang: 'es' }, - { text: 'German', flag: 'assets/images/flags/germany.jpg', lang: 'de' }, - { text: 'Ukraine', flag: 'assets/images/flags/ukraine.png', lang: 'ua' }, - ]; - notifications: Notifications[] = [ - { - message: 'Please check your mail', - time: '14 mins ago', - icon: 'mail', - color: 'nfc-green', - status: 'msg-unread', - }, - { - message: 'New Employee Added..', - time: '22 mins ago', - icon: 'person_add', - color: 'nfc-blue', - status: 'msg-read', - }, - { - message: 'Your leave is approved!! ', - time: '3 hours ago', - icon: 'event_available', - color: 'nfc-orange', - status: 'msg-read', - }, - { - message: 'Lets break for lunch...', - time: '5 hours ago', - icon: 'lunch_dining', - color: 'nfc-blue', - status: 'msg-read', - }, - { - message: 'Employee report generated', - time: '14 mins ago', - icon: 'description', - color: 'nfc-green', - status: 'msg-read', - }, - { - message: 'Please check your mail', - time: '22 mins ago', - icon: 'mail', - color: 'nfc-red', - status: 'msg-read', - }, - { - message: 'Salary credited...', - time: '3 hours ago', - icon: 'paid', - color: 'nfc-purple', - status: 'msg-read', - }, - ]; - - ngOnInit() { - this.config = this.configService.configData; - - this.setUser(); - - this.homePage = 'dashboard/rests'; - - this.langStoreValue = localStorage.getItem('lang') as string; - const val = this.listLang.filter((x) => x.lang === this.langStoreValue); - this.countryName = val.map((element) => element.text); - if (val.length === 0) { - if (this.flagvalue === undefined) { - this.defaultFlag = 'assets/images/flags/us.jpg'; - } - } else { - this.flagvalue = val.map((element) => element.flag); - } - } - - ngAfterViewInit() { - // set theme on startup - if (localStorage.getItem('theme')) { - this.renderer.removeClass(this.document.body, this.config.layout.variant); - this.renderer.addClass( - this.document.body, - localStorage.getItem('theme') as string - ); - } else { - this.renderer.addClass(this.document.body, this.config.layout.variant); - } - - if (localStorage.getItem('menuOption')) { - this.renderer.addClass( - this.document.body, - localStorage.getItem('menuOption') as string - ); - } else { - this.renderer.addClass( - this.document.body, - 'menu_' + this.config.layout.sidebar.backgroundColor - ); - } - - if (localStorage.getItem('choose_logoheader')) { - this.renderer.addClass( - this.document.body, - localStorage.getItem('choose_logoheader') as string - ); - } else { - this.renderer.addClass( - this.document.body, - 'logo-' + this.config.layout.logo_bg_color - ); - } - - if (localStorage.getItem('sidebar_status')) { - if (localStorage.getItem('sidebar_status') === 'close') { - this.renderer.addClass(this.document.body, 'side-closed'); - this.renderer.addClass(this.document.body, 'submenu-closed'); - } else { - this.renderer.removeClass(this.document.body, 'side-closed'); - this.renderer.removeClass(this.document.body, 'submenu-closed'); - } - } else { - if (this.config.layout.sidebar.collapsed === true) { - this.renderer.addClass(this.document.body, 'side-closed'); - this.renderer.addClass(this.document.body, 'submenu-closed'); - } - } - } - - callFullscreen() { - if (!this.isFullScreen) { - this.docElement?.requestFullscreen(); - } else { - document.exitFullscreen(); - } - this.isFullScreen = !this.isFullScreen; - } - - setLanguage(text: string, lang: string, flag: string) { - this.countryName = text; - this.flagvalue = flag; - this.langStoreValue = lang; - this.languageService.setLanguage(lang); - } - - mobileMenuSidebarOpen(event: Event, className: string) { - const hasClass = (event.target as HTMLInputElement).classList.contains( - className - ); - if (hasClass) { - this.renderer.removeClass(this.document.body, className); - } else { - this.renderer.addClass(this.document.body, className); - } - - const hasClass2 = this.document.body.classList.contains('side-closed'); - if (hasClass2) { - // this.renderer.removeClass(this.document.body, "side-closed"); - this.renderer.removeClass(this.document.body, 'submenu-closed'); - } else { - // this.renderer.addClass(this.document.body, "side-closed"); - this.renderer.addClass(this.document.body, 'submenu-closed'); - } - } - - callSidemenuCollapse() { - const hasClass = this.document.body.classList.contains('side-closed'); - if (hasClass) { - this.renderer.removeClass(this.document.body, 'side-closed'); - this.renderer.removeClass(this.document.body, 'submenu-closed'); - } else { - this.renderer.addClass(this.document.body, 'side-closed'); - this.renderer.addClass(this.document.body, 'submenu-closed'); - } - } - - logout() { - this.subs.sink = this.authService.logout().subscribe((res) => { - if (!res.success) { - this.router.navigate(['/authentication/signin']); - } - }); - } - - private setUser() { - this.userImg = this.authService.currentUserValue.img; - - this.userName = [ - this.authService.currentUserValue.firstName, - this.authService.currentUserValue.lastName - ].join(' ').trim(); - - this.userName = this.userName || this.authService.currentUserValue.userName; - } -} diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.html b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.html deleted file mode 100644 index c0c959c..0000000 --- a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.scss b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.scss deleted file mode 100644 index 8b13789..0000000 --- a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.spec.ts b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.spec.ts deleted file mode 100644 index d2479a5..0000000 --- a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { PageLoaderComponent } from './page-loader.component'; -describe('PageLoaderComponent', - () => { - let component: PageLoaderComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [PageLoaderComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(PageLoaderComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.ts b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.ts deleted file mode 100644 index 5eab98c..0000000 --- a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; -import { LoadingBarModule } from '@ngx-loading-bar/core'; - -@Component({ - selector: 'app-page-loader', - templateUrl: './page-loader.component.html', - styleUrls: ['./page-loader.component.scss'], - standalone: true, - imports: [LoadingBarModule], -}) -export class PageLoaderComponent { - constructor() { - // constructor - } -} diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.html b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.html deleted file mode 100644 index 9e15752..0000000 --- a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.html +++ /dev/null @@ -1,48 +0,0 @@ -
- - - - -
-
-
- Setting Panel -
-
-
Select Layout
-
-
- -
Light
-
-
- -
Dark
-
-
-
-
-
Sidebar Menu Color
- - Light - Dark - -
-
-
RTL Layout
- -
-
-
-
-
diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.scss b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.scss deleted file mode 100644 index 8b13789..0000000 --- a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.spec.ts b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.spec.ts deleted file mode 100644 index 2528b67..0000000 --- a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RightSidebarComponent } from './right-sidebar.component'; -describe('RightSidebarComponent', - () => { - let component: RightSidebarComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [RightSidebarComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(RightSidebarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.ts b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.ts deleted file mode 100644 index 84f3a00..0000000 --- a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.ts +++ /dev/null @@ -1,258 +0,0 @@ -import { DOCUMENT } from '@angular/common'; -import { - Component, - Inject, - ElementRef, - OnInit, - AfterViewInit, - Renderer2, - ChangeDetectionStrategy, - ChangeDetectorRef, -} from '@angular/core'; -import { ConfigService } from 'src/app/config/config.service'; -import { RightSidebarService } from 'src/app/core/service/rightsidebar.service'; -import { MatSlideToggleChange } from '@angular/material/slide-toggle'; -import { UnsubscribeOnDestroyAdapter } from 'src/app/shared/UnsubscribeOnDestroyAdapter'; -import { DirectionService } from 'src/app/core/service/direction.service'; -import { InConfiguration } from 'src/app/core/models/config.interface'; -import { SharedModule } from 'src/app/shared/shared.module'; -import { NgScrollbarModule } from 'ngx-scrollbar'; - -@Component({ - changeDetection: ChangeDetectionStrategy.OnPush, - selector: 'app-right-sidebar', - templateUrl: './right-sidebar.component.html', - styleUrls: ['./right-sidebar.component.scss'], - standalone: true, - imports: [SharedModule, NgScrollbarModule], -}) -export class RightSidebarComponent -extends UnsubscribeOnDestroyAdapter -implements OnInit, AfterViewInit { - selectedBgColor = 'white'; - maxHeight!: string; - maxWidth!: string; - showpanel = false; - isOpenSidebar!: boolean; - isDarkSidebar = false; - isDarTheme = false; - innerHeight?: number; - headerHeight = 60; - isRtl = false; - config!: InConfiguration; - - constructor( - @Inject(DOCUMENT) private document: Document, - private renderer: Renderer2, - public elementRef: ElementRef, - private rightSidebarService: RightSidebarService, - private configService: ConfigService, - private directionService: DirectionService, - private cdr: ChangeDetectorRef - ) { - super(); - } - - ngOnInit() { - this.config = this.configService.configData; - this.subs.sink = this.rightSidebarService.sidebarState.subscribe( - (isRunning) => { - this.isOpenSidebar = isRunning; - } - ); - this.setRightSidebarWindowHeight(); - } - - ngAfterViewInit() { - // Light/dark skins only (clamp legacy color-skin values). - const storedSkin = localStorage.getItem('choose_skin_active'); - const skin = storedSkin === 'black' || this.config.layout.theme_color === 'black' - ? 'black' - : 'white'; - this.selectedBgColor = skin; - this.renderer.addClass(this.document.body, 'theme-' + skin); - localStorage.setItem('choose_skin', 'theme-' + skin); - localStorage.setItem('choose_skin_active', skin); - - if (localStorage.getItem('menuOption')) { - if (localStorage.getItem('menuOption') === 'menu_dark') { - this.isDarkSidebar = true; - } else if (localStorage.getItem('menuOption') === 'menu_light') { - this.isDarkSidebar = false; - } else { - this.isDarkSidebar = - this.config.layout.sidebar.backgroundColor === 'dark' ? true : false; - } - } else { - this.isDarkSidebar = - this.config.layout.sidebar.backgroundColor === 'dark' ? true : false; - } - - if (localStorage.getItem('theme')) { - if (localStorage.getItem('theme') === 'dark') { - this.isDarTheme = true; - } else if (localStorage.getItem('theme') === 'light') { - this.isDarTheme = false; - } else { - this.isDarTheme = this.config.layout.variant === 'dark' ? true : false; - } - } else { - this.isDarTheme = this.config.layout.variant === 'dark' ? true : false; - } - - // Content styles use body.dark; keep in sync with the layout toggle (theme-black alone is chrome-only). - if (this.isDarTheme) { - this.renderer.removeClass(this.document.body, 'light'); - this.renderer.addClass(this.document.body, 'dark'); - } else { - this.renderer.removeClass(this.document.body, 'dark'); - this.renderer.addClass(this.document.body, 'light'); - } - - if (localStorage.getItem('isRtl')) { - if (localStorage.getItem('isRtl') === 'true') { - this.setRTLSettings(); - } else if (localStorage.getItem('isRtl') === 'false') { - this.setLTRSettings(); - } - } else { - if (this.config.layout.rtl == true) { - this.setRTLSettings(); - } else { - this.setLTRSettings(); - } - } - this.cdr.markForCheck(); - } - - lightSidebarBtnClick() { - this.renderer.removeClass(this.document.body, 'menu_dark'); - this.renderer.removeClass(this.document.body, 'logo-black'); - this.renderer.addClass(this.document.body, 'menu_light'); - this.renderer.addClass(this.document.body, 'logo-white'); - this.isDarkSidebar = false; - localStorage.setItem('choose_logoheader', 'logo-white'); - localStorage.setItem('menuOption', 'menu_light'); - this.cdr.markForCheck(); - } - - darkSidebarBtnClick() { - this.renderer.removeClass(this.document.body, 'menu_light'); - this.renderer.removeClass(this.document.body, 'logo-white'); - this.renderer.addClass(this.document.body, 'menu_dark'); - this.renderer.addClass(this.document.body, 'logo-black'); - this.isDarkSidebar = true; - localStorage.setItem('choose_logoheader', 'logo-black'); - localStorage.setItem('menuOption', 'menu_dark'); - this.cdr.markForCheck(); - } - - lightThemeBtnClick() { - this.removeBodyThemeClasses(); - this.renderer.removeClass(this.document.body, 'dark'); - this.renderer.removeClass(this.document.body, 'menu_dark'); - this.renderer.removeClass(this.document.body, 'logo-black'); - - this.renderer.addClass(this.document.body, 'light'); - this.renderer.addClass(this.document.body, 'submenu-closed'); - this.renderer.addClass(this.document.body, 'menu_light'); - this.renderer.addClass(this.document.body, 'logo-white'); - this.renderer.addClass(this.document.body, 'theme-white'); - - this.selectedBgColor = 'white'; - this.isDarkSidebar = false; - this.isDarTheme = false; - localStorage.setItem('choose_logoheader', 'logo-white'); - localStorage.setItem('choose_skin', 'theme-white'); - localStorage.setItem('choose_skin_active', 'white'); - localStorage.setItem('theme', 'light'); - localStorage.setItem('menuOption', 'menu_light'); - this.cdr.markForCheck(); - } - - darkThemeBtnClick() { - this.removeBodyThemeClasses(); - this.renderer.removeClass(this.document.body, 'light'); - this.renderer.removeClass(this.document.body, 'menu_light'); - this.renderer.removeClass(this.document.body, 'logo-white'); - - this.renderer.addClass(this.document.body, 'dark'); - this.renderer.addClass(this.document.body, 'submenu-closed'); - this.renderer.addClass(this.document.body, 'menu_dark'); - this.renderer.addClass(this.document.body, 'logo-black'); - this.renderer.addClass(this.document.body, 'theme-black'); - - this.selectedBgColor = 'black'; - this.isDarkSidebar = true; - this.isDarTheme = true; - localStorage.setItem('choose_logoheader', 'logo-black'); - localStorage.setItem('choose_skin', 'theme-black'); - localStorage.setItem('choose_skin_active', 'black'); - localStorage.setItem('theme', 'dark'); - localStorage.setItem('menuOption', 'menu_dark'); - this.cdr.markForCheck(); - } - - /** Clears light/dark theme-* classes before applying a layout. */ - private removeBodyThemeClasses() { - ['theme-white', 'theme-black', 'theme-purple', 'theme-orange', 'theme-cyan', 'theme-green', 'theme-blue'] - .forEach((themeClass) => this.renderer.removeClass(this.document.body, themeClass)); - } - - setRightSidebarWindowHeight() { - this.innerHeight = window.innerHeight; - const height = this.innerHeight - this.headerHeight; - this.maxHeight = height + ''; - this.maxWidth = '500px'; - } - - onClickedOutside(event: Event) { - const button = event.target as HTMLButtonElement; - if (button.id !== 'settingBtn') { - if (this.isOpenSidebar === true) { - this.toggleRightSidebar(); - } - } - } - - toggleRightSidebar(): void { - this.rightSidebarService.setRightSidebar( - (this.isOpenSidebar = !this.isOpenSidebar) - ); - } - - switchDirection(event: MatSlideToggleChange) { - const isrtl = String(event.checked); - if ( - isrtl === 'false' && - document.getElementsByTagName('html')[0].hasAttribute('dir') - ) { - document.getElementsByTagName('html')[0].removeAttribute('dir'); - this.renderer.removeClass(this.document.body, 'rtl'); - this.directionService.updateDirection('ltr'); - } else if ( - isrtl === 'true' && - !document.getElementsByTagName('html')[0].hasAttribute('dir') - ) { - document.getElementsByTagName('html')[0].setAttribute('dir', 'rtl'); - this.renderer.addClass(this.document.body, 'rtl'); - this.directionService.updateDirection('rtl'); - } - localStorage.setItem('isRtl', isrtl); - this.isRtl = event.checked; - } - - setRTLSettings() { - document.getElementsByTagName('html')[0].setAttribute('dir', 'rtl'); - this.renderer.addClass(this.document.body, 'rtl'); - this.isRtl = true; - localStorage.setItem('isRtl', 'true'); - } - - setLTRSettings() { - document.getElementsByTagName('html')[0].removeAttribute('dir'); - this.renderer.removeClass(this.document.body, 'rtl'); - this.isRtl = false; - localStorage.setItem('isRtl', 'false'); - } -} diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar-items.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar-items.ts deleted file mode 100644 index 08d9e58..0000000 --- a/MyOffice.SPA/src/app/layout/sidebar/sidebar-items.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { RouteInfo } from './sidebar.metadata'; - -export const ROUTES: RouteInfo[] = [ - { - path: '', - title: 'MENUITEMS.MAIN.TEXT', - iconType: '', - icon: '', - class: '', - groupTitle: true, - badge: '', - badgeClass: '', - submenu: [], - }, - { - path: '', - title: 'MENUITEMS.DASHBOARD.TEXT', - iconType: 'feather', - icon: 'home', - class: 'menu-toggle', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [ - { - path: 'dashboard/rests', - title: 'MENUITEMS.DASHBOARD.LIST.DASHBOARD', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - { - path: 'dashboard/income', - title: 'MENUITEMS.DASHBOARD.LIST.INCOME', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - { - path: 'dashboard/outcome', - title: 'MENUITEMS.DASHBOARD.LIST.OUTCOME', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - ], - }, - - // Common Modules - { - id: 'accounts', - path: '', - title: 'MENUITEMS.ACCOUNTS.TEXT', - iconType: 'feather', - icon: 'chevrons-down', - class: 'menu-toggle', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [ - ], - }, - { - path: '', - title: 'MENUITEMS.SETTINGS.TEXT', - iconType: 'feather', - icon: 'settings', - class: 'menu-toggle', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [ - { - path: '/settings/currencies', - title: 'MENUITEMS.SETTINGS.LIST.CURRENCIES', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - { - path: '/settings/account-categories', - title: 'MENUITEMS.SETTINGS.LIST.ACCOUNTCATEGORIES', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - { - path: '/settings/accounts', - title: 'MENUITEMS.SETTINGS.LIST.ACCOUNTS', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - { - path: '/settings/item-categories', - title: 'MENUITEMS.SETTINGS.LIST.ITEMCATEGORIES', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - { - path: '/settings/items', - title: 'MENUITEMS.SETTINGS.LIST.ITEMS', - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - }, - ], - }, -]; diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.html b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.html deleted file mode 100644 index aa8d3f3..0000000 --- a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.html +++ /dev/null @@ -1,75 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.scss b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.scss deleted file mode 100644 index 8b13789..0000000 --- a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.spec.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.spec.ts deleted file mode 100644 index 5d604f1..0000000 --- a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { SidebarComponent } from './sidebar.component'; -describe('SidebarComponent', - () => { - let component: SidebarComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [SidebarComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(SidebarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.ts deleted file mode 100644 index f76d647..0000000 --- a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.ts +++ /dev/null @@ -1,208 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -// angular -import { Router, NavigationEnd } from '@angular/router'; -import { DOCUMENT } from '@angular/common'; -import { Component, DestroyRef, Inject, ElementRef, OnInit, Renderer2, HostListener, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { filter } from 'rxjs/operators'; - -// libs -import { NgScrollbarModule } from 'ngx-scrollbar'; -import { TranslateModule } from '@ngx-translate/core'; - -// app -import { ROUTES } from './sidebar-items'; -import { AuthService } from 'src/app/core/service/auth.service'; -import { AccountCategoryService } from '../../services/account.category.service'; -import { RouteInfo } from './sidebar.metadata'; -import { SharedModule } from 'src/app/shared/shared.module'; - -@Component({ - selector: 'app-sidebar', - templateUrl: './sidebar.component.html', - styleUrls: ['./sidebar.component.scss'], - standalone: true, - imports: [SharedModule, NgScrollbarModule, TranslateModule], -}) -export class SidebarComponent implements OnInit { - sidebarItems!: RouteInfo[]; - innerHeight?: number; - bodyTag!: HTMLElement; - listMaxHeight?: string; - listMaxWidth?: string; - userFullName?: string; - userImg?: string; - userType?: string; - headerHeight = 60; - currentRoute?: string; - menuIcon = 'radio_button_checked'; - private readonly destroyRef = inject(DestroyRef); - - constructor( - @Inject(DOCUMENT) private document: Document, - private renderer: Renderer2, - public elementRef: ElementRef, - private authService: AuthService, - private router: Router, - private accountCategoryService: AccountCategoryService, - ) { - this.elementRef.nativeElement.closest('body'); - this.router.events - .pipe( - filter((event): event is NavigationEnd => event instanceof NavigationEnd), - takeUntilDestroyed(this.destroyRef) - ) - .subscribe(() => { - // close sidebar on mobile screen after menu select - this.renderer.removeClass(this.document.body, 'overlay-open'); - }); - } - - @HostListener('window:resize', ['$event']) - windowResizecall() { - this.setMenuHeight(); - this.checkStatuForResize(false); - } - - @HostListener('document:mousedown', ['$event']) - onGlobalClick(event: Event): void { - if (!this.elementRef.nativeElement.contains(event.target)) { - this.renderer.removeClass(this.document.body, 'overlay-open'); - } - } - - callToggleMenu(event: Event, length: number) { - if (length > 0) { - const parentElement = (event.target as HTMLInputElement).closest('li'); - const activeClass = parentElement?.classList.contains('active'); - - if (activeClass) { - this.renderer.removeClass(parentElement, 'active'); - } else { - this.renderer.addClass(parentElement, 'active'); - } - } - } - - ngOnInit() { - if (this.authService.currentUserValue) { - this.userFullName = - this.authService.currentUserValue.firstName + - ' ' + - this.authService.currentUserValue.lastName; - this.userImg = this.authService.currentUserValue.img; - this.userType = 'Admin'; - this.sidebarItems = ROUTES.filter((sidebarItem) => sidebarItem); - - this.accountCategoryService - .getCategories() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(categories => { - var accounts = this.sidebarItems.filter(x => x.id === 'accounts'); - accounts[0].submenu = []; - for (var category of categories) { - accounts[0].submenu.push({ - path: '/account-category/' + category.id, - title: category.name!, - iconType: '', - icon: '', - class: 'ml-menu', - groupTitle: false, - badge: '', - badgeClass: '', - submenu: [], - - }); - } - }); - } - - // this.sidebarItems = ROUTES.filter((sidebarItem) => sidebarItem); - this.initLeftSidebar(); - this.bodyTag = this.document.body; - } - - initLeftSidebar() { - // eslint-disable-next-line @typescript-eslint/no-this-alias - const _this = this; - // Set menu height - _this.setMenuHeight(); - _this.checkStatuForResize(true); - } - - setMenuHeight() { - this.innerHeight = window.innerHeight; - const height = this.innerHeight - this.headerHeight; - this.listMaxHeight = height + ''; - this.listMaxWidth = '500px'; - } - - isOpen() { - return this.bodyTag.classList.contains('overlay-open'); - } - - checkStatuForResize(firstTime: boolean) { - if (window.innerWidth < 1170) { - this.renderer.addClass(this.document.body, 'ls-closed'); - } else { - this.renderer.removeClass(this.document.body, 'ls-closed'); - } - } - - mouseHover() { - const body = this.elementRef.nativeElement.closest('body'); - if (body.classList.contains('submenu-closed')) { - this.renderer.addClass(this.document.body, 'side-closed-hover'); - this.renderer.removeClass(this.document.body, 'submenu-closed'); - } - } - - mouseOut() { - const body = this.elementRef.nativeElement.closest('body'); - if (body.classList.contains('side-closed-hover')) { - this.renderer.removeClass(this.document.body, 'side-closed-hover'); - this.renderer.addClass(this.document.body, 'submenu-closed'); - } - } - - mobileMenuSidebarOpen(event: Event, className: string) { - const hasClass = (event.target as HTMLInputElement).classList.contains( - className - ); - if (hasClass) { - this.renderer.removeClass(this.document.body, className); - } else { - this.renderer.addClass(this.document.body, className); - } - } - - callSidemenuCollapse() { - const hasClass = this.document.body.classList.contains('side-closed'); - if (hasClass) { - this.renderer.removeClass(this.document.body, 'side-closed'); - this.renderer.removeClass(this.document.body, 'submenu-closed'); - this.menuIcon = 'radio_button_checked'; - } else { - this.renderer.addClass(this.document.body, 'side-closed'); - this.renderer.addClass(this.document.body, 'submenu-closed'); - this.menuIcon = 'radio_button_unchecked'; - } - - const sideClosedHover = - this.document.body.classList.contains('side-closed'); - if (sideClosedHover) { - this.renderer.removeClass(this.document.body, 'side-closed-hover'); - } - } - - logout() { - this.authService.logout() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe((res) => { - if (!res.success) { - console.log('sidebar.logout'); - this.router.navigate(['/authentication/signin']); - } - }); - } -} diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.metadata.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar.metadata.ts deleted file mode 100644 index 1be5931..0000000 --- a/MyOffice.SPA/src/app/layout/sidebar/sidebar.metadata.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Sidebar route metadata -export interface RouteInfo { - id?: string; - path: string; - title: string; - iconType: string; - icon: string; - class: string; - groupTitle: boolean; - badge: string; - badgeClass: string; - submenu: RouteInfo[]; -} diff --git a/MyOffice.SPA/src/app/model/account.accessRight.model.ts b/MyOffice.SPA/src/app/model/account.accessRight.model.ts deleted file mode 100644 index 0836e3f..0000000 --- a/MyOffice.SPA/src/app/model/account.accessRight.model.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { UserModel } from '../core/models/user.model'; - -export interface AccountAccessRightModel { - user: UserModel; - isAllowRead: boolean; - isAllowWrite: boolean; - isAllowManage: boolean; - isAllowDelete: boolean; - isOwner: boolean; -} diff --git a/MyOffice.SPA/src/app/model/account.category.model.ts b/MyOffice.SPA/src/app/model/account.category.model.ts deleted file mode 100644 index 2d33b16..0000000 --- a/MyOffice.SPA/src/app/model/account.category.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface AccountCategoryModel { - id?: string, - name?: string, - allowDelete: boolean, -} diff --git a/MyOffice.SPA/src/app/model/account.detailed.model.ts b/MyOffice.SPA/src/app/model/account.detailed.model.ts deleted file mode 100644 index 6c0bcc9..0000000 --- a/MyOffice.SPA/src/app/model/account.detailed.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { AccountModel } from './account.model'; - -export interface AccountDetailedModel { - account: AccountModel; - rest: number; -} diff --git a/MyOffice.SPA/src/app/model/account.invite.model.ts b/MyOffice.SPA/src/app/model/account.invite.model.ts deleted file mode 100644 index 7c45d0b..0000000 --- a/MyOffice.SPA/src/app/model/account.invite.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface AccountInviteModel { - id?: string, - account?: string, - allowWrite: boolean, -} diff --git a/MyOffice.SPA/src/app/model/account.model.ts b/MyOffice.SPA/src/app/model/account.model.ts deleted file mode 100644 index f617014..0000000 --- a/MyOffice.SPA/src/app/model/account.model.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { AccountCategoryModel } from './account.category.model'; -import { AccountAccessRightModel } from './account.accessRight.model'; - -export interface AccountModel { - id?: string, - name?: string, - currencyId?: string, - currencyName?: string, - type?: string, - allowWrite: boolean, - allowDelete: boolean, - allowManage: boolean, - categories?: AccountCategoryModel[], - accessRights?: AccountAccessRightModel[], -} diff --git a/MyOffice.SPA/src/app/model/currency.model.ts b/MyOffice.SPA/src/app/model/currency.model.ts deleted file mode 100644 index 5ad985a..0000000 --- a/MyOffice.SPA/src/app/model/currency.model.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface CurrencyModel { - id?: string, - name?: string, - code?: string, - shortName?: string, - symbol?: string, - quantity?: number, - rate?: number, - rateDate?: Date, - isConnected?: boolean, - isPrimary?: boolean, -} diff --git a/MyOffice.SPA/src/app/model/dashboard.model.ts b/MyOffice.SPA/src/app/model/dashboard.model.ts deleted file mode 100644 index 1545917..0000000 --- a/MyOffice.SPA/src/app/model/dashboard.model.ts +++ /dev/null @@ -1,38 +0,0 @@ -export interface DashboardModel { - incomeLast: number; - incomePrevious: number; - incomeChange: number; - outcomeLast: number; - outcomePrevious: number; - outcomeChange: number; - - balance: number; - balanceDebit: number; - balanceCredit: number; - - balanceRests: DashboardRestModel[]; -} - -export interface DashboardRestModel { - id: string; - name: string; - currencyName: string; - currencyShortName: string; - balance: number; - currencyRate: number; - currencyQuantity: number; - balanceAtRate: number; -} - -export interface DashboardInOutModel { - data: DashboardInOutItemModel[]; - details: DashboardInOutItemModel[]; -} - -export interface DashboardInOutItemModel { - id: string; - currency: string; - name: string; - value: number; - valueRaw: number; -} diff --git a/MyOffice.SPA/src/app/model/item.category.model.ts b/MyOffice.SPA/src/app/model/item.category.model.ts deleted file mode 100644 index 73a4191..0000000 --- a/MyOffice.SPA/src/app/model/item.category.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface ItemCategoryModel { - id?: string, - name?: string, - allowDelete: boolean, - internal: boolean, -} diff --git a/MyOffice.SPA/src/app/model/item.model.ts b/MyOffice.SPA/src/app/model/item.model.ts deleted file mode 100644 index 661682d..0000000 --- a/MyOffice.SPA/src/app/model/item.model.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface ItemModel { - id?: string, - name?: string, - categoryId?: string, - category?: string, - allowDelete: boolean, -} diff --git a/MyOffice.SPA/src/app/model/motion.model.ts b/MyOffice.SPA/src/app/model/motion.model.ts deleted file mode 100644 index 40a82d5..0000000 --- a/MyOffice.SPA/src/app/model/motion.model.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface MotionModel { - id?: string; - date?: Date; - item?: string; - description?: string; - itemId?: string; - accountId?: string; - plus?: number; - minus?: number; - amountBalancing?: number; -} diff --git a/MyOffice.SPA/src/app/pages/accounts/account.component.html b/MyOffice.SPA/src/app/pages/accounts/account.component.html deleted file mode 100644 index 50c925d..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/account.component.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -

{{account.account.name}}

-

- {{account.rest | number: '1.2-6'}} - ({{account.account.currencyId}}) -

-
-
-
- -
-
- - - - -
diff --git a/MyOffice.SPA/src/app/pages/accounts/account.component.scss b/MyOffice.SPA/src/app/pages/accounts/account.component.scss deleted file mode 100644 index 493077c..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/account.component.scss +++ /dev/null @@ -1,15 +0,0 @@ -:host-context(body.dark)account-motion:nth-child(even) { - filter: brightness(1); -} - -:host-context(body.dark)account-motion:nth-child(odd) { - filter: brightness(1.75); -} - -:host-context(body.light)account-motion:nth-child(even) { - filter: brightness(0.75); -} - -:host-context(body.light)account-motion:nth-child(odd) { - filter: brightness(1); -} diff --git a/MyOffice.SPA/src/app/pages/accounts/account.component.ts b/MyOffice.SPA/src/app/pages/accounts/account.component.ts deleted file mode 100644 index 852fdfb..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/account.component.ts +++ /dev/null @@ -1,110 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { Input } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { ActivatedRoute } from '@angular/router'; -import { Output } from '@angular/core'; -import { EventEmitter } from '@angular/core'; - -// libs -import moment from 'moment'; -import { Observable } from 'rxjs'; - -// app -import { ApiRoutes } from '../../api-routes'; -import { AccountDetailedModel } from '../../model/account.detailed.model'; -import { MotionModel } from '../../model/motion.model'; - -@Component({ - templateUrl: './account.component.html', - styleUrls: ['./account.component.scss'], - selector: 'account' -}) -export class AccountComponent { - public motions?: MotionModel[]; - public newMotion: MotionModel; - public dateFrom: Date = moment(new Date).add(-7, 'days').toDate(); - public dateTo: Date = moment(new Date).add(0, 'days').toDate(); - @Input('account') account!: AccountDetailedModel; - @Input('active') active: boolean = false; - @Input() reloadEvent!: Observable; - - @Output() onUpdate: EventEmitter = new EventEmitter(); - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - private activatedRoute: ActivatedRoute - ) { - this.newMotion = { - date: new Date(), - plus: 0, - minus: 0, - }; - } - - ngOnInit(): void { - this.loadMotions(); - - this.reloadEvent - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x.find(id => id === this.account.account.id)) { - this.loadMotions(); - } - }); - } - - onSubmitClick() { - } - - handlerOnAdd(motions: MotionModel[]) { - this.onUpdate?.emit(motions.filter(x => x.accountId !== this.account.account!.id)); - this.loadMotions(); - - this.httpClient - .get(ApiRoutes.Account.replace(':id', this.account.account!.id!)) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.account = data; - }); - } - - handlerOnDelete(motion: MotionModel) { - const index = this.motions!.findIndex(x => x.id === motion.id); - this.motions!.splice(index, 1); - } - - onChangePeriod(dates: Date[]) { - this.dateFrom = dates[0]; - this.dateTo = dates[1]; - this.loadMotions(); - } - - private loadMotions() { - var url = ApiRoutes.Motions.replace(':id', this.account.account.id!); - url += '?from=' + moment(this.dateFrom).format('yyyy-MM-DD'); - url += '&to=' + moment(this.dateTo).format('yyyy-MM-DD'); - - this.httpClient - .get(url) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.motions = data; - }); - } - - afterExpand() { - var refresh = window.location.protocol + "//"; - refresh += window.location.host; - refresh += window.location.pathname; - refresh += window.location.hash; - var idx = refresh.indexOf('/account/'); - if (idx > -1) { - refresh = refresh.substr(0, idx); - } - refresh += '/account/' + this.account.account.id; - window.history.pushState({ path: refresh }, '', refresh); - } -} diff --git a/MyOffice.SPA/src/app/pages/accounts/account.list.component.html b/MyOffice.SPA/src/app/pages/accounts/account.list.component.html deleted file mode 100644 index 8af7ec9..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/account.list.component.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
-
- - - -
-
-
- -
- -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/accounts/account.list.component.scss b/MyOffice.SPA/src/app/pages/accounts/account.list.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/accounts/account.list.component.ts b/MyOffice.SPA/src/app/pages/accounts/account.list.component.ts deleted file mode 100644 index c61c669..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/account.list.component.ts +++ /dev/null @@ -1,62 +0,0 @@ -// angular -import { Component, DestroyRef, inject, OnInit } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { ActivatedRoute } from '@angular/router'; - -// libs -import { Subject } from 'rxjs'; - -// app -import { AccountCategoryService } from '../../services/account.category.service'; -import { ApiRoutes } from '../../api-routes'; -import { AccountDetailedModel } from '../../model/account.detailed.model'; -import { MotionModel } from '../../model/motion.model'; - -@Component({ - templateUrl: './account.list.component.html', - styleUrls: ['./account.list.component.scss'], -}) -export class AccountListComponent implements OnInit { - public accounts?: AccountDetailedModel[]; - public category = ''; - public activeAccount = ''; - - reloadSubject: Subject = new Subject(); - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - private activatedRoute: ActivatedRoute, - private accountCategoryService: AccountCategoryService, - ) { - this.activatedRoute.params - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => this.activeAccount = x['accountId']); - } - - ngOnInit(): void { - this.activatedRoute.params - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(params => { - var categoryId = params['id']; - - this.httpClient - .get(ApiRoutes.Accounts + '?category=' + categoryId) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.accounts = data; - }); - this.accountCategoryService - .getCategory(categoryId) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.category = data.name!; - }); - }); - } - - handlerOnUpdate(motions: MotionModel[]) { - this.reloadSubject.next(motions.map(x => x.accountId!)); - } -} diff --git a/MyOffice.SPA/src/app/pages/accounts/motion.component.html b/MyOffice.SPA/src/app/pages/accounts/motion.component.html deleted file mode 100644 index 91e378b..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/motion.component.html +++ /dev/null @@ -1,84 +0,0 @@ -
-
-
-
- - arrow_back - - - - - YYYY/MM/DD - - - - Please enter rate date - - - - - arrow_forward - -
-
-
- - - Motion - !! - - - - Please enter motion - - - - {{item.name}} - - - - - - -
-
- - - - Please enter motion - - - - - - Please enter motion - - -
-
- - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/accounts/motion.component.scss b/MyOffice.SPA/src/app/pages/accounts/motion.component.scss deleted file mode 100644 index 47f7e12..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/motion.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.mat-mdc-option.mdc-list-item.mat-mdc-option-active { - filter: brightness(50%) -} diff --git a/MyOffice.SPA/src/app/pages/accounts/motion.component.ts b/MyOffice.SPA/src/app/pages/accounts/motion.component.ts deleted file mode 100644 index 82938a9..0000000 --- a/MyOffice.SPA/src/app/pages/accounts/motion.component.ts +++ /dev/null @@ -1,274 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { FormBuilder } from '@angular/forms'; -import { FormGroup } from '@angular/forms'; -import { Validators } from '@angular/forms'; -import { Input } from '@angular/core'; -import { Output } from '@angular/core'; -import { EventEmitter } from '@angular/core'; -import { ViewChild } from '@angular/core'; -import { ElementRef } from '@angular/core'; - -// libs -import moment from 'moment'; -import Swal from 'sweetalert2'; -import { debounceTime, switchMap } from 'rxjs/operators'; -import { of } from 'rxjs'; -import { pulseAnimation } from 'angular-animations'; - -// app -import { ApiRoutes } from '../../api-routes'; -import { AccountModel } from '../../model/account.model'; -import { MotionModel } from '../../model/motion.model'; -import { ItemModel } from '../../model/item.model'; -import { atLeastOneNumber } from '../../core/validators/atleastonenumber.validator'; - -@Component({ - selector: 'account-motion', - templateUrl: './motion.component.html', - styleUrls: ['./motion.component.scss'], - animations: [ - pulseAnimation({ direction: '<=>', duration: 200 }), - ], -}) -export class MotionComponent { - public form!: FormGroup; - public errorMessage?: string; - public filteredItems: ItemModel[] = []; - public option?: string; - public selectedItem?: ItemModel; - public inProgress: boolean = false; - - @Input('motion') motion!: MotionModel; - @Input('account') account!: AccountModel; - - @Output() onAdd: EventEmitter = new EventEmitter(); - @Output() onDelete: EventEmitter = new EventEmitter(); - - @ViewChild('motionInput') motionInput?: ElementRef; - @ViewChild('dateInput') dateInput?: ElementRef; - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - ) { - } - - ngOnInit(): void { - this.form = this.fb.group({ - id: [ - this.motion.id, - ], - date: [ - this.motion.date, - [Validators.required], - ], - item: [ - this.motion.item, - [Validators.required], - ], - description: [ - this.motion.description, - ], - plus: [ - this.motion.plus, - ], - minus: [ - this.motion.minus, - ], - }, { - validator: atLeastOneNumber(Validators.required, ['plus', 'minus']) - }); - - this.form.controls['item'].valueChanges - .pipe( - debounceTime(200), - switchMap(value => { - if (!value || typeof value !== 'string') { - return of([] as ItemModel[]); - } - this.selectedItem = undefined; - return this.httpClient.get( - ApiRoutes.Items + '?term=' + encodeURIComponent(value) - ); - }), - takeUntilDestroyed(this.destroyRef) - ) - .subscribe(x => { - this.filteredItems = x; - }); - - this.form.valueChanges - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(() => { - this.form.controls['plus'].markAsPristine(); - this.form.controls['plus'].markAsUntouched(); - this.form.controls['plus'].setErrors(null); - this.form.controls['minus'].markAsPristine(); - this.form.controls['minus'].markAsUntouched(); - this.form.controls['minus'].setErrors(null); - }); - } - - displayFn(item: any): string { - var value = item && item.name ? item.name : item; - return value; - } - - selectedFn(item: ItemModel) { - this.selectedItem = item; - } - - add() { - this.form.markAllAsTouched(); - - if (this.form.hasError('atLeastOne')) { - this.form.get('plus')!.setErrors(this.form.errors); - this.form.get('minus')!.setErrors(this.form.errors); - return; - } - - if (!this.form.valid) { - return; - } - - this.setInProgress(); - - var data: MotionModel = { - date: this.form.value.date, - description: this.form.value.description, - plus: this.form.value.plus || 0, - minus: this.form.value.minus || 0, - }; - - if (this.form.value.item.name) { - data.date = this.form.value.date; - data.item = this.form.value.item.name; - data.itemId = this.form.value.item.id; - data.accountId = this.form.value.item.accountId; - data.amountBalancing = data.plus! > 0 ? data.plus : data.minus; - } else { - data.item = this.form.value.item; - } - - this.httpClient - .post(ApiRoutes.Motions.replace(':id', this.account.id!), data) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: response => { - this.onAdd?.emit(response); - - this.form.patchValue({ - item: '', - plus: 0, - minus: 0, - }); - - this.filteredItems = []; - this.motionInput?.nativeElement.focus(); - this.form.markAsUntouched(); - this.setInProgress(false); - }, - error: error => { - this.errorMessage = error.detail; - this.setInProgress(false); - } - }); - } - - private setInProgress(inProgress: boolean = true) { - this.inProgress = inProgress; - } - - update() { - this.form.markAllAsTouched(); - - if (!this.form.valid) { - if (this.form.hasError('atLeastOne')) { - this.form.get('plus')!.setErrors(this.form.errors); - this.form.get('minus')!.setErrors(this.form.errors); - } - return; - } - - this.setInProgress(); - - var url = ApiRoutes.Motion - .replace(':id', this.account.id!) - .replace(':motionId', this.motion.id!); - - var data = this.form.value; - data.motion = data.item.name - ? data.item.name - : data.motion; - data.itemId = this.selectedItem?.id; - - this.httpClient - .put(url, data) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: () => { - this.form.markAsUntouched(); - this.setInProgress(false); - }, - error: error => { - this.errorMessage = error.detail; - this.setInProgress(false); - } - }); - } - - delete() { - Swal.fire({ - title: 'Delete motion ' + this.motion.item, - showCancelButton: true, - confirmButtonText: 'Delete', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - var url = ApiRoutes.Motion - .replace(':id', this.account.id!) - .replace(':motionId', this.motion.id!); - - this.setInProgress(); - - this.httpClient.delete(url) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: data => { - resolve(data); - this.setInProgress(false); - }, - error: error => { - Swal.showValidationMessage(error.detail); - reject(); - this.setInProgress(false); - } - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - if (result.isConfirmed) { - this.onDelete?.emit((result.value! as MotionModel)); - } - }); - } - - import() { - - } - - addDay(days: number) { - var date = moment(this.form!.get('date')!.value).add(days, 'days').toDate(); - this.form.patchValue({ - date: date, - }); - } -} diff --git a/MyOffice.SPA/src/app/pages/pages-routing.module.ts b/MyOffice.SPA/src/app/pages/pages-routing.module.ts deleted file mode 100644 index 9341c68..0000000 --- a/MyOffice.SPA/src/app/pages/pages-routing.module.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { UserProfileComponent } from './user-profile/user-profile.component'; -import { SettingsCurrencyComponent } from './settings/currency/currency.component'; -import { SettingsAccountCategoryComponent } from './settings/account/account.category.component'; -import { SettingsAccountComponent } from './settings/account/account.component'; -import { SettingsItemCategoryComponent } from './settings/item/item.category.component'; -import { SettingsItemComponent } from './settings/item/item.component'; -import { AccountListComponent } from './accounts/account.list.component'; - -const routes: Routes = [ - { - path: '', - redirectTo: 'signin', - pathMatch: 'full', - }, - { - path: 'user/profile', - component: UserProfileComponent, - }, - { - path: 'settings/currencies', - component: SettingsCurrencyComponent, - }, - { - path: 'settings/account-categories', - component: SettingsAccountCategoryComponent, - }, - { - path: 'settings/accounts', - component: SettingsAccountComponent, - }, - { - path: 'settings/item-categories', - component: SettingsItemCategoryComponent, - }, - { - path: 'settings/items', - component: SettingsItemComponent, - }, - { - path: 'account-category/:id', - component: AccountListComponent, - }, - { - path: 'account-category/:id/account/:accountId', - component: AccountListComponent, - }, -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class PagesRoutingModule { -} diff --git a/MyOffice.SPA/src/app/pages/pages.module.ts b/MyOffice.SPA/src/app/pages/pages.module.ts deleted file mode 100644 index 7a18563..0000000 --- a/MyOffice.SPA/src/app/pages/pages.module.ts +++ /dev/null @@ -1,102 +0,0 @@ -// angular -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { ReactiveFormsModule } from '@angular/forms'; - -// libs -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatSelectModule } from '@angular/material/select'; -import { MatTabsModule } from '@angular/material/tabs'; -import { MatIconModule } from '@angular/material/icon'; -import { MatButtonModule } from '@angular/material/button'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatDatepickerModule } from '@angular/material/datepicker'; -import { MatGridListModule } from '@angular/material/grid-list'; -import { MatCardModule } from '@angular/material/card'; -import { NgxMaskDirective, NgxMaskPipe } from 'ngx-mask'; -import { NgxCurrencyDirective } from 'ngx-currency'; -import { MatExpansionModule } from '@angular/material/expansion'; -import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatMenuModule } from '@angular/material/menu'; -import { MAT_DATE_LOCALE } from '@angular/material/core'; - -// app -import { PagesRoutingModule } from './pages-routing.module'; -import { ComponentsModule } from '../shared/components/components.module'; -import { SettingsCurrencyComponent } from './settings/currency/currency.component'; -import { SettingsConnectCurrencyComponent } from './settings/currency/connect.currency.component'; -import { UserProfileComponent } from './user-profile/user-profile.component'; -import { SettingsRateCurrencyComponent } from './settings/currency/rate.currency.component'; -import { SettingsAccountCategoryComponent } from './settings/account/account.category.component'; -import { SettingsAccountComponent } from './settings/account/account.component'; -import { SettingsAccountAddComponent } from './settings/account/add.account.component'; -import { SettingsAccountEditComponent } from './settings/account/edit.account.component'; -import { SettingsAccountAccessComponent } from './settings/account/access.account.component'; -import { CurrencyService } from '../services/currency.service'; -import { ItemService } from '../services/item.service'; -import { SettingsItemCategoryComponent } from './settings/item/item.category.component'; -import { SettingsItemComponent } from './settings/item/item.component'; -import { SettingsItemEditComponent } from './settings/item/edit.item.component'; -import { AccountListComponent } from './accounts/account.list.component'; -import { AccountComponent } from './accounts/account.component'; -import { MotionComponent } from './accounts/motion.component'; -import { SettingsItemCategoryEditComponent } from './settings/item/edit.item.category.component'; - -@NgModule({ - declarations: [ - UserProfileComponent, - - SettingsCurrencyComponent, - SettingsConnectCurrencyComponent, - SettingsRateCurrencyComponent, - - SettingsAccountCategoryComponent, - SettingsAccountComponent, - SettingsAccountAddComponent, - SettingsAccountEditComponent, - SettingsAccountAccessComponent, - - SettingsItemCategoryComponent, - SettingsItemComponent, - SettingsItemEditComponent, - SettingsItemCategoryEditComponent, - - AccountListComponent, - AccountComponent, - MotionComponent, - ], - imports: [ - CommonModule, - ComponentsModule, - FormsModule, - ReactiveFormsModule, - PagesRoutingModule, - MatFormFieldModule, - MatSelectModule, - MatInputModule, - MatIconModule, - MatButtonModule, - MatTabsModule, - MatDialogModule, - MatDatepickerModule, - MatGridListModule, - MatCardModule, - MatExpansionModule, - MatAutocompleteModule, - NgxMaskDirective, - NgxMaskPipe, - NgxCurrencyDirective, - MatCheckboxModule, - MatMenuModule, - ], - providers: [ - { provide: MAT_DATE_LOCALE, useValue: 'en-GB' }, - CurrencyService, - ItemService, - ], -}) -export class PagesModule { -} diff --git a/MyOffice.SPA/src/app/pages/settings/account/access.account.component.html b/MyOffice.SPA/src/app/pages/settings/account/access.account.component.html deleted file mode 100644 index 78ddef0..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/access.account.component.html +++ /dev/null @@ -1,47 +0,0 @@ -
-
- - - - - - -
-
- -
- - Email - - -
-
-
-
User rights
-
- - Allow write - -
-
-
-
-
-
- - {{access.user.email}} - (owner) -
-
- - Allow write - -
-
- -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/account/access.account.component.scss b/MyOffice.SPA/src/app/pages/settings/account/access.account.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/account/access.account.component.ts b/MyOffice.SPA/src/app/pages/settings/account/access.account.component.ts deleted file mode 100644 index 818d251..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/access.account.component.ts +++ /dev/null @@ -1,128 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { Inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; - -// libs -import Swal from 'sweetalert2'; -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import * as ld from 'lodash'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { AccountModel } from '../../../model/account.model'; -import { MatDialogRef } from '@angular/material/dialog'; -import { CurrencyService } from '../../../services/currency.service'; -import { CurrencyModel } from '../../../model/currency.model'; -import { AccountCategoryService } from '../../../services/account.category.service'; -import { AccountCategoryModel } from '../../../model/account.category.model'; -import { AccountAccessRightModel } from '../../../model/account.accessRight.model'; -import { AccountService } from '../../../services/account.service'; - -@Component({ - templateUrl: './access.account.component.html', - styleUrls: ['./access.account.component.scss'], -}) -export class SettingsAccountAccessComponent { - public editForm!: FormGroup; - public errorMessage?: string; - public currencies?: CurrencyModel[]; - public categories?: AccountCategoryModel[]; - public types = new Map(); - - public accessRightsSorted: AccountAccessRightModel[]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private dialogRef: MatDialogRef, - private accountService: AccountService, - @Inject(MAT_DIALOG_DATA) public account: AccountModel - ) { - this.types = this.accountService.getTypes(); - - this.accessRightsSorted = ld.orderBy(account.accessRights!, ['isOwner', 'user.email'], ['desc', 'asc']); - - } - - ngOnInit(): void { - const accesses = this.fb.array( - this.accessRightsSorted.map(x => this.fb.group({ - userId: [ - x.user.id - ], - allowWrite: [{ - value: x.isAllowWrite, - disabled: !x.isAllowDelete, - }], - })) - ); - - this.editForm = this.fb.group({ - email: [ - '', - ], - allowWrite: [ - false, - ], - accesses: accesses, - }); - } - - removeAccessRight(accessRight: AccountAccessRightModel) { - Swal.fire({ - title: 'Delete access ' + accessRight.user.email, - showCancelButton: true, - confirmButtonText: 'Delete', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - var url = ApiRoutes.SettingsAccountAccess - .replace(':id', this.account.id!) - .replace(':access', accessRight.user.id); - - this.errorMessage = undefined; - this.httpClient - .delete(url, this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - resolve(response); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - if (result.isConfirmed) { - this.dialogRef.close({ refresh: true }); - } - }); - } - - closeDialog(): void { - this.dialogRef.close(); - } - - onSubmitClick() { - if (this.editForm.valid) { - this.errorMessage = undefined; - this.httpClient - .post(ApiRoutes.SettingsAccountAccesses.replace(':id', this.account.id!), this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dialogRef.close({ refresh: true }); - }, error => { - this.errorMessage = error.detail; - }); - } - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/account/account.category.component.html b/MyOffice.SPA/src/app/pages/settings/account/account.category.component.html deleted file mode 100644 index 55ca473..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/account.category.component.html +++ /dev/null @@ -1,47 +0,0 @@ -
-
-
- - - -
-
-
- - - - - Account categories - - - - -
- -
- -
- - - - - - - -
{{item.name}} - - -
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/account/account.category.component.scss b/MyOffice.SPA/src/app/pages/settings/account/account.category.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/account/account.category.component.ts b/MyOffice.SPA/src/app/pages/settings/account/account.category.component.ts deleted file mode 100644 index 2c6c309..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/account.category.component.ts +++ /dev/null @@ -1,129 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; - -// libs -import Swal from 'sweetalert2'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { AccountCategoryModel } from '../../../model/account.category.model'; - -@Component({ - templateUrl: './account.category.component.html', - styleUrls: ['./account.category.component.scss'], -}) -export class SettingsAccountCategoryComponent { - public categories?: AccountCategoryModel[]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - ) { - } - - ngOnInit(): void { - this.load(); - } - - private load() { - this.httpClient - .get(ApiRoutes.SettingsAccountCategories) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.categories = data; - }); - } - - public add() { - Swal.fire({ - title: 'Account category name', - input: 'text', - inputAttributes: { - autocapitalize: 'off', - }, - showCancelButton: true, - confirmButtonText: 'Add', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - this.httpClient.post(ApiRoutes.SettingsAccountCategories, { name: name }) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - this.load(); - }); - } - - public edit(category: AccountCategoryModel) { - Swal.fire({ - title: 'Account category name', - input: 'text', - inputValue: category.name, - inputAttributes: { - autocapitalize: 'off', - }, - showCancelButton: true, - confirmButtonText: 'Update', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - this.httpClient.put(ApiRoutes.SettingsAccountCategory.replace(':id', category.id!), { name: name }) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - this.load(); - }); - } - - public remove(category: AccountCategoryModel) { - Swal.fire({ - title: 'Delete account category ' + category.name, - showCancelButton: true, - confirmButtonText: 'Delete', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - this.httpClient.delete(ApiRoutes.SettingsAccountCategory.replace(':id', category.id!)) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - this.load(); - }); - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/account/account.component.html b/MyOffice.SPA/src/app/pages/settings/account/account.component.html deleted file mode 100644 index 7f820bc..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/account.component.html +++ /dev/null @@ -1,99 +0,0 @@ -
-
-
- - - -
-
-
- - - - - Accounts - - - - -
-
- - - - -
- -
- -
- - - - - - - - - - - -
{{account.name}}{{account.currencyId}}{{account.type}} - - - -
-
- - - - - - - - - - -
{{account.name}}{{account.currencyId}}{{account.type}} - - -
-
- - - - - - - - - -
{{account.name}}{{account.currencyId}} - - -
-
-
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/account/account.component.scss b/MyOffice.SPA/src/app/pages/settings/account/account.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/account/account.component.ts b/MyOffice.SPA/src/app/pages/settings/account/account.component.ts deleted file mode 100644 index d2bcf46..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/account.component.ts +++ /dev/null @@ -1,214 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; - -// libs -import Swal from 'sweetalert2'; -import { MatDialog } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { AccountModel } from '../../../model/account.model'; -import { AccountCategoryModel } from '../../../model/account.category.model'; -import { AccountInviteModel } from '../../../model/account.invite.model'; -import { SettingsAccountAddComponent } from './add.account.component'; -import { SettingsAccountEditComponent } from './edit.account.component'; -import { SettingsAccountAccessComponent } from './access.account.component'; -import { AccountCategoryService } from '../../../services/account.category.service'; - -@Component({ - templateUrl: './account.component.html', - styleUrls: ['./account.component.scss'], -}) -export class SettingsAccountComponent { - public accountCategories?: AccountCategoryModel[]; - public accounts?: AccountModel[]; - public invites?: AccountInviteModel[]; - public tabIndex = 0; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - private dialogModel: MatDialog, - private accountCategoryService: AccountCategoryService, - ) { - } - - ngOnInit(): void { - this.loadCategories(); - this.loadInvites(); - } - - private loadAccounts(accountToShow?: string) { - this.httpClient - .get(ApiRoutes.SettingsAccounts) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.accounts = data; - if (accountToShow) { - var idx = -1; - var account = this.accounts.find(x => x.id === accountToShow); - if (account && account.categories && account.categories.length > 0) { - for (var i = 0; i < this.accountCategories!.length; i++) { - if (account!.categories!.find(c => c.id === this.accountCategories![i].id)) { - idx = i; - break; - } - } - } - this.tabIndex = idx === -1 ? this.accountCategories!.length : idx; - } - }); - } - - private loadInvites() { - return this.httpClient - .get(ApiRoutes.SettingsAccountInvites) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.invites = response; - }); - } - - private loadCategories() { - this.accountCategoryService - .getCategories() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - this.accountCategories = x; - this.loadAccounts(); - }); - } - - public accountInCategory(category?: AccountCategoryModel) { - if (this.accounts) { - return this.accounts.filter(acc => (!category && (!acc.categories || acc.categories.length === 0)) || (category && acc.categories && acc.categories.filter(cat => cat.id === category.id).length > 0)); - } - return null; - } - - public add() { - this.dialogModel.open(SettingsAccountAddComponent, { - width: '640px', - disableClose: true, - data: this.accounts, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - this.loadAccounts(); - } - }); - } - - public edit(account: AccountModel) { - this.dialogModel.open(SettingsAccountEditComponent, { - width: '640px', - disableClose: true, - data: account, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - this.loadAccounts(); - } - }); - } - - public remove(account: AccountModel) { - Swal.fire({ - title: 'Remove account ' + account.name, - showCancelButton: true, - confirmButtonText: 'Delete', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - this.httpClient.delete(ApiRoutes.SettingsAccount.replace(':id', account.id!)) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - this.loadAccounts(); - }); - } - - public access(account: AccountModel) { - this.dialogModel.open(SettingsAccountAccessComponent, { - width: '640px', - disableClose: true, - data: account, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - this.loadAccounts(); - } - }); - } - - public startInvite(invite: AccountInviteModel) { - Swal.fire({ - title: 'Accept to invite the account "' + invite.account + '"', - input: 'text', - inputLabel: 'Accept with name', - inputValue: invite.account, - showDenyButton: true, - showCancelButton: true, - confirmButtonText: 'Accept', - denyButtonText: 'Reject', - showLoaderOnConfirm: true, - preConfirm: (input) => { - return new Promise((resolve, reject) => { - this.httpClient.post(ApiRoutes.SettingsAccountInviteAccept.replace(':id', invite.id!), { name: input }) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - preDeny: (x) => { - return new Promise((resolve, reject) => { - this.httpClient.post(ApiRoutes.SettingsAccountInviteReject.replace(':id', invite.id!), null) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - var id; - if (result.value) { - var account = result.value as AccountModel; - id = account.id; - } - this.loadInvites(); - this.loadAccounts(id); - }); - - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/account/add.account.component.html b/MyOffice.SPA/src/app/pages/settings/account/add.account.component.html deleted file mode 100644 index 5f94441..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/add.account.component.html +++ /dev/null @@ -1,62 +0,0 @@ -
-
- - - - - - -
-
-
- - Type - - - {{type.key}} ({{type.value}}) - - - -
-
-
- -
-
-
- - Name - - -
-
-
-
- - Currency - - - {{currency.code}} ({{currency.name}}) - - - -
-
-
-
-
-
- - Category - - - {{category.name}} - - - -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/account/add.account.component.scss b/MyOffice.SPA/src/app/pages/settings/account/add.account.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/account/add.account.component.ts b/MyOffice.SPA/src/app/pages/settings/account/add.account.component.ts deleted file mode 100644 index 70688cd..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/add.account.component.ts +++ /dev/null @@ -1,101 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { Inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -// libs -import Swal from 'sweetalert2'; -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { AccountModel } from '../../../model/account.model'; -import { MatDialogRef } from '@angular/material/dialog'; -import { CurrencyService } from '../../../services/currency.service'; -import { CurrencyModel } from '../../../model/currency.model'; -import { AccountCategoryService } from '../../../services/account.category.service'; -import { AccountCategoryModel } from '../../../model/account.category.model'; -import { AuthService } from '../../../core/service/auth.service'; -import { AccountService } from '../../../services/account.service'; - -@Component({ - templateUrl: './add.account.component.html', - styleUrls: ['./add.account.component.scss'], -}) -export class SettingsAccountAddComponent { - public editForm!: FormGroup; - public errorMessage?: string; - public currencies?: CurrencyModel[]; - public categories?: AccountCategoryModel[]; - public username: string; - public types = new Map(); - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private dialogRef: MatDialogRef, - private currencyService: CurrencyService, - private accountCategoryService: AccountCategoryService, - private authService: AuthService, - private accountService: AccountService, - @Inject(MAT_DIALOG_DATA) public account: AccountModel - ) { - this.username = authService.currentUserValue.userName; - this.types = this.accountService.getTypes(); - } - - ngOnInit(): void { - this.editForm = this.fb.group({ - id: [ - this.account.id, - ], - name: [ - this.account.name, - [Validators.required], - ], - currencyId: [ - this.account.currencyId, - [Validators.required], - ], - categoryId: [ - '', - [Validators.required], - ], - type: [ - this.account.type - ] - }); - - this.currencyService - .getCurrencies() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => this.currencies = x); - - this.accountCategoryService - .getCategories() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => this.categories = x); - } - - closeDialog(): void { - this.dialogRef.close(); - } - - onSubmitClick() { - if (this.editForm.valid) { - this.errorMessage = undefined; - this.httpClient - .post(ApiRoutes.SettingsAccounts, this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dialogRef.close({ refresh: true }); - }, error => { - this.errorMessage = error.detail; - }); - } - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.html b/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.html deleted file mode 100644 index 913a55a..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.html +++ /dev/null @@ -1,93 +0,0 @@ -
-
- - - - - - -
-
-
- - Type - - - {{type.key}} ({{type.value}}) - - - -
-
-
- -
-
-
- - Name - - -
-
-
-
- - Currency - - - {{currency.code}} ({{currency.name}}) - - - -
-
-
- -
-
- - - - - - - - -
{{category.name}} - -
- -
No categories assigned
-
-
-
- -
-
- -
- - Category - - - {{category.name}} - - - - -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.scss b/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.scss deleted file mode 100644 index 07f1433..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -.section-label { - display: block; - font-weight: 500; - margin-bottom: 8px; -} - -.category-add-block { - margin-bottom: 8px; -} - -.category-add-row { - display: flex; - align-items: flex-start; - gap: 12px; -} - -.category-add-select { - flex: 1; -} - -.empty-categories { - opacity: 0.7; - padding: 8px 0 16px; -} diff --git a/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.ts b/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.ts deleted file mode 100644 index d5550e1..0000000 --- a/MyOffice.SPA/src/app/pages/settings/account/edit.account.component.ts +++ /dev/null @@ -1,161 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { Inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -// libs -import Swal from 'sweetalert2'; -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import * as ld from 'lodash'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { AccountModel } from '../../../model/account.model'; -import { MatDialogRef } from '@angular/material/dialog'; -import { CurrencyService } from '../../../services/currency.service'; -import { CurrencyModel } from '../../../model/currency.model'; -import { AccountCategoryService } from '../../../services/account.category.service'; -import { AccountCategoryModel } from '../../../model/account.category.model'; -import { AccountAccessRightModel } from '../../../model/account.accessRight.model'; -import { AccountService } from '../../../services/account.service'; - -@Component({ - templateUrl: './edit.account.component.html', - styleUrls: ['./edit.account.component.scss'], -}) -export class SettingsAccountEditComponent { - public editForm!: FormGroup; - public errorMessage?: string; - public currencies?: CurrencyModel[]; - public categories?: AccountCategoryModel[]; - public types = new Map(); - - public categoriesSorted: AccountCategoryModel[]; - public accessRightsSorted: AccountAccessRightModel[]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private dialogRef: MatDialogRef, - private currencyService: CurrencyService, - private accountCategoryService: AccountCategoryService, - private accountService: AccountService, - @Inject(MAT_DIALOG_DATA) public account: AccountModel - ) { - this.types = this.accountService.getTypes(); - - this.categoriesSorted = ld.orderBy(account.categories ?? [], ['name'], ['asc']); - this.accessRightsSorted = ld.orderBy(account.accessRights!, ['isOwner', 'user.email'], ['desc', 'asc']); - } - - /** Categories not yet assigned to this account (for the Add select). */ - get availableCategories(): AccountCategoryModel[] { - const assigned = new Set((this.categoriesSorted ?? []).map(c => c.id)); - return (this.categories ?? []).filter(c => !assigned.has(c.id)); - } - - ngOnInit(): void { - this.editForm = this.fb.group({ - id: [ - this.account.id, - ], - name: [ - this.account.name, - [Validators.required], - ], - currencyId: [ - this.account.currencyId, - [Validators.required], - ], - categoryId: [ - '', - ], - type: [ - this.account.type, - ], - userEmail: [ - '', - ], - }); - - this.currencyService - .getCurrencies() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => this.currencies = x); - - this.accountCategoryService - .getCategories() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => this.categories = x); - } - - addCategory() { - const categoryId = this.editForm.get('categoryId')?.value; - if (!categoryId || !this.editForm.valid) { - this.editForm.markAllAsTouched(); - return; - } - - this.errorMessage = undefined; - this.httpClient - .put(ApiRoutes.SettingsAccount.replace(':id', this.account.id!), this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: account => { - this.applyAccountCategories(account); - this.editForm.patchValue({ categoryId: '' }); - }, - error: error => { - this.errorMessage = error.detail; - }, - }); - } - - removeCategory(category: AccountCategoryModel) { - const url = ApiRoutes.SettingsAccountAccountCategory - .replace(':id', this.account.id!) - .replace(':categoryId', category.id!); - - this.errorMessage = undefined; - this.httpClient - .delete(url) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: account => this.applyAccountCategories(account), - error: error => { - this.errorMessage = error.detail; - }, - }); - } - - private applyAccountCategories(account: AccountModel) { - this.account.categories = account.categories ?? []; - this.categoriesSorted = ld.orderBy(this.account.categories, ['name'], ['asc']); - } - - removeAccessRight(accessRight: AccountAccessRightModel) { - - } - - closeDialog(): void { - this.dialogRef.close(); - } - - onSubmitClick() { - if (this.editForm.valid) { - this.errorMessage = undefined; - this.httpClient - .put(ApiRoutes.SettingsAccount.replace(':id', this.account.id!), this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dialogRef.close({ refresh: true }); - }, error => { - this.errorMessage = error.detail; - }); - } - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.html b/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.html deleted file mode 100644 index 8d21ed8..0000000 --- a/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.html +++ /dev/null @@ -1,85 +0,0 @@ -
-
- - - - - - -
-
-
- - Symbol - - -
-
-
-
- - Code - - -
-
-
-
-
-
- - Name - - -
-
-
-
- - Short Name - - -
-
-
-
-
-
- - Rate - - - Please enter rate - - -
-
-
-
- - Quantity - - - Please enter rate - - -
-
-
-
- - Rate Date - - YYYY/MM/DD - - - - Please enter rate date - - -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.scss b/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.ts b/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.ts deleted file mode 100644 index 7d142ee..0000000 --- a/MyOffice.SPA/src/app/pages/settings/currency/connect.currency.component.ts +++ /dev/null @@ -1,80 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -// libs -import { MatDialogRef } from '@angular/material/dialog'; -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { CurrencyModel } from '../../../model/currency.model'; - -@Component({ - templateUrl: './connect.currency.component.html', - styleUrls: ['./connect.currency.component.scss'], -}) -export class SettingsConnectCurrencyComponent { - public addForm!: FormGroup; - public errorMessage?: string; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public currency: CurrencyModel - ) { - } - - public ngOnInit(): void { - this.addForm = this.fb.group({ - id: [ - this.currency.id, - ], - symbol: [ - this.currency.symbol, - ], - name: [ - this.currency.name, - ], - shortName: [ - this.currency.id, - ], - quantity: [ - this.currency.quantity || 1, - [Validators.required], - ], - rate: [ - this.currency.rate || 1, - [Validators.required], - ], - rateDate: [ - this.currency.rateDate, - [Validators.required], - ], - }); - } - - closeDialog(): void { - this.dialogRef.close(); - } - - onSubmitClick() { - if (this.addForm.valid) { - this.errorMessage = undefined; - this.httpClient - .post(ApiRoutes.SettingsCurrencies, this.addForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dialogRef.close({ refresh: true }); - }, error => { - this.errorMessage = error.detail; - }); - } - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/currency/currency.component.html b/MyOffice.SPA/src/app/pages/settings/currency/currency.component.html deleted file mode 100644 index f3c3b86..0000000 --- a/MyOffice.SPA/src/app/pages/settings/currency/currency.component.html +++ /dev/null @@ -1,88 +0,0 @@ -
-
-
- - - -
-
-
-
-
-

My currencies

-
-
- - -
- - - - - - - - - - - - - - - - - - - - - - - -
CodeNameShort NameQuantityRateRate Date
{{item.code}}{{item.name}}{{item.shortName}} - {{item.quantity}} - - {{item.rate | number: '1.2-6'}} - {{item.symbol}} - {{item.rateDate | date:'yyyy-MM-dd'}} - - -
-
-
- -
- - - - - - - - - - - - - - - - - -
{{item.symbol}}{{item.id}}{{item.name}} - -
-
-
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/currency/currency.component.scss b/MyOffice.SPA/src/app/pages/settings/currency/currency.component.scss deleted file mode 100644 index faf4a57..0000000 --- a/MyOffice.SPA/src/app/pages/settings/currency/currency.component.scss +++ /dev/null @@ -1,15 +0,0 @@ -// Primary currency highlight must target cells — Bootstrap paints td backgrounds, -// so a class on alone is invisible in light theme. -.table tbody tr.currency-row-primary > td, -.table tbody tr.currency-row-primary > th { - background-color: rgba(0, 188, 212, 0.18) !important; - color: inherit; -} - -:host-context(body.dark) { - .table tbody tr.currency-row-primary > td, - .table tbody tr.currency-row-primary > th { - background-color: rgba(33, 150, 243, 0.22) !important; - color: #cfe8ff; - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/currency/currency.component.ts b/MyOffice.SPA/src/app/pages/settings/currency/currency.component.ts deleted file mode 100644 index adab3f8..0000000 --- a/MyOffice.SPA/src/app/pages/settings/currency/currency.component.ts +++ /dev/null @@ -1,133 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; - -// libs -import { MatDialog } from '@angular/material/dialog'; -import Swal from 'sweetalert2'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { SettingsConnectCurrencyComponent } from './connect.currency.component'; -import { CurrencyModel } from '../../../model/currency.model'; -import { SettingsRateCurrencyComponent } from './rate.currency.component'; - -@Component({ - templateUrl: './currency.component.html', - styleUrls: ['./currency.component.scss'], -}) -export class SettingsCurrencyComponent { - public tabIndex = 0; - - public currencies?: CurrencyModel[]; - public myCurrencies?: CurrencyModel[]; - public primaryId?: string; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - private dialogModel: MatDialog - ) { - } - - ngOnInit(): void { - this.load(); - } - - connect(currency: CurrencyModel) { - this.dialogModel.open(SettingsConnectCurrencyComponent, { - width: '640px', - disableClose: true, - data: currency, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - this.tabIndex = 0; - this.loadMyCurrency(); - } - }); - } - - disconnect(currency: CurrencyModel) { - } - - setRate(currency: CurrencyModel) { - this.dialogModel.open(SettingsRateCurrencyComponent, { - width: '640px', - disableClose: true, - data: currency, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - this.loadMyCurrency(); - } - }); - } - - delete(currency: CurrencyModel) { - Swal.fire({ - title: 'Delete currency ' + currency.name, - showCancelButton: true, - confirmButtonText: 'Delete', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - this.httpClient.delete(ApiRoutes.SettingsCurrency.replace(':id', currency.id!)) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - this.load(); - }); - - } - - private load() { - this.httpClient - .get(ApiRoutes.GeneralCurrencies) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.currencies = data; - this.loadMyCurrency(); - }); - } - - private loadMyCurrency() { - this.httpClient - .get(ApiRoutes.SettingsCurrencies) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.myCurrencies = data - .sort((a, b) => a.code!.localeCompare(b.code!)) - .map(myCurrency => { - var globalCurrency = this.currencies?.find(x => x.id === myCurrency.code); - - return { - id: myCurrency.id, - code: myCurrency.code, - name: myCurrency.name, - quantity: myCurrency.quantity, - rate: myCurrency.rate, - rateDate: myCurrency.rateDate, - shortName: myCurrency.shortName, - symbol: globalCurrency?.symbol, - isPrimary: myCurrency.isPrimary, - }; - }); - }); - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.html b/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.html deleted file mode 100644 index 61c3640..0000000 --- a/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.html +++ /dev/null @@ -1,95 +0,0 @@ -
-
- - - - - - -
-
-
- - Symbol - - -
-
-
-
- - Code - - -
-
-
-
- - Name - - -
-
-
-
- - Short name - - -
-
-
-
-
-
- - Rate - - - Please enter rate - - -
-
-
-
- - Quantity - - - Please enter rate - - -
-
-
-
- - Rate Date - - DD/MM/YYYY - - - - Please enter rate date - - -
-
-
-
-
-
- - Primary currency - -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.scss b/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.ts b/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.ts deleted file mode 100644 index 88b4777..0000000 --- a/MyOffice.SPA/src/app/pages/settings/currency/rate.currency.component.ts +++ /dev/null @@ -1,99 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -// libs -import { MatDialogRef } from '@angular/material/dialog'; -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { CurrencyModel } from '../../../model/currency.model'; - -@Component({ - templateUrl: './rate.currency.component.html', - styleUrls: ['./rate.currency.component.scss'], -}) -export class SettingsRateCurrencyComponent { - public addForm!: FormGroup; - public error?: any; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public currency: CurrencyModel - ) { - } - - public ngOnInit(): void { - this.addForm = this.fb.group({ - id: [ - this.currency.id, - ], - code: [ - this.currency.code, - ], - symbol: [ - this.currency.symbol, - ], - name: [ - this.currency.name, - ], - shortName: [ - this.currency.shortName, - ], - quantity: [ - this.currency.quantity || 1, - [Validators.required], - ], - rate: [ - this.currency.rate || 1, - [Validators.required], - ], - rateDate: [ - this.currency.rateDate, - [Validators.required], - ], - isPrimary: [ - this.currency.isPrimary, - ], - }); - } - - closeDialog(): void { - this.dialogRef.close(); - } - - onSubmitClick() { - this.error = undefined; - if (this.addForm.valid) { - this.httpClient - .put(ApiRoutes.SettingsCurrency.replace(':id', this.addForm.value.id), this.addForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: (response) => { - this.httpClient - .post(ApiRoutes.SettingsCurrenciesRate.replace(':id', this.addForm.value.id), this.addForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe({ - next: (response) => { - this.dialogRef.close({ refresh: true }); - }, - error: (error) => { - this.error = error; - }, - }); - }, - error: (error) => { - this.error = error; - } - }); - } - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.html b/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.html deleted file mode 100644 index dafe1c2..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.html +++ /dev/null @@ -1,26 +0,0 @@ -
-
- - - - - - -
-
-
- - Name - - -
-
-
-
- Is internal motion -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.scss b/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.ts b/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.ts deleted file mode 100644 index 017b03e..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/edit.item.category.component.ts +++ /dev/null @@ -1,77 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { Inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -// libs -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { MatDialogRef } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { ItemCategoryModel } from '../../../model/item.category.model'; - -@Component({ - templateUrl: './edit.item.category.component.html', - styleUrls: ['./edit.item.category.component.scss'], -}) -export class SettingsItemCategoryEditComponent { - public editForm!: FormGroup; - public errorMessage?: string; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public category: ItemCategoryModel - ) { - } - - ngOnInit(): void { - this.editForm = this.fb.group({ - id: [ - this.category.id, - ], - name: [ - this.category.name, - [Validators.required], - ], - internal: [ - this.category?.internal ?? false, - ], - }); - } - - closeDialog(): void { - this.dialogRef.close(); - } - - onSubmitClick() { - if (this.editForm.valid) { - this.errorMessage = undefined; - if (!this.category.id) { - this.httpClient - .post(ApiRoutes.SettingsItemCategories, this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dialogRef.close({ category: response, refresh: true }); - }, error => { - this.errorMessage = error.detail; - }); - } else { - this.httpClient - .put(ApiRoutes.SettingsItemCategory.replace(':id', this.category.id!), this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dialogRef.close({ category: response, refresh: true }); - }, error => { - this.errorMessage = error.detail; - }); - } - } - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.html b/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.html deleted file mode 100644 index 910111a..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.html +++ /dev/null @@ -1,33 +0,0 @@ -
-
- - - - - - -
-
-
- - Name - - -
-
-
-
- - Category - - - {{category.name}} - - - -
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.scss b/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.ts b/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.ts deleted file mode 100644 index 42bbe1b..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/edit.item.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { Inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -// libs -import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { MatDialogRef } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { ItemCategoryModel } from '../../../model/item.category.model'; -import { ItemModel } from '../../../model/item.model'; -import { ItemService } from '../../../services/item.service'; - -@Component({ - templateUrl: './edit.item.component.html', - styleUrls: ['./edit.item.component.scss'], -}) -export class SettingsItemEditComponent { - public editForm!: FormGroup; - public errorMessage?: string; - public categories?: ItemCategoryModel[]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private dialogRef: MatDialogRef, - private itemService: ItemService, - @Inject(MAT_DIALOG_DATA) public item: ItemModel - ) { - } - - ngOnInit(): void { - this.editForm = this.fb.group({ - id: [ - this.item.id, - ], - name: [ - this.item.name, - [Validators.required], - ], - category: [ - this.item.categoryId, - [Validators.required], - ], - }); - - this.itemService - .getCategories() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => this.categories = x); - } - - closeDialog(): void { - this.dialogRef.close(); - } - - onSubmitClick() { - console.log(this.item); - console.log(this.editForm.value); - if (this.editForm.valid) { - this.errorMessage = undefined; - this.httpClient - .put(ApiRoutes.SettingsItem.replace(':id', this.item.id!), this.editForm.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(response => { - this.dialogRef.close({ motion: response, refresh: true }); - }, error => { - this.errorMessage = error.detail; - }); - } - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/item/item.category.component.html b/MyOffice.SPA/src/app/pages/settings/item/item.category.component.html deleted file mode 100644 index f56ed7c..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/item.category.component.html +++ /dev/null @@ -1,49 +0,0 @@ -
-
-
- - - -
-
-
- - - - - - - - -
- -
- -
- - - - - - - - -
{{item.name}} - done - - - -
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/item/item.category.component.scss b/MyOffice.SPA/src/app/pages/settings/item/item.category.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/settings/item/item.category.component.ts b/MyOffice.SPA/src/app/pages/settings/item/item.category.component.ts deleted file mode 100644 index fce7de7..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/item.category.component.ts +++ /dev/null @@ -1,97 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; - -// libs -import Swal from 'sweetalert2'; -import { MatDialog } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { ItemCategoryModel } from '../../../model/item.category.model'; -import { SettingsItemCategoryEditComponent } from './edit.item.category.component'; - -@Component({ - templateUrl: './item.category.component.html', - styleUrls: ['./item.category.component.scss'], -}) -export class SettingsItemCategoryComponent { - public categories?: ItemCategoryModel[]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private httpClient: HttpClient, - private dialogModel: MatDialog, - ) { - } - - ngOnInit(): void { - this.load(); - } - - private load() { - this.httpClient - .get(ApiRoutes.SettingsItemCategories) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.categories = data; - }); - } - - public add() { - this.dialogModel.open(SettingsItemCategoryEditComponent, { - width: '640px', - disableClose: true, - data: { }, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - this.load(); - } - }); - } - - public edit(category: ItemCategoryModel) { - this.dialogModel.open(SettingsItemCategoryEditComponent, { - width: '640px', - disableClose: true, - data: category, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - this.load(); - } - }); - } - - public remove(category: ItemCategoryModel) { - Swal.fire({ - title: 'Delete item category ' + category.name, - showCancelButton: true, - confirmButtonText: 'Delete', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - this.httpClient.delete(ApiRoutes.SettingsItemCategory.replace(':id', category.id!)) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - this.load(); - }); - } -} diff --git a/MyOffice.SPA/src/app/pages/settings/item/item.component.html b/MyOffice.SPA/src/app/pages/settings/item/item.component.html deleted file mode 100644 index c93753c..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/item.component.html +++ /dev/null @@ -1,77 +0,0 @@ -
-
-
- - - -
-
-
-
-
-
-
    - - Move to category - - - {{category.name}} - - - -
- -
    - - Code - - -
-
    - -
-
-
-
-
-
- - - - - Motions - - - - -
-
- -
- - - - - - - -
- - {{item.model.name}} - - - -
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/settings/item/item.component.scss b/MyOffice.SPA/src/app/pages/settings/item/item.component.scss deleted file mode 100644 index 72edd68..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/item.component.scss +++ /dev/null @@ -1,11 +0,0 @@ -.card-title { - display: flex; -} - -.left-content { - flex: 1; -} - -.right-content { - margin-left: auto; -} diff --git a/MyOffice.SPA/src/app/pages/settings/item/item.component.ts b/MyOffice.SPA/src/app/pages/settings/item/item.component.ts deleted file mode 100644 index f58012f..0000000 --- a/MyOffice.SPA/src/app/pages/settings/item/item.component.ts +++ /dev/null @@ -1,130 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; - -// libs -import Swal from 'sweetalert2'; -import { MatDialog } from '@angular/material/dialog'; - -// app -import { ApiRoutes } from '../../../api-routes'; -import { SettingsItemEditComponent } from './edit.item.component'; -import { ItemService } from '../../../services/item.service'; -import { ISelectableModel } from '../../../core/models/selectable.model'; -import { ItemModel } from '../../../model/item.model'; -import { ItemCategoryModel } from '../../../model/item.category.model'; - -@Component({ - templateUrl: './item.component.html', - styleUrls: ['./item.component.scss'], -}) -export class SettingsItemComponent { - public items?: ISelectableModel[]; - public categories?: ItemCategoryModel[]; - public selectedCategory?: ItemCategoryModel; - public selectedCount: number = 0; - public category?: ItemCategoryModel; - public categoryAddShow: boolean = false; - public categoryAddName?: string; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private dialogModel: MatDialog, - private httpClient: HttpClient, - private itemService: ItemService, - ) { - } - - ngOnInit(): void { - this.load(); - } - - private load(categoryId?: string) { - this.itemService.getCategories() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.categories = data; - var selected = data[0]; - if (categoryId) { - var categories = this.categories.filter(x => x.id === categoryId); - selected = categories.length === 0 - ? selected - : categories[0]; - } - - this.selectCategory(selected); - }); - } - - public selectCategory(category: ItemCategoryModel) { - this.selectedCategory = category; - this.itemService.getItems(category.id) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.items = data.map>(x => { return { model: x, selected: false } }); - }); - } - - public edit(item: ItemModel) { - this.dialogModel.open(SettingsItemEditComponent, { - width: '640px', - disableClose: true, - data: item, - }).afterClosed() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - if (x && x.refresh) { - console.log(x.motion.categoryId); - this.load(x.motion.categoryId); - } - }); - } - - public remove(category: ItemModel) { - Swal.fire({ - title: 'Delete item from ' + category.name, - showCancelButton: true, - confirmButtonText: 'Delete', - showLoaderOnConfirm: true, - preConfirm: (name) => { - return new Promise((resolve, reject) => { - this.httpClient.delete(ApiRoutes.SettingsItemCategory.replace(':id', category.id!)) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - resolve(data); - }, error => { - Swal.showValidationMessage(error.detail); - reject(); - }); - - }).catch(x => { - return false; - }); - }, - allowOutsideClick: () => !Swal.isLoading(), - }).then((result) => { - this.load(); - }); - } - - onCheckboxChange(item: ISelectableModel) { - this.selectedCount += item.selected ? 1 : -1; - } - - onCategoryChange(item: any) { - var data = { - category: item.value, - items: this.items!.filter(x => x.selected).map(x => x.model.id) - } - this.httpClient.post(ApiRoutes.SettingsItems, data) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.category = undefined; - this.selectedCount = 0; - this.load(); - }, error => { - }); - } -} diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.html b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.html deleted file mode 100644 index e418b7c..0000000 --- a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.html +++ /dev/null @@ -1,129 +0,0 @@ -
-
-
- - - -
-
-
-
-
-

User Profile

-
-
-
-
-
- - Email - - email - -
-
-
-
- - First name - - face - - Only characters or numbers allowed - - -
-
- - Last name - - face - - Only characters or numbers allowed - - -
-
-
-
- - Full name - - face - - Full name is empty - - -
-
-
-
- - Currency - - - ({{item.symbol}}) {{item.name}} - - - - -
-
-
-
- - -
-
-
-
-
-
-
-
-
-

- Providers -

-
-
-
-
- link - email - mark_email_read -
-
- {{provider.name}} -
-
- - - - - - -
-
-
-
-
-
-
-
diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.scss b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.spec.ts b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.spec.ts deleted file mode 100644 index bc71b08..0000000 --- a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { UserProfileComponent } from './user-profile.component'; - -describe('UserProfileComponent', - () => { - let component: UserProfileComponent; - let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UserProfileComponent], - }).compileComponents(); - }) - ); - beforeEach(() => { - fixture = TestBed.createComponent(UserProfileComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.ts b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.ts deleted file mode 100644 index 3fb03f0..0000000 --- a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.ts +++ /dev/null @@ -1,178 +0,0 @@ -// angular -import { Component, DestroyRef, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HttpClient } from '@angular/common/http'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -// libs -import Swal from 'sweetalert2'; - -// app -import { ApiRoutes } from '../../api-routes'; -import { ExternalLoginConfig } from '../../config.external-login'; -import { AuthService } from '../../core/service/auth.service'; - -@Component({ - selector: 'app-blank', - templateUrl: './user-profile.component.html', - styleUrls: ['./user-profile.component.scss'], -}) -export class UserProfileComponent { - form: FormGroup; - providers?: ProviderModel[]; - profile?: ProfileModel; - currencies?: CurrencyModel[]; - - private readonly destroyRef = inject(DestroyRef); - - constructor( - private fb: FormBuilder, - private httpClient: HttpClient, - private authService: AuthService, - ) { - this.form = this.fb.group({ - firstName: ['', [Validators.pattern('[a-zA-Z0-9]+')]], - lastName: ['', [Validators.pattern('[a-zA-Z0-9]+')]], - fullName: ['', [Validators.pattern('[a-zA-Z0-9 ]+')]], - email: [{ value: '', disabled: true }, []], - currency: [{ value: '' }, []], - }); - - this.providers = ExternalLoginConfig - .getConfiguredProviders() - .map(x => { - provider: x.provider, - name: x.name, - isConnected: false, - isEmailConfirmed: false - }); - } - - ngOnInit(): void { - this.load(); - } - - private updateForm(data: ProfileModel) { - this.form.patchValue(data); - } - - private load() { - this.loadProfile(); - } - - private loadProfile() { - this.httpClient - .get(ApiRoutes.UserProfile) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.profile = data; - this.loadCurrencies(); - - this.updateForm(data); - - this.providers?.map((provider) => { - var attached = data.providers?.find(x => x.provider === provider.provider); - provider.isConnected = false; - provider.isEmailConfirmed = false; - if (attached) { - provider.isConnected = true; - provider.isEmailConfirmed = attached.isEmailConfirmed; - } - }); - }); - } - - private loadCurrencies() { - this.httpClient - .get(ApiRoutes.GeneralCurrencies) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.currencies = data; - }); - } - - onSubmit() { - if (this.form.invalid) { - return; - } - - this.httpClient.post(ApiRoutes.UserProfile, this.form.value) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(data => { - this.updateForm(data); - console.log(this.form); - }); - } - - connect(provider: ProviderModel) { - provider.error = undefined; - provider.isLoading = true; - - if (provider.provider === ExternalLoginConfig.GOOGLE) { - this.authService.attachGoogle() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(r => { - this.load(); - provider.isLoading = false; - }); - } - if (provider.provider === ExternalLoginConfig.AUTH0) { - this.authService.attachAuth0() - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(resp => { - provider.error = ''; - if (!resp.success) { - provider.error = resp.data || 'Connect failed'; - } - this.load(); - provider.isLoading = false; - }); - } - } - - disconnect(provider: string) { - Swal.fire({ - title: 'Are you sure to disconnect ' + provider + ' ?', - text: 'Some providers can be connected only with login!', - icon: 'warning', - showCancelButton: true, - confirmButtonColor: '#3085d6', - cancelButtonColor: '#d33', - confirmButtonText: 'Yes, disconnect it!', - }).then((result) => { - if (result.value) { - this.authService.deattach(provider) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(x => { - this.load(); - }); - } - }); - } -} - -interface ProviderModel { - provider: string; - name: string; - isConnected: boolean; - isEmailConfirmed: boolean; - error?: string; - isLoading: boolean; -} - -interface ProfileModel { - firstName?: string, - lastName?: string, - fullName?: string, - currency?: string, - isEmailConfirmed?: boolean, - providers?: ProviderModel[], -} - -interface CurrencyModel { - id?: string, - name?: string, - symbol?: string, - rate?: number, - rateDate?: string, -} diff --git a/MyOffice.SPA/src/app/services/account.category.service.ts b/MyOffice.SPA/src/app/services/account.category.service.ts deleted file mode 100644 index 26a3ea7..0000000 --- a/MyOffice.SPA/src/app/services/account.category.service.ts +++ /dev/null @@ -1,29 +0,0 @@ -// angular -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -// libs -import { Observable } from 'rxjs'; - -// app -import { ApiRoutes } from '../api-routes'; -import { AccountCategoryModel } from '../model/account.category.model'; - -@Injectable() -export class AccountCategoryService { - - constructor( - private httpClient: HttpClient, - ) { - } - - public getCategories(): Observable { - return this.httpClient - .get(ApiRoutes.SettingsAccountCategories); - } - - public getCategory(id: string): Observable { - return this.httpClient - .get(ApiRoutes.SettingsAccountCategory.replace(':id', id)); - } -} diff --git a/MyOffice.SPA/src/app/services/account.service.ts b/MyOffice.SPA/src/app/services/account.service.ts deleted file mode 100644 index 06d4216..0000000 --- a/MyOffice.SPA/src/app/services/account.service.ts +++ /dev/null @@ -1,28 +0,0 @@ -// angular -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -// libs -import { Observable } from 'rxjs'; - -// app -import { ApiRoutes } from '../api-routes'; -import { AccountCategoryModel } from '../model/account.category.model'; - -@Injectable() -export class AccountService { - private types = new Map(); - - constructor( - private httpClient: HttpClient, - ) { - this.types.set('balance', 'Account with balance'); - this.types.set('credit', 'Account with loan funds'); - this.types.set('external', 'External account'); - this.types.set('other', 'Other account'); - } - - public getTypes(): Map { - return this.types; - } -} diff --git a/MyOffice.SPA/src/app/services/currency.service.ts b/MyOffice.SPA/src/app/services/currency.service.ts deleted file mode 100644 index 9733638..0000000 --- a/MyOffice.SPA/src/app/services/currency.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -// angular -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -// libs -import { Observable } from 'rxjs'; - -// app -import { ApiRoutes } from '../api-routes'; -import { CurrencyModel } from '../model/currency.model'; - -@Injectable() -export class CurrencyService { - - constructor( - private httpClient: HttpClient, - ) { - } - - public getCurrencies(): Observable { - return this.httpClient - .get(ApiRoutes.SettingsCurrencies); - } -} diff --git a/MyOffice.SPA/src/app/services/item.service.ts b/MyOffice.SPA/src/app/services/item.service.ts deleted file mode 100644 index 32f804f..0000000 --- a/MyOffice.SPA/src/app/services/item.service.ts +++ /dev/null @@ -1,34 +0,0 @@ -// angular -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -// libs -import { Observable } from 'rxjs'; - -// app -import { ApiRoutes } from '../api-routes'; -import { ItemModel } from '../model/item.model'; -import { ItemCategoryModel } from '../model/item.category.model'; - -@Injectable() -export class ItemService { - - constructor( - private httpClient: HttpClient, - ) { - } - - public getCategories(category?: string): Observable { - return this.httpClient - .get(ApiRoutes.SettingsItemCategories); - } - - public getItems(categoryId?: string): Observable { - var url = categoryId - ? ApiRoutes.SettingsItems + "?category=" + categoryId - : ApiRoutes.SettingsItems; - - return this.httpClient - .get(url); - } -} diff --git a/MyOffice.SPA/src/app/shared/TableElement.ts b/MyOffice.SPA/src/app/shared/TableElement.ts deleted file mode 100644 index ad7a93a..0000000 --- a/MyOffice.SPA/src/app/shared/TableElement.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface TableElement { - [key: string]: string | number; -} diff --git a/MyOffice.SPA/src/app/shared/UnsubscribeOnDestroyAdapter.ts b/MyOffice.SPA/src/app/shared/UnsubscribeOnDestroyAdapter.ts deleted file mode 100644 index 8fcd939..0000000 --- a/MyOffice.SPA/src/app/shared/UnsubscribeOnDestroyAdapter.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Injectable, OnDestroy } from '@angular/core'; -import { SubSink } from './sub-sink'; - -/** - * A class that automatically unsubscribes all observables when the object gets destroyed - */ -@Injectable() -export class UnsubscribeOnDestroyAdapter implements OnDestroy { - /** - * The subscription sink object that stores all subscriptions - */ - subs = new SubSink(); - - /** - * The lifecycle hook that unsubscribes all subscriptions when the component / object gets destroyed - */ - ngOnDestroy(): void { - this.subs.unsubscribe(); - } -} diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.html b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.html deleted file mode 100644 index 805084e..0000000 --- a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.html +++ /dev/null @@ -1,20 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.scss b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts deleted file mode 100644 index e8f9133..0000000 --- a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { BreadcrumbComponent } from './breadcrumb.component'; - -describe('BreadcrumbComponent', - () => { - let component: BreadcrumbComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [BreadcrumbComponent] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(BreadcrumbComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.ts b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.ts deleted file mode 100644 index 5e67931..0000000 --- a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'app-breadcrumb', - templateUrl: './breadcrumb.component.html', - styleUrls: ['./breadcrumb.component.scss'], -}) -export class BreadcrumbComponent { - @Input() - title!: string; - @Input() - items!: string[]; - @Input() - active_item!: string; - - constructor() { - //constructor - } -} diff --git a/MyOffice.SPA/src/app/shared/components/components.module.ts b/MyOffice.SPA/src/app/shared/components/components.module.ts deleted file mode 100644 index 69a47bc..0000000 --- a/MyOffice.SPA/src/app/shared/components/components.module.ts +++ /dev/null @@ -1,33 +0,0 @@ -// angular -import { NgModule } from '@angular/core'; - -// libs -import { TranslateModule } from '@ngx-translate/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { FileUploadComponent } from './file-upload/file-upload.component'; -import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component'; -import { SharedModule } from '../shared.module'; -import { DatePeriodComponent } from './date-period/date-period.component'; -import { DialogChromeComponent } from './dialog-chrome/dialog-chrome.component'; - -@NgModule({ - declarations: [ - FileUploadComponent, - BreadcrumbComponent, - DatePeriodComponent, - DialogChromeComponent, - ], - imports: [ - SharedModule, - TranslateModule, - MatDialogModule, - ], - exports: [ - FileUploadComponent, - BreadcrumbComponent, - DatePeriodComponent, - DialogChromeComponent, - ], -}) -export class ComponentsModule { -} diff --git a/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.css b/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.css deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.html b/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.html deleted file mode 100644 index d4a9468..0000000 --- a/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.html +++ /dev/null @@ -1,28 +0,0 @@ -
-
-
- - From - - YYYY/MM/DD - - - - Please enter rate date - - -
-
- - To - - YYYY/MM/DD - - - - Please enter rate date - - -
-
-
diff --git a/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.spec.ts b/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.spec.ts deleted file mode 100644 index 81cf7ca..0000000 --- a/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { DatePeriodComponent } from './date-period.component'; - -describe('DatePeriodComponent', () => { - let component: DatePeriodComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ DatePeriodComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(DatePeriodComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.ts b/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.ts deleted file mode 100644 index 0411193..0000000 --- a/MyOffice.SPA/src/app/shared/components/date-period/date-period.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -// app -import { Component } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { Input } from '@angular/core'; -import { Output } from '@angular/core'; -import { EventEmitter } from '@angular/core'; - -// libs -import moment from 'moment'; - - -type DatePeriodForm = { - dateFrom: FormControl; - dateTo: FormControl; -}; - -@Component({ - selector: 'app-date-period', - templateUrl: './date-period.component.html', - styleUrls: ['./date-period.component.css'] -}) -export class DatePeriodComponent { - - @Input('from') dateFrom!: Date; - @Input('to') dateTo!: Date; - - @Output() onChange: EventEmitter = new EventEmitter(); - - form!: FormGroup; - - constructor( - private fb: FormBuilder - ) { - - } - - ngOnInit() { - this.form = this.fb.group({ - dateFrom: [ - this.dateFrom, - [Validators.required], - ], - dateTo: [ - this.dateTo, - [Validators.required], - ], - }); - } - - onSubmitClick() { - } - - onInputChange() { - this.onChange.emit([this.form.value.dateFrom!, this.form.value.dateTo!]); - } -} diff --git a/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.html b/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.html deleted file mode 100644 index a34b6d6..0000000 --- a/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.html +++ /dev/null @@ -1,39 +0,0 @@ -
-

{{ title }}

-
- -
-
- -
- {{ errorMessage }} - -

{{ error.title }}

-
    -
  • {{ item.value }}
  • -
-
-
- -
- - - -
-
- {{ errorMessage }} - -

{{ error.title }}

-
    -
  • {{ item.value }}
  • -
-
-
-
-
-
- -
-
-
-
diff --git a/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.scss b/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.scss deleted file mode 100644 index 19ab249..0000000 --- a/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -.dialog-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: 16px; -} - -.dialog-header [mat-dialog-title] { - flex: 1; - min-width: 0; -} - -.dialog-header-actions { - display: flex; - align-items: center; - flex-shrink: 0; - margin-top: 24px; - margin-right: 24px; - gap: 8px; -} - -.dialog-header-error { - margin: 0 24px 8px; -} diff --git a/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.ts b/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.ts deleted file mode 100644 index fb75106..0000000 --- a/MyOffice.SPA/src/app/shared/components/dialog-chrome/dialog-chrome.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Component, Input, TemplateRef } from '@angular/core'; -import { UI_CONFIG } from '../../../config/ui.config'; - -@Component({ - selector: 'app-dialog-chrome', - templateUrl: './dialog-chrome.component.html', - styleUrls: ['./dialog-chrome.component.scss'], -}) -export class DialogChromeComponent { - @Input({ required: true }) title!: string; - @Input({ required: true }) actions!: TemplateRef; - @Input() errorMessage?: string | null; - /** Structured validation error (e.g. currency rate dialog). */ - @Input() error?: { title?: string; errors?: Record } | null; - - readonly modalButtonsTop = UI_CONFIG.modal_buttons === 'top'; - - get hasError(): boolean { - return !!(this.errorMessage || this.error?.title || this.error?.errors); - } -} diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.html b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.html deleted file mode 100644 index 1e97cd1..0000000 --- a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.scss b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.spec.ts b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.spec.ts deleted file mode 100644 index c1e8bbf..0000000 --- a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { FeatherIconsComponent } from './feather-icons.component'; - -describe('FeatherIconsComponent', - () => { - let component: FeatherIconsComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [FeatherIconsComponent] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(FeatherIconsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.ts b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.ts deleted file mode 100644 index 5f97c19..0000000 --- a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'app-feather-icons', - templateUrl: './feather-icons.component.html', - styleUrls: ['./feather-icons.component.scss'], -}) -export class FeatherIconsComponent { - @Input() - icon?: string; - @Input() - class?: string; - - constructor() { - // constructor - } -} diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.module.ts b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.module.ts deleted file mode 100644 index 0b3bbb2..0000000 --- a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FeatherIconsComponent } from './feather-icons.component'; - -import { FeatherModule } from 'angular-feather'; -import { allIcons } from 'angular-feather/icons'; - -@NgModule({ - imports: [CommonModule, FeatherModule.pick(allIcons)], - exports: [FeatherIconsComponent, FeatherModule], - declarations: [FeatherIconsComponent], -}) -export class FeatherIconsModule { -} diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.html b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.html deleted file mode 100644 index 8fb6747..0000000 --- a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.html +++ /dev/null @@ -1,5 +0,0 @@ -
- - {{file ? file.name : ' or drag and drop file here' }} - -
diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.scss b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.scss deleted file mode 100644 index d3cb0d4..0000000 --- a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.scss +++ /dev/null @@ -1,27 +0,0 @@ -.file-drop-area { - border: 1px dashed #7c7db3; - border-radius: 3px; - position: relative; - max-width: 100%; - margin-top: 5px; - padding: 26px 20px 30px; - transition: 0.2s; -} - -.file-input { - position: absolute; - left: 0; - top: 0; - height: 100%; - width: 100%; - cursor: pointer; - opacity: 0; -} - -.file-msg { - display: inline-block; - margin-left: 5px; - font-size: 12px; - font-weight: 500; - color: #5b5bff; -} diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.spec.ts b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.spec.ts deleted file mode 100644 index 622f59d..0000000 --- a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { FileUploadComponent } from './file-upload.component'; - -describe('FileUploadComponent', - () => { - let component: FileUploadComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [FileUploadComponent] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(FileUploadComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', - () => { - expect(component).toBeTruthy(); - }); - }); diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.ts b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.ts deleted file mode 100644 index 9dfd503..0000000 --- a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/ban-types */ -import { Component, ElementRef, HostListener, Input } from '@angular/core'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; - -@Component({ - selector: 'app-file-upload', - templateUrl: './file-upload.component.html', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: FileUploadComponent, - multi: true, - }, - ], - styleUrls: ['./file-upload.component.scss'], -}) -export class FileUploadComponent implements ControlValueAccessor { - onChange!: Function; - file: File | null = null; - - @HostListener('change', ['$event.target.files']) - emitFiles(event: FileList) { - const file = event && event.item(0); - this.onChange(file); - this.file = file; - } - - constructor(private host: ElementRef) {} - - writeValue(value: null) { - // clear file input - this.host.nativeElement.value = ''; - this.file = null; - } - - registerOnChange(fn: Function) { - this.onChange = fn; - } - - registerOnTouched(fn: Function) { - // add code here - } -} diff --git a/MyOffice.SPA/src/app/shared/feather-icons.module.ts b/MyOffice.SPA/src/app/shared/feather-icons.module.ts deleted file mode 100644 index d3e4d0c..0000000 --- a/MyOffice.SPA/src/app/shared/feather-icons.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { FeatherModule } from 'angular-feather'; -import { allIcons } from 'angular-feather/icons'; - -// Select some icons (use an object, not an array) - -@NgModule({ - imports: [FeatherModule.pick(allIcons)], - exports: [FeatherModule], -}) -export class FeatherIconsModule { -} diff --git a/MyOffice.SPA/src/app/shared/material.module.ts b/MyOffice.SPA/src/app/shared/material.module.ts deleted file mode 100644 index dd3372f..0000000 --- a/MyOffice.SPA/src/app/shared/material.module.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { NgModule } from '@angular/core'; -import { MatIconModule } from '@angular/material/icon'; -import { MatButtonModule } from '@angular/material/button'; -import { MatDatepickerModule } from '@angular/material/datepicker'; -import { MatNativeDateModule } from '@angular/material/core'; -import { NgxMaskDirective, NgxMaskPipe, provideNgxMask } from 'ngx-mask'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatListModule } from '@angular/material/list'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatSlideToggleModule } from '@angular/material/slide-toggle'; - -const materialModules = [ - MatButtonModule, - MatInputModule, - MatListModule, - MatIconModule, - MatTooltipModule, - MatDatepickerModule, - MatNativeDateModule, - NgxMaskDirective, - NgxMaskPipe, - MatButtonToggleModule, - MatFormFieldModule, - MatMenuModule, - MatSlideToggleModule, -]; - -@NgModule({ - declarations: [], - imports: [...materialModules], - exports: [...materialModules], - providers: [provideNgxMask()], -}) -export class MaterialModule { -} diff --git a/MyOffice.SPA/src/app/shared/shared.module.ts b/MyOffice.SPA/src/app/shared/shared.module.ts deleted file mode 100644 index 4f1da2e..0000000 --- a/MyOffice.SPA/src/app/shared/shared.module.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; - -import { MaterialModule } from './material.module'; -import { FeatherIconsModule } from './components/feather-icons/feather-icons.module'; - -@NgModule({ - declarations: [], - imports: [CommonModule, FormsModule, ReactiveFormsModule, RouterModule], - exports: [ - CommonModule, - FormsModule, - ReactiveFormsModule, - RouterModule, - MaterialModule, - FeatherIconsModule, - ], -}) -export class SharedModule { -} diff --git a/MyOffice.SPA/src/app/shared/sub-sink.ts b/MyOffice.SPA/src/app/shared/sub-sink.ts deleted file mode 100644 index afb3d23..0000000 --- a/MyOffice.SPA/src/app/shared/sub-sink.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { SubscriptionLike } from 'rxjs'; - -// TODO: SubSink -> SubSync -/** - * Subscription sink that holds Observable subscriptions - * until you call unsubscribe on it in ngOnDestroy. - */ -export class SubSink { - protected _subs: SubscriptionLike[] = []; - - /** - * Subscription sink that holds Observable subscriptions - * until you call unsubscribe on it in ngOnDestroy. - * - * @example - * In Angular: - * ``` - * private subs = new SubSink(); - * ... - * this.subs.sink = observable$.subscribe( - * this.subs.add(observable$.subscribe(...)); - * ... - * ngOnDestroy() { - * this.subs.unsubscribe(); - * } - * ``` - */ - constructor() { - // constructor - } - - /** - * Add subscriptions to the tracked subscriptions - * @example - * this.subs.add(observable$.subscribe(...)); - */ - add(...subscriptions: SubscriptionLike[]) { - this._subs = this._subs.concat(subscriptions); - } - - /** - * Assign subscription to this sink to add it to the tracked subscriptions - * @example - * this.subs.sink = observable$.subscribe(...); - */ - set sink(subscription: SubscriptionLike) { - this._subs.push(subscription); - } - - /** - * Unsubscribe to all subscriptions in ngOnDestroy() - * @example - * ngOnDestroy() { - * this.subs.unsubscribe(); - * } - */ - unsubscribe() { - this._subs.forEach((sub) => sub && sub.unsubscribe()); - this._subs = []; - } -} diff --git a/MyOffice.SPA/src/app/shared/tableExportUtil.ts b/MyOffice.SPA/src/app/shared/tableExportUtil.ts deleted file mode 100644 index e22b342..0000000 --- a/MyOffice.SPA/src/app/shared/tableExportUtil.ts +++ /dev/null @@ -1,42 +0,0 @@ -import * as XLSX from 'xlsx'; -import { TableElement } from './TableElement'; - -const getFileName = (name: string) => { - const timeSpan = new Date().toISOString(); - const sheetName = name || 'ExportResult'; - const fileName = `${sheetName}-${timeSpan}`; - return { - sheetName, - fileName, - }; -}; - -export class TableExportUtil { - static exportToExcel(arr: Partial[], name: string) { - const { sheetName, fileName } = getFileName(name); - - const wb = XLSX.utils.book_new(); - const ws = XLSX.utils.json_to_sheet(arr); - XLSX.utils.book_append_sheet(wb, ws, sheetName); - XLSX.writeFile(wb, `${fileName}.xlsx`); - } - - // static exportToPDF(exportData: any[]) { - // const doc = new jsPDF(); - // const dataValue: any = Object.keys(exportData).map(function ( - // personNamedIndex: any - // ) { - // return Object.values(exportData[personNamedIndex]); - // }); - // const keys: any = Object.keys(exportData[0]); - - // autoTable(doc, { - // head: [keys], - // body: dataValue, - // }); - - // const { fileName } = getFileName('pdf'); - - // doc.save(`${fileName}.pdf`); - // } -} diff --git a/MyOffice.SPA/src/assets/.gitkeep b/MyOffice.SPA/src/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.eot b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.eot deleted file mode 100644 index f5c1fd4..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.eot and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.svg b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.svg deleted file mode 100644 index e29de15..0000000 --- a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.svg +++ /dev/null @@ -1,1181 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.ttf b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.ttf deleted file mode 100644 index 218ff47..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.ttf and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff deleted file mode 100644 index d24c3a9..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff2 b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff2 deleted file mode 100644 index 372c314..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff2 and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.eot b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.eot deleted file mode 100644 index 5999593..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.eot and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.svg b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.svg deleted file mode 100644 index 0085843..0000000 --- a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.svg +++ /dev/null @@ -1,467 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.ttf b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.ttf deleted file mode 100644 index 4adbd66..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.ttf and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff deleted file mode 100644 index 94d86d1..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff2 b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff2 deleted file mode 100644 index cff972c..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff2 and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.eot b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.eot deleted file mode 100644 index 9def162..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.eot and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.svg b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.svg deleted file mode 100644 index a229433..0000000 --- a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.svg +++ /dev/null @@ -1,2567 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.ttf b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.ttf deleted file mode 100644 index c681849..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.ttf and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff deleted file mode 100644 index 891a580..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff2 b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff2 deleted file mode 100644 index 00d15c4..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff2 and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.eot b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.eot deleted file mode 100644 index ff32634..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.eot and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.svg b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.svg deleted file mode 100644 index c3d485c..0000000 --- a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.svg +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.ttf b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.ttf deleted file mode 100644 index 5f2caab..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.ttf and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff deleted file mode 100644 index cfb9c3d..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff and /dev/null differ diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff2 b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff2 deleted file mode 100644 index 19f70c6..0000000 Binary files a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff2 and /dev/null differ diff --git a/MyOffice.SPA/src/assets/i18n/de.json b/MyOffice.SPA/src/assets/i18n/de.json deleted file mode 100644 index 6b93e47..0000000 --- a/MyOffice.SPA/src/assets/i18n/de.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "HEADER": { - "SEARCH": { - "TEXT": "Suche.." - } - }, - "MENUITEMS": { - "USER": { - "POST": "Manager" - }, - "MAIN": { - "TEXT": "Main" - }, - "DASHBOARD": { - "TEXT": "Zuhause", - "LIST": { - "DASHBOARD": "Dashboard" - } - }, - "ADVANCE-TABLE": { - "TEXT": "Vorab-Tabelle" - }, - "APPS": { - "TEXT": "Apps" - }, - "CALENDAR": { - "TEXT": "Kalender" - }, - "TASK": { - "TEXT": "Aufgabe" - }, - "CONTACTS": { - "TEXT": "Kontakte" - }, - "EMAIL": { - "TEXT": "Email", - "LIST": { - "INBOX": "Posteingang", - "COMPOSE": "Komponieren", - "READ": "E-Mail lesen" - } - }, - "MORE-APPS": { - "TEXT": "Mehr Apps", - "LIST": { - "CHAT": "Plaudern", - "SUPPORT": "Unterstützung", - "DRAG-DROP": "Ziehen und loslassen", - "CONTACT-GRID": "Kontakt Grid" - } - }, - "COMPONENTS": { - "TEXT": "Komponenten" - }, - "WIDGETS": { - "TEXT": "Widgets", - "LIST": { - "CHART-WIDGET": "Diagramm-Widget", - "DATA-WIDGET": "Daten-Widget" - } - }, - "FORMS": { - "TEXT": "Formen", - "LIST": { - "CONTROLS": "Form Controls", - "ADVANCE": "Advance Control", - "EXAMPLE": "Vorabkontrolle", - "VALIDATION": "Formularvalidierung", - "WIZARD": "Magier", - "EDITORS": "Redakteurinnen" - } - }, - "TABLES": { - "TEXT": "Tabellen", - "LIST": { - "BASIC": "Tablas básicas", - "MATERIAL": "Materialtabellen", - "NGX-DATATABLE": "NGX-datierbar" - } - } - } -} diff --git a/MyOffice.SPA/src/assets/i18n/en.json b/MyOffice.SPA/src/assets/i18n/en.json deleted file mode 100644 index 2f87228..0000000 --- a/MyOffice.SPA/src/assets/i18n/en.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "HEADER": { - "SEARCH": { - "TEXT": "Search.." - } - }, - "MENUITEMS": { - "USER": { - "POST": "Manager" - }, - "MAIN": { - "TEXT": "Main" - }, - "DASHBOARD": { - "TEXT": "Dashboard", - "LIST": { - "DASHBOARD": "Rests", - "INCOME": "Incomes", - "OUTCOME": "Outcomes" - } - }, - "ACCOUNTS": { - "TEXT": "Accounts" - }, - "SETTINGS": { - "TEXT": "Settings", - "LIST": { - "CURRENCIES": "Currencies", - "ACCOUNTCATEGORIES": "Account categories", - "ACCOUNTS": "Accounts", - "ITEMCATEGORIES": "Item categories", - "ITEMS": "Items" - } - }, - - "ADVANCE-TABLE": { - "TEXT": "Advance Table" - }, - "APPS": { - "TEXT": "Apps" - }, - "CALENDAR": { - "TEXT": "Calendar" - }, - "TASK": { - "TEXT": "Task" - }, - "CONTACTS": { - "TEXT": "Contacts" - }, - "EMAIL": { - "TEXT": "Email", - "LIST": { - "INBOX": "Inbox", - "COMPOSE": "Compose", - "READ": "Read Email" - } - }, - "MORE-APPS": { - "TEXT": "More Apps", - "LIST": { - "CHAT": "Chat", - "SUPPORT": "Support", - "DRAG-DROP": "Drag & Drop", - "CONTACT-GRID": "Contact Grid" - } - }, - "COMPONENTS": { - "TEXT": "Components" - }, - "WIDGETS": { - "TEXT": "Widgets", - "LIST": { - "CHART-WIDGET": "Chart-Widget", - "DATA-WIDGET": "Data-Widget" - } - }, - "FORMS": { - "TEXT": "Forms", - "LIST": { - "CONTROLS": "Form Controls", - "ADVANCE": "Advance Control", - "EXAMPLE": "Form Examples", - "VALIDATION": "Form Validation", - "WIZARD": "Wizard", - "EDITORS": "Editors" - } - }, - "TABLES": { - "TEXT": "Tables", - "LIST": { - "BASIC": "Basic Tables", - "MATERIAL": "Material Tables", - "NGX-DATATABLE": "NGX-Datatable" - } - } - }, - - "BALANCE": "Balance", - "DEBIT.BALANCE": "Debit balance", - "CREDIT.BALANCE": "Credit balance", - "CURRENT.BALANCE": "Current balance", - "HOME": "Home", - "OTHER": "Other", - "TOTAL": "Total" -} diff --git a/MyOffice.SPA/src/assets/i18n/es.json b/MyOffice.SPA/src/assets/i18n/es.json deleted file mode 100644 index 58966ef..0000000 --- a/MyOffice.SPA/src/assets/i18n/es.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "HEADER": { - "SEARCH": { - "TEXT": "Buscar.." - } - }, - "MENUITEMS": { - "USER": { - "POST": "Gerente" - }, - "MAIN": { - "TEXT": "Principal" - }, - "DASHBOARD": { - "TEXT": "Casa", - "LIST": { - "DASHBOARD": "Tablero" - } - }, - "ADVANCE-TABLE": { - "TEXT": "Tabla de avance" - }, - "APPS": { - "TEXT": "Aplicaciones" - }, - "CALENDAR": { - "TEXT": "Calendario" - }, - "TASK": { - "TEXT": "Tarea" - }, - "CONTACTS": { - "TEXT": "Contactos" - }, - "EMAIL": { - "TEXT": "Email", - "LIST": { - "INBOX": "Bandeja de entrada", - "COMPOSE": "Componer", - "READ": "Leer el correo electrónico" - } - }, - "MORE-APPS": { - "TEXT": "Más aplicaciones", - "LIST": { - "CHAT": "Charla", - "SUPPORT": "Apoyo", - "DRAG-DROP": "Arrastrar y soltar", - "CONTACT-GRID": "Cuadrícula de contacto" - } - }, - "COMPONENTS": { - "TEXT": "Componentes" - }, - "WIDGETS": { - "TEXT": "Widgets", - "LIST": { - "CHART-WIDGET": "Widget de gráfico", - "DATA-WIDGET": "Widget de datos" - } - }, - "FORMS": { - "TEXT": "Formularios", - "LIST": { - "CONTROLS": "Controles de formulario", - "ADVANCE": "Control avanzado", - "EXAMPLE": "Ejemplos de formularios", - "VALIDATION": "Validación de formulario", - "WIZARD": "Mago", - "EDITORS": "Editoras" - } - }, - "TABLES": { - "TEXT": "Tabellen", - "LIST": { - "BASIC": "Tablas básicas", - "MATERIAL": "Tablas de materiales", - "NGX-DATATABLE": "NGX-Datatable" - } - } - } -} diff --git a/MyOffice.SPA/src/assets/i18n/ua.json b/MyOffice.SPA/src/assets/i18n/ua.json deleted file mode 100644 index 38167be..0000000 --- a/MyOffice.SPA/src/assets/i18n/ua.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "HEADER": { - "SEARCH": { - "TEXT": "Шукати.." - } - }, - "MENUITEMS": { - "USER": { - "POST": "Manager" - }, - "MAIN": { - "TEXT": "Головне" - }, - "DASHBOARD": { - "TEXT": "Панелі", - "LIST": { - "DASHBOARD": "Залишки", - "INCOME": "Надходження", - "OUTCOME": "Витрати" - } - }, - "ACCOUNTS": { - "TEXT": "Рахунки" - }, - "SETTINGS": { - "TEXT": "Налаштування", - "LIST": { - "CURRENCIES": "Валюти", - "ACCOUNTCATEGORIES": "Категорії рахунків", - "ACCOUNTS": "Рахунки", - "ITEMCATEGORIES": "Категорії статей", - "ITEMS": "Статті" - } - }, - - "ADVANCE-TABLE": { - "TEXT": "Advance Table" - }, - "APPS": { - "TEXT": "Apps" - }, - "CALENDAR": { - "TEXT": "Calendar" - }, - "TASK": { - "TEXT": "Task" - }, - "CONTACTS": { - "TEXT": "Contacts" - }, - "EMAIL": { - "TEXT": "Email", - "LIST": { - "INBOX": "Inbox", - "COMPOSE": "Compose", - "READ": "Read Email" - } - }, - "MORE-APPS": { - "TEXT": "More Apps", - "LIST": { - "CHAT": "Chat", - "SUPPORT": "Support", - "DRAG-DROP": "Drag & Drop", - "CONTACT-GRID": "Contact Grid" - } - }, - "COMPONENTS": { - "TEXT": "Components" - }, - "WIDGETS": { - "TEXT": "Widgets", - "LIST": { - "CHART-WIDGET": "Chart-Widget", - "DATA-WIDGET": "Data-Widget" - } - }, - "FORMS": { - "TEXT": "Forms", - "LIST": { - "CONTROLS": "Form Controls", - "ADVANCE": "Advance Control", - "EXAMPLE": "Form Examples", - "VALIDATION": "Form Validation", - "WIZARD": "Wizard", - "EDITORS": "Editors" - } - }, - "TABLES": { - "TEXT": "Tables", - "LIST": { - "BASIC": "Basic Tables", - "MATERIAL": "Material Tables", - "NGX-DATATABLE": "NGX-Datatable" - } - } - }, - "BALANCE": "Баланс", - "DEBIT.BALANCE": "Остаток", - "CREDIT.BALANCE": "Кредиты", - "CURRENT.BALANCE": "Поточний баланс", - "HOME": "Головна", - "OTHER": "Інші", - "TOTAL": "Всього", - "INCOME": "Надходження", - "OUTCOME": "Витрати", - "PERIOD": "Період" -} diff --git a/MyOffice.SPA/src/assets/images/apps/calendar.png b/MyOffice.SPA/src/assets/images/apps/calendar.png deleted file mode 100644 index 2778d98..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/calendar.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/apps/chat.png b/MyOffice.SPA/src/assets/images/apps/chat.png deleted file mode 100644 index a67f315..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/chat.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/apps/contact.png b/MyOffice.SPA/src/assets/images/apps/contact.png deleted file mode 100644 index df66232..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/contact.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/apps/gallery.png b/MyOffice.SPA/src/assets/images/apps/gallery.png deleted file mode 100644 index 7845170..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/gallery.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/apps/mail.png b/MyOffice.SPA/src/assets/images/apps/mail.png deleted file mode 100644 index dcdc777..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/mail.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/apps/support.png b/MyOffice.SPA/src/assets/images/apps/support.png deleted file mode 100644 index c5f5b76..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/support.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/apps/table.png b/MyOffice.SPA/src/assets/images/apps/table.png deleted file mode 100644 index b1d2feb..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/table.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/apps/task.png b/MyOffice.SPA/src/assets/images/apps/task.png deleted file mode 100644 index bcbe59f..0000000 Binary files a/MyOffice.SPA/src/assets/images/apps/task.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/banner/1.png b/MyOffice.SPA/src/assets/images/banner/1.png deleted file mode 100644 index d90352c..0000000 Binary files a/MyOffice.SPA/src/assets/images/banner/1.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/banner/2.png b/MyOffice.SPA/src/assets/images/banner/2.png deleted file mode 100644 index d90352c..0000000 Binary files a/MyOffice.SPA/src/assets/images/banner/2.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/banner/3.png b/MyOffice.SPA/src/assets/images/banner/3.png deleted file mode 100644 index d90352c..0000000 Binary files a/MyOffice.SPA/src/assets/images/banner/3.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/banner/4.png b/MyOffice.SPA/src/assets/images/banner/4.png deleted file mode 100644 index d90352c..0000000 Binary files a/MyOffice.SPA/src/assets/images/banner/4.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/dark.png b/MyOffice.SPA/src/assets/images/dark.png deleted file mode 100644 index 9698d4f..0000000 Binary files a/MyOffice.SPA/src/assets/images/dark.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/details_close.png b/MyOffice.SPA/src/assets/images/details_close.png deleted file mode 100644 index 9c7d698..0000000 Binary files a/MyOffice.SPA/src/assets/images/details_close.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/details_open.png b/MyOffice.SPA/src/assets/images/details_open.png deleted file mode 100644 index c0edf44..0000000 Binary files a/MyOffice.SPA/src/assets/images/details_open.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/favicon.ico b/MyOffice.SPA/src/assets/images/favicon.ico deleted file mode 100644 index 9ba9214..0000000 Binary files a/MyOffice.SPA/src/assets/images/favicon.ico and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/flags/germany.jpg b/MyOffice.SPA/src/assets/images/flags/germany.jpg deleted file mode 100644 index 46147e4..0000000 Binary files a/MyOffice.SPA/src/assets/images/flags/germany.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/flags/spain.jpg b/MyOffice.SPA/src/assets/images/flags/spain.jpg deleted file mode 100644 index f81c83a..0000000 Binary files a/MyOffice.SPA/src/assets/images/flags/spain.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/flags/ukraine.png b/MyOffice.SPA/src/assets/images/flags/ukraine.png deleted file mode 100644 index 3479ad3..0000000 Binary files a/MyOffice.SPA/src/assets/images/flags/ukraine.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/flags/us.jpg b/MyOffice.SPA/src/assets/images/flags/us.jpg deleted file mode 100644 index 851cd7b..0000000 Binary files a/MyOffice.SPA/src/assets/images/flags/us.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/icons/xlsx.png b/MyOffice.SPA/src/assets/images/icons/xlsx.png deleted file mode 100644 index 2362390..0000000 Binary files a/MyOffice.SPA/src/assets/images/icons/xlsx.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/1.jpg b/MyOffice.SPA/src/assets/images/image-gallery/1.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/1.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/10.jpg b/MyOffice.SPA/src/assets/images/image-gallery/10.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/10.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/11.jpg b/MyOffice.SPA/src/assets/images/image-gallery/11.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/11.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/12.jpg b/MyOffice.SPA/src/assets/images/image-gallery/12.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/12.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/2.jpg b/MyOffice.SPA/src/assets/images/image-gallery/2.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/2.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/3.jpg b/MyOffice.SPA/src/assets/images/image-gallery/3.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/3.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/4.jpg b/MyOffice.SPA/src/assets/images/image-gallery/4.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/4.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/5.jpg b/MyOffice.SPA/src/assets/images/image-gallery/5.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/5.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/6.jpg b/MyOffice.SPA/src/assets/images/image-gallery/6.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/6.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/7.jpg b/MyOffice.SPA/src/assets/images/image-gallery/7.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/7.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/8.jpg b/MyOffice.SPA/src/assets/images/image-gallery/8.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/8.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/9.jpg b/MyOffice.SPA/src/assets/images/image-gallery/9.jpg deleted file mode 100644 index 25bdf2b..0000000 Binary files a/MyOffice.SPA/src/assets/images/image-gallery/9.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/invoice_logo.png b/MyOffice.SPA/src/assets/images/invoice_logo.png deleted file mode 100644 index 357b09e..0000000 Binary files a/MyOffice.SPA/src/assets/images/invoice_logo.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/light.png b/MyOffice.SPA/src/assets/images/light.png deleted file mode 100644 index 46595db..0000000 Binary files a/MyOffice.SPA/src/assets/images/light.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/logo.png b/MyOffice.SPA/src/assets/images/logo.png deleted file mode 100644 index 8396882..0000000 Binary files a/MyOffice.SPA/src/assets/images/logo.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/media.png b/MyOffice.SPA/src/assets/images/media.png deleted file mode 100644 index d889069..0000000 Binary files a/MyOffice.SPA/src/assets/images/media.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-01.png b/MyOffice.SPA/src/assets/images/pages/bg-01.png deleted file mode 100644 index 2847236..0000000 Binary files a/MyOffice.SPA/src/assets/images/pages/bg-01.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-02.png b/MyOffice.SPA/src/assets/images/pages/bg-02.png deleted file mode 100644 index 2847236..0000000 Binary files a/MyOffice.SPA/src/assets/images/pages/bg-02.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-03.png b/MyOffice.SPA/src/assets/images/pages/bg-03.png deleted file mode 100644 index 2847236..0000000 Binary files a/MyOffice.SPA/src/assets/images/pages/bg-03.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-04.png b/MyOffice.SPA/src/assets/images/pages/bg-04.png deleted file mode 100644 index 2847236..0000000 Binary files a/MyOffice.SPA/src/assets/images/pages/bg-04.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-05.png b/MyOffice.SPA/src/assets/images/pages/bg-05.png deleted file mode 100644 index 2847236..0000000 Binary files a/MyOffice.SPA/src/assets/images/pages/bg-05.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/pages/home-1.png b/MyOffice.SPA/src/assets/images/pages/home-1.png deleted file mode 100644 index df6683d..0000000 Binary files a/MyOffice.SPA/src/assets/images/pages/home-1.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post1.jpg b/MyOffice.SPA/src/assets/images/posts/post1.jpg deleted file mode 100644 index d706d8b..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post1.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post10.jpg b/MyOffice.SPA/src/assets/images/posts/post10.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post10.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post11.jpg b/MyOffice.SPA/src/assets/images/posts/post11.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post11.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post12.jpg b/MyOffice.SPA/src/assets/images/posts/post12.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post12.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post13.jpg b/MyOffice.SPA/src/assets/images/posts/post13.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post13.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post2.jpg b/MyOffice.SPA/src/assets/images/posts/post2.jpg deleted file mode 100644 index d706d8b..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post2.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post3.jpg b/MyOffice.SPA/src/assets/images/posts/post3.jpg deleted file mode 100644 index d706d8b..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post3.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post4.jpg b/MyOffice.SPA/src/assets/images/posts/post4.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post4.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post5.jpg b/MyOffice.SPA/src/assets/images/posts/post5.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post5.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post6.jpg b/MyOffice.SPA/src/assets/images/posts/post6.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post6.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post7.jpg b/MyOffice.SPA/src/assets/images/posts/post7.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post7.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post8.jpg b/MyOffice.SPA/src/assets/images/posts/post8.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post8.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/posts/post9.jpg b/MyOffice.SPA/src/assets/images/posts/post9.jpg deleted file mode 100644 index 5d46edc..0000000 Binary files a/MyOffice.SPA/src/assets/images/posts/post9.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/products/p-13.jpg b/MyOffice.SPA/src/assets/images/products/p-13.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/products/p-13.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/products/p-14.jpg b/MyOffice.SPA/src/assets/images/products/p-14.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/products/p-14.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/products/p-15.jpg b/MyOffice.SPA/src/assets/images/products/p-15.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/products/p-15.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/test.pdf b/MyOffice.SPA/src/assets/images/test.pdf deleted file mode 100644 index fc3d58a..0000000 Binary files a/MyOffice.SPA/src/assets/images/test.pdf and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/thumbs-up.png b/MyOffice.SPA/src/assets/images/thumbs-up.png deleted file mode 100644 index 8273711..0000000 Binary files a/MyOffice.SPA/src/assets/images/thumbs-up.png and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/admin.jpg b/MyOffice.SPA/src/assets/images/user/admin.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/admin.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user1.jpg b/MyOffice.SPA/src/assets/images/user/user1.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user1.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user10.jpg b/MyOffice.SPA/src/assets/images/user/user10.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user10.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user11.jpg b/MyOffice.SPA/src/assets/images/user/user11.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user11.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user2.jpg b/MyOffice.SPA/src/assets/images/user/user2.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user2.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user3.jpg b/MyOffice.SPA/src/assets/images/user/user3.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user3.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user4.jpg b/MyOffice.SPA/src/assets/images/user/user4.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user4.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user5.jpg b/MyOffice.SPA/src/assets/images/user/user5.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user5.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user6.jpg b/MyOffice.SPA/src/assets/images/user/user6.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user6.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user7.jpg b/MyOffice.SPA/src/assets/images/user/user7.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user7.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user8.jpg b/MyOffice.SPA/src/assets/images/user/user8.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user8.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/user9.jpg b/MyOffice.SPA/src/assets/images/user/user9.jpg deleted file mode 100644 index dd2b3b8..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/user9.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig1.jpg b/MyOffice.SPA/src/assets/images/user/usrbig1.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig1.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig10.jpg b/MyOffice.SPA/src/assets/images/user/usrbig10.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig10.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig11.jpg b/MyOffice.SPA/src/assets/images/user/usrbig11.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig11.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig2.jpg b/MyOffice.SPA/src/assets/images/user/usrbig2.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig2.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig3.jpg b/MyOffice.SPA/src/assets/images/user/usrbig3.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig3.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig4.jpg b/MyOffice.SPA/src/assets/images/user/usrbig4.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig4.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig5.jpg b/MyOffice.SPA/src/assets/images/user/usrbig5.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig5.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig6.jpg b/MyOffice.SPA/src/assets/images/user/usrbig6.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig6.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig7.jpg b/MyOffice.SPA/src/assets/images/user/usrbig7.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig7.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig8.jpg b/MyOffice.SPA/src/assets/images/user/usrbig8.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig8.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig9.jpg b/MyOffice.SPA/src/assets/images/user/usrbig9.jpg deleted file mode 100644 index cbe59c3..0000000 Binary files a/MyOffice.SPA/src/assets/images/user/usrbig9.jpg and /dev/null differ diff --git a/MyOffice.SPA/src/assets/scss/apps/_calendar.scss b/MyOffice.SPA/src/assets/scss/apps/_calendar.scss deleted file mode 100644 index 0a416be..0000000 --- a/MyOffice.SPA/src/assets/scss/apps/_calendar.scss +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Document : _calendar.scss - * Author : RedStar Template - * Description: This scss file for style related to calendar app - */ - -#event_title { - font-size: 1.2rem; -} - -#calendar { - float: right; - width: 100%; -} - -#external-events { - .fc-event { - padding: 5px 10px; - font-size: 14px; - margin-bottom: 4px; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); - text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); - border-radius: 3px; - cursor: move; - } - - .form-check .form-check-label { - font-size: 14px; - } -} - -.cal-event { - display: inline-block !important; - height: 10px; - width: 10px; - border-radius: 50%; - padding: 0; -} - -.fc-state-active { - background: #a389d4 !important; - color: #fff; -} - -.fc-day-grid-event { - color: white !important; - text-align: center; -} - -.fc-event-primary { - border: none !important; - background-color: #007bff !important; - box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), - 0 7px 10px -5px rgba(0, 154, 255, 0.4); - color: #fff; -} - -.fc-event-warning { - border: none !important; - background-color: #ff9800 !important; - box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), - 0 7px 10px -5px rgba(255, 152, 0, 0.4); - color: #fff; -} - -.fc-event-success { - border: none !important; - position: relative; - background-color: #53b958 !important; - box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), - 0 7px 10px -5px rgba(76, 175, 80, 0.4); - font-weight: 400; - color: #fff; -} - -.fc-event-danger { - border: none !important; - background-color: #f9483b !important; - box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), - 0 7px 10px -5px rgba(244, 67, 54, 0.4); - color: #fff; -} - -.fc-event-info { - border: none !important; - position: relative; - background-color: #03c5de !important; - box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), - 0 7px 10px -5px rgba(0, 188, 212, 0.4); - font-weight: 400; - color: #fff; -} - -.fc-event-default { - background: #007bff; - border: 1px solid #007bff; -} - -.fc-state-default { - border: 1px solid #eee; - background: transparent !important; - color: #7e869d; - border-radius: 0; -} - -.catLbl { - font-weight: 600; - color: #34395e; - font-size: 12px; - letter-spacing: 0.5px; - margin-bottom: 0; -} - -.fc .fc-button-primary { - background-color: #ffffff !important; - border: 1px solid #eee !important; - color: #7e869d !important; - border-radius: 5px !important; - margin-right: 8px !important; - - &:disabled { - color: #fff !important; - background-color: #6777ef !important; - border-color: #6777ef !important; - } - - &:hover { - color: #868181 !important; - background-color: #e1e0e0 !important; - border-color: #e1e0e0 !important; - } - - &:focus { - box-shadow: none !important; - } - - &:not(:disabled) { - &.fc-button-active { - color: #fff !important; - background-color: #6777ef !important; - border-color: #6777ef !important; - } - - &:active { - color: #fff !important; - background-color: #6777ef !important; - border-color: #6777ef !important; - } - } -} - -.fc-color-picker { - list-style: none; - margin: 0; - padding: 0; - - > li { - float: left; - font-size: 30px; - margin-right: 5px; - line-height: 30px; - } -} - -.fc-content-skeleton thead { - border-bottom: none; -} - -.fc-toolbar h2 { - font-size: 16px; - margin-top: 4px; -} - -.fc-view { - border-color: #f2f2f2; - - > table { - border-color: #f2f2f2; - - th { - border-color: #ddd; - color: color(fontdark) !important; - font-weight: 500; - padding: 15px; - } - } - - color: color(fontdark) !important; - font-weight: 500; - padding: 10px; - - .fc-scrollgrid-section { - > th { - padding: 0px; - } - } -} - -.fc-view-container > .fc-view { - padding: 0; -} - -.fc-view { - color: #666; - text-align: right; - - > table td { - color: #666; - text-align: right; - } -} - -.fc button .fc-icon { - top: -0.09em; -} - -.fc-basic-view { - .fc-day-number, - .fc-week-number { - padding: 10px; - } -} - -.fc .fc-daygrid-event { - padding: 0px 10px; - box-shadow: 0 4px 25px 0 rgba(0, 0, 0, 0.1); - color: #ffffff; - text-align: left; -} -.fc-daygrid-block-event .fc-event-time { - font-weight: 400 !important; - font-size: 12px; -} -.fc-daygrid-event-dot { - display: none; -} -.fc-daygrid-dot-event .fc-event-title { - font-weight: 400 !important; - text-align: left; - font-size: 12px; -} -.fc-daygrid-dot-event .fc-event-time { - font-weight: 400 !important; - text-align: left; - font-size: 12px; -} -.fc-event-title-container .fc-event-title { - font-weight: 400 !important; - text-align: left; - font-size: 12px; -} - -tr:first-child > td > .fc-day-grid-event { - margin-bottom: 10px; -} - -.fc-state-default { - border-radius: 3px; - background-color: #f2f2f2; - background-image: none; - border: none; - box-shadow: none; - text-transform: capitalize; - font-weight: 500; -} - -.fc button { - height: auto; - padding: 10px 15px; - text-shadow: none; - border-radius: 0; - - &.fc-state-active { - background-color: color(primary); - color: #fff; - } -} - -.fc .fc-axis { - vertical-align: middle; - padding: 0 4px; - white-space: nowrap; -} - -.ngx-mat-timepicker { - .ng-pristine { - td { - padding: 0px; - border-top: none; - border-bottom: none; - } - } -} - -.fc-time-grid-event .fc-content { - color: #ffffff; -} - -.fc-list-event { - color: #ffffff; -} - -.fc-list-event:hover td { - background-color: #cccaca !important; -} - -.fc-event-container:hover { - cursor: pointer; -} - -.fc-daygrid-day-top { - text-align: center; - display: block !important; - .fc-daygrid-day-number { - color: #666; - display: inline-flex; - align-items: center; - justify-content: center; - margin: 4px 0; - font-size: 12px !important; - } -} -.fc-day-today .fc-daygrid-day-number { - display: inline-flex; - align-items: center; - justify-content: center; - width: 25px; - height: 25px; - margin: 4px 0; - font-size: 12px; - border-radius: 50%; - background: #6777ef; - color: #fff; -} -.fc .fc-daygrid-day.fc-day-today { - background-color: transparent !important; -} -.fc .fc-col-header-cell-cushion { - color: #666; -} diff --git a/MyOffice.SPA/src/assets/scss/apps/_chat.scss b/MyOffice.SPA/src/assets/scss/apps/_chat.scss deleted file mode 100644 index 4cc8208..0000000 --- a/MyOffice.SPA/src/assets/scss/apps/_chat.scss +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Document : _chat.scss - * Author : RedStar Template - * Description: This scss file for style related to chat app - */ -%font_extend { - font-size: 16px; - color: gray; - cursor: pointer; -} - -.chat-app { - height: 690px; - .people-list { - width: 280px; - position: absolute; - left: 0; - top: 0; - padding: 20px; - } - .chat { - // margin-left: 280px; - border-left: 1px solid #e8e8e8; - } - .list_btn { - position: fixed; - bottom: 20px; - right: 20px; - z-index: 9999; - padding: 0; - width: 40px; - height: 40px; - text-align: center; - line-height: 40px; - display: none; - @include box-shadow(0 10px 25px 0 rgba(0, 0, 0, 0.3)); - @include border-radius(3px); - } -} -.people-list { - transition: 0.5s; - .chat-list { - li { - padding: 10px 15px; - list-style: none; - @include border-radius(3px); - &:hover { - background: #efefef; - cursor: pointer; - } - &.active { - background: #efefef; - } - .name { - font-size: 15px; - } - } - img { - width: 45px; - @include border-radius(50%); - } - } - img { - float: left; - border: 1px solid #fff; - @include box-shadow(0px 5px 25px 0px rgba(0, 0, 0, 0.2)); - @include border-radius(50%); - } - .about { - float: left; - padding-left: 8px; - } - .status { - color: #999; - font-size: 13px; - } -} -.chat { - .chat-header { - padding: 20px; - border-bottom: 1px solid #eee; - border-radius: 0 0.55rem 0 0; - img { - float: left; - @include border-radius(50%); - width: 45px; - } - .chat-about { - float: left; - padding-left: 10px; - } - .chat-with { - font-weight: bold; - font-size: 16px; - } - .chat-num-messages { - color: 434651; - } - } - .chat-history { - padding: 20px; - border-bottom: 2px solid #fff; - height: 450px; - ul { - padding: 0; - li { - list-style: none; - } - } - .message-data { - margin-bottom: 15px; - .message-data-name { - font-size: 13px; - font-weight: 700; - } - } - .message-data-time { - color: #434651; - padding-left: 6px; - } - .message { - color: #444; - padding: 18px 20px; - line-height: 26px; - font-size: 13px; - @include border-radius(7px); - margin-bottom: 30px; - width: 90%; - position: relative; - &:after { - bottom: 100%; - left: 7%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-bottom-color: #fff; - border-width: 10px; - margin-left: -10px; - } - } - .my-message { - background: #e8e8e8; - &:after { - bottom: 100%; - left: 7%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-bottom-color: #e8e8e8; - border-width: 10px; - margin-left: -10px; - } - } - .other-message { - background: #d9e7ea; - &:after { - border-bottom-color: #d9e7ea; - left: 93%; - } - } - } - .chat-message { - padding: 20px; - textarea { - width: 100%; - border: none; - padding: 10px 20px; - font: 14px/22px Lato, Arial, sans-serif; - margin-bottom: 10px; - @include border-radius(5px); - resize: none; - } - .fa-file-o { - @extend %font_extend; - } - .fa-file-image-o { - @extend %font_extend; - } - } -} -.online { - margin-right: 3px; - font-size: 10px; - color: #86bb71; -} -.offline { - margin-right: 3px; - font-size: 10px; - color: #e38968; -} -.me { - margin-right: 3px; - font-size: 10px; - color: #0498bd; -} -.float-end { - float: right; -} -.clearfix:after { - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; -} -.slimScrollBar { - z-index: 0 !important; -} -.chat-upload { - float: right; -} diff --git a/MyOffice.SPA/src/assets/scss/apps/_contactgrid.scss b/MyOffice.SPA/src/assets/scss/apps/_contactgrid.scss deleted file mode 100644 index 5e7eea7..0000000 --- a/MyOffice.SPA/src/assets/scss/apps/_contactgrid.scss +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Document : _contactgrid.scss - * Author : RedStar Template - * Description: This scss file for style related to contact grid app - */ -.contact-grid { - float: left; - width: 100%; - text-align: center; -} -.profile-header { - min-height: 150px; - color: #fff; -} -.user-name { - padding: 3px; - font-size: 22px; - text-align: center; - padding-top: 10px; -} -.user-img { - padding: 3px; - border-radius: 50% 50% 50% 50%; - max-width: 112px; - margin-top: -70px; - box-shadow: 0px 10px 25px 0px rgba(0, 0, 0, 0.3); - margin-bottom: 20px; -} -.profile-userbuttons { - text-align: center; - margin-top: 10px; -} -.contact-grid .phone .material-icons { - font-size: 16px; - padding: 4px 7px 40px 0px; -} diff --git a/MyOffice.SPA/src/assets/scss/apps/_contactlist.scss b/MyOffice.SPA/src/assets/scss/apps/_contactlist.scss deleted file mode 100644 index 18c17da..0000000 --- a/MyOffice.SPA/src/assets/scss/apps/_contactlist.scss +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Document : _contactlist.scss - * Author : RedStar Template - * Description: This scss file for style related to contact list app - */ -.contact-detail { - .fa { - float: left; - width: 30px; - font-size: 20px; - margin-top: 5px; - } - span { - float: left; - width: calc(100% - 30px); - margin-bottom: 20px; - } - .fa-envelope { - font-size: 15px; - } - .fa-mobile { - font-size: 25px; - } -} -.contact-photo { - float: left; - width: 100%; - text-align: center; - padding-top: 20px; - img { - margin: 0 auto; - width: 130px; - padding: 3px; - border: 3px solid rgb(210, 214, 222); - border-radius: 50% 50% 50% 50%; - } -} -.contact-usertitle { - text-align: center; - margin-top: 5px; -} -.contact-usertitle-name { - font-size: 20px; - margin-bottom: 2px; - font-weight: bold; - color: #3a405b; -} -.contact-usertitle-job { - color: #777777; - font-size: 12px; - margin-bottom: 5px; -} -.newLabelBtn { - padding: 20px 0; - text-align: center; -} -.alert-dismissible .close { - text-indent: 0; -} -.alert.alert-dismissible { - color: #ffffff; -} -.contact_list { - .phone { - position: relative; - padding-left: 20px; - .material-icons { - position: absolute; - left: 0; - font-size: 16px; - top: 1px; - } - } -} -.list-group-unbordered { - .list-group-item { - border: 0px; - } -} -.contact-header { - display: flex; - - .contact-details-img img { - position: relative; - display: flex; - width: 80px; - height: 80px; - border-radius: 50%; - margin-right: 0px; - overflow: hidden; - } -} - -.contact-details-name { - font-size: 20px; - font-weight: 500; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - letter-spacing: 1px; -} - -.contact-details-field { - display: flex; - margin-top: 30px; - - .material-icons-two-tone { - margin: 0 20px 0 10px; - } - - .contact-detail-info { - white-space: pre-wrap; - } - - .color-icon { - filter: invert(14%) sepia(0%) saturate(5141%) hue-rotate(101deg) - brightness(95%) contrast(97%); - } -} - -.contact-form { - .modalHeader img { - border-radius: 50%; - height: 35px; - width: 35px; - } -} diff --git a/MyOffice.SPA/src/assets/scss/apps/_dragdrop.scss b/MyOffice.SPA/src/assets/scss/apps/_dragdrop.scss deleted file mode 100644 index cd4c6eb..0000000 --- a/MyOffice.SPA/src/assets/scss/apps/_dragdrop.scss +++ /dev/null @@ -1,153 +0,0 @@ -.example-box { - width: 200px; - height: 200px; - border: solid 1px #ccc; - color: rgba(0, 0, 0, 0.87); - cursor: move; - display: inline-flex; - justify-content: center; - align-items: center; - text-align: center; - background: #fff; - border-radius: 4px; - margin-right: 25px; - position: relative; - z-index: 1; - box-sizing: border-box; - padding: 10px; - transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1); - box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), - 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} - -.example-box:active { - box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), - 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); -} - -.example-boundary { - width: 400px; - height: 400px; - max-width: 100%; - border: dotted #ccc 2px; -} - -.example-container2 { - width: 400px; - max-width: 100%; - margin: 0 25px 25px 0; - display: inline-block; - vertical-align: top; -} - -.example-list { - border: solid 1px #ccc; - min-height: 60px; - background: white; - border-radius: 4px; - overflow: hidden; - display: block; -} - -.example-box-small { - padding: 20px 10px; - border-bottom: solid 1px #ccc; - color: rgba(0, 0, 0, 0.87); - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - box-sizing: border-box; - cursor: move; - background: white; - font-size: 14px; -} - -.cdk-drag-preview { - box-sizing: border-box; - border-radius: 4px; - box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), - 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); -} - -.cdk-drag-placeholder { - opacity: 0; -} - -.cdk-drag-animating { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.example-box-small:last-child { - border: none; -} - -.example-list.cdk-drop-list-dragging - .example-box-small:not(.cdk-drag-placeholder) { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.example-list2 { - width: 500px; - max-width: 100%; - border: solid 1px #ccc; - min-height: 60px; - display: block; - background: white; - border-radius: 4px; - overflow: hidden; -} - -.example-box2 { - padding: 20px 10px; - border-bottom: solid 1px #ccc; - color: rgba(0, 0, 0, 0.87); - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - box-sizing: border-box; - cursor: move; - background: white; - font-size: 14px; -} - -.cdk-drag-preview { - box-sizing: border-box; - border-radius: 4px; - box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), - 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); -} - -.cdk-drag-animating { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.example-box2:last-child { - border: none; -} - -.example-list2.cdk-drop-list-dragging .example-box2:not(.cdk-drag-placeholder) { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.example-custom-placeholder { - background: #ccc; - border: dotted 3px #999; - min-height: 60px; - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.example-box-small.cdk-drag-disabled { - background: #ccc; - cursor: default; -} -.example-handle { - position: absolute; - top: 10px; - right: 10px; - color: #ccc; - cursor: move; - width: 24px; - height: 24px; -} diff --git a/MyOffice.SPA/src/assets/scss/apps/_task.scss b/MyOffice.SPA/src/assets/scss/apps/_task.scss deleted file mode 100644 index 28116f9..0000000 --- a/MyOffice.SPA/src/assets/scss/apps/_task.scss +++ /dev/null @@ -1,250 +0,0 @@ -.gu-mirror { - position: fixed !important; - margin: 0 !important; - z-index: 9999 !important; - opacity: 0.8; - filter: alpha(opacity=80); -} - -.gu-hide { - display: none !important; -} - -.gu-unselectable { - //Instead of the line below you could use @include user-select($select) - user-select: none !important; -} - -.gu-transit { - opacity: 0.2; - filter: alpha(opacity=20); -} - -.taskbar { - .checked { - border: 3px solid #dda500 !important; - } - - .box { - padding-bottom: 7px; - - .task-name { - font-size: 18px; - font-weight: 600; - color: green; - } - - .task-desc { - font-size: 1.1em; - color: #555; - } - - .task-deadline { - margin-top: 5px; - margin-right: 5px; - font-size: 0.8em; - color: #555; - } - } - - .done div.box { - pointer-events: none; - - .tasks { - color: #fff !important; - } - } - - .avatar-image { - display: inline-block; - position: relative; - } - - .task-header { - text-align: center; - font-size: 25px; - padding: 20px; - color: #6b6a6a; - } - - .card-footer { - background: #fff !important; - border-radius: 0px 0px 10px 10px; - - .progress { - height: 5px; - } - } -} - -.pad { - padding-left: 0; - padding-right: 0; - display: flex; -} - -.move { - text-align: center; - background: #eee; - - .btn { - margin-bottom: 20px; - } -} - -.task-module { - display: flex; - flex-direction: column; - padding: 0 !important; - min-height: 100%; - - .mat-drawer.mat-drawer-end { - width: 500px; - min-width: 500px; - border: 1px solid #dcd6d6; - } - - .task-header { - display: flex; - flex: 0 1 auto; - align-items: center; - margin: 10px 0px 23px 0px; - } - - .header-button { - margin-left: auto; - } -} - -.task-container { - .header { - .header-title { - margin: 0px 0px 0px 5px; - } - - .header-close { - position: absolute; - top: 10px; - right: 15px; - list-style: none; - } - } -} - -.task-list { - width: 100%; - max-width: 100%; - border: solid 1px #ccc; - min-height: 60px; - display: block; - background: white; - border-radius: 4px; - overflow: hidden; -} - -.task-user-img { - height: 30px; - width: 30px; - position: relative; - margin-left: 30px; - border-radius: 50%; -} - -.task-date { - margin-left: 30px; -} - -.lbl-low { - display: inline-flex; - vertical-align: middle; -} - -.lbl-high { - display: inline-flex; - vertical-align: middle; -} - -.lbl-normal { - display: inline-flex; - vertical-align: middle; -} - -.task-low { - color: #0bc53a; - position: relative; - margin-left: auto; -} - -.task-high { - color: #f9683a; - position: relative; - margin-left: auto; -} - -.task-normal { - color: #868688; - position: relative; - margin-left: auto; -} - -.task-box { - padding: 10px 10px; - border-bottom: solid 1px #ccc; - color: rgba(0, 0, 0, 0.87); - display: flex; - flex-direction: row; - align-items: center; - // justify-content: space-between; - box-sizing: border-box; - cursor: move; - background: white; - font-size: 14px; - - &:hover { - cursor: pointer; - } -} - -.cdk-drag-preview { - box-sizing: border-box; - border-radius: 4px; - box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), - 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); -} - -.cdk-drag-animating { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.task-box:last-child { - border: none; -} - -.task-list.cdk-drop-list-dragging .task-box:not(.cdk-drag-placeholder) { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.task-custom-placeholder { - background: #ccc; - border: dotted 3px #999; - min-height: 60px; - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.task-handle { - color: #ccc; - cursor: move; - width: 24px; - height: 24px; -} - -.done { - text-decoration: line-through; - opacity: 0.5; -} - -.mat-list-item-content { - display: flex; - flex-direction: row; - justify-content: space-between; -} diff --git a/MyOffice.SPA/src/assets/scss/browser/_ie10.scss b/MyOffice.SPA/src/assets/scss/browser/_ie10.scss deleted file mode 100644 index 698e265..0000000 --- a/MyOffice.SPA/src/assets/scss/browser/_ie10.scss +++ /dev/null @@ -1,60 +0,0 @@ -html { - &.ie10 { - .sidebar { - .menu { - .list { - li { - line-height: 30px; - } - - .ml-menu { - li { - &.active { - a { - &:not(.menu-toggle) { - &.toggled { - &:before { - top: 6px !important; - line-height: 20px !important; - } - } - } - } - } - } - } - } - } - - .user-info { - .info-container { - top: 15px; - } - } - } - - .search-bar { - input[type="text"] { - padding: 26px 60px 26px 56px; - } - } - - .dropdown-menu { - ul { - &.menu { - li { - a { - margin-top: -22px; - } - } - } - } - } - - .bs-searchbox { - .form-control { - width: 90%; - } - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/browser/_ie11.scss b/MyOffice.SPA/src/assets/scss/browser/_ie11.scss deleted file mode 100644 index 00779db..0000000 --- a/MyOffice.SPA/src/assets/scss/browser/_ie11.scss +++ /dev/null @@ -1,56 +0,0 @@ -html { - &.ie11 { - .sidebar { - .menu { - .list { - .ml-menu { - li { - &.active { - a { - &:not(.menu-toggle) { - &.toggled { - &:before { - top: 6px !important; - line-height: 20px !important; - } - } - } - } - } - } - } - } - } - - .user-info { - .info-container { - top: 15px; - } - } - } - - .search-bar { - input[type="text"] { - padding: 26px 60px 26px 56px; - } - } - - .dropdown-menu { - ul { - &.menu { - li { - a { - margin-top: -22px; - } - } - } - } - } - - .bs-searchbox { - .form-control { - width: 90%; - } - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/common/_animation.scss b/MyOffice.SPA/src/assets/scss/common/_animation.scss deleted file mode 100644 index 6ed8cde..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_animation.scss +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * Document : _animation.scss - * Author : RedStar Template - * Description: This scss file for animation css classes - */ -.waves-effect { - position: relative; - cursor: pointer; - display: inline-block; - overflow: hidden; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-tap-highlight-color: transparent; -} -.waves-effect .waves-ripple { - position: absolute; - border-radius: 50%; - width: 100px; - height: 100px; - margin-top: -50px; - margin-left: -50px; - opacity: 0; - background: transparent; - // background:rgba(0,0,0,0.2); - // background:-webkit-radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); - // background:-o-radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); - // background:-moz-radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); - // background:radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); - -webkit-transition: all 0.5s ease-out; - -moz-transition: all 0.5s ease-out; - -o-transition: all 0.5s ease-out; - transition: all 0.5s ease-out; - -webkit-transition-property: -webkit-transform, opacity; - -moz-transition-property: -moz-transform, opacity; - -o-transition-property: -o-transform, opacity; - transition-property: transform, opacity; - -webkit-transform: scale(0) translate(0, 0); - -moz-transform: scale(0) translate(0, 0); - -ms-transform: scale(0) translate(0, 0); - -o-transform: scale(0) translate(0, 0); - transform: scale(0) translate(0, 0); - pointer-events: none; -} -.waves-effect.waves-light .waves-ripple { - background: rgba(255, 255, 255, 0.4); - background: -webkit-radial-gradient( - rgba(255, 255, 255, 0.2) 0, - rgba(255, 255, 255, 0.3) 40%, - rgba(255, 255, 255, 0.4) 50%, - rgba(255, 255, 255, 0.5) 60%, - rgba(255, 255, 255, 0) 70% - ); - background: -o-radial-gradient( - rgba(255, 255, 255, 0.2) 0, - rgba(255, 255, 255, 0.3) 40%, - rgba(255, 255, 255, 0.4) 50%, - rgba(255, 255, 255, 0.5) 60%, - rgba(255, 255, 255, 0) 70% - ); - background: -moz-radial-gradient( - rgba(255, 255, 255, 0.2) 0, - rgba(255, 255, 255, 0.3) 40%, - rgba(255, 255, 255, 0.4) 50%, - rgba(255, 255, 255, 0.5) 60%, - rgba(255, 255, 255, 0) 70% - ); - background: radial-gradient( - rgba(255, 255, 255, 0.2) 0, - rgba(255, 255, 255, 0.3) 40%, - rgba(255, 255, 255, 0.4) 50%, - rgba(255, 255, 255, 0.5) 60%, - rgba(255, 255, 255, 0) 70% - ); -} -.waves-effect.waves-classic .waves-ripple { - background: rgba(0, 0, 0, 0.2); -} -.waves-effect.waves-classic.waves-light .waves-ripple { - background: rgba(255, 255, 255, 0.4); -} -.waves-notransition { - -webkit-transition: none !important; - -moz-transition: none !important; - -o-transition: none !important; - transition: none !important; -} -.waves-button, -.waves-circle { - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - -webkit-mask-image: -webkit-radial-gradient(circle, #fff 100%, #000 100%); -} -.waves-button, -.waves-button:hover, -.waves-button:visited, -.waves-button-input { - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - border: none; - outline: none; - color: inherit; - background-color: transparent; - font-size: 1em; - line-height: 1em; - text-align: center; - text-decoration: none; - z-index: 1; -} -.waves-button { - padding: 0.85em 1.1em; - border-radius: 0.2em; -} -.waves-button-input { - margin: 0; - padding: 0.85em 1.1em; -} -.waves-input-wrapper { - border-radius: 0.2em; - vertical-align: bottom; -} -.waves-input-wrapper.waves-button { - padding: 0; -} -.waves-input-wrapper .waves-button-input { - position: relative; - top: 0; - left: 0; - z-index: 1; -} -.waves-circle { - text-align: center; - width: 2.5em; - height: 2.5em; - line-height: 2.5em; - border-radius: 50%; -} -.waves-float { - -webkit-mask-image: none; - -webkit-box-shadow: 0px 1px 1.5px 1px rgba(0, 0, 0, 0.12); - box-shadow: 0px 1px 1.5px 1px rgba(0, 0, 0, 0.12); - -webkit-transition: all 300ms; - -moz-transition: all 300ms; - -o-transition: all 300ms; - transition: all 300ms; -} -.waves-float:active { - -webkit-box-shadow: 0px 8px 20px 1px rgba(0, 0, 0, 0.3); - box-shadow: 0px 8px 20px 1px rgba(0, 0, 0, 0.3); -} -.waves-block { - display: block; -} -.slideDown { - animation-name: slideDown; - -webkit-animation-name: slideDown; - animation-duration: 1s; - -webkit-animation-duration: 1s; - animation-timing-function: ease; - -webkit-animation-timing-function: ease; - visibility: visible !important; -} -@keyframes slideDown { - 0% { - transform: translateY(-100%); - } - 50% { - transform: translateY(8%); - } - 65% { - transform: translateY(-4%); - } - 80% { - transform: translateY(4%); - } - 95% { - transform: translateY(-2%); - } - 100% { - transform: translateY(0%); - } -} -@-webkit-keyframes slideDown { - 0% { - -webkit-transform: translateY(-100%); - } - 50% { - -webkit-transform: translateY(8%); - } - 65% { - -webkit-transform: translateY(-4%); - } - 80% { - -webkit-transform: translateY(4%); - } - 95% { - -webkit-transform: translateY(-2%); - } - 100% { - -webkit-transform: translateY(0%); - } -} -.slideUp { - animation-name: slideUp; - -webkit-animation-name: slideUp; - animation-duration: 1s; - -webkit-animation-duration: 1s; - animation-timing-function: ease; - -webkit-animation-timing-function: ease; - visibility: visible !important; -} -@keyframes slideUp { - 0% { - transform: translateY(100%); - } - 50% { - transform: translateY(-8%); - } - 65% { - transform: translateY(4%); - } - 80% { - transform: translateY(-4%); - } - 95% { - transform: translateY(2%); - } - 100% { - transform: translateY(0%); - } -} -@-webkit-keyframes slideUp { - 0% { - -webkit-transform: translateY(100%); - } - 50% { - -webkit-transform: translateY(-8%); - } - 65% { - -webkit-transform: translateY(4%); - } - 80% { - -webkit-transform: translateY(-4%); - } - 95% { - -webkit-transform: translateY(2%); - } - 100% { - -webkit-transform: translateY(0%); - } -} -.slideLeft { - animation-name: slideLeft; - -webkit-animation-name: slideLeft; - animation-duration: 1s; - -webkit-animation-duration: 1s; - animation-timing-function: ease-in-out; - -webkit-animation-timing-function: ease-in-out; - visibility: visible !important; -} -@keyframes slideLeft { - 0% { - transform: translateX(150%); - } - 50% { - transform: translateX(-8%); - } - 65% { - transform: translateX(4%); - } - 80% { - transform: translateX(-4%); - } - 95% { - transform: translateX(2%); - } - 100% { - transform: translateX(0%); - } -} -@-webkit-keyframes slideLeft { - 0% { - -webkit-transform: translateX(150%); - } - 50% { - -webkit-transform: translateX(-8%); - } - 65% { - -webkit-transform: translateX(4%); - } - 80% { - -webkit-transform: translateX(-4%); - } - 95% { - -webkit-transform: translateX(2%); - } - 100% { - -webkit-transform: translateX(0%); - } -} -.slideRight { - animation-name: slideRight; - -webkit-animation-name: slideRight; - animation-duration: 1s; - -webkit-animation-duration: 1s; - animation-timing-function: ease-in-out; - -webkit-animation-timing-function: ease-in-out; - visibility: visible !important; -} -@keyframes slideRight { - 0% { - transform: translateX(-150%); - } - 50% { - transform: translateX(8%); - } - 65% { - transform: translateX(-4%); - } - 80% { - transform: translateX(4%); - } - 95% { - transform: translateX(-2%); - } - 100% { - transform: translateX(0%); - } -} -@-webkit-keyframes slideRight { - 0% { - -webkit-transform: translateX(-150%); - } - 50% { - -webkit-transform: translateX(8%); - } - 65% { - -webkit-transform: translateX(-4%); - } - 80% { - -webkit-transform: translateX(4%); - } - 95% { - -webkit-transform: translateX(-2%); - } - 100% { - -webkit-transform: translateX(0%); - } -} -.slideExpandUp { - animation-name: slideExpandUp; - -webkit-animation-name: slideExpandUp; - animation-duration: 1.6s; - -webkit-animation-duration: 1.6s; - animation-timing-function: ease-out; - -webkit-animation-timing-function: ease -out; - visibility: visible !important; -} -@keyframes slideExpandUp { - 0% { - transform: translateY(100%) scaleX(0.5); - } - 30% { - transform: translateY(-8%) scaleX(0.5); - } - 40% { - transform: translateY(2%) scaleX(0.5); - } - 50% { - transform: translateY(0%) scaleX(1.1); - } - 60% { - transform: translateY(0%) scaleX(0.9); - } - 70% { - transform: translateY(0%) scaleX(1.05); - } - 80% { - transform: translateY(0%) scaleX(0.95); - } - 90% { - transform: translateY(0%) scaleX(1.02); - } - 100% { - transform: translateY(0%) scaleX(1); - } -} -@-webkit-keyframes slideExpandUp { - 0% { - -webkit-transform: translateY(100%) scaleX(0.5); - } - 30% { - -webkit-transform: translateY(-8%) scaleX(0.5); - } - 40% { - -webkit-transform: translateY(2%) scaleX(0.5); - } - 50% { - -webkit-transform: translateY(0%) scaleX(1.1); - } - 60% { - -webkit-transform: translateY(0%) scaleX(0.9); - } - 70% { - -webkit-transform: translateY(0%) scaleX(1.05); - } - 80% { - -webkit-transform: translateY(0%) scaleX(0.95); - } - 90% { - -webkit-transform: translateY(0%) scaleX(1.02); - } - 100% { - -webkit-transform: translateY(0%) scaleX(1); - } -} -.expandUp { - animation-name: expandUp; - -webkit-animation-name: expandUp; - animation-duration: 0.7s; - -webkit-animation-duration: 0.7s; - animation-timing-function: ease; - -webkit-animation-timing-function: ease; - visibility: visible !important; -} -@keyframes expandUp { - 0% { - transform: translateY(100%) scale(0.6) scaleY(0.5); - } - 60% { - transform: translateY(-7%) scaleY(1.12); - } - 75% { - transform: translateY(3%); - } - 100% { - transform: translateY(0%) scale(1) scaleY(1); - } -} -@-webkit-keyframes expandUp { - 0% { - -webkit-transform: translateY(100%) scale(0.6) scaleY(0.5); - } - 60% { - -webkit-transform: translateY(-7%) scaleY(1.12); - } - 75% { - -webkit-transform: translateY(3%); - } - 100% { - -webkit-transform: translateY(0%) scale(1) scaleY(1); - } -} -.fadeIn { - animation-name: fadeIn; - -webkit-animation-name: fadeIn; - animation-duration: 1.5s; - -webkit-animation-duration: 1.5s; - animation-timing-function: ease-in-out; - -webkit-animation-timing-function: ease-in-out; - visibility: visible !important; -} -@keyframes fadeIn { - 0% { - transform: scale(0); - opacity: 0; - } - 60% { - transform: scale(1.1); - } - 80% { - transform: scale(0.9); - opacity: 1; - } - 100% { - transform: scale(1); - opacity: 1; - } -} -@-webkit-keyframes fadeIn { - 0% { - -webkit-transform: scale(0); - opacity: 0; - } - 60% { - -webkit-transform: scale(1.1); - } - 80% { - -webkit-transform: scale(0.9); - opacity: 1; - } - 100% { - -webkit-transform: scale(1); - opacity: 1; - } -} -.expandOpen { - animation-name: expandOpen; - -webkit-animation-name: expandOpen; - animation-duration: 1.2s; - -webkit-animation-duration: 1.2s; - animation-timing-function: ease-out; - -webkit-animation-timing-function: ease-out; - visibility: visible !important; -} -@keyframes expandOpen { - 0% { - transform: scale(1.8); - } - 50% { - transform: scale(0.95); - } - 80% { - transform: scale(1.05); - } - 90% { - transform: scale(0.98); - } - 100% { - transform: scale(1); - } -} -@-webkit-keyframes expandOpen { - 0% { - -webkit-transform: scale(1.8); - } - 50% { - -webkit-transform: scale(0.95); - } - 80% { - -webkit-transform: scale(1.05); - } - 90% { - -webkit-transform: scale(0.98); - } - 100% { - -webkit-transform: scale(1); - } -} -.bigEntrance { - animation-name: bigEntrance; - -webkit-animation-name: bigEntrance; - animation-duration: 1.6s; - -webkit-animation-duration: 1.6s; - animation-timing-function: ease-out; - -webkit-animation-timing-function: ease-out; - visibility: visible !important; -} -@keyframes bigEntrance { - 0% { - transform: scale(0.3) rotate(6deg) translateX(-30%) translateY(30%); - opacity: 0.2; - } - 30% { - transform: scale(1.03) rotate(-2deg) translateX(2%) translateY(-2%); - opacity: 1; - } - 45% { - transform: scale(0.98) rotate(1deg) translateX(0%) translateY(0%); - opacity: 1; - } - 60% { - transform: scale(1.01) rotate(-1deg) translateX(0%) translateY(0%); - opacity: 1; - } - 75% { - transform: scale(0.99) rotate(1deg) translateX(0%) translateY(0%); - opacity: 1; - } - 90% { - transform: scale(1.01) rotate(0deg) translateX(0%) translateY(0%); - opacity: 1; - } - 100% { - transform: scale(1) rotate(0deg) translateX(0%) translateY(0%); - opacity: 1; - } -} -@-webkit-keyframes bigEntrance { - 0% { - -webkit-transform: scale(0.3) rotate(6deg) translateX(-30%) translateY(30%); - opacity: 0.2; - } - 30% { - -webkit-transform: scale(1.03) rotate(-2deg) translateX(2%) translateY(-2%); - opacity: 1; - } - 45% { - -webkit-transform: scale(0.98) rotate(1deg) translateX(0%) translateY(0%); - opacity: 1; - } - 60% { - -webkit-transform: scale(1.01) rotate(-1deg) translateX(0%) translateY(0%); - opacity: 1; - } - 75% { - -webkit-transform: scale(0.99) rotate(1deg) translateX(0%) translateY(0%); - opacity: 1; - } - 90% { - -webkit-transform: scale(1.01) rotate(0deg) translateX(0%) translateY(0%); - opacity: 1; - } - 100% { - -webkit-transform: scale(1) rotate(0deg) translateX(0%) translateY(0%); - opacity: 1; - } -} -.hatch { - animation-name: hatch; - -webkit-animation-name: hatch; - animation-duration: 2s; - -webkit-animation-duration: 2s; - animation-timing-function: ease-in-out; - -webkit-animation-timing-function: ease-in-out; - transform-origin: 50% 100%; - -ms-transform-origin: 50% 100%; - -webkit-transform-origin: 50% 100%; - visibility: visible !important; -} -@keyframes hatch { - 0% { - transform: rotate(0deg) scaleY(0.6); - } - 20% { - transform: rotate(-2deg) scaleY(1.05); - } - 35% { - transform: rotate(2deg) scaleY(1); - } - 50% { - transform: rotate(-2deg); - } - 65% { - transform: rotate(1deg); - } - 80% { - transform: rotate(-1deg); - } - 100% { - transform: rotate(0deg); - } -} -@-webkit-keyframes hatch { - 0% { - -webkit-transform: rotate(0deg) scaleY(0.6); - } - 20% { - -webkit-transform: rotate(-2deg) scaleY(1.05); - } - 35% { - -webkit-transform: rotate(2deg) scaleY(1); - } - 50% { - -webkit-transform: rotate(-2deg); - } - 65% { - -webkit-transform: rotate(1deg); - } - 80% { - -webkit-transform: rotate(-1deg); - } - 100% { - -webkit-transform: rotate(0deg); - } -} -.bounce { - animation-name: bounce; - -webkit-animation-name: bounce; - animation-duration: 1.6s; - -webkit-animation-duration: 1.6s; - animation-timing-function: ease; - -webkit-animation-timing-function: ease; - transform-origin: 50% 100%; - -ms-transform-origin: 50% 100%; - -webkit-transform-origin: 50% 100%; -} -@keyframes bounce { - 0% { - transform: translateY(0%) scaleY(0.6); - } - 60% { - transform: translateY(-100%) scaleY(1.1); - } - 70% { - transform: translateY(0%) scaleY(0.95) scaleX(1.05); - } - 80% { - transform: translateY(0%) scaleY(1.05) scaleX(1); - } - 90% { - transform: translateY(0%) scaleY(0.95) scaleX(1); - } - 100% { - transform: translateY(0%) scaleY(1) scaleX(1); - } -} -@-webkit-keyframes bounce { - 0% { - -webkit-transform: translateY(0%) scaleY(0.6); - } - 60% { - -webkit-transform: translateY(-100%) scaleY(1.1); - } - 70% { - -webkit-transform: translateY(0%) scaleY(0.95) scaleX(1.05); - } - 80% { - -webkit-transform: translateY(0%) scaleY(1.05) scaleX(1); - } - 90% { - -webkit-transform: translateY(0%) scaleY(0.95) scaleX(1); - } - 100% { - -webkit-transform: translateY(0%) scaleY(1) scaleX(1); - } -} -.pulse { - animation-name: pulse; - -webkit-animation-name: pulse; - animation-duration: 1.5s; - -webkit-animation-duration: 1.5s; - animation-iteration-count: infinite; - -webkit-animation-iteration-count: infinite; -} -@keyframes pulse { - 0% { - transform: scale(0.9); - opacity: 0.7; - } - 50% { - transform: scale(1); - opacity: 1; - } - 100% { - transform: scale(0.9); - opacity: 0.7; - } -} -@-webkit-keyframes pulse { - 0% { - -webkit-transform: scale(0.95); - opacity: 0.7; - } - 50% { - -webkit-transform: scale(1); - opacity: 1; - } - 100% { - -webkit-transform: scale(0.95); - opacity: 0.7; - } -} -.floating { - animation-name: floating; - -webkit-animation-name: floating; - animation-duration: 1.5s; - -webkit-animation-duration: 1.5s; - animation-iteration-count: infinite; - -webkit-animation-iteration-count: infinite; -} -@keyframes floating { - 0% { - transform: translateY(0%); - } - 50% { - transform: translateY(8%); - } - 100% { - transform: translateY(0%); - } -} -@-webkit-keyframes floating { - 0% { - -webkit-transform: translateY(0%); - } - 50% { - -webkit-transform: translateY(8%); - } - 100% { - -webkit-transform: translateY(0%); - } -} -.tossing { - animation-name: tossing; - -webkit-animation-name: tossing; - animation-duration: 2.5s; - -webkit-animation-duration: 2.5s; - animation-iteration-count: infinite; - -webkit-animation-iteration-count: infinite; -} -@keyframes tossing { - 0% { - transform: rotate(-4deg); - } - 50% { - transform: rotate(4deg); - } - 100% { - transform: rotate(-4deg); - } -} -@-webkit-keyframes tossing { - 0% { - -webkit-transform: rotate(-4deg); - } - 50% { - -webkit-transform: rotate(4deg); - } - 100% { - -webkit-transform: rotate(-4deg); - } -} -.pullUp { - animation-name: pullUp; - -webkit-animation-name: pullUp; - animation-duration: 1.1s; - -webkit-animation-duration: 1.1s; - animation-timing-function: ease-out; - -webkit-animation-timing-function: ease-out; - transform-origin: 50% 100%; - -ms-transform-origin: 50% 100%; - -webkit-transform-origin: 50% 100%; -} -@keyframes pullUp { - 0% { - transform: scaleY(0.1); - } - 40% { - transform: scaleY(1.02); - } - 60% { - transform: scaleY(0.98); - } - 80% { - transform: scaleY(1.01); - } - 100% { - transform: scaleY(0.98); - } - 80% { - transform: scaleY(1.01); - } - 100% { - transform: scaleY(1); - } -} -@-webkit-keyframes pullUp { - 0% { - -webkit-transform: scaleY(0.1); - } - 40% { - -webkit-transform: scaleY(1.02); - } - 60% { - -webkit-transform: scaleY(0.98); - } - 80% { - -webkit-transform: scaleY(1.01); - } - 100% { - -webkit-transform: scaleY(0.98); - } - 80% { - -webkit-transform: scaleY(1.01); - } - 100% { - -webkit-transform: scaleY(1); - } -} -.pullDown { - animation-name: pullDown; - -webkit-animation-name: pullDown; - animation-duration: 0.8s; - -webkit-animation-duration: 0.8s; - animation-timing-function: ease-out; - -webkit-animation-timing-function: ease-out; - transform-origin: 50% 0%; - -ms-transform-origin: 50% 0%; - -webkit-transform-origin: 50% 0%; -} -@keyframes pullDown { - 0% { - transform: scaleY(0.1); - } - 40% { - transform: scaleY(1.02); - } - 60% { - transform: scaleY(0.98); - } - 80% { - transform: scaleY(1.01); - } - 100% { - transform: scaleY(0.98); - } - 80% { - transform: scaleY(1.01); - } - 100% { - transform: scaleY(1); - } -} -@-webkit-keyframes pullDown { - 0% { - -webkit-transform: scaleY(0.1); - } - 40% { - -webkit-transform: scaleY(1.02); - } - 60% { - -webkit-transform: scaleY(0.98); - } - 80% { - -webkit-transform: scaleY(1.01); - } - 100% { - -webkit-transform: scaleY(0.98); - } - 80% { - -webkit-transform: scaleY(1.01); - } - 100% { - -webkit-transform: scaleY(1); - } -} -.stretchLeft { - animation-name: stretchLeft; - -webkit-animation-name: stretchLeft; - animation-duration: 1.5s; - -webkit-animation-duration: 1.5s; - animation-timing-function: ease-out; - -webkit-animation-timing-function: ease-out; - transform-origin: 100% 0%; - -ms-transform-origin: 100% 0%; - -webkit-transform-origin: 100% 0%; -} -@keyframes stretchLeft { - 0% { - transform: scaleX(0.3); - } - 40% { - transform: scaleX(1.02); - } - 60% { - transform: scaleX(0.98); - } - 80% { - transform: scaleX(1.01); - } - 100% { - transform: scaleX(0.98); - } - 80% { - transform: scaleX(1.01); - } - 100% { - transform: scaleX(1); - } -} -@-webkit-keyframes stretchLeft { - 0% { - -webkit-transform: scaleX(0.3); - } - 40% { - -webkit-transform: scaleX(1.02); - } - 60% { - -webkit-transform: scaleX(0.98); - } - 80% { - -webkit-transform: scaleX(1.01); - } - 100% { - -webkit-transform: scaleX(0.98); - } - 80% { - -webkit-transform: scaleX(1.01); - } - 100% { - -webkit-transform: scaleX(1); - } -} -.stretchRight { - animation-name: stretchRight; - -webkit-animation-name: stretchRight; - animation-duration: 1.5s; - -webkit-animation-duration: 1.5s; - animation-timing-function: ease-out; - -webkit-animation-timing-function: ease-out; - transform-origin: 0% 0%; - -ms-transform-origin: 0% 0%; - -webkit-transform-origin: 0% 0%; -} -@keyframes stretchRight { - 0% { - transform: scaleX(0.3); - } - 40% { - transform: scaleX(1.02); - } - 60% { - transform: scaleX(0.98); - } - 80% { - transform: scaleX(1.01); - } - 100% { - transform: scaleX(0.98); - } - 80% { - transform: scaleX(1.01); - } - 100% { - transform: scaleX(1); - } -} -@-webkit-keyframes stretchRight { - 0% { - -webkit-transform: scaleX(0.3); - } - 40% { - -webkit-transform: scaleX(1.02); - } - 60% { - -webkit-transform: scaleX(0.98); - } - 80% { - -webkit-transform: scaleX(1.01); - } - 100% { - -webkit-transform: scaleX(0.98); - } - 80% { - -webkit-transform: scaleX(1.01); - } - 100% { - -webkit-transform: scaleX(1); - } -} diff --git a/MyOffice.SPA/src/assets/scss/common/_customanimate.scss b/MyOffice.SPA/src/assets/scss/common/_customanimate.scss deleted file mode 100644 index bd021ce..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_customanimate.scss +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Document : _customanimate.scss - * Author : RedStar Template - * Description: This scss file for mixure of custom animation classes - */ -@-ms-keyframes spin { - from { - -ms-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - to { - -ms-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-moz-keyframes spin { - from { - -moz-transform: rotate(0deg); - -ms-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - to { - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-webkit-keyframes spin { - from { - -webkit-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -ms-transform: rotate(0deg); - -o-transform: rotate(0deg); - transform: rotate(0deg); - } - - to { - -webkit-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@keyframes spin { - from { - -moz-transform: rotate(0deg); - -ms-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - to { - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} diff --git a/MyOffice.SPA/src/assets/scss/common/_demo.scss b/MyOffice.SPA/src/assets/scss/common/_demo.scss deleted file mode 100644 index 74cbef7..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_demo.scss +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Document : _demo.scss - * Author : RedStar Template - * Description: This scss file style classes of following components - - Structure (with shortcodes): - - 1. BUTTONS - 2. CHECKBOX & RADIO - 3. JQUERY KNOB-CHART - 4. SWITCH - 5. COLOR BOX - 6. IMAGES - 7. TAGS INPUT - 8. GOOGLE MATERIAL DESIGN ICON - 9. PRELOADER - 10. ION RANGE SLIDER - 11. RIGHT SIDEBAR - - */ - -/*********************************************************************** - - [1. BUTTONS ] - -***********************************************************************/ -.demo-button-sizes { - .btn { - margin-bottom: 5px; - } -} - -.icon-button-demo { - button { - margin-right: 5px; - margin-bottom: 12px; - } -} - -.icon-and-text-button-demo { - button { - margin-right: 5px; - margin-bottom: 12px; - width: 16.66666666666667%; - } -} - -.button-demo { - ul { - padding-left: 0; - - li { - list-style: none; - padding-left: 0; - display: inline-block; - margin-right: 7px; - - .btn { - display: block; - min-width: 175px; - } - } - } - - .btn { - margin-right: 8px; - margin-bottom: 13px; - min-width: 100px; - } -} - -.demo-button-groups { - .btn-group { - margin-right: 10px; - margin-bottom: 10px; - } -} - -.demo-button-toolbar { - .btn-toolbar { - float: left; - margin-right: 25px; - margin-bottom: 10px; - .btn-group { - margin-left: 5px; - } - } -} - -.demo-button-nesting { - > .btn-group { - margin-right: 15px; - } -} - -.demo-single-button-dropdowns { - > .btn-group { - margin-right: 10px; - } -} - -.demo-splite-button-dropdowns { - > .btn-group { - margin-right: 10px; - } -} - -.demo-dropup { - .dropup { - margin-right: 10px; - } -} - -/*********************************************************************** - - [2. CHECKBOX & RADIO ] - -***********************************************************************/ - -.demo-checkbox, -.demo-radio-button { - label { - min-width: 150px; - } -} -/*********************************************************************** - - [3. JQUERY KNOB-CHART ] - -***********************************************************************/ - -.demo-knob-chart { - div { - margin-right: 15px; - } -} -/*********************************************************************** - - [4. SWITCH ] - -***********************************************************************/ - -.demo-switch { - .switch { - display: inline-block; - min-width: 170px; - } - - .demo-switch-title { - min-width: 95px; - display: inline-block; - } -} -/*********************************************************************** - - [5. COLOR BOX ] - -***********************************************************************/ -.demo-color-box { - padding: 15px 0; - text-align: center; - margin-bottom: 20px; - @include border-radius(3px); - - .color-name { - font-size: 16px; - margin-bottom: 5px; - } - - .color-code, - .color-class-name { - font-size: 13px; - } -} -/*********************************************************************** - - [6. IMAGES ] - -***********************************************************************/ -.demo-image-copyright { - text-align: right; - font-style: italic; - font-size: 12px; - color: #777; - margin: 5px 0 10px 0; - - a { - font-weight: bold; - color: #555 !important; - } -} -/*********************************************************************** - - [7. TAGS INPUT ] - -***********************************************************************/ -.demo-tagsinput-area { - margin-bottom: 0px !important; - &.form-group .form-line:after { - border-bottom: 0px; - } -} -/*********************************************************************** - - [8 .GOOGLE MATERIAL DESIGN ICON ] - -***********************************************************************/ -.demo-icon-container { - .demo-google-material-icon { - margin-bottom: 5px; - text-align: left; - - .icon-name { - position: relative; - top: -8px; - left: 7px; - } - - .material-icons { - width: 24px; - } - } -} -/*********************************************************************** - - [9. PRELOADERS ] - -***********************************************************************/ -.demo-preloader { - .preloader { - margin-right: 10px; - } -} -/*********************************************************************** - - [10. ION RANGE SLIDER ] - -***********************************************************************/ -.irs-demo { - margin-bottom: 40px; - - .irs { - margin-top: 15px; - } -} -/*********************************************************************** - - [11. RIGHT SIDEBAR ] - -***********************************************************************/ -.right-sidebar { - .nav-tabs + .tab-content { - padding: 0; - } - - p { - margin: 20px 15px 15px 15px; - font-weight: bold; - text-align: center; - } - - #settings { - .setting-list { - list-style: none; - padding-left: 0; - margin-bottom: 20px; - - li { - padding: 15px; - position: relative; - border-top: 1px solid #eee; - - .switch { - position: absolute; - top: 15px; - right: 5px; - } - } - } - } - .progress { - -webkit-border-radius: 50px; - -moz-border-radius: 50px; - -ms-border-radius: 50px; - border-radius: 50px; - height: 7px; - margin: 10px 0px 0px 0px; - } -} -.right-sidebar .choose-theme li { - position: relative; - cursor: pointer; - display: inline-block; -} - -.demo-choose-skin, -.demo-choose-logoheader { - list-style: none; - padding-left: 0; - overflow-y: hidden; - - li { - padding: 10px 7px 4px 0px; - position: relative; - cursor: pointer; - float: left; - - &.actived { - &:after { - font-family: "Material Icons"; - position: absolute; - top: 10px; - right: 10px; - content: "\E876"; - font-size: 18px; - color: #ece6e6; - } - } - - div { - width: 24px; - height: 24px; - display: inline-block; - @include border-radius(3px); - } - - span { - position: relative; - bottom: 7px; - left: 5px; - } - } - .white-theme { - background-color: #fff; - } - .black-theme { - background-color: #3a3f51; - } - .purple-theme { - background-color: #813ae1; - } - .blue-theme { - background-color: #03a9f3; - } - .cyan-theme { - background-color: #13d1d3; - } - .green-theme { - background-color: #13b464; - } - .orange-theme { - background-color: #f06533; - } - - @each $key, $val in $colors { - .#{$key} { - background-color: $val; - } - } -} -.white-theme-border { - border: 1px solid #888888; -} - -.btn-sidebar-light, -.btn-theme-light { - background: 0 0 !important; - color: #888888 !important; - border: 1px solid #888888 !important; - margin: 10px; -} -//===================================================================================== diff --git a/MyOffice.SPA/src/assets/scss/common/_general.scss b/MyOffice.SPA/src/assets/scss/common/_general.scss deleted file mode 100644 index 80cfc33..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_general.scss +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Document : _general.scss - * Author : RedStar Template - * Description: This scss file for all common style classes - */ - -body, -html { - @include transition(all 0.5s); - background-color: #f0eff3; - font-family: "Roboto", sans-serif; - font-size: 14px; -} - -button, -input, -select, -a { - outline: none !important; - font-size: 14px !important; - text-decoration: none; - - &:hover { - text-decoration: none; - } -} - -textarea { - font-size: 14px !important; -} - -ol, -ul, -dl { - padding-left: 0px; - list-style-type: none; -} - -.no-animate { - -o-transition-property: none !important; - -moz-transition-property: none !important; - -ms-transition-property: none !important; - -webkit-transition-property: none !important; - transition-property: none !important; - -o-transform: none !important; - -moz-transform: none !important; - -ms-transform: none !important; - -webkit-transform: none !important; - transform: none !important; - -webkit-animation: none !important; - -moz-animation: none !important; - -o-animation: none !important; - -ms-animation: none !important; - animation: none !important; -} - -section { - &.content { - margin: 55px 27px 0 260px; - min-height: calc(100vh - 76px); - @include transition(0.5s); - .content-block { - padding: 25px 0px 0px 25px; - } - } -} - -.horizontal-layout { - section { - &.content { - margin: 170px 15px 0 15px; - float: left; - width: calc(100% - 30px); - } - } -} - -.pull-left { - float: left !important; -} - -.pull-right { - float: right !important; -} - -.msl-1 { - margin-left: 0.25rem !important; -} -.msl-2 { - margin-left: 0.5rem !important; -} -.msl-3 { - margin-left: 1rem !important; -} -.msl-4 { - margin-left: 1.5rem !important; -} -.msl-5 { - margin-left: 3rem !important; -} - -.msr-1 { - margin-right: 0.25rem !important; -} -.msr-2 { - margin-right: 0.5rem !important; -} -.msr-3 { - margin-right: 1rem !important; -} -.msr-4 { - margin-right: 1.5rem !important; -} -.msr-5 { - margin-right: 3rem !important; -} - -.psl-1 { - padding-left: 0.25rem !important; -} -.psl-2 { - padding-left: 0.5rem !important; -} -.psl-3 { - padding-left: 1rem !important; -} -.psl-4 { - padding-left: 1.5rem !important; -} -.psl-5 { - padding-left: 3rem !important; -} - -.psr-1 { - padding-right: 0.25rem !important; -} -.psr-2 { - padding-right: 0.5rem !important; -} -.psr-3 { - padding-right: 1rem !important; -} -.psr-4 { - padding-right: 1.5rem !important; -} -.psr-5 { - padding-right: 3rem !important; -} -.cursor-pointer { - cursor: pointer; -} - -.jqvmap-zoomin, -.jqvmap-zoomout { - width: 15px; - height: 15px; -} - -table { - .checkbox { - [type="checkbox"] + label { - margin: 0; - height: 20px; - padding-left: 20px; - vertical-align: middle; - } - } -} - -.loading-img-spin { - position: absolute; - top: 50%; - left: 50%; - width: 50px; - height: 50px; - margin: -60px 0 20px -20px; - -webkit-animation: spin 1.5s linear infinite; - -moz-animation: spin 1.5s linear infinite; - animation: spin 1.5s linear infinite; -} - -.shadow-style { - -webkit-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); -} - -.review-img { - padding-left: 20px; - padding-top: 5px; - width: 70px; - - img { - border-radius: 50%; - border: 2px solid #ffffff; - box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); - } -} - -.horizontal-layout { - .sidebar, - .nav-left-menu { - display: none; - } -} - -.bootstrap-notify-container { - max-width: 320px; - text-align: center; -} - -.map iframe { - width: 100%; -} - -.jqvmap-label { - position: absolute; - display: none; - -webkit-border-radius: 30px; - -moz-border-radius: 30px; - border-radius: 30px; - background: #eee; - color: black; - font-size: 14px; - font-family: sans-serif, Verdana; - padding: 10px; - pointer-events: none; -} - -.logo-white { - .navbar-toggle, - .bars:before, - .bars:after { - color: #000 !important; - } -} - -.logo-black { - .navbar-toggle, - .bars:before, - .bars:after { - color: #fff !important; - } -} - -.dark { - .sidemenu-collapse i { - color: #fff; - } - - .nav { - > li { - > a { - color: #fff; - } - } - } -} - -.light { - .sidemenu-collapse i { - color: #0d091d; - } - - .nav { - > li { - > a { - color: #0d091d; - } - } - } -} - -.border-apply { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2) !important; -} - -input::-webkit-input-placeholder { - font-size: 12px; - color: #adabab; -} - -input:-moz-placeholder { - /* Firefox 18- */ - font-size: 12px; - color: #adabab; -} - -input::-moz-placeholder { - /* Firefox 19+ */ - font-size: 12px; - color: #adabab; -} - -input:-ms-input-placeholder { - font-size: 12px; - color: #adabab; -} - -textarea::-webkit-input-placeholder { - font-size: 12px; - color: #adabab; -} - -textarea:-moz-placeholder { - /* Firefox 18- */ - font-size: 12px; - color: #adabab; -} - -textarea::-moz-placeholder { - /* Firefox 19+ */ - font-size: 12px; - color: #adabab; -} - -textarea:-ms-input-placeholder { - font-size: 12px; - color: #adabab; -} - -.profile-image img { - width: 100%; -} - -@media screen and (max-width: 1169px) { - .horizontal-layout { - .sidebar { - display: block; - } - - .top-sidebar { - display: none; - } - - section.content { - margin-top: 100px; - } - } -} - -.font-icon { - display: flex; - flex-direction: row; - align-items: center; - margin-bottom: 20px; - padding: 10px; - transition: all 0.2s; - - .icon-preview { - font-size: 1.8rem; - margin-right: 10px; - line-height: 1; - color: #333439; - } -} - -.deshboard-echart-height { - height: 250px; -} -.pill-style { - font-size: 17px; - color: #a9a6a6; - padding-right: 5px; -} -.pill-timing { - width: 30%; -} - -@media screen and (min-width: 1400px) { - .boxed-layout .container { - width: 1370px; - max-width: 100%; - } -} diff --git a/MyOffice.SPA/src/assets/scss/common/_helpers.scss b/MyOffice.SPA/src/assets/scss/common/_helpers.scss deleted file mode 100644 index 12b1938..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_helpers.scss +++ /dev/null @@ -1,164 +0,0 @@ -@use "sass:math"; -@for $i from -25 through 25 { - .m-l-#{$i * 5} { - margin-left: #{$i * 5}px; - } - - .m-t-#{$i * 5} { - margin-top: #{$i * 5}px; - } - - .m-r-#{$i * 5} { - margin-right: #{$i * 5}px; - } - - .m-b-#{$i * 5} { - margin-bottom: #{$i * 5}px; - } -} - -.margin-0 { - margin: 0; -} - -@for $i from 0 through 25 { - .p-l-#{$i * 5} { - padding-left: #{$i * 5}px; - } - - .p-t-#{$i * 5} { - padding-top: #{$i * 5}px; - } - - .p-r-#{$i * 5} { - padding-right: #{$i * 5}px; - } - - .p-b-#{$i * 5} { - padding-bottom: #{$i * 5}px; - } -} -@for $i from 0 through 25 { - .margin-#{$i * 5} { - margin: #{$i * 5}px; - } - .padding-#{$i * 5} { - padding: #{$i * 5}px; - } -} - -.padding-0 { - padding: 0; -} - -@for $i from 5 through 49 { - .font-#{$i + 1} { - font-size: #{$i + 1}px; - } -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -.align-justify { - text-align: justify; -} - -.no-resize { - resize: none; -} - -.font-bold { - font-weight: bold; -} - -.font-italic { - font-style: italic; -} - -.font-underline { - text-decoration: underline; -} - -.font-line-through { - text-decoration: line-through; -} - -.font-overline { - text-decoration: overline; -} - -.block-header { - //margin-bottom: 15px; - - h2 { - margin: 0 !important; - color: #666 !important; - font-weight: normal; - font-size: 22px; - line-height: 46px; - - small { - display: block; - font-size: 12px; - margin-top: 8px; - color: #888; - - a { - font-weight: bold; - color: #777; - } - } - } -} - -@each $key, $val in $colors { - .bg-#{$key} { - background-color: $val !important; - color: #fff; - - .content { - .text, - .number { - color: #fff !important; - } - } - } -} - -@each $key, $val in $linear-colors { - .l-bg-#{$key} { - background: $val !important; - color: #fff; - - .content { - .text, - .number { - color: #fff !important; - } - } - } -} - -@each $key, $val in $colors { - .col-#{$key} { - color: $val !important; - } -} -@for $i from 0 through 100 { - .width-per-#{$i} { - width: round(percentage(math.div($i, 100))); - } - .tbl-col-width-per-#{$i} { - max-width: round(percentage(math.div($i, 100))); - } -} diff --git a/MyOffice.SPA/src/assets/scss/common/_media.scss b/MyOffice.SPA/src/assets/scss/common/_media.scss deleted file mode 100644 index 24868d0..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_media.scss +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Document : _media.scss - * Author : RedStar Template - * Description: This scss file for media queries classes - */ -@media (max-width: 1169px) { - // .sidemenu-collapse { - // display: none !important; - // } - .ls-closed .sidebar { - margin-left: -300px; - } - section.content { - margin: 83px 15px 0 0px; - } - .search-box { - margin-left: 25px; - } - .side-closed.submenu-closed .navbar-header { - width: 260px !important; - .navbar-brand span { - display: inline-block !important; - } - } - nav.navbar { - width: calc(100% - 4rem) !important; - } - .navbar .collapse-menu-icon { - display: block !important; - } - .sidebar .sidemenu-collapse { - display: none !important; - } -} -@media (max-width: 800px) { - .responsive_table { - overflow-x: auto !important; - } - - .mat-table { - min-width: 800px; - } -} - -@media (max-width: 799px) { - .navbar { - .search-box { - margin-left: 20px; - } - // .nav > li > a { - // padding: 10px 10px; - // } - } -} -@media (min-width: 768px) { - .navbar-header { - float: left; - } - .navbar-collapse { - width: auto; - border-top: 0; - box-shadow: none; - &.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - } - .navbar-toggle { - display: none; - } - .navbar-nav { - float: left; - margin: 0; - > li { - float: left; - > a { - padding-top: 15px; - padding-bottom: 15px; - } - } - } - - .container > { - .navbar-header { - margin-right: 0; - margin-left: 0; - } - .navbar-collapse { - margin-right: 0; - margin-left: 0; - } - } - .container-fluid > { - .navbar-header { - margin-right: 0; - margin-left: 0; - } - .navbar-collapse { - margin-right: 0; - margin-left: 0; - } - } - .navbar > { - .container .navbar-brand { - margin-left: -15px; - } - .container-fluid .navbar-brand { - margin-left: -15px; - } - } -} -.container > { - .navbar-header { - margin-right: -15px; - margin-left: -15px; - } - .navbar-collapse { - margin-right: -15px; - margin-left: -15px; - } -} -.container-fluid > { - .navbar-header { - margin-right: -15px; - margin-left: -15px; - border-right: 1px solid #f2f4f9; - } - .navbar-collapse { - margin-right: -15px; - margin-left: -15px; - } -} -@media (max-width: 767px) { - .navbar { - height: auto; - > .container, - > .container-fluid { - .navbar-brand { - margin-left: 30px; - width: 88%; - margin-right: 0; - } - } - - .navbar-toggle { - float: right; - } - - .nav-left-menu { - display: none; - } - - .navbar-right { - .fullscreen { - display: none; - } - } - - .navbar-header { - display: inline-block; - // margin-bottom: -25px; - width: calc(100% + 30px); - float: left; - } - - .nav { - > li { - display: inline-block; - > a { - // padding: 13px 15px 8px 15px; - &.js-right-sidebar { - padding: 9px 8px 8px 15px; - } - } - } - } - - .navbar-nav { - // margin-top: -10px; - margin-bottom: 1px; - margin-left: -7px; - - .open { - .dropdown-menu { - background-color: #fff; - position: absolute; - } - } - } - - .dropdown-menu { - margin-left: -50px; - } - - .navbar-collapse { - display: block; - } - } - .side-closed.submenu-closed .navbar-header { - width: calc(100% + 30px) !important; - } - .side-closed.submenu-closed .navbar-header .navbar-brand span { - display: inline-block !important; - } - .dt-buttons { - float: none !important; - text-align: center; - margin-bottom: 15px; - } - - .panel-switch-btn { - top: 12px; - right: 0 !important; - } - .rtl { - .navbar { - .navbar-toggle { - float: left; - margin-left: 15px; - margin-right: 0; - } - .navbar-header { - margin-bottom: 0px; - } - } - } - section.content, - body.ls-closed section.content { - margin-right: 0px; - margin-left: 0px; - } -} -@media (max-width: 600px) { - .navbar { - > .container, - > .container-fluid { - .navbar-brand { - /*width: 86%;*/ - } - } - .navbar-header { - margin-bottom: 0; - } - .navbar-toggle:before { - margin-top: 2px; - float: left; - } - // .nav-notification-icons { - // margin-top: 7px; - // } - } - .ls-closed .bars:after, - .ls-closed .bars:before { - margin-top: 2px; - } -} -@media (max-width: 500px) { - .navbar-nav { - &.nav { - .dropdown-menu { - width: 245px; - right: -80px; - &::before { - right: 95px; - } - &::after { - right: 96px; - } - } - .user_profile { - .dropdown-menu { - &::before { - right: 19px; - } - &::after { - right: 20px; - } - } - } - } - } - .navbar { - > .container, - > .container-fluid { - .navbar-brand { - margin-left: 28px; - width: 84%; - } - } - } - .breadcrumb-chart { - margin: 0 0 0 20px; - } - .search-box { - display: none; - } - full-calendar > div.fc-toolbar { - display: block !important; - } -} -@media (max-width: 420px) { - .navbar { - > .container, - > .container-fluid { - .navbar-brand { - width: 79%; - } - } - } - .btnAppList { - display: none; - } -} -@media (max-width: 350px) { - .navbar { - .nav { - > li { - > a { - padding: 13px 10px 8px 10px; - &.js-right-sidebar { - padding: 9px 10px 8px 10px; - } - } - } - .user_profile { - .dropdown-toggle { - padding: 7px 0px 9px 10px; - } - } - } - > .container-fluid { - .navbar-brand { - margin-left: 25px; - } - } - } -} - -@media (min-width: 768px) and (max-width: 991px) { - .navbar { - > .container, - > .container-fluid { - .navbar-brand { - margin-left: 20px; - } - } - } -} - -@media (min-width: 992px) and (max-width: 1169px) { - .navbar { - > .container, - > .container-fluid { - .navbar-brand { - margin-left: 20px; - } - } - } -} - -@media (min-width: 1170px) and (max-width: 1999px) { -} - -@media (min-width: 1200px) { -} diff --git a/MyOffice.SPA/src/assets/scss/common/_mixins.scss b/MyOffice.SPA/src/assets/scss/common/_mixins.scss deleted file mode 100644 index ba9a5d6..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_mixins.scss +++ /dev/null @@ -1,70 +0,0 @@ -@mixin border-radius($radius) { - -webkit-border-radius: $radius; - -moz-border-radius: $radius; - -ms-border-radius: $radius; - border-radius: $radius; -} - -@mixin box-shadow($shadowinfo) { - -webkit-box-shadow: $shadowinfo; - -moz-box-shadow: $shadowinfo; - -ms-box-shadow: $shadowinfo; - box-shadow: $shadowinfo; -} -@mixin transform($transform) { - -moz-transform: $transform; - -ms-transform: $transform; - -o-transform: $transform; - -webkit-transform: $transform; - transform: $transform; -} - -@mixin transition($transition) { - -moz-transition: $transition; - -o-transition: $transition; - -webkit-transition: $transition; - transition: $transition; -} - -@mixin three-dots-overflow() { - white-space: nowrap; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - overflow: hidden; -} - -@mixin navbar-link-color($textcolor, $navbarcolor, $opacity) { - .navbar-brand, - .navbar-brand:hover, - .navbar-brand:active, - .navbar-brand:focus { - color: $textcolor; - } - - .nav > li > a:hover, - .nav > li > a:focus, - .nav .open > a, - .nav .open > a:hover, - .nav .open > a:focus { - background-color: transparentize($navbarcolor, $opacity); - } - - .nav > li > a { - color: $textcolor; - } - - .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: $textcolor; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; - } - - .bars:hover { - background-color: rgba(0, 0, 0, 0.08); - } -} diff --git a/MyOffice.SPA/src/assets/scss/common/_rtl.scss b/MyOffice.SPA/src/assets/scss/common/_rtl.scss deleted file mode 100644 index a213c35..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_rtl.scss +++ /dev/null @@ -1,816 +0,0 @@ -.rtl { - direction: rtl; - text-align: right; - .navbar { - right: unset; - left: 0; - .navbar-toggle { - float: left; - margin-left: 15px; - margin-right: 0; - } - - .navbar-header { - margin-bottom: 0px; - } - .navbar-left { - padding-right: 0px; - } - } - - .navbar-nav { - &.navbar-right { - float: left !important; - margin-left: 0px; - margin-right: unset; - display: flex !important; - flex-direction: unset; - - .user_profile { - margin: 0px 0px 0px 6px; - .user_img { - border-radius: 50%; - } - } - - // .lang-dropdown { - // margin: 14px 10px 0px 20px; - // } - } - .dropdown-menu { - left: 0; - right: auto !important; - } - .nfc-dropdown { - left: 0; - right: auto !important; - } - .nfc-dropdown::before { - left: 19px; - right: unset; - } - .nfc-dropdown::after { - left: 20px; - right: unset; - } - > li .js-right-sidebar { - margin-left: 0px; - margin-right: 0; - } - .user_profile .user_dw_menu li i { - float: right; - padding-left: 5px; - } - .app-dropdown { - left: unset !important; - right: 0 !important; - - &::before { - right: 19px !important; - left: unset !important; - } - &::after { - right: 20px !important; - left: unset !important; - } - } - } - section { - &.content { - margin: 55px 260px 0px 27px; - min-height: calc(100vh - 76px); - transition: 0.5s; - .content-block { - padding: 25px 25px 0px 0px; - } - } - } - .breadcrumb-main { - .page-title { - border-right: none; - padding-right: 0px; - &:after { - display: none; - } - &:before { - content: "\f104"; - font-family: "Font Awesome 5 Free"; - font-size: 18px; - font-weight: 900; - padding: 0px 5px; - } - } - .breadcrumb-list { - float: left; - } - li a .fa-home { - float: right; - padding-right: 10px; - padding-left: unset; - } - .breadcrumb-item + .breadcrumb-item { - padding-right: 5px; - padding-left: unset; - &:after { - content: "\f104"; - font-family: "Font Awesome 5 Free"; - font-size: 14px; - font-weight: 900; - padding-left: 0.5rem; - } - &:before { - display: none; - } - } - } - .sidebar { - right: 0; - .menu { - clear: right; - .list { - .menu-toggle { - &:after { - left: 17px; - right: unset; - } - &:before { - content: "\f053"; - left: 17px; - right: unset; - } - } - a { - padding: 9px 9px 9px 9px; - span { - margin: 7px 12px 7px 0; - } - .mat-button-wrapper { - margin: 7px 0 7px 12px; - } - .material-icons-two-tone { - float: right; - } - .sidebarIcon { - float: right; - margin-right: 5px; - } - } - .ml-menu { - li a { - padding-right: 55px; - padding-top: 7px; - padding-bottom: 7px; - margin-right: 0; - } - .ml-menu-2 { - padding-right: 55px; - li a { - padding-right: 20px; - padding-top: 4px; - padding-bottom: 4px; - } - } - .ml-menu-3 { - padding-right: 20px; - li a { - padding-right: 20px; - padding-top: 4px; - padding-bottom: 4px; - } - } - } - .ml-sub-menu:after, - .ml-sub-menu:before { - left: 17px; - right: unset; - } - .header { - margin: 15px 35px 5px 0 !important; - } - .ml-sub-menu2:after, - .ml-sub-menu2:before { - left: 17px; - right: unset; - } - } - } - .sidebar-badge { - left: 35px; - right: unset; - } - .nav { - padding-right: 0px; - .logo { - margin-left: auto; - margin-right: unset; - } - } - } - .sidemenu-reorder { - float: right; - } - .form-check { - .form-check-label { - padding-right: 30px; - } - .form-check-sign { - left: unset; - right: 0px; - padding-right: 0px; - } - } - .mat-radio-button ~ .mat-radio-button { - margin-right: 16px; - } - @media (min-width: 768px) { - .navbar-header { - float: right; - } - } - - .msl-1 { - margin-right: 0.25rem !important; - margin-left: unset !important; - } - .msl-2 { - margin-right: 0.5rem !important; - margin-left: unset !important; - } - .msl-3 { - margin-right: 1rem !important; - margin-left: unset !important; - } - .msl-4 { - margin-right: 1.5rem !important; - margin-left: unset !important; - } - .msl-5 { - margin-right: 3rem !important; - margin-left: unset !important; - } - - .msr-1 { - margin-left: 0.25rem !important; - margin-right: unset !important; - } - .msr-2 { - margin-left: 0.5rem !important; - margin-right: unset !important; - } - .msr-3 { - margin-left: 1rem !important; - margin-right: unset !important; - } - .msr-4 { - margin-left: 1.5rem !important; - margin-right: unset !important; - } - .msr-5 { - margin-left: 3rem !important; - margin-right: unset !important; - } - - .psl-1 { - padding-right: 0.25rem !important; - padding-left: unset !important; - } - .psl-2 { - padding-right: 0.5rem !important; - padding-left: unset !important; - } - .psl-3 { - padding-right: 1rem !important; - padding-left: unset !important; - } - .psl-4 { - padding-right: 1.5rem !important; - padding-left: unset !important; - } - .psl-5 { - padding-right: 3rem !important; - padding-left: unset !important; - } - - .psr-1 { - padding-left: 0.25rem !important; - padding-right: unset !important; - } - .psr-2 { - padding-left: 0.5rem !important; - padding-right: unset !important; - } - .psr-3 { - padding-left: 1rem !important; - padding-right: unset !important; - } - .psr-4 { - padding-left: 1.5rem !important; - padding-right: unset !important; - } - .psr-5 { - padding-left: 3rem !important; - padding-right: unset !important; - } - - &.side-closed { - &.side-closed-hover { - section.content { - margin-right: 260px; - margin-left: 27px; - } - .sidebar .menu .list { - .ml-menu { - li a { - padding-right: 55px; - :before { - padding-right: 40px; - } - } - .ml-menu-2 { - padding-right: 55px; - li a { - padding-right: 20px; - } - } - } - li { - i { - float: right; - line-height: 2rem; - } - span { - display: block; - float: right; - } - .sidebarIcon { - float: right; - } - } - li .menu-toggle:before { - content: "\f053"; - } - } - } - section.content { - margin-right: 60px; - margin-left: 27px; - } - .navbar-brand { - margin-right: 5px; - } - a .sidebarIcon { - margin-right: 0px !important; - } - } - .card .header .header-dropdown { - left: 0px; - right: unset; - } - .dropdown-menu ul.menu { - .msg-user { - float: right; - } - .menu-info { - right: 10px; - float: right; - text-align: right; - .menu-desc .material-icons { - float: right; - margin-left: 3px; - } - } - li a { - float: right; - } - } - .right-sidebar { - &.open { - left: 0; - right: unset; - } - .rightSidebarClose { - right: 5px; - left: unset; - } - } - .collapse-menu-icon { - float: right !important; - } - .list-unstyled { - padding-right: 0; - } - .review-img { - padding-left: 0 !important; - padding-right: 20px; - } - .progress-percent { - float: left !important; - } - .todo-actionlist { - left: 0; - } - .ngxTableHeader { - .header-buttons-left { - right: -15px; - li { - margin-right: 10px; - } - .search-icon { - left: 0; - } - } - .header-buttons { - left: 35px; - right: unset; - } - } - #mail-nav { - #mail-folders { - padding-right: 0; - .badge { - float: left; - } - } - #mail-labels { - padding-right: 0; - } - #online-offline { - padding-right: 0; - } - } - .chat { - .chat-header { - img { - float: right; - } - .chat-about { - float: right; - padding-right: 10px; - } - } - .chat-history .my-message:after { - right: 7%; - } - } - .owl-carousel { - direction: ltr; - .owl-item { - direction: rtl; - } - } - .bx-wrapper { - direction: ltr; - } - .lg-outer { - direction: ltr; - } - .rightSetting p { - text-align: right; - } - .sidebar .menu .list { - padding-right: 0; - .active .ml-menu { - // padding-right: 30px; - margin-right: 0; - padding-left: 0px; - } - .ml-menu { - padding-right: 0; - li.active .ml-menu:before { - right: 30px; - left: unset; - content: "\f104"; - font-family: "Font Awesome 5 Free"; - } - .ml-menu-2 li.active a:not(.menu-toggle):before { - right: 0px; - left: unset; - } - } - .ml-menu-3 li.active .ml-menu3:before { - content: "\f104"; - } - } - .notice-board .notice-body { - padding: 0 10px 5px 0; - } - .ngx-datatable.material .datatable-footer .datatable-pager { - text-align: left; - } - .people-list img { - float: right; - } - .cd-timeline-img img { - right: 10%; - } - .navbar-header .bars:before { - right: 10px; - left: unset; - } - .navbar-brand { - margin-right: 60px; - span { - padding-left: unset; - padding-right: 10px; - } - } - .dropdown-menu ul.menu { - padding-right: 0; - } - .navbar-nav .user_profile .user_dw_menu { - padding-right: 0; - text-align: right; - } - .progress-list .status { - left: 0; - right: unset; - } - .to-do-list { - padding-right: 0px; - } - .materialTableHeader { - .tbl-export-btn { - left: 20px; - right: unset; - float: left; - } - .header-buttons-left { - padding-right: 0px; - .tbl-title { - margin-right: 20px; - margin-left: 0px; - } - - .tbl-search-box { - margin-right: 10px; - } - .search-icon { - padding-right: 10px; - padding-left: unset; - } - - input.search-field { - padding: 8px 50px 8px 8px; - } - } - } - #mail-nav #mail-labels li { - float: right; - } - #mail-nav #online-offline .material-icons { - padding: 0px 5px 2px 5px; - } - .chat-upload { - float: left; - } - .modal-header .close { - margin-left: 0px; - } - .modal-close-button { - left: 10px; - right: unset; - } - .owl-dt-container { - direction: rtl; - } - - .owl-dt-control-arrow-button svg { - transform: rotate(180deg); - } - .card-statistic-4 { - .card-spacing { - padding-right: 15px; - padding-top: 1rem; - } - } - .card-statistic-3 .card-icon { - left: -5px; - right: unset; - margin-left: 0px; - } - .card-statistic-2 .card-right { - float: left; - margin: 15px 0px 15px 15px; - } - .post-user { - .avtar-img { - float: right; - margin-left: 15px; - margin-right: unset; - } - } - .info-box6 { - .count-numbers { - left: 35px; - right: unset; - } - .count-name { - left: 35px; - right: unset; - } - } - - .feedBody { - border-right: 1px solid #d6d6d6; - border-left: unset; - margin-right: 30px; - margin-left: unset; - padding-right: 0px; - padding-left: unset; - li { - padding-left: unset; - padding-right: 30px; - .feed-user-img { - right: -20px; - left: unset; - } - } - } - .sl-item { - border-right: 1px solid #13b1e0; - border-left: unset; - padding-right: 15px; - padding-left: unset; - &::before { - right: -6.5px; - left: unset; - } - } - .task-module .header-button { - margin-right: auto; - margin-left: unset; - } - .task-list { - .task-low { - margin-right: auto; - margin-left: unset; - } - - .task-high { - margin-right: auto; - margin-left: unset; - } - - .task-normal { - margin-right: auto; - margin-left: unset; - } - } - .task-container .header .header-close { - left: 15px; - right: unset; - } - .form-check .form-check-sign .check:before { - margin-right: 10px; - margin-left: unset; - } - .top-sell { - .product-title { - margin-right: 20px; - } - .product-price { - margin-right: 20px; - } - .sell-price { - float: left; - } - } - .doc-file-type .media-cta { - margin-left: 15px; - } - .lang-dropdown { - margin-left: 0px; - .country-name { - margin-right: 5px; - } - } - .lang-item .lang-item-list { - text-align: right; - line-height: 15px; - display: block; - .flag-img { - float: right; - margin: 5px 0px 0px 5px; - } - } - &.ls-closed .sidebar { - margin-right: -300px; - margin-left: unset; - } - &.ls-closed section.content { - margin-right: 15px; - margin-left: 15px; - } - &.overlay-open.ls-closed .sidebar { - margin-right: 0; - margin-left: unset; - } - - .btn-space { - margin-left: 10px !important; - } - .ms-auto { - margin-right: auto !important; - margin-left: unset !important; - } - .float-end { - float: left !important; - } - .float-start { - float: right !important; - } - .text-end { - text-align: left !important; - } - .text-start { - text-align: right !important; - } - .settingSidebar { - left: -280px; - right: unset; - &.showSettingPanel { - left: 0; - right: unset; - } - - .settingPanelToggle { - background: #6777ef; - padding: 10px 15px; - color: #fff; - position: absolute; - top: 30%; - left: 280px; - width: 40px; - border-radius: 0px 10px 10px 0px; - } - } - .hiddenradio { - padding: 0px 0px 0px 20px; - margin: 10px 10px 0px 20px; - } - - .card-bnner { - img { - transform: scaleX(-1); - } - } - .user_img { - margin: 0px 0px 0px 5px; - } - &.side-closed .sidebar .menu .list li a { - padding-right: 9px; - } - - .nfc-menu { - right: auto; - left: unset; - .nfc-dropdown .menu { - .msg-user { - float: right; - } - .menu-info { - margin-right: 20px; - float: right; - text-align: right; - .menu-desc .material-icons { - float: right; - margin-left: 3px; - } - } - li a { - float: right; - } - } - } - - .mat-menu-item .user-menu-icons { - float: right; - } - .profile-menu .menu .user_dw_menu .mdc-list-item { - display: block; - .user-menu-icons { - float: right; - } - } - .order-list li + li { - margin-left: unset; - margin-right: -14px; - } - .info-card { - text-align: left; - } - .mdc-linear-progress__bar-inner { - left: 0px; - } - .ng-scrollbar-wrapper { - direction: rtl; - } -} - -@media (max-width: 1169px) { - .rtl { - .sidemenu-collapse { - display: none !important; - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/common/_variables.scss b/MyOffice.SPA/src/assets/scss/common/_variables.scss deleted file mode 100644 index 3a7718c..0000000 --- a/MyOffice.SPA/src/assets/scss/common/_variables.scss +++ /dev/null @@ -1,34 +0,0 @@ -$colors: ( - "red": #f44336, - "pink": #e91e63, - "purple": #6f42c1, - "indigo": #3f51b5, - "blue": #2196f3, - "cyan": #00bcd4, - "teal": #009688, - "green": #4caf50, - "yellow": #ffe821, - "orange": #fd7e14, - "deep-orange": #ff5722, - "brown": #795548, - "grey": #9e9e9e, - "black": #000000, - "white": #ffffff, -) !default; - -$linear-colors: ( - "green": linear-gradient(45deg, #9ce89d, #cdfa7e), - "orange": linear-gradient(135deg, #ffc480, #ff763b), - "cyan": linear-gradient(45deg, #72c2ff, #86f0ff), - "red": linear-gradient(316deg, #fc5286, #fbaaa2), - "purple": linear-gradient(230deg, #759bff, #843cf6), - "purple-dark": linear-gradient(45deg, #a52dd8, #e29bf1), - "card1": linear-gradient(to left, #3a7bd5, #3a6073), - "card2": linear-gradient(to right, #c33764, #1d2671), - "card3": linear-gradient(to left, #134e5e, #71b280), - "card4": linear-gradient(to left, #d38312, #a83279), -); - -//Fonts Family -$navbar-font-family: "Roboto", sans-serif; -$sidebar-font-family: "Roboto", sans-serif; diff --git a/MyOffice.SPA/src/assets/scss/components/_breadcrumbs.scss b/MyOffice.SPA/src/assets/scss/components/_breadcrumbs.scss deleted file mode 100644 index 4721d45..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_breadcrumbs.scss +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Document : _breadscrumbs.scss - * Author : RedStar Template - * Description: This scss file for breadscrumbs style classes - */ - -.breadcrumb-main { - // background-color: transparent; - // font-size: 15px; - // align-items: center; - // margin: 3rem 0 3rem; - // padding: 0px; - // color: #555; - - // &:before { - // content: ""; - // margin: 0; - // } - - .breadcrumb-title { - background-color: transparent; - font-size: 15px; - align-items: center; - margin: 30px 0px; - padding: 0px; - color: #555; - } - .breadcrumb-list { - background-color: transparent; - font-size: 15px; - align-items: center; - margin: 32px 0px; - float: right; - color: #555; - padding: 0px 5px; - } - - li { - display: inline-block; - a { - color: #444; - text-decoration: none; - - .fa-home { - font-size: 17px; - position: relative; - top: 0; - float: left; - padding-left: 10px; - color: #5798f7; - } - } - - .material-icons { - font-size: 18px; - position: relative; - top: 4px; - float: none; - } - &.active { - color: #444444; - } - } - - > li + li:before { - // content: "/" !important; - // color: #444444; - // padding-left: 5px; - } - .page-title { - // border-right: 1px solid #c5c5c5; - // padding-right: 10px; - font-size: 20px; - font-weight: 500; - color: #444444; - margin-bottom: 0px; - // &:after { - // content: "\f105"; - // font-family: "Font Awesome 5 Free"; - // font-size: 18px; - // font-weight: 900; - // padding: 0px 5px; - // } - i { - padding: 0px 5px; - &:before { - color: #717883; - font-size: 20px; - } - } - } - .breadcrumb-item + .breadcrumb-item { - padding-left: 5px; - &:before { - content: "\f105"; - font-family: "Font Awesome 5 Free"; - font-size: 14px; - display: block; - font-weight: 900; - padding-right: 0.5rem; - } - } -} - -@each $key, $val in $colors { - .breadcrumb-col-#{$key} { - li { - a { - color: $val !important; - font-weight: bold; - } - } - } - - .breadcrumb-bg-#{$key} { - background-color: $val !important; - - li { - a { - color: #fff; - font-weight: bold; - - .material-icons { - padding-bottom: 8px; - } - } - - color: #fff !important; - } - - li + li:before { - color: #fff; - } - } -} -.breadcrumb-style { - border-radius: 30px; - /*background: #ffffff; - padding-left: 20px !important;*/ -} -.breadcrumb-chart { - display: inline-block; - .chart-info p { - font-size: 13px; - } -} -.breadcrumb-icon { - vertical-align: top; - height: 18px !important; - width: 18px !important; - margin: 0px 3px; - .feather { - width: 18px; - height: 18px; - color: #2c323f; - position: relative; - float: left; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_checkboxradio.scss b/MyOffice.SPA/src/assets/scss/components/_checkboxradio.scss deleted file mode 100644 index 55fbea2..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_checkboxradio.scss +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Document : _checkboxradio.scss - * Author : RedStar Template - * Description: This scss file for checkbox and radio button style classes - */ -[type="checkbox"] { - +label { - padding-left: 26px; - height: 25px; - line-height: 21px; - font-size: 13px; - font-weight: normal; - vertical-align: middle; - } - - &:checked { - +label { - &:before { - top: -4px; - left: -2px; - width: 11px; - height: 19px; - } - } - } - - @each $key, - $val in $colors { - &:checked.chk-col-#{$key} { - +label { - &:before { - border-right: 2px solid $val; - border-bottom: 2px solid $val; - } - } - } - } -} - -@each $key, -$val in $colors { - :checked.chk-col-#{$key} { - +span { - &:after { - color: $val; - } - } - } -} - -[type="checkbox"].filled-in { - &:checked { - +label { - &:after { - top: 0; - width: 20px; - height: 20px; - border: 2px solid #26a69a; - background-color: #26a69a; - z-index: 0; - } - - &:before { - border-right: 2px solid #fff !important; - border-bottom: 2px solid #fff !important; - } - } - } - - @each $key, - $val in $colors { - &:checked.chk-col-#{$key} { - +label { - &:after { - border: 2px solid $val; - background-color: $val; - } - } - } - } -} - -[type="radio"] { - &:not(:checked) { - +label { - padding-left: 26px; - height: 25px; - line-height: 25px; - font-size: 13px; - font-weight: normal; - } - } - - &:checked { - +label { - padding-left: 26px; - height: 25px; - line-height: 25px; - font-size: 13px; - font-weight: normal; - } - } - - +label { - vertical-align: middle; - } -} - -@each $key, -$val in $colors { - [type="radio"].radio-col-#{$key} { - &:checked { - +label { - &:after { - background-color: $val; - border-color: $val; - } - } - } - } -} - -@each $key, -$val in $colors { - [type="radio"].with-gap.radio-col-#{$key} { - &:checked { - +label { - &:before { - border: 2px solid $val; - } - - &:after { - background-color: $val; - border: 2px solid $val; - } - } - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_dropdownmenu.scss b/MyOffice.SPA/src/assets/scss/components/_dropdownmenu.scss deleted file mode 100644 index 4f21eff..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_dropdownmenu.scss +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Document : _dropdownmenu.scss - * Author : RedStar Template - * Description: This scss file for dropdown menu style classes - */ -.dropdown-menu { - @include border-radius(0); - margin-top: -35px !important; - margin-left: -15px; - -webkit-box-shadow: 0 5px 15px 2px rgba(64, 70, 74, 0.2) !important; - box-shadow: 0 5px 15px 2px rgba(64, 70, 74, 0.2) !important; - border-radius: 0px; - border: none; - padding: 0px; - - .divider { - margin: 5px 0; - } - - .header { - font-size: 13px; - font-weight: bold; - width: 100%; - border-bottom: 1px solid #eee; - text-align: center; - padding: 4px 0 6px 0; - } - - .footer { - a { - text-align: center; - border-top: 1px solid #eee; - padding: 10px 0 5px 0; - font-size: 13px; - margin-bottom: -5px; - color: #ff5e00; - font-weight: 500; - - &:hover { - background-color: transparent; - } - } - } - - > li { - > a { - padding: 7px 18px; - color: #666; - @include transition(all 0.5s); - font-size: 14px; - line-height: 25px; - display: block; - - &:hover { - background-color: rgba(0, 0, 0, 0.075); - } - - i.material-icons { - float: left; - margin-right: 7px; - margin-top: 2px; - font-size: 20px; - } - } - } -} - -.app-dropdown { - width: 350px; - max-width: 350px !important; - .nfc-header { - padding: 20px; - background-color: #7366ff; - border-radius: 5px 5px 0px 0px; - h5 { - color: #fff; - } - } - .app-icons { - display: block; - border-radius: 3px; - line-height: 34px; - text-align: center; - padding: 15px 0 9px; - border: 1px solid transparent; - color: black; - font-weight: 500; - &:hover { - background-color: #eef4fd; - } - } - .mat-mdc-menu-content { - padding: 0px; - } -} - -.dropdown-content li > a, -.dropdown-content li > span { - font-size: 13px; - color: #636262; -} - -.dropdown-animated { - -webkit-animation-duration: 0.3s !important; - -moz-animation-duration: 0.3s !important; - -o-animation-duration: 0.3s !important; - animation-duration: 0.3s !important; -} - -.dropdown-menu.pull-right.show { - position: absolute !important; - left: auto !important; - right: 0 !important; - top: 50px !important; - transform: none !important; -} -.nfc-menu { - transform-origin: left top; - width: 325px; - max-width: 100vw !important; - right: 10px; - left: auto; - position: absolute !important; - top: 0; - padding: 0; - border-radius: 5px; - .nfc-dropdown { - .menu { - padding-left: 0; - button { - padding: 11px 11px; - text-decoration: none; - @include transition(0.5s); - float: left; - width: 100%; - height: 65px; - // border-bottom: 1px solid #eee; - margin-bottom: 2px; - - &:hover { - background-color: #eef4fd; - } - .mdc-list-item__primary-text { - width: 100%; - } - } - - &.tasks { - h4 { - color: #333; - font-size: 13px; - margin: 0 0 8px 0; - - small { - float: right; - margin-top: 6px; - } - } - - .progress { - height: 7px; - margin-bottom: 7px; - } - } - - .icon-circle { - width: 36px; - height: 36px; - @include border-radius(50%); - color: #fff; - text-align: center; - display: inline-block; - float: left; - - i { - font-size: 18px; - line-height: 36px !important; - } - } - - .msg-user { - width: 44px; - height: 44px; - @include border-radius(50%); - color: #fff; - text-align: center; - display: inline-block; - vertical-align: top; - float: left; - - img { - float: left; - } - } - - li { - &:last-child { - border-bottom: none; - } - } - - .menu-info { - display: inline-block; - position: relative; - top: 3px; - left: 10px; - float: left; - width: calc(100% - 75px); - - h4, - .menu-title { - margin: 0; - font-size: 14px; - color: #121212; - float: left; - width: 100%; - line-height: 1; - } - - p, - .menu-desc { - margin: 0; - font-size: 11px; - color: rgba(0, 0, 0, 0.54); - float: left; - width: 100%; - line-height: 20px; - - .material-icons { - font-size: 13px; - color: rgba(0, 0, 0, 0.54); - position: relative; - top: 3px; - float: left; - margin-right: 3px; - height: 20px; - } - } - } - .nfc-close { - display: flex; - height: 40px; - line-height: 40px; - .feather { - color: #747474; - height: 12px !important; - width: 12px !important; - } - } - .nfc-type-icon { - height: 40px; - width: 40px; - display: flex; - align-items: center; - justify-content: center; - &.nfc-green { - filter: invert(77%) sepia(4%) saturate(5247%) hue-rotate(85deg) - brightness(88%) contrast(95%); - } - &.nfc-blue { - filter: invert(67%) sepia(95%) saturate(5173%) hue-rotate(214deg) - brightness(101%) contrast(101%); - } - &.nfc-orange { - filter: invert(69%) sepia(81%) saturate(523%) hue-rotate(353deg) - brightness(101%) contrast(102%); - } - &.nfc-purple { - filter: invert(19%) sepia(98%) saturate(7474%) hue-rotate(284deg) - brightness(105%) contrast(117%); - } - &.nfc-red { - filter: invert(24%) sepia(94%) saturate(7102%) hue-rotate(356deg) - brightness(103%) contrast(100%); - } - } - .msg-unread { - background-color: #f5f9ff; - border-bottom: 1px solid #eee; - } - .msg-read { - border-bottom: 1px solid #eee; - } - } - } - .mat-menu-content { - padding-top: 0px !important; - padding-bottom: 0px !important; - } - .nfc-header { - padding: 20px; - background-color: #7366ff; - border-radius: 5px 5px 0px 0px; - display: flex; - h5 { - color: #fff; - } - } - - .nfc-mark-as-read { - display: block; - text-align: right; - color: #ffffff; - float: right; - width: 100%; - font-size: 12px !important; - } - .nfc-footer { - line-height: 50px; - cursor: pointer; - text-align: center; - border-top: 1px solid rgba(0, 0, 0, 0.15); - - .nfc-read-all { - color: rgb(106 106 106); - } - } - .mat-mdc-menu-content { - padding: 0px; - } -} -.profile-menu { - width: 200px; - max-width: 200px !important; - right: 10px; - - .user-menu-icons .feather { - height: 18px !important; - width: 18px !important; - vertical-align: middle; - } - .mat-mdc-menu-content { - padding: 0px; - } -} -.lang-item-menu .mat-mdc-menu-content { - padding: 0px; -} diff --git a/MyOffice.SPA/src/assets/scss/components/_feed.scss b/MyOffice.SPA/src/assets/scss/components/_feed.scss deleted file mode 100644 index cdec4ea..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_feed.scss +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Document : _feed.scss - * Author : RedStar Template - * Description: This scss file for feed style classes - */ -.feedBody { - border-left: 1px solid #d6d6d6; - margin-left: 30px; - padding-top: 10px; - padding-left: 0px; -} - -.col-auto { - padding-left: 15px; - padding-right: 15px; -} - -.feedLblStyle { - font-weight: bold; - padding: 0px 7px 0px 7px; - border-radius: 10px; -} - -.lblFileStyle { - color: red; - border: 1px solid red; -} - -.lblTaskStyle { - color: #2ed8b6; - border: 1px solid #2ed8b6; -} - -.lblCommentStyle { - color: #4099ff; - border: 1px solid #4099ff; -} - -.lblReplyStyle { - color: #f15317; - border: 1px solid #f15317; -} - -.feedBody li { - position: relative; - padding-left: 30px; - margin-bottom: 25px; -} - -.feedBody li .feed-user-img { - position: absolute; - left: -20px; - top: -10px; -} - -.feedBody li .feed-user-img img { - width: 40px; - height: 40px; - border-radius: 50%; -} - -.feedBody li.active-feed .feed-user-img:after { - border-color: #2ed8b6; -} - -.feedBody li .feed-user-img:after { - content: ""; - position: absolute; - top: 3px; - right: 3px; - border: 3px solid transparent; - border-radius: 50%; -} - -.feedBody li h6 { - line-height: 1.5; - cursor: pointer; -} - -.text-muted { - color: #96a2b4 !important; - margin-bottom: 10px; -} - -.img-100 { - width: 100px; -} - -.feedBody li h6 { - line-height: 1.5; - cursor: pointer; -} - -.feedBody li.active-feed .feed-user-img:after { - border-color: #2ed8b6; -} - -.sl-item { - border-left: 1px solid #13b1e0; - padding-bottom: 1px; - padding-left: 15px; - position: relative; - - &:last-child::after { - //Instead of the line below you could use @include border-radius($radius, $vertical-radius) - border-radius: 100%; - bottom: 0; - content: ""; - height: 6px; - left: -3px; - position: absolute; - width: 6px; - } - - .sl-content { - i { - font-size: 12px; - } - - small { - position: relative; - top: -4px; - } - - p { - padding-bottom: 4px; - position: relative; - } - } -} - -.sl-item::before { - background-color: #13b1e0; - border-radius: 100%; - content: ""; - height: 12px; - left: -6.5px; - position: absolute; - top: 0; - width: 12px; -} - -.sl-primary { - border-left-color: #2196f3; - - &:last-child::after { - background-color: #2196f3; - } -} - -.sl-primary::before { - background-color: #2196f3; -} - -.sl-danger { - border-left-color: #f44336; - - &:last-child::after { - background-color: #f44336; - } -} - -.sl-danger::before { - background-color: #f44336; -} - -.sl-success { - border-left-color: #4caf50; - - &:last-child::after { - background-color: #4caf50; - } -} - -.sl-success::before { - background-color: #4caf50; -} - -.sl-warning { - border-left-color: #ff5722; - - &:last-child::after { - background-color: #ff5722; - } -} - -.sl-warning::before { - background-color: #ff5722; -} diff --git a/MyOffice.SPA/src/assets/scss/components/_formcomponents.scss b/MyOffice.SPA/src/assets/scss/components/_formcomponents.scss deleted file mode 100644 index 365fb1d..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_formcomponents.scss +++ /dev/null @@ -1,59 +0,0 @@ -.example-form { - min-width: 150px; - max-width: 500px; - width: 100%; -} - -.example-full-width { - width: 100%; -} -.example-h2 { - margin: 10px; -} - -.example-section { - display: flex; - align-content: center; - align-items: center; - height: 60px; -} - -.example-margin { - margin: 0 10px; -} - -.example-radio-group { - display: flex; - flex-direction: column; - margin: 15px 0; -} - -.example-radio-button { - margin: 5px; -} - -.advance-validation .error-msg { - margin-top: -15px; -} -.mat-radio-button ~ .mat-radio-button { - margin-left: 16px; -} -.mat-radio-label { - margin-bottom: 0px; -} -.mat-datepicker-content-touch .mat-calendar { - width: 50vh !important; - height: 57vh !important; -} -.mat-datepicker-toggle-default-icon { - width: 1.4em !important; -} -.mat-form-field { - .date-icon { - cursor: pointer; - } -} -.mat-form-field-prefix, -.mat-form-field-suffix { - color: rgba(0, 0, 0, 0.54); -} diff --git a/MyOffice.SPA/src/assets/scss/components/_infobox.scss b/MyOffice.SPA/src/assets/scss/components/_infobox.scss deleted file mode 100644 index 188ac5e..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_infobox.scss +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Document : _infobox.scss - * Author : RedStar Template - * Description: This scss file for info box style classes - */ -.info-box { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; - - .icon { - display: inline-block; - text-align: center; - background-color: rgba(0, 0, 0, 0.12); - width: 80px; - - i { - color: #fff; - font-size: 50px; - line-height: 80px; - } - - .chart.chart-bar { - height: 100%; - line-height: 100px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-pie { - height: 100%; - line-height: 123px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-line { - height: 100%; - line-height: 115px; - - canvas { - vertical-align: baseline !important; - } - } - } - - .content { - display: inline-block; - padding: 7px 10px; - - .text { - font-size: 13px; - margin-top: 11px; - color: #555; - } - - .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; - } - } -} - -.info-box.hover-zoom-effect { - .icon { - overflow: hidden; - - i { - @include transition(all 0.3s ease); - } - } - - &:hover { - .icon { - i { - opacity: 0.4; - @include transform(rotate(-32deg) scale(1.4)); - } - } - } -} - -.info-box.hover-expand-effect { - &:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 80px; - top: 0; - width: 0; - height: 100%; - color: transparent; - @include transition(all 0.95s); - } - - &:hover { - &:after { - width: 100%; - } - } -} - -.info-box-2 { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; - - .icon { - display: inline-block; - text-align: center; - width: 80px; - - i { - color: #fff; - font-size: 50px; - line-height: 80px; - } - } - - .chart.chart-bar { - height: 100%; - line-height: 105px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-pie { - height: 100%; - line-height: 123px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-line { - height: 100%; - line-height: 115px; - - canvas { - vertical-align: baseline !important; - } - } - - .content { - display: inline-block; - padding: 7px 10px; - - .text { - font-size: 13px; - margin-top: 11px; - color: #555; - } - - .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; - } - } -} - -.info-box-2.hover-zoom-effect { - .icon { - overflow: hidden; - - i { - @include transition(all 0.3s ease); - } - } - - &:hover { - .icon { - i { - opacity: 0.4; - @include transform(rotate(-32deg) scale(1.4)); - } - } - } -} - -.info-box-2.hover-expand-effect { - &:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 0; - top: 0; - width: 0; - height: 100%; - color: transparent; - @include transition(all 0.95s); - } - - &:hover { - &:after { - width: 100%; - } - } -} - -.info-box-3 { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; - - .icon { - position: absolute; - right: 10px; - bottom: 2px; - text-align: center; - - i { - color: rgba(0, 0, 0, 0.15); - font-size: 60px; - } - } - - .chart { - margin-right: 5px; - } - - .chart.chart-bar { - height: 100%; - line-height: 50px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-pie { - height: 100%; - line-height: 34px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-line { - height: 100%; - line-height: 40px; - - canvas { - vertical-align: baseline !important; - } - } - - .content { - display: inline-block; - padding: 7px 16px; - - .text { - font-size: 13px; - margin-top: 11px; - color: #555; - } - - .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; - } - } -} - -.info-box-3.hover-zoom-effect { - .icon { - i { - @include transition(all 0.3s ease); - } - } - - &:hover { - .icon { - i { - opacity: 0.4; - @include transform(rotate(-32deg) scale(1.4)); - } - } - } -} - -.info-box-3.hover-expand-effect { - &:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 0; - top: 0; - width: 0; - height: 100%; - color: transparent; - @include transition(all 0.95s); - } - - &:hover { - &:after { - width: 100%; - } - } -} - -.info-box-4 { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; - - .icon { - position: absolute; - right: 10px; - bottom: 2px; - text-align: center; - - i { - color: rgba(0, 0, 0, 0.15); - font-size: 60px; - } - } - - .chart { - margin-right: 5px; - } - - .chart.chart-bar { - height: 100%; - line-height: 50px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-pie { - height: 100%; - line-height: 34px; - - canvas { - vertical-align: baseline !important; - } - } - - .chart.chart-line { - height: 100%; - line-height: 40px; - - canvas { - vertical-align: baseline !important; - } - } - - .content { - display: inline-block; - padding: 7px 16px; - - .text { - font-size: 13px; - margin-top: 11px; - color: #555; - } - - .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; - } - } -} - -.info-box-4.hover-zoom-effect { - .icon { - i { - @include transition(all 0.3s ease); - } - } - - &:hover { - .icon { - i { - opacity: 0.4; - @include transform(rotate(-32deg) scale(1.4)); - } - } - } -} - -.info-box-4.hover-expand-effect { - &:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 0; - top: 0; - width: 0; - height: 100%; - color: transparent; - @include transition(all 0.95s); - } - - &:hover { - &:after { - width: 100%; - } - } -} -.info-box-new { - background: #fff; - padding: 20px 20px 0px 20px; - color: #463f3f; - border-radius: 15px; - - .progress { - height: 10px; - border-radius: 20px; - } -} -.support-box { - padding: 15px; - color: #fff; - margin: 8px 0px 25px 0px; - border-radius: 10px; - min-height: 140px; -} -.counter-box { - padding: 15px; - color: #212529; - margin: 8px 0px 25px 0px; - border-radius: 10px; - min-height: 140px; - background-color: #ffffff; - box-shadow: 0 5px 25px rgba(0, 0, 0, 0.1); -} -.info-box1 .text-end h2 { - color: #44e229; -} -.info-box2 .text-end h2 { - color: #e66c2f; -} -.info-box3 .text-end h2 { - color: #58b5f5; -} -.info-box4 .text-end h2 { - color: #ab92d4; -} - -.info-box5 { - width: 100%; - box-shadow: 0 5px 25px rgba(0, 0, 0, 0.1); - margin-bottom: 25px; - padding: 0px 20px 0 20px; - border-radius: 25px; - height: 110px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - small { - font-size: 14px; - } - .progress { - background: rgba(0, 0, 0, 0.2); - margin: 5px -10px 5px 0; - height: 8px; - background: #e3e3e3; - border-radius: 20px; - box-shadow: none; - overflow: visible; - .progress-bar { - border-radius: 20px; - background: #fff; - } - } - .knob-icon { - margin-top: 16px; - } - .info-box-content { - margin-top: 24px; - margin-left: 10px; - } - .progress-bar { - position: relative; - animation: animate-positive 4s; - line-height: 8px; - } -} -.info-box6 { - box-shadow: 2px 2px 10px #dadada; - margin: 8px 0px 25px 0px; - padding: 20px 10px; - background-color: #fff; - height: 100px; - border-radius: 5px; - transition: 0.3s linear all; - &:hover { - //Instead of the line below you could use @include box-shadow($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10) - box-shadow: 4px 4px 20px #dadada; - //Instead of the line below you could use @include transition($transition-1, $transition-2, $transition-3, $transition-4, $transition-5, $transition-6, $transition-7, $transition-8, $transition-9, $transition-10) - transition: 0.3s linear all; - } - &.primary { - background-color: #007bff; - color: #fff; - } - &.danger { - background-color: #ef5350; - color: #fff; - } - &.success { - background-color: #66bb6a; - color: #fff; - } - &.info { - background-color: #26c6da; - color: #fff; - } - i { - font-size: 5em; - opacity: 0.2; - } - .count-numbers { - position: absolute; - right: 35px; - top: 20px; - font-size: 32px; - display: block; - } - .count-name { - position: absolute; - right: 35px; - top: 65px; - font-style: italic; - text-transform: capitalize; - opacity: 0.5; - display: block; - font-size: 18px; - } -} -.bg-c-blue { - background: linear-gradient(to right, #5b73e8, #44c4fa); -} -.bg-c-green { - background: linear-gradient(to right, #1d976c, #2fd38a); -} -.bg-c-yellow { - background: linear-gradient(45deg, #ffb64d, #ffcb80); -} -.bg-c-pink { - background: linear-gradient(45deg, #ff5370, #ff869a); -} -.bg-c-purple { - background: linear-gradient(to right, #664dc9, #9884ea); -} -.bg-c-orange { - background: linear-gradient(to right, #fa5420, #f6a800); -} -.info-box7 { - border-radius: 5px; - color: #fff; - box-shadow: 0 1px 2.94px 0.06px rgba(4, 26, 55, 0.16); - border: none; - margin: 8px 0px 25px 0px; - transition: all 0.3s ease-in-out; - .info-box7-block { - padding: 25px; - } -} -.order-info-box7 i { - font-size: 30px; -} -.box-part { - background: #fff; - border-radius: 10px; - padding: 30px 15px; - margin: 5px 0 23px; -} -.box-part { - background: #fff; - border-radius: 10px; - padding: 30px 15px; - margin: 5px 0 23px; -} -.infobox-5 { - .card-icon { - i { - font-size: 4rem; - } - } -} -.card-statistic-4 { - position: relative; - color: #000000; - padding: 15px; - border-radius: 3px; - overflow: hidden; - - .card-icon-large { - font-size: 110px; - width: 110px; - height: 50px; - text-shadow: 3px 7px rgba(0, 0, 0, 0.3); - } - - .card-icon { - text-align: center; - line-height: 50px; - margin-left: 15px; - color: #000; - position: absolute; - right: -5px; - top: 20px; - opacity: 0.1; - } - - .banner-img img { - max-width: 100%; - float: right; - } -} - -.info-card { - margin-top: 20px; - text-align: right; - - .info-box8 { - padding: 15px 20px; - } - .card1-icon { - width: 50px; - height: 50px; - position: absolute; - top: -15px; - font-size: 35px; - border-radius: 8px; - display: flex; - color: #fff; - align-items: center; - justify-content: center; - transition: all 0.3s ease-in-out; - } - .card-block > span { - color: #919aa3; - } - :hover .card1-icon { - top: -25px; - } -} - -@-webkit-keyframes animate-positive { - 0% { - width: 0; - } -} -@keyframes animate-positive { - 0% { - width: 0; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_inputformgroup.scss b/MyOffice.SPA/src/assets/scss/components/_inputformgroup.scss deleted file mode 100644 index 1baa625..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_inputformgroup.scss +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Document : _inputformgroup.scss - * Author : RedStar Template - * Description: This scss file for input form style classes - */ -%extend_check { - font-size: 13px; - line-height: 1.42857; - color: #414244; - font-weight: 400; -} - -.input-group { - width: 100%; - margin-bottom: 20px; - display: table; - - .form-line { - display: inline-block; - width: 100%; - //border-bottom: 1px solid #ddd; - position: relative; - - &:after { - content: ""; - position: absolute; - left: 0; - width: 100%; - bottom: 0px; - @include transform(scaleX(0)); - @include transition(0.25s ease-in); - border-bottom: 2px solid #1f91f3; - } - - +.input-group-addon { - padding-right: 0; - padding-left: 10px; - } - } - - .help-info { - float: right; - font-size: 12px; - margin-top: 5px; - color: #999; - } - - label.error { - font-size: 12px; - display: block; - margin-top: 5px; - font-weight: normal; - color: #f44336; - } - - .form-line.error { - &:after { - border-bottom: 2px solid #f44336; - } - } - - .form-line.success { - &:after { - border-bottom: 2px solid #4caf50; - } - } - - .form-line.warning { - &:after { - border-bottom: 2px solid #ffc107; - } - } - - .form-line.focused { - &:after { - @include transform(scaleX(1)); - } - - .form-label { - bottom: 25px; - left: 0; - font-size: 12px; - } - } - - .input-group-addon { - border: none; - background-color: transparent; - padding-left: 0; - font-weight: bold; - display: table-cell; - - .material-icons { - font-size: 18px; - color: #555; - } - } - - input[type="text"], - .form-control { - //border: none; - box-shadow: none; - padding-left: 0; - margin: 0; - font-size: 13px; - } - - .form-control { - &:focus { - @include box-shadow(none !important); - } - } -} - -.input-group.input-group-sm { - .input-group-addon { - i { - font-size: 14px; - } - } - - .form-control { - font-size: 12px !important; - } -} - -.input-group.input-group-lg { - .input-group-addon { - i { - font-size: 26px; - } - } - - .form-control { - font-size: 18px !important; - } -} - -.input-field { - >label:not(.label-icon).active { - font-size: 15px !important; - transform: translateY(-5px) scale(0.8); - } - - input, - textarea { - font-size: 13px !important; - } - - >label { - font-size: 13px !important; - } -} - -.form-control-label { - text-align: right; - - label { - margin-top: 8px; - } -} - -.form-horizontal { - .form-group { - margin-bottom: 0; - } -} - -.form-group { - width: 100%; - margin-bottom: 25px; - - .form-control { - width: 100%; - /* border: none; */ - box-shadow: none; - /* border-bottom: 1px solid #9e9e9e;*/ - @include border-radius(0); - padding-left: 0; - } - - input.form-control { - margin: 0; - font-size: 13px; - } - - .help-info { - float: right; - font-size: 12px; - margin-top: 5px; - color: #999; - } - - label.error { - font-size: 12px; - display: block; - margin-top: 5px; - font-weight: normal; - color: #f44336; - } - - .form-line { - width: 100%; - position: relative; - //border-bottom: 1px solid #ddd; - - &:after { - content: ""; - position: absolute; - left: 0; - width: 100%; - height: 0; - bottom: -1px; - @include transform(scaleX(0)); - @include transition(0.25s ease-in); - border-bottom: 2px solid #1f91f3; - } - - .form-label { - font-weight: normal; - color: #aaa; - position: absolute; - top: 10px; - left: 0; - cursor: text; - @include transition(0.2s); - } - } - - .form-line.error { - &:after { - border-bottom: 2px solid #f44336; - } - } - - .form-line.success { - &:after { - border-bottom: 2px solid #4caf50; - } - } - - .form-line.warning { - &:after { - border-bottom: 2px solid #ffc107; - } - } - - .form-line.focused { - &:after { - @include transform(scaleX(1)); - } - - .form-label { - top: -10px; - left: 0; - font-size: 12px; - } - } -} - -.form-group-sm { - .form-label { - font-size: 12px; - } - - .form-line.focused { - .form-label { - bottom: 20px; - font-size: 10px; - } - } -} - -.form-group-lg { - .form-label { - font-size: 18px; - } - - .form-line.focused { - .form-label { - bottom: 35px; - font-size: 12px; - } - } -} - -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - background-color: transparent; -} - -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px dashed; - border-top: 4px solid \9; - border-right: 4px solid transparent; - border-left: 4px solid transparent; -} - -.show>.dropdown-menu { - display: block; -} - -.spinner { - .input-group-addon { - /*position: relative;*/ - position: absolute; - top: 10px; - right: 0; - - .spin-up i { - position: absolute; - left: 0; - } - - .spin-down i { - position: absolute; - left: 0; - bottom: -15px; - } - } -} - -.bootstrap-select { - .btn { - color: #333; - } -} - -.input-group-addon, -.input-group-btn, -.input-group .form-control { - display: table-cell; -} - -.form-check { - @extend %extend_check; - margin-bottom: 0.5rem; - padding-left: 0; - - .form-check-label { - cursor: pointer; - padding-left: 25px; - position: relative; - padding-right: 15px; - - span { - display: block; - position: absolute; - left: -1px; - top: -1px; - transition-duration: 0.2s; - padding-left: 0; - } - } - - .form-check-input { - opacity: 0; - height: 0; - width: 0; - overflow: hidden; - position: absolute; - margin: 0; - z-index: -1; - left: 0; - pointer-events: none; - - &:checked+.form-check-sign { - &:before { - animation: rippleOn 0.5s; - } - - .check { - background: #9c27b0; - - &:before { - color: #ffffff; - box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, - 0 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; - animation: checkboxOn 0.3s forwards; - } - } - } - } - - .form-check-sign { - vertical-align: middle; - position: relative; - top: -2px; - float: left; - padding-right: 10px; - display: inline-block; - - &:before { - display: block; - position: absolute; - left: 0; - content: ""; - background-color: rgba(0, 0, 0, 0.84); - height: 20px; - width: 20px; - border-radius: 100%; - z-index: 1; - opacity: 0; - margin: 0; - top: 0; - transform: scale3d(2.3, 2.3, 1); - } - - .check { - position: relative; - display: inline-block; - width: 20px; - height: 20px; - border: 1px solid rgba(0, 0, 0, 0.54); - overflow: hidden; - z-index: 1; - border-radius: 3px; - - &:before { - position: absolute; - content: ""; - transform: rotate(45deg); - display: block; - margin-top: -3px; - margin-left: 7px; - width: 0; - color: #ffffff; - height: 0; - animation: checkboxOff 0.3s forwards; - } - } - } -} - -label { - @extend %extend_check; -} - -.default-select { - select { - width: 100px; - -moz-appearance: none; - -webkit-appearance: none; - appearance: none; - } - - .select-wrapper input.select-dropdown { - display: none; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_labels.scss b/MyOffice.SPA/src/assets/scss/components/_labels.scss deleted file mode 100644 index 8a2f508..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_labels.scss +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Document : _labels.scss - * Author : RedStar Template - * Description: This scss file for label style classes - */ -.label { - @include border-radius(10px); - padding: 2px 10px; - color: #fff; - display: inline-block; -} - -.label-default { - background-color: #777; -} - -.label-primary { - background-color: #1f91f3; -} - -.label-success { - background-color: #2b982b; -} - -.label-info { - background-color: #00b0e4; -} - -.label-warning { - background-color: #ff9600; -} - -.label-danger { - background-color: #fb483a; -} diff --git a/MyOffice.SPA/src/assets/scss/components/_leftsidebaroverlay.scss b/MyOffice.SPA/src/assets/scss/components/_leftsidebaroverlay.scss deleted file mode 100644 index 3d898e0..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_leftsidebaroverlay.scss +++ /dev/null @@ -1,952 +0,0 @@ -/* - * Document : _leftsidebaroverlay.scss - * Author : RedStar Template - * Description: This scss file for left side bar style classes - */ -.overlay { - position: fixed; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - z-index: 10; -} - -.overlay-open { - .sidebar { - margin-left: 0; - z-index: 99999999; - } -} - -.sidebar { - @include transition(all 0.5s); - font-family: $sidebar-font-family; - background: #ffffff; - width: 260px; - overflow: hidden; - display: inline-block; - height: calc(100vh - 0px); - position: fixed; - top: 0px; - left: 0; - border-right: 1px solid #f2f4f9; - -webkit-box-shadow: 0 8px 10px 0 rgba(183, 192, 206, 0.2); - box-shadow: 0 8px 10px 0 rgba(183, 192, 206, 0.2); - z-index: 999 !important; - - .user-info { - padding: 13px 15px 12px 15px; - white-space: nowrap; - position: relative; - border-bottom: 1px solid #e9e9e9; - height: 135px; - - .image { - margin-right: 12px; - display: inline-block; - - img { - @include border-radius(50%); - vertical-align: bottom !important; - } - } - - .info-container { - cursor: default; - display: block; - position: relative; - top: 25px; - - .name { - @include three-dots-overflow(); - font-size: 14px; - max-width: 200px; - color: #fff; - } - - .email { - @include three-dots-overflow(); - font-size: 12px; - max-width: 200px; - color: #fff; - } - - .user-helper-dropdown { - position: absolute; - right: -3px; - bottom: -12px; - @include box-shadow(none); - cursor: pointer; - color: #fff; - } - } - } - - .menu { - position: relative; - overflow-y: auto; - height: 100vh; - clear: left; - - .list { - list-style: none; - padding-left: 0; - - li { - &.active { - .menu-top { - background-color: #f0f3fb; - border-radius: 5px; - } - > :first-child { - span { - font-weight: 500; - } - } - } - &.active-top { - .menu-top { - background-color: #f0f3fb; - } - } - } - - .header { - font-size: 12px; - margin: 15px 0px 5px 23px; - text-transform: uppercase; - letter-spacing: 0.5px; - color: #000000; - } - - i.material-icons { - font-size: 15px; - } - - i.fas { - font-size: 15px; - } - - i.far { - font-size: 15px; - } - - i.fab { - font-size: 15px; - } - - i.fa { - font-size: 15px; - } - - .tooltips .sidebarQuickIcon { - font-size: 18px; - margin-top: 10px; - } - - .active { - .menu-toggle { - background: rgba(146, 144, 144, 0.28); - } - - .ml-menu { - display: block; - } - .ml-sub-menu { - display: block; - } - .ml-sub-menu2 { - display: block; - } - .ml-sub-menu3 { - display: block; - } - } - - .menu-toggle { - &:after, - &:before { - position: absolute; - top: calc(50% - 13px); - right: 17px; - font-size: 19px; - @include transform(scale(0)); - @include transition(all 0.3s); - } - - &:before { - content: "\f054"; - transform: scale(1); - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - @include transform(scale(1)); - } - - &:after { - content: "\f078"; - transform: scale(1); - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - @include transform(scale(0)); - } - } - - .material-icons-two-tone { - vertical-align: middle; - filter: invert(43%) sepia(4%) saturate(19%) hue-rotate(342deg) - brightness(94%) contrast(88%); - } - - .active .menu-toggle { - &:before { - @include transform(scale(0)); - } - - &:after { - @include transform(scale(1)); - } - } - - .ml-sub-menu { - &:after, - &:before { - position: absolute; - top: calc(50% - 13px); - right: 17px; - font-size: 19px; - @include transition(all 0.3s); - } - - &:before { - content: "\f054"; - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - // @include transform(scale(1)); - } - - &:after { - content: "\f078"; - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - // content: "\2013"; - // @include transform(scale(0)); - } - } - .ml-sub-menu2 { - &:after, - &:before { - position: absolute; - top: calc(50% - 13px); - right: 17px; - font-size: 19px; - // @include transform(scale(0)); - @include transition(all 0.3s); - } - - &:before { - content: "\f054"; - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - // @include transform(scale(1)); - } - - &:after { - content: "\f078"; - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - // @include transform(scale(0)); - } - } - .ml-sub-menu3 { - &:after, - &:before { - position: absolute; - top: calc(50% - 13px); - right: 17px; - font-size: 19px; - // @include transform(scale(0)); - @include transition(all 0.3s); - } - - &:before { - content: "\f054"; - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - // @include transform(scale(1)); - } - - &:after { - content: "\f078"; - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - // @include transform(scale(0)); - } - } - - a { - color: #000000; - position: relative; - font-size: 15px !important; - display: block; - overflow: hidden; - line-height: 2rem; - padding: 9px 9px 9px 9px; - margin: 8px 11px 0px 11px; - // Parent items (menu-toggle) have no routerLink/href — force pointer on hover. - cursor: pointer; - &:hover, - &:active { - text-decoration: none !important; - background-color: #f0f3fb; - } - - small { - position: absolute; - top: calc(50% - 7.5px); - right: 15px; - } - - span { - margin: 7px 0 7px 7px; - color: rgba(0, 0, 0, 0.85); - // font-weight: bold; - font-size: 16px; - overflow: hidden; - } - } - - .ml-menu { - list-style: none; - display: none; - padding-left: 0; - - span { - font-weight: normal; - font-size: 14px; - margin: 3px 0 1px 6px; - } - - li { - a { - padding-left: 40px; - padding-top: 4px; - padding-bottom: 4px; - } - - &.active { - a.toggled:not(.menu-toggle) { - &:before { - content: ""; - display: block; - width: 7px; - height: 7px; - border-radius: 50%; - position: absolute; - left: 18%; - top: 50%; - transform: translate(-10px, -50%); - opacity: 1; - transition: all 0.2s ease; - } - } - - .ml-menu { - &:before { - content: "\f105"; - font-family: "Font Awesome 5 Free"; - font-size: 13px; - display: block; - width: 7px; - height: 7px; - position: absolute; - transition: 0.5s; - left: 6%; - font-weight: 900; - top: calc(50% - 15px); - } - // &:hover:before { - // font-weight: 600; - // left: 25px; - // } - } - .ml-menu-2 { - display: block; - } - .ml-menu { - color: #5668f3; - font-weight: 500; - } - .ml-sub-sub-menu { - color: #5668f3; - font-weight: 500; - } - } - a { - &.ml-sub-sub-menu { - &:before { - content: "\f105"; - font-family: "Font Awesome 5 Free"; - font-size: 13px; - display: block; - width: 7px; - height: 7px; - position: absolute; - transition: 0.5s; - left: 18%; - font-weight: 900; - top: calc(50% - 15px); - } - &:hover:before { - font-weight: 600; - left: 50px; - } - } - } - - .ml-menu { - li { - a { - padding-left: 80px; - } - } - - .ml-menu { - li { - a { - padding-left: 95px; - } - } - } - } - } - .activeSub { - .ml-menu-2 { - display: block; - } - .ml-menu-3 { - display: block; - } - } - } - .ml-menu-2 { - list-style: none; - display: none; - padding-left: 0; - - span { - font-weight: normal; - font-size: 14px; - margin: 3px 0 1px 6px; - } - - li { - a { - padding-left: 55px; - padding-top: 4px; - padding-bottom: 4px; - } - } - li.active .ml-menu-3 { - display: block; - } - li.active .ml-menu2:before { - content: "\f105"; - font-family: "Font Awesome 5 Free"; - font-size: 13px; - display: block; - width: 7px; - height: 7px; - position: absolute; - left: 17%; - font-weight: 900; - top: calc(50% - 15px); - } - } - .ml-menu-3 { - list-style: none; - display: none; - padding-left: 0; - - span { - font-weight: normal; - font-size: 14px; - margin: 3px 0 1px 6px; - } - - li { - a { - padding-left: 70px; - padding-top: 4px; - padding-bottom: 4px; - } - } - li.active .ml-menu3:before { - content: "\f105"; - font-family: "Font Awesome 5 Free"; - font-size: 13px; - display: block; - width: 7px; - height: 7px; - position: absolute; - left: 24%; - font-weight: 900; - top: calc(50% - 15px); - } - } - } - } - .sidebar-badge { - position: absolute; - right: 35px; - padding: 3px 6px; - margin-top: 5px !important; - border-radius: 15px; - color: #ffffff !important; - font-size: 12px !important; - border: none; - font-weight: 300 !important; - } -} -.ml-menu { - .ml-sub-menu { - &:before { - @include transform(scale(1)); - } - &:after { - @include transform(scale(0)); - } - } - - .ml-sub-menu2 { - &:before { - @include transform(scale(1)); - } - &:after { - @include transform(scale(0)); - } - } - - .ml-sub-menu3 { - &:before { - @include transform(scale(1)); - } - &:after { - @include transform(scale(0)); - } - } - - .active .ml-sub-menu { - &:after { - @include transform(scale(1)); - } - - &:before { - @include transform(scale(0)); - } - } - - .ml-menu-2 { - li.active .ml-sub-menu2 { - &:after { - @include transform(scale(1)); - } - - &:before { - @include transform(scale(0)); - } - } - } - - .ml-menu-3 { - li.active .ml-sub-menu3 { - &:after { - @include transform(scale(1)); - } - - &:before { - @include transform(scale(0)); - } - } - } -} -.right-sidebar { - width: 280px; - height: calc(100vh - 60px); - position: fixed; - right: -300px; - top: 60px; - background: #fdfdfd; - z-index: 999 !important; - @include box-shadow(-2px 2px 5px rgba(0, 0, 0, 0.1)); - overflow: hidden; - @include transition(0.5s); - - &.open { - right: 0; - } - - .nav-tabs { - font-weight: 600; - font-size: 13px; - width: 100%; - margin-left: 2px; - - li { - text-align: center; - - > a { - margin-right: 0; - } - - &:first-child { - width: 45%; - } - - &:last-child { - width: 55%; - } - } - } - - .rightSidebarClose { - position: absolute; - top: 8px; - left: 8px; - z-index: 99; - cursor: pointer; - } -} - -.boxed-layout { - .sidebar { - left: auto; - } - - &.side-closed .sidebar { - left: 0; - } -} - -.horizontal-menu { - width: 100%; - text-align: center; -} - -.top-sidebar { - float: left; - width: 100%; - position: fixed; - z-index: 9; - top: 60px; - background-color: #ffffff; - -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -ms-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - - ul.horizontal-list { - overflow: visible !important; - margin: 0; - display: inline-block; - height: 60px; - - a { - color: #747474; - float: left; - width: 100%; - } - - li { - float: left; - position: relative; - padding: 20px 20px; - - &:hover > ul { - display: block !important; - position: absolute; - top: 63px; - background-color: #fff; - border-radius: 5px; - z-index: 9; - -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -ms-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - - &:after { - position: absolute; - bottom: 100%; - left: 1.8rem; - width: 0; - height: 0; - margin-left: -16px; - content: " "; - pointer-events: none; - border: solid transparent; - border-width: 9px; - border-color: rgba(136, 183, 213, 0); - border-bottom-color: #fff; - } - - &:before { - position: absolute; - bottom: 100%; - left: 1.8rem; - width: 0; - height: 0; - margin-left: -16px; - content: " "; - pointer-events: none; - border: solid transparent; - border-width: 9px; - border-color: rgba(136, 183, 213, 0); - border-bottom-color: #ad5454; - } - - &.mega-ml-menu { - position: relative; - top: 0; - } - } - - ul li { - width: 100%; - padding: 10px 15px; - text-align: left; - } - } - - ul.ml-menu { - display: none !important; - width: 200px; - - li:hover ul { - top: 0; - left: 100%; - } - - .menu-toggle { - position: relative; - - &:after { - content: "\2023"; - position: absolute; - right: 0; - font-size: 25px; - top: 0; - line-height: 22px; - } - } - } - - i.material-icons { - margin-top: 1px; - margin-right: 3px; - float: left; - font-size: 20px; - } - - // .menu-toggle::after{ - // content: "\2304"; - // position: absolute; - // top: 15px; - // right: 0; - // } - } - - .slimScrollDiv { - overflow: visible !important; - } -} - -// Dark left sidebar style -.menu_dark .sidebar { - background: #1a202e; - border-right: 1px solid #2f3a44; - font-weight: 500; - - .menu .list { - a { - color: #cfd8e3; - span { - color: #cfd8e3; - } - } - - a:hover { - background-color: rgba(0, 0, 0, 0.2); - } - - .header { - background: transparent; - color: #9babf1; - font-size: 12px; - margin: 15px 0px 5px 23px; - text-transform: uppercase; - letter-spacing: 0.5px; - } - - .active { - .menu-toggle { - background-color: rgba(0, 0, 0, 0.4); - } - } - - .menu-toggle::after { - color: #b8babb; - } - - .menu-toggle::before { - color: #b8babb; - } - - .material-icons-two-tone { - filter: invert(86%) sepia(3%) saturate(2995%) hue-rotate(185deg) - brightness(79%) contrast(78%); - } - - .ml-menu { - li a { - color: #dadada; - } - } - - li { - &.active { - .menu-top { - background-color: rgba(0, 0, 0, 0.4); - } - } - &.active-top { - .menu-top { - background-color: rgba(0, 0, 0, 0.4); - } - } - } - } - - .menu .list .ml-menu .active a::before { - content: "\f105"; - font-family: "Font Awesome 5 Free"; - font-size: 13px; - display: block; - width: 7px; - height: 7px; - position: absolute; - left: 10%; - font-weight: 900; - } -} - -.menu_dark { - .sidebar-userpic-name { - color: #e6e6e6; - } - - .profile-usertitle-job { - color: #e6e6e6; - } -} - -.user-panel { - float: left; - width: 100%; - color: #ccc; - padding: 25px 0px 10px 0; - .image { - width: 35%; - max-width: 75px; - margin: 0 auto; - - img { - max-width: 100%; - } - } -} - -.user-img-circle { - background: #fff; - z-index: 1000; - position: inherit; - box-shadow: 10px 10px 13px 0px rgba(78, 78, 78, 0.15); -} - -.img-circle { - border-radius: 15%; -} - -.profile-usertitle { - text-align: center; - color: #060606; -} - -.profile-usertitle-job { - font-size: 11px; - color: #000000; -} - -.sidebar-userpic-btn { - display: flex; - place-content: space-around; - margin: auto; - line-height: 2rem; - padding: 9px 9px 9px 9px; - margin: 8px 13px 0px 13px; - - a { - padding: 0px !important; - margin: 0px !important; - height: 30px; - width: 30px; - - &:hover { - cursor: pointer; - } - - .mat-button-wrapper { - margin-left: 0px !important; - } - - &:hover { - background-color: transparent !important; - } - } -} - -.collapse.in { - display: block; - list-style-type: none; -} -.sidebarIcon { - height: 18px !important; - width: 18px !important; - text-align: center; - fill: rgba(75, 75, 90, 0.12) !important; -} -.headerShadow { - width: 100%; - height: 100px; - position: fixed; - top: 0; - z-index: 1; - background: linear-gradient(180deg, #f8f8f8e6 44%, #f7f7f780 73%, #ffffff00); -} diff --git a/MyOffice.SPA/src/assets/scss/components/_navbar.scss b/MyOffice.SPA/src/assets/scss/components/_navbar.scss deleted file mode 100644 index 35ed72f..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_navbar.scss +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Document : _navbar.scss - * Author : RedStar Template - * Description: This scss file for navbar style classes - */ -.navbar { - font-family: $navbar-font-family; - @include border-radius(0); - box-shadow: none; - // @include box-shadow(0px 0px 20px 0px rgba(0,0,0,0.15)); - border: none; - position: fixed; - top: 0; - left: 0; - z-index: 999; - width: 100%; - padding: 0; - - .navbar-brand { - @include three-dots-overflow(); - } - - .navbar-custom-right-menu { - float: right; - } - - .navbar-toggle { - text-decoration: none; - color: #fff; - width: 20px; - height: 20px; - margin-top: -7px; - line-height: 60px; - margin-right: 17px; - - &:before { - content: "\E8D5"; - font-family: "Material Icons"; - font-size: 26px; - } - } - - .navbar-collapse { - &.in { - overflow: visible; - } - } - .nav.navbar-nav { - display: block; - } - .container-fluid, - .container { - display: block; - box-shadow: 0 4px 24px 0 rgb(35 42 48 / 10%); - } - .dropdown-menu ul.menu li { - width: 100%; - } - .nav-left-menu { - margin: 3px 15px; - } - .collapse-menu-icon { - margin-bottom: 0px; - line-height: 60px; - display: none; - } - .header-icon { - vertical-align: top !important; - .feather { - height: 20px; - width: 20px; - } - } -} -.ls-closed { - .sidebar { - margin-left: -300px; - } - - section.content { - margin-left: 15px; - } - - .bars { - &:after, - &:before { - font-family: "Material Icons"; - font-size: 24px; - position: absolute; - left: 10px; - top: 0px; - line-height: 60px; - margin-right: 10px; - @include transform(scale(0)); - @include transition(all 0.3s); - } - - &:before { - content: "\E5D2"; - @include transform(scale(1)); - } - - // &:after { - // content: "\E5C4"; - // @include transform(scale(0)); - // } - } - - .navbar-brand { - margin-left: 30px; - } -} - -.overlay-open { - .bars { - &:before { - @include transform(scale(0)); - } - - &:after { - @include transform(scale(1)); - } - } - &.ls-closed { - .sidebar { - margin-left: 0; - } - } -} - -.navbar-header { - padding: 8px; - background-color: #000; - width: 260px; - float: left; - @include transition(all 0.5s); - - .bars { - float: left; - text-decoration: none; - } -} -.navbar-icon { - list-style-type: none; - padding-left: 20px; -} -.logo-name { - color: white; - font-size: 24px; - font-weight: 400; -} -.navbar-nav { - > li { - > a { - padding: 7px 7px 2px 7px; - } - .js-right-sidebar { - margin-right: 5px; - } - } - &.navbar-left { - margin-right: 10px; - line-height: 60px; - } - - &.navbar-right { - float: right !important; - margin-right: 10px; - line-height: 60px; - // .nav-item { - // margin: 0px 4px; - // } - - .user_profile { - .dropdown-toggle { - cursor: pointer; - } - .user_img { - float: right; - margin: 13px 0px 0px 10px; - border-radius: 50%; - } - span { - font-weight: 500; - color: #fff; - } - } - } - .langSelItem .dropdown-menu { - margin-top: 35px !important; - } - - .app-dropdown { - right: unset !important; - left: 0 !important; - &::before { - left: 19px !important; - right: unset !important; - } - &::after { - left: 20px !important; - right: unset !important; - } - } - .dropdown-menu { - margin-top: 60px !important; - width: 325px; - right: 0; - left: auto; - position: absolute !important; - top: 0; - padding: 0; - border-radius: 5px; - &::before { - content: ""; - position: absolute; - top: -7px; - right: 19px; - display: inline-block !important; - border-right: 7px solid transparent; - border-bottom: 7px solid #eee; - border-left: 7px solid transparent; - border-bottom-color: rgba(0, 0, 0, 0.2); - } - &::after { - content: ""; - position: absolute; - top: -6px; - right: 20px; - display: inline-block !important; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - border-left: 6px solid transparent; - } - ul.menu .menu-info p { - line-height: 1; - .material-icons { - display: inline-block; - } - } - li.footer { - width: 100%; - height: 45px; - } - .header { - line-height: 2; - } - } - .material-icons { - line-height: 1; - height: 24px; - font-size: 27px; - } - .fas { - line-height: 1; - height: 24px; - font-size: 18px; - } - .far { - line-height: 1; - height: 24px; - font-size: 18px; - } - .fab { - line-height: 1; - height: 24px; - font-size: 18px; - } - .fa { - line-height: 1; - height: 24px; - font-size: 18px; - } - .user_profile { - .user_dw_menu { - list-style-type: none; - padding-left: 0px; - li { - width: 100%; - border-bottom: 1px solid #eee; - height: 45px; - a { - line-height: 24px; - color: #333333; - display: inline-flex; - } - i { - float: left; - padding-right: 5px; - } - &:last-child { - border-bottom: 0; - } - } - } - .dropdown-menu { - width: 200px; - right: -10px; - } - } -} -.nav-notification-icons { - min-width: 0 !important; - flex-shrink: 0; - line-height: 40px !important; - border-radius: 50% !important; - margin: 0px 4px; - &:after { - display: none; - } - .material-icons-outlined { - display: flex; - vertical-align: middle; - } -} -.lang-dropdown { - cursor: pointer; - // margin: 14px 20px 0px 10px; - .country-name { - margin-left: 5px; - vertical-align: middle; - } - &::after { - display: none; - } - img { - height: 17px; - border-radius: 3px; - } -} -.lang-item { - width: 175px !important; - .lang-item-list { - line-height: 30px; - &.active { - background-color: #eef1f9; - color: #000000; - } - &:active { - background-color: #eef1f9; - color: #000000; - } - .flag-img { - margin: 0px 5px; - } - } -} - -.label-count { - position: absolute; - top: 5px; - right: 10px; - font-size: 10px; - line-height: 15px; - background-color: #000; - padding: 3px 3px; - border-radius: 3px; -} -.navbar-brand { - float: left; - height: 45px; - padding: 6px 25px; - margin-left: 20px; - font-size: 18px; - line-height: 20px; - text-align: center; - width: 100%; - img { - /*float: left;*/ - vertical-align: top; - } - span { - line-height: 32px; - padding-left: 10px; - } -} -.navbar-collapse { - padding-right: 15px; - padding-left: 15px; - overflow-x: visible; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); -} -.collapse { - display: none; -} -.navbar-nav { - float: none; - > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px; - } -} -.nav { - padding-left: 0; - margin-bottom: 0; - list-style: none; - > li { - position: relative; - display: block; - > a { - position: relative; - display: block; - padding: 5px 0px; - } - } - .fullscreen { - // margin: 0px 10px; - } - .langSelItem { - margin: 15px 10px 0px 10px; - } - .btnNotification { - margin: 0px 10px; - } - .btnUserDropdown { - margin: 0px 8px; - } - .btnHeaderSetting { - margin: 0px 8px; - .settingBtn { - vertical-align: top; - } - } - .user-menu-icons { - margin: 0px 5px; - .feather { - height: 18px !important; - width: 18px !important; - vertical-align: middle; - } - } - - .menuIcon { - line-height: 20px !important; - height: 20px; - font-size: 20px; - } - .logo { - margin-right: auto; - } -} -nav.navbar { - min-height: 60px; - position: fixed; - width: calc(100% - 4rem - 257px); - z-index: 12; - right: 0; - left: unset; - margin: 1.3rem 2rem 0; - border-radius: 0.428rem; - box-shadow: 0 -18px 1px 5px rgb(241 240 244); - top: 0; -} - -@each $key, $val in $colors { - .col-#{$key} { - .navbar { - @include navbar-link-color(#fff, #000, 0.95); - // @include navbar-link-color(rgba(0,0,0,0.85), #000, .95); - } - } -} -.side-closed { - .sidebar { - /*margin-left: -300px;*/ - width: 60px; - .menu { - .list { - li { - .menu-toggle { - &:before, - &:after { - content: ""; - } - } - span { - display: none; - } - a { - line-height: 1rem; - padding-left: 9px; - &:after { - top: calc(50% - 7px); - } - } - } - } - } - } - &.submenu-closed { - .sidebar .menu .list { - li .ml-menu, - .header { - display: none !important; - } - } - .navbar-header { - width: 65px; - .navbar-brand { - padding-right: 0; - padding-left: 0; - // margin: 0; - span { - display: none; - } - } - .navbar-nav { - .sidemenu-collapse { - display: none; - } - } - } - .sidebar-user-panel { - display: none; - } - } - - section.content { - margin-left: 58px; - transition: all 1s, width 1s; - } - nav.navbar { - width: calc(100% - 4rem - 55px); - transition: all 1s, width 1s; - } - - .navbar-brand { - margin-left: 5px; - } - &.side-closed-hover { - .sidebar { - width: 260px; - transition: all 1s, width 1s; - .menu { - .list { - li { - .menu-toggle { - &:before { - content: "\f054"; - transform: scale(1); - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - top: calc(50% - 7px); - @include transform(scale(1)); - } - &:after { - content: "\f078"; - transform: scale(1); - font-family: "Font Awesome 5 Free"; - font-weight: 600; - font-size: 12px; - color: gray; - @include transform(scale(0)); - } - } - span { - display: block; - float: left; - } - a { - padding: 9px 9px 9px 9px; - } - i { - float: left; - line-height: 2rem; - } - .sidebarIcon { - float: left; - line-height: 2rem; - } - } - .ml-menu { - li { - a { - padding-left: 45px; - padding-top: 7px; - padding-bottom: 7px; - line-height: 2rem; - } - } - .ml-menu-2 { - li { - a { - padding-left: 65px; - padding-top: 4px; - padding-bottom: 4px; - } - } - } - .ml-menu-3 { - li { - a { - padding-left: 85px; - padding-top: 4px; - padding-bottom: 4px; - } - } - } - } - .active .menu-toggle { - &:before { - @include transform(scale(0)); - } - - &:after { - @include transform(scale(1)); - } - } - } - } - } - section.content { - margin-left: 260px; - transition: all 1s, width 1s; - } - nav.navbar { - width: calc(100% - 4rem - 257px); - transition: all 1s, width 1s; - } - } -} -.sidemenu-collapse { - height: 50px; - padding: 0px 20px 0px 44px; - &:hover { - text-decoration: none; - color: #fff; - background-color: transparent; - } - .fas { - line-height: 1; - height: 24px; - font-size: 18px; - color: #3a2c70; - } -} -nav, -nav .nav-wrapper i, -nav a.button-collapse, -nav a.button-collapse i { - @media screen and (min-width: 601px) { - // height: 60px; - // line-height: 60px; - } -} -.boxed-layout { - .container > .navbar-header { - margin-left: 0; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_navtabs.scss b/MyOffice.SPA/src/assets/scss/components/_navtabs.scss deleted file mode 100644 index 1e52768..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_navtabs.scss +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Document : _navtabs.scss - * Author : RedStar Template - * Description: This scss file for navbar tabs style classes - */ -.nav-tabs { - border-bottom: 2px solid #eee; - - > li { - position: relative; - top: 3px; - left: -2px; - - > a { - border: none !important; - color: #999 !important; - @include border-radius(0); - - &:hover, - &:active, - &:focus { - background-color: transparent !important; - } - - &:before { - content: ""; - position: absolute; - left: 0; - width: 100%; - height: 0; - border-bottom: 2px solid #2196f3; - bottom: 2px; - @include transform(scaleX(0)); - @include transition(0.1s ease-in); - } - - .material-icons { - position: relative; - top: 7px; - margin-bottom: 8px; - } - } - } - - li { - a.active { - color: #222 !important; - - &:hover, - &:active, - &:focus { - background-color: transparent !important; - } - - &:before { - @include transform(scaleX(1)); - } - } - } - - + .tab-content { - padding: 15px 0; - } -} - -@each $key, $val in $colors { - .nav-tabs.tab-col-#{$key} { - > li { - > a { - &:before { - border-bottom: 2px solid $val; - } - } - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_noticeboard.scss b/MyOffice.SPA/src/assets/scss/components/_noticeboard.scss deleted file mode 100644 index cf4603c..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_noticeboard.scss +++ /dev/null @@ -1,18 +0,0 @@ -.notice-board { - display: -ms-flexbox; - display: -webkit-box; - display: flex; - -ms-flex-align: start; - -webkit-box-align: start; - align-items: flex-start; - .notice-body { - font-size: 13px; - padding: 0px 0px 5px 10px; - p { - margin-bottom: 0px; - } - .notice-heading { - margin: 5px 0px 0px 0px; - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_rightsidebar.scss b/MyOffice.SPA/src/assets/scss/components/_rightsidebar.scss deleted file mode 100644 index e2a555d..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_rightsidebar.scss +++ /dev/null @@ -1,30 +0,0 @@ -.rightSetting { - padding: 20px 25px 0px 25px; - p { - font-weight: bold; - margin: 0; - border-bottom: 1px solid #eee; - font-size: 12px; - text-align: left; - } - .mat-button-toggle-checked { - background-color: #6e68c1; - color: #ffffff !important; - } - .mat-button-toggle { - width: 70px; - height: 30px; - font-size: 14px; - } - .mat-button-toggle-button { - height: 100%; - display: flex; - align-items: center; - justify-content: center; - } - .mat-button-toggle-appearance-standard .mat-button-toggle-label-content { - line-height: 30px !important; - padding: 0 12px !important; - text-align: center; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_searchbar.scss b/MyOffice.SPA/src/assets/scss/components/_searchbar.scss deleted file mode 100644 index 26c5770..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_searchbar.scss +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Document : _noUISlider.scss - * Author : RedStar Template - * Description: This scss file for noUISlider component style classes - */ -%extend_search { - outline: none; - opacity: 1; - margin-left: -43px; -} - -.search-box { - overflow: hidden; - width: 270px; - vertical-align: middle; - white-space: nowrap; - input { - &#search { - width: 250px; - height: 40px; - background: rgb(255, 255, 255); - border: none; - font-size: 10pt; - float: left; - color: #fff; - padding-left: 15px; - margin-bottom: 0; - margin-top: 10px; - border-radius: 50px; - &:-moz-placeholder { - color: #65737e; - } - &:-ms-input-placeholder { - color: #65737e; - } - } - &#search::-webkit-input-placeholder { - color: #65737e; - } - &#search::-moz-placeholder { - color: #65737e; - } - } - button.icon { - border: none; - background: transparent; - height: 50px; - width: 0px; - color: #4f5b66; - opacity: 0; - font-size: 10pt; - transition: all 0.55s ease; - - .fa { - font-size: 18px; - } - } - &:hover button.icon { - @extend %extend_search; - &:hover { - background: transparent; - } - } - &:active button.icon { - @extend %extend_search; - } - &:focus button.icon { - @extend %extend_search; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_settingSidebar.scss b/MyOffice.SPA/src/assets/scss/components/_settingSidebar.scss deleted file mode 100644 index a90e1d1..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_settingSidebar.scss +++ /dev/null @@ -1,197 +0,0 @@ -.settingSidebar { - background: #fff; - position: fixed; - height: 100%; - width: 280px; - top: 62px; - right: -280px; - z-index: 999; - transition: 0.3s ease-in; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.16), 0 2px 10px rgba(0, 0, 0, 0.12); - - .settingPanelToggle { - background: #6777ef; - padding: 13px 13px; - color: #fff; - position: absolute; - top: 30%; - left: -40px; - width: 40px; - border-radius: 10px 0 0 10px; - .setting-sidebar-icon .feather { - height: 17px; - width: 17px; - } - } - - &.showSettingPanel { - right: 0; - } - - .settingSidebar-body { - position: relative; - height: 100%; - } - - .settingSidebar-tab { - display: flex; - - .nav-item { - width: 33.33%; - text-align: center; - - .nav-link { - padding: 15px 12px; - color: #6a7a8c; - border-bottom: 3px solid transparent; - - &.active { - border-bottom: 3px solid #2962ff; - color: #2962ff; - } - - &:hover { - border-bottom: 3px solid #2962ff; - color: #2962ff; - } - } - } - } - - ul.choose-theme li { - display: inline-block; - - &:hover { - cursor: pointer; - } - } - - ul.choose-theme li div { - border-radius: 15px; - display: inline-block; - vertical-align: middle; - height: 25px; - width: 25px; - overflow: hidden; - position: relative; - margin: 4px; - } - - ul.choose-theme li div.purple { - background: #6777ef; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - - ul.choose-theme li div.orange { - background: #ffa117; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - - ul.choose-theme li div.cyan { - background: #3dc7be; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - - ul.choose-theme li div.green { - background: #4caf4f; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - - ul.choose-theme li div.red { - background: #ea5455; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - - ul.choose-theme li div.white { - background: #ece8e8; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - - ul.choose-theme li div.black { - background: #343a40; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - ul.choose-theme li div.blue { - background: #03a9f3; - -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - - ul.choose-theme li.active div::after { - content: "\f00c"; - color: #fff; - top: 4px; - left: 7px; - font-family: "Font Awesome 5 Free"; - font-weight: 900; - font-size: 12px; - position: absolute; - -webkit-transition: 0.5s; - transition: 0.5s; - } - - .setting-panel-header { - display: block; - padding: 15px 20px; - color: #212529; - font-size: 15px; - border: 1px solid #eae9e9; - background: #e9ecef; - } - - .disk-server-setting { - .progress { - height: 8px; - } - - p { - font-weight: bold; - margin: 0; - border-bottom: 1px solid #eee; - font-size: 14px; - text-align: left; - padding-bottom: 5px; - } - } - - .rt-sidebar-last-ele { - margin-bottom: 70px !important; - } -} -.hiddenradio { - padding: 0px 20px 0px 0px; - margin: 0px 20px 0px 0px; -} -.hiddenradio [type="radio"] { - position: absolute; - opacity: 0; - width: 0; - height: 0; -} - -/* IMAGE STYLES */ -.hiddenradio [type="radio"] + img { - cursor: pointer; - height: auto; - width: 100%; - border: 3px solid #d5e0ec; -} - -/* CHECKED STYLES */ -.hiddenradio [type="radio"]:checked + img, -.hiddenradio label.layout-selected img { - outline: 2px solid #6777ef; -} - -@media only screen and (max-width: 1024px) { - .settingSidebar { - display: none; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_switch.scss b/MyOffice.SPA/src/assets/scss/components/_switch.scss deleted file mode 100644 index 6324216..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_switch.scss +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Document : _switch.scss - * Author : RedStar Template - * Description: This scss file switch button style classes - */ -.switch { - label { - font-weight: normal; - font-size: 13px; - - .lever { - margin: 0 14px; - } - - input[type="checkbox"] { - &:checked { - @each $key, $val in $colors { - &:not(:disabled) { - ~ .lever.switch-col-#{$key} { - &:active { - &:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), - 0 0 0 15px rgba($val, 0.1); - } - } - } - } - - + .lever.switch-col-#{$key} { - background-color: rgba($val, 0.5); - - &:after { - background-color: $val; - } - } - } - } - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_thumbnails.scss b/MyOffice.SPA/src/assets/scss/components/_thumbnails.scss deleted file mode 100644 index b229ed0..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_thumbnails.scss +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Document : _thumbnail.scss - * Author : RedStar Template - * Description: This scss file for thumbnail style classes - */ -.thumbnail { - @include border-radius(0); - - p:not(button) { - color: #999999; - font-size: 14px; - } - - h3 { - font-weight: bold; - font-size: 17px; - } -} diff --git a/MyOffice.SPA/src/assets/scss/components/_todo.scss b/MyOffice.SPA/src/assets/scss/components/_todo.scss deleted file mode 100644 index fa5536f..0000000 --- a/MyOffice.SPA/src/assets/scss/components/_todo.scss +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Document : _todo.scss - * Author : RedStar Template - * Description: This scss file for todo style classes - */ -.to-do-list { - padding-left: 0; - margin-top: -10px; - font-size: 12px; - min-height: 311px; - float: left; - width: 100%; - li { - padding: 15px 0; - border-radius: 3px; - position: relative; - cursor: move; - list-style: none; - font-size: 14px; - background: #fff; - border-bottom: 1px dotted rgba(0, 0, 0, 0.2); - p { - margin: 0; - padding-left: 50px; - } - .todo-check input[type="checkbox"] { - visibility: hidden; - } - } -} -.todo-actionlist { - position: absolute; - right: -5px; - top: 22px; - a { - height: 24px; - width: 24px; - display: inline-block; - float: left; - i { - height: 24px; - width: 24px; - display: inline-block; - text-align: center; - line-height: 24px; - color: #ccc; - } - &:hover i { - color: #666; - } - } -} -.line-through { - text-decoration: line-through; -} -.todo-action-bar { - margin-top: 20px; -} -.todo-check { - width: 20px; - position: relative; - margin-right: 10px; - margin-left: 10px; - input[type="checkbox"] { - visibility: hidden; - } - label { - cursor: pointer; - position: absolute; - width: 20px; - height: 20px; - top: 0; - left: 0; - border-radius: 2px; - } -} -.todo-done i { - font-size: 14px; -} -.todo-remove i { - font-size: 10px; -} -.inbox-small-cells .todo-check input[type="checkbox"] { - visibility: hidden; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_animated.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_animated.scss deleted file mode 100644 index 7c7c0e1..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_animated.scss +++ /dev/null @@ -1,20 +0,0 @@ -// Animated Icons -// -------------------------- - -.#{$fa-css-prefix}-spin { - animation: fa-spin 2s infinite linear; -} - -.#{$fa-css-prefix}-pulse { - animation: fa-spin 1s infinite steps(8); -} - -@keyframes fa-spin { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_bordered-pulled.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_bordered-pulled.scss deleted file mode 100644 index c8c4274..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_bordered-pulled.scss +++ /dev/null @@ -1,20 +0,0 @@ -// Bordered & Pulled -// ------------------------- - -.#{$fa-css-prefix}-border { - border: solid .08em $fa-border-color; - border-radius: .1em; - padding: .2em .25em .15em; -} - -.#{$fa-css-prefix}-pull-left { float: left; } -.#{$fa-css-prefix}-pull-right { float: right; } - -.#{$fa-css-prefix}, -.fas, -.far, -.fal, -.fab { - &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } - &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_core.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_core.scss deleted file mode 100644 index cbd4cf7..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_core.scss +++ /dev/null @@ -1,21 +0,0 @@ -// Base Class Definition -// ------------------------- - -.#{$fa-css-prefix}, -.fas, -.far, -.fal, -.fad, -.fab { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - display: inline-block; - font-style: normal; - font-variant: normal; - text-rendering: auto; - line-height: 1; -} - -%fa-icon { - @include fa-icon; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_fixed-width.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_fixed-width.scss deleted file mode 100644 index 970641f..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_fixed-width.scss +++ /dev/null @@ -1,6 +0,0 @@ -// Fixed Width Icons -// ------------------------- -.#{$fa-css-prefix}-fw { - text-align: center; - width: $fa-fw-width; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_icons.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_icons.scss deleted file mode 100644 index fa3ac07..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_icons.scss +++ /dev/null @@ -1,1451 +0,0 @@ -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen -readers do not read off random characters that represent icons */ - -.#{$fa-css-prefix}-500px:before { content: fa-content($fa-var-500px); } -.#{$fa-css-prefix}-accessible-icon:before { content: fa-content($fa-var-accessible-icon); } -.#{$fa-css-prefix}-accusoft:before { content: fa-content($fa-var-accusoft); } -.#{$fa-css-prefix}-acquisitions-incorporated:before { content: fa-content($fa-var-acquisitions-incorporated); } -.#{$fa-css-prefix}-ad:before { content: fa-content($fa-var-ad); } -.#{$fa-css-prefix}-address-book:before { content: fa-content($fa-var-address-book); } -.#{$fa-css-prefix}-address-card:before { content: fa-content($fa-var-address-card); } -.#{$fa-css-prefix}-adjust:before { content: fa-content($fa-var-adjust); } -.#{$fa-css-prefix}-adn:before { content: fa-content($fa-var-adn); } -.#{$fa-css-prefix}-adobe:before { content: fa-content($fa-var-adobe); } -.#{$fa-css-prefix}-adversal:before { content: fa-content($fa-var-adversal); } -.#{$fa-css-prefix}-affiliatetheme:before { content: fa-content($fa-var-affiliatetheme); } -.#{$fa-css-prefix}-air-freshener:before { content: fa-content($fa-var-air-freshener); } -.#{$fa-css-prefix}-airbnb:before { content: fa-content($fa-var-airbnb); } -.#{$fa-css-prefix}-algolia:before { content: fa-content($fa-var-algolia); } -.#{$fa-css-prefix}-align-center:before { content: fa-content($fa-var-align-center); } -.#{$fa-css-prefix}-align-justify:before { content: fa-content($fa-var-align-justify); } -.#{$fa-css-prefix}-align-left:before { content: fa-content($fa-var-align-left); } -.#{$fa-css-prefix}-align-right:before { content: fa-content($fa-var-align-right); } -.#{$fa-css-prefix}-alipay:before { content: fa-content($fa-var-alipay); } -.#{$fa-css-prefix}-allergies:before { content: fa-content($fa-var-allergies); } -.#{$fa-css-prefix}-amazon:before { content: fa-content($fa-var-amazon); } -.#{$fa-css-prefix}-amazon-pay:before { content: fa-content($fa-var-amazon-pay); } -.#{$fa-css-prefix}-ambulance:before { content: fa-content($fa-var-ambulance); } -.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: fa-content($fa-var-american-sign-language-interpreting); } -.#{$fa-css-prefix}-amilia:before { content: fa-content($fa-var-amilia); } -.#{$fa-css-prefix}-anchor:before { content: fa-content($fa-var-anchor); } -.#{$fa-css-prefix}-android:before { content: fa-content($fa-var-android); } -.#{$fa-css-prefix}-angellist:before { content: fa-content($fa-var-angellist); } -.#{$fa-css-prefix}-angle-double-down:before { content: fa-content($fa-var-angle-double-down); } -.#{$fa-css-prefix}-angle-double-left:before { content: fa-content($fa-var-angle-double-left); } -.#{$fa-css-prefix}-angle-double-right:before { content: fa-content($fa-var-angle-double-right); } -.#{$fa-css-prefix}-angle-double-up:before { content: fa-content($fa-var-angle-double-up); } -.#{$fa-css-prefix}-angle-down:before { content: fa-content($fa-var-angle-down); } -.#{$fa-css-prefix}-angle-left:before { content: fa-content($fa-var-angle-left); } -.#{$fa-css-prefix}-angle-right:before { content: fa-content($fa-var-angle-right); } -.#{$fa-css-prefix}-angle-up:before { content: fa-content($fa-var-angle-up); } -.#{$fa-css-prefix}-angry:before { content: fa-content($fa-var-angry); } -.#{$fa-css-prefix}-angrycreative:before { content: fa-content($fa-var-angrycreative); } -.#{$fa-css-prefix}-angular:before { content: fa-content($fa-var-angular); } -.#{$fa-css-prefix}-ankh:before { content: fa-content($fa-var-ankh); } -.#{$fa-css-prefix}-app-store:before { content: fa-content($fa-var-app-store); } -.#{$fa-css-prefix}-app-store-ios:before { content: fa-content($fa-var-app-store-ios); } -.#{$fa-css-prefix}-apper:before { content: fa-content($fa-var-apper); } -.#{$fa-css-prefix}-apple:before { content: fa-content($fa-var-apple); } -.#{$fa-css-prefix}-apple-alt:before { content: fa-content($fa-var-apple-alt); } -.#{$fa-css-prefix}-apple-pay:before { content: fa-content($fa-var-apple-pay); } -.#{$fa-css-prefix}-archive:before { content: fa-content($fa-var-archive); } -.#{$fa-css-prefix}-archway:before { content: fa-content($fa-var-archway); } -.#{$fa-css-prefix}-arrow-alt-circle-down:before { content: fa-content($fa-var-arrow-alt-circle-down); } -.#{$fa-css-prefix}-arrow-alt-circle-left:before { content: fa-content($fa-var-arrow-alt-circle-left); } -.#{$fa-css-prefix}-arrow-alt-circle-right:before { content: fa-content($fa-var-arrow-alt-circle-right); } -.#{$fa-css-prefix}-arrow-alt-circle-up:before { content: fa-content($fa-var-arrow-alt-circle-up); } -.#{$fa-css-prefix}-arrow-circle-down:before { content: fa-content($fa-var-arrow-circle-down); } -.#{$fa-css-prefix}-arrow-circle-left:before { content: fa-content($fa-var-arrow-circle-left); } -.#{$fa-css-prefix}-arrow-circle-right:before { content: fa-content($fa-var-arrow-circle-right); } -.#{$fa-css-prefix}-arrow-circle-up:before { content: fa-content($fa-var-arrow-circle-up); } -.#{$fa-css-prefix}-arrow-down:before { content: fa-content($fa-var-arrow-down); } -.#{$fa-css-prefix}-arrow-left:before { content: fa-content($fa-var-arrow-left); } -.#{$fa-css-prefix}-arrow-right:before { content: fa-content($fa-var-arrow-right); } -.#{$fa-css-prefix}-arrow-up:before { content: fa-content($fa-var-arrow-up); } -.#{$fa-css-prefix}-arrows-alt:before { content: fa-content($fa-var-arrows-alt); } -.#{$fa-css-prefix}-arrows-alt-h:before { content: fa-content($fa-var-arrows-alt-h); } -.#{$fa-css-prefix}-arrows-alt-v:before { content: fa-content($fa-var-arrows-alt-v); } -.#{$fa-css-prefix}-artstation:before { content: fa-content($fa-var-artstation); } -.#{$fa-css-prefix}-assistive-listening-systems:before { content: fa-content($fa-var-assistive-listening-systems); } -.#{$fa-css-prefix}-asterisk:before { content: fa-content($fa-var-asterisk); } -.#{$fa-css-prefix}-asymmetrik:before { content: fa-content($fa-var-asymmetrik); } -.#{$fa-css-prefix}-at:before { content: fa-content($fa-var-at); } -.#{$fa-css-prefix}-atlas:before { content: fa-content($fa-var-atlas); } -.#{$fa-css-prefix}-atlassian:before { content: fa-content($fa-var-atlassian); } -.#{$fa-css-prefix}-atom:before { content: fa-content($fa-var-atom); } -.#{$fa-css-prefix}-audible:before { content: fa-content($fa-var-audible); } -.#{$fa-css-prefix}-audio-description:before { content: fa-content($fa-var-audio-description); } -.#{$fa-css-prefix}-autoprefixer:before { content: fa-content($fa-var-autoprefixer); } -.#{$fa-css-prefix}-avianex:before { content: fa-content($fa-var-avianex); } -.#{$fa-css-prefix}-aviato:before { content: fa-content($fa-var-aviato); } -.#{$fa-css-prefix}-award:before { content: fa-content($fa-var-award); } -.#{$fa-css-prefix}-aws:before { content: fa-content($fa-var-aws); } -.#{$fa-css-prefix}-baby:before { content: fa-content($fa-var-baby); } -.#{$fa-css-prefix}-baby-carriage:before { content: fa-content($fa-var-baby-carriage); } -.#{$fa-css-prefix}-backspace:before { content: fa-content($fa-var-backspace); } -.#{$fa-css-prefix}-backward:before { content: fa-content($fa-var-backward); } -.#{$fa-css-prefix}-bacon:before { content: fa-content($fa-var-bacon); } -.#{$fa-css-prefix}-bacteria:before { content: fa-content($fa-var-bacteria); } -.#{$fa-css-prefix}-bacterium:before { content: fa-content($fa-var-bacterium); } -.#{$fa-css-prefix}-bahai:before { content: fa-content($fa-var-bahai); } -.#{$fa-css-prefix}-balance-scale:before { content: fa-content($fa-var-balance-scale); } -.#{$fa-css-prefix}-balance-scale-left:before { content: fa-content($fa-var-balance-scale-left); } -.#{$fa-css-prefix}-balance-scale-right:before { content: fa-content($fa-var-balance-scale-right); } -.#{$fa-css-prefix}-ban:before { content: fa-content($fa-var-ban); } -.#{$fa-css-prefix}-band-aid:before { content: fa-content($fa-var-band-aid); } -.#{$fa-css-prefix}-bandcamp:before { content: fa-content($fa-var-bandcamp); } -.#{$fa-css-prefix}-barcode:before { content: fa-content($fa-var-barcode); } -.#{$fa-css-prefix}-bars:before { content: fa-content($fa-var-bars); } -.#{$fa-css-prefix}-baseball-ball:before { content: fa-content($fa-var-baseball-ball); } -.#{$fa-css-prefix}-basketball-ball:before { content: fa-content($fa-var-basketball-ball); } -.#{$fa-css-prefix}-bath:before { content: fa-content($fa-var-bath); } -.#{$fa-css-prefix}-battery-empty:before { content: fa-content($fa-var-battery-empty); } -.#{$fa-css-prefix}-battery-full:before { content: fa-content($fa-var-battery-full); } -.#{$fa-css-prefix}-battery-half:before { content: fa-content($fa-var-battery-half); } -.#{$fa-css-prefix}-battery-quarter:before { content: fa-content($fa-var-battery-quarter); } -.#{$fa-css-prefix}-battery-three-quarters:before { content: fa-content($fa-var-battery-three-quarters); } -.#{$fa-css-prefix}-battle-net:before { content: fa-content($fa-var-battle-net); } -.#{$fa-css-prefix}-bed:before { content: fa-content($fa-var-bed); } -.#{$fa-css-prefix}-beer:before { content: fa-content($fa-var-beer); } -.#{$fa-css-prefix}-behance:before { content: fa-content($fa-var-behance); } -.#{$fa-css-prefix}-behance-square:before { content: fa-content($fa-var-behance-square); } -.#{$fa-css-prefix}-bell:before { content: fa-content($fa-var-bell); } -.#{$fa-css-prefix}-bell-slash:before { content: fa-content($fa-var-bell-slash); } -.#{$fa-css-prefix}-bezier-curve:before { content: fa-content($fa-var-bezier-curve); } -.#{$fa-css-prefix}-bible:before { content: fa-content($fa-var-bible); } -.#{$fa-css-prefix}-bicycle:before { content: fa-content($fa-var-bicycle); } -.#{$fa-css-prefix}-biking:before { content: fa-content($fa-var-biking); } -.#{$fa-css-prefix}-bimobject:before { content: fa-content($fa-var-bimobject); } -.#{$fa-css-prefix}-binoculars:before { content: fa-content($fa-var-binoculars); } -.#{$fa-css-prefix}-biohazard:before { content: fa-content($fa-var-biohazard); } -.#{$fa-css-prefix}-birthday-cake:before { content: fa-content($fa-var-birthday-cake); } -.#{$fa-css-prefix}-bitbucket:before { content: fa-content($fa-var-bitbucket); } -.#{$fa-css-prefix}-bitcoin:before { content: fa-content($fa-var-bitcoin); } -.#{$fa-css-prefix}-bity:before { content: fa-content($fa-var-bity); } -.#{$fa-css-prefix}-black-tie:before { content: fa-content($fa-var-black-tie); } -.#{$fa-css-prefix}-blackberry:before { content: fa-content($fa-var-blackberry); } -.#{$fa-css-prefix}-blender:before { content: fa-content($fa-var-blender); } -.#{$fa-css-prefix}-blender-phone:before { content: fa-content($fa-var-blender-phone); } -.#{$fa-css-prefix}-blind:before { content: fa-content($fa-var-blind); } -.#{$fa-css-prefix}-blog:before { content: fa-content($fa-var-blog); } -.#{$fa-css-prefix}-blogger:before { content: fa-content($fa-var-blogger); } -.#{$fa-css-prefix}-blogger-b:before { content: fa-content($fa-var-blogger-b); } -.#{$fa-css-prefix}-bluetooth:before { content: fa-content($fa-var-bluetooth); } -.#{$fa-css-prefix}-bluetooth-b:before { content: fa-content($fa-var-bluetooth-b); } -.#{$fa-css-prefix}-bold:before { content: fa-content($fa-var-bold); } -.#{$fa-css-prefix}-bolt:before { content: fa-content($fa-var-bolt); } -.#{$fa-css-prefix}-bomb:before { content: fa-content($fa-var-bomb); } -.#{$fa-css-prefix}-bone:before { content: fa-content($fa-var-bone); } -.#{$fa-css-prefix}-bong:before { content: fa-content($fa-var-bong); } -.#{$fa-css-prefix}-book:before { content: fa-content($fa-var-book); } -.#{$fa-css-prefix}-book-dead:before { content: fa-content($fa-var-book-dead); } -.#{$fa-css-prefix}-book-medical:before { content: fa-content($fa-var-book-medical); } -.#{$fa-css-prefix}-book-open:before { content: fa-content($fa-var-book-open); } -.#{$fa-css-prefix}-book-reader:before { content: fa-content($fa-var-book-reader); } -.#{$fa-css-prefix}-bookmark:before { content: fa-content($fa-var-bookmark); } -.#{$fa-css-prefix}-bootstrap:before { content: fa-content($fa-var-bootstrap); } -.#{$fa-css-prefix}-border-all:before { content: fa-content($fa-var-border-all); } -.#{$fa-css-prefix}-border-none:before { content: fa-content($fa-var-border-none); } -.#{$fa-css-prefix}-border-style:before { content: fa-content($fa-var-border-style); } -.#{$fa-css-prefix}-bowling-ball:before { content: fa-content($fa-var-bowling-ball); } -.#{$fa-css-prefix}-box:before { content: fa-content($fa-var-box); } -.#{$fa-css-prefix}-box-open:before { content: fa-content($fa-var-box-open); } -.#{$fa-css-prefix}-box-tissue:before { content: fa-content($fa-var-box-tissue); } -.#{$fa-css-prefix}-boxes:before { content: fa-content($fa-var-boxes); } -.#{$fa-css-prefix}-braille:before { content: fa-content($fa-var-braille); } -.#{$fa-css-prefix}-brain:before { content: fa-content($fa-var-brain); } -.#{$fa-css-prefix}-bread-slice:before { content: fa-content($fa-var-bread-slice); } -.#{$fa-css-prefix}-briefcase:before { content: fa-content($fa-var-briefcase); } -.#{$fa-css-prefix}-briefcase-medical:before { content: fa-content($fa-var-briefcase-medical); } -.#{$fa-css-prefix}-broadcast-tower:before { content: fa-content($fa-var-broadcast-tower); } -.#{$fa-css-prefix}-broom:before { content: fa-content($fa-var-broom); } -.#{$fa-css-prefix}-brush:before { content: fa-content($fa-var-brush); } -.#{$fa-css-prefix}-btc:before { content: fa-content($fa-var-btc); } -.#{$fa-css-prefix}-buffer:before { content: fa-content($fa-var-buffer); } -.#{$fa-css-prefix}-bug:before { content: fa-content($fa-var-bug); } -.#{$fa-css-prefix}-building:before { content: fa-content($fa-var-building); } -.#{$fa-css-prefix}-bullhorn:before { content: fa-content($fa-var-bullhorn); } -.#{$fa-css-prefix}-bullseye:before { content: fa-content($fa-var-bullseye); } -.#{$fa-css-prefix}-burn:before { content: fa-content($fa-var-burn); } -.#{$fa-css-prefix}-buromobelexperte:before { content: fa-content($fa-var-buromobelexperte); } -.#{$fa-css-prefix}-bus:before { content: fa-content($fa-var-bus); } -.#{$fa-css-prefix}-bus-alt:before { content: fa-content($fa-var-bus-alt); } -.#{$fa-css-prefix}-business-time:before { content: fa-content($fa-var-business-time); } -.#{$fa-css-prefix}-buy-n-large:before { content: fa-content($fa-var-buy-n-large); } -.#{$fa-css-prefix}-buysellads:before { content: fa-content($fa-var-buysellads); } -.#{$fa-css-prefix}-calculator:before { content: fa-content($fa-var-calculator); } -.#{$fa-css-prefix}-calendar:before { content: fa-content($fa-var-calendar); } -.#{$fa-css-prefix}-calendar-alt:before { content: fa-content($fa-var-calendar-alt); } -.#{$fa-css-prefix}-calendar-check:before { content: fa-content($fa-var-calendar-check); } -.#{$fa-css-prefix}-calendar-day:before { content: fa-content($fa-var-calendar-day); } -.#{$fa-css-prefix}-calendar-minus:before { content: fa-content($fa-var-calendar-minus); } -.#{$fa-css-prefix}-calendar-plus:before { content: fa-content($fa-var-calendar-plus); } -.#{$fa-css-prefix}-calendar-times:before { content: fa-content($fa-var-calendar-times); } -.#{$fa-css-prefix}-calendar-week:before { content: fa-content($fa-var-calendar-week); } -.#{$fa-css-prefix}-camera:before { content: fa-content($fa-var-camera); } -.#{$fa-css-prefix}-camera-retro:before { content: fa-content($fa-var-camera-retro); } -.#{$fa-css-prefix}-campground:before { content: fa-content($fa-var-campground); } -.#{$fa-css-prefix}-canadian-maple-leaf:before { content: fa-content($fa-var-canadian-maple-leaf); } -.#{$fa-css-prefix}-candy-cane:before { content: fa-content($fa-var-candy-cane); } -.#{$fa-css-prefix}-cannabis:before { content: fa-content($fa-var-cannabis); } -.#{$fa-css-prefix}-capsules:before { content: fa-content($fa-var-capsules); } -.#{$fa-css-prefix}-car:before { content: fa-content($fa-var-car); } -.#{$fa-css-prefix}-car-alt:before { content: fa-content($fa-var-car-alt); } -.#{$fa-css-prefix}-car-battery:before { content: fa-content($fa-var-car-battery); } -.#{$fa-css-prefix}-car-crash:before { content: fa-content($fa-var-car-crash); } -.#{$fa-css-prefix}-car-side:before { content: fa-content($fa-var-car-side); } -.#{$fa-css-prefix}-caravan:before { content: fa-content($fa-var-caravan); } -.#{$fa-css-prefix}-caret-down:before { content: fa-content($fa-var-caret-down); } -.#{$fa-css-prefix}-caret-left:before { content: fa-content($fa-var-caret-left); } -.#{$fa-css-prefix}-caret-right:before { content: fa-content($fa-var-caret-right); } -.#{$fa-css-prefix}-caret-square-down:before { content: fa-content($fa-var-caret-square-down); } -.#{$fa-css-prefix}-caret-square-left:before { content: fa-content($fa-var-caret-square-left); } -.#{$fa-css-prefix}-caret-square-right:before { content: fa-content($fa-var-caret-square-right); } -.#{$fa-css-prefix}-caret-square-up:before { content: fa-content($fa-var-caret-square-up); } -.#{$fa-css-prefix}-caret-up:before { content: fa-content($fa-var-caret-up); } -.#{$fa-css-prefix}-carrot:before { content: fa-content($fa-var-carrot); } -.#{$fa-css-prefix}-cart-arrow-down:before { content: fa-content($fa-var-cart-arrow-down); } -.#{$fa-css-prefix}-cart-plus:before { content: fa-content($fa-var-cart-plus); } -.#{$fa-css-prefix}-cash-register:before { content: fa-content($fa-var-cash-register); } -.#{$fa-css-prefix}-cat:before { content: fa-content($fa-var-cat); } -.#{$fa-css-prefix}-cc-amazon-pay:before { content: fa-content($fa-var-cc-amazon-pay); } -.#{$fa-css-prefix}-cc-amex:before { content: fa-content($fa-var-cc-amex); } -.#{$fa-css-prefix}-cc-apple-pay:before { content: fa-content($fa-var-cc-apple-pay); } -.#{$fa-css-prefix}-cc-diners-club:before { content: fa-content($fa-var-cc-diners-club); } -.#{$fa-css-prefix}-cc-discover:before { content: fa-content($fa-var-cc-discover); } -.#{$fa-css-prefix}-cc-jcb:before { content: fa-content($fa-var-cc-jcb); } -.#{$fa-css-prefix}-cc-mastercard:before { content: fa-content($fa-var-cc-mastercard); } -.#{$fa-css-prefix}-cc-paypal:before { content: fa-content($fa-var-cc-paypal); } -.#{$fa-css-prefix}-cc-stripe:before { content: fa-content($fa-var-cc-stripe); } -.#{$fa-css-prefix}-cc-visa:before { content: fa-content($fa-var-cc-visa); } -.#{$fa-css-prefix}-centercode:before { content: fa-content($fa-var-centercode); } -.#{$fa-css-prefix}-centos:before { content: fa-content($fa-var-centos); } -.#{$fa-css-prefix}-certificate:before { content: fa-content($fa-var-certificate); } -.#{$fa-css-prefix}-chair:before { content: fa-content($fa-var-chair); } -.#{$fa-css-prefix}-chalkboard:before { content: fa-content($fa-var-chalkboard); } -.#{$fa-css-prefix}-chalkboard-teacher:before { content: fa-content($fa-var-chalkboard-teacher); } -.#{$fa-css-prefix}-charging-station:before { content: fa-content($fa-var-charging-station); } -.#{$fa-css-prefix}-chart-area:before { content: fa-content($fa-var-chart-area); } -.#{$fa-css-prefix}-chart-bar:before { content: fa-content($fa-var-chart-bar); } -.#{$fa-css-prefix}-chart-line:before { content: fa-content($fa-var-chart-line); } -.#{$fa-css-prefix}-chart-pie:before { content: fa-content($fa-var-chart-pie); } -.#{$fa-css-prefix}-check:before { content: fa-content($fa-var-check); } -.#{$fa-css-prefix}-check-circle:before { content: fa-content($fa-var-check-circle); } -.#{$fa-css-prefix}-check-double:before { content: fa-content($fa-var-check-double); } -.#{$fa-css-prefix}-check-square:before { content: fa-content($fa-var-check-square); } -.#{$fa-css-prefix}-cheese:before { content: fa-content($fa-var-cheese); } -.#{$fa-css-prefix}-chess:before { content: fa-content($fa-var-chess); } -.#{$fa-css-prefix}-chess-bishop:before { content: fa-content($fa-var-chess-bishop); } -.#{$fa-css-prefix}-chess-board:before { content: fa-content($fa-var-chess-board); } -.#{$fa-css-prefix}-chess-king:before { content: fa-content($fa-var-chess-king); } -.#{$fa-css-prefix}-chess-knight:before { content: fa-content($fa-var-chess-knight); } -.#{$fa-css-prefix}-chess-pawn:before { content: fa-content($fa-var-chess-pawn); } -.#{$fa-css-prefix}-chess-queen:before { content: fa-content($fa-var-chess-queen); } -.#{$fa-css-prefix}-chess-rook:before { content: fa-content($fa-var-chess-rook); } -.#{$fa-css-prefix}-chevron-circle-down:before { content: fa-content($fa-var-chevron-circle-down); } -.#{$fa-css-prefix}-chevron-circle-left:before { content: fa-content($fa-var-chevron-circle-left); } -.#{$fa-css-prefix}-chevron-circle-right:before { content: fa-content($fa-var-chevron-circle-right); } -.#{$fa-css-prefix}-chevron-circle-up:before { content: fa-content($fa-var-chevron-circle-up); } -.#{$fa-css-prefix}-chevron-down:before { content: fa-content($fa-var-chevron-down); } -.#{$fa-css-prefix}-chevron-left:before { content: fa-content($fa-var-chevron-left); } -.#{$fa-css-prefix}-chevron-right:before { content: fa-content($fa-var-chevron-right); } -.#{$fa-css-prefix}-chevron-up:before { content: fa-content($fa-var-chevron-up); } -.#{$fa-css-prefix}-child:before { content: fa-content($fa-var-child); } -.#{$fa-css-prefix}-chrome:before { content: fa-content($fa-var-chrome); } -.#{$fa-css-prefix}-chromecast:before { content: fa-content($fa-var-chromecast); } -.#{$fa-css-prefix}-church:before { content: fa-content($fa-var-church); } -.#{$fa-css-prefix}-circle:before { content: fa-content($fa-var-circle); } -.#{$fa-css-prefix}-circle-notch:before { content: fa-content($fa-var-circle-notch); } -.#{$fa-css-prefix}-city:before { content: fa-content($fa-var-city); } -.#{$fa-css-prefix}-clinic-medical:before { content: fa-content($fa-var-clinic-medical); } -.#{$fa-css-prefix}-clipboard:before { content: fa-content($fa-var-clipboard); } -.#{$fa-css-prefix}-clipboard-check:before { content: fa-content($fa-var-clipboard-check); } -.#{$fa-css-prefix}-clipboard-list:before { content: fa-content($fa-var-clipboard-list); } -.#{$fa-css-prefix}-clock:before { content: fa-content($fa-var-clock); } -.#{$fa-css-prefix}-clone:before { content: fa-content($fa-var-clone); } -.#{$fa-css-prefix}-closed-captioning:before { content: fa-content($fa-var-closed-captioning); } -.#{$fa-css-prefix}-cloud:before { content: fa-content($fa-var-cloud); } -.#{$fa-css-prefix}-cloud-download-alt:before { content: fa-content($fa-var-cloud-download-alt); } -.#{$fa-css-prefix}-cloud-meatball:before { content: fa-content($fa-var-cloud-meatball); } -.#{$fa-css-prefix}-cloud-moon:before { content: fa-content($fa-var-cloud-moon); } -.#{$fa-css-prefix}-cloud-moon-rain:before { content: fa-content($fa-var-cloud-moon-rain); } -.#{$fa-css-prefix}-cloud-rain:before { content: fa-content($fa-var-cloud-rain); } -.#{$fa-css-prefix}-cloud-showers-heavy:before { content: fa-content($fa-var-cloud-showers-heavy); } -.#{$fa-css-prefix}-cloud-sun:before { content: fa-content($fa-var-cloud-sun); } -.#{$fa-css-prefix}-cloud-sun-rain:before { content: fa-content($fa-var-cloud-sun-rain); } -.#{$fa-css-prefix}-cloud-upload-alt:before { content: fa-content($fa-var-cloud-upload-alt); } -.#{$fa-css-prefix}-cloudscale:before { content: fa-content($fa-var-cloudscale); } -.#{$fa-css-prefix}-cloudsmith:before { content: fa-content($fa-var-cloudsmith); } -.#{$fa-css-prefix}-cloudversify:before { content: fa-content($fa-var-cloudversify); } -.#{$fa-css-prefix}-cocktail:before { content: fa-content($fa-var-cocktail); } -.#{$fa-css-prefix}-code:before { content: fa-content($fa-var-code); } -.#{$fa-css-prefix}-code-branch:before { content: fa-content($fa-var-code-branch); } -.#{$fa-css-prefix}-codepen:before { content: fa-content($fa-var-codepen); } -.#{$fa-css-prefix}-codiepie:before { content: fa-content($fa-var-codiepie); } -.#{$fa-css-prefix}-coffee:before { content: fa-content($fa-var-coffee); } -.#{$fa-css-prefix}-cog:before { content: fa-content($fa-var-cog); } -.#{$fa-css-prefix}-cogs:before { content: fa-content($fa-var-cogs); } -.#{$fa-css-prefix}-coins:before { content: fa-content($fa-var-coins); } -.#{$fa-css-prefix}-columns:before { content: fa-content($fa-var-columns); } -.#{$fa-css-prefix}-comment:before { content: fa-content($fa-var-comment); } -.#{$fa-css-prefix}-comment-alt:before { content: fa-content($fa-var-comment-alt); } -.#{$fa-css-prefix}-comment-dollar:before { content: fa-content($fa-var-comment-dollar); } -.#{$fa-css-prefix}-comment-dots:before { content: fa-content($fa-var-comment-dots); } -.#{$fa-css-prefix}-comment-medical:before { content: fa-content($fa-var-comment-medical); } -.#{$fa-css-prefix}-comment-slash:before { content: fa-content($fa-var-comment-slash); } -.#{$fa-css-prefix}-comments:before { content: fa-content($fa-var-comments); } -.#{$fa-css-prefix}-comments-dollar:before { content: fa-content($fa-var-comments-dollar); } -.#{$fa-css-prefix}-compact-disc:before { content: fa-content($fa-var-compact-disc); } -.#{$fa-css-prefix}-compass:before { content: fa-content($fa-var-compass); } -.#{$fa-css-prefix}-compress:before { content: fa-content($fa-var-compress); } -.#{$fa-css-prefix}-compress-alt:before { content: fa-content($fa-var-compress-alt); } -.#{$fa-css-prefix}-compress-arrows-alt:before { content: fa-content($fa-var-compress-arrows-alt); } -.#{$fa-css-prefix}-concierge-bell:before { content: fa-content($fa-var-concierge-bell); } -.#{$fa-css-prefix}-confluence:before { content: fa-content($fa-var-confluence); } -.#{$fa-css-prefix}-connectdevelop:before { content: fa-content($fa-var-connectdevelop); } -.#{$fa-css-prefix}-contao:before { content: fa-content($fa-var-contao); } -.#{$fa-css-prefix}-cookie:before { content: fa-content($fa-var-cookie); } -.#{$fa-css-prefix}-cookie-bite:before { content: fa-content($fa-var-cookie-bite); } -.#{$fa-css-prefix}-copy:before { content: fa-content($fa-var-copy); } -.#{$fa-css-prefix}-copyright:before { content: fa-content($fa-var-copyright); } -.#{$fa-css-prefix}-cotton-bureau:before { content: fa-content($fa-var-cotton-bureau); } -.#{$fa-css-prefix}-couch:before { content: fa-content($fa-var-couch); } -.#{$fa-css-prefix}-cpanel:before { content: fa-content($fa-var-cpanel); } -.#{$fa-css-prefix}-creative-commons:before { content: fa-content($fa-var-creative-commons); } -.#{$fa-css-prefix}-creative-commons-by:before { content: fa-content($fa-var-creative-commons-by); } -.#{$fa-css-prefix}-creative-commons-nc:before { content: fa-content($fa-var-creative-commons-nc); } -.#{$fa-css-prefix}-creative-commons-nc-eu:before { content: fa-content($fa-var-creative-commons-nc-eu); } -.#{$fa-css-prefix}-creative-commons-nc-jp:before { content: fa-content($fa-var-creative-commons-nc-jp); } -.#{$fa-css-prefix}-creative-commons-nd:before { content: fa-content($fa-var-creative-commons-nd); } -.#{$fa-css-prefix}-creative-commons-pd:before { content: fa-content($fa-var-creative-commons-pd); } -.#{$fa-css-prefix}-creative-commons-pd-alt:before { content: fa-content($fa-var-creative-commons-pd-alt); } -.#{$fa-css-prefix}-creative-commons-remix:before { content: fa-content($fa-var-creative-commons-remix); } -.#{$fa-css-prefix}-creative-commons-sa:before { content: fa-content($fa-var-creative-commons-sa); } -.#{$fa-css-prefix}-creative-commons-sampling:before { content: fa-content($fa-var-creative-commons-sampling); } -.#{$fa-css-prefix}-creative-commons-sampling-plus:before { content: fa-content($fa-var-creative-commons-sampling-plus); } -.#{$fa-css-prefix}-creative-commons-share:before { content: fa-content($fa-var-creative-commons-share); } -.#{$fa-css-prefix}-creative-commons-zero:before { content: fa-content($fa-var-creative-commons-zero); } -.#{$fa-css-prefix}-credit-card:before { content: fa-content($fa-var-credit-card); } -.#{$fa-css-prefix}-critical-role:before { content: fa-content($fa-var-critical-role); } -.#{$fa-css-prefix}-crop:before { content: fa-content($fa-var-crop); } -.#{$fa-css-prefix}-crop-alt:before { content: fa-content($fa-var-crop-alt); } -.#{$fa-css-prefix}-cross:before { content: fa-content($fa-var-cross); } -.#{$fa-css-prefix}-crosshairs:before { content: fa-content($fa-var-crosshairs); } -.#{$fa-css-prefix}-crow:before { content: fa-content($fa-var-crow); } -.#{$fa-css-prefix}-crown:before { content: fa-content($fa-var-crown); } -.#{$fa-css-prefix}-crutch:before { content: fa-content($fa-var-crutch); } -.#{$fa-css-prefix}-css3:before { content: fa-content($fa-var-css3); } -.#{$fa-css-prefix}-css3-alt:before { content: fa-content($fa-var-css3-alt); } -.#{$fa-css-prefix}-cube:before { content: fa-content($fa-var-cube); } -.#{$fa-css-prefix}-cubes:before { content: fa-content($fa-var-cubes); } -.#{$fa-css-prefix}-cut:before { content: fa-content($fa-var-cut); } -.#{$fa-css-prefix}-cuttlefish:before { content: fa-content($fa-var-cuttlefish); } -.#{$fa-css-prefix}-d-and-d:before { content: fa-content($fa-var-d-and-d); } -.#{$fa-css-prefix}-d-and-d-beyond:before { content: fa-content($fa-var-d-and-d-beyond); } -.#{$fa-css-prefix}-dailymotion:before { content: fa-content($fa-var-dailymotion); } -.#{$fa-css-prefix}-dashcube:before { content: fa-content($fa-var-dashcube); } -.#{$fa-css-prefix}-database:before { content: fa-content($fa-var-database); } -.#{$fa-css-prefix}-deaf:before { content: fa-content($fa-var-deaf); } -.#{$fa-css-prefix}-deezer:before { content: fa-content($fa-var-deezer); } -.#{$fa-css-prefix}-delicious:before { content: fa-content($fa-var-delicious); } -.#{$fa-css-prefix}-democrat:before { content: fa-content($fa-var-democrat); } -.#{$fa-css-prefix}-deploydog:before { content: fa-content($fa-var-deploydog); } -.#{$fa-css-prefix}-deskpro:before { content: fa-content($fa-var-deskpro); } -.#{$fa-css-prefix}-desktop:before { content: fa-content($fa-var-desktop); } -.#{$fa-css-prefix}-dev:before { content: fa-content($fa-var-dev); } -.#{$fa-css-prefix}-deviantart:before { content: fa-content($fa-var-deviantart); } -.#{$fa-css-prefix}-dharmachakra:before { content: fa-content($fa-var-dharmachakra); } -.#{$fa-css-prefix}-dhl:before { content: fa-content($fa-var-dhl); } -.#{$fa-css-prefix}-diagnoses:before { content: fa-content($fa-var-diagnoses); } -.#{$fa-css-prefix}-diaspora:before { content: fa-content($fa-var-diaspora); } -.#{$fa-css-prefix}-dice:before { content: fa-content($fa-var-dice); } -.#{$fa-css-prefix}-dice-d20:before { content: fa-content($fa-var-dice-d20); } -.#{$fa-css-prefix}-dice-d6:before { content: fa-content($fa-var-dice-d6); } -.#{$fa-css-prefix}-dice-five:before { content: fa-content($fa-var-dice-five); } -.#{$fa-css-prefix}-dice-four:before { content: fa-content($fa-var-dice-four); } -.#{$fa-css-prefix}-dice-one:before { content: fa-content($fa-var-dice-one); } -.#{$fa-css-prefix}-dice-six:before { content: fa-content($fa-var-dice-six); } -.#{$fa-css-prefix}-dice-three:before { content: fa-content($fa-var-dice-three); } -.#{$fa-css-prefix}-dice-two:before { content: fa-content($fa-var-dice-two); } -.#{$fa-css-prefix}-digg:before { content: fa-content($fa-var-digg); } -.#{$fa-css-prefix}-digital-ocean:before { content: fa-content($fa-var-digital-ocean); } -.#{$fa-css-prefix}-digital-tachograph:before { content: fa-content($fa-var-digital-tachograph); } -.#{$fa-css-prefix}-directions:before { content: fa-content($fa-var-directions); } -.#{$fa-css-prefix}-discord:before { content: fa-content($fa-var-discord); } -.#{$fa-css-prefix}-discourse:before { content: fa-content($fa-var-discourse); } -.#{$fa-css-prefix}-disease:before { content: fa-content($fa-var-disease); } -.#{$fa-css-prefix}-divide:before { content: fa-content($fa-var-divide); } -.#{$fa-css-prefix}-dizzy:before { content: fa-content($fa-var-dizzy); } -.#{$fa-css-prefix}-dna:before { content: fa-content($fa-var-dna); } -.#{$fa-css-prefix}-dochub:before { content: fa-content($fa-var-dochub); } -.#{$fa-css-prefix}-docker:before { content: fa-content($fa-var-docker); } -.#{$fa-css-prefix}-dog:before { content: fa-content($fa-var-dog); } -.#{$fa-css-prefix}-dollar-sign:before { content: fa-content($fa-var-dollar-sign); } -.#{$fa-css-prefix}-dolly:before { content: fa-content($fa-var-dolly); } -.#{$fa-css-prefix}-dolly-flatbed:before { content: fa-content($fa-var-dolly-flatbed); } -.#{$fa-css-prefix}-donate:before { content: fa-content($fa-var-donate); } -.#{$fa-css-prefix}-door-closed:before { content: fa-content($fa-var-door-closed); } -.#{$fa-css-prefix}-door-open:before { content: fa-content($fa-var-door-open); } -.#{$fa-css-prefix}-dot-circle:before { content: fa-content($fa-var-dot-circle); } -.#{$fa-css-prefix}-dove:before { content: fa-content($fa-var-dove); } -.#{$fa-css-prefix}-download:before { content: fa-content($fa-var-download); } -.#{$fa-css-prefix}-draft2digital:before { content: fa-content($fa-var-draft2digital); } -.#{$fa-css-prefix}-drafting-compass:before { content: fa-content($fa-var-drafting-compass); } -.#{$fa-css-prefix}-dragon:before { content: fa-content($fa-var-dragon); } -.#{$fa-css-prefix}-draw-polygon:before { content: fa-content($fa-var-draw-polygon); } -.#{$fa-css-prefix}-dribbble:before { content: fa-content($fa-var-dribbble); } -.#{$fa-css-prefix}-dribbble-square:before { content: fa-content($fa-var-dribbble-square); } -.#{$fa-css-prefix}-dropbox:before { content: fa-content($fa-var-dropbox); } -.#{$fa-css-prefix}-drum:before { content: fa-content($fa-var-drum); } -.#{$fa-css-prefix}-drum-steelpan:before { content: fa-content($fa-var-drum-steelpan); } -.#{$fa-css-prefix}-drumstick-bite:before { content: fa-content($fa-var-drumstick-bite); } -.#{$fa-css-prefix}-drupal:before { content: fa-content($fa-var-drupal); } -.#{$fa-css-prefix}-dumbbell:before { content: fa-content($fa-var-dumbbell); } -.#{$fa-css-prefix}-dumpster:before { content: fa-content($fa-var-dumpster); } -.#{$fa-css-prefix}-dumpster-fire:before { content: fa-content($fa-var-dumpster-fire); } -.#{$fa-css-prefix}-dungeon:before { content: fa-content($fa-var-dungeon); } -.#{$fa-css-prefix}-dyalog:before { content: fa-content($fa-var-dyalog); } -.#{$fa-css-prefix}-earlybirds:before { content: fa-content($fa-var-earlybirds); } -.#{$fa-css-prefix}-ebay:before { content: fa-content($fa-var-ebay); } -.#{$fa-css-prefix}-edge:before { content: fa-content($fa-var-edge); } -.#{$fa-css-prefix}-edge-legacy:before { content: fa-content($fa-var-edge-legacy); } -.#{$fa-css-prefix}-edit:before { content: fa-content($fa-var-edit); } -.#{$fa-css-prefix}-egg:before { content: fa-content($fa-var-egg); } -.#{$fa-css-prefix}-eject:before { content: fa-content($fa-var-eject); } -.#{$fa-css-prefix}-elementor:before { content: fa-content($fa-var-elementor); } -.#{$fa-css-prefix}-ellipsis-h:before { content: fa-content($fa-var-ellipsis-h); } -.#{$fa-css-prefix}-ellipsis-v:before { content: fa-content($fa-var-ellipsis-v); } -.#{$fa-css-prefix}-ello:before { content: fa-content($fa-var-ello); } -.#{$fa-css-prefix}-ember:before { content: fa-content($fa-var-ember); } -.#{$fa-css-prefix}-empire:before { content: fa-content($fa-var-empire); } -.#{$fa-css-prefix}-envelope:before { content: fa-content($fa-var-envelope); } -.#{$fa-css-prefix}-envelope-open:before { content: fa-content($fa-var-envelope-open); } -.#{$fa-css-prefix}-envelope-open-text:before { content: fa-content($fa-var-envelope-open-text); } -.#{$fa-css-prefix}-envelope-square:before { content: fa-content($fa-var-envelope-square); } -.#{$fa-css-prefix}-envira:before { content: fa-content($fa-var-envira); } -.#{$fa-css-prefix}-equals:before { content: fa-content($fa-var-equals); } -.#{$fa-css-prefix}-eraser:before { content: fa-content($fa-var-eraser); } -.#{$fa-css-prefix}-erlang:before { content: fa-content($fa-var-erlang); } -.#{$fa-css-prefix}-ethereum:before { content: fa-content($fa-var-ethereum); } -.#{$fa-css-prefix}-ethernet:before { content: fa-content($fa-var-ethernet); } -.#{$fa-css-prefix}-etsy:before { content: fa-content($fa-var-etsy); } -.#{$fa-css-prefix}-euro-sign:before { content: fa-content($fa-var-euro-sign); } -.#{$fa-css-prefix}-evernote:before { content: fa-content($fa-var-evernote); } -.#{$fa-css-prefix}-exchange-alt:before { content: fa-content($fa-var-exchange-alt); } -.#{$fa-css-prefix}-exclamation:before { content: fa-content($fa-var-exclamation); } -.#{$fa-css-prefix}-exclamation-circle:before { content: fa-content($fa-var-exclamation-circle); } -.#{$fa-css-prefix}-exclamation-triangle:before { content: fa-content($fa-var-exclamation-triangle); } -.#{$fa-css-prefix}-expand:before { content: fa-content($fa-var-expand); } -.#{$fa-css-prefix}-expand-alt:before { content: fa-content($fa-var-expand-alt); } -.#{$fa-css-prefix}-expand-arrows-alt:before { content: fa-content($fa-var-expand-arrows-alt); } -.#{$fa-css-prefix}-expeditedssl:before { content: fa-content($fa-var-expeditedssl); } -.#{$fa-css-prefix}-external-link-alt:before { content: fa-content($fa-var-external-link-alt); } -.#{$fa-css-prefix}-external-link-square-alt:before { content: fa-content($fa-var-external-link-square-alt); } -.#{$fa-css-prefix}-eye:before { content: fa-content($fa-var-eye); } -.#{$fa-css-prefix}-eye-dropper:before { content: fa-content($fa-var-eye-dropper); } -.#{$fa-css-prefix}-eye-slash:before { content: fa-content($fa-var-eye-slash); } -.#{$fa-css-prefix}-facebook:before { content: fa-content($fa-var-facebook); } -.#{$fa-css-prefix}-facebook-f:before { content: fa-content($fa-var-facebook-f); } -.#{$fa-css-prefix}-facebook-messenger:before { content: fa-content($fa-var-facebook-messenger); } -.#{$fa-css-prefix}-facebook-square:before { content: fa-content($fa-var-facebook-square); } -.#{$fa-css-prefix}-fan:before { content: fa-content($fa-var-fan); } -.#{$fa-css-prefix}-fantasy-flight-games:before { content: fa-content($fa-var-fantasy-flight-games); } -.#{$fa-css-prefix}-fast-backward:before { content: fa-content($fa-var-fast-backward); } -.#{$fa-css-prefix}-fast-forward:before { content: fa-content($fa-var-fast-forward); } -.#{$fa-css-prefix}-faucet:before { content: fa-content($fa-var-faucet); } -.#{$fa-css-prefix}-fax:before { content: fa-content($fa-var-fax); } -.#{$fa-css-prefix}-feather:before { content: fa-content($fa-var-feather); } -.#{$fa-css-prefix}-feather-alt:before { content: fa-content($fa-var-feather-alt); } -.#{$fa-css-prefix}-fedex:before { content: fa-content($fa-var-fedex); } -.#{$fa-css-prefix}-fedora:before { content: fa-content($fa-var-fedora); } -.#{$fa-css-prefix}-female:before { content: fa-content($fa-var-female); } -.#{$fa-css-prefix}-fighter-jet:before { content: fa-content($fa-var-fighter-jet); } -.#{$fa-css-prefix}-figma:before { content: fa-content($fa-var-figma); } -.#{$fa-css-prefix}-file:before { content: fa-content($fa-var-file); } -.#{$fa-css-prefix}-file-alt:before { content: fa-content($fa-var-file-alt); } -.#{$fa-css-prefix}-file-archive:before { content: fa-content($fa-var-file-archive); } -.#{$fa-css-prefix}-file-audio:before { content: fa-content($fa-var-file-audio); } -.#{$fa-css-prefix}-file-code:before { content: fa-content($fa-var-file-code); } -.#{$fa-css-prefix}-file-contract:before { content: fa-content($fa-var-file-contract); } -.#{$fa-css-prefix}-file-csv:before { content: fa-content($fa-var-file-csv); } -.#{$fa-css-prefix}-file-download:before { content: fa-content($fa-var-file-download); } -.#{$fa-css-prefix}-file-excel:before { content: fa-content($fa-var-file-excel); } -.#{$fa-css-prefix}-file-export:before { content: fa-content($fa-var-file-export); } -.#{$fa-css-prefix}-file-image:before { content: fa-content($fa-var-file-image); } -.#{$fa-css-prefix}-file-import:before { content: fa-content($fa-var-file-import); } -.#{$fa-css-prefix}-file-invoice:before { content: fa-content($fa-var-file-invoice); } -.#{$fa-css-prefix}-file-invoice-dollar:before { content: fa-content($fa-var-file-invoice-dollar); } -.#{$fa-css-prefix}-file-medical:before { content: fa-content($fa-var-file-medical); } -.#{$fa-css-prefix}-file-medical-alt:before { content: fa-content($fa-var-file-medical-alt); } -.#{$fa-css-prefix}-file-pdf:before { content: fa-content($fa-var-file-pdf); } -.#{$fa-css-prefix}-file-powerpoint:before { content: fa-content($fa-var-file-powerpoint); } -.#{$fa-css-prefix}-file-prescription:before { content: fa-content($fa-var-file-prescription); } -.#{$fa-css-prefix}-file-signature:before { content: fa-content($fa-var-file-signature); } -.#{$fa-css-prefix}-file-upload:before { content: fa-content($fa-var-file-upload); } -.#{$fa-css-prefix}-file-video:before { content: fa-content($fa-var-file-video); } -.#{$fa-css-prefix}-file-word:before { content: fa-content($fa-var-file-word); } -.#{$fa-css-prefix}-fill:before { content: fa-content($fa-var-fill); } -.#{$fa-css-prefix}-fill-drip:before { content: fa-content($fa-var-fill-drip); } -.#{$fa-css-prefix}-film:before { content: fa-content($fa-var-film); } -.#{$fa-css-prefix}-filter:before { content: fa-content($fa-var-filter); } -.#{$fa-css-prefix}-fingerprint:before { content: fa-content($fa-var-fingerprint); } -.#{$fa-css-prefix}-fire:before { content: fa-content($fa-var-fire); } -.#{$fa-css-prefix}-fire-alt:before { content: fa-content($fa-var-fire-alt); } -.#{$fa-css-prefix}-fire-extinguisher:before { content: fa-content($fa-var-fire-extinguisher); } -.#{$fa-css-prefix}-firefox:before { content: fa-content($fa-var-firefox); } -.#{$fa-css-prefix}-firefox-browser:before { content: fa-content($fa-var-firefox-browser); } -.#{$fa-css-prefix}-first-aid:before { content: fa-content($fa-var-first-aid); } -.#{$fa-css-prefix}-first-order:before { content: fa-content($fa-var-first-order); } -.#{$fa-css-prefix}-first-order-alt:before { content: fa-content($fa-var-first-order-alt); } -.#{$fa-css-prefix}-firstdraft:before { content: fa-content($fa-var-firstdraft); } -.#{$fa-css-prefix}-fish:before { content: fa-content($fa-var-fish); } -.#{$fa-css-prefix}-fist-raised:before { content: fa-content($fa-var-fist-raised); } -.#{$fa-css-prefix}-flag:before { content: fa-content($fa-var-flag); } -.#{$fa-css-prefix}-flag-checkered:before { content: fa-content($fa-var-flag-checkered); } -.#{$fa-css-prefix}-flag-usa:before { content: fa-content($fa-var-flag-usa); } -.#{$fa-css-prefix}-flask:before { content: fa-content($fa-var-flask); } -.#{$fa-css-prefix}-flickr:before { content: fa-content($fa-var-flickr); } -.#{$fa-css-prefix}-flipboard:before { content: fa-content($fa-var-flipboard); } -.#{$fa-css-prefix}-flushed:before { content: fa-content($fa-var-flushed); } -.#{$fa-css-prefix}-fly:before { content: fa-content($fa-var-fly); } -.#{$fa-css-prefix}-folder:before { content: fa-content($fa-var-folder); } -.#{$fa-css-prefix}-folder-minus:before { content: fa-content($fa-var-folder-minus); } -.#{$fa-css-prefix}-folder-open:before { content: fa-content($fa-var-folder-open); } -.#{$fa-css-prefix}-folder-plus:before { content: fa-content($fa-var-folder-plus); } -.#{$fa-css-prefix}-font:before { content: fa-content($fa-var-font); } -.#{$fa-css-prefix}-font-awesome:before { content: fa-content($fa-var-font-awesome); } -.#{$fa-css-prefix}-font-awesome-alt:before { content: fa-content($fa-var-font-awesome-alt); } -.#{$fa-css-prefix}-font-awesome-flag:before { content: fa-content($fa-var-font-awesome-flag); } -.#{$fa-css-prefix}-font-awesome-logo-full:before { content: fa-content($fa-var-font-awesome-logo-full); } -.#{$fa-css-prefix}-fonticons:before { content: fa-content($fa-var-fonticons); } -.#{$fa-css-prefix}-fonticons-fi:before { content: fa-content($fa-var-fonticons-fi); } -.#{$fa-css-prefix}-football-ball:before { content: fa-content($fa-var-football-ball); } -.#{$fa-css-prefix}-fort-awesome:before { content: fa-content($fa-var-fort-awesome); } -.#{$fa-css-prefix}-fort-awesome-alt:before { content: fa-content($fa-var-fort-awesome-alt); } -.#{$fa-css-prefix}-forumbee:before { content: fa-content($fa-var-forumbee); } -.#{$fa-css-prefix}-forward:before { content: fa-content($fa-var-forward); } -.#{$fa-css-prefix}-foursquare:before { content: fa-content($fa-var-foursquare); } -.#{$fa-css-prefix}-free-code-camp:before { content: fa-content($fa-var-free-code-camp); } -.#{$fa-css-prefix}-freebsd:before { content: fa-content($fa-var-freebsd); } -.#{$fa-css-prefix}-frog:before { content: fa-content($fa-var-frog); } -.#{$fa-css-prefix}-frown:before { content: fa-content($fa-var-frown); } -.#{$fa-css-prefix}-frown-open:before { content: fa-content($fa-var-frown-open); } -.#{$fa-css-prefix}-fulcrum:before { content: fa-content($fa-var-fulcrum); } -.#{$fa-css-prefix}-funnel-dollar:before { content: fa-content($fa-var-funnel-dollar); } -.#{$fa-css-prefix}-futbol:before { content: fa-content($fa-var-futbol); } -.#{$fa-css-prefix}-galactic-republic:before { content: fa-content($fa-var-galactic-republic); } -.#{$fa-css-prefix}-galactic-senate:before { content: fa-content($fa-var-galactic-senate); } -.#{$fa-css-prefix}-gamepad:before { content: fa-content($fa-var-gamepad); } -.#{$fa-css-prefix}-gas-pump:before { content: fa-content($fa-var-gas-pump); } -.#{$fa-css-prefix}-gavel:before { content: fa-content($fa-var-gavel); } -.#{$fa-css-prefix}-gem:before { content: fa-content($fa-var-gem); } -.#{$fa-css-prefix}-genderless:before { content: fa-content($fa-var-genderless); } -.#{$fa-css-prefix}-get-pocket:before { content: fa-content($fa-var-get-pocket); } -.#{$fa-css-prefix}-gg:before { content: fa-content($fa-var-gg); } -.#{$fa-css-prefix}-gg-circle:before { content: fa-content($fa-var-gg-circle); } -.#{$fa-css-prefix}-ghost:before { content: fa-content($fa-var-ghost); } -.#{$fa-css-prefix}-gift:before { content: fa-content($fa-var-gift); } -.#{$fa-css-prefix}-gifts:before { content: fa-content($fa-var-gifts); } -.#{$fa-css-prefix}-git:before { content: fa-content($fa-var-git); } -.#{$fa-css-prefix}-git-alt:before { content: fa-content($fa-var-git-alt); } -.#{$fa-css-prefix}-git-square:before { content: fa-content($fa-var-git-square); } -.#{$fa-css-prefix}-github:before { content: fa-content($fa-var-github); } -.#{$fa-css-prefix}-github-alt:before { content: fa-content($fa-var-github-alt); } -.#{$fa-css-prefix}-github-square:before { content: fa-content($fa-var-github-square); } -.#{$fa-css-prefix}-gitkraken:before { content: fa-content($fa-var-gitkraken); } -.#{$fa-css-prefix}-gitlab:before { content: fa-content($fa-var-gitlab); } -.#{$fa-css-prefix}-gitter:before { content: fa-content($fa-var-gitter); } -.#{$fa-css-prefix}-glass-cheers:before { content: fa-content($fa-var-glass-cheers); } -.#{$fa-css-prefix}-glass-martini:before { content: fa-content($fa-var-glass-martini); } -.#{$fa-css-prefix}-glass-martini-alt:before { content: fa-content($fa-var-glass-martini-alt); } -.#{$fa-css-prefix}-glass-whiskey:before { content: fa-content($fa-var-glass-whiskey); } -.#{$fa-css-prefix}-glasses:before { content: fa-content($fa-var-glasses); } -.#{$fa-css-prefix}-glide:before { content: fa-content($fa-var-glide); } -.#{$fa-css-prefix}-glide-g:before { content: fa-content($fa-var-glide-g); } -.#{$fa-css-prefix}-globe:before { content: fa-content($fa-var-globe); } -.#{$fa-css-prefix}-globe-africa:before { content: fa-content($fa-var-globe-africa); } -.#{$fa-css-prefix}-globe-americas:before { content: fa-content($fa-var-globe-americas); } -.#{$fa-css-prefix}-globe-asia:before { content: fa-content($fa-var-globe-asia); } -.#{$fa-css-prefix}-globe-europe:before { content: fa-content($fa-var-globe-europe); } -.#{$fa-css-prefix}-gofore:before { content: fa-content($fa-var-gofore); } -.#{$fa-css-prefix}-golf-ball:before { content: fa-content($fa-var-golf-ball); } -.#{$fa-css-prefix}-goodreads:before { content: fa-content($fa-var-goodreads); } -.#{$fa-css-prefix}-goodreads-g:before { content: fa-content($fa-var-goodreads-g); } -.#{$fa-css-prefix}-google:before { content: fa-content($fa-var-google); } -.#{$fa-css-prefix}-google-drive:before { content: fa-content($fa-var-google-drive); } -.#{$fa-css-prefix}-google-pay:before { content: fa-content($fa-var-google-pay); } -.#{$fa-css-prefix}-google-play:before { content: fa-content($fa-var-google-play); } -.#{$fa-css-prefix}-google-plus:before { content: fa-content($fa-var-google-plus); } -.#{$fa-css-prefix}-google-plus-g:before { content: fa-content($fa-var-google-plus-g); } -.#{$fa-css-prefix}-google-plus-square:before { content: fa-content($fa-var-google-plus-square); } -.#{$fa-css-prefix}-google-wallet:before { content: fa-content($fa-var-google-wallet); } -.#{$fa-css-prefix}-gopuram:before { content: fa-content($fa-var-gopuram); } -.#{$fa-css-prefix}-graduation-cap:before { content: fa-content($fa-var-graduation-cap); } -.#{$fa-css-prefix}-gratipay:before { content: fa-content($fa-var-gratipay); } -.#{$fa-css-prefix}-grav:before { content: fa-content($fa-var-grav); } -.#{$fa-css-prefix}-greater-than:before { content: fa-content($fa-var-greater-than); } -.#{$fa-css-prefix}-greater-than-equal:before { content: fa-content($fa-var-greater-than-equal); } -.#{$fa-css-prefix}-grimace:before { content: fa-content($fa-var-grimace); } -.#{$fa-css-prefix}-grin:before { content: fa-content($fa-var-grin); } -.#{$fa-css-prefix}-grin-alt:before { content: fa-content($fa-var-grin-alt); } -.#{$fa-css-prefix}-grin-beam:before { content: fa-content($fa-var-grin-beam); } -.#{$fa-css-prefix}-grin-beam-sweat:before { content: fa-content($fa-var-grin-beam-sweat); } -.#{$fa-css-prefix}-grin-hearts:before { content: fa-content($fa-var-grin-hearts); } -.#{$fa-css-prefix}-grin-squint:before { content: fa-content($fa-var-grin-squint); } -.#{$fa-css-prefix}-grin-squint-tears:before { content: fa-content($fa-var-grin-squint-tears); } -.#{$fa-css-prefix}-grin-stars:before { content: fa-content($fa-var-grin-stars); } -.#{$fa-css-prefix}-grin-tears:before { content: fa-content($fa-var-grin-tears); } -.#{$fa-css-prefix}-grin-tongue:before { content: fa-content($fa-var-grin-tongue); } -.#{$fa-css-prefix}-grin-tongue-squint:before { content: fa-content($fa-var-grin-tongue-squint); } -.#{$fa-css-prefix}-grin-tongue-wink:before { content: fa-content($fa-var-grin-tongue-wink); } -.#{$fa-css-prefix}-grin-wink:before { content: fa-content($fa-var-grin-wink); } -.#{$fa-css-prefix}-grip-horizontal:before { content: fa-content($fa-var-grip-horizontal); } -.#{$fa-css-prefix}-grip-lines:before { content: fa-content($fa-var-grip-lines); } -.#{$fa-css-prefix}-grip-lines-vertical:before { content: fa-content($fa-var-grip-lines-vertical); } -.#{$fa-css-prefix}-grip-vertical:before { content: fa-content($fa-var-grip-vertical); } -.#{$fa-css-prefix}-gripfire:before { content: fa-content($fa-var-gripfire); } -.#{$fa-css-prefix}-grunt:before { content: fa-content($fa-var-grunt); } -.#{$fa-css-prefix}-guitar:before { content: fa-content($fa-var-guitar); } -.#{$fa-css-prefix}-gulp:before { content: fa-content($fa-var-gulp); } -.#{$fa-css-prefix}-h-square:before { content: fa-content($fa-var-h-square); } -.#{$fa-css-prefix}-hacker-news:before { content: fa-content($fa-var-hacker-news); } -.#{$fa-css-prefix}-hacker-news-square:before { content: fa-content($fa-var-hacker-news-square); } -.#{$fa-css-prefix}-hackerrank:before { content: fa-content($fa-var-hackerrank); } -.#{$fa-css-prefix}-hamburger:before { content: fa-content($fa-var-hamburger); } -.#{$fa-css-prefix}-hammer:before { content: fa-content($fa-var-hammer); } -.#{$fa-css-prefix}-hamsa:before { content: fa-content($fa-var-hamsa); } -.#{$fa-css-prefix}-hand-holding:before { content: fa-content($fa-var-hand-holding); } -.#{$fa-css-prefix}-hand-holding-heart:before { content: fa-content($fa-var-hand-holding-heart); } -.#{$fa-css-prefix}-hand-holding-medical:before { content: fa-content($fa-var-hand-holding-medical); } -.#{$fa-css-prefix}-hand-holding-usd:before { content: fa-content($fa-var-hand-holding-usd); } -.#{$fa-css-prefix}-hand-holding-water:before { content: fa-content($fa-var-hand-holding-water); } -.#{$fa-css-prefix}-hand-lizard:before { content: fa-content($fa-var-hand-lizard); } -.#{$fa-css-prefix}-hand-middle-finger:before { content: fa-content($fa-var-hand-middle-finger); } -.#{$fa-css-prefix}-hand-paper:before { content: fa-content($fa-var-hand-paper); } -.#{$fa-css-prefix}-hand-peace:before { content: fa-content($fa-var-hand-peace); } -.#{$fa-css-prefix}-hand-point-down:before { content: fa-content($fa-var-hand-point-down); } -.#{$fa-css-prefix}-hand-point-left:before { content: fa-content($fa-var-hand-point-left); } -.#{$fa-css-prefix}-hand-point-right:before { content: fa-content($fa-var-hand-point-right); } -.#{$fa-css-prefix}-hand-point-up:before { content: fa-content($fa-var-hand-point-up); } -.#{$fa-css-prefix}-hand-pointer:before { content: fa-content($fa-var-hand-pointer); } -.#{$fa-css-prefix}-hand-rock:before { content: fa-content($fa-var-hand-rock); } -.#{$fa-css-prefix}-hand-scissors:before { content: fa-content($fa-var-hand-scissors); } -.#{$fa-css-prefix}-hand-sparkles:before { content: fa-content($fa-var-hand-sparkles); } -.#{$fa-css-prefix}-hand-spock:before { content: fa-content($fa-var-hand-spock); } -.#{$fa-css-prefix}-hands:before { content: fa-content($fa-var-hands); } -.#{$fa-css-prefix}-hands-helping:before { content: fa-content($fa-var-hands-helping); } -.#{$fa-css-prefix}-hands-wash:before { content: fa-content($fa-var-hands-wash); } -.#{$fa-css-prefix}-handshake:before { content: fa-content($fa-var-handshake); } -.#{$fa-css-prefix}-handshake-alt-slash:before { content: fa-content($fa-var-handshake-alt-slash); } -.#{$fa-css-prefix}-handshake-slash:before { content: fa-content($fa-var-handshake-slash); } -.#{$fa-css-prefix}-hanukiah:before { content: fa-content($fa-var-hanukiah); } -.#{$fa-css-prefix}-hard-hat:before { content: fa-content($fa-var-hard-hat); } -.#{$fa-css-prefix}-hashtag:before { content: fa-content($fa-var-hashtag); } -.#{$fa-css-prefix}-hat-cowboy:before { content: fa-content($fa-var-hat-cowboy); } -.#{$fa-css-prefix}-hat-cowboy-side:before { content: fa-content($fa-var-hat-cowboy-side); } -.#{$fa-css-prefix}-hat-wizard:before { content: fa-content($fa-var-hat-wizard); } -.#{$fa-css-prefix}-hdd:before { content: fa-content($fa-var-hdd); } -.#{$fa-css-prefix}-head-side-cough:before { content: fa-content($fa-var-head-side-cough); } -.#{$fa-css-prefix}-head-side-cough-slash:before { content: fa-content($fa-var-head-side-cough-slash); } -.#{$fa-css-prefix}-head-side-mask:before { content: fa-content($fa-var-head-side-mask); } -.#{$fa-css-prefix}-head-side-virus:before { content: fa-content($fa-var-head-side-virus); } -.#{$fa-css-prefix}-heading:before { content: fa-content($fa-var-heading); } -.#{$fa-css-prefix}-headphones:before { content: fa-content($fa-var-headphones); } -.#{$fa-css-prefix}-headphones-alt:before { content: fa-content($fa-var-headphones-alt); } -.#{$fa-css-prefix}-headset:before { content: fa-content($fa-var-headset); } -.#{$fa-css-prefix}-heart:before { content: fa-content($fa-var-heart); } -.#{$fa-css-prefix}-heart-broken:before { content: fa-content($fa-var-heart-broken); } -.#{$fa-css-prefix}-heartbeat:before { content: fa-content($fa-var-heartbeat); } -.#{$fa-css-prefix}-helicopter:before { content: fa-content($fa-var-helicopter); } -.#{$fa-css-prefix}-highlighter:before { content: fa-content($fa-var-highlighter); } -.#{$fa-css-prefix}-hiking:before { content: fa-content($fa-var-hiking); } -.#{$fa-css-prefix}-hippo:before { content: fa-content($fa-var-hippo); } -.#{$fa-css-prefix}-hips:before { content: fa-content($fa-var-hips); } -.#{$fa-css-prefix}-hire-a-helper:before { content: fa-content($fa-var-hire-a-helper); } -.#{$fa-css-prefix}-history:before { content: fa-content($fa-var-history); } -.#{$fa-css-prefix}-hockey-puck:before { content: fa-content($fa-var-hockey-puck); } -.#{$fa-css-prefix}-holly-berry:before { content: fa-content($fa-var-holly-berry); } -.#{$fa-css-prefix}-home:before { content: fa-content($fa-var-home); } -.#{$fa-css-prefix}-hooli:before { content: fa-content($fa-var-hooli); } -.#{$fa-css-prefix}-hornbill:before { content: fa-content($fa-var-hornbill); } -.#{$fa-css-prefix}-horse:before { content: fa-content($fa-var-horse); } -.#{$fa-css-prefix}-horse-head:before { content: fa-content($fa-var-horse-head); } -.#{$fa-css-prefix}-hospital:before { content: fa-content($fa-var-hospital); } -.#{$fa-css-prefix}-hospital-alt:before { content: fa-content($fa-var-hospital-alt); } -.#{$fa-css-prefix}-hospital-symbol:before { content: fa-content($fa-var-hospital-symbol); } -.#{$fa-css-prefix}-hospital-user:before { content: fa-content($fa-var-hospital-user); } -.#{$fa-css-prefix}-hot-tub:before { content: fa-content($fa-var-hot-tub); } -.#{$fa-css-prefix}-hotdog:before { content: fa-content($fa-var-hotdog); } -.#{$fa-css-prefix}-hotel:before { content: fa-content($fa-var-hotel); } -.#{$fa-css-prefix}-hotjar:before { content: fa-content($fa-var-hotjar); } -.#{$fa-css-prefix}-hourglass:before { content: fa-content($fa-var-hourglass); } -.#{$fa-css-prefix}-hourglass-end:before { content: fa-content($fa-var-hourglass-end); } -.#{$fa-css-prefix}-hourglass-half:before { content: fa-content($fa-var-hourglass-half); } -.#{$fa-css-prefix}-hourglass-start:before { content: fa-content($fa-var-hourglass-start); } -.#{$fa-css-prefix}-house-damage:before { content: fa-content($fa-var-house-damage); } -.#{$fa-css-prefix}-house-user:before { content: fa-content($fa-var-house-user); } -.#{$fa-css-prefix}-houzz:before { content: fa-content($fa-var-houzz); } -.#{$fa-css-prefix}-hryvnia:before { content: fa-content($fa-var-hryvnia); } -.#{$fa-css-prefix}-html5:before { content: fa-content($fa-var-html5); } -.#{$fa-css-prefix}-hubspot:before { content: fa-content($fa-var-hubspot); } -.#{$fa-css-prefix}-i-cursor:before { content: fa-content($fa-var-i-cursor); } -.#{$fa-css-prefix}-ice-cream:before { content: fa-content($fa-var-ice-cream); } -.#{$fa-css-prefix}-icicles:before { content: fa-content($fa-var-icicles); } -.#{$fa-css-prefix}-icons:before { content: fa-content($fa-var-icons); } -.#{$fa-css-prefix}-id-badge:before { content: fa-content($fa-var-id-badge); } -.#{$fa-css-prefix}-id-card:before { content: fa-content($fa-var-id-card); } -.#{$fa-css-prefix}-id-card-alt:before { content: fa-content($fa-var-id-card-alt); } -.#{$fa-css-prefix}-ideal:before { content: fa-content($fa-var-ideal); } -.#{$fa-css-prefix}-igloo:before { content: fa-content($fa-var-igloo); } -.#{$fa-css-prefix}-image:before { content: fa-content($fa-var-image); } -.#{$fa-css-prefix}-images:before { content: fa-content($fa-var-images); } -.#{$fa-css-prefix}-imdb:before { content: fa-content($fa-var-imdb); } -.#{$fa-css-prefix}-inbox:before { content: fa-content($fa-var-inbox); } -.#{$fa-css-prefix}-indent:before { content: fa-content($fa-var-indent); } -.#{$fa-css-prefix}-industry:before { content: fa-content($fa-var-industry); } -.#{$fa-css-prefix}-infinity:before { content: fa-content($fa-var-infinity); } -.#{$fa-css-prefix}-info:before { content: fa-content($fa-var-info); } -.#{$fa-css-prefix}-info-circle:before { content: fa-content($fa-var-info-circle); } -.#{$fa-css-prefix}-instagram:before { content: fa-content($fa-var-instagram); } -.#{$fa-css-prefix}-instagram-square:before { content: fa-content($fa-var-instagram-square); } -.#{$fa-css-prefix}-intercom:before { content: fa-content($fa-var-intercom); } -.#{$fa-css-prefix}-internet-explorer:before { content: fa-content($fa-var-internet-explorer); } -.#{$fa-css-prefix}-invision:before { content: fa-content($fa-var-invision); } -.#{$fa-css-prefix}-ioxhost:before { content: fa-content($fa-var-ioxhost); } -.#{$fa-css-prefix}-italic:before { content: fa-content($fa-var-italic); } -.#{$fa-css-prefix}-itch-io:before { content: fa-content($fa-var-itch-io); } -.#{$fa-css-prefix}-itunes:before { content: fa-content($fa-var-itunes); } -.#{$fa-css-prefix}-itunes-note:before { content: fa-content($fa-var-itunes-note); } -.#{$fa-css-prefix}-java:before { content: fa-content($fa-var-java); } -.#{$fa-css-prefix}-jedi:before { content: fa-content($fa-var-jedi); } -.#{$fa-css-prefix}-jedi-order:before { content: fa-content($fa-var-jedi-order); } -.#{$fa-css-prefix}-jenkins:before { content: fa-content($fa-var-jenkins); } -.#{$fa-css-prefix}-jira:before { content: fa-content($fa-var-jira); } -.#{$fa-css-prefix}-joget:before { content: fa-content($fa-var-joget); } -.#{$fa-css-prefix}-joint:before { content: fa-content($fa-var-joint); } -.#{$fa-css-prefix}-joomla:before { content: fa-content($fa-var-joomla); } -.#{$fa-css-prefix}-journal-whills:before { content: fa-content($fa-var-journal-whills); } -.#{$fa-css-prefix}-js:before { content: fa-content($fa-var-js); } -.#{$fa-css-prefix}-js-square:before { content: fa-content($fa-var-js-square); } -.#{$fa-css-prefix}-jsfiddle:before { content: fa-content($fa-var-jsfiddle); } -.#{$fa-css-prefix}-kaaba:before { content: fa-content($fa-var-kaaba); } -.#{$fa-css-prefix}-kaggle:before { content: fa-content($fa-var-kaggle); } -.#{$fa-css-prefix}-key:before { content: fa-content($fa-var-key); } -.#{$fa-css-prefix}-keybase:before { content: fa-content($fa-var-keybase); } -.#{$fa-css-prefix}-keyboard:before { content: fa-content($fa-var-keyboard); } -.#{$fa-css-prefix}-keycdn:before { content: fa-content($fa-var-keycdn); } -.#{$fa-css-prefix}-khanda:before { content: fa-content($fa-var-khanda); } -.#{$fa-css-prefix}-kickstarter:before { content: fa-content($fa-var-kickstarter); } -.#{$fa-css-prefix}-kickstarter-k:before { content: fa-content($fa-var-kickstarter-k); } -.#{$fa-css-prefix}-kiss:before { content: fa-content($fa-var-kiss); } -.#{$fa-css-prefix}-kiss-beam:before { content: fa-content($fa-var-kiss-beam); } -.#{$fa-css-prefix}-kiss-wink-heart:before { content: fa-content($fa-var-kiss-wink-heart); } -.#{$fa-css-prefix}-kiwi-bird:before { content: fa-content($fa-var-kiwi-bird); } -.#{$fa-css-prefix}-korvue:before { content: fa-content($fa-var-korvue); } -.#{$fa-css-prefix}-landmark:before { content: fa-content($fa-var-landmark); } -.#{$fa-css-prefix}-language:before { content: fa-content($fa-var-language); } -.#{$fa-css-prefix}-laptop:before { content: fa-content($fa-var-laptop); } -.#{$fa-css-prefix}-laptop-code:before { content: fa-content($fa-var-laptop-code); } -.#{$fa-css-prefix}-laptop-house:before { content: fa-content($fa-var-laptop-house); } -.#{$fa-css-prefix}-laptop-medical:before { content: fa-content($fa-var-laptop-medical); } -.#{$fa-css-prefix}-laravel:before { content: fa-content($fa-var-laravel); } -.#{$fa-css-prefix}-lastfm:before { content: fa-content($fa-var-lastfm); } -.#{$fa-css-prefix}-lastfm-square:before { content: fa-content($fa-var-lastfm-square); } -.#{$fa-css-prefix}-laugh:before { content: fa-content($fa-var-laugh); } -.#{$fa-css-prefix}-laugh-beam:before { content: fa-content($fa-var-laugh-beam); } -.#{$fa-css-prefix}-laugh-squint:before { content: fa-content($fa-var-laugh-squint); } -.#{$fa-css-prefix}-laugh-wink:before { content: fa-content($fa-var-laugh-wink); } -.#{$fa-css-prefix}-layer-group:before { content: fa-content($fa-var-layer-group); } -.#{$fa-css-prefix}-leaf:before { content: fa-content($fa-var-leaf); } -.#{$fa-css-prefix}-leanpub:before { content: fa-content($fa-var-leanpub); } -.#{$fa-css-prefix}-lemon:before { content: fa-content($fa-var-lemon); } -.#{$fa-css-prefix}-less:before { content: fa-content($fa-var-less); } -.#{$fa-css-prefix}-less-than:before { content: fa-content($fa-var-less-than); } -.#{$fa-css-prefix}-less-than-equal:before { content: fa-content($fa-var-less-than-equal); } -.#{$fa-css-prefix}-level-down-alt:before { content: fa-content($fa-var-level-down-alt); } -.#{$fa-css-prefix}-level-up-alt:before { content: fa-content($fa-var-level-up-alt); } -.#{$fa-css-prefix}-life-ring:before { content: fa-content($fa-var-life-ring); } -.#{$fa-css-prefix}-lightbulb:before { content: fa-content($fa-var-lightbulb); } -.#{$fa-css-prefix}-line:before { content: fa-content($fa-var-line); } -.#{$fa-css-prefix}-link:before { content: fa-content($fa-var-link); } -.#{$fa-css-prefix}-linkedin:before { content: fa-content($fa-var-linkedin); } -.#{$fa-css-prefix}-linkedin-in:before { content: fa-content($fa-var-linkedin-in); } -.#{$fa-css-prefix}-linode:before { content: fa-content($fa-var-linode); } -.#{$fa-css-prefix}-linux:before { content: fa-content($fa-var-linux); } -.#{$fa-css-prefix}-lira-sign:before { content: fa-content($fa-var-lira-sign); } -.#{$fa-css-prefix}-list:before { content: fa-content($fa-var-list); } -.#{$fa-css-prefix}-list-alt:before { content: fa-content($fa-var-list-alt); } -.#{$fa-css-prefix}-list-ol:before { content: fa-content($fa-var-list-ol); } -.#{$fa-css-prefix}-list-ul:before { content: fa-content($fa-var-list-ul); } -.#{$fa-css-prefix}-location-arrow:before { content: fa-content($fa-var-location-arrow); } -.#{$fa-css-prefix}-lock:before { content: fa-content($fa-var-lock); } -.#{$fa-css-prefix}-lock-open:before { content: fa-content($fa-var-lock-open); } -.#{$fa-css-prefix}-long-arrow-alt-down:before { content: fa-content($fa-var-long-arrow-alt-down); } -.#{$fa-css-prefix}-long-arrow-alt-left:before { content: fa-content($fa-var-long-arrow-alt-left); } -.#{$fa-css-prefix}-long-arrow-alt-right:before { content: fa-content($fa-var-long-arrow-alt-right); } -.#{$fa-css-prefix}-long-arrow-alt-up:before { content: fa-content($fa-var-long-arrow-alt-up); } -.#{$fa-css-prefix}-low-vision:before { content: fa-content($fa-var-low-vision); } -.#{$fa-css-prefix}-luggage-cart:before { content: fa-content($fa-var-luggage-cart); } -.#{$fa-css-prefix}-lungs:before { content: fa-content($fa-var-lungs); } -.#{$fa-css-prefix}-lungs-virus:before { content: fa-content($fa-var-lungs-virus); } -.#{$fa-css-prefix}-lyft:before { content: fa-content($fa-var-lyft); } -.#{$fa-css-prefix}-magento:before { content: fa-content($fa-var-magento); } -.#{$fa-css-prefix}-magic:before { content: fa-content($fa-var-magic); } -.#{$fa-css-prefix}-magnet:before { content: fa-content($fa-var-magnet); } -.#{$fa-css-prefix}-mail-bulk:before { content: fa-content($fa-var-mail-bulk); } -.#{$fa-css-prefix}-mailchimp:before { content: fa-content($fa-var-mailchimp); } -.#{$fa-css-prefix}-male:before { content: fa-content($fa-var-male); } -.#{$fa-css-prefix}-mandalorian:before { content: fa-content($fa-var-mandalorian); } -.#{$fa-css-prefix}-map:before { content: fa-content($fa-var-map); } -.#{$fa-css-prefix}-map-marked:before { content: fa-content($fa-var-map-marked); } -.#{$fa-css-prefix}-map-marked-alt:before { content: fa-content($fa-var-map-marked-alt); } -.#{$fa-css-prefix}-map-marker:before { content: fa-content($fa-var-map-marker); } -.#{$fa-css-prefix}-map-marker-alt:before { content: fa-content($fa-var-map-marker-alt); } -.#{$fa-css-prefix}-map-pin:before { content: fa-content($fa-var-map-pin); } -.#{$fa-css-prefix}-map-signs:before { content: fa-content($fa-var-map-signs); } -.#{$fa-css-prefix}-markdown:before { content: fa-content($fa-var-markdown); } -.#{$fa-css-prefix}-marker:before { content: fa-content($fa-var-marker); } -.#{$fa-css-prefix}-mars:before { content: fa-content($fa-var-mars); } -.#{$fa-css-prefix}-mars-double:before { content: fa-content($fa-var-mars-double); } -.#{$fa-css-prefix}-mars-stroke:before { content: fa-content($fa-var-mars-stroke); } -.#{$fa-css-prefix}-mars-stroke-h:before { content: fa-content($fa-var-mars-stroke-h); } -.#{$fa-css-prefix}-mars-stroke-v:before { content: fa-content($fa-var-mars-stroke-v); } -.#{$fa-css-prefix}-mask:before { content: fa-content($fa-var-mask); } -.#{$fa-css-prefix}-mastodon:before { content: fa-content($fa-var-mastodon); } -.#{$fa-css-prefix}-maxcdn:before { content: fa-content($fa-var-maxcdn); } -.#{$fa-css-prefix}-mdb:before { content: fa-content($fa-var-mdb); } -.#{$fa-css-prefix}-medal:before { content: fa-content($fa-var-medal); } -.#{$fa-css-prefix}-medapps:before { content: fa-content($fa-var-medapps); } -.#{$fa-css-prefix}-medium:before { content: fa-content($fa-var-medium); } -.#{$fa-css-prefix}-medium-m:before { content: fa-content($fa-var-medium-m); } -.#{$fa-css-prefix}-medkit:before { content: fa-content($fa-var-medkit); } -.#{$fa-css-prefix}-medrt:before { content: fa-content($fa-var-medrt); } -.#{$fa-css-prefix}-meetup:before { content: fa-content($fa-var-meetup); } -.#{$fa-css-prefix}-megaport:before { content: fa-content($fa-var-megaport); } -.#{$fa-css-prefix}-meh:before { content: fa-content($fa-var-meh); } -.#{$fa-css-prefix}-meh-blank:before { content: fa-content($fa-var-meh-blank); } -.#{$fa-css-prefix}-meh-rolling-eyes:before { content: fa-content($fa-var-meh-rolling-eyes); } -.#{$fa-css-prefix}-memory:before { content: fa-content($fa-var-memory); } -.#{$fa-css-prefix}-mendeley:before { content: fa-content($fa-var-mendeley); } -.#{$fa-css-prefix}-menorah:before { content: fa-content($fa-var-menorah); } -.#{$fa-css-prefix}-mercury:before { content: fa-content($fa-var-mercury); } -.#{$fa-css-prefix}-meteor:before { content: fa-content($fa-var-meteor); } -.#{$fa-css-prefix}-microblog:before { content: fa-content($fa-var-microblog); } -.#{$fa-css-prefix}-microchip:before { content: fa-content($fa-var-microchip); } -.#{$fa-css-prefix}-microphone:before { content: fa-content($fa-var-microphone); } -.#{$fa-css-prefix}-microphone-alt:before { content: fa-content($fa-var-microphone-alt); } -.#{$fa-css-prefix}-microphone-alt-slash:before { content: fa-content($fa-var-microphone-alt-slash); } -.#{$fa-css-prefix}-microphone-slash:before { content: fa-content($fa-var-microphone-slash); } -.#{$fa-css-prefix}-microscope:before { content: fa-content($fa-var-microscope); } -.#{$fa-css-prefix}-microsoft:before { content: fa-content($fa-var-microsoft); } -.#{$fa-css-prefix}-minus:before { content: fa-content($fa-var-minus); } -.#{$fa-css-prefix}-minus-circle:before { content: fa-content($fa-var-minus-circle); } -.#{$fa-css-prefix}-minus-square:before { content: fa-content($fa-var-minus-square); } -.#{$fa-css-prefix}-mitten:before { content: fa-content($fa-var-mitten); } -.#{$fa-css-prefix}-mix:before { content: fa-content($fa-var-mix); } -.#{$fa-css-prefix}-mixcloud:before { content: fa-content($fa-var-mixcloud); } -.#{$fa-css-prefix}-mixer:before { content: fa-content($fa-var-mixer); } -.#{$fa-css-prefix}-mizuni:before { content: fa-content($fa-var-mizuni); } -.#{$fa-css-prefix}-mobile:before { content: fa-content($fa-var-mobile); } -.#{$fa-css-prefix}-mobile-alt:before { content: fa-content($fa-var-mobile-alt); } -.#{$fa-css-prefix}-modx:before { content: fa-content($fa-var-modx); } -.#{$fa-css-prefix}-monero:before { content: fa-content($fa-var-monero); } -.#{$fa-css-prefix}-money-bill:before { content: fa-content($fa-var-money-bill); } -.#{$fa-css-prefix}-money-bill-alt:before { content: fa-content($fa-var-money-bill-alt); } -.#{$fa-css-prefix}-money-bill-wave:before { content: fa-content($fa-var-money-bill-wave); } -.#{$fa-css-prefix}-money-bill-wave-alt:before { content: fa-content($fa-var-money-bill-wave-alt); } -.#{$fa-css-prefix}-money-check:before { content: fa-content($fa-var-money-check); } -.#{$fa-css-prefix}-money-check-alt:before { content: fa-content($fa-var-money-check-alt); } -.#{$fa-css-prefix}-monument:before { content: fa-content($fa-var-monument); } -.#{$fa-css-prefix}-moon:before { content: fa-content($fa-var-moon); } -.#{$fa-css-prefix}-mortar-pestle:before { content: fa-content($fa-var-mortar-pestle); } -.#{$fa-css-prefix}-mosque:before { content: fa-content($fa-var-mosque); } -.#{$fa-css-prefix}-motorcycle:before { content: fa-content($fa-var-motorcycle); } -.#{$fa-css-prefix}-mountain:before { content: fa-content($fa-var-mountain); } -.#{$fa-css-prefix}-mouse:before { content: fa-content($fa-var-mouse); } -.#{$fa-css-prefix}-mouse-pointer:before { content: fa-content($fa-var-mouse-pointer); } -.#{$fa-css-prefix}-mug-hot:before { content: fa-content($fa-var-mug-hot); } -.#{$fa-css-prefix}-music:before { content: fa-content($fa-var-music); } -.#{$fa-css-prefix}-napster:before { content: fa-content($fa-var-napster); } -.#{$fa-css-prefix}-neos:before { content: fa-content($fa-var-neos); } -.#{$fa-css-prefix}-network-wired:before { content: fa-content($fa-var-network-wired); } -.#{$fa-css-prefix}-neuter:before { content: fa-content($fa-var-neuter); } -.#{$fa-css-prefix}-newspaper:before { content: fa-content($fa-var-newspaper); } -.#{$fa-css-prefix}-nimblr:before { content: fa-content($fa-var-nimblr); } -.#{$fa-css-prefix}-node:before { content: fa-content($fa-var-node); } -.#{$fa-css-prefix}-node-js:before { content: fa-content($fa-var-node-js); } -.#{$fa-css-prefix}-not-equal:before { content: fa-content($fa-var-not-equal); } -.#{$fa-css-prefix}-notes-medical:before { content: fa-content($fa-var-notes-medical); } -.#{$fa-css-prefix}-npm:before { content: fa-content($fa-var-npm); } -.#{$fa-css-prefix}-ns8:before { content: fa-content($fa-var-ns8); } -.#{$fa-css-prefix}-nutritionix:before { content: fa-content($fa-var-nutritionix); } -.#{$fa-css-prefix}-object-group:before { content: fa-content($fa-var-object-group); } -.#{$fa-css-prefix}-object-ungroup:before { content: fa-content($fa-var-object-ungroup); } -.#{$fa-css-prefix}-odnoklassniki:before { content: fa-content($fa-var-odnoklassniki); } -.#{$fa-css-prefix}-odnoklassniki-square:before { content: fa-content($fa-var-odnoklassniki-square); } -.#{$fa-css-prefix}-oil-can:before { content: fa-content($fa-var-oil-can); } -.#{$fa-css-prefix}-old-republic:before { content: fa-content($fa-var-old-republic); } -.#{$fa-css-prefix}-om:before { content: fa-content($fa-var-om); } -.#{$fa-css-prefix}-opencart:before { content: fa-content($fa-var-opencart); } -.#{$fa-css-prefix}-openid:before { content: fa-content($fa-var-openid); } -.#{$fa-css-prefix}-opera:before { content: fa-content($fa-var-opera); } -.#{$fa-css-prefix}-optin-monster:before { content: fa-content($fa-var-optin-monster); } -.#{$fa-css-prefix}-orcid:before { content: fa-content($fa-var-orcid); } -.#{$fa-css-prefix}-osi:before { content: fa-content($fa-var-osi); } -.#{$fa-css-prefix}-otter:before { content: fa-content($fa-var-otter); } -.#{$fa-css-prefix}-outdent:before { content: fa-content($fa-var-outdent); } -.#{$fa-css-prefix}-page4:before { content: fa-content($fa-var-page4); } -.#{$fa-css-prefix}-pagelines:before { content: fa-content($fa-var-pagelines); } -.#{$fa-css-prefix}-pager:before { content: fa-content($fa-var-pager); } -.#{$fa-css-prefix}-paint-brush:before { content: fa-content($fa-var-paint-brush); } -.#{$fa-css-prefix}-paint-roller:before { content: fa-content($fa-var-paint-roller); } -.#{$fa-css-prefix}-palette:before { content: fa-content($fa-var-palette); } -.#{$fa-css-prefix}-palfed:before { content: fa-content($fa-var-palfed); } -.#{$fa-css-prefix}-pallet:before { content: fa-content($fa-var-pallet); } -.#{$fa-css-prefix}-paper-plane:before { content: fa-content($fa-var-paper-plane); } -.#{$fa-css-prefix}-paperclip:before { content: fa-content($fa-var-paperclip); } -.#{$fa-css-prefix}-parachute-box:before { content: fa-content($fa-var-parachute-box); } -.#{$fa-css-prefix}-paragraph:before { content: fa-content($fa-var-paragraph); } -.#{$fa-css-prefix}-parking:before { content: fa-content($fa-var-parking); } -.#{$fa-css-prefix}-passport:before { content: fa-content($fa-var-passport); } -.#{$fa-css-prefix}-pastafarianism:before { content: fa-content($fa-var-pastafarianism); } -.#{$fa-css-prefix}-paste:before { content: fa-content($fa-var-paste); } -.#{$fa-css-prefix}-patreon:before { content: fa-content($fa-var-patreon); } -.#{$fa-css-prefix}-pause:before { content: fa-content($fa-var-pause); } -.#{$fa-css-prefix}-pause-circle:before { content: fa-content($fa-var-pause-circle); } -.#{$fa-css-prefix}-paw:before { content: fa-content($fa-var-paw); } -.#{$fa-css-prefix}-paypal:before { content: fa-content($fa-var-paypal); } -.#{$fa-css-prefix}-peace:before { content: fa-content($fa-var-peace); } -.#{$fa-css-prefix}-pen:before { content: fa-content($fa-var-pen); } -.#{$fa-css-prefix}-pen-alt:before { content: fa-content($fa-var-pen-alt); } -.#{$fa-css-prefix}-pen-fancy:before { content: fa-content($fa-var-pen-fancy); } -.#{$fa-css-prefix}-pen-nib:before { content: fa-content($fa-var-pen-nib); } -.#{$fa-css-prefix}-pen-square:before { content: fa-content($fa-var-pen-square); } -.#{$fa-css-prefix}-pencil-alt:before { content: fa-content($fa-var-pencil-alt); } -.#{$fa-css-prefix}-pencil-ruler:before { content: fa-content($fa-var-pencil-ruler); } -.#{$fa-css-prefix}-penny-arcade:before { content: fa-content($fa-var-penny-arcade); } -.#{$fa-css-prefix}-people-arrows:before { content: fa-content($fa-var-people-arrows); } -.#{$fa-css-prefix}-people-carry:before { content: fa-content($fa-var-people-carry); } -.#{$fa-css-prefix}-pepper-hot:before { content: fa-content($fa-var-pepper-hot); } -.#{$fa-css-prefix}-percent:before { content: fa-content($fa-var-percent); } -.#{$fa-css-prefix}-percentage:before { content: fa-content($fa-var-percentage); } -.#{$fa-css-prefix}-periscope:before { content: fa-content($fa-var-periscope); } -.#{$fa-css-prefix}-person-booth:before { content: fa-content($fa-var-person-booth); } -.#{$fa-css-prefix}-phabricator:before { content: fa-content($fa-var-phabricator); } -.#{$fa-css-prefix}-phoenix-framework:before { content: fa-content($fa-var-phoenix-framework); } -.#{$fa-css-prefix}-phoenix-squadron:before { content: fa-content($fa-var-phoenix-squadron); } -.#{$fa-css-prefix}-phone:before { content: fa-content($fa-var-phone); } -.#{$fa-css-prefix}-phone-alt:before { content: fa-content($fa-var-phone-alt); } -.#{$fa-css-prefix}-phone-slash:before { content: fa-content($fa-var-phone-slash); } -.#{$fa-css-prefix}-phone-square:before { content: fa-content($fa-var-phone-square); } -.#{$fa-css-prefix}-phone-square-alt:before { content: fa-content($fa-var-phone-square-alt); } -.#{$fa-css-prefix}-phone-volume:before { content: fa-content($fa-var-phone-volume); } -.#{$fa-css-prefix}-photo-video:before { content: fa-content($fa-var-photo-video); } -.#{$fa-css-prefix}-php:before { content: fa-content($fa-var-php); } -.#{$fa-css-prefix}-pied-piper:before { content: fa-content($fa-var-pied-piper); } -.#{$fa-css-prefix}-pied-piper-alt:before { content: fa-content($fa-var-pied-piper-alt); } -.#{$fa-css-prefix}-pied-piper-hat:before { content: fa-content($fa-var-pied-piper-hat); } -.#{$fa-css-prefix}-pied-piper-pp:before { content: fa-content($fa-var-pied-piper-pp); } -.#{$fa-css-prefix}-pied-piper-square:before { content: fa-content($fa-var-pied-piper-square); } -.#{$fa-css-prefix}-piggy-bank:before { content: fa-content($fa-var-piggy-bank); } -.#{$fa-css-prefix}-pills:before { content: fa-content($fa-var-pills); } -.#{$fa-css-prefix}-pinterest:before { content: fa-content($fa-var-pinterest); } -.#{$fa-css-prefix}-pinterest-p:before { content: fa-content($fa-var-pinterest-p); } -.#{$fa-css-prefix}-pinterest-square:before { content: fa-content($fa-var-pinterest-square); } -.#{$fa-css-prefix}-pizza-slice:before { content: fa-content($fa-var-pizza-slice); } -.#{$fa-css-prefix}-place-of-worship:before { content: fa-content($fa-var-place-of-worship); } -.#{$fa-css-prefix}-plane:before { content: fa-content($fa-var-plane); } -.#{$fa-css-prefix}-plane-arrival:before { content: fa-content($fa-var-plane-arrival); } -.#{$fa-css-prefix}-plane-departure:before { content: fa-content($fa-var-plane-departure); } -.#{$fa-css-prefix}-plane-slash:before { content: fa-content($fa-var-plane-slash); } -.#{$fa-css-prefix}-play:before { content: fa-content($fa-var-play); } -.#{$fa-css-prefix}-play-circle:before { content: fa-content($fa-var-play-circle); } -.#{$fa-css-prefix}-playstation:before { content: fa-content($fa-var-playstation); } -.#{$fa-css-prefix}-plug:before { content: fa-content($fa-var-plug); } -.#{$fa-css-prefix}-plus:before { content: fa-content($fa-var-plus); } -.#{$fa-css-prefix}-plus-circle:before { content: fa-content($fa-var-plus-circle); } -.#{$fa-css-prefix}-plus-square:before { content: fa-content($fa-var-plus-square); } -.#{$fa-css-prefix}-podcast:before { content: fa-content($fa-var-podcast); } -.#{$fa-css-prefix}-poll:before { content: fa-content($fa-var-poll); } -.#{$fa-css-prefix}-poll-h:before { content: fa-content($fa-var-poll-h); } -.#{$fa-css-prefix}-poo:before { content: fa-content($fa-var-poo); } -.#{$fa-css-prefix}-poo-storm:before { content: fa-content($fa-var-poo-storm); } -.#{$fa-css-prefix}-poop:before { content: fa-content($fa-var-poop); } -.#{$fa-css-prefix}-portrait:before { content: fa-content($fa-var-portrait); } -.#{$fa-css-prefix}-pound-sign:before { content: fa-content($fa-var-pound-sign); } -.#{$fa-css-prefix}-power-off:before { content: fa-content($fa-var-power-off); } -.#{$fa-css-prefix}-pray:before { content: fa-content($fa-var-pray); } -.#{$fa-css-prefix}-praying-hands:before { content: fa-content($fa-var-praying-hands); } -.#{$fa-css-prefix}-prescription:before { content: fa-content($fa-var-prescription); } -.#{$fa-css-prefix}-prescription-bottle:before { content: fa-content($fa-var-prescription-bottle); } -.#{$fa-css-prefix}-prescription-bottle-alt:before { content: fa-content($fa-var-prescription-bottle-alt); } -.#{$fa-css-prefix}-print:before { content: fa-content($fa-var-print); } -.#{$fa-css-prefix}-procedures:before { content: fa-content($fa-var-procedures); } -.#{$fa-css-prefix}-product-hunt:before { content: fa-content($fa-var-product-hunt); } -.#{$fa-css-prefix}-project-diagram:before { content: fa-content($fa-var-project-diagram); } -.#{$fa-css-prefix}-pump-medical:before { content: fa-content($fa-var-pump-medical); } -.#{$fa-css-prefix}-pump-soap:before { content: fa-content($fa-var-pump-soap); } -.#{$fa-css-prefix}-pushed:before { content: fa-content($fa-var-pushed); } -.#{$fa-css-prefix}-puzzle-piece:before { content: fa-content($fa-var-puzzle-piece); } -.#{$fa-css-prefix}-python:before { content: fa-content($fa-var-python); } -.#{$fa-css-prefix}-qq:before { content: fa-content($fa-var-qq); } -.#{$fa-css-prefix}-qrcode:before { content: fa-content($fa-var-qrcode); } -.#{$fa-css-prefix}-question:before { content: fa-content($fa-var-question); } -.#{$fa-css-prefix}-question-circle:before { content: fa-content($fa-var-question-circle); } -.#{$fa-css-prefix}-quidditch:before { content: fa-content($fa-var-quidditch); } -.#{$fa-css-prefix}-quinscape:before { content: fa-content($fa-var-quinscape); } -.#{$fa-css-prefix}-quora:before { content: fa-content($fa-var-quora); } -.#{$fa-css-prefix}-quote-left:before { content: fa-content($fa-var-quote-left); } -.#{$fa-css-prefix}-quote-right:before { content: fa-content($fa-var-quote-right); } -.#{$fa-css-prefix}-quran:before { content: fa-content($fa-var-quran); } -.#{$fa-css-prefix}-r-project:before { content: fa-content($fa-var-r-project); } -.#{$fa-css-prefix}-radiation:before { content: fa-content($fa-var-radiation); } -.#{$fa-css-prefix}-radiation-alt:before { content: fa-content($fa-var-radiation-alt); } -.#{$fa-css-prefix}-rainbow:before { content: fa-content($fa-var-rainbow); } -.#{$fa-css-prefix}-random:before { content: fa-content($fa-var-random); } -.#{$fa-css-prefix}-raspberry-pi:before { content: fa-content($fa-var-raspberry-pi); } -.#{$fa-css-prefix}-ravelry:before { content: fa-content($fa-var-ravelry); } -.#{$fa-css-prefix}-react:before { content: fa-content($fa-var-react); } -.#{$fa-css-prefix}-reacteurope:before { content: fa-content($fa-var-reacteurope); } -.#{$fa-css-prefix}-readme:before { content: fa-content($fa-var-readme); } -.#{$fa-css-prefix}-rebel:before { content: fa-content($fa-var-rebel); } -.#{$fa-css-prefix}-receipt:before { content: fa-content($fa-var-receipt); } -.#{$fa-css-prefix}-record-vinyl:before { content: fa-content($fa-var-record-vinyl); } -.#{$fa-css-prefix}-recycle:before { content: fa-content($fa-var-recycle); } -.#{$fa-css-prefix}-red-river:before { content: fa-content($fa-var-red-river); } -.#{$fa-css-prefix}-reddit:before { content: fa-content($fa-var-reddit); } -.#{$fa-css-prefix}-reddit-alien:before { content: fa-content($fa-var-reddit-alien); } -.#{$fa-css-prefix}-reddit-square:before { content: fa-content($fa-var-reddit-square); } -.#{$fa-css-prefix}-redhat:before { content: fa-content($fa-var-redhat); } -.#{$fa-css-prefix}-redo:before { content: fa-content($fa-var-redo); } -.#{$fa-css-prefix}-redo-alt:before { content: fa-content($fa-var-redo-alt); } -.#{$fa-css-prefix}-registered:before { content: fa-content($fa-var-registered); } -.#{$fa-css-prefix}-remove-format:before { content: fa-content($fa-var-remove-format); } -.#{$fa-css-prefix}-renren:before { content: fa-content($fa-var-renren); } -.#{$fa-css-prefix}-reply:before { content: fa-content($fa-var-reply); } -.#{$fa-css-prefix}-reply-all:before { content: fa-content($fa-var-reply-all); } -.#{$fa-css-prefix}-replyd:before { content: fa-content($fa-var-replyd); } -.#{$fa-css-prefix}-republican:before { content: fa-content($fa-var-republican); } -.#{$fa-css-prefix}-researchgate:before { content: fa-content($fa-var-researchgate); } -.#{$fa-css-prefix}-resolving:before { content: fa-content($fa-var-resolving); } -.#{$fa-css-prefix}-restroom:before { content: fa-content($fa-var-restroom); } -.#{$fa-css-prefix}-retweet:before { content: fa-content($fa-var-retweet); } -.#{$fa-css-prefix}-rev:before { content: fa-content($fa-var-rev); } -.#{$fa-css-prefix}-ribbon:before { content: fa-content($fa-var-ribbon); } -.#{$fa-css-prefix}-ring:before { content: fa-content($fa-var-ring); } -.#{$fa-css-prefix}-road:before { content: fa-content($fa-var-road); } -.#{$fa-css-prefix}-robot:before { content: fa-content($fa-var-robot); } -.#{$fa-css-prefix}-rocket:before { content: fa-content($fa-var-rocket); } -.#{$fa-css-prefix}-rocketchat:before { content: fa-content($fa-var-rocketchat); } -.#{$fa-css-prefix}-rockrms:before { content: fa-content($fa-var-rockrms); } -.#{$fa-css-prefix}-route:before { content: fa-content($fa-var-route); } -.#{$fa-css-prefix}-rss:before { content: fa-content($fa-var-rss); } -.#{$fa-css-prefix}-rss-square:before { content: fa-content($fa-var-rss-square); } -.#{$fa-css-prefix}-ruble-sign:before { content: fa-content($fa-var-ruble-sign); } -.#{$fa-css-prefix}-ruler:before { content: fa-content($fa-var-ruler); } -.#{$fa-css-prefix}-ruler-combined:before { content: fa-content($fa-var-ruler-combined); } -.#{$fa-css-prefix}-ruler-horizontal:before { content: fa-content($fa-var-ruler-horizontal); } -.#{$fa-css-prefix}-ruler-vertical:before { content: fa-content($fa-var-ruler-vertical); } -.#{$fa-css-prefix}-running:before { content: fa-content($fa-var-running); } -.#{$fa-css-prefix}-rupee-sign:before { content: fa-content($fa-var-rupee-sign); } -.#{$fa-css-prefix}-rust:before { content: fa-content($fa-var-rust); } -.#{$fa-css-prefix}-sad-cry:before { content: fa-content($fa-var-sad-cry); } -.#{$fa-css-prefix}-sad-tear:before { content: fa-content($fa-var-sad-tear); } -.#{$fa-css-prefix}-safari:before { content: fa-content($fa-var-safari); } -.#{$fa-css-prefix}-salesforce:before { content: fa-content($fa-var-salesforce); } -.#{$fa-css-prefix}-sass:before { content: fa-content($fa-var-sass); } -.#{$fa-css-prefix}-satellite:before { content: fa-content($fa-var-satellite); } -.#{$fa-css-prefix}-satellite-dish:before { content: fa-content($fa-var-satellite-dish); } -.#{$fa-css-prefix}-save:before { content: fa-content($fa-var-save); } -.#{$fa-css-prefix}-schlix:before { content: fa-content($fa-var-schlix); } -.#{$fa-css-prefix}-school:before { content: fa-content($fa-var-school); } -.#{$fa-css-prefix}-screwdriver:before { content: fa-content($fa-var-screwdriver); } -.#{$fa-css-prefix}-scribd:before { content: fa-content($fa-var-scribd); } -.#{$fa-css-prefix}-scroll:before { content: fa-content($fa-var-scroll); } -.#{$fa-css-prefix}-sd-card:before { content: fa-content($fa-var-sd-card); } -.#{$fa-css-prefix}-search:before { content: fa-content($fa-var-search); } -.#{$fa-css-prefix}-search-dollar:before { content: fa-content($fa-var-search-dollar); } -.#{$fa-css-prefix}-search-location:before { content: fa-content($fa-var-search-location); } -.#{$fa-css-prefix}-search-minus:before { content: fa-content($fa-var-search-minus); } -.#{$fa-css-prefix}-search-plus:before { content: fa-content($fa-var-search-plus); } -.#{$fa-css-prefix}-searchengin:before { content: fa-content($fa-var-searchengin); } -.#{$fa-css-prefix}-seedling:before { content: fa-content($fa-var-seedling); } -.#{$fa-css-prefix}-sellcast:before { content: fa-content($fa-var-sellcast); } -.#{$fa-css-prefix}-sellsy:before { content: fa-content($fa-var-sellsy); } -.#{$fa-css-prefix}-server:before { content: fa-content($fa-var-server); } -.#{$fa-css-prefix}-servicestack:before { content: fa-content($fa-var-servicestack); } -.#{$fa-css-prefix}-shapes:before { content: fa-content($fa-var-shapes); } -.#{$fa-css-prefix}-share:before { content: fa-content($fa-var-share); } -.#{$fa-css-prefix}-share-alt:before { content: fa-content($fa-var-share-alt); } -.#{$fa-css-prefix}-share-alt-square:before { content: fa-content($fa-var-share-alt-square); } -.#{$fa-css-prefix}-share-square:before { content: fa-content($fa-var-share-square); } -.#{$fa-css-prefix}-shekel-sign:before { content: fa-content($fa-var-shekel-sign); } -.#{$fa-css-prefix}-shield-alt:before { content: fa-content($fa-var-shield-alt); } -.#{$fa-css-prefix}-shield-virus:before { content: fa-content($fa-var-shield-virus); } -.#{$fa-css-prefix}-ship:before { content: fa-content($fa-var-ship); } -.#{$fa-css-prefix}-shipping-fast:before { content: fa-content($fa-var-shipping-fast); } -.#{$fa-css-prefix}-shirtsinbulk:before { content: fa-content($fa-var-shirtsinbulk); } -.#{$fa-css-prefix}-shoe-prints:before { content: fa-content($fa-var-shoe-prints); } -.#{$fa-css-prefix}-shopify:before { content: fa-content($fa-var-shopify); } -.#{$fa-css-prefix}-shopping-bag:before { content: fa-content($fa-var-shopping-bag); } -.#{$fa-css-prefix}-shopping-basket:before { content: fa-content($fa-var-shopping-basket); } -.#{$fa-css-prefix}-shopping-cart:before { content: fa-content($fa-var-shopping-cart); } -.#{$fa-css-prefix}-shopware:before { content: fa-content($fa-var-shopware); } -.#{$fa-css-prefix}-shower:before { content: fa-content($fa-var-shower); } -.#{$fa-css-prefix}-shuttle-van:before { content: fa-content($fa-var-shuttle-van); } -.#{$fa-css-prefix}-sign:before { content: fa-content($fa-var-sign); } -.#{$fa-css-prefix}-sign-in-alt:before { content: fa-content($fa-var-sign-in-alt); } -.#{$fa-css-prefix}-sign-language:before { content: fa-content($fa-var-sign-language); } -.#{$fa-css-prefix}-sign-out-alt:before { content: fa-content($fa-var-sign-out-alt); } -.#{$fa-css-prefix}-signal:before { content: fa-content($fa-var-signal); } -.#{$fa-css-prefix}-signature:before { content: fa-content($fa-var-signature); } -.#{$fa-css-prefix}-sim-card:before { content: fa-content($fa-var-sim-card); } -.#{$fa-css-prefix}-simplybuilt:before { content: fa-content($fa-var-simplybuilt); } -.#{$fa-css-prefix}-sink:before { content: fa-content($fa-var-sink); } -.#{$fa-css-prefix}-sistrix:before { content: fa-content($fa-var-sistrix); } -.#{$fa-css-prefix}-sitemap:before { content: fa-content($fa-var-sitemap); } -.#{$fa-css-prefix}-sith:before { content: fa-content($fa-var-sith); } -.#{$fa-css-prefix}-skating:before { content: fa-content($fa-var-skating); } -.#{$fa-css-prefix}-sketch:before { content: fa-content($fa-var-sketch); } -.#{$fa-css-prefix}-skiing:before { content: fa-content($fa-var-skiing); } -.#{$fa-css-prefix}-skiing-nordic:before { content: fa-content($fa-var-skiing-nordic); } -.#{$fa-css-prefix}-skull:before { content: fa-content($fa-var-skull); } -.#{$fa-css-prefix}-skull-crossbones:before { content: fa-content($fa-var-skull-crossbones); } -.#{$fa-css-prefix}-skyatlas:before { content: fa-content($fa-var-skyatlas); } -.#{$fa-css-prefix}-skype:before { content: fa-content($fa-var-skype); } -.#{$fa-css-prefix}-slack:before { content: fa-content($fa-var-slack); } -.#{$fa-css-prefix}-slack-hash:before { content: fa-content($fa-var-slack-hash); } -.#{$fa-css-prefix}-slash:before { content: fa-content($fa-var-slash); } -.#{$fa-css-prefix}-sleigh:before { content: fa-content($fa-var-sleigh); } -.#{$fa-css-prefix}-sliders-h:before { content: fa-content($fa-var-sliders-h); } -.#{$fa-css-prefix}-slideshare:before { content: fa-content($fa-var-slideshare); } -.#{$fa-css-prefix}-smile:before { content: fa-content($fa-var-smile); } -.#{$fa-css-prefix}-smile-beam:before { content: fa-content($fa-var-smile-beam); } -.#{$fa-css-prefix}-smile-wink:before { content: fa-content($fa-var-smile-wink); } -.#{$fa-css-prefix}-smog:before { content: fa-content($fa-var-smog); } -.#{$fa-css-prefix}-smoking:before { content: fa-content($fa-var-smoking); } -.#{$fa-css-prefix}-smoking-ban:before { content: fa-content($fa-var-smoking-ban); } -.#{$fa-css-prefix}-sms:before { content: fa-content($fa-var-sms); } -.#{$fa-css-prefix}-snapchat:before { content: fa-content($fa-var-snapchat); } -.#{$fa-css-prefix}-snapchat-ghost:before { content: fa-content($fa-var-snapchat-ghost); } -.#{$fa-css-prefix}-snapchat-square:before { content: fa-content($fa-var-snapchat-square); } -.#{$fa-css-prefix}-snowboarding:before { content: fa-content($fa-var-snowboarding); } -.#{$fa-css-prefix}-snowflake:before { content: fa-content($fa-var-snowflake); } -.#{$fa-css-prefix}-snowman:before { content: fa-content($fa-var-snowman); } -.#{$fa-css-prefix}-snowplow:before { content: fa-content($fa-var-snowplow); } -.#{$fa-css-prefix}-soap:before { content: fa-content($fa-var-soap); } -.#{$fa-css-prefix}-socks:before { content: fa-content($fa-var-socks); } -.#{$fa-css-prefix}-solar-panel:before { content: fa-content($fa-var-solar-panel); } -.#{$fa-css-prefix}-sort:before { content: fa-content($fa-var-sort); } -.#{$fa-css-prefix}-sort-alpha-down:before { content: fa-content($fa-var-sort-alpha-down); } -.#{$fa-css-prefix}-sort-alpha-down-alt:before { content: fa-content($fa-var-sort-alpha-down-alt); } -.#{$fa-css-prefix}-sort-alpha-up:before { content: fa-content($fa-var-sort-alpha-up); } -.#{$fa-css-prefix}-sort-alpha-up-alt:before { content: fa-content($fa-var-sort-alpha-up-alt); } -.#{$fa-css-prefix}-sort-amount-down:before { content: fa-content($fa-var-sort-amount-down); } -.#{$fa-css-prefix}-sort-amount-down-alt:before { content: fa-content($fa-var-sort-amount-down-alt); } -.#{$fa-css-prefix}-sort-amount-up:before { content: fa-content($fa-var-sort-amount-up); } -.#{$fa-css-prefix}-sort-amount-up-alt:before { content: fa-content($fa-var-sort-amount-up-alt); } -.#{$fa-css-prefix}-sort-down:before { content: fa-content($fa-var-sort-down); } -.#{$fa-css-prefix}-sort-numeric-down:before { content: fa-content($fa-var-sort-numeric-down); } -.#{$fa-css-prefix}-sort-numeric-down-alt:before { content: fa-content($fa-var-sort-numeric-down-alt); } -.#{$fa-css-prefix}-sort-numeric-up:before { content: fa-content($fa-var-sort-numeric-up); } -.#{$fa-css-prefix}-sort-numeric-up-alt:before { content: fa-content($fa-var-sort-numeric-up-alt); } -.#{$fa-css-prefix}-sort-up:before { content: fa-content($fa-var-sort-up); } -.#{$fa-css-prefix}-soundcloud:before { content: fa-content($fa-var-soundcloud); } -.#{$fa-css-prefix}-sourcetree:before { content: fa-content($fa-var-sourcetree); } -.#{$fa-css-prefix}-spa:before { content: fa-content($fa-var-spa); } -.#{$fa-css-prefix}-space-shuttle:before { content: fa-content($fa-var-space-shuttle); } -.#{$fa-css-prefix}-speakap:before { content: fa-content($fa-var-speakap); } -.#{$fa-css-prefix}-speaker-deck:before { content: fa-content($fa-var-speaker-deck); } -.#{$fa-css-prefix}-spell-check:before { content: fa-content($fa-var-spell-check); } -.#{$fa-css-prefix}-spider:before { content: fa-content($fa-var-spider); } -.#{$fa-css-prefix}-spinner:before { content: fa-content($fa-var-spinner); } -.#{$fa-css-prefix}-splotch:before { content: fa-content($fa-var-splotch); } -.#{$fa-css-prefix}-spotify:before { content: fa-content($fa-var-spotify); } -.#{$fa-css-prefix}-spray-can:before { content: fa-content($fa-var-spray-can); } -.#{$fa-css-prefix}-square:before { content: fa-content($fa-var-square); } -.#{$fa-css-prefix}-square-full:before { content: fa-content($fa-var-square-full); } -.#{$fa-css-prefix}-square-root-alt:before { content: fa-content($fa-var-square-root-alt); } -.#{$fa-css-prefix}-squarespace:before { content: fa-content($fa-var-squarespace); } -.#{$fa-css-prefix}-stack-exchange:before { content: fa-content($fa-var-stack-exchange); } -.#{$fa-css-prefix}-stack-overflow:before { content: fa-content($fa-var-stack-overflow); } -.#{$fa-css-prefix}-stackpath:before { content: fa-content($fa-var-stackpath); } -.#{$fa-css-prefix}-stamp:before { content: fa-content($fa-var-stamp); } -.#{$fa-css-prefix}-star:before { content: fa-content($fa-var-star); } -.#{$fa-css-prefix}-star-and-crescent:before { content: fa-content($fa-var-star-and-crescent); } -.#{$fa-css-prefix}-star-half:before { content: fa-content($fa-var-star-half); } -.#{$fa-css-prefix}-star-half-alt:before { content: fa-content($fa-var-star-half-alt); } -.#{$fa-css-prefix}-star-of-david:before { content: fa-content($fa-var-star-of-david); } -.#{$fa-css-prefix}-star-of-life:before { content: fa-content($fa-var-star-of-life); } -.#{$fa-css-prefix}-staylinked:before { content: fa-content($fa-var-staylinked); } -.#{$fa-css-prefix}-steam:before { content: fa-content($fa-var-steam); } -.#{$fa-css-prefix}-steam-square:before { content: fa-content($fa-var-steam-square); } -.#{$fa-css-prefix}-steam-symbol:before { content: fa-content($fa-var-steam-symbol); } -.#{$fa-css-prefix}-step-backward:before { content: fa-content($fa-var-step-backward); } -.#{$fa-css-prefix}-step-forward:before { content: fa-content($fa-var-step-forward); } -.#{$fa-css-prefix}-stethoscope:before { content: fa-content($fa-var-stethoscope); } -.#{$fa-css-prefix}-sticker-mule:before { content: fa-content($fa-var-sticker-mule); } -.#{$fa-css-prefix}-sticky-note:before { content: fa-content($fa-var-sticky-note); } -.#{$fa-css-prefix}-stop:before { content: fa-content($fa-var-stop); } -.#{$fa-css-prefix}-stop-circle:before { content: fa-content($fa-var-stop-circle); } -.#{$fa-css-prefix}-stopwatch:before { content: fa-content($fa-var-stopwatch); } -.#{$fa-css-prefix}-stopwatch-20:before { content: fa-content($fa-var-stopwatch-20); } -.#{$fa-css-prefix}-store:before { content: fa-content($fa-var-store); } -.#{$fa-css-prefix}-store-alt:before { content: fa-content($fa-var-store-alt); } -.#{$fa-css-prefix}-store-alt-slash:before { content: fa-content($fa-var-store-alt-slash); } -.#{$fa-css-prefix}-store-slash:before { content: fa-content($fa-var-store-slash); } -.#{$fa-css-prefix}-strava:before { content: fa-content($fa-var-strava); } -.#{$fa-css-prefix}-stream:before { content: fa-content($fa-var-stream); } -.#{$fa-css-prefix}-street-view:before { content: fa-content($fa-var-street-view); } -.#{$fa-css-prefix}-strikethrough:before { content: fa-content($fa-var-strikethrough); } -.#{$fa-css-prefix}-stripe:before { content: fa-content($fa-var-stripe); } -.#{$fa-css-prefix}-stripe-s:before { content: fa-content($fa-var-stripe-s); } -.#{$fa-css-prefix}-stroopwafel:before { content: fa-content($fa-var-stroopwafel); } -.#{$fa-css-prefix}-studiovinari:before { content: fa-content($fa-var-studiovinari); } -.#{$fa-css-prefix}-stumbleupon:before { content: fa-content($fa-var-stumbleupon); } -.#{$fa-css-prefix}-stumbleupon-circle:before { content: fa-content($fa-var-stumbleupon-circle); } -.#{$fa-css-prefix}-subscript:before { content: fa-content($fa-var-subscript); } -.#{$fa-css-prefix}-subway:before { content: fa-content($fa-var-subway); } -.#{$fa-css-prefix}-suitcase:before { content: fa-content($fa-var-suitcase); } -.#{$fa-css-prefix}-suitcase-rolling:before { content: fa-content($fa-var-suitcase-rolling); } -.#{$fa-css-prefix}-sun:before { content: fa-content($fa-var-sun); } -.#{$fa-css-prefix}-superpowers:before { content: fa-content($fa-var-superpowers); } -.#{$fa-css-prefix}-superscript:before { content: fa-content($fa-var-superscript); } -.#{$fa-css-prefix}-supple:before { content: fa-content($fa-var-supple); } -.#{$fa-css-prefix}-surprise:before { content: fa-content($fa-var-surprise); } -.#{$fa-css-prefix}-suse:before { content: fa-content($fa-var-suse); } -.#{$fa-css-prefix}-swatchbook:before { content: fa-content($fa-var-swatchbook); } -.#{$fa-css-prefix}-swift:before { content: fa-content($fa-var-swift); } -.#{$fa-css-prefix}-swimmer:before { content: fa-content($fa-var-swimmer); } -.#{$fa-css-prefix}-swimming-pool:before { content: fa-content($fa-var-swimming-pool); } -.#{$fa-css-prefix}-symfony:before { content: fa-content($fa-var-symfony); } -.#{$fa-css-prefix}-synagogue:before { content: fa-content($fa-var-synagogue); } -.#{$fa-css-prefix}-sync:before { content: fa-content($fa-var-sync); } -.#{$fa-css-prefix}-sync-alt:before { content: fa-content($fa-var-sync-alt); } -.#{$fa-css-prefix}-syringe:before { content: fa-content($fa-var-syringe); } -.#{$fa-css-prefix}-table:before { content: fa-content($fa-var-table); } -.#{$fa-css-prefix}-table-tennis:before { content: fa-content($fa-var-table-tennis); } -.#{$fa-css-prefix}-tablet:before { content: fa-content($fa-var-tablet); } -.#{$fa-css-prefix}-tablet-alt:before { content: fa-content($fa-var-tablet-alt); } -.#{$fa-css-prefix}-tablets:before { content: fa-content($fa-var-tablets); } -.#{$fa-css-prefix}-tachometer-alt:before { content: fa-content($fa-var-tachometer-alt); } -.#{$fa-css-prefix}-tag:before { content: fa-content($fa-var-tag); } -.#{$fa-css-prefix}-tags:before { content: fa-content($fa-var-tags); } -.#{$fa-css-prefix}-tape:before { content: fa-content($fa-var-tape); } -.#{$fa-css-prefix}-tasks:before { content: fa-content($fa-var-tasks); } -.#{$fa-css-prefix}-taxi:before { content: fa-content($fa-var-taxi); } -.#{$fa-css-prefix}-teamspeak:before { content: fa-content($fa-var-teamspeak); } -.#{$fa-css-prefix}-teeth:before { content: fa-content($fa-var-teeth); } -.#{$fa-css-prefix}-teeth-open:before { content: fa-content($fa-var-teeth-open); } -.#{$fa-css-prefix}-telegram:before { content: fa-content($fa-var-telegram); } -.#{$fa-css-prefix}-telegram-plane:before { content: fa-content($fa-var-telegram-plane); } -.#{$fa-css-prefix}-temperature-high:before { content: fa-content($fa-var-temperature-high); } -.#{$fa-css-prefix}-temperature-low:before { content: fa-content($fa-var-temperature-low); } -.#{$fa-css-prefix}-tencent-weibo:before { content: fa-content($fa-var-tencent-weibo); } -.#{$fa-css-prefix}-tenge:before { content: fa-content($fa-var-tenge); } -.#{$fa-css-prefix}-terminal:before { content: fa-content($fa-var-terminal); } -.#{$fa-css-prefix}-text-height:before { content: fa-content($fa-var-text-height); } -.#{$fa-css-prefix}-text-width:before { content: fa-content($fa-var-text-width); } -.#{$fa-css-prefix}-th:before { content: fa-content($fa-var-th); } -.#{$fa-css-prefix}-th-large:before { content: fa-content($fa-var-th-large); } -.#{$fa-css-prefix}-th-list:before { content: fa-content($fa-var-th-list); } -.#{$fa-css-prefix}-the-red-yeti:before { content: fa-content($fa-var-the-red-yeti); } -.#{$fa-css-prefix}-theater-masks:before { content: fa-content($fa-var-theater-masks); } -.#{$fa-css-prefix}-themeco:before { content: fa-content($fa-var-themeco); } -.#{$fa-css-prefix}-themeisle:before { content: fa-content($fa-var-themeisle); } -.#{$fa-css-prefix}-thermometer:before { content: fa-content($fa-var-thermometer); } -.#{$fa-css-prefix}-thermometer-empty:before { content: fa-content($fa-var-thermometer-empty); } -.#{$fa-css-prefix}-thermometer-full:before { content: fa-content($fa-var-thermometer-full); } -.#{$fa-css-prefix}-thermometer-half:before { content: fa-content($fa-var-thermometer-half); } -.#{$fa-css-prefix}-thermometer-quarter:before { content: fa-content($fa-var-thermometer-quarter); } -.#{$fa-css-prefix}-thermometer-three-quarters:before { content: fa-content($fa-var-thermometer-three-quarters); } -.#{$fa-css-prefix}-think-peaks:before { content: fa-content($fa-var-think-peaks); } -.#{$fa-css-prefix}-thumbs-down:before { content: fa-content($fa-var-thumbs-down); } -.#{$fa-css-prefix}-thumbs-up:before { content: fa-content($fa-var-thumbs-up); } -.#{$fa-css-prefix}-thumbtack:before { content: fa-content($fa-var-thumbtack); } -.#{$fa-css-prefix}-ticket-alt:before { content: fa-content($fa-var-ticket-alt); } -.#{$fa-css-prefix}-tiktok:before { content: fa-content($fa-var-tiktok); } -.#{$fa-css-prefix}-times:before { content: fa-content($fa-var-times); } -.#{$fa-css-prefix}-times-circle:before { content: fa-content($fa-var-times-circle); } -.#{$fa-css-prefix}-tint:before { content: fa-content($fa-var-tint); } -.#{$fa-css-prefix}-tint-slash:before { content: fa-content($fa-var-tint-slash); } -.#{$fa-css-prefix}-tired:before { content: fa-content($fa-var-tired); } -.#{$fa-css-prefix}-toggle-off:before { content: fa-content($fa-var-toggle-off); } -.#{$fa-css-prefix}-toggle-on:before { content: fa-content($fa-var-toggle-on); } -.#{$fa-css-prefix}-toilet:before { content: fa-content($fa-var-toilet); } -.#{$fa-css-prefix}-toilet-paper:before { content: fa-content($fa-var-toilet-paper); } -.#{$fa-css-prefix}-toilet-paper-slash:before { content: fa-content($fa-var-toilet-paper-slash); } -.#{$fa-css-prefix}-toolbox:before { content: fa-content($fa-var-toolbox); } -.#{$fa-css-prefix}-tools:before { content: fa-content($fa-var-tools); } -.#{$fa-css-prefix}-tooth:before { content: fa-content($fa-var-tooth); } -.#{$fa-css-prefix}-torah:before { content: fa-content($fa-var-torah); } -.#{$fa-css-prefix}-torii-gate:before { content: fa-content($fa-var-torii-gate); } -.#{$fa-css-prefix}-tractor:before { content: fa-content($fa-var-tractor); } -.#{$fa-css-prefix}-trade-federation:before { content: fa-content($fa-var-trade-federation); } -.#{$fa-css-prefix}-trademark:before { content: fa-content($fa-var-trademark); } -.#{$fa-css-prefix}-traffic-light:before { content: fa-content($fa-var-traffic-light); } -.#{$fa-css-prefix}-trailer:before { content: fa-content($fa-var-trailer); } -.#{$fa-css-prefix}-train:before { content: fa-content($fa-var-train); } -.#{$fa-css-prefix}-tram:before { content: fa-content($fa-var-tram); } -.#{$fa-css-prefix}-transgender:before { content: fa-content($fa-var-transgender); } -.#{$fa-css-prefix}-transgender-alt:before { content: fa-content($fa-var-transgender-alt); } -.#{$fa-css-prefix}-trash:before { content: fa-content($fa-var-trash); } -.#{$fa-css-prefix}-trash-alt:before { content: fa-content($fa-var-trash-alt); } -.#{$fa-css-prefix}-trash-restore:before { content: fa-content($fa-var-trash-restore); } -.#{$fa-css-prefix}-trash-restore-alt:before { content: fa-content($fa-var-trash-restore-alt); } -.#{$fa-css-prefix}-tree:before { content: fa-content($fa-var-tree); } -.#{$fa-css-prefix}-trello:before { content: fa-content($fa-var-trello); } -.#{$fa-css-prefix}-tripadvisor:before { content: fa-content($fa-var-tripadvisor); } -.#{$fa-css-prefix}-trophy:before { content: fa-content($fa-var-trophy); } -.#{$fa-css-prefix}-truck:before { content: fa-content($fa-var-truck); } -.#{$fa-css-prefix}-truck-loading:before { content: fa-content($fa-var-truck-loading); } -.#{$fa-css-prefix}-truck-monster:before { content: fa-content($fa-var-truck-monster); } -.#{$fa-css-prefix}-truck-moving:before { content: fa-content($fa-var-truck-moving); } -.#{$fa-css-prefix}-truck-pickup:before { content: fa-content($fa-var-truck-pickup); } -.#{$fa-css-prefix}-tshirt:before { content: fa-content($fa-var-tshirt); } -.#{$fa-css-prefix}-tty:before { content: fa-content($fa-var-tty); } -.#{$fa-css-prefix}-tumblr:before { content: fa-content($fa-var-tumblr); } -.#{$fa-css-prefix}-tumblr-square:before { content: fa-content($fa-var-tumblr-square); } -.#{$fa-css-prefix}-tv:before { content: fa-content($fa-var-tv); } -.#{$fa-css-prefix}-twitch:before { content: fa-content($fa-var-twitch); } -.#{$fa-css-prefix}-twitter:before { content: fa-content($fa-var-twitter); } -.#{$fa-css-prefix}-twitter-square:before { content: fa-content($fa-var-twitter-square); } -.#{$fa-css-prefix}-typo3:before { content: fa-content($fa-var-typo3); } -.#{$fa-css-prefix}-uber:before { content: fa-content($fa-var-uber); } -.#{$fa-css-prefix}-ubuntu:before { content: fa-content($fa-var-ubuntu); } -.#{$fa-css-prefix}-uikit:before { content: fa-content($fa-var-uikit); } -.#{$fa-css-prefix}-umbraco:before { content: fa-content($fa-var-umbraco); } -.#{$fa-css-prefix}-umbrella:before { content: fa-content($fa-var-umbrella); } -.#{$fa-css-prefix}-umbrella-beach:before { content: fa-content($fa-var-umbrella-beach); } -.#{$fa-css-prefix}-underline:before { content: fa-content($fa-var-underline); } -.#{$fa-css-prefix}-undo:before { content: fa-content($fa-var-undo); } -.#{$fa-css-prefix}-undo-alt:before { content: fa-content($fa-var-undo-alt); } -.#{$fa-css-prefix}-uniregistry:before { content: fa-content($fa-var-uniregistry); } -.#{$fa-css-prefix}-unity:before { content: fa-content($fa-var-unity); } -.#{$fa-css-prefix}-universal-access:before { content: fa-content($fa-var-universal-access); } -.#{$fa-css-prefix}-university:before { content: fa-content($fa-var-university); } -.#{$fa-css-prefix}-unlink:before { content: fa-content($fa-var-unlink); } -.#{$fa-css-prefix}-unlock:before { content: fa-content($fa-var-unlock); } -.#{$fa-css-prefix}-unlock-alt:before { content: fa-content($fa-var-unlock-alt); } -.#{$fa-css-prefix}-unsplash:before { content: fa-content($fa-var-unsplash); } -.#{$fa-css-prefix}-untappd:before { content: fa-content($fa-var-untappd); } -.#{$fa-css-prefix}-upload:before { content: fa-content($fa-var-upload); } -.#{$fa-css-prefix}-ups:before { content: fa-content($fa-var-ups); } -.#{$fa-css-prefix}-usb:before { content: fa-content($fa-var-usb); } -.#{$fa-css-prefix}-user:before { content: fa-content($fa-var-user); } -.#{$fa-css-prefix}-user-alt:before { content: fa-content($fa-var-user-alt); } -.#{$fa-css-prefix}-user-alt-slash:before { content: fa-content($fa-var-user-alt-slash); } -.#{$fa-css-prefix}-user-astronaut:before { content: fa-content($fa-var-user-astronaut); } -.#{$fa-css-prefix}-user-check:before { content: fa-content($fa-var-user-check); } -.#{$fa-css-prefix}-user-circle:before { content: fa-content($fa-var-user-circle); } -.#{$fa-css-prefix}-user-clock:before { content: fa-content($fa-var-user-clock); } -.#{$fa-css-prefix}-user-cog:before { content: fa-content($fa-var-user-cog); } -.#{$fa-css-prefix}-user-edit:before { content: fa-content($fa-var-user-edit); } -.#{$fa-css-prefix}-user-friends:before { content: fa-content($fa-var-user-friends); } -.#{$fa-css-prefix}-user-graduate:before { content: fa-content($fa-var-user-graduate); } -.#{$fa-css-prefix}-user-injured:before { content: fa-content($fa-var-user-injured); } -.#{$fa-css-prefix}-user-lock:before { content: fa-content($fa-var-user-lock); } -.#{$fa-css-prefix}-user-md:before { content: fa-content($fa-var-user-md); } -.#{$fa-css-prefix}-user-minus:before { content: fa-content($fa-var-user-minus); } -.#{$fa-css-prefix}-user-ninja:before { content: fa-content($fa-var-user-ninja); } -.#{$fa-css-prefix}-user-nurse:before { content: fa-content($fa-var-user-nurse); } -.#{$fa-css-prefix}-user-plus:before { content: fa-content($fa-var-user-plus); } -.#{$fa-css-prefix}-user-secret:before { content: fa-content($fa-var-user-secret); } -.#{$fa-css-prefix}-user-shield:before { content: fa-content($fa-var-user-shield); } -.#{$fa-css-prefix}-user-slash:before { content: fa-content($fa-var-user-slash); } -.#{$fa-css-prefix}-user-tag:before { content: fa-content($fa-var-user-tag); } -.#{$fa-css-prefix}-user-tie:before { content: fa-content($fa-var-user-tie); } -.#{$fa-css-prefix}-user-times:before { content: fa-content($fa-var-user-times); } -.#{$fa-css-prefix}-users:before { content: fa-content($fa-var-users); } -.#{$fa-css-prefix}-users-cog:before { content: fa-content($fa-var-users-cog); } -.#{$fa-css-prefix}-users-slash:before { content: fa-content($fa-var-users-slash); } -.#{$fa-css-prefix}-usps:before { content: fa-content($fa-var-usps); } -.#{$fa-css-prefix}-ussunnah:before { content: fa-content($fa-var-ussunnah); } -.#{$fa-css-prefix}-utensil-spoon:before { content: fa-content($fa-var-utensil-spoon); } -.#{$fa-css-prefix}-utensils:before { content: fa-content($fa-var-utensils); } -.#{$fa-css-prefix}-vaadin:before { content: fa-content($fa-var-vaadin); } -.#{$fa-css-prefix}-vector-square:before { content: fa-content($fa-var-vector-square); } -.#{$fa-css-prefix}-venus:before { content: fa-content($fa-var-venus); } -.#{$fa-css-prefix}-venus-double:before { content: fa-content($fa-var-venus-double); } -.#{$fa-css-prefix}-venus-mars:before { content: fa-content($fa-var-venus-mars); } -.#{$fa-css-prefix}-viacoin:before { content: fa-content($fa-var-viacoin); } -.#{$fa-css-prefix}-viadeo:before { content: fa-content($fa-var-viadeo); } -.#{$fa-css-prefix}-viadeo-square:before { content: fa-content($fa-var-viadeo-square); } -.#{$fa-css-prefix}-vial:before { content: fa-content($fa-var-vial); } -.#{$fa-css-prefix}-vials:before { content: fa-content($fa-var-vials); } -.#{$fa-css-prefix}-viber:before { content: fa-content($fa-var-viber); } -.#{$fa-css-prefix}-video:before { content: fa-content($fa-var-video); } -.#{$fa-css-prefix}-video-slash:before { content: fa-content($fa-var-video-slash); } -.#{$fa-css-prefix}-vihara:before { content: fa-content($fa-var-vihara); } -.#{$fa-css-prefix}-vimeo:before { content: fa-content($fa-var-vimeo); } -.#{$fa-css-prefix}-vimeo-square:before { content: fa-content($fa-var-vimeo-square); } -.#{$fa-css-prefix}-vimeo-v:before { content: fa-content($fa-var-vimeo-v); } -.#{$fa-css-prefix}-vine:before { content: fa-content($fa-var-vine); } -.#{$fa-css-prefix}-virus:before { content: fa-content($fa-var-virus); } -.#{$fa-css-prefix}-virus-slash:before { content: fa-content($fa-var-virus-slash); } -.#{$fa-css-prefix}-viruses:before { content: fa-content($fa-var-viruses); } -.#{$fa-css-prefix}-vk:before { content: fa-content($fa-var-vk); } -.#{$fa-css-prefix}-vnv:before { content: fa-content($fa-var-vnv); } -.#{$fa-css-prefix}-voicemail:before { content: fa-content($fa-var-voicemail); } -.#{$fa-css-prefix}-volleyball-ball:before { content: fa-content($fa-var-volleyball-ball); } -.#{$fa-css-prefix}-volume-down:before { content: fa-content($fa-var-volume-down); } -.#{$fa-css-prefix}-volume-mute:before { content: fa-content($fa-var-volume-mute); } -.#{$fa-css-prefix}-volume-off:before { content: fa-content($fa-var-volume-off); } -.#{$fa-css-prefix}-volume-up:before { content: fa-content($fa-var-volume-up); } -.#{$fa-css-prefix}-vote-yea:before { content: fa-content($fa-var-vote-yea); } -.#{$fa-css-prefix}-vr-cardboard:before { content: fa-content($fa-var-vr-cardboard); } -.#{$fa-css-prefix}-vuejs:before { content: fa-content($fa-var-vuejs); } -.#{$fa-css-prefix}-walking:before { content: fa-content($fa-var-walking); } -.#{$fa-css-prefix}-wallet:before { content: fa-content($fa-var-wallet); } -.#{$fa-css-prefix}-warehouse:before { content: fa-content($fa-var-warehouse); } -.#{$fa-css-prefix}-water:before { content: fa-content($fa-var-water); } -.#{$fa-css-prefix}-wave-square:before { content: fa-content($fa-var-wave-square); } -.#{$fa-css-prefix}-waze:before { content: fa-content($fa-var-waze); } -.#{$fa-css-prefix}-weebly:before { content: fa-content($fa-var-weebly); } -.#{$fa-css-prefix}-weibo:before { content: fa-content($fa-var-weibo); } -.#{$fa-css-prefix}-weight:before { content: fa-content($fa-var-weight); } -.#{$fa-css-prefix}-weight-hanging:before { content: fa-content($fa-var-weight-hanging); } -.#{$fa-css-prefix}-weixin:before { content: fa-content($fa-var-weixin); } -.#{$fa-css-prefix}-whatsapp:before { content: fa-content($fa-var-whatsapp); } -.#{$fa-css-prefix}-whatsapp-square:before { content: fa-content($fa-var-whatsapp-square); } -.#{$fa-css-prefix}-wheelchair:before { content: fa-content($fa-var-wheelchair); } -.#{$fa-css-prefix}-whmcs:before { content: fa-content($fa-var-whmcs); } -.#{$fa-css-prefix}-wifi:before { content: fa-content($fa-var-wifi); } -.#{$fa-css-prefix}-wikipedia-w:before { content: fa-content($fa-var-wikipedia-w); } -.#{$fa-css-prefix}-wind:before { content: fa-content($fa-var-wind); } -.#{$fa-css-prefix}-window-close:before { content: fa-content($fa-var-window-close); } -.#{$fa-css-prefix}-window-maximize:before { content: fa-content($fa-var-window-maximize); } -.#{$fa-css-prefix}-window-minimize:before { content: fa-content($fa-var-window-minimize); } -.#{$fa-css-prefix}-window-restore:before { content: fa-content($fa-var-window-restore); } -.#{$fa-css-prefix}-windows:before { content: fa-content($fa-var-windows); } -.#{$fa-css-prefix}-wine-bottle:before { content: fa-content($fa-var-wine-bottle); } -.#{$fa-css-prefix}-wine-glass:before { content: fa-content($fa-var-wine-glass); } -.#{$fa-css-prefix}-wine-glass-alt:before { content: fa-content($fa-var-wine-glass-alt); } -.#{$fa-css-prefix}-wix:before { content: fa-content($fa-var-wix); } -.#{$fa-css-prefix}-wizards-of-the-coast:before { content: fa-content($fa-var-wizards-of-the-coast); } -.#{$fa-css-prefix}-wolf-pack-battalion:before { content: fa-content($fa-var-wolf-pack-battalion); } -.#{$fa-css-prefix}-won-sign:before { content: fa-content($fa-var-won-sign); } -.#{$fa-css-prefix}-wordpress:before { content: fa-content($fa-var-wordpress); } -.#{$fa-css-prefix}-wordpress-simple:before { content: fa-content($fa-var-wordpress-simple); } -.#{$fa-css-prefix}-wpbeginner:before { content: fa-content($fa-var-wpbeginner); } -.#{$fa-css-prefix}-wpexplorer:before { content: fa-content($fa-var-wpexplorer); } -.#{$fa-css-prefix}-wpforms:before { content: fa-content($fa-var-wpforms); } -.#{$fa-css-prefix}-wpressr:before { content: fa-content($fa-var-wpressr); } -.#{$fa-css-prefix}-wrench:before { content: fa-content($fa-var-wrench); } -.#{$fa-css-prefix}-x-ray:before { content: fa-content($fa-var-x-ray); } -.#{$fa-css-prefix}-xbox:before { content: fa-content($fa-var-xbox); } -.#{$fa-css-prefix}-xing:before { content: fa-content($fa-var-xing); } -.#{$fa-css-prefix}-xing-square:before { content: fa-content($fa-var-xing-square); } -.#{$fa-css-prefix}-y-combinator:before { content: fa-content($fa-var-y-combinator); } -.#{$fa-css-prefix}-yahoo:before { content: fa-content($fa-var-yahoo); } -.#{$fa-css-prefix}-yammer:before { content: fa-content($fa-var-yammer); } -.#{$fa-css-prefix}-yandex:before { content: fa-content($fa-var-yandex); } -.#{$fa-css-prefix}-yandex-international:before { content: fa-content($fa-var-yandex-international); } -.#{$fa-css-prefix}-yarn:before { content: fa-content($fa-var-yarn); } -.#{$fa-css-prefix}-yelp:before { content: fa-content($fa-var-yelp); } -.#{$fa-css-prefix}-yen-sign:before { content: fa-content($fa-var-yen-sign); } -.#{$fa-css-prefix}-yin-yang:before { content: fa-content($fa-var-yin-yang); } -.#{$fa-css-prefix}-yoast:before { content: fa-content($fa-var-yoast); } -.#{$fa-css-prefix}-youtube:before { content: fa-content($fa-var-youtube); } -.#{$fa-css-prefix}-youtube-square:before { content: fa-content($fa-var-youtube-square); } -.#{$fa-css-prefix}-zhihu:before { content: fa-content($fa-var-zhihu); } diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_larger.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_larger.scss deleted file mode 100644 index 58a3f67..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_larger.scss +++ /dev/null @@ -1,23 +0,0 @@ -// Icon Sizes -// ------------------------- -@use 'sass:math'; -// makes the font 33% larger relative to the icon container -.#{$fa-css-prefix}-lg { - font-size: (math.div(4em, 3)); - line-height: (math.div(3em, 4)); - vertical-align: -0.0667em; -} - -.#{$fa-css-prefix}-xs { - font-size: 0.75em; -} - -.#{$fa-css-prefix}-sm { - font-size: 0.875em; -} - -@for $i from 1 through 10 { - .#{$fa-css-prefix}-#{$i}x { - font-size: $i * 1em; - } -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_list.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_list.scss deleted file mode 100644 index a44483e..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_list.scss +++ /dev/null @@ -1,21 +0,0 @@ -// List Icons -// ------------------------- -@use 'sass:math'; - -.#{$fa-css-prefix}-ul { - list-style-type: none; - margin-left: math.div($fa-li-width * 5, 4); - padding-left: 0; - - > li { - position: relative; - } -} - -.#{$fa-css-prefix}-li { - left: -$fa-li-width; - position: absolute; - text-align: center; - width: $fa-li-width; - line-height: inherit; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_mixins.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_mixins.scss deleted file mode 100644 index 55baeeb..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_mixins.scss +++ /dev/null @@ -1,56 +0,0 @@ -// Mixins -// -------------------------- - -@mixin fa-icon { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - display: inline-block; - font-style: normal; - font-variant: normal; - font-weight: normal; - line-height: 1; -} - -@mixin fa-icon-rotate($degrees, $rotation) { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; - transform: rotate($degrees); -} - -@mixin fa-icon-flip($horiz, $vert, $rotation) { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; - transform: scale($horiz, $vert); -} - - -// Only display content to screen readers. A la Bootstrap 4. -// -// See: http://a11yproject.com/posts/how-to-hide-content/ - -@mixin sr-only { - border: 0; - clip: rect(0, 0, 0, 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} - -// Use in conjunction with .sr-only to only display content when it's focused. -// -// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 -// -// Credit: HTML5 Boilerplate - -@mixin sr-only-focusable { - &:active, - &:focus { - clip: auto; - height: auto; - margin: 0; - overflow: visible; - position: static; - width: auto; - } -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_rotated-flipped.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_rotated-flipped.scss deleted file mode 100644 index 164d972..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_rotated-flipped.scss +++ /dev/null @@ -1,24 +0,0 @@ -// Rotated & Flipped Icons -// ------------------------- - -.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } -.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } -.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } - -.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } -.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } -.#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } - -// Hook for IE8-9 -// ------------------------- - -:root { - .#{$fa-css-prefix}-rotate-90, - .#{$fa-css-prefix}-rotate-180, - .#{$fa-css-prefix}-rotate-270, - .#{$fa-css-prefix}-flip-horizontal, - .#{$fa-css-prefix}-flip-vertical, - .#{$fa-css-prefix}-flip-both { - filter: none; - } -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_screen-reader.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_screen-reader.scss deleted file mode 100644 index 5d0ab26..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_screen-reader.scss +++ /dev/null @@ -1,5 +0,0 @@ -// Screen Readers -// ------------------------- - -.sr-only { @include sr-only; } -.sr-only-focusable { @include sr-only-focusable; } diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_shims.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_shims.scss deleted file mode 100644 index d175344..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_shims.scss +++ /dev/null @@ -1,2066 +0,0 @@ -.#{$fa-css-prefix}.#{$fa-css-prefix}-glass:before { content: fa-content($fa-var-glass-martini); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-meetup { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-o:before { content: fa-content($fa-var-star); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-remove:before { content: fa-content($fa-var-times); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-close:before { content: fa-content($fa-var-times); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gear:before { content: fa-content($fa-var-cog); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-trash-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-trash-o:before { content: fa-content($fa-var-trash-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-o:before { content: fa-content($fa-var-file); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-clock-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-clock-o:before { content: fa-content($fa-var-clock); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-down { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-down:before { content: fa-content($fa-var-arrow-alt-circle-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-up { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-up:before { content: fa-content($fa-var-arrow-alt-circle-up); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-play-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-play-circle-o:before { content: fa-content($fa-var-play-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-repeat:before { content: fa-content($fa-var-redo); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-rotate-right:before { content: fa-content($fa-var-redo); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-refresh:before { content: fa-content($fa-var-sync); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-list-alt { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-dedent:before { content: fa-content($fa-var-outdent); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-video-camera:before { content: fa-content($fa-var-video); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-picture-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-picture-o:before { content: fa-content($fa-var-image); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-photo { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-photo:before { content: fa-content($fa-var-image); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-image { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-image:before { content: fa-content($fa-var-image); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil:before { content: fa-content($fa-var-pencil-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-map-marker:before { content: fa-content($fa-var-map-marker-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square-o:before { content: fa-content($fa-var-edit); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-share-square-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-share-square-o:before { content: fa-content($fa-var-share-square); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-check-square-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-check-square-o:before { content: fa-content($fa-var-check-square); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows:before { content: fa-content($fa-var-arrows-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-times-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-times-circle-o:before { content: fa-content($fa-var-times-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-check-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-check-circle-o:before { content: fa-content($fa-var-check-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-forward:before { content: fa-content($fa-var-share); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-expand:before { content: fa-content($fa-var-expand-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-compress:before { content: fa-content($fa-var-compress-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-eye { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-eye-slash { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-warning:before { content: fa-content($fa-var-exclamation-triangle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar:before { content: fa-content($fa-var-calendar-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-v:before { content: fa-content($fa-var-arrows-alt-v); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-h:before { content: fa-content($fa-var-arrows-alt-h); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart:before { content: fa-content($fa-var-chart-bar); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart-o:before { content: fa-content($fa-var-chart-bar); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-twitter-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gears:before { content: fa-content($fa-var-cogs); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-up { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-up:before { content: fa-content($fa-var-thumbs-up); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-down { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-down:before { content: fa-content($fa-var-thumbs-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-heart-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-heart-o:before { content: fa-content($fa-var-heart); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sign-out:before { content: fa-content($fa-var-sign-out-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin-square:before { content: fa-content($fa-var-linkedin); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thumb-tack:before { content: fa-content($fa-var-thumbtack); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-external-link:before { content: fa-content($fa-var-external-link-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sign-in:before { content: fa-content($fa-var-sign-in-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-github-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-lemon-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-lemon-o:before { content: fa-content($fa-var-lemon); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-square-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-square-o:before { content: fa-content($fa-var-square); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bookmark-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-bookmark-o:before { content: fa-content($fa-var-bookmark); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-twitter { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook:before { content: fa-content($fa-var-facebook-f); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-f { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-f:before { content: fa-content($fa-var-facebook-f); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-github { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-credit-card { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-feed:before { content: fa-content($fa-var-rss); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hdd-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hdd-o:before { content: fa-content($fa-var-hdd); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-right { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-right:before { content: fa-content($fa-var-hand-point-right); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-left { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-left:before { content: fa-content($fa-var-hand-point-left); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-up { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-up:before { content: fa-content($fa-var-hand-point-up); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-down { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-down:before { content: fa-content($fa-var-hand-point-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-alt:before { content: fa-content($fa-var-expand-arrows-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-group:before { content: fa-content($fa-var-users); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-chain:before { content: fa-content($fa-var-link); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-scissors:before { content: fa-content($fa-var-cut); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-files-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-files-o:before { content: fa-content($fa-var-copy); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-floppy-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-floppy-o:before { content: fa-content($fa-var-save); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-navicon:before { content: fa-content($fa-var-bars); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-reorder:before { content: fa-content($fa-var-bars); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus:before { content: fa-content($fa-var-google-plus-g); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-money { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-money:before { content: fa-content($fa-var-money-bill-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-unsorted:before { content: fa-content($fa-var-sort); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-desc:before { content: fa-content($fa-var-sort-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-asc:before { content: fa-content($fa-var-sort-up); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin:before { content: fa-content($fa-var-linkedin-in); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-rotate-left:before { content: fa-content($fa-var-undo); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-legal:before { content: fa-content($fa-var-gavel); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-tachometer:before { content: fa-content($fa-var-tachometer-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-dashboard:before { content: fa-content($fa-var-tachometer-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-comment-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-comment-o:before { content: fa-content($fa-var-comment); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-comments-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-comments-o:before { content: fa-content($fa-var-comments); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-flash:before { content: fa-content($fa-var-bolt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-clipboard { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-paste { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-paste:before { content: fa-content($fa-var-clipboard); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-lightbulb-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-lightbulb-o:before { content: fa-content($fa-var-lightbulb); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-exchange:before { content: fa-content($fa-var-exchange-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cloud-download:before { content: fa-content($fa-var-cloud-download-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cloud-upload:before { content: fa-content($fa-var-cloud-upload-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-o:before { content: fa-content($fa-var-bell); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cutlery:before { content: fa-content($fa-var-utensils); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text-o:before { content: fa-content($fa-var-file-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-building-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-building-o:before { content: fa-content($fa-var-building); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hospital-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hospital-o:before { content: fa-content($fa-var-hospital); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-tablet:before { content: fa-content($fa-var-tablet-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-mobile:before { content: fa-content($fa-var-mobile-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-mobile-phone:before { content: fa-content($fa-var-mobile-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o:before { content: fa-content($fa-var-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-reply:before { content: fa-content($fa-var-reply); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-github-alt { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-o:before { content: fa-content($fa-var-folder); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-open-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-open-o:before { content: fa-content($fa-var-folder-open); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-smile-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-smile-o:before { content: fa-content($fa-var-smile); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-frown-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-frown-o:before { content: fa-content($fa-var-frown); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-meh-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-meh-o:before { content: fa-content($fa-var-meh); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-keyboard-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-keyboard-o:before { content: fa-content($fa-var-keyboard); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-flag-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-flag-o:before { content: fa-content($fa-var-flag); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-reply-all:before { content: fa-content($fa-var-reply-all); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-o:before { content: fa-content($fa-var-star-half); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-empty { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-empty:before { content: fa-content($fa-var-star-half); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-full { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-full:before { content: fa-content($fa-var-star-half); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-code-fork:before { content: fa-content($fa-var-code-branch); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-chain-broken:before { content: fa-content($fa-var-unlink); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-shield:before { content: fa-content($fa-var-shield-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-o:before { content: fa-content($fa-var-calendar); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-maxcdn { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-html5 { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-css3 { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-ticket:before { content: fa-content($fa-var-ticket-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-minus-square-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-minus-square-o:before { content: fa-content($fa-var-minus-square); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-level-up:before { content: fa-content($fa-var-level-up-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-level-down:before { content: fa-content($fa-var-level-down-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square:before { content: fa-content($fa-var-pen-square); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-external-link-square:before { content: fa-content($fa-var-external-link-square-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-compass { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-down { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-down:before { content: fa-content($fa-var-caret-square-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-down { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-down:before { content: fa-content($fa-var-caret-square-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-up { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-up:before { content: fa-content($fa-var-caret-square-up); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-up { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-up:before { content: fa-content($fa-var-caret-square-up); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-right { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-right:before { content: fa-content($fa-var-caret-square-right); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-right { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-right:before { content: fa-content($fa-var-caret-square-right); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-eur:before { content: fa-content($fa-var-euro-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-euro:before { content: fa-content($fa-var-euro-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gbp:before { content: fa-content($fa-var-pound-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-usd:before { content: fa-content($fa-var-dollar-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-dollar:before { content: fa-content($fa-var-dollar-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-inr:before { content: fa-content($fa-var-rupee-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-rupee:before { content: fa-content($fa-var-rupee-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-jpy:before { content: fa-content($fa-var-yen-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cny:before { content: fa-content($fa-var-yen-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-rmb:before { content: fa-content($fa-var-yen-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-yen:before { content: fa-content($fa-var-yen-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-rub:before { content: fa-content($fa-var-ruble-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-ruble:before { content: fa-content($fa-var-ruble-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-rouble:before { content: fa-content($fa-var-ruble-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-krw:before { content: fa-content($fa-var-won-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-won:before { content: fa-content($fa-var-won-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-btc { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bitcoin { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-bitcoin:before { content: fa-content($fa-var-btc); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text:before { content: fa-content($fa-var-file-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-alpha-asc:before { content: fa-content($fa-var-sort-alpha-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-alpha-desc:before { content: fa-content($fa-var-sort-alpha-down-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-amount-asc:before { content: fa-content($fa-var-sort-amount-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-amount-desc:before { content: fa-content($fa-var-sort-amount-down-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-numeric-asc:before { content: fa-content($fa-var-sort-numeric-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-numeric-desc:before { content: fa-content($fa-var-sort-numeric-down-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-xing { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-xing-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-play { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-play:before { content: fa-content($fa-var-youtube); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-dropbox { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-stack-overflow { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-instagram { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-flickr { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-adn { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket-square:before { content: fa-content($fa-var-bitbucket); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-tumblr { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-tumblr-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-down:before { content: fa-content($fa-var-long-arrow-alt-down); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-up:before { content: fa-content($fa-var-long-arrow-alt-up); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-left:before { content: fa-content($fa-var-long-arrow-alt-left); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-right:before { content: fa-content($fa-var-long-arrow-alt-right); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-apple { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-windows { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-android { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-linux { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-dribbble { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-skype { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-foursquare { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-trello { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gratipay { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gittip { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-gittip:before { content: fa-content($fa-var-gratipay); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sun-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-sun-o:before { content: fa-content($fa-var-sun); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-moon-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-moon-o:before { content: fa-content($fa-var-moon); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-vk { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-weibo { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-renren { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pagelines { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-stack-exchange { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-right { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-right:before { content: fa-content($fa-var-arrow-alt-circle-right); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-left { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-left:before { content: fa-content($fa-var-arrow-alt-circle-left); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-left { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-left:before { content: fa-content($fa-var-caret-square-left); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-left { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-left:before { content: fa-content($fa-var-caret-square-left); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-dot-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-dot-circle-o:before { content: fa-content($fa-var-dot-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-try:before { content: fa-content($fa-var-lira-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-turkish-lira:before { content: fa-content($fa-var-lira-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-plus-square-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-plus-square-o:before { content: fa-content($fa-var-plus-square); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-slack { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-wordpress { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-openid { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-institution:before { content: fa-content($fa-var-university); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bank:before { content: fa-content($fa-var-university); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-mortar-board:before { content: fa-content($fa-var-graduation-cap); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-yahoo { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-google { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-stumbleupon-circle { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-stumbleupon { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-delicious { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-digg { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper-pp { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper-alt { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-drupal { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-joomla { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-spoon:before { content: fa-content($fa-var-utensil-spoon); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-behance { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-behance-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-steam { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-steam-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-automobile:before { content: fa-content($fa-var-car); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-o:before { content: fa-content($fa-var-envelope); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-spotify { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-deviantart { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-soundcloud { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-pdf-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-pdf-o:before { content: fa-content($fa-var-file-pdf); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-word-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-word-o:before { content: fa-content($fa-var-file-word); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-excel-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-excel-o:before { content: fa-content($fa-var-file-excel); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-powerpoint-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-powerpoint-o:before { content: fa-content($fa-var-file-powerpoint); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-image-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-image-o:before { content: fa-content($fa-var-file-image); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-photo-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-photo-o:before { content: fa-content($fa-var-file-image); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-picture-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-picture-o:before { content: fa-content($fa-var-file-image); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-archive-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-archive-o:before { content: fa-content($fa-var-file-archive); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-zip-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-zip-o:before { content: fa-content($fa-var-file-archive); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-audio-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-audio-o:before { content: fa-content($fa-var-file-audio); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-sound-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-sound-o:before { content: fa-content($fa-var-file-audio); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-video-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-video-o:before { content: fa-content($fa-var-file-video); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-movie-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-movie-o:before { content: fa-content($fa-var-file-video); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-code-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-file-code-o:before { content: fa-content($fa-var-file-code); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-vine { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-codepen { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-jsfiddle { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-life-ring { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-life-bouy { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-life-bouy:before { content: fa-content($fa-var-life-ring); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-life-buoy { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-life-buoy:before { content: fa-content($fa-var-life-ring); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-life-saver { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-life-saver:before { content: fa-content($fa-var-life-ring); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-support { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-support:before { content: fa-content($fa-var-life-ring); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o-notch:before { content: fa-content($fa-var-circle-notch); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-rebel { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-ra { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-ra:before { content: fa-content($fa-var-rebel); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-resistance { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-resistance:before { content: fa-content($fa-var-rebel); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-empire { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-ge { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-ge:before { content: fa-content($fa-var-empire); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-git-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-git { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hacker-news { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator-square:before { content: fa-content($fa-var-hacker-news); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-yc-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-yc-square:before { content: fa-content($fa-var-hacker-news); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-tencent-weibo { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-qq { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-weixin { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-wechat { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-wechat:before { content: fa-content($fa-var-weixin); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-send:before { content: fa-content($fa-var-paper-plane); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-paper-plane-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-paper-plane-o:before { content: fa-content($fa-var-paper-plane); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-send-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-send-o:before { content: fa-content($fa-var-paper-plane); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-thin { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-thin:before { content: fa-content($fa-var-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-header:before { content: fa-content($fa-var-heading); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sliders:before { content: fa-content($fa-var-sliders-h); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-futbol-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-futbol-o:before { content: fa-content($fa-var-futbol); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-soccer-ball-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-soccer-ball-o:before { content: fa-content($fa-var-futbol); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-slideshare { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-twitch { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-yelp { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-newspaper-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-newspaper-o:before { content: fa-content($fa-var-newspaper); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-paypal { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-wallet { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-visa { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-mastercard { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-discover { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-amex { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-paypal { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-stripe { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-slash-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-slash-o:before { content: fa-content($fa-var-bell-slash); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-trash:before { content: fa-content($fa-var-trash-alt); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-copyright { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-eyedropper:before { content: fa-content($fa-var-eye-dropper); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-area-chart:before { content: fa-content($fa-var-chart-area); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pie-chart:before { content: fa-content($fa-var-chart-pie); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-line-chart:before { content: fa-content($fa-var-chart-line); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-lastfm { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-lastfm-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-ioxhost { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-angellist { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc:before { content: fa-content($fa-var-closed-captioning); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-ils:before { content: fa-content($fa-var-shekel-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-shekel:before { content: fa-content($fa-var-shekel-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sheqel:before { content: fa-content($fa-var-shekel-sign); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-meanpath { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-meanpath:before { content: fa-content($fa-var-font-awesome); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-buysellads { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-connectdevelop { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-dashcube { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-forumbee { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-leanpub { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sellsy { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-shirtsinbulk { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-simplybuilt { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-skyatlas { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-diamond { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-diamond:before { content: fa-content($fa-var-gem); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-intersex:before { content: fa-content($fa-var-transgender); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-official { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-official:before { content: fa-content($fa-var-facebook); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest-p { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-whatsapp { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hotel:before { content: fa-content($fa-var-bed); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-viacoin { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-medium { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-yc { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-yc:before { content: fa-content($fa-var-y-combinator); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-optin-monster { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-opencart { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-expeditedssl { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-4:before { content: fa-content($fa-var-battery-full); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-battery:before { content: fa-content($fa-var-battery-full); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-3:before { content: fa-content($fa-var-battery-three-quarters); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-2:before { content: fa-content($fa-var-battery-half); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-1:before { content: fa-content($fa-var-battery-quarter); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-0:before { content: fa-content($fa-var-battery-empty); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-object-group { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-object-ungroup { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-sticky-note-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-sticky-note-o:before { content: fa-content($fa-var-sticky-note); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-jcb { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-diners-club { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-clone { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-o:before { content: fa-content($fa-var-hourglass); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-1:before { content: fa-content($fa-var-hourglass-start); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-2:before { content: fa-content($fa-var-hourglass-half); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-3:before { content: fa-content($fa-var-hourglass-end); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-rock-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-rock-o:before { content: fa-content($fa-var-hand-rock); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-grab-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-grab-o:before { content: fa-content($fa-var-hand-rock); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-paper-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-paper-o:before { content: fa-content($fa-var-hand-paper); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-stop-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-stop-o:before { content: fa-content($fa-var-hand-paper); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-scissors-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-scissors-o:before { content: fa-content($fa-var-hand-scissors); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-lizard-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-lizard-o:before { content: fa-content($fa-var-hand-lizard); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-spock-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-spock-o:before { content: fa-content($fa-var-hand-spock); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-pointer-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-pointer-o:before { content: fa-content($fa-var-hand-pointer); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-peace-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-peace-o:before { content: fa-content($fa-var-hand-peace); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-registered { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-creative-commons { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gg { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gg-circle { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-tripadvisor { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-odnoklassniki { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-odnoklassniki-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-get-pocket { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-wikipedia-w { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-safari { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-chrome { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-firefox { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-opera { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-internet-explorer { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-television:before { content: fa-content($fa-var-tv); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-contao { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-500px { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-amazon { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-plus-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-plus-o:before { content: fa-content($fa-var-calendar-plus); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-minus-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-minus-o:before { content: fa-content($fa-var-calendar-minus); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-times-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-times-o:before { content: fa-content($fa-var-calendar-times); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-check-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-check-o:before { content: fa-content($fa-var-calendar-check); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-map-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-map-o:before { content: fa-content($fa-var-map); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting:before { content: fa-content($fa-var-comment-dots); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting-o:before { content: fa-content($fa-var-comment-dots); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-houzz { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo:before { content: fa-content($fa-var-vimeo-v); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-black-tie { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-fonticons { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit-alien { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-edge { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-credit-card-alt:before { content: fa-content($fa-var-credit-card); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-codiepie { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-modx { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-fort-awesome { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-usb { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-product-hunt { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-mixcloud { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-scribd { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pause-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-pause-circle-o:before { content: fa-content($fa-var-pause-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-stop-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-stop-circle-o:before { content: fa-content($fa-var-stop-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bluetooth { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bluetooth-b { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-gitlab { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-wpbeginner { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-wpforms { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-envira { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-wheelchair-alt { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-wheelchair-alt:before { content: fa-content($fa-var-accessible-icon); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-question-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-question-circle-o:before { content: fa-content($fa-var-question-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-volume-control-phone:before { content: fa-content($fa-var-phone-volume); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-asl-interpreting:before { content: fa-content($fa-var-american-sign-language-interpreting); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-deafness:before { content: fa-content($fa-var-deaf); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-hard-of-hearing:before { content: fa-content($fa-var-deaf); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-glide { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-glide-g { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-signing:before { content: fa-content($fa-var-sign-language); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-viadeo { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-viadeo-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-ghost { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-square { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-first-order { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-yoast { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-themeisle { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-official { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-official:before { content: fa-content($fa-var-google-plus); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-circle { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-circle:before { content: fa-content($fa-var-google-plus); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-font-awesome { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-fa { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-fa:before { content: fa-content($fa-var-font-awesome); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-handshake-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-handshake-o:before { content: fa-content($fa-var-handshake); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-open-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-open-o:before { content: fa-content($fa-var-envelope-open); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-linode { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-address-book-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-address-book-o:before { content: fa-content($fa-var-address-book); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard:before { content: fa-content($fa-var-address-card); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-address-card-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-address-card-o:before { content: fa-content($fa-var-address-card); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard-o:before { content: fa-content($fa-var-address-card); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-user-circle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-user-circle-o:before { content: fa-content($fa-var-user-circle); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-user-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-user-o:before { content: fa-content($fa-var-user); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-id-badge { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license:before { content: fa-content($fa-var-id-card); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-id-card-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-id-card-o:before { content: fa-content($fa-var-id-card); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license-o:before { content: fa-content($fa-var-id-card); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-quora { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-free-code-camp { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-telegram { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-4:before { content: fa-content($fa-var-thermometer-full); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer:before { content: fa-content($fa-var-thermometer-full); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-3:before { content: fa-content($fa-var-thermometer-three-quarters); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-2:before { content: fa-content($fa-var-thermometer-half); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-1:before { content: fa-content($fa-var-thermometer-quarter); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-0:before { content: fa-content($fa-var-thermometer-empty); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bathtub:before { content: fa-content($fa-var-bath); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-s15:before { content: fa-content($fa-var-bath); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-window-maximize { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-window-restore { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle:before { content: fa-content($fa-var-window-close); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-window-close-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-window-close-o:before { content: fa-content($fa-var-window-close); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle-o:before { content: fa-content($fa-var-window-close); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-bandcamp { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-grav { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-etsy { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-imdb { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-ravelry { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-eercast { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-eercast:before { content: fa-content($fa-var-sellcast); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-snowflake-o { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} -.#{$fa-css-prefix}.#{$fa-css-prefix}-snowflake-o:before { content: fa-content($fa-var-snowflake); } - -.#{$fa-css-prefix}.#{$fa-css-prefix}-superpowers { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-wpexplorer { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} - -.#{$fa-css-prefix}.#{$fa-css-prefix}-cab:before { content: fa-content($fa-var-taxi); } - diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_stacked.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_stacked.scss deleted file mode 100644 index ae7ef4e..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_stacked.scss +++ /dev/null @@ -1,31 +0,0 @@ -// Stacked Icons -// ------------------------- - -.#{$fa-css-prefix}-stack { - display: inline-block; - height: 2em; - line-height: 2em; - position: relative; - vertical-align: middle; - width: ($fa-fw-width*2); -} - -.#{$fa-css-prefix}-stack-1x, -.#{$fa-css-prefix}-stack-2x { - left: 0; - position: absolute; - text-align: center; - width: 100%; -} - -.#{$fa-css-prefix}-stack-1x { - line-height: inherit; -} - -.#{$fa-css-prefix}-stack-2x { - font-size: 2em; -} - -.#{$fa-css-prefix}-inverse { - color: $fa-inverse; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_variables.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_variables.scss deleted file mode 100644 index fb203b9..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_variables.scss +++ /dev/null @@ -1,1469 +0,0 @@ -// Variables -// -------------------------- -@use 'sass:math'; - -$fa-font-path: '../../../fonts/fontawesome' !default; -$fa-font-size-base: 16px !default; -$fa-font-display: block !default; -$fa-css-prefix: fa !default; -$fa-version: '5.13.1' !default; -$fa-border-color: #eee !default; -$fa-inverse: #fff !default; -$fa-li-width: 2em !default; -$fa-fw-width: (math.div(20em, 16)); -$fa-primary-opacity: 1 !default; -$fa-secondary-opacity: 0.4 !default; - -// Convenience function used to set content property -@function fa-content($fa-var) { - @return unquote('"#{ $fa-var }"'); -} - -$fa-var-500px: \f26e; -$fa-var-accessible-icon: \f368; -$fa-var-accusoft: \f369; -$fa-var-acquisitions-incorporated: \f6af; -$fa-var-ad: \f641; -$fa-var-address-book: \f2b9; -$fa-var-address-card: \f2bb; -$fa-var-adjust: \f042; -$fa-var-adn: \f170; -$fa-var-adobe: \f778; -$fa-var-adversal: \f36a; -$fa-var-affiliatetheme: \f36b; -$fa-var-air-freshener: \f5d0; -$fa-var-airbnb: \f834; -$fa-var-algolia: \f36c; -$fa-var-align-center: \f037; -$fa-var-align-justify: \f039; -$fa-var-align-left: \f036; -$fa-var-align-right: \f038; -$fa-var-alipay: \f642; -$fa-var-allergies: \f461; -$fa-var-amazon: \f270; -$fa-var-amazon-pay: \f42c; -$fa-var-ambulance: \f0f9; -$fa-var-american-sign-language-interpreting: \f2a3; -$fa-var-amilia: \f36d; -$fa-var-anchor: \f13d; -$fa-var-android: \f17b; -$fa-var-angellist: \f209; -$fa-var-angle-double-down: \f103; -$fa-var-angle-double-left: \f100; -$fa-var-angle-double-right: \f101; -$fa-var-angle-double-up: \f102; -$fa-var-angle-down: \f107; -$fa-var-angle-left: \f104; -$fa-var-angle-right: \f105; -$fa-var-angle-up: \f106; -$fa-var-angry: \f556; -$fa-var-angrycreative: \f36e; -$fa-var-angular: \f420; -$fa-var-ankh: \f644; -$fa-var-app-store: \f36f; -$fa-var-app-store-ios: \f370; -$fa-var-apper: \f371; -$fa-var-apple: \f179; -$fa-var-apple-alt: \f5d1; -$fa-var-apple-pay: \f415; -$fa-var-archive: \f187; -$fa-var-archway: \f557; -$fa-var-arrow-alt-circle-down: \f358; -$fa-var-arrow-alt-circle-left: \f359; -$fa-var-arrow-alt-circle-right: \f35a; -$fa-var-arrow-alt-circle-up: \f35b; -$fa-var-arrow-circle-down: \f0ab; -$fa-var-arrow-circle-left: \f0a8; -$fa-var-arrow-circle-right: \f0a9; -$fa-var-arrow-circle-up: \f0aa; -$fa-var-arrow-down: \f063; -$fa-var-arrow-left: \f060; -$fa-var-arrow-right: \f061; -$fa-var-arrow-up: \f062; -$fa-var-arrows-alt: \f0b2; -$fa-var-arrows-alt-h: \f337; -$fa-var-arrows-alt-v: \f338; -$fa-var-artstation: \f77a; -$fa-var-assistive-listening-systems: \f2a2; -$fa-var-asterisk: \f069; -$fa-var-asymmetrik: \f372; -$fa-var-at: \f1fa; -$fa-var-atlas: \f558; -$fa-var-atlassian: \f77b; -$fa-var-atom: \f5d2; -$fa-var-audible: \f373; -$fa-var-audio-description: \f29e; -$fa-var-autoprefixer: \f41c; -$fa-var-avianex: \f374; -$fa-var-aviato: \f421; -$fa-var-award: \f559; -$fa-var-aws: \f375; -$fa-var-baby: \f77c; -$fa-var-baby-carriage: \f77d; -$fa-var-backspace: \f55a; -$fa-var-backward: \f04a; -$fa-var-bacon: \f7e5; -$fa-var-bacteria: \f959; -$fa-var-bacterium: \f95a; -$fa-var-bahai: \f666; -$fa-var-balance-scale: \f24e; -$fa-var-balance-scale-left: \f515; -$fa-var-balance-scale-right: \f516; -$fa-var-ban: \f05e; -$fa-var-band-aid: \f462; -$fa-var-bandcamp: \f2d5; -$fa-var-barcode: \f02a; -$fa-var-bars: \f0c9; -$fa-var-baseball-ball: \f433; -$fa-var-basketball-ball: \f434; -$fa-var-bath: \f2cd; -$fa-var-battery-empty: \f244; -$fa-var-battery-full: \f240; -$fa-var-battery-half: \f242; -$fa-var-battery-quarter: \f243; -$fa-var-battery-three-quarters: \f241; -$fa-var-battle-net: \f835; -$fa-var-bed: \f236; -$fa-var-beer: \f0fc; -$fa-var-behance: \f1b4; -$fa-var-behance-square: \f1b5; -$fa-var-bell: \f0f3; -$fa-var-bell-slash: \f1f6; -$fa-var-bezier-curve: \f55b; -$fa-var-bible: \f647; -$fa-var-bicycle: \f206; -$fa-var-biking: \f84a; -$fa-var-bimobject: \f378; -$fa-var-binoculars: \f1e5; -$fa-var-biohazard: \f780; -$fa-var-birthday-cake: \f1fd; -$fa-var-bitbucket: \f171; -$fa-var-bitcoin: \f379; -$fa-var-bity: \f37a; -$fa-var-black-tie: \f27e; -$fa-var-blackberry: \f37b; -$fa-var-blender: \f517; -$fa-var-blender-phone: \f6b6; -$fa-var-blind: \f29d; -$fa-var-blog: \f781; -$fa-var-blogger: \f37c; -$fa-var-blogger-b: \f37d; -$fa-var-bluetooth: \f293; -$fa-var-bluetooth-b: \f294; -$fa-var-bold: \f032; -$fa-var-bolt: \f0e7; -$fa-var-bomb: \f1e2; -$fa-var-bone: \f5d7; -$fa-var-bong: \f55c; -$fa-var-book: \f02d; -$fa-var-book-dead: \f6b7; -$fa-var-book-medical: \f7e6; -$fa-var-book-open: \f518; -$fa-var-book-reader: \f5da; -$fa-var-bookmark: \f02e; -$fa-var-bootstrap: \f836; -$fa-var-border-all: \f84c; -$fa-var-border-none: \f850; -$fa-var-border-style: \f853; -$fa-var-bowling-ball: \f436; -$fa-var-box: \f466; -$fa-var-box-open: \f49e; -$fa-var-box-tissue: \f95b; -$fa-var-boxes: \f468; -$fa-var-braille: \f2a1; -$fa-var-brain: \f5dc; -$fa-var-bread-slice: \f7ec; -$fa-var-briefcase: \f0b1; -$fa-var-briefcase-medical: \f469; -$fa-var-broadcast-tower: \f519; -$fa-var-broom: \f51a; -$fa-var-brush: \f55d; -$fa-var-btc: \f15a; -$fa-var-buffer: \f837; -$fa-var-bug: \f188; -$fa-var-building: \f1ad; -$fa-var-bullhorn: \f0a1; -$fa-var-bullseye: \f140; -$fa-var-burn: \f46a; -$fa-var-buromobelexperte: \f37f; -$fa-var-bus: \f207; -$fa-var-bus-alt: \f55e; -$fa-var-business-time: \f64a; -$fa-var-buy-n-large: \f8a6; -$fa-var-buysellads: \f20d; -$fa-var-calculator: \f1ec; -$fa-var-calendar: \f133; -$fa-var-calendar-alt: \f073; -$fa-var-calendar-check: \f274; -$fa-var-calendar-day: \f783; -$fa-var-calendar-minus: \f272; -$fa-var-calendar-plus: \f271; -$fa-var-calendar-times: \f273; -$fa-var-calendar-week: \f784; -$fa-var-camera: \f030; -$fa-var-camera-retro: \f083; -$fa-var-campground: \f6bb; -$fa-var-canadian-maple-leaf: \f785; -$fa-var-candy-cane: \f786; -$fa-var-cannabis: \f55f; -$fa-var-capsules: \f46b; -$fa-var-car: \f1b9; -$fa-var-car-alt: \f5de; -$fa-var-car-battery: \f5df; -$fa-var-car-crash: \f5e1; -$fa-var-car-side: \f5e4; -$fa-var-caravan: \f8ff; -$fa-var-caret-down: \f0d7; -$fa-var-caret-left: \f0d9; -$fa-var-caret-right: \f0da; -$fa-var-caret-square-down: \f150; -$fa-var-caret-square-left: \f191; -$fa-var-caret-square-right: \f152; -$fa-var-caret-square-up: \f151; -$fa-var-caret-up: \f0d8; -$fa-var-carrot: \f787; -$fa-var-cart-arrow-down: \f218; -$fa-var-cart-plus: \f217; -$fa-var-cash-register: \f788; -$fa-var-cat: \f6be; -$fa-var-cc-amazon-pay: \f42d; -$fa-var-cc-amex: \f1f3; -$fa-var-cc-apple-pay: \f416; -$fa-var-cc-diners-club: \f24c; -$fa-var-cc-discover: \f1f2; -$fa-var-cc-jcb: \f24b; -$fa-var-cc-mastercard: \f1f1; -$fa-var-cc-paypal: \f1f4; -$fa-var-cc-stripe: \f1f5; -$fa-var-cc-visa: \f1f0; -$fa-var-centercode: \f380; -$fa-var-centos: \f789; -$fa-var-certificate: \f0a3; -$fa-var-chair: \f6c0; -$fa-var-chalkboard: \f51b; -$fa-var-chalkboard-teacher: \f51c; -$fa-var-charging-station: \f5e7; -$fa-var-chart-area: \f1fe; -$fa-var-chart-bar: \f080; -$fa-var-chart-line: \f201; -$fa-var-chart-pie: \f200; -$fa-var-check: \f00c; -$fa-var-check-circle: \f058; -$fa-var-check-double: \f560; -$fa-var-check-square: \f14a; -$fa-var-cheese: \f7ef; -$fa-var-chess: \f439; -$fa-var-chess-bishop: \f43a; -$fa-var-chess-board: \f43c; -$fa-var-chess-king: \f43f; -$fa-var-chess-knight: \f441; -$fa-var-chess-pawn: \f443; -$fa-var-chess-queen: \f445; -$fa-var-chess-rook: \f447; -$fa-var-chevron-circle-down: \f13a; -$fa-var-chevron-circle-left: \f137; -$fa-var-chevron-circle-right: \f138; -$fa-var-chevron-circle-up: \f139; -$fa-var-chevron-down: \f078; -$fa-var-chevron-left: \f053; -$fa-var-chevron-right: \f054; -$fa-var-chevron-up: \f077; -$fa-var-child: \f1ae; -$fa-var-chrome: \f268; -$fa-var-chromecast: \f838; -$fa-var-church: \f51d; -$fa-var-circle: \f111; -$fa-var-circle-notch: \f1ce; -$fa-var-city: \f64f; -$fa-var-clinic-medical: \f7f2; -$fa-var-clipboard: \f328; -$fa-var-clipboard-check: \f46c; -$fa-var-clipboard-list: \f46d; -$fa-var-clock: \f017; -$fa-var-clone: \f24d; -$fa-var-closed-captioning: \f20a; -$fa-var-cloud: \f0c2; -$fa-var-cloud-download-alt: \f381; -$fa-var-cloud-meatball: \f73b; -$fa-var-cloud-moon: \f6c3; -$fa-var-cloud-moon-rain: \f73c; -$fa-var-cloud-rain: \f73d; -$fa-var-cloud-showers-heavy: \f740; -$fa-var-cloud-sun: \f6c4; -$fa-var-cloud-sun-rain: \f743; -$fa-var-cloud-upload-alt: \f382; -$fa-var-cloudscale: \f383; -$fa-var-cloudsmith: \f384; -$fa-var-cloudversify: \f385; -$fa-var-cocktail: \f561; -$fa-var-code: \f121; -$fa-var-code-branch: \f126; -$fa-var-codepen: \f1cb; -$fa-var-codiepie: \f284; -$fa-var-coffee: \f0f4; -$fa-var-cog: \f013; -$fa-var-cogs: \f085; -$fa-var-coins: \f51e; -$fa-var-columns: \f0db; -$fa-var-comment: \f075; -$fa-var-comment-alt: \f27a; -$fa-var-comment-dollar: \f651; -$fa-var-comment-dots: \f4ad; -$fa-var-comment-medical: \f7f5; -$fa-var-comment-slash: \f4b3; -$fa-var-comments: \f086; -$fa-var-comments-dollar: \f653; -$fa-var-compact-disc: \f51f; -$fa-var-compass: \f14e; -$fa-var-compress: \f066; -$fa-var-compress-alt: \f422; -$fa-var-compress-arrows-alt: \f78c; -$fa-var-concierge-bell: \f562; -$fa-var-confluence: \f78d; -$fa-var-connectdevelop: \f20e; -$fa-var-contao: \f26d; -$fa-var-cookie: \f563; -$fa-var-cookie-bite: \f564; -$fa-var-copy: \f0c5; -$fa-var-copyright: \f1f9; -$fa-var-cotton-bureau: \f89e; -$fa-var-couch: \f4b8; -$fa-var-cpanel: \f388; -$fa-var-creative-commons: \f25e; -$fa-var-creative-commons-by: \f4e7; -$fa-var-creative-commons-nc: \f4e8; -$fa-var-creative-commons-nc-eu: \f4e9; -$fa-var-creative-commons-nc-jp: \f4ea; -$fa-var-creative-commons-nd: \f4eb; -$fa-var-creative-commons-pd: \f4ec; -$fa-var-creative-commons-pd-alt: \f4ed; -$fa-var-creative-commons-remix: \f4ee; -$fa-var-creative-commons-sa: \f4ef; -$fa-var-creative-commons-sampling: \f4f0; -$fa-var-creative-commons-sampling-plus: \f4f1; -$fa-var-creative-commons-share: \f4f2; -$fa-var-creative-commons-zero: \f4f3; -$fa-var-credit-card: \f09d; -$fa-var-critical-role: \f6c9; -$fa-var-crop: \f125; -$fa-var-crop-alt: \f565; -$fa-var-cross: \f654; -$fa-var-crosshairs: \f05b; -$fa-var-crow: \f520; -$fa-var-crown: \f521; -$fa-var-crutch: \f7f7; -$fa-var-css3: \f13c; -$fa-var-css3-alt: \f38b; -$fa-var-cube: \f1b2; -$fa-var-cubes: \f1b3; -$fa-var-cut: \f0c4; -$fa-var-cuttlefish: \f38c; -$fa-var-d-and-d: \f38d; -$fa-var-d-and-d-beyond: \f6ca; -$fa-var-dailymotion: \f952; -$fa-var-dashcube: \f210; -$fa-var-database: \f1c0; -$fa-var-deaf: \f2a4; -$fa-var-deezer: \f977; -$fa-var-delicious: \f1a5; -$fa-var-democrat: \f747; -$fa-var-deploydog: \f38e; -$fa-var-deskpro: \f38f; -$fa-var-desktop: \f108; -$fa-var-dev: \f6cc; -$fa-var-deviantart: \f1bd; -$fa-var-dharmachakra: \f655; -$fa-var-dhl: \f790; -$fa-var-diagnoses: \f470; -$fa-var-diaspora: \f791; -$fa-var-dice: \f522; -$fa-var-dice-d20: \f6cf; -$fa-var-dice-d6: \f6d1; -$fa-var-dice-five: \f523; -$fa-var-dice-four: \f524; -$fa-var-dice-one: \f525; -$fa-var-dice-six: \f526; -$fa-var-dice-three: \f527; -$fa-var-dice-two: \f528; -$fa-var-digg: \f1a6; -$fa-var-digital-ocean: \f391; -$fa-var-digital-tachograph: \f566; -$fa-var-directions: \f5eb; -$fa-var-discord: \f392; -$fa-var-discourse: \f393; -$fa-var-disease: \f7fa; -$fa-var-divide: \f529; -$fa-var-dizzy: \f567; -$fa-var-dna: \f471; -$fa-var-dochub: \f394; -$fa-var-docker: \f395; -$fa-var-dog: \f6d3; -$fa-var-dollar-sign: \f155; -$fa-var-dolly: \f472; -$fa-var-dolly-flatbed: \f474; -$fa-var-donate: \f4b9; -$fa-var-door-closed: \f52a; -$fa-var-door-open: \f52b; -$fa-var-dot-circle: \f192; -$fa-var-dove: \f4ba; -$fa-var-download: \f019; -$fa-var-draft2digital: \f396; -$fa-var-drafting-compass: \f568; -$fa-var-dragon: \f6d5; -$fa-var-draw-polygon: \f5ee; -$fa-var-dribbble: \f17d; -$fa-var-dribbble-square: \f397; -$fa-var-dropbox: \f16b; -$fa-var-drum: \f569; -$fa-var-drum-steelpan: \f56a; -$fa-var-drumstick-bite: \f6d7; -$fa-var-drupal: \f1a9; -$fa-var-dumbbell: \f44b; -$fa-var-dumpster: \f793; -$fa-var-dumpster-fire: \f794; -$fa-var-dungeon: \f6d9; -$fa-var-dyalog: \f399; -$fa-var-earlybirds: \f39a; -$fa-var-ebay: \f4f4; -$fa-var-edge: \f282; -$fa-var-edge-legacy: \f978; -$fa-var-edit: \f044; -$fa-var-egg: \f7fb; -$fa-var-eject: \f052; -$fa-var-elementor: \f430; -$fa-var-ellipsis-h: \f141; -$fa-var-ellipsis-v: \f142; -$fa-var-ello: \f5f1; -$fa-var-ember: \f423; -$fa-var-empire: \f1d1; -$fa-var-envelope: \f0e0; -$fa-var-envelope-open: \f2b6; -$fa-var-envelope-open-text: \f658; -$fa-var-envelope-square: \f199; -$fa-var-envira: \f299; -$fa-var-equals: \f52c; -$fa-var-eraser: \f12d; -$fa-var-erlang: \f39d; -$fa-var-ethereum: \f42e; -$fa-var-ethernet: \f796; -$fa-var-etsy: \f2d7; -$fa-var-euro-sign: \f153; -$fa-var-evernote: \f839; -$fa-var-exchange-alt: \f362; -$fa-var-exclamation: \f12a; -$fa-var-exclamation-circle: \f06a; -$fa-var-exclamation-triangle: \f071; -$fa-var-expand: \f065; -$fa-var-expand-alt: \f424; -$fa-var-expand-arrows-alt: \f31e; -$fa-var-expeditedssl: \f23e; -$fa-var-external-link-alt: \f35d; -$fa-var-external-link-square-alt: \f360; -$fa-var-eye: \f06e; -$fa-var-eye-dropper: \f1fb; -$fa-var-eye-slash: \f070; -$fa-var-facebook: \f09a; -$fa-var-facebook-f: \f39e; -$fa-var-facebook-messenger: \f39f; -$fa-var-facebook-square: \f082; -$fa-var-fan: \f863; -$fa-var-fantasy-flight-games: \f6dc; -$fa-var-fast-backward: \f049; -$fa-var-fast-forward: \f050; -$fa-var-faucet: \f905; -$fa-var-fax: \f1ac; -$fa-var-feather: \f52d; -$fa-var-feather-alt: \f56b; -$fa-var-fedex: \f797; -$fa-var-fedora: \f798; -$fa-var-female: \f182; -$fa-var-fighter-jet: \f0fb; -$fa-var-figma: \f799; -$fa-var-file: \f15b; -$fa-var-file-alt: \f15c; -$fa-var-file-archive: \f1c6; -$fa-var-file-audio: \f1c7; -$fa-var-file-code: \f1c9; -$fa-var-file-contract: \f56c; -$fa-var-file-csv: \f6dd; -$fa-var-file-download: \f56d; -$fa-var-file-excel: \f1c3; -$fa-var-file-export: \f56e; -$fa-var-file-image: \f1c5; -$fa-var-file-import: \f56f; -$fa-var-file-invoice: \f570; -$fa-var-file-invoice-dollar: \f571; -$fa-var-file-medical: \f477; -$fa-var-file-medical-alt: \f478; -$fa-var-file-pdf: \f1c1; -$fa-var-file-powerpoint: \f1c4; -$fa-var-file-prescription: \f572; -$fa-var-file-signature: \f573; -$fa-var-file-upload: \f574; -$fa-var-file-video: \f1c8; -$fa-var-file-word: \f1c2; -$fa-var-fill: \f575; -$fa-var-fill-drip: \f576; -$fa-var-film: \f008; -$fa-var-filter: \f0b0; -$fa-var-fingerprint: \f577; -$fa-var-fire: \f06d; -$fa-var-fire-alt: \f7e4; -$fa-var-fire-extinguisher: \f134; -$fa-var-firefox: \f269; -$fa-var-firefox-browser: \f907; -$fa-var-first-aid: \f479; -$fa-var-first-order: \f2b0; -$fa-var-first-order-alt: \f50a; -$fa-var-firstdraft: \f3a1; -$fa-var-fish: \f578; -$fa-var-fist-raised: \f6de; -$fa-var-flag: \f024; -$fa-var-flag-checkered: \f11e; -$fa-var-flag-usa: \f74d; -$fa-var-flask: \f0c3; -$fa-var-flickr: \f16e; -$fa-var-flipboard: \f44d; -$fa-var-flushed: \f579; -$fa-var-fly: \f417; -$fa-var-folder: \f07b; -$fa-var-folder-minus: \f65d; -$fa-var-folder-open: \f07c; -$fa-var-folder-plus: \f65e; -$fa-var-font: \f031; -$fa-var-font-awesome: \f2b4; -$fa-var-font-awesome-alt: \f35c; -$fa-var-font-awesome-flag: \f425; -$fa-var-font-awesome-logo-full: \f4e6; -$fa-var-fonticons: \f280; -$fa-var-fonticons-fi: \f3a2; -$fa-var-football-ball: \f44e; -$fa-var-fort-awesome: \f286; -$fa-var-fort-awesome-alt: \f3a3; -$fa-var-forumbee: \f211; -$fa-var-forward: \f04e; -$fa-var-foursquare: \f180; -$fa-var-free-code-camp: \f2c5; -$fa-var-freebsd: \f3a4; -$fa-var-frog: \f52e; -$fa-var-frown: \f119; -$fa-var-frown-open: \f57a; -$fa-var-fulcrum: \f50b; -$fa-var-funnel-dollar: \f662; -$fa-var-futbol: \f1e3; -$fa-var-galactic-republic: \f50c; -$fa-var-galactic-senate: \f50d; -$fa-var-gamepad: \f11b; -$fa-var-gas-pump: \f52f; -$fa-var-gavel: \f0e3; -$fa-var-gem: \f3a5; -$fa-var-genderless: \f22d; -$fa-var-get-pocket: \f265; -$fa-var-gg: \f260; -$fa-var-gg-circle: \f261; -$fa-var-ghost: \f6e2; -$fa-var-gift: \f06b; -$fa-var-gifts: \f79c; -$fa-var-git: \f1d3; -$fa-var-git-alt: \f841; -$fa-var-git-square: \f1d2; -$fa-var-github: \f09b; -$fa-var-github-alt: \f113; -$fa-var-github-square: \f092; -$fa-var-gitkraken: \f3a6; -$fa-var-gitlab: \f296; -$fa-var-gitter: \f426; -$fa-var-glass-cheers: \f79f; -$fa-var-glass-martini: \f000; -$fa-var-glass-martini-alt: \f57b; -$fa-var-glass-whiskey: \f7a0; -$fa-var-glasses: \f530; -$fa-var-glide: \f2a5; -$fa-var-glide-g: \f2a6; -$fa-var-globe: \f0ac; -$fa-var-globe-africa: \f57c; -$fa-var-globe-americas: \f57d; -$fa-var-globe-asia: \f57e; -$fa-var-globe-europe: \f7a2; -$fa-var-gofore: \f3a7; -$fa-var-golf-ball: \f450; -$fa-var-goodreads: \f3a8; -$fa-var-goodreads-g: \f3a9; -$fa-var-google: \f1a0; -$fa-var-google-drive: \f3aa; -$fa-var-google-pay: \f979; -$fa-var-google-play: \f3ab; -$fa-var-google-plus: \f2b3; -$fa-var-google-plus-g: \f0d5; -$fa-var-google-plus-square: \f0d4; -$fa-var-google-wallet: \f1ee; -$fa-var-gopuram: \f664; -$fa-var-graduation-cap: \f19d; -$fa-var-gratipay: \f184; -$fa-var-grav: \f2d6; -$fa-var-greater-than: \f531; -$fa-var-greater-than-equal: \f532; -$fa-var-grimace: \f57f; -$fa-var-grin: \f580; -$fa-var-grin-alt: \f581; -$fa-var-grin-beam: \f582; -$fa-var-grin-beam-sweat: \f583; -$fa-var-grin-hearts: \f584; -$fa-var-grin-squint: \f585; -$fa-var-grin-squint-tears: \f586; -$fa-var-grin-stars: \f587; -$fa-var-grin-tears: \f588; -$fa-var-grin-tongue: \f589; -$fa-var-grin-tongue-squint: \f58a; -$fa-var-grin-tongue-wink: \f58b; -$fa-var-grin-wink: \f58c; -$fa-var-grip-horizontal: \f58d; -$fa-var-grip-lines: \f7a4; -$fa-var-grip-lines-vertical: \f7a5; -$fa-var-grip-vertical: \f58e; -$fa-var-gripfire: \f3ac; -$fa-var-grunt: \f3ad; -$fa-var-guitar: \f7a6; -$fa-var-gulp: \f3ae; -$fa-var-h-square: \f0fd; -$fa-var-hacker-news: \f1d4; -$fa-var-hacker-news-square: \f3af; -$fa-var-hackerrank: \f5f7; -$fa-var-hamburger: \f805; -$fa-var-hammer: \f6e3; -$fa-var-hamsa: \f665; -$fa-var-hand-holding: \f4bd; -$fa-var-hand-holding-heart: \f4be; -$fa-var-hand-holding-medical: \f95c; -$fa-var-hand-holding-usd: \f4c0; -$fa-var-hand-holding-water: \f4c1; -$fa-var-hand-lizard: \f258; -$fa-var-hand-middle-finger: \f806; -$fa-var-hand-paper: \f256; -$fa-var-hand-peace: \f25b; -$fa-var-hand-point-down: \f0a7; -$fa-var-hand-point-left: \f0a5; -$fa-var-hand-point-right: \f0a4; -$fa-var-hand-point-up: \f0a6; -$fa-var-hand-pointer: \f25a; -$fa-var-hand-rock: \f255; -$fa-var-hand-scissors: \f257; -$fa-var-hand-sparkles: \f95d; -$fa-var-hand-spock: \f259; -$fa-var-hands: \f4c2; -$fa-var-hands-helping: \f4c4; -$fa-var-hands-wash: \f95e; -$fa-var-handshake: \f2b5; -$fa-var-handshake-alt-slash: \f95f; -$fa-var-handshake-slash: \f960; -$fa-var-hanukiah: \f6e6; -$fa-var-hard-hat: \f807; -$fa-var-hashtag: \f292; -$fa-var-hat-cowboy: \f8c0; -$fa-var-hat-cowboy-side: \f8c1; -$fa-var-hat-wizard: \f6e8; -$fa-var-hdd: \f0a0; -$fa-var-head-side-cough: \f961; -$fa-var-head-side-cough-slash: \f962; -$fa-var-head-side-mask: \f963; -$fa-var-head-side-virus: \f964; -$fa-var-heading: \f1dc; -$fa-var-headphones: \f025; -$fa-var-headphones-alt: \f58f; -$fa-var-headset: \f590; -$fa-var-heart: \f004; -$fa-var-heart-broken: \f7a9; -$fa-var-heartbeat: \f21e; -$fa-var-helicopter: \f533; -$fa-var-highlighter: \f591; -$fa-var-hiking: \f6ec; -$fa-var-hippo: \f6ed; -$fa-var-hips: \f452; -$fa-var-hire-a-helper: \f3b0; -$fa-var-history: \f1da; -$fa-var-hockey-puck: \f453; -$fa-var-holly-berry: \f7aa; -$fa-var-home: \f015; -$fa-var-hooli: \f427; -$fa-var-hornbill: \f592; -$fa-var-horse: \f6f0; -$fa-var-horse-head: \f7ab; -$fa-var-hospital: \f0f8; -$fa-var-hospital-alt: \f47d; -$fa-var-hospital-symbol: \f47e; -$fa-var-hospital-user: \f80d; -$fa-var-hot-tub: \f593; -$fa-var-hotdog: \f80f; -$fa-var-hotel: \f594; -$fa-var-hotjar: \f3b1; -$fa-var-hourglass: \f254; -$fa-var-hourglass-end: \f253; -$fa-var-hourglass-half: \f252; -$fa-var-hourglass-start: \f251; -$fa-var-house-damage: \f6f1; -$fa-var-house-user: \f965; -$fa-var-houzz: \f27c; -$fa-var-hryvnia: \f6f2; -$fa-var-html5: \f13b; -$fa-var-hubspot: \f3b2; -$fa-var-i-cursor: \f246; -$fa-var-ice-cream: \f810; -$fa-var-icicles: \f7ad; -$fa-var-icons: \f86d; -$fa-var-id-badge: \f2c1; -$fa-var-id-card: \f2c2; -$fa-var-id-card-alt: \f47f; -$fa-var-ideal: \f913; -$fa-var-igloo: \f7ae; -$fa-var-image: \f03e; -$fa-var-images: \f302; -$fa-var-imdb: \f2d8; -$fa-var-inbox: \f01c; -$fa-var-indent: \f03c; -$fa-var-industry: \f275; -$fa-var-infinity: \f534; -$fa-var-info: \f129; -$fa-var-info-circle: \f05a; -$fa-var-instagram: \f16d; -$fa-var-instagram-square: \f955; -$fa-var-intercom: \f7af; -$fa-var-internet-explorer: \f26b; -$fa-var-invision: \f7b0; -$fa-var-ioxhost: \f208; -$fa-var-italic: \f033; -$fa-var-itch-io: \f83a; -$fa-var-itunes: \f3b4; -$fa-var-itunes-note: \f3b5; -$fa-var-java: \f4e4; -$fa-var-jedi: \f669; -$fa-var-jedi-order: \f50e; -$fa-var-jenkins: \f3b6; -$fa-var-jira: \f7b1; -$fa-var-joget: \f3b7; -$fa-var-joint: \f595; -$fa-var-joomla: \f1aa; -$fa-var-journal-whills: \f66a; -$fa-var-js: \f3b8; -$fa-var-js-square: \f3b9; -$fa-var-jsfiddle: \f1cc; -$fa-var-kaaba: \f66b; -$fa-var-kaggle: \f5fa; -$fa-var-key: \f084; -$fa-var-keybase: \f4f5; -$fa-var-keyboard: \f11c; -$fa-var-keycdn: \f3ba; -$fa-var-khanda: \f66d; -$fa-var-kickstarter: \f3bb; -$fa-var-kickstarter-k: \f3bc; -$fa-var-kiss: \f596; -$fa-var-kiss-beam: \f597; -$fa-var-kiss-wink-heart: \f598; -$fa-var-kiwi-bird: \f535; -$fa-var-korvue: \f42f; -$fa-var-landmark: \f66f; -$fa-var-language: \f1ab; -$fa-var-laptop: \f109; -$fa-var-laptop-code: \f5fc; -$fa-var-laptop-house: \f966; -$fa-var-laptop-medical: \f812; -$fa-var-laravel: \f3bd; -$fa-var-lastfm: \f202; -$fa-var-lastfm-square: \f203; -$fa-var-laugh: \f599; -$fa-var-laugh-beam: \f59a; -$fa-var-laugh-squint: \f59b; -$fa-var-laugh-wink: \f59c; -$fa-var-layer-group: \f5fd; -$fa-var-leaf: \f06c; -$fa-var-leanpub: \f212; -$fa-var-lemon: \f094; -$fa-var-less: \f41d; -$fa-var-less-than: \f536; -$fa-var-less-than-equal: \f537; -$fa-var-level-down-alt: \f3be; -$fa-var-level-up-alt: \f3bf; -$fa-var-life-ring: \f1cd; -$fa-var-lightbulb: \f0eb; -$fa-var-line: \f3c0; -$fa-var-link: \f0c1; -$fa-var-linkedin: \f08c; -$fa-var-linkedin-in: \f0e1; -$fa-var-linode: \f2b8; -$fa-var-linux: \f17c; -$fa-var-lira-sign: \f195; -$fa-var-list: \f03a; -$fa-var-list-alt: \f022; -$fa-var-list-ol: \f0cb; -$fa-var-list-ul: \f0ca; -$fa-var-location-arrow: \f124; -$fa-var-lock: \f023; -$fa-var-lock-open: \f3c1; -$fa-var-long-arrow-alt-down: \f309; -$fa-var-long-arrow-alt-left: \f30a; -$fa-var-long-arrow-alt-right: \f30b; -$fa-var-long-arrow-alt-up: \f30c; -$fa-var-low-vision: \f2a8; -$fa-var-luggage-cart: \f59d; -$fa-var-lungs: \f604; -$fa-var-lungs-virus: \f967; -$fa-var-lyft: \f3c3; -$fa-var-magento: \f3c4; -$fa-var-magic: \f0d0; -$fa-var-magnet: \f076; -$fa-var-mail-bulk: \f674; -$fa-var-mailchimp: \f59e; -$fa-var-male: \f183; -$fa-var-mandalorian: \f50f; -$fa-var-map: \f279; -$fa-var-map-marked: \f59f; -$fa-var-map-marked-alt: \f5a0; -$fa-var-map-marker: \f041; -$fa-var-map-marker-alt: \f3c5; -$fa-var-map-pin: \f276; -$fa-var-map-signs: \f277; -$fa-var-markdown: \f60f; -$fa-var-marker: \f5a1; -$fa-var-mars: \f222; -$fa-var-mars-double: \f227; -$fa-var-mars-stroke: \f229; -$fa-var-mars-stroke-h: \f22b; -$fa-var-mars-stroke-v: \f22a; -$fa-var-mask: \f6fa; -$fa-var-mastodon: \f4f6; -$fa-var-maxcdn: \f136; -$fa-var-mdb: \f8ca; -$fa-var-medal: \f5a2; -$fa-var-medapps: \f3c6; -$fa-var-medium: \f23a; -$fa-var-medium-m: \f3c7; -$fa-var-medkit: \f0fa; -$fa-var-medrt: \f3c8; -$fa-var-meetup: \f2e0; -$fa-var-megaport: \f5a3; -$fa-var-meh: \f11a; -$fa-var-meh-blank: \f5a4; -$fa-var-meh-rolling-eyes: \f5a5; -$fa-var-memory: \f538; -$fa-var-mendeley: \f7b3; -$fa-var-menorah: \f676; -$fa-var-mercury: \f223; -$fa-var-meteor: \f753; -$fa-var-microblog: \f91a; -$fa-var-microchip: \f2db; -$fa-var-microphone: \f130; -$fa-var-microphone-alt: \f3c9; -$fa-var-microphone-alt-slash: \f539; -$fa-var-microphone-slash: \f131; -$fa-var-microscope: \f610; -$fa-var-microsoft: \f3ca; -$fa-var-minus: \f068; -$fa-var-minus-circle: \f056; -$fa-var-minus-square: \f146; -$fa-var-mitten: \f7b5; -$fa-var-mix: \f3cb; -$fa-var-mixcloud: \f289; -$fa-var-mixer: \f956; -$fa-var-mizuni: \f3cc; -$fa-var-mobile: \f10b; -$fa-var-mobile-alt: \f3cd; -$fa-var-modx: \f285; -$fa-var-monero: \f3d0; -$fa-var-money-bill: \f0d6; -$fa-var-money-bill-alt: \f3d1; -$fa-var-money-bill-wave: \f53a; -$fa-var-money-bill-wave-alt: \f53b; -$fa-var-money-check: \f53c; -$fa-var-money-check-alt: \f53d; -$fa-var-monument: \f5a6; -$fa-var-moon: \f186; -$fa-var-mortar-pestle: \f5a7; -$fa-var-mosque: \f678; -$fa-var-motorcycle: \f21c; -$fa-var-mountain: \f6fc; -$fa-var-mouse: \f8cc; -$fa-var-mouse-pointer: \f245; -$fa-var-mug-hot: \f7b6; -$fa-var-music: \f001; -$fa-var-napster: \f3d2; -$fa-var-neos: \f612; -$fa-var-network-wired: \f6ff; -$fa-var-neuter: \f22c; -$fa-var-newspaper: \f1ea; -$fa-var-nimblr: \f5a8; -$fa-var-node: \f419; -$fa-var-node-js: \f3d3; -$fa-var-not-equal: \f53e; -$fa-var-notes-medical: \f481; -$fa-var-npm: \f3d4; -$fa-var-ns8: \f3d5; -$fa-var-nutritionix: \f3d6; -$fa-var-object-group: \f247; -$fa-var-object-ungroup: \f248; -$fa-var-odnoklassniki: \f263; -$fa-var-odnoklassniki-square: \f264; -$fa-var-oil-can: \f613; -$fa-var-old-republic: \f510; -$fa-var-om: \f679; -$fa-var-opencart: \f23d; -$fa-var-openid: \f19b; -$fa-var-opera: \f26a; -$fa-var-optin-monster: \f23c; -$fa-var-orcid: \f8d2; -$fa-var-osi: \f41a; -$fa-var-otter: \f700; -$fa-var-outdent: \f03b; -$fa-var-page4: \f3d7; -$fa-var-pagelines: \f18c; -$fa-var-pager: \f815; -$fa-var-paint-brush: \f1fc; -$fa-var-paint-roller: \f5aa; -$fa-var-palette: \f53f; -$fa-var-palfed: \f3d8; -$fa-var-pallet: \f482; -$fa-var-paper-plane: \f1d8; -$fa-var-paperclip: \f0c6; -$fa-var-parachute-box: \f4cd; -$fa-var-paragraph: \f1dd; -$fa-var-parking: \f540; -$fa-var-passport: \f5ab; -$fa-var-pastafarianism: \f67b; -$fa-var-paste: \f0ea; -$fa-var-patreon: \f3d9; -$fa-var-pause: \f04c; -$fa-var-pause-circle: \f28b; -$fa-var-paw: \f1b0; -$fa-var-paypal: \f1ed; -$fa-var-peace: \f67c; -$fa-var-pen: \f304; -$fa-var-pen-alt: \f305; -$fa-var-pen-fancy: \f5ac; -$fa-var-pen-nib: \f5ad; -$fa-var-pen-square: \f14b; -$fa-var-pencil-alt: \f303; -$fa-var-pencil-ruler: \f5ae; -$fa-var-penny-arcade: \f704; -$fa-var-people-arrows: \f968; -$fa-var-people-carry: \f4ce; -$fa-var-pepper-hot: \f816; -$fa-var-percent: \f295; -$fa-var-percentage: \f541; -$fa-var-periscope: \f3da; -$fa-var-person-booth: \f756; -$fa-var-phabricator: \f3db; -$fa-var-phoenix-framework: \f3dc; -$fa-var-phoenix-squadron: \f511; -$fa-var-phone: \f095; -$fa-var-phone-alt: \f879; -$fa-var-phone-slash: \f3dd; -$fa-var-phone-square: \f098; -$fa-var-phone-square-alt: \f87b; -$fa-var-phone-volume: \f2a0; -$fa-var-photo-video: \f87c; -$fa-var-php: \f457; -$fa-var-pied-piper: \f2ae; -$fa-var-pied-piper-alt: \f1a8; -$fa-var-pied-piper-hat: \f4e5; -$fa-var-pied-piper-pp: \f1a7; -$fa-var-pied-piper-square: \f91e; -$fa-var-piggy-bank: \f4d3; -$fa-var-pills: \f484; -$fa-var-pinterest: \f0d2; -$fa-var-pinterest-p: \f231; -$fa-var-pinterest-square: \f0d3; -$fa-var-pizza-slice: \f818; -$fa-var-place-of-worship: \f67f; -$fa-var-plane: \f072; -$fa-var-plane-arrival: \f5af; -$fa-var-plane-departure: \f5b0; -$fa-var-plane-slash: \f969; -$fa-var-play: \f04b; -$fa-var-play-circle: \f144; -$fa-var-playstation: \f3df; -$fa-var-plug: \f1e6; -$fa-var-plus: \f067; -$fa-var-plus-circle: \f055; -$fa-var-plus-square: \f0fe; -$fa-var-podcast: \f2ce; -$fa-var-poll: \f681; -$fa-var-poll-h: \f682; -$fa-var-poo: \f2fe; -$fa-var-poo-storm: \f75a; -$fa-var-poop: \f619; -$fa-var-portrait: \f3e0; -$fa-var-pound-sign: \f154; -$fa-var-power-off: \f011; -$fa-var-pray: \f683; -$fa-var-praying-hands: \f684; -$fa-var-prescription: \f5b1; -$fa-var-prescription-bottle: \f485; -$fa-var-prescription-bottle-alt: \f486; -$fa-var-print: \f02f; -$fa-var-procedures: \f487; -$fa-var-product-hunt: \f288; -$fa-var-project-diagram: \f542; -$fa-var-pump-medical: \f96a; -$fa-var-pump-soap: \f96b; -$fa-var-pushed: \f3e1; -$fa-var-puzzle-piece: \f12e; -$fa-var-python: \f3e2; -$fa-var-qq: \f1d6; -$fa-var-qrcode: \f029; -$fa-var-question: \f128; -$fa-var-question-circle: \f059; -$fa-var-quidditch: \f458; -$fa-var-quinscape: \f459; -$fa-var-quora: \f2c4; -$fa-var-quote-left: \f10d; -$fa-var-quote-right: \f10e; -$fa-var-quran: \f687; -$fa-var-r-project: \f4f7; -$fa-var-radiation: \f7b9; -$fa-var-radiation-alt: \f7ba; -$fa-var-rainbow: \f75b; -$fa-var-random: \f074; -$fa-var-raspberry-pi: \f7bb; -$fa-var-ravelry: \f2d9; -$fa-var-react: \f41b; -$fa-var-reacteurope: \f75d; -$fa-var-readme: \f4d5; -$fa-var-rebel: \f1d0; -$fa-var-receipt: \f543; -$fa-var-record-vinyl: \f8d9; -$fa-var-recycle: \f1b8; -$fa-var-red-river: \f3e3; -$fa-var-reddit: \f1a1; -$fa-var-reddit-alien: \f281; -$fa-var-reddit-square: \f1a2; -$fa-var-redhat: \f7bc; -$fa-var-redo: \f01e; -$fa-var-redo-alt: \f2f9; -$fa-var-registered: \f25d; -$fa-var-remove-format: \f87d; -$fa-var-renren: \f18b; -$fa-var-reply: \f3e5; -$fa-var-reply-all: \f122; -$fa-var-replyd: \f3e6; -$fa-var-republican: \f75e; -$fa-var-researchgate: \f4f8; -$fa-var-resolving: \f3e7; -$fa-var-restroom: \f7bd; -$fa-var-retweet: \f079; -$fa-var-rev: \f5b2; -$fa-var-ribbon: \f4d6; -$fa-var-ring: \f70b; -$fa-var-road: \f018; -$fa-var-robot: \f544; -$fa-var-rocket: \f135; -$fa-var-rocketchat: \f3e8; -$fa-var-rockrms: \f3e9; -$fa-var-route: \f4d7; -$fa-var-rss: \f09e; -$fa-var-rss-square: \f143; -$fa-var-ruble-sign: \f158; -$fa-var-ruler: \f545; -$fa-var-ruler-combined: \f546; -$fa-var-ruler-horizontal: \f547; -$fa-var-ruler-vertical: \f548; -$fa-var-running: \f70c; -$fa-var-rupee-sign: \f156; -$fa-var-rust: \f97a; -$fa-var-sad-cry: \f5b3; -$fa-var-sad-tear: \f5b4; -$fa-var-safari: \f267; -$fa-var-salesforce: \f83b; -$fa-var-sass: \f41e; -$fa-var-satellite: \f7bf; -$fa-var-satellite-dish: \f7c0; -$fa-var-save: \f0c7; -$fa-var-schlix: \f3ea; -$fa-var-school: \f549; -$fa-var-screwdriver: \f54a; -$fa-var-scribd: \f28a; -$fa-var-scroll: \f70e; -$fa-var-sd-card: \f7c2; -$fa-var-search: \f002; -$fa-var-search-dollar: \f688; -$fa-var-search-location: \f689; -$fa-var-search-minus: \f010; -$fa-var-search-plus: \f00e; -$fa-var-searchengin: \f3eb; -$fa-var-seedling: \f4d8; -$fa-var-sellcast: \f2da; -$fa-var-sellsy: \f213; -$fa-var-server: \f233; -$fa-var-servicestack: \f3ec; -$fa-var-shapes: \f61f; -$fa-var-share: \f064; -$fa-var-share-alt: \f1e0; -$fa-var-share-alt-square: \f1e1; -$fa-var-share-square: \f14d; -$fa-var-shekel-sign: \f20b; -$fa-var-shield-alt: \f3ed; -$fa-var-shield-virus: \f96c; -$fa-var-ship: \f21a; -$fa-var-shipping-fast: \f48b; -$fa-var-shirtsinbulk: \f214; -$fa-var-shoe-prints: \f54b; -$fa-var-shopify: \f957; -$fa-var-shopping-bag: \f290; -$fa-var-shopping-basket: \f291; -$fa-var-shopping-cart: \f07a; -$fa-var-shopware: \f5b5; -$fa-var-shower: \f2cc; -$fa-var-shuttle-van: \f5b6; -$fa-var-sign: \f4d9; -$fa-var-sign-in-alt: \f2f6; -$fa-var-sign-language: \f2a7; -$fa-var-sign-out-alt: \f2f5; -$fa-var-signal: \f012; -$fa-var-signature: \f5b7; -$fa-var-sim-card: \f7c4; -$fa-var-simplybuilt: \f215; -$fa-var-sink: \f96d; -$fa-var-sistrix: \f3ee; -$fa-var-sitemap: \f0e8; -$fa-var-sith: \f512; -$fa-var-skating: \f7c5; -$fa-var-sketch: \f7c6; -$fa-var-skiing: \f7c9; -$fa-var-skiing-nordic: \f7ca; -$fa-var-skull: \f54c; -$fa-var-skull-crossbones: \f714; -$fa-var-skyatlas: \f216; -$fa-var-skype: \f17e; -$fa-var-slack: \f198; -$fa-var-slack-hash: \f3ef; -$fa-var-slash: \f715; -$fa-var-sleigh: \f7cc; -$fa-var-sliders-h: \f1de; -$fa-var-slideshare: \f1e7; -$fa-var-smile: \f118; -$fa-var-smile-beam: \f5b8; -$fa-var-smile-wink: \f4da; -$fa-var-smog: \f75f; -$fa-var-smoking: \f48d; -$fa-var-smoking-ban: \f54d; -$fa-var-sms: \f7cd; -$fa-var-snapchat: \f2ab; -$fa-var-snapchat-ghost: \f2ac; -$fa-var-snapchat-square: \f2ad; -$fa-var-snowboarding: \f7ce; -$fa-var-snowflake: \f2dc; -$fa-var-snowman: \f7d0; -$fa-var-snowplow: \f7d2; -$fa-var-soap: \f96e; -$fa-var-socks: \f696; -$fa-var-solar-panel: \f5ba; -$fa-var-sort: \f0dc; -$fa-var-sort-alpha-down: \f15d; -$fa-var-sort-alpha-down-alt: \f881; -$fa-var-sort-alpha-up: \f15e; -$fa-var-sort-alpha-up-alt: \f882; -$fa-var-sort-amount-down: \f160; -$fa-var-sort-amount-down-alt: \f884; -$fa-var-sort-amount-up: \f161; -$fa-var-sort-amount-up-alt: \f885; -$fa-var-sort-down: \f0dd; -$fa-var-sort-numeric-down: \f162; -$fa-var-sort-numeric-down-alt: \f886; -$fa-var-sort-numeric-up: \f163; -$fa-var-sort-numeric-up-alt: \f887; -$fa-var-sort-up: \f0de; -$fa-var-soundcloud: \f1be; -$fa-var-sourcetree: \f7d3; -$fa-var-spa: \f5bb; -$fa-var-space-shuttle: \f197; -$fa-var-speakap: \f3f3; -$fa-var-speaker-deck: \f83c; -$fa-var-spell-check: \f891; -$fa-var-spider: \f717; -$fa-var-spinner: \f110; -$fa-var-splotch: \f5bc; -$fa-var-spotify: \f1bc; -$fa-var-spray-can: \f5bd; -$fa-var-square: \f0c8; -$fa-var-square-full: \f45c; -$fa-var-square-root-alt: \f698; -$fa-var-squarespace: \f5be; -$fa-var-stack-exchange: \f18d; -$fa-var-stack-overflow: \f16c; -$fa-var-stackpath: \f842; -$fa-var-stamp: \f5bf; -$fa-var-star: \f005; -$fa-var-star-and-crescent: \f699; -$fa-var-star-half: \f089; -$fa-var-star-half-alt: \f5c0; -$fa-var-star-of-david: \f69a; -$fa-var-star-of-life: \f621; -$fa-var-staylinked: \f3f5; -$fa-var-steam: \f1b6; -$fa-var-steam-square: \f1b7; -$fa-var-steam-symbol: \f3f6; -$fa-var-step-backward: \f048; -$fa-var-step-forward: \f051; -$fa-var-stethoscope: \f0f1; -$fa-var-sticker-mule: \f3f7; -$fa-var-sticky-note: \f249; -$fa-var-stop: \f04d; -$fa-var-stop-circle: \f28d; -$fa-var-stopwatch: \f2f2; -$fa-var-stopwatch-20: \f96f; -$fa-var-store: \f54e; -$fa-var-store-alt: \f54f; -$fa-var-store-alt-slash: \f970; -$fa-var-store-slash: \f971; -$fa-var-strava: \f428; -$fa-var-stream: \f550; -$fa-var-street-view: \f21d; -$fa-var-strikethrough: \f0cc; -$fa-var-stripe: \f429; -$fa-var-stripe-s: \f42a; -$fa-var-stroopwafel: \f551; -$fa-var-studiovinari: \f3f8; -$fa-var-stumbleupon: \f1a4; -$fa-var-stumbleupon-circle: \f1a3; -$fa-var-subscript: \f12c; -$fa-var-subway: \f239; -$fa-var-suitcase: \f0f2; -$fa-var-suitcase-rolling: \f5c1; -$fa-var-sun: \f185; -$fa-var-superpowers: \f2dd; -$fa-var-superscript: \f12b; -$fa-var-supple: \f3f9; -$fa-var-surprise: \f5c2; -$fa-var-suse: \f7d6; -$fa-var-swatchbook: \f5c3; -$fa-var-swift: \f8e1; -$fa-var-swimmer: \f5c4; -$fa-var-swimming-pool: \f5c5; -$fa-var-symfony: \f83d; -$fa-var-synagogue: \f69b; -$fa-var-sync: \f021; -$fa-var-sync-alt: \f2f1; -$fa-var-syringe: \f48e; -$fa-var-table: \f0ce; -$fa-var-table-tennis: \f45d; -$fa-var-tablet: \f10a; -$fa-var-tablet-alt: \f3fa; -$fa-var-tablets: \f490; -$fa-var-tachometer-alt: \f3fd; -$fa-var-tag: \f02b; -$fa-var-tags: \f02c; -$fa-var-tape: \f4db; -$fa-var-tasks: \f0ae; -$fa-var-taxi: \f1ba; -$fa-var-teamspeak: \f4f9; -$fa-var-teeth: \f62e; -$fa-var-teeth-open: \f62f; -$fa-var-telegram: \f2c6; -$fa-var-telegram-plane: \f3fe; -$fa-var-temperature-high: \f769; -$fa-var-temperature-low: \f76b; -$fa-var-tencent-weibo: \f1d5; -$fa-var-tenge: \f7d7; -$fa-var-terminal: \f120; -$fa-var-text-height: \f034; -$fa-var-text-width: \f035; -$fa-var-th: \f00a; -$fa-var-th-large: \f009; -$fa-var-th-list: \f00b; -$fa-var-the-red-yeti: \f69d; -$fa-var-theater-masks: \f630; -$fa-var-themeco: \f5c6; -$fa-var-themeisle: \f2b2; -$fa-var-thermometer: \f491; -$fa-var-thermometer-empty: \f2cb; -$fa-var-thermometer-full: \f2c7; -$fa-var-thermometer-half: \f2c9; -$fa-var-thermometer-quarter: \f2ca; -$fa-var-thermometer-three-quarters: \f2c8; -$fa-var-think-peaks: \f731; -$fa-var-thumbs-down: \f165; -$fa-var-thumbs-up: \f164; -$fa-var-thumbtack: \f08d; -$fa-var-ticket-alt: \f3ff; -$fa-var-tiktok: \f97b; -$fa-var-times: \f00d; -$fa-var-times-circle: \f057; -$fa-var-tint: \f043; -$fa-var-tint-slash: \f5c7; -$fa-var-tired: \f5c8; -$fa-var-toggle-off: \f204; -$fa-var-toggle-on: \f205; -$fa-var-toilet: \f7d8; -$fa-var-toilet-paper: \f71e; -$fa-var-toilet-paper-slash: \f972; -$fa-var-toolbox: \f552; -$fa-var-tools: \f7d9; -$fa-var-tooth: \f5c9; -$fa-var-torah: \f6a0; -$fa-var-torii-gate: \f6a1; -$fa-var-tractor: \f722; -$fa-var-trade-federation: \f513; -$fa-var-trademark: \f25c; -$fa-var-traffic-light: \f637; -$fa-var-trailer: \f941; -$fa-var-train: \f238; -$fa-var-tram: \f7da; -$fa-var-transgender: \f224; -$fa-var-transgender-alt: \f225; -$fa-var-trash: \f1f8; -$fa-var-trash-alt: \f2ed; -$fa-var-trash-restore: \f829; -$fa-var-trash-restore-alt: \f82a; -$fa-var-tree: \f1bb; -$fa-var-trello: \f181; -$fa-var-tripadvisor: \f262; -$fa-var-trophy: \f091; -$fa-var-truck: \f0d1; -$fa-var-truck-loading: \f4de; -$fa-var-truck-monster: \f63b; -$fa-var-truck-moving: \f4df; -$fa-var-truck-pickup: \f63c; -$fa-var-tshirt: \f553; -$fa-var-tty: \f1e4; -$fa-var-tumblr: \f173; -$fa-var-tumblr-square: \f174; -$fa-var-tv: \f26c; -$fa-var-twitch: \f1e8; -$fa-var-twitter: \f099; -$fa-var-twitter-square: \f081; -$fa-var-typo3: \f42b; -$fa-var-uber: \f402; -$fa-var-ubuntu: \f7df; -$fa-var-uikit: \f403; -$fa-var-umbraco: \f8e8; -$fa-var-umbrella: \f0e9; -$fa-var-umbrella-beach: \f5ca; -$fa-var-underline: \f0cd; -$fa-var-undo: \f0e2; -$fa-var-undo-alt: \f2ea; -$fa-var-uniregistry: \f404; -$fa-var-unity: \f949; -$fa-var-universal-access: \f29a; -$fa-var-university: \f19c; -$fa-var-unlink: \f127; -$fa-var-unlock: \f09c; -$fa-var-unlock-alt: \f13e; -$fa-var-unsplash: \f97c; -$fa-var-untappd: \f405; -$fa-var-upload: \f093; -$fa-var-ups: \f7e0; -$fa-var-usb: \f287; -$fa-var-user: \f007; -$fa-var-user-alt: \f406; -$fa-var-user-alt-slash: \f4fa; -$fa-var-user-astronaut: \f4fb; -$fa-var-user-check: \f4fc; -$fa-var-user-circle: \f2bd; -$fa-var-user-clock: \f4fd; -$fa-var-user-cog: \f4fe; -$fa-var-user-edit: \f4ff; -$fa-var-user-friends: \f500; -$fa-var-user-graduate: \f501; -$fa-var-user-injured: \f728; -$fa-var-user-lock: \f502; -$fa-var-user-md: \f0f0; -$fa-var-user-minus: \f503; -$fa-var-user-ninja: \f504; -$fa-var-user-nurse: \f82f; -$fa-var-user-plus: \f234; -$fa-var-user-secret: \f21b; -$fa-var-user-shield: \f505; -$fa-var-user-slash: \f506; -$fa-var-user-tag: \f507; -$fa-var-user-tie: \f508; -$fa-var-user-times: \f235; -$fa-var-users: \f0c0; -$fa-var-users-cog: \f509; -$fa-var-users-slash: \f973; -$fa-var-usps: \f7e1; -$fa-var-ussunnah: \f407; -$fa-var-utensil-spoon: \f2e5; -$fa-var-utensils: \f2e7; -$fa-var-vaadin: \f408; -$fa-var-vector-square: \f5cb; -$fa-var-venus: \f221; -$fa-var-venus-double: \f226; -$fa-var-venus-mars: \f228; -$fa-var-viacoin: \f237; -$fa-var-viadeo: \f2a9; -$fa-var-viadeo-square: \f2aa; -$fa-var-vial: \f492; -$fa-var-vials: \f493; -$fa-var-viber: \f409; -$fa-var-video: \f03d; -$fa-var-video-slash: \f4e2; -$fa-var-vihara: \f6a7; -$fa-var-vimeo: \f40a; -$fa-var-vimeo-square: \f194; -$fa-var-vimeo-v: \f27d; -$fa-var-vine: \f1ca; -$fa-var-virus: \f974; -$fa-var-virus-slash: \f975; -$fa-var-viruses: \f976; -$fa-var-vk: \f189; -$fa-var-vnv: \f40b; -$fa-var-voicemail: \f897; -$fa-var-volleyball-ball: \f45f; -$fa-var-volume-down: \f027; -$fa-var-volume-mute: \f6a9; -$fa-var-volume-off: \f026; -$fa-var-volume-up: \f028; -$fa-var-vote-yea: \f772; -$fa-var-vr-cardboard: \f729; -$fa-var-vuejs: \f41f; -$fa-var-walking: \f554; -$fa-var-wallet: \f555; -$fa-var-warehouse: \f494; -$fa-var-water: \f773; -$fa-var-wave-square: \f83e; -$fa-var-waze: \f83f; -$fa-var-weebly: \f5cc; -$fa-var-weibo: \f18a; -$fa-var-weight: \f496; -$fa-var-weight-hanging: \f5cd; -$fa-var-weixin: \f1d7; -$fa-var-whatsapp: \f232; -$fa-var-whatsapp-square: \f40c; -$fa-var-wheelchair: \f193; -$fa-var-whmcs: \f40d; -$fa-var-wifi: \f1eb; -$fa-var-wikipedia-w: \f266; -$fa-var-wind: \f72e; -$fa-var-window-close: \f410; -$fa-var-window-maximize: \f2d0; -$fa-var-window-minimize: \f2d1; -$fa-var-window-restore: \f2d2; -$fa-var-windows: \f17a; -$fa-var-wine-bottle: \f72f; -$fa-var-wine-glass: \f4e3; -$fa-var-wine-glass-alt: \f5ce; -$fa-var-wix: \f5cf; -$fa-var-wizards-of-the-coast: \f730; -$fa-var-wolf-pack-battalion: \f514; -$fa-var-won-sign: \f159; -$fa-var-wordpress: \f19a; -$fa-var-wordpress-simple: \f411; -$fa-var-wpbeginner: \f297; -$fa-var-wpexplorer: \f2de; -$fa-var-wpforms: \f298; -$fa-var-wpressr: \f3e4; -$fa-var-wrench: \f0ad; -$fa-var-x-ray: \f497; -$fa-var-xbox: \f412; -$fa-var-xing: \f168; -$fa-var-xing-square: \f169; -$fa-var-y-combinator: \f23b; -$fa-var-yahoo: \f19e; -$fa-var-yammer: \f840; -$fa-var-yandex: \f413; -$fa-var-yandex-international: \f414; -$fa-var-yarn: \f7e3; -$fa-var-yelp: \f1e9; -$fa-var-yen-sign: \f157; -$fa-var-yin-yang: \f6ad; -$fa-var-yoast: \f2b1; -$fa-var-youtube: \f167; -$fa-var-youtube-square: \f431; -$fa-var-zhihu: \f63f; diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/brands.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/brands.scss deleted file mode 100644 index eb153b2..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/brands.scss +++ /dev/null @@ -1,23 +0,0 @@ -/*! - * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -@import 'variables'; - -@font-face { - font-family: 'Font Awesome 5 Brands'; - font-style: normal; - font-weight: 400; - font-display: $fa-font-display; - src: url('#{$fa-font-path}/fa-brands-400.eot'); - src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), - url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), - url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), - url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), - url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); -} - -.fab { - font-family: 'Font Awesome 5 Brands'; - font-weight: 400; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/fontawesome.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/fontawesome.scss deleted file mode 100644 index ac6d7e9..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/fontawesome.scss +++ /dev/null @@ -1,16 +0,0 @@ -/*! - * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -@import 'variables'; -@import 'mixins'; -@import 'core'; -@import 'larger'; -@import 'fixed-width'; -@import 'list'; -@import 'bordered-pulled'; -@import 'animated'; -@import 'rotated-flipped'; -@import 'stacked'; -@import 'icons'; -@import 'screen-reader'; diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/regular.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/regular.scss deleted file mode 100644 index 953e3a7..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/regular.scss +++ /dev/null @@ -1,23 +0,0 @@ -/*! - * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -@import 'variables'; - -@font-face { - font-family: 'Font Awesome 5 Free'; - font-style: normal; - font-weight: 400; - font-display: $fa-font-display; - src: url('#{$fa-font-path}/fa-regular-400.eot'); - src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), - url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), - url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), - url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), - url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); -} - -.far { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/solid.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/solid.scss deleted file mode 100644 index 6ea911c..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/solid.scss +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -@import 'variables'; - -@font-face { - font-family: 'Font Awesome 5 Free'; - font-style: normal; - font-weight: 900; - font-display: $fa-font-display; - src: url('#{$fa-font-path}/fa-solid-900.eot'); - src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), - url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), - url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), - url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), - url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); -} - -.fa, -.fas { - font-family: 'Font Awesome 5 Free'; - font-weight: 900; -} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/v4-shims.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/v4-shims.scss deleted file mode 100644 index 90f1392..0000000 --- a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/v4-shims.scss +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -@import 'variables'; -@import 'shims'; diff --git a/MyOffice.SPA/src/assets/scss/pages/_auth.scss b/MyOffice.SPA/src/assets/scss/pages/_auth.scss deleted file mode 100644 index 113d220..0000000 --- a/MyOffice.SPA/src/assets/scss/pages/_auth.scss +++ /dev/null @@ -1,211 +0,0 @@ -.auth-container { - height: 100%; - width: 100%; - .auth-main { - height: 100%; - width: 100%; - margin: 0px !important; - min-height: 100vh; - } -} - -.left-img { - height: 100%; - width: 100%; - background-repeat: no-repeat; - background-position: center center; - background-size: cover; - display: flex; - align-items: center; - justify-content: center; - padding: 30px 15px; - position: relative; - z-index: 1; -} - -.left-content { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - max-width: 480px; - width: 100%; - text-align: center; - - h1 { - color: #fff; - } - p { - color: #fff; - } -} -.auth-form-section { - background-color: #fff; -} -.auth-form-btn { - display: flex; - justify-content: center; - width: 100%; - height: 50px !important; - border-radius: 10px; - cursor: pointer; - button { - width: 100%; - } -} -.form-section { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 100%; -} -.auth-signup-text { - font-size: 18px; - color: #000; - padding-bottom: 30px; - width: 410px; - max-width: 100%; -} -.sign-up-link { - color: #3699ff; - font-size: 20px !important; - margin: 0px 10px; -} -.auth-wrapper { - width: 410px; - max-width: 100%; - margin-top: auto; - margin-bottom: auto; -} -.login-title { - margin-bottom: 20px; -} -.social-login-title { - font-size: 15px; - color: #919aa3; - display: flex; - margin: 20px 0px; - - &::before, - &::after { - content: ""; - background-image: linear-gradient(#bbb8b8, #f3f3f3); - flex-grow: 1; - background-size: calc(100% - 20px) 1px; - background-repeat: no-repeat; - } - - &::before { - background-position: center left; - } - - &::after { - background-position: center right; - } -} -.welcome-msg { - font-weight: 500; -} -.social-icon { - text-align: center; - li a { - color: #3c4858; - border: 1px solid #3c4858; - display: inline-block; - height: 32px; - width: 32px; - line-height: 32px; - text-align: center; - transition: all 0.4s ease; - overflow: hidden; - position: relative; - &:hover { - background-color: #2f55d4; - border-color: #2f55d4 !important; - color: #ffffff !important; - } - } -} -.sm-icon { - height: 16px !important; - width: 16px !important; -} -.show-pwd-icon { - color: rgba(0, 0, 0, 0.55); - padding: 12px; -} -.face-icon { - color: rgba(0, 0, 0, 0.55); -} -.auth-locked { - font-size: 60px; - color: #333; - width: 120px; - height: 120px; - background-color: transparent; - margin: 0 auto; - img { - width: 100px; - border-radius: 50%; - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2); - } -} -.auth-locked-title { - font-size: 30px; - font-family: Poppins, sans-serif; - color: #403866; - line-height: 1.2; - text-align: center; - width: 100%; - display: block; -} -.error-header { - font-size: 80px; - line-height: 1.2; - color: #403866; - text-transform: uppercase; - text-align: center; - width: 100%; - display: block; - font-weight: 700; -} -.error-subheader { - font-size: 17px; - color: #403866; - text-transform: uppercase; - text-align: center; - width: 100%; - display: block; - font-weight: 700; -} -.error-subheader2 { - font-size: 12px; - color: #919192; - text-align: center; - width: 100%; - display: block; - font-weight: 500; -} - -@keyframes spinner { - to { - transform: rotate(360deg); - } -} - -.auth-spinner:before { - content: ""; - box-sizing: border-box; - position: absolute; - top: 50%; - left: 50%; - width: 20px; - height: 20px; - margin-top: -10px; - margin-left: -10px; - border-radius: 50%; - border: 2px solid #ffffff; - border-top-color: #000000; - animation: spinner 0.8s linear infinite; -} diff --git a/MyOffice.SPA/src/assets/scss/pages/_dashboard.scss b/MyOffice.SPA/src/assets/scss/pages/_dashboard.scss deleted file mode 100644 index 539e19f..0000000 --- a/MyOffice.SPA/src/assets/scss/pages/_dashboard.scss +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Document : _dashboard.scss - * Author : RedStar Template - * Description: This scss file for dashboard page style classes - */ -.dashboard-flot-chart { - height: 275px; -} - -.dashboard-donut-chart { - height: 265px; - text-align: center; -} - -.dashboard-line-chart { - height: 250px; -} - -.dashboard-stat-list { - list-style: none; - padding-left: 0; - margin-top: 40px; - - li { - padding: 16px 0 0 0; - - small { - font-size: 8px; - } - } -} - -.dashboard-task-infos { - .progress { - height: 10px; - position: relative; - top: 6px; - } -} -.totalEarning { - text-align: center; - padding: 6px; - color: #ff9800; -} -.earningProgress .progress { - height: 9px; -} diff --git a/MyOffice.SPA/src/assets/scss/pages/_inbox.scss b/MyOffice.SPA/src/assets/scss/pages/_inbox.scss deleted file mode 100644 index ba18d1a..0000000 --- a/MyOffice.SPA/src/assets/scss/pages/_inbox.scss +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Document : _inbox.scss - * Author : RedStar Template - * Description: This scss file for email page style classes - */ -.p-15 { - padding: 15px; -} -.p-10 { - padding: 10px; -} -.b-b { - border-bottom: 1px solid rgba(0, 0, 0, 0.2); -} -.mail_listing { - .mail-option { - .btn-group { - margin-bottom: 5px; - } - } -} -#mail-nav { - .btn { - min-width: 110px; - } - #mail-folders { - list-style-type: none; - padding-left: 0px; - .badge { - float: right; - } - } - #mail-folders > li { - margin: 2px 0; - a { - &:hover { - color: #fff; - background-color: #337ab7; - } - } - &.active > a { - color: #fff; - background-color: #337ab7; - &:hover { - background-color: #32c0c3; - } - } - } - #mail-labels { - float: left; - width: 100%; - list-style-type: none; - padding-left: 0px; - li { - float: left; - } - .material-icons { - font-size: 16px; - height: 16px; - padding: 2px; - float: left; - } - } - #online-offline { - list-style-type: none; - padding-left: 0px; - .material-icons { - font-size: 8px; - height: 8px; - padding: 0px 5px 2px 0; - } - } - #mail-labels, - #online-offline { - li { - a:hover { - background-color: #e6e6e6; - } - } - } - li { - a { - color: #212529; - padding: 7px 10px; - display: block; - border-radius: 4px; - position: relative; - -webkit-transition: all 0.2s ease-out; - -moz-transition: all 0.2s ease-out; - transition: all 0.2s ease-out; - } - } -} -.composeForm { - padding: 25px; -} -.inbox-body { - padding: 20px; -} -.replyBox { - border: 1px solid rgba(120, 130, 140, 0.13); - padding: 20px; -} -.inbox-center .table thead th { - vertical-align: middle; - padding: 20px; -} -.email-btn-group { - position: relative; - display: -ms-inline-flexbox; - display: -webkit-inline-box; - display: inline-flex; - vertical-align: middle; -} -.max-texts { - padding: 15px !important; - a { - color: #212529; - padding: 10px 0px 10px 0px; - } -} diff --git a/MyOffice.SPA/src/assets/scss/pages/_pricing.scss b/MyOffice.SPA/src/assets/scss/pages/_pricing.scss deleted file mode 100644 index 74de917..0000000 --- a/MyOffice.SPA/src/assets/scss/pages/_pricing.scss +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Document : _pricing.scss - * Author : RedStar Template - * Description: This scss file for pricing page style classes - */ -//colors -$white: #fff; -$color_orange: #ffa442; -$color_blue: #4b64ff; -$color_red: #ff4b4b; -$color_green: #40c952; - -.pricingTable { - text-align: center; - background: $white; - margin: 0 -10px; - box-shadow: 0 0 10px #ababab; - padding-bottom: 40px; - border-radius: 10px; - color: #cad0de; - transform: scale(1); - transition: all 0.5s ease 0s; - &:hover { - transform: scale(1.05); - z-index: 1; - .pricingTable-header { - background: #ff9624; - i { - color: $white; - } - } - .price-value { - color: $white; - } - .month { - color: $white; - } - } - .pricingTable-header { - padding: 40px 0; - background: #f5f6f9; - border-radius: 10px 10px 50% 50%; - transition: all 0.5s ease 0s; - i { - font-size: 50px; - color: #858c9a; - margin-bottom: 10px; - transition: all 0.5s ease 0s; - } - } - .price-value { - font-size: 35px; - color: #ff9624; - transition: all 0.5s ease 0s; - } - .month { - display: block; - font-size: 14px; - color: #cad0de; - } - .heading { - font-size: 24px; - color: #ff9624; - margin-bottom: 20px; - text-transform: uppercase; - padding-top: 15px; - } - &.blue { - .price-value { - color: $color_blue; - } - .heading { - color: $color_blue; - } - &:hover .pricingTable-header { - background: $color_blue; - } - .pricingTable-signup a { - background: $color_blue; - &:hover { - box-shadow: 0 0 10px $color_blue; - } - } - } - &.red { - .price-value { - color: $color_red; - } - .heading { - color: $color_red; - } - &:hover .pricingTable-header { - background: $color_red; - } - .pricingTable-signup a { - background: $color_red; - &:hover { - box-shadow: 0 0 10px $color_red; - } - } - } - &.greenColor { - .price-value { - color: $color_green; - } - &:hover { - .pricingTable-header { - background: $color_green; - } - .price-value { - color: $white; - } - } - .pricingTable-signup a { - background: $color_green; - &:hover { - box-shadow: 0 0 10px $color_green; - } - } - } - &.blueColor { - &:hover { - .pricingTable-header { - background: $color_blue; - } - .price-value { - color: $white; - } - } - .price-value { - color: $color_blue; - } - .heading { - color: $color_blue; - } - .pricingTable-signup a { - background: $color_blue; - } - } - &.redColor { - &:hover { - .pricingTable-header { - background: $color_red; - } - .price-value { - color: $white; - } - } - .price-value { - color: $color_red; - } - .heading { - color: $color_red; - } - .pricingTable-signup a { - background: $color_red; - } - } - .pricing-content ul { - list-style: none; - padding: 0; - margin-bottom: 30px; - li { - line-height: 30px; - color: #a7a8aa; - } - } - .pricingTable-signup a { - display: inline-block; - font-size: 15px; - color: $white; - padding: 10px 35px; - border-radius: 20px; - background: $color_orange; - text-transform: uppercase; - transition: all 0.3s ease 0s; - &:hover { - box-shadow: 0 0 10px $color_orange; - } - } - &.green .heading { - color: $color_green; - } -} -@media screen and (max-width: 990px) { - .pricingTable { - margin: 0 0 20px 0; - } -} -.greenColor .heading { - font-size: 24px; - color: $color_green; - margin-bottom: 20px; - text-transform: uppercase; -} diff --git a/MyOffice.SPA/src/assets/scss/pages/_profile.scss b/MyOffice.SPA/src/assets/scss/pages/_profile.scss deleted file mode 100644 index a7c61ea..0000000 --- a/MyOffice.SPA/src/assets/scss/pages/_profile.scss +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Document : _profile.scss - * Author : RedStar Template - * Description: This scss file for profile page style classes - */ -.profile-tab-box { - background: $white; - padding: 10px; - margin-top: 10px; - margin-bottom: 15px; - width: 100%; -} - -.skill-progress { - height: 10px !important; -} -.tab-all a { - color: #948f8f !important; - &.active { - background-color: #e91e63 !important; - box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), - 0 13px 24px -11px rgba(233, 30, 99, 0.6); - color: #ffffff !important; - border-radius: 30px; - } -} diff --git a/MyOffice.SPA/src/assets/scss/pages/_projects.scss b/MyOffice.SPA/src/assets/scss/pages/_projects.scss deleted file mode 100644 index 7d910ba..0000000 --- a/MyOffice.SPA/src/assets/scss/pages/_projects.scss +++ /dev/null @@ -1,539 +0,0 @@ -@use "sass:math"; - -@function rem($size) { - $remSize: math.div($size, 16px); - @return #{$remSize}rem; -} - -.board { - height: 100%; - max-width: 100%; - background-color: #ffffff; - float: none; - box-shadow: none; - .list { - flex: 1 0 0; - margin: rem(16px) 0; - border-radius: rem(5px); - box-shadow: 0 rem(2px) rem(2px) rgba(#000, 0.03), - 0 rem(1px) rem(5px) rgba(#000, 0.02); - overflow: hidden; - .header { - display: flex; - padding: rem(18px) rem(14px); - background: #ffffff; - align-items: center; - .title { - flex: 1; - text-align: center; - h2 { - margin: 0 0 rem(6px); - font-weight: 500; - font-size: 18px; - line-height: 1; - } - .count { - font-size: rem(14px); - line-height: 1; - opacity: 0.65; - } - } - } - .projects { - margin: 0; - padding: rem(14px); - list-style: none; - &.cdk-drop-list-dragging { - opacity: 0.65; - } - .cdk-drag-placeholder { - display: none; - } - } - } -} - -.project { - cursor: pointer; - list-style: none; - padding: rem(16px); - background: #ffffff; - transition: box-shadow 0.2s; - min-height: 50px; - position: relative; - margin-bottom: 24px; - border: 1px solid #d1d1d1; - border-radius: 10px; - box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); - -webkit-box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); - - &:hover { - box-shadow: 0 rem(2px) rem(2px) rgba(#000, 0.1), - 0 rem(1px) rem(5px) rgba(#000, 0.09); - } - &:last-child { - margin-bottom: 0; - } - &:not(.project-list-add) { - padding-right: rem(32px); - } - - h3 { - margin: 0 0 rem(4px); - font-size: 1em; - font-weight: 500; - } - .description { - margin: 0 0 rem(8px); - } - .gravity { - display: flex; - font-size: rem(11px); - letter-spacing: 1px; - text-transform: uppercase; - .priority { - flex: 1; - } - .deadline { - margin-right: rem(-16px); - text-align: right; - .icon { - margin-right: rem(4px); - display: inline-block; - height: 1em; - overflow: visible; - font-size: inherit; - vertical-align: -0.125em; - } - .deadline-label { - display: none; - } - } - } - .project-actions { - opacity: 0; - position: absolute; - top: rem(6px); - right: rem(-3px); - transition: opacity 0.2s; - } - .project-actions[aria-expanded="true"], - &:hover .project-actions { - opacity: 1; - } -} - -@media (min-width: 768px) { - .board { - display: flex; - .list { - margin: 0; - box-shadow: none; - border-radius: 0; - border-width: 0 0 0 1px; - // &:last-child { - // border-right: 1px solid #bbb; - // } - } - } -} - -@media (min-width: 992px) { - .project .gravity .deadline .deadline-label { - display: inline; - } -} - -.wrapper { - display: flex; - flex-flow: column; - height: 100%; -} - -.container { - margin: 0 auto; - padding: 0 rem(8px); - max-width: 1320px; -} - -.header { - flex: 0 1 auto; - padding: rem(18px) 0; - background: linear-gradient( - to top, - var(--color-purple-heart), - var(--color-purple-heart-light) - ); - color: var(--color-white); - .container { - display: flex; - justify-content: space-between; - align-items: center; - } - h1 { - margin: 0; - font-size: rem(16px); - line-height: 1; - font-weight: 500; - text-transform: uppercase; - letter-spacing: rem(1.5px); - a { - color: var(--color-white); - } - svg { - position: relative; - top: -1px; - margin-right: rem(12px); - display: inline-block; - vertical-align: middle; - height: rem(25px); - } - span { - display: inline-block; - vertical-align: middle; - } - } -} - -nav { - flex: 0 1 auto; - padding: rem(3px) 0; - background: var(--color-purple-heart-dark); - .container { - display: flex; - justify-content: space-between; - align-items: center; - } - .menu { - a { - display: inline-block; - padding: rem(11px) rem(11px) rem(9px); - color: var(--color-white); - font-weight: 500; - text-decoration: none; - border-bottom: rem(3px) solid rgba(#fff, 0.5); - } - } - .actions { - position: fixed; - z-index: 10; - right: rem(40px); - bottom: rem(40px); - button { - width: rem(60px); - height: rem(60px); - padding: 0; - background: #1075f2; - color: white; - border: none; - border-radius: 50%; - box-shadow: 0 0 rem(20px) rgba(#000, 0.3); - cursor: pointer; - svg { - height: rem(30px); - } - } - } -} - -main { - position: relative; - flex: 1 1 auto; - .container { - height: 100%; - } -} -.project-bedge { - font-size: 12px; - font-weight: 500; - background-color: #d1d3d4; - display: inline-flex; - cursor: default; - user-select: none; - border-radius: 3px; - padding: 2px 5px; - float: right; -} -.project-bedge2 { - font-size: 12px; - font-weight: 500; - background-color: #d1d3d4; - display: inline-flex; - cursor: default; - user-select: none; - border-radius: 3px; - padding: 2px 5px; - float: left; -} -.project-priority--1 { - color: rgb(0, 218, 0); - font-weight: 500; -} -.project-priority-0 { - color: rgb(233, 0, 233); - font-weight: 500; -} -.project-priority-1 { - color: hsl(0, 84%, 31%); - font-weight: 500; -} -.project-type-Website { - background-color: #1075f2; - color: #fff; -} -.project-type-Android { - background-color: #f21023; - color: #fff; -} -.project-type-IPhone { - background-color: #110103; - color: #fff; -} -.project-type-Testing { - background-color: #06a800; - color: #fff; -} -.pro-left { - font-weight: 500; - padding: 0px 10px; - border-radius: 5px; -} -.project-title { - font-size: 17px; - color: #1f2225; -} -.project-icon { - font-size: 19px; - margin-right: 5px; - vertical-align: text-top; -} -.project-icon2 { - font-size: 16px; - margin-right: 5px; - vertical-align: text-top; -} -.add-icon { - font-size: 19px; - margin-right: 5px; - vertical-align: text-top; -} - -@media (min-width: 576px) { - .container { - padding: 0 rem(16px); - } -} - -.project-people { - text-align: right; - vertical-align: middle; - img { - width: 32px; - height: 32px; - } -} -.project-actions { - text-align: right; - vertical-align: middle; -} -.profile-content { - border-top: none !important; -} -.profile-stats { - margin-right: 10px; -} -.profile-image { - width: 120px; - float: left; - img { - width: 96px; - height: 96px; - } -} -.profile-info { - margin-left: 120px; -} -.feed-element { - padding-bottom: 15px; - margin-top: 15px; - overflow: hidden; - &:first-child { - margin-top: 0; - } - .media { - margin-top: 15px; - } - .well { - border: 1px solid #e7eaec; - box-shadow: none; - background: #f2f3ff; - margin-top: 10px; - margin-bottom: 5px; - padding: 10px 20px; - font-size: 11px; - line-height: 16px; - } - .actions { - margin-top: 10px; - } - .photos { - margin: 10px 0; - } - > .pull-left { - margin-right: 10px; - } - img.img-circle { - width: 38px; - height: 38px; - } -} -.media-body { - overflow: hidden; -} -.feed-photo { - max-height: 180px; - //Instead of the line below you could use @include border-radius($radius, $vertical-radius) - border-radius: 4px; - overflow: hidden; - margin-right: 10px; - margin-bottom: 10px; -} -.ibox { - clear: both; - margin-bottom: 25px; - margin-top: 0; - padding: 0; - &.collapsed { - .ibox-content { - display: none; - } - .fa { - &.fa-chevron-up:before { - content: "\f078"; - } - &.fa-chevron-down:before { - content: "\f077"; - } - } - } - &:after { - display: table; - } - &:before { - display: table; - } -} -.ibox-title { - background-color: #ffffff; - border-color: #e7eaec; - //Instead of the line below you could use @include border-image($value) - border-image: none; - border-style: solid solid none; - border-width: 3px 0 0; - color: inherit; - margin-bottom: 0; - padding: 14px 15px 7px; - min-height: 48px; -} -.ibox-content { - background-color: #ffffff; - color: inherit; - padding: 0px 20px 20px; - border-image: none; - border-width: 1px 0; -} -.ibox-footer { - color: inherit; - border-top: 1px solid #e7eaec; - font-size: 90%; - background: #ffffff; - padding: 10px 15px; -} -dd.project-people { - text-align: left; - margin-top: 5px; -} -.project-title a { - font-size: 14px; - color: #676a6c; - font-weight: 600; -} -.project-list table tr td { - border-top: none; - border-bottom: 1px solid #e7eaec; - padding: 15px 10px; - vertical-align: middle; -} -.project-manager .tag-list li a { - font-size: 10px; - background-color: white; - padding: 5px 12px; - color: inherit; - //Instead of the line below you could use @include border-radius($radius, $vertical-radius) - border-radius: 2px; - border: 1px solid #e7eaec; - margin-right: 5px; - margin-top: 5px; - display: block; -} -.project-files li a { - font-size: 11px; - color: #676a6c; - margin-left: 10px; - line-height: 22px; -} -.feed-activity-list { - margin: 10px; - .feed-element { - border-bottom: 1px solid #e7eaec; - } -} -.dropdown-messages-box img.img-circle { - width: 38px; - height: 38px; -} -.file-list li { - padding: 5px 10px; - font-size: 11px; - //Instead of the line below you could use @include border-radius($radius, $vertical-radius) - border-radius: 2px; - border: 1px solid #e7eaec; - margin-bottom: 5px; - a { - color: inherit; - &:hover { - color: #1ab394; - } - } -} -.user-friends img { - width: 42px; - height: 42px; - margin-bottom: 5px; - margin-right: 5px; -} -.project-activity { - border: 1px solid #e5e5e5; - margin-top: 20px; -} -.project-doc-icon { - width: 40px; - height: 40px; - border: 1px solid #d9d9d9; - border-radius: 0.55rem; - i { - font-size: 20px; - line-height: 40px; - } -} -.project-name { - color: #f68c1f; -} -.project-card-header { - color: #5b626b; - font-size: 17px; - line-height: 28px; - padding-right: 10px; - font-weight: 500; - margin-bottom: 10px; -} diff --git a/MyOffice.SPA/src/assets/scss/pages/_timeline.scss b/MyOffice.SPA/src/assets/scss/pages/_timeline.scss deleted file mode 100644 index a5445a7..0000000 --- a/MyOffice.SPA/src/assets/scss/pages/_timeline.scss +++ /dev/null @@ -1,744 +0,0 @@ -/* - * Document : _timeline.scss - * Author : RedStar Template - * Description: This scss file for timeline page style classes - */ - -.cd-container { - width: 90%; - max-width: 1170px; - margin: 0 auto; -} - -.cd-container::after { - content: ""; - display: table; - clear: both; -} - -/* -------------------------------- - - Main components - - -------------------------------- */ -header { - height: 200px; - line-height: 200px; - text-align: center; - background: #303e49; -} - -header h1 { - color: #ffffff; - font-size: 18px; - font-size: 1.125rem; -} - -.timelineImgHight { - width: 150px; -} - -@media only screen and (min-width: 1170px) { - header { - height: 300px; - line-height: 300px; - } - header h1 { - font-size: 24px; - font-size: 1.5rem; - } -} - -#cd-timeline { - position: relative; - padding: 2em 0; - margin-top: 2em; - margin-bottom: 2em; -} - -#cd-timeline::before { - /* this is the vertical line */ - content: ""; - position: absolute; - top: 0; - left: 18px; - height: 100%; - width: 4px; - background: #d7e4ed; -} - -@media only screen and (min-width: 1170px) { - #cd-timeline { - margin-top: 3em; - margin-bottom: 3em; - } - #cd-timeline::before { - left: 50%; - margin-left: -2px; - } -} - -.cd-timeline-block { - position: relative; - margin: 2em 0; -} - -.cd-timeline-block::after { - clear: both; - content: ""; - display: table; -} - -.cd-timeline-block:first-child { - margin-top: 0; -} - -.cd-timeline-block:last-child { - margin-bottom: 0; -} - -@media only screen and (min-width: 1170px) { - .cd-timeline-block { - margin: 4em 0; - } - .cd-timeline-block:first-child { - margin-top: 0; - } - .cd-timeline-block:last-child { - margin-bottom: 0; - } -} - -.cd-timeline-img { - position: absolute; - top: 0; - left: 0; - width: 40px; - height: 40px; - border-radius: 50%; - box-shadow: 0 0 0 4px #e6dfdf, inset 0 2px 0 rgba(0, 0, 0, 0.08), - 0 3px 0 4px rgba(0, 0, 0, 0.05); -} - -.cd-timeline-img img { - display: block; - width: 48px; - position: relative; - left: 30%; - top: 30%; - margin-left: -12px; - margin-top: -12px; - border-radius: 50%; -} - -.cd-timeline-img.cd-picture { - background: #75ce66; -} - -.cd-timeline-img.cd-movie { - background: #c03b44; -} - -.cd-timeline-img.cd-location { - background: #f0ca45; -} - -@media only screen and (min-width: 1170px) { - .cd-timeline-img { - width: 60px; - height: 60px; - left: 50%; - margin-left: -30px; - /* Force Hardware Acceleration in WebKit */ - -webkit-transform: translateZ(0); - -webkit-backface-visibility: hidden; - } - .cssanimations .cd-timeline-img.is-hidden { - visibility: hidden; - } - .cssanimations .cd-timeline-img.bounce-in { - visibility: visible; - -webkit-animation: cd-bounce-1 0.6s; - -moz-animation: cd-bounce-1 0.6s; - animation: cd-bounce-1 0.6s; - } -} - -@-webkit-keyframes cd-bounce-1 { - 0% { - opacity: 0; - -webkit-transform: scale(0.5); - } - 60% { - opacity: 1; - -webkit-transform: scale(1.2); - } - 100% { - -webkit-transform: scale(1); - } -} - -@-moz-keyframes cd-bounce-1 { - 0% { - opacity: 0; - -moz-transform: scale(0.5); - } - 60% { - opacity: 1; - -moz-transform: scale(1.2); - } - 100% { - -moz-transform: scale(1); - } -} - -@keyframes cd-bounce-1 { - 0% { - opacity: 0; - -webkit-transform: scale(0.5); - -moz-transform: scale(0.5); - -ms-transform: scale(0.5); - -o-transform: scale(0.5); - transform: scale(0.5); - } - 60% { - opacity: 1; - -webkit-transform: scale(1.2); - -moz-transform: scale(1.2); - -ms-transform: scale(1.2); - -o-transform: scale(1.2); - transform: scale(1.2); - } - 100% { - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); - } -} - -.cd-timeline-content { - position: relative; - margin-left: 60px; - background: #f0f1f3; - border-radius: 0.25em; - padding: 1em; - box-shadow: 0 3px 0 #d7e4ed; -} - -.cd-timeline-content::after { - clear: both; - content: ""; - display: table; -} - -.cd-timeline-content h2 { - color: #303e49; -} - -.cd-timeline-content p, -.cd-timeline-content .cd-read-more, -.cd-timeline-content .cd-date { - font-size: 13px; - font-size: 0.8125rem; -} - -.cd-timeline-content .cd-read-more, -.cd-timeline-content .cd-date { - display: inline-block; -} - -.cd-timeline-content p { - margin: 1em 0; - line-height: 1.6; -} - -.cd-timeline-content .cd-read-more { - float: right; - padding: 0.8em 1em; - background: #acb7c0; - color: #ffffff; - border-radius: 0.25em; -} - -.no-touch .cd-timeline-content .cd-read-more:hover { - background-color: #bac4cb; -} - -.cd-timeline-content .cd-date { - float: left; - padding: 0.8em 0; - opacity: 0.7; -} - -.cd-timeline-content::before { - content: ""; - position: absolute; - top: 16px; - right: 100%; - height: 0; - width: 0; - border: 7px solid transparent; - border-right: 7px solid #ffffff; -} - -@media only screen and (min-width: 768px) { - .cd-timeline-content h2 { - font-size: 20px; - font-size: 1.25rem; - } - .cd-timeline-content p { - font-size: 16px; - font-size: 1rem; - } - .cd-timeline-content .cd-read-more, - .cd-timeline-content .cd-date { - font-size: 14px; - font-size: 0.875rem; - } -} - -@media only screen and (min-width: 1170px) { - .cd-timeline-content { - margin-left: 0; - padding: 1.6em; - width: 45%; - } - .cd-timeline-content::before { - top: 24px; - left: 100%; - border-color: transparent; - border-left-color: #f0f1f3; - } - .cd-timeline-content .cd-read-more { - float: left; - } - .cd-timeline-content .cd-date { - position: absolute; - width: 100%; - left: 122%; - top: 6px; - font-size: 16px; - font-size: 1rem; - } - .cd-timeline-block:nth-child(even) .cd-timeline-content { - float: right; - } - .cd-timeline-block:nth-child(even) .cd-timeline-content::before { - top: 24px; - left: auto; - right: 100%; - border-color: transparent; - border-right-color: #f0f1f3; - } - .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-read-more { - float: right; - } - .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-date { - left: auto; - right: 122%; - text-align: right; - } - .cssanimations .cd-timeline-content.is-hidden { - visibility: hidden; - } - .cssanimations .cd-timeline-content.bounce-in { - visibility: visible; - -webkit-animation: cd-bounce-2 0.6s; - -moz-animation: cd-bounce-2 0.6s; - animation: cd-bounce-2 0.6s; - } -} - -@media only screen and (min-width: 1170px) { - /* inverse bounce effect on even content blocks */ - .cssanimations - .cd-timeline-block:nth-child(even) - .cd-timeline-content.bounce-in { - -webkit-animation: cd-bounce-2-inverse 0.6s; - -moz-animation: cd-bounce-2-inverse 0.6s; - animation: cd-bounce-2-inverse 0.6s; - } -} - -@-webkit-keyframes cd-bounce-2 { - 0% { - opacity: 0; - -webkit-transform: translateX(-100px); - } - 60% { - opacity: 1; - -webkit-transform: translateX(20px); - } - 100% { - -webkit-transform: translateX(0); - } -} - -@-moz-keyframes cd-bounce-2 { - 0% { - opacity: 0; - -moz-transform: translateX(-100px); - } - 60% { - opacity: 1; - -moz-transform: translateX(20px); - } - 100% { - -moz-transform: translateX(0); - } -} - -@keyframes cd-bounce-2 { - 0% { - opacity: 0; - -webkit-transform: translateX(-100px); - -moz-transform: translateX(-100px); - -ms-transform: translateX(-100px); - -o-transform: translateX(-100px); - transform: translateX(-100px); - } - 60% { - opacity: 1; - -webkit-transform: translateX(20px); - -moz-transform: translateX(20px); - -ms-transform: translateX(20px); - -o-transform: translateX(20px); - transform: translateX(20px); - } - 100% { - -webkit-transform: translateX(0); - -moz-transform: translateX(0); - -ms-transform: translateX(0); - -o-transform: translateX(0); - transform: translateX(0); - } -} - -@-webkit-keyframes cd-bounce-2-inverse { - 0% { - opacity: 0; - -webkit-transform: translateX(100px); - } - 60% { - opacity: 1; - -webkit-transform: translateX(-20px); - } - 100% { - -webkit-transform: translateX(0); - } -} - -@-moz-keyframes cd-bounce-2-inverse { - 0% { - opacity: 0; - -moz-transform: translateX(100px); - } - 60% { - opacity: 1; - -moz-transform: translateX(-20px); - } - 100% { - -moz-transform: translateX(0); - } -} - -@keyframes cd-bounce-2-inverse { - 0% { - opacity: 0; - -webkit-transform: translateX(100px); - -moz-transform: translateX(100px); - -ms-transform: translateX(100px); - -o-transform: translateX(100px); - transform: translateX(100px); - } - 60% { - opacity: 1; - -webkit-transform: translateX(-20px); - -moz-transform: translateX(-20px); - -ms-transform: translateX(-20px); - -o-transform: translateX(-20px); - transform: translateX(-20px); - } - 100% { - -webkit-transform: translateX(0); - -moz-transform: translateX(0); - -ms-transform: translateX(0); - -o-transform: translateX(0); - transform: translateX(0); - } -} - -.timeline { - list-style: none; - padding: 0 0 8px; - position: relative; - &:before { - top: 00px; - bottom: 0; - position: absolute; - content: " "; - width: 3px; - background-color: #e7e7e7; - left: 25px; - margin-right: -1.5px; - } - > li { - margin-bottom: 5px; - position: relative; - &:before { - content: " "; - display: table; - } - &:after { - content: " "; - display: table; - clear: both; - } - > { - .timeline-panel { - width: calc(100% - 70px); - float: right; - border: 1px solid #e7e7e7; - border-radius: 2px; - padding: 5px 20px; - position: relative; - border-radius: 10px; - margin-bottom: 5px; - &:before { - position: absolute; - top: 26px; - left: -15px; - display: inline-block; - border-top: 15px solid transparent; - border-right: 15px solid #e7e7e7; - border-left: 0 solid #e7e7e7; - border-bottom: 15px solid transparent; - content: " "; - } - &:after { - position: absolute; - top: 27px; - left: -14px; - display: inline-block; - border-top: 14px solid transparent; - border-right: 14px solid #ffffff; - border-left: 0 solid #ffffff; - border-bottom: 14px solid transparent; - content: " "; - } - } - .timeline-badge { - width: 35px; - height: 35px; - position: absolute; - top: 25px; - left: 8px; - img { - border-radius: 50%; - border: 2px solid #ffffff; - -webkit-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); - -ms-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); - box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); - } - } - } - } -} -.timeline-title { - margin: 4px 0 !important; - font-size: 13px; -} -.timeline-body > p { - font-size: 12px; - margin-bottom: 2px; -} - -// Timeline 2 - -.left-timeline { - margin: 0; - padding: 0; - list-style: none; - position: relative; - &:before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - width: 3px; - background: #eee; - left: 20%; - margin-left: -6px; - } - > li { - position: relative; - &:first-child { - .left-icon { - background: #fff; - color: #666; - } - .left-time span.large { - color: #444; - font-size: 17px !important; - font-weight: 700; - } - } - &:nth-child(odd) { - .left-label { - background: #f0f1f3; - &:after { - border-right-color: #f0f1f3; - } - } - .left-time span:last-child { - color: #444; - font-size: 13px; - } - } - .left-time { - display: block; - width: 23%; - padding-right: 70px; - position: absolute; - span { - display: block; - text-align: right; - &:first-child { - font-size: 15px; - color: #3d4c5a; - font-weight: 700; - } - &:last-child { - font-size: 14px; - color: #444; - } - } - } - .left-label { - margin: 0 0 15px 25%; - background: #f0f1f3; - padding: 1.2em; - position: relative; - //Instead of the line below you could use @include border-radius($radius, $vertical-radius) - border-radius: 5px; - &:after { - right: 100%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-right-color: #f0f1f3; - border-width: 10px; - top: 10px; - } - blockquote { - font-size: 16px; - } - .map-checkin { - border: 5px solid rgba(235, 235, 235, 0.2); - //Instead of the line below you could use @include box-shadow($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10) - box-shadow: 0 0 0 1px #ebebeb; - background: #fff !important; - } - h2 { - margin: 0; - padding: 0 0 10px 0; - line-height: 26px; - font-size: 16px; - font-weight: normal; - a { - font-size: 15px; - &:hover { - text-decoration: none; - } - } - span { - font-size: 15px; - } - } - p { - color: #444; - } - } - .left-icon { - width: 40px; - height: 40px; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - font-size: 1.4em; - line-height: 40px; - position: absolute; - color: #fff; - border-radius: 50%; - box-shadow: 0 5px 25px 0 rgba(0, 0, 0, 0.2); - text-align: center; - left: 20%; - top: 0; - margin: 0 0 0 -25px; - img { - border-radius: 50%; - } - } - .empty span { - color: #777; - } - } -} -@media screen and (max-width: 992px) and (min-width: 768px) { - .left-timeline > li .left-time { - padding-right: 60px; - } -} -@media screen and (max-width: 65.375em) { - .left-timeline > li .left-time span:last-child { - font-size: 12px; - } -} -@media screen and (max-width: 47.2em) { - .left-timeline { - &:before { - display: none; - } - > li { - .left-time { - width: 100%; - position: relative; - padding: 0 0 20px 0; - span { - text-align: left; - } - } - .left-label { - margin: 0 0 30px 0; - padding: 1em; - font-weight: 400; - font-size: 95%; - &:after { - right: auto; - left: 20px; - border-right-color: transparent; - border-bottom-color: #f5f5f6; - top: -20px; - } - } - .left-icon { - position: relative; - float: right; - left: auto; - margin: -64px 5px 0 0; - } - &:nth-child(odd) .left-label:after { - border-right-color: transparent; - border-bottom-color: #f5f5f6; - } - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_carousel.scss b/MyOffice.SPA/src/assets/scss/plugins/_carousel.scss deleted file mode 100644 index 435404d..0000000 --- a/MyOffice.SPA/src/assets/scss/plugins/_carousel.scss +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Document : _carousel.scss - * Author : RedStar Template - * Description: This scss file for owl carousel style classes - */ - -.owl-btns { - text-align: center; - [class*="owl-"] { - color: #fff; - font-size: 14px; - margin: 5px; - padding: 4px 7px; - background: #d6d6d6; - display: inline-block; - cursor: pointer; - border-radius: 3px; - &:hover { - background: #869791; - color: #fff; - text-decoration: none; - } - } -} -#dashboard_slide { - padding: 6px 10px 0px 0px; -} -#dashboard_slide2 { - padding: 0px 10px 0px 0px; -} -.carousel-content { - height: 232px; - border-radius: 5px; - .slide-heading { - font-size: 20px; - } -} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_charts.scss b/MyOffice.SPA/src/assets/scss/plugins/_charts.scss deleted file mode 100644 index fa7850f..0000000 --- a/MyOffice.SPA/src/assets/scss/plugins/_charts.scss +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Document : _charts.scss - * Author : RedStar Template - * Description: This scss file for all charts style classes - */ -/* Morris */ -.morris-hover { - &.morris-default-style { - @include border-radius(0); - } -} - -/* Flot */ -.flot-chart { - width: 100%; - height: 320px; -} - -.panel-switch-btn { - position: relative; - right: 20px; - z-index: 9; - - label { - font-weight: bold !important; - } -} - -.legendLabel { - width: 85px !important; - position: relative; - left: 3px; -} - -#multiple_axis_chart { - .legendLabel { - width: 160px !important; - } -} - -/* Sparkline */ -.sparkline { - text-align: center; -} - -.chart-box { - display: flex; - justify-content: space-between; - font-size: 14px; - margin-bottom: 30px; -} -.chart-box2 { - font-size: 14px; - margin-bottom: 30px; - text-align: center; -} -.chart-note { - text-transform: capitalize; - display: inline-block; - margin-right: 12px; - font-size: 14px; - .dot { - margin: 0px 7px; - } -} -.chart-statis { - display: inline-block; - margin-right: 35px; - .label { - display: block; - text-transform: capitalize; - line-height: 1.2; - } - .index { - font-size: 18px; - color: #333; - padding-left: 15px; - } -} - -.dot { - display: inline-block; - width: 10px; - height: 10px; - border-radius: 100%; -} -.dot-black { - background: #000000; -} -.dot-orange { - background: #f96332; -} -.chart-box-left { - padding-left: 10px; -} -.area_chart-style { - height: 170px; - margin: 30px; -} -.chart-shadow2 { - -webkit-filter: drop-shadow(0 -6px 4px rgba(106, 141, 247, 0.5)); - filter: drop-shadow(0 -6px 4px rgba(106, 141, 247, 0.5)); -} -.chart-shadow { - -webkit-filter: drop-shadow(0px 9px 2px rgba(0, 0, 0, 0.3)); - filter: drop-shadow(0px 9px 2px rgba(0, 0, 0, 0.3)); -} -.chartsh { - height: 16rem; -} - -// chartjs - -.axisData { - position: absolute; - color: #fff; - z-index: 1; - text-transform: uppercase; - display: flex; - width: 100%; - bottom: 0; - .tick { - flex: 1; - position: relative; - overflow: hidden; - opacity: 0.2; - font-size: 11px; - text-align: center; - line-height: 40px; - padding-top: 150px; - &:hover { - opacity: 1; - background-color: rgba(255, 255, 255, 0.2); - .value { - &.productValue { - transform: translateY(0); - display: block; - } - &.serviceValue { - transform: translateY(0); - display: block; - left: 0; - top: 80px; - color: #000; - transition: 0.3s transform; - } - } - } - .value { - transform: translateY(20px); - transition: 0.3s transform; - position: absolute; - top: 20px; - color: #000; - border-radius: 2px; - width: 100%; - line-height: 20px; - } - } -} -.dot-product { - background: #5bcfe4; -} -.dot-service { - background: #64e88b; -} -.dot-product1 { - background: #d3d3d3; -} -.dot-service1 { - background: #6e68c1; -} - -// ngx-chart -.chart-legend { - header { - background: transparent; - height: 0px; - } - .legend-labels { - background: transparent !important; - } -} -.ngx-charts { - text { - fill: #9aa0ac; - } -} - -// Gauge chart -mwl-gauge { - width: 150px; - height: 150px; - display: block; - padding: 10px; -} -mwl-gauge > .gauge > .dial { - stroke: #d7d7d7; - stroke-width: 5; - fill: rgba(0, 0, 0, 0); -} -mwl-gauge > .gauge > .value { - stroke: #4fa1f1; - stroke-width: 5; - fill: rgba(0, 0, 0, 0); -} -mwl-gauge > .gauge > .value-text { - fill: #4fa1f1; - font-family: sans-serif; - font-weight: bold; - font-size: 0.8em; -} -/* ------- Alternate Style ------- */ -mwl-gauge.two { -} -mwl-gauge.two > .gauge > .dial { - stroke: #334455; - stroke-width: 10; -} -mwl-gauge.two > .gauge > .value { - stroke: orange; - stroke-dasharray: none; - stroke-width: 13; -} -mwl-gauge.two > .gauge > .value-text { - fill: orange; -} -/* ------- Alternate Style ------- */ -mwl-gauge.three { -} -mwl-gauge.three > .gauge > .dial { - stroke: #334455; - stroke-width: 2; -} -mwl-gauge.three > .gauge > .value { - stroke: #c9de3c; - stroke-width: 5; -} -mwl-gauge.three > .gauge > .value-text { - fill: #c9de3c; -} -/* ----- Alternate Style ----- */ -mwl-gauge.four > .gauge > .dial { - stroke: #334455; - stroke-width: 5; -} -mwl-gauge.four > .gauge > .value { - stroke: #be80ff; - stroke-dasharray: none; - stroke-width: 5; -} -mwl-gauge.four > .gauge > .value-text { - fill: #be80ff; -} -/* ----- Alternate Style ----- */ -mwl-gauge.five > .gauge > .dial { - stroke: #334455; - stroke-width: 5; -} -mwl-gauge.five > .gauge > .value { - stroke: #f8774b; - stroke-dasharray: 25 1; - stroke-width: 5; -} -mwl-gauge.five > .gauge > .value-text { - fill: #f8774b; - font-size: 0.7em; -} -/* ----- Alternate Style ----- */ -mwl-gauge.six > .gauge > .dial { - stroke: #334455; - fill: #334455; - stroke-width: 20; -} -mwl-gauge.six > .gauge > .value { - stroke: #ff6daf; - stroke-width: 20; -} -mwl-gauge.six > .gauge > .value-text { - fill: #ff6daf; - font-size: 0.7em; -} -mwl-gauge.seven > .gauge > .dial { - stroke: transparent; - stroke-width: 5; - transform: scale(0.9, 0.9) translate3d(5.5px, 5.5px, 0); - fill: rgba(191, 202, 214, 0.42); -} -mwl-gauge.seven > .gauge > .value { - stroke: #f8774b; - stroke-dasharray: none; - stroke-width: 5; -} -ngx-gauge.guage-chart-center { - display: flex; - justify-content: center; - width: 100% !important; -} -.apex-pie-center { - display: flex; - justify-content: center; -} -.apexcharts-legend-marker { - margin: 0px 5px !important; -} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_formwizard.scss b/MyOffice.SPA/src/assets/scss/plugins/_formwizard.scss deleted file mode 100644 index a63cbc2..0000000 --- a/MyOffice.SPA/src/assets/scss/plugins/_formwizard.scss +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Document : _formwizard.scss - * Author : RedStar Template - * Description: This scss file for wizard style classes - */ - -.wizard, -.tabcontrol { - display: block; - width: 100%; - overflow: hidden; -} - -.wizard a, -.tabcontrol a { - outline: 0; -} - -.wizard ul, -.tabcontrol ul { - list-style: none !important; - padding: 0; - margin: 0; -} - -.wizard ul > li, -.tabcontrol ul > li { - display: block; - padding: 0; -} -/* Accessibility */ -.wizard > .steps .current-info, -.tabcontrol > .steps .current-info, -.wizard > .content > .title, -.tabcontrol > .content > .title { - position: absolute; - left: -999em; -} - -.wizard { - > .steps { - position: relative; - display: block; - width: 100%; - } - - &.vertical { - > .steps { - float: left; - width: 30%; - clear: none; - } - - > .steps > ul > li { - float: none; - width: 100%; - } - - > .content { - float: left; - margin: 0 0 0.5em 0; - width: 70%; - clear: none; - } - - > .actions { - float: right; - width: 100%; - } - - > .actions > ul > li { - margin: 0 0 0 1em; - } - } - - > { - .steps { - .number { - font-size: 1.429em; - } - - > ul > li { - width: 25%; - float: left; - } - } - - .actions > ul > li { - float: left; - } - } - - > { - .steps { - a { - display: block; - width: auto; - margin: 0 0.5em 0.5em; - padding: 1em 1em; - text-decoration: none; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - - &:hover, - &:active { - display: block; - width: auto; - margin: 0 0.5em 0.5em; - padding: 1em 1em; - text-decoration: none; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - } - } - - .disabled a { - background: #eee; - color: #aaa; - cursor: default; - - &:hover, - &:active { - background: #eee; - color: #aaa; - cursor: default; - } - } - - .current a { - background: #2184be; - color: #fff; - cursor: default; - - &:hover, - &:active { - background: #2184be; - color: #fff; - cursor: default; - } - } - - .done a { - background: #9dc8e2; - color: #fff; - - &:hover, - &:active { - background: #9dc8e2; - color: #fff; - } - } - - .error a { - background: #ff3111; - color: #fff; - - &:hover, - &:active { - background: #ff3111; - color: #fff; - } - } - } - - .content { - border: 1px solid #ddd; - display: block; - margin: 0.5em; - min-height: 35em; - overflow: hidden; - position: relative; - width: auto; - } - } - - > { - .actions { - position: relative; - display: block; - text-align: right; - width: 100%; - } - } - - > .actions > ul { - display: inline-block; - text-align: right; - - > li { - margin: 0 0.5em; - } - } - - > { - .actions { - a { - background: #009688; - color: #fff; - display: block; - padding: 0.5em 1em; - text-decoration: none; - @include border-radius(0); - - &:hover, - &:active { - background: #009688; - color: #fff; - display: block; - padding: 0.5em 1em; - text-decoration: none; - @include border-radius(0); - } - } - - .disabled a { - background: #eee; - color: #aaa; - - &:hover, - &:active { - background: #eee; - color: #aaa; - } - } - } - } -} - -.tabcontrol > { - .steps { - position: relative; - display: block; - width: 100%; - - > ul { - position: relative; - margin: 6px 0 0 0; - top: 1px; - z-index: 1; - - > li { - float: left; - margin: 5px 2px 0 0; - padding: 1px; - -webkit-border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topleft: 5px; - -moz-border-radius-topright: 5px; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - - &:hover { - background: #edecec; - border: 1px solid #bbb; - padding: 0; - } - - &.current { - background: #fff; - border: 1px solid #bbb; - border-bottom: 0 none; - padding: 0 0 1px 0; - margin-top: 0; - - > a { - padding: 15px 30px 10px 30px; - } - } - - > a { - color: #5f5f5f; - display: inline-block; - border: 0 none; - margin: 0; - padding: 10px 30px; - text-decoration: none; - - &:hover { - text-decoration: none; - } - } - } - } - } - - .content { - position: relative; - display: inline-block; - width: 100%; - height: 35em; - overflow: hidden; - border-top: 1px solid #bbb; - padding-top: 20px; - - > .body { - float: left; - position: absolute; - width: 95%; - height: 95%; - padding: 2.5%; - - ul { - list-style: disc !important; - - > li { - display: list-item; - } - } - } - } -} - -.wizard { - .content { - min-height: 245px; - @include border-radius(0); - overflow-y: auto; - - .body { - padding: 15px; - } - } - - .steps { - a { - @include border-radius(0); - @include transition(0.5s); - - &:active, - &:focus, - &:hover { - @include border-radius(0); - } - } - - .done { - a { - background-color: rgba(#009688, 0.6); - - &:hover, - &:active, - &:focus { - background-color: rgba(#009688, 0.5); - } - } - } - - .error { - a { - background-color: #f44336 !important; - } - } - - .current { - a { - background-color: #009688; - - &:active, - &:focus, - &:hover { - background-color: #009688; - } - } - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_imagegallery.scss b/MyOffice.SPA/src/assets/scss/plugins/_imagegallery.scss deleted file mode 100644 index 9586c44..0000000 --- a/MyOffice.SPA/src/assets/scss/plugins/_imagegallery.scss +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Document : _imagegallery.scss - * Author : RedStar Template - * Description: This scss file for image gallery style classes - */ -.group-1, -.group-2 { - border: 1px solid #ffffff; - border-radius: 5px; - display: table; - margin-bottom: 20px; - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); -} - -.group-1 img, -.group-2 img { - cursor: pointer; - width: 300px; - height: 300px; - padding: 10px; - border-radius: 10px; -} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_maps.scss b/MyOffice.SPA/src/assets/scss/plugins/_maps.scss deleted file mode 100644 index 3d4aef8..0000000 --- a/MyOffice.SPA/src/assets/scss/plugins/_maps.scss +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Document : _maps.scss - * Author : RedStar Template - * Description: This scss file for maps style classes - */ -/* Google Maps */ -agm-map { - height: 300px; -} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_tables.scss b/MyOffice.SPA/src/assets/scss/plugins/_tables.scss deleted file mode 100644 index 46c0189..0000000 --- a/MyOffice.SPA/src/assets/scss/plugins/_tables.scss +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Document : _tables.scss - * Author : RedStar Template - * Description: This scss file for tables style classes - */ - - .table { - tbody { - border-top: none !important; - tr { - td, - th { - padding: 10px; - border-top: 1px solid #eee; - border-bottom: 1px solid #eee; - vertical-align: middle; - - ul { - margin: 0; - } - .tbl-user-img-small { - margin: 0px 5px; - border-radius: 5px; - height: 30px; - width: 30px; - } - } - } - - tr.primary { - td, - th { - background-color: #1f91f3; - color: #fff; - } - } - - tr.success { - td, - th { - background-color: #2b982b; - color: #fff; - } - } - - tr.info { - td, - th { - background-color: #00b0e4; - color: #fff; - } - } - - tr.warning { - td, - th { - background-color: #ff9600; - color: #fff; - } - } - - tr.danger { - td, - th { - background-color: #fb483a; - color: #fff; - } - } - } - - thead { - tr { - th { - padding: 0 10px; - height: 50px; - vertical-align: middle; - background-color: #f5f5f5; - color: #666; - font-weight: 500; - border: none; - } - } - } - - .tbl-pdf { - color: #f96332; - font-size: 20px; - cursor: pointer; - } - .tbl-action-btn { - height: 40px; - width: 40px; - display: inline-flex; - align-items: center; - } -} - -.table-bordered { - border-top: 1px solid #eee; - - tbody { - tr { - td, - th { - padding: 10px; - border: 1px solid #eee; - } - } - } - - thead { - tr { - th { - padding: 10px; - border: 1px solid #eee; - } - } - } -} - -.table-img { - img { - border-radius: 5px; - height: 33px; - width: 33px; - background: #fff; - position: inherit; - } -} - -.btn-tbl-edit { - background-color: #96a2b4; - height: 30px !important; - width: 30px !important; - margin: 2px !important; - line-height: 30px !important; - color: #fff; - - // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; - .material-icons { - font-size: 16px !important; - } - - &:hover { - background-color: #888; - color: $white; - } - - &:focus { - background-color: #888; - } -} - -.btn-tbl-delete { - background-color: #ff944f; - height: 30px !important; - width: 30px !important; - margin: 2px !important; - line-height: 30px !important; - color: #fff; - - // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; - .material-icons { - font-size: 16px !important; - } - - &:hover { - background-color: #ff9600; - color: $white; - } - - &:focus { - background-color: #ff9600; - } -} -.btn-tbl-confirm { - background-color: #3fa3f3; - height: 30px !important; - width: 30px !important; - margin: 2px !important; - line-height: 30px !important; - color: #fff; - - // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; - .material-icons { - font-size: 16px !important; - } - - &:hover { - background-color: #62b5f8; - color: $white; - } - - &:focus { - background-color: #62b5f8; - } -} -.btn-tbl-reject { - background-color: #f96333; - height: 30px !important; - width: 30px !important; - margin: 2px !important; - line-height: 30px !important; - color: #fff; - - // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; - .material-icons { - font-size: 16px !important; - } - - &:hover { - background-color: #f87346; - color: $white; - } - - &:focus { - background-color: #f87346; - } -} - -.tbl-fav-edit { - color: #6777ef; - display: inline !important; - .feather { - height: 20px !important; - width: 20px !important; - } -} -.tbl-fav-delete { - color: #ff5200; - display: inline !important; - .feather { - height: 20px !important; - width: 20px !important; - } -} -.avatar { - position: relative; - width: 30px; - white-space: nowrap; - border-radius: 1000px; - vertical-align: bottom; - display: inline-block; - - img { - width: 100%; - max-width: 100%; - height: auto; - border: 0; - border-radius: 1000px; - } -} - -.avatar-sm { - width: 32px; -} - -.list-inline { - padding-left: 0; - list-style: none; -} - -.list-unstyled { - padding-left: 0; - list-style: none; -} - -.spinner { - display: inline-block; -} - -.spinner-reverse { - display: inline-block; -} - -.order-list li { - img { - border: 2px solid #ffffff; - box-shadow: 0 2px 10px 0 rgba(107, 111, 130, 0.3); - } - - + li { - margin-left: -14px; - } - - .badge { - background: rgba(255, 255, 255, 0.8); - color: #6b6f82; - margin-bottom: 6px; - } -} - -.buttons-copy { - background-color: #666 !important; - box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), - 0 13px 24px -11px rgba(233, 30, 99, 0.6); - color: #fff !important; - border-radius: 30px !important; - border: 0px !important; - height: 30px; - width: 60px; - cursor: pointer; -} - -.buttons-excel { - background-color: #59bf70 !important; - box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), - 0 13px 24px -11px rgba(233, 30, 99, 0.6); - color: #fff !important; - border-radius: 30px !important; - border: 0px !important; - height: 30px; - width: 60px; - cursor: pointer; -} - -.buttons-csv { - background-color: #2ab9d0 !important; - box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), - 0 13px 24px -11px rgba(233, 30, 99, 0.6); - color: #fff !important; - border-radius: 30px !important; - border: 0px !important; - height: 30px; - width: 60px; - cursor: pointer; -} - -.buttons-pdf { - background-color: #e91e63 !important; - box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), - 0 13px 24px -11px rgba(233, 30, 99, 0.6); - color: #fff !important; - border-radius: 30px !important; - border: 0px !important; - height: 30px; - width: 60px; - cursor: pointer; -} - -.buttons-print { - background-color: #6563ef !important; - box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), 0 13px 24px -11px #6563ef; - color: #fff !important; - border-radius: 30px !important; - border: 0px !important; - height: 30px; - width: 60px; - cursor: pointer; -} - -tr.group, -tr.group:hover { - background-color: #ddd !important; -} - -.tableBody { - font-size: 14px; - color: #555; - padding: 0px 15px 0px 15px; -} - -.tbl-checkbox { - text-align: center; -} - -.ngx-datatable.material { - background: #fff; - border: 1px solid #f5f5f5; - box-shadow: none !important; - - .datatable-footer { - .datatable-pager { - .pager li a { - margin: 5px; - - .datatable-icon-right, - .datatable-icon-skip, - .datatable-icon-left, - .datatable-icon-prev { - line-height: 30px; - } - } - - li.active a { - background-color: #0d8df3; - transition: 0.25s ease; - color: #ffffff; - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - } - } -} - -.ngx-table-form-select { - margin-top: 0px; - padding-left: 40px !important; -} - -.ngx-search { - margin: 15px auto !important; - width: 30% !important; - font-size: 13px !important; -} - -.ngx-datatable { - .datatable-body-cell { - display: table !important; - } - - .datatable-body-cell-label { - display: table-cell !important; - vertical-align: middle !important; - } - - .datatable-header-cell { - line-height: 2.4 !important; - } -} - -.ngxTableHeader { - padding: 10px 20px; - display: flex; - align-items: center; - border-color: #e6e9ed; - background-color: #ebebee; - min-width: 800px; - height: 70px; - - .header-buttons { - position: absolute; - right: 30px; - list-style: none; - margin-bottom: 0px; - - li { - display: inline-block; - } - - .material-icons { - color: #000000; - vertical-align: text-bottom; - } - } - - .header-buttons-left { - position: absolute; - list-style: none; - - li { - display: inline-block; - } - - .searchbox { - position: relative; - } - - ::placeholder { - color: rgba(0, 0, 0, 0.54); - } - - .search-icon { - position: absolute; - top: 10px; - padding-left: 10px; - color: rgba(0, 0, 0, 0.54); - } - - input.search-field { - font-weight: 500; - color: rgba(0, 0, 0, 0.54); - border-radius: 25px; - border: 0; - height: 45px; - padding: 8px 8px 8px 50px; - width: 250px; - background: #ffffff; - transition: background 0.2s, width 0.2s; - - &:hover { - background: #fffefe; - } - - &:focus { - outline: none; - width: 380px; - color: #212121; - - &:hover { - background: #f7f7f7; - } - } - } - } - - h2 { - margin: 0; - font-size: 16px; - font-weight: normal; - color: #5b626b; - } -} - -.mat-table { - .mat-header-cell { - font-size: 14px; - font-weight: 600; - } -} - -.ngx-datatable.material { - background: #fff; - border: 1px solid #f5f5f5; - box-shadow: none !important; - - .datatable-footer { - .datatable-pager { - .pager li a { - margin: 5px; - - .datatable-icon-right, - .datatable-icon-skip, - .datatable-icon-left, - .datatable-icon-prev { - line-height: 30px; - } - } - - li.active a { - background-color: #0d8df3; - transition: 0.25s ease; - color: #ffffff; - box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); - } - } - } -} - -.ngx-table-form-select { - margin-top: 0px; - padding-left: 40px !important; -} - -.ngx-search { - margin: 15px auto !important; - width: 30% !important; - font-size: 13px !important; -} - -.ngx-datatable { - .datatable-body-cell { - display: table !important; - } - - .datatable-body-cell-label { - display: table-cell !important; - vertical-align: middle !important; - } - - .datatable-header-cell { - line-height: 2.4 !important; - } -} - -.materialTableHeader { - -webkit-box-align: center; - align-items: center; - border-color: #dae1f3; - background-color: #dae1f3; - display: flex; - flex-wrap: wrap; - text-align: center; - // min-width: 800px; - - .left { - flex: 35%; - height: 60px; - display: table-cell; - vertical-align: middle; - text-align: center; - } - .center { - flex: 40%; - height: 60px; - display: table-cell; - vertical-align: middle; - text-align: left; - } - - .right { - flex: 10%; - height: 60px; - display: table-cell; - vertical-align: middle; - text-align: center; - } - - .tbl-export-btn { - float: right; - margin: 0px 15px; - list-style: none; - height: 100%; - display: flex; - align-items: center; - - li { - display: inline-block; - position: relative; - } - } - - .header-buttons-left { - list-style: none; - height: 100%; - display: flex; - align-items: center; - - .tbl-search-box { - position: relative; - margin-left: 10px; - } - .tbl-title { - vertical-align: middle; - margin-left: 20px; - - h2 { - font-weight: 500; - } - } - .tbl-header-btn { - position: relative; - } - - li { - display: inline-block; - } - - .searchbox { - position: relative; - } - - ::placeholder { - color: rgba(0, 0, 0, 0.54); - } - - .search-icon { - position: absolute; - top: 10px; - padding-left: 10px; - color: rgba(0, 0, 0, 0.54); - } - - input.search-field { - font-weight: 500; - color: rgba(0, 0, 0, 0.54); - border-radius: 5px; - border: 0; - height: 45px; - padding: 8px 8px 8px 50px; - width: 250px; - background: #ffffff; - - &:hover { - background: #fffefe; - } - - // &:focus { - // outline: none; - // width: 380px; - // color: #212121; - // &:hover { - // background: #f7f7f7; - // } - // } - } - } - - .header-buttons-right { - text-align: right; - list-style: none; - height: 100%; - margin: 0px 10px; - - .tbl-header-btn { - position: relative; - top: 12px; - } - - li { - display: inline-block; - } - - h2 { - margin: 0; - font-size: 16px; - font-weight: normal; - color: #5b626b; - } - } - - h2 { - margin: 0; - font-size: 16px; - font-weight: normal; - color: #5b626b; - } -} - -.tbl-checkbox label { - margin-bottom: 0px; -} -.column-nowrap { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.table-tab a { - background-color: #e2e2e2 !important; - color: #868788 !important; - border-radius: 30px; - &.active { - background-color: #7274e2 !important; - box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.2), 0 4px 13px -11px #7197b5; - color: #ffffff !important; - border-radius: 30px; - } -} -.app-list { - display: flex; - flex-direction: row; - align-items: center; - border-radius: 10px; - vertical-align: middle; - padding: 10px; - margin-bottom: 10px; - background: #f9f9f9; - img { - margin: 0px 10px; - } - .set-flex { - flex: 1; - } -} -.lecture-list { - display: flex; - flex-direction: row; - align-items: center; - border-radius: 5px; - vertical-align: middle; - padding: 10px; - margin-bottom: 10px; - background: #f6f4ff; -} -.report-list { - display: flex; - align-items: center; - margin-bottom: 20px; - padding: 12px 12px; - border: 1px dashed #bfc9d4; - border-radius: 6px; - .file-style { - font-size: 20px; - margin: 0px 10px; - } - .ms-auto { - margin-right: 10px; - cursor: pointer; - i { - padding-right: 10px; - } - } -} -.patient-group-list { - display: flex; - align-items: center; - padding: 12px 12px; - border-radius: 6px; - .lbl-bedge { - padding: 10px; - margin: 0px 5px; - border-radius: 50%; - position: relative; - display: inline-block; - width: 38px; - height: 38px; - font-size: 14px; - font-weight: 600; - letter-spacing: 1px; - .lbl-bedge-title { - color: #ffffff; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - } - } - - .group-details { - line-height: 38px; - padding-left: 10px; - font-weight: 500; - } -} -.tbl-spinner { - display: flex; - justify-content: center; - align-items: center; - margin-top: 20px; -} -.doc-file-type { - .d-flex { - margin-bottom: 15px; - padding-bottom: 15px; - border-bottom: 1px solid #d5dadb; - } - .img-icon { - width: 46px; - height: 46px; - line-height: 46px; - border-radius: 10%; - font-size: 23px; - text-align: center; - margin: 0px 15px; - } - .set-flex { - display: block; - color: #000; - height: 30px; - } - .ms-auto { - margin-right: 10px; - cursor: pointer; - } -} -.primary-rgba { - background-color: rgba(110, 129, 220, 0.1); -} -.success-rgba { - background-color: rgba(95, 194, 126, 0.1); -} -.danger-rgba { - background-color: rgba(244, 68, 85, 0.1); -} -.info-rgba { - background-color: rgba(114, 208, 251, 0.1); -} -.timetable-block { - border-radius: 4px; - border: 1px solid #f4f4f4; - padding: 10px; - margin-bottom: 20px; - box-shadow: 0 0.46875rem 2.1875rem rgba(90, 97, 105, 0.1), - 0 0.9375rem 1.40625rem rgba(90, 97, 105, 0.1), - 0 0.25rem 0.53125rem rgba(90, 97, 105, 0.12), - 0 0.125rem 0.1875rem rgba(90, 97, 105, 0.1); - background: #ffffff; -} -.medicine-list td { - padding: 0.4rem; -} -mat-cell > span.truncate-text { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} -.export-button { - cursor: pointer; - img { - height: 32px; - width: 32px; - } -} - -.mobile-label { - display: none; -} - -@media (max-width: 600px) { - .mobile-label { - width: 100px; - display: inline-block; - font-weight: bold; - } - - .mat-mdc-table .mdc-data-table__header-row { - display: none; - } - - .mat-mdc-table .mdc-data-table__row { - flex-direction: column; - align-items: start; - padding: 8px 24px; - } - mat-cell:first-of-type, - mat-header-cell:first-of-type, - mat-footer-cell:first-of-type { - padding-left: 10px; - } - .flex-item-right, - .flex-item-left { - flex: 100%; - } - .tbl-col-width-per-6 { - max-width: 100%; - } - .tbl-col-width-per-7 { - max-width: 100%; - } -} diff --git a/MyOffice.SPA/src/assets/scss/style.scss b/MyOffice.SPA/src/assets/scss/style.scss deleted file mode 100644 index 7cd7eee..0000000 --- a/MyOffice.SPA/src/assets/scss/style.scss +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Document : style.css - * Author : RedStar Template - * Description: This is a main style scss file for import all scss files. - * - * Structure (with shortcodes): - [1. Common ] - [2. Fonts ] - [3. Components ] - [4. Apps] - [5. Pages ] - [6. Pugins ] - [7. UI ] - [8. Browser ] - - -/* [1. Common ] */ - -/* Importing Bootstrap SCSS file. */ -@import "common/_variables"; -@import "common/_mixins"; -@import "common/_customanimate.scss"; -@import "common/_general.scss"; -@import "common/_demo.scss"; -@import "common/_helpers.scss"; -@import "common/_media.scss"; -@import "common/_animation.scss"; -@import "common/_rtl.scss"; - -/* [2. Fonts] */ -@import "fonts/fontawesome/fontawesome.scss"; -@import "fonts/fontawesome/regular.scss"; -@import "fonts/fontawesome/solid.scss"; -@import "fonts/fontawesome/brands.scss"; - -/* [3. Components ] */ -@import "components/_breadcrumbs.scss"; -@import "components/_checkboxradio.scss"; -@import "components/_dropdownmenu.scss"; -@import "components/_feed.scss"; -@import "components/_formcomponents.scss"; -@import "components/_infobox.scss"; -@import "components/_inputformgroup.scss"; -@import "components/_labels.scss"; -@import "components/_leftsidebaroverlay.scss"; -@import "components/_navbar"; -@import "components/_navtabs.scss"; -@import "components/_noticeboard.scss"; -@import "components/_rightsidebar.scss"; -@import "components/_searchbar.scss"; -@import "components/_switch.scss"; -@import "components/_thumbnails.scss"; -@import "components/_todo.scss"; -@import "components/_settingSidebar.scss"; - -/* [4. Apps] */ -@import "apps/_calendar.scss"; -@import "apps/_chat.scss"; -@import "apps/_contactlist.scss"; -@import "apps/_contactgrid.scss"; -@import "apps/_dragdrop.scss"; -@import "apps/_task.scss"; - -/* [5. Pages ] */ -@import "pages/_dashboard.scss"; -@import "pages/_inbox.scss"; -@import "pages/_pricing.scss"; -@import "pages/_profile.scss"; -@import "pages/_timeline.scss"; -@import "pages/_projects.scss"; -@import "pages/_auth.scss"; - -/* [6. Pugins ] */ -@import "plugins/_carousel.scss"; -@import "plugins/_charts.scss"; -@import "plugins/_formwizard.scss"; -@import "plugins/_imagegallery.scss"; -@import "plugins/_maps.scss"; -@import "plugins/_tables.scss"; - -/* [7. UI ] */ -@import "ui/_alerts.scss"; -@import "ui/_badgelistgroupitem.scss"; -@import "ui/_buttons.scss"; -@import "ui/_card.scss"; -@import "ui/_collapse.scss"; -@import "ui/_dialogs.scss"; -@import "ui/_expansion.scss"; -@import "ui/_mediaobject.scss"; -@import "ui/_modals.scss"; -@import "ui/_pageloader.scss"; -@import "ui/_pagination.scss"; -@import "ui/_panels.scss"; -@import "ui/_preloaders.scss"; -@import "ui/_progressbars.scss"; -@import "ui/_slider.scss"; -@import "ui/_snackbar.scss"; -@import "ui/_tabs.scss"; -@import "ui/_tooltippopovers.scss"; -@import "ui/_listItems.scss"; - -/* [8. Browser ] */ -@import "browser/_ie10.scss"; -@import "browser/_ie11.scss"; diff --git a/MyOffice.SPA/src/assets/scss/theme/_dark.scss b/MyOffice.SPA/src/assets/scss/theme/_dark.scss deleted file mode 100644 index 7481525..0000000 --- a/MyOffice.SPA/src/assets/scss/theme/_dark.scss +++ /dev/null @@ -1,1741 +0,0 @@ -/* - * Document : dark.scss - * Author : RedStar Template - * Description: This scss file for dark theme style classes - */ -.dark { - background-color: #232b3e; - color: #96a2b4; - padding-top: 1px; - - body, - html { - background-color: #232b3e; - } - - input { - color: #96a2b4 !important; - } - - .dark-font-col { - color: #96a2b4; - } - - .card { - --bs-card-bg: #1a202e; - --bs-card-color: #96a2b4; - --bs-card-border-color: rgba(255, 255, 255, 0.08); - background: #1a202e; - color: #96a2b4; - border: none; - box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); - - .body { - color: #96a2b4; - background: transparent; - } - - .header { - color: #96a2b4; - - h2 { - color: #96a2b4; - } - } - - .card-content { - color: #96a2b4; - } - - .card-statistic-3 { - .card-content { - color: #ffffff; - } - } - } - .card-bnner { - background: #1a202e; - } - - .course-card { - background: #1a202e; - - .bg-body-light { - background-color: #292c31; - } - } - - .plain-card { - background: #1a202e; - } - - .people-list { - .chat-list { - li { - &:hover { - background: #3f4650; - cursor: pointer; - } - - &.active { - background: #262b33; - } - } - } - } - - .chat { - .chat-history { - .message-data-time { - color: #96a2b4; - } - } - } - - .contact-usertitle-name { - color: #fff; - } - - .demo-skin { - color: #eaeaea; - - .form-check-label { - color: #eaeaea; - } - } - - .demo-settings { - color: #eaeaea; - } - - .block-header { - padding-bottom: 0px; - - h2 { - color: #96a2b4 !important; - } - } - - .select-wrapper { - input.select-dropdown { - color: #fff; - } - } - - .breadcrumb { - li { - &.active { - color: #a5abb1; - } - } - } - - .dropzone { - border: 1px solid #afacac !important; - background-color: #1a202e !important; - - .dz-message { - min-height: 150px !important; - background: #1a202e !important; - color: white; - } - } - - .sl-item { - .sl-content { - p { - color: #96a2b4; - } - } - } - - .info-box5 { - background-color: #1a202e; - } - - .form-check { - color: #96a2b4; - } - - label { - color: #96a2b4; - } - - .input-field { - input, - textarea { - color: #96a2b4; - } - } - - .input-group { - .input-group-addon { - .material-icons { - color: #96a2b4; - } - } - - input[type="text"], - .form-control { - color: #96a2b4; - } - } - - .container-login100 { - .form-group { - .form-control { - background: transparent; - } - } - } - - .form-group { - .form-control { - color: #96a2b4; - background: #1a202e; - } - - input.form-control { - color: #96a2b4; - border-bottom: 1px solid #9e9e9e; - } - } - - .form-check { - .form-check-sign { - .check { - border: 1px solid #96a2b4; - } - } - } - - .form-control { - color: #96a2b4; - background: #1a202e; - } - - .right-sidebar { - background: #1a202e; - } - - .ms-container { - .ms-selectable, - .ms-selection { - li.ms-hover { - color: #96a2b4 !important; - background-color: #46484e !important; - } - } - } - - .nav-tabs { - li { - a.active { - color: #fff !important; - } - } - } - - .bootstrap-tagsinput { - background-color: #343840 !important; - } - - .to-do-list { - li { - background: #1a202e; - } - } - - #mail-nav { - li { - a { - color: #96a2b4; - } - } - } - - .max-texts { - a { - color: #96a2b4; - } - } - - .pricingTable { - background: #0c0c0c; - - .pricingTable-header { - background: #36373c; - } - } - - .profile-tab-box { - background: #1a202e; - } - - .cd-timeline-content { - background: #10131c; - - .timelineLabelColor strong { - color: #ffffff !important; - } - } - - .timeline > li > .timeline-panel { - border: 1px solid #444444; - } - - .cd-timeline-content h2 { - color: #96a2b4; - } - - .chart-note { - color: #96a2b4; - } - - .chart-statis { - .index { - color: #96a2b4; - } - } - - .dataTables_wrapper { - input[type="search"] { - color: #96a2b4; - } - } - - .page-item.disabled .page-link { - color: #96a2b4; - pointer-events: none; - cursor: auto; - background-color: #1a202e; - } - - .table { - // Bootstrap 5 paints cell backgrounds via --bs-table-bg (defaults light). - --bs-table-bg: transparent; - --bs-table-color: #96a2b4; - --bs-table-striped-bg: rgba(255, 255, 255, 0.04); - --bs-table-hover-bg: rgba(255, 255, 255, 0.06); - --bs-table-border-color: rgba(255, 255, 255, 0.1); - --bs-table-striped-color: #96a2b4; - --bs-table-hover-color: #96a2b4; - background-color: transparent; - color: #96a2b4; - - > :not(caption) > * > * { - background-color: var(--bs-table-bg); - color: #96a2b4; - border-bottom-color: var(--bs-table-border-color); - box-shadow: none; - } - - tbody { - tr { - color: #96a2b4; - background-color: transparent; - - td, - th { - border-top: 1px solid rgb(21 24 29); - border-bottom: 1px solid rgba(255, 255, 255, 0.1); - background-color: transparent !important; - color: #96a2b4; - } - } - } - - thead { - tr { - color: #96a2b4; - - th { - border-bottom: 1px solid #15181d; - border-top: 1px solid #15181d; - background-color: #15181d !important; - color: #abaaaa; - } - } - } - } - - .table-bordered { - border: 1px solid rgba(120, 130, 140, 0.5); - - tbody { - tr { - td, - th { - border-right: 1px solid rgba(120, 130, 140, 0.5); - border-bottom: none; - } - } - } - - thead { - tr { - th { - border: 1px solid rgba(120, 130, 140, 0.5); - } - } - } - - th { - border: 1px solid rgba(120, 130, 140, 0.5); - color: #96a2b4; - } - } - - tr.group, - tr.group:hover { - background-color: #282d35 !important; - } - - .tableBody { - color: #96a2b4; - } - - $theme-black: #1a202e; - - .card .header h2 strong { - color: #96a2b4 !important; - } - - .breadcrumb-main { - .page-title { - color: #a5abb1; - } - .breadcrumb-icon .feather { - color: #a5abb1 !important; - } - .breadcrumb-item { - color: #a5abb1; - ::before { - color: #a5abb1; - } - } - } - - .counter-box, - .box-part { - background: #1a202e !important; - color: #96a2b4; - } - - .tblActnBtn i { - color: #96a2b4; - } - - .chat .chat-history { - .other-message { - background: #3b4453; - - &:after { - border-bottom-color: #3b4454; - } - } - - .message { - color: #96a2b4; - } - - .my-message { - background: #343840; - - &:after { - border-bottom-color: #343840; - } - } - } - - .task-box { - border-bottom: solid 1px #5e5e5f; - color: #96a2b4; - background: #141a27; - } - - .task-list { - border: solid 1px #10141d; - background: #141a27; - } - - .mat-drawer { - background-color: #141a27; - color: #96a2b4; - border-color: #121315 !important; - } - - .mat-drawer-container { - background-color: #1a202e; - } - - .taskbar .card-footer { - background: #1a202e !important; - } - - .move { - background: #1a202e; - } - - .board { - background-color: #1a202e; - - .drop-card { - background-color: #404754; - } - .list { - .header { - background: #10131c; - } - .project-title { - color: #96a2b4; - } - .project { - background: #10131c; - border: 1px solid #363b47; - } - } - } - - .list-group-item { - background: #1a202e; - } - - .product-grid .product-content { - background-color: #3b4453; - } - - .ibox-title, - .ibox-content { - background: #1a202e; - border-color: #6c757d; - } - - .collapsible-header { - background: #1a202e; - } - - .card .card-inside-title { - color: #96a2b4; - } - - .left-timeline > li { - &:nth-child(odd) { - .left-label { - background: #202529; - - &:after { - border-right-color: #202428; - } - } - - .left-time span:last-child { - color: #eee; - } - } - - .left-label { - background: #303438; - - p { - color: #96a2b4; - } - - &:after { - border-right-color: #303438; - } - } - - .empty span { - color: #96a2b4; - } - - .left-time span { - &:first-child { - color: #96a2b4; - } - - &:last-child { - color: #eae9e9; - } - } - } - - .font-icon .icon-preview i { - color: #96a2b4; - } - - .nav-tabs .nav-link.active, - .nav-tabs .nav-item.show .nav-link { - background-color: transparent; - } - - .panel-group { - .panel-primary .panel-title a { - color: #96a2b4; - background: #32363c; - } - - .panel .panel-body { - color: #96a2b4; - } - } - - .btn-outline-primary { - color: #96a2b4 !important; - border: 1px solid #96a2b4 !important; - } - - .chip { - background-color: #31353a; - color: #96a2b4; - } - - .dropdown-content { - background-color: #31353a; - - li > span { - color: #96a2b4; - } - } - - .autocomplete { - font-size: 13px !important; - color: #96a2b4; - caret-color: #fff; - - &:focus { - color: #96a2b4; - } - } - - .autocomplete-content li { - .highlight { - color: #fff; - } - - :hover { - background-color: #343d44; - } - } - - //select 2 - .select2-container--default { - .select2-selection--single { - background: #1a202e; - color: #96a2b4; - border-bottom: 1px solid #9e9e9e; - - .select2-selection__rendered { - background: #1a202e; - color: #96a2b4; - border-bottom: 1px solid #9e9e9e; - } - } - - .select2-selection--multiple { - background: #1a202e; - color: #96a2b4; - border-bottom: 1px solid #9e9e9e; - - .select2-selection__choice { - background-color: #444141; - border: 1px solid #656464; - } - } - - &.select2-container--focus .select2-selection--multiple { - background: #1a202e; - color: #96a2b4; - border-bottom: 1px solid #9e9e9e; - } - - .select2-results > .select2-results__options { - background-color: #282d35; - } - } - - .select2-search--dropdown { - background-color: #1c1f25; - } - - .flatpickr-input { - border-bottom: 1px solid #9e9e9e !important; - } - - .ngx-datatable.material { - background: #1a202e; - color: #96a2b4; - - .datatable-body .datatable-body-row .datatable-body-cell { - color: #96a2b4; - } - - .datatable-header-cell-label { - color: #96a2b4; - } - - :not(.cell-selection) .datatable-body-row:hover .datatable-row-group { - background-color: #1c1f25; - } - } - - .pagination > li > a:hover { - background-color: #fff; - color: #000; - } - - .dataTables_length .custom-select { - background-color: #1a202e; - color: white; - } - - .ngx-search { - color: #96a2b4; - } - - .ngx-datatable { - &.material { - background: #1a202e; - border: 1px solid #404755; - - .datatable-header { - .datatable-header-cell { - background: #1a202e; - } - - .resize-handle { - border-right: solid 1px #1a202e; - } - } - - .datatable-footer { - color: #fff; - - .datatable-pager { - a { - color: #fff; - } - - li.disabled a { - color: #fff !important; - } - } - } - - .datatable-body .datatable-body-row .datatable-body-cell { - color: #96a2b4; - } - - &:not(.cell-selection) .datatable-body-row:hover { - background: #32383e; - - .datatable-row-group { - background: #32383e; - } - } - - .datatable-body-cell, - .datatable-header-cell { - border: 1px solid #404755; - } - } - - &.fixed-header - .datatable-header - .datatable-header-inner - .datatable-header-cell { - color: #96a2b4; - } - } - - ::-webkit-input-placeholder { - color: #96a2b4; - opacity: 1 !important; - /* for older chrome versions. may no longer apply. */ - } - - :-moz-placeholder { - /* Firefox 18- */ - color: #96a2b4; - opacity: 1 !important; - } - - ::-moz-placeholder { - /* Firefox 19+ */ - color: #96a2b4; - opacity: 1 !important; - } - - :-ms-input-placeholder { - color: #96a2b4; - } - - input, - textarea { - color: #96a2b4; - } - - .flatPicker { - color: #96a2b4; - } - - .modal { - .modal-content { - background: #1a202e; - - .modal-body { - color: #96a2b4; - } - } - - .modal-close-button { - color: #96a2b4; - } - } - - .ngx-search { - color: #96a2b4; - } - - .ngx-datatable { - background: #434f5a; - border: 1px solid #343d45; - - &.material { - background: #1a202e; - - .datatable-header { - .datatable-header-cell { - background: #313742; - } - - .resize-handle { - border-right: solid 1px #434f5a; - } - } - - .datatable-footer { - color: #fff; - - .datatable-pager { - a { - color: #fff; - } - - li.disabled a { - color: #fff !important; - } - } - } - - .datatable-body .datatable-body-row .datatable-body-cell { - color: #96a2b4; - } - - &:not(.cell-selection) .datatable-body-row:hover { - background: #32383e; - - .datatable-row-group { - background: #32383e; - } - } - } - - &.fixed-header - .datatable-header - .datatable-header-inner - .datatable-header-cell { - color: #96a2b4; - } - } - - .ngxTableHeader { - background-color: #242931; - - .header-buttons-left strong, - .header-buttons { - color: #96a2b4; - - .material-icons { - color: #96a2b4; - } - - .dropdown-menu li span { - color: #000000; - } - } - .header-buttons-left { - input.search-field { - background-color: #000000; - } - .search-icon { - color: rgba(255, 255, 255, 0.55); - } - input.search-field:focus:hover { - background: #000000; - } - } - } - - .navbar-nav { - .dropdown-menu { - background-color: #1a202e; - border: 1px solid #292a2a; - - &::after { - border-bottom: 6px solid #10131c; - } - - .header { - color: #96a2b4; - border-bottom: 1px solid #232a31; - } - - ul.menu { - .menu-info .menu-title { - color: #fff; - } - - li a { - border-bottom: 1px solid #232a31; - - &:hover { - background-color: #141820; - } - } - .msg-unread { - background-color: #141820; - } - .menu-info .menu-desc { - color: rgb(255, 255, 255, 0.5); - .material-icons { - color: rgb(255, 255, 255, 0.5); - } - } - } - .nfc-read-more { - color: #96a2b4; - } - } - - .user_dw_menu li { - border-bottom: 1px solid #232a31; - - a { - color: #96a2b4; - } - } - } - .fc .fc-col-header-cell-cushion { - color: #fff; - } - - .fc-daygrid-day-top .fc-daygrid-day-number { - color: #96a2b4; - } - .fc-theme-standard .fc-scrollgrid { - border: 1px solid #5c5c5c; - } - .fc-view > table td { - color: #96a2b4; - } - .fc-unthemed td { - &.fc-today { - background: transparent; - } - - &.fc-day-top .fc-day-number { - color: #ffffff; - } - } - - .fc-button-primary { - background-color: #151414 !important; - border-color: #4a4a4a !important; - color: #fff !important; - } - - .fc-view > table { - td { - border-color: #65686d; - } - - th { - color: #fff; - border-color: #65686d; - } - } - - /* Material Design Form style */ - - .mat-checkbox-frame { - border-color: #96a2b4; - } - - .mat-radio-outer-circle { - border-color: #96a2b4; - } - - .mat-datepicker-content { - .mat-calendar-next-button { - color: #96a2b4; - } - - .mat-calendar-previous-button { - color: #96a2b4; - } - - .time-container { - background-color: #12161f; - } - - .actions { - background-color: #12161f; - - .mat-button-wrapper { - .material-icons { - color: white; - } - } - - .mat-stroked-button:not([disabled]) { - border-color: rgba(255, 255, 255, 0.37); - } - } - } - - .mat-datepicker-toggle { - color: #96a2b4; - } - - .mat-select-value { - color: #96a2b4; - } - - .mat-form-field-appearance-legacy { - .mat-hint { - color: #96a2b4; - } - - .mat-form-field-label { - color: #96a2b4; - } - - .mat-form-field-underline { - background-color: #96a2b4; - } - } - - .mat-form-field-appearance-outline { - .mat-form-field-outline-thick { - color: #b7b7b7; - } - - .mat-form-field-outline { - color: #96a2b4; - } - - &.mat-focused .mat-form-field-outline-thick { - color: #96a2b4; - } - } - - .mat-stepper-horizontal { - background-color: #1a202e; - } - - .mat-stepper-vertical { - background-color: #1a202e; - } - - .mat-horizontal-stepper-header::after { - border-top-color: rgba(255, 255, 255, 0.12); - } - - .mat-horizontal-stepper-header::before { - border-top-color: rgba(255, 255, 255, 0.12); - } - - .mat-stepper-horizontal-line { - border-top-color: rgba(255, 255, 255, 0.12); - } - - .mat-form-field-ripple { - background-color: #96a2b4; - } - - .mat-select-arrow { - color: #96a2b4; - } - - input { - caret-color: #96a2b4; - } - - .mat-input-element { - caret-color: #96a2b4; - } - - .mat-hint { - color: #96a2b4; - } - - .mat-mdc-table { - background: #1a202e; - } - - .mat-mdc-cell { - color: #96a2b4; - border-bottom-color: rgba(234, 229, 229, 0.12); - } - - .mat-mdc-footer-cell { - color: #96a2b4; - } - - .mat-mdc-header-cell { - color: #96a2b4; - border-bottom: 1px solid #2a3040; - border-top: 1px solid #2a3040; - background-color: #2a3040; - font-weight: 500; - } - - .mat-mdc-paginator { - color: #96a2b4; - background: #1a202e; - } - - .mat-form-field-type-mat-native-select .mat-form-field-infix::after { - color: #96a2b4; - } - - .mat-form-field.mat-focused .mat-form-field-label { - color: #96a2b4; - } - - .mat-form-field-appearance-fill { - .mat-form-field-flex { - background-color: rgba(0, 0, 0, 0.25); - } - - .mat-form-field-underline::before { - background-color: #96a2b4; - } - } - - .mat-step-header .mat-step-label.mat-step-label-active { - color: #96a2b4; - } - - .mat-paginator-page-size .mat-select-trigger { - color: #96a2b4; - } - - .mat-dialog-container { - background: #2d364a; - color: #c5cdd8; - border: 1px solid #4a5568; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55); - } - - .mat-expansion-panel { - background: #101217; - color: #96a2b4; - border-bottom: 1px solid #31384b; - } - - .mat-expansion-panel-header-title { - color: #96a2b4; - } - - .mat-expansion-panel-header-description { - color: #96a2b4; - } - - .mat-card, - .mat-mdc-card { - background: #12161f; - color: #96a2b4; - } - - .mat-card-subtitle, - .mat-mdc-card-subtitle { - color: #96a2b4; - } - - .mat-list-base .mat-list-option { - color: #96a2b4; - } - - .mat-list-base .mat-list-item { - color: #96a2b4; - } - - .list-group { - a.list-group-item { - color: #96a2b4; - } - - button.list-group-item { - color: #96a2b4; - } - - .list-group-item:hover { - background-color: rgba(10, 10, 10, 0.5); - } - } - - .mat-tab-label, - .mat-tab-link { - color: #96a2b4; - } - - .materialTableHeader { - background-color: #020910; - - h2 { - color: #96a2b4; - } - - ::placeholder { - /* Chrome, Firefox, Opera, Safari 10.1+ */ - color: #96a2b4; - opacity: 1; - /* Firefox */ - } - - :-ms-input-placeholder { - /* Internet Explorer 10-11 */ - color: #96a2b4; - } - - ::-ms-input-placeholder { - /* Microsoft Edge */ - color: #96a2b4; - } - - .header-buttons-left { - input.search-field { - background: #12161f; - color: #96a2b4; - } - - .search-icon { - color: #96a2b4; - } - } - } - - .mat-menu-panel { - background: #12161f; - } - - .mat-menu-item { - color: #96a2b4; - - .mat-icon { - color: #96a2b4; - } - } - - .mat-menu-item-submenu-trigger::after { - color: #96a2b4; - } - - // Angular Material 15+ / MDC: menu colors come from CSS variables on html. - // Overlay panels inherit from body.dark when dark theme is active. - --mat-menu-container-color: #12161f; - --mat-menu-item-label-text-color: #e0e6ed; - --mat-menu-item-icon-color: #e0e6ed; - --mat-menu-item-hover-state-layer-color: rgba(255, 255, 255, 0.08); - --mat-menu-item-focus-state-layer-color: rgba(255, 255, 255, 0.08); - --mat-menu-divider-color: rgba(255, 255, 255, 0.12); - - .mat-datepicker-content { - .mat-calendar { - background: #12161f; - color: #b8bbbd; - - .mat-calendar-body-cell-content { - color: #b8bbbd; - } - - .mat-calendar-table-header { - color: #b8bbbd; - } - - .mat-calendar-body-label { - color: #b8bbbd; - } - - .mat-calendar-body-today:not(.mat-calendar-body-selected) { - border-color: rgba(255, 255, 255, 0.32); - } - - .mat-calendar-arrow { - border-top-color: #b8bbbd; - } - } - } - - .mat-select-panel { - background: #12161f; - color: #b8bbbd; - - .mat-option { - color: #b8bbbd; - } - - .mat-option.mat-active { - color: #b8bbbd; - background: rgba(0, 0, 0, 0.4); - } - } - - .mat-pseudo-checkbox { - color: #b8bbbd; - } - - .mat-autocomplete-panel { - background: #12161f; - color: #b8bbbd; - - .mat-option-text { - color: #b8bbbd; - } - } - - .container-login100 { - background: #12161f; - } - - .login100-form { - background-color: #1a202e; - } - - .login100-form-title, - .error-header, - .error-subheader { - color: #ffffff; - } - - .txt1 { - color: #96a2b4; - } - - .apexcharts-legend-text { - color: #96a2b4 !important; - } - - .mat-button[disabled], - .mat-icon-button[disabled], - .mat-stroked-button[disabled], - .mat-flat-button[disabled], - .mat-raised-button[disabled], - .mat-fab[disabled], - .mat-mini-fab[disabled], - .mat-flat-button[disabled], - .mat-raised-button[disabled], - .mat-fab[disabled], - .mat-mini-fab[disabled], - .mat-flat-button[disabled], - .mat-raised-button[disabled], - .mat-fab[disabled], - .mat-mini-fab[disabled] { - color: rgba(255, 255, 255, 0.23); - } - - .mat-stroked-button:not([disabled]) { - border-color: rgba(255, 255, 255, 0.3); - } - - .mat-bottom-sheet-container { - background: #12161f; - } - - .mat-row { - border-bottom-color: rgba(255, 255, 255, 0.12); - } - // .material-icons-two-tone { - // filter: invert(99%) sepia(95%) saturate(4461%) hue-rotate(181deg) - // brightness(134%) contrast(83%); - // } - .appointment-tab-box { - background-color: #11141b; - } - .owl-dt-calendar-table { - .owl-dt-calendar-cell { - color: #96a2b4; - } - .owl-dt-calendar-header { - color: #96a2b4; - } - } - .owl-dt-container { - background: #11141b; - } - .owl-dt-calendar-control { - color: #ffffff; - } - .owl-dt-timer-content .owl-dt-timer-input { - border: 1px solid #717070; - background-color: #000000; - } - .owl-dt-container-buttons { - color: #ffffff; - } - .show-pwd-icon { - color: #96a2b4; - } - .mat-form-field-prefix, - .mat-form-field-suffix { - color: #96a2b4; - } - .app-list { - background: #181c27; - } - .lecture-list { - background: #181c27; - } - .media .media-body { - color: #96a2b4; - } - .auth-form-section { - background-color: #11141b; - } - .lang-item .lang-item-list { - color: #96a2b4; - &.active { - background-color: #10131c; - } - &:hover { - background-color: #171a21; - span.mdc-list-item__primary-text { - color: #ffffff; - } - } - } - .settingSidebar { - background: #1a202e; - .setting-panel-header { - color: #ffffff; - border: 1px solid #000000; - background: #000000; - } - .border-bottom { - border-bottom: 1px solid #3b434a !important; - } - } - .breadcrumb { - color: #96a2b4; - } - .breadcrumb-icon .feather { - color: #96a2b4; - } - .contact-details-field .color-icon { - filter: invert(68%) sepia(6%) saturate(787%) hue-rotate(177deg) - brightness(94%) contrast(86%); - } - .material-icons-two-tone { - filter: invert(68%) sepia(6%) saturate(787%) hue-rotate(177deg) - brightness(94%) contrast(86%); - } - .doc-file-type { - .d-flex { - border-bottom: 1px solid #15181d; - } - .set-flex { - color: #96a2b4; - } - } - .feed-element .well { - border: 1px solid #10131c; - background: #10131c; - } - .feed-activity-list .feed-element { - border-bottom: 1px solid #525252; - } - .project-activity { - border: 1px solid #525252; - margin-top: 20px; - } - .project-card-header { - color: #96a2b4; - } - .navbar-nav.navbar-right .user_profile span { - color: #fff; - } - - .mat-mdc-dialog-container { - .mdc-dialog__surface { - background: #2d364a; - color: #c5cdd8; - border: 1px solid #4a5568; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55); - } - .mdc-dialog__content { - background: #2d364a; - color: #c5cdd8 !important; - } - } - .mdc-text-field--outlined:not(.mdc-text-field--disabled) - .mdc-notched-outline__leading, - .mdc-text-field--outlined:not(.mdc-text-field--disabled) - .mdc-notched-outline__notch, - .mdc-text-field--outlined:not(.mdc-text-field--disabled) - .mdc-notched-outline__trailing { - border-color: rgba(255, 255, 255, 0.38); - } - - .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( - .mdc-text-field--focused - ):hover - .mdc-notched-outline - .mdc-notched-outline__leading, - .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( - .mdc-text-field--focused - ):hover - .mdc-notched-outline - .mdc-notched-outline__notch, - .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( - .mdc-text-field--focused - ):hover - .mdc-notched-outline - .mdc-notched-outline__trailing { - border-color: #96a2b4; - } - - .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( - .mdc-text-field--focused - ):hover - .mdc-notched-outline - .mdc-notched-outline__notch { - border-left: none; - } - .mat-mdc-dialog-container .mdc-dialog__title { - color: #e2e6ed; - } - .mat-button-toggle-appearance-standard { - color: #96a2b4; - background: #1d1d1d; - } - .mat-button-toggle-checked { - background: #000000 !important; - color: #96a2b4; - } - .mat-button-toggle-standalone.mat-button-toggle-appearance-standard, - .mat-button-toggle-group-appearance-standard { - border: solid 1px #4a4a4a; - } - .mat-button-toggle-group-appearance-standard - .mat-button-toggle - + .mat-button-toggle { - border: solid 1px #4a4a4a; - } - .mat-button-toggle-disabled .mat-button-toggle-button { - background-color: #565656; - color: white; - } - - .mdc-text-field:not(.mdc-text-field--disabled) .mdc-floating-label { - color: #96a2b4; - } - .mdc-text-field:not(.mdc-text-field--disabled) .mdc-text-field__input { - color: #96a2b4; - } - .mat-mdc-select-value { - color: #96a2b4; - } - .mdc-text-field--filled:not(.mdc-text-field--disabled) { - background-color: #181b24; - } - .mat-mdc-checkbox - .mdc-checkbox - .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate):not( - [data-indeterminate="true"] - ) - ~ .mdc-checkbox__background { - border-color: #96a2b4; - } - .mat-mdc-checkbox - .mdc-checkbox:hover - .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate):not( - [data-indeterminate="true"] - ) - ~ .mdc-checkbox__background { - border-color: #96a2b4; - } - - .mat-mdc-paginator-icon { - fill: #96a2b4; - } - .mat-mdc-radio-button - .mdc-radio - .mdc-radio__native-control:enabled:not(:checked) - + .mdc-radio__background - .mdc-radio__outer-circle { - border-color: #96a2b4; - } - .mat-mdc-select-arrow { - color: #96a2b4; - } - .mat-mdc-icon-button[disabled] .mat-mdc-paginator-icon { - fill: rgba(255, 255, 255, 0.15); - } - .mat-mdc-tab:not(.mat-mdc-tab-disabled) .mdc-tab__text-label { - color: #96a2b4; - } - - .mat-mdc-tab-group, - .mat-mdc-tab-header, - .mat-mdc-tab-body-wrapper, - .mat-mdc-tab-body-content, - .mat-mdc-tab-body.mat-mdc-tab-body-active { - background: #1a202e; - color: #96a2b4; - } - - .mat-mdc-tab-header { - border-bottom-color: rgba(255, 255, 255, 0.1); - } - - .mdc-tab-indicator__content--underline { - border-color: #2196f3; - } - .order-list li { - .badge { - background: rgb(12, 12, 12, 0.8); - } - img { - border: 2px solid #545454; - } - } - .mat-mdc-raised-button:disabled { - color: #7c7c7c; - } - - .nfc-menu { - .nfc-dropdown { - background-color: #1b1e27; - .menu { - button { - &:hover { - background-color: #10131c; - } - } - .msg-read { - background-color: #1b1e27; - border-bottom: 1px solid #5e5e5e; - } - .menu-info { - h4 { - color: #96a2b4; - } - .menu-title { - color: #96a2b4; - } - p { - color: rgba(255, 255, 255, 0.55); - } - .menu-desc { - color: rgba(255, 255, 255, 0.55); - .material-icons { - color: #979797; - } - } - } - .msg-unread { - background-color: #000000; - border-bottom: 1px solid #5e5e5e; - } - } - } - .nfc-footer { - background-color: #1b1e27; - border-top: 1px solid #363636; - .nfc-read-all { - color: rgb(181 181 181); - } - } - } - .user_dw_menu { - .mat-mdc-menu-item.mdc-list-item { - background-color: #1b1e27; - color: #e0e6ed; - - &:hover { - background-color: #10131c; - } - } - .mat-mdc-menu-item .mdc-list-item__primary-text { - color: #e0e6ed !important; - } - .user-menu-icons, - .user-menu-icons .feather { - color: #e0e6ed !important; - stroke: #e0e6ed; - } - } - .mat-mdc-select-panel-above .mdc-menu-surface.mat-mdc-select-panel { - background-color: #10131c; - } - .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple):not( - .mdc-list-item--disabled - ) { - background: rgb(0 0 0); - } - .mat-mdc-option.mat-mdc-option-active { - background: rgb(0 0 0); - } - .mat-mdc-option.mdc-list-item { - background-color: #10131c; - } - .mdc-menu-surface.mat-mdc-select-panel { - background-color: #10131c; - } - .mat-mdc-option:hover:not(.mdc-list-item--disabled) { - background: rgb(0 0 0); - } - .mat-mdc-option .mdc-list-item__primary-text { - color: #d5d5d5 !important; - } - .mat-mdc-menu-panel.mat-mdc-menu-panel { - background-color: var(--mat-menu-container-color, #10131c); - } - .mat-mdc-menu-item { - color: var(--mat-menu-item-label-text-color, #e0e6ed) !important; - } - .mat-mdc-menu-item .mdc-list-item__primary-text { - color: var(--mat-menu-item-label-text-color, #e0e6ed) !important; - } - .mat-mdc-menu-item[disabled] .mat-icon-no-color { - color: #d5d5d5; - } - .mat-mdc-menu-item .mat-icon { - color: var(--mat-menu-item-icon-color, #e0e6ed) !important; - } - .profile-menu { - .mat-mdc-menu-item, - .mat-mdc-menu-item .mdc-list-item__primary-text, - .user-menu-icons, - .user-menu-icons .feather { - color: #e0e6ed !important; - } - .user-menu-icons .feather { - stroke: #e0e6ed; - } - } - nav.navbar { - box-shadow: 0 -18px 1px 5px rgb(35 43 62); - } - .app-dropdown { - .app-icons:hover { - background-color: #000000; - } - p { - color: #d5d5d5; - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-black.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-black.scss deleted file mode 100644 index b7b27b4..0000000 --- a/MyOffice.SPA/src/assets/scss/theme/_theme-black.scss +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Document : theme-black.scss - * Author : RedStar Template - * Description: This scss file for black theme style classes - */ -@import "_theme-color-variables"; - -.theme-black { - .navbar { - background-color: transparent; - .icon-color { - color: #fff; - } - .navbar-nav.navbar-right .user_profile span { - color: #fff; - } - } - - .navbar.active { - background: #485563; - /* fallback for old browsers */ - background: -webkit-linear-gradient(to right, #1c212d, #1a202e); - /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient(to right, #1c212d, #1a202e); - - .nav { - > li { - > a { - color: #fff; - } - } - } - - .collapse-menu-icon .mat-icon { - color: #fff; - } - .collapse-menu-icon .feather { - color: #fff; - } - .nav-notification-icons .mat-icon { - color: #fff; - } - .nav-notification-icons .feather { - color: #fff; - } - } - - .navbar-brand { - color: $theme-black-navbar-brand; - - &:hover { - color: $theme-black-navbar-brand_hover; - } - - &:active { - color: $theme-black-navbar-brand_active; - } - - &:focus { - color: $theme-black-navbar-brand_focus; - } - } - - .nav { - > li { - > a { - &:hover { - background-color: $theme-black-nav-anchor_hover; - text-decoration: none; - } - - &:focus { - background-color: $theme-black-nav-anchor_focus; - text-decoration: none; - } - } - } - - .open { - > a { - background-color: $theme-black-nav-anchor-opened; - - &:hover { - background-color: $theme-black-nav-anchor-opened_hover; - } - - &:focus { - background-color: $theme-black-nav-anchor-opened_focus; - } - } - } - } - - .bars { - color: $theme-black-bar; - } - - .sidebar { - .menu { - .list { - li { - &.active { - background-color: $theme-black-menu-list-active; - } - - a { - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; - - i, - span { - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; - } - - &:hover { - color: $theme-black-sidebar-menu-hover; - // i, - // span { - // color: $theme-black-sidebar-menu-hover; - // } - } - } - } - - .ml-menu { - background-color: $theme-black-menu-list-submenu; - } - } - } - - .legal { - background-color: $theme-black-legal-bg; - - .copyright { - a { - color: $theme-black !important; - } - } - } - } - - .breadcrumb li a { - color: $theme-black !important; - } - - .page-item.active .page-link { - background-color: $theme-black; - border-color: $theme-black; - color: #ffffff; - border-radius: 50%; - box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); - } - - .btn-primary { - background-color: $theme-black-button-color !important; - color: #fff !important; - border-color: $theme-black !important; - - &:hover { - background-color: $theme-black !important; - color: #fff !important; - } - - &:active { - background-color: $theme-black !important; - color: #fff !important; - } - - &:focus { - background-color: $theme-black !important; - color: #fff !important; - } - - &:disabled { - background-color: $theme-black !important; - color: #fff !important; - } - } - - .btn-outline-primary { - background: 0 0 !important; - color: $theme-black !important; - border: 1px solid $theme-black !important; - - &:hover { - background: $theme-black !important; - color: #fff !important; - border: 1px solid $theme-black !important; - } - } - - .timelineLabelColor strong { - color: $theme-black !important; - } - - .top-sidebar { - .horizontal-menu { - li { - &.active { - > a { - color: $theme-black; - } - } - - a { - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; - - &:hover { - color: $theme-black; - } - } - } - } - } - - .nav-tabs > li > a:before { - border-bottom: 2px solid $theme-black; - } -} - -/*Logo Header Background Color*/ -.logo-black { - .navbar-header { - background-color: #1a202e; - border-right: 1px solid #323538; - } -} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-color-variables.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-color-variables.scss deleted file mode 100644 index 8c5a655..0000000 --- a/MyOffice.SPA/src/assets/scss/theme/_theme-color-variables.scss +++ /dev/null @@ -1,132 +0,0 @@ -//Theme white -$theme-white: #fff; -$theme-white-active-color: #00bcd4; -$theme-white-sidemenu-active-color: #ffffff; -$theme-white-legal-bg: #2c303b; -$theme-white-bar: #2c303b; -$theme-white-navbar-brand: #2c303b; -$theme-white-navbar-brand_active: #2c303b; -$theme-white-navbar-brand_hover: #2c303b; -$theme-white-navbar-brand_focus: #2c303b; -$theme-white-nav-anchor: #3a2c70; -$theme-white-nav-anchor_hover: rgba(0, 0, 0, 0); -$theme-white-nav-anchor_focus: rgba(0, 0, 0, 0); -$theme-white-nav-anchor-opened: rgba(0, 0, 0, 0); -$theme-white-nav-anchor-opened_hover: rgba(0, 0, 0, 0); -$theme-white-nav-anchor-opened_focus: rgba(0, 0, 0, 0); -$theme-white-menu-list-active: rgba(0, 0, 0, 0); -$theme-white-menu-list-toggled: rgba(0, 0, 0, 0); -$theme-white-menu-list-submenu: rgba(0, 0, 0, 0); -$theme-white-sidebar-menu-active: #5783c7; -$theme-white-sidebar-menu-hover: #5783c7; - -//Theme Black -$theme-black: #1a202e; -$theme-black-legal-bg: #fff; -$theme-black-bar: #fff; -$theme-black-button-color: #5783c7; -$theme-black-navbar-brand: #fff; -$theme-black-navbar-brand_active: #fff; -$theme-black-navbar-brand_hover: #fff; -$theme-black-navbar-brand_focus: #fff; -$theme-black-nav-anchor: #fff; -$theme-black-nav-anchor_hover: rgba(0, 0, 0, 0); -$theme-black-nav-anchor_focus: rgba(0, 0, 0, 0); -$theme-black-nav-anchor-opened: rgba(0, 0, 0, 0); -$theme-black-nav-anchor-opened_hover: rgba(0, 0, 0, 0); -$theme-black-nav-anchor-opened_focus: rgba(0, 0, 0, 0); -$theme-black-menu-list-active: rgba(0, 0, 0, 0); -$theme-black-menu-list-toggled: rgba(0, 0, 0, 0); -$theme-black-menu-list-submenu: rgba(0, 0, 0, 0); -$theme-black-sidebar-menu-active: #5783c7; -$theme-black-sidebar-menu-hover: #5783c7; - -//Theme Purple -$theme-purple: #909de4; -$theme-purple-legal-bg: #fff; -$theme-purple-bar: #fff; -$theme-purple-navbar-brand: #fff; -$theme-purple-navbar-brand_active: #fff; -$theme-purple-navbar-brand_hover: #fff; -$theme-purple-navbar-brand_focus: #fff; -$theme-purple-nav-anchor: #fff; -$theme-purple-nav-anchor_hover: rgba(0, 0, 0, 0); -$theme-purple-nav-anchor_focus: rgba(0, 0, 0, 0); -$theme-purple-nav-anchor-opened: rgba(0, 0, 0, 0); -$theme-purple-nav-anchor-opened_hover: rgba(0, 0, 0, 0); -$theme-purple-nav-anchor-opened_focus: rgba(0, 0, 0, 0); -$theme-purple-menu-list-active: rgba(0, 0, 0, 0); -$theme-purple-menu-list-toggled: rgba(0, 0, 0, 0); -$theme-purple-menu-list-submenu: rgba(0, 0, 0, 0); - -//Theme Blue -$theme-blue: #03a9f3; -$theme-blue-legal-bg: #fff; -$theme-blue-bar: #fff; -$theme-blue-navbar-brand: #fff; -$theme-blue-navbar-brand_active: #fff; -$theme-blue-navbar-brand_hover: #fff; -$theme-blue-navbar-brand_focus: #fff; -$theme-blue-nav-anchor: #fff; -$theme-blue-nav-anchor_hover: rgba(0, 0, 0, 0); -$theme-blue-nav-anchor_focus: rgba(0, 0, 0, 0); -$theme-blue-nav-anchor-opened: rgba(0, 0, 0, 0); -$theme-blue-nav-anchor-opened_hover: rgba(0, 0, 0, 0); -$theme-blue-nav-anchor-opened_focus: rgba(0, 0, 0, 0); -$theme-blue-menu-list-active: rgba(0, 0, 0, 0); -$theme-blue-menu-list-toggled: rgba(0, 0, 0, 0); -$theme-blue-menu-list-submenu: rgba(0, 0, 0, 0); - -//Theme Cyan -$theme-cyan: #01d8da; -$theme-cyan-legal-bg: #fff; -$theme-cyan-bar: #fff; -$theme-cyan-navbar-brand: #fff; -$theme-cyan-navbar-brand_active: #fff; -$theme-cyan-navbar-brand_hover: #fff; -$theme-cyan-navbar-brand_focus: #fff; -$theme-cyan-nav-anchor: #fff; -$theme-cyan-nav-anchor_hover: rgba(0, 0, 0, 0); -$theme-cyan-nav-anchor_focus: rgba(0, 0, 0, 0); -$theme-cyan-nav-anchor-opened: rgba(0, 0, 0, 0); -$theme-cyan-nav-anchor-opened_hover: rgba(0, 0, 0, 0); -$theme-cyan-nav-anchor-opened_focus: rgba(0, 0, 0, 0); -$theme-cyan-menu-list-active: rgba(0, 0, 0, 0); -$theme-cyan-menu-list-toggled: rgba(0, 0, 0, 0); -$theme-cyan-menu-list-submenu: rgba(0, 0, 0, 0); - -//Theme Green -$theme-green: #11a37d; -$theme-green-legal-bg: #fff; -$theme-green-bar: #fff; -$theme-green-navbar-brand: #fff; -$theme-green-navbar-brand_active: #fff; -$theme-green-navbar-brand_hover: #fff; -$theme-green-navbar-brand_focus: #fff; -$theme-green-nav-anchor: #fff; -$theme-green-nav-anchor_hover: rgba(0, 0, 0, 0); -$theme-green-nav-anchor_focus: rgba(0, 0, 0, 0); -$theme-green-nav-anchor-opened: rgba(0, 0, 0, 0); -$theme-green-nav-anchor-opened_hover: rgba(0, 0, 0, 0); -$theme-green-nav-anchor-opened_focus: rgba(0, 0, 0, 0); -$theme-green-menu-list-active: rgba(0, 0, 0, 0); -$theme-green-menu-list-toggled: rgba(0, 0, 0, 0); -$theme-green-menu-list-submenu: rgba(0, 0, 0, 0); - -//Theme Orange -$theme-orange: #f16735; -$theme-orange-legal-bg: #fff; -$theme-orange-bar: #fff; -$theme-orange-navbar-brand: #fff; -$theme-orange-navbar-brand_active: #fff; -$theme-orange-navbar-brand_hover: #fff; -$theme-orange-navbar-brand_focus: #fff; -$theme-orange-nav-anchor: #fff; -$theme-orange-nav-anchor_hover: rgba(0, 0, 0, 0); -$theme-orange-nav-anchor_focus: rgba(0, 0, 0, 0); -$theme-orange-nav-anchor-opened: rgba(0, 0, 0, 0); -$theme-orange-nav-anchor-opened_hover: rgba(0, 0, 0, 0); -$theme-orange-nav-anchor-opened_focus: rgba(0, 0, 0, 0); -$theme-orange-menu-list-active: rgba(0, 0, 0, 0); -$theme-orange-menu-list-toggled: rgba(0, 0, 0, 0); -$theme-orange-menu-list-submenu: rgba(0, 0, 0, 0); diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-white.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-white.scss deleted file mode 100644 index 4651044..0000000 --- a/MyOffice.SPA/src/assets/scss/theme/_theme-white.scss +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Document : theme-white.scss - * Author : RedStar Template - * Description: This scss file for white theme style classes - */ -@import "_theme-color-variables"; - -.theme-white { - .navbar { - background-color: transparent; - .header-icon .feather { - color: black; - } - } - .navbar-right .user_profile span { - color: rgb(0, 0, 0) !important; - } - .navbar.active { - background-color: $theme-white !important; - .nav { - > li { - > a { - color: #3a2c70; - } - } - } - .collapse-menu-icon .mat-icon { - color: #3a2c70; - } - .nav-notification-icons .mat-icon { - color: #3a2c70; - } - } - - .navbar-brand { - color: $theme-white-navbar-brand; - - &:hover { - color: $theme-white-navbar-brand_hover; - } - - &:active { - color: $theme-white-navbar-brand_active; - } - - &:focus { - color: $theme-white-navbar-brand_focus; - } - } - - .nav { - > li { - > a { - &:hover { - background-color: $theme-white-nav-anchor_hover; - text-decoration: none; - } - - &:focus { - background-color: $theme-white-nav-anchor_focus; - text-decoration: none; - } - } - } - - .open { - > a { - background-color: $theme-white-nav-anchor-opened; - - &:hover { - background-color: $theme-white-nav-anchor-opened_hover; - } - - &:focus { - background-color: $theme-white-nav-anchor-opened_focus; - } - } - } - } - - .bars { - color: $theme-white-bar; - } - - .sidebar { - .menu { - .list { - li { - &.active { - background-color: $theme-white-menu-list-active; - } - a { - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; - i, - span { - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; - } - } - } - - .ml-menu { - background-color: $theme-white-menu-list-submenu; - - // li.active a:not(.menu-toggle):before { - // content: "\f068"; - // font-family: "Font Awesome 5 Free"; - // font-size: 11px; - // display: block; - // width: 7px; - // height: 7px; - // position: absolute; - // left: 10%; - // font-weight: 900; - // } - } - } - } - - .legal { - background-color: $theme-white-legal-bg; - - .copyright { - a { - color: $theme-white !important; - } - } - } - } - - .breadcrumb li a { - color: $theme-white-active-color !important; - } - .page-item.active .page-link { - background-color: $theme-white-active-color; - border-color: $theme-white-active-color; - border-radius: 50%; - margin: 5px; - box-shadow: 0 4px 5px 0 #d4d8da, 0 1px 10px 0 #d4d8da, - 0 2px 4px -1px #d4d8da; - padding: 0px 12px; - min-width: 30px; - line-height: 30px; - color: #ffffff; - text-transform: uppercase; - } - - .btn-primary { - background-color: $theme-white-active-color !important; - color: #fff !important; - border-color: $theme-white-active-color !important; - &:hover { - background-color: $theme-white-active-color !important; - color: #fff !important; - } - &:active { - background-color: $theme-white-active-color !important; - color: #fff !important; - } - &:focus { - background-color: $theme-white-active-color !important; - color: #fff !important; - } - &:disabled { - background-color: $theme-white-active-color !important; - color: #fff !important; - } - } - .btn-outline-primary { - background: 0 0 !important; - color: $theme-white-bar !important; - border: 1px solid $theme-white-active-color !important; - &:hover { - background: $theme-white-active-color !important; - color: #fff !important; - border: 1px solid $theme-white !important; - } - } - .timelineLabelColor strong { - color: $theme-white-active-color !important; - } - .top-sidebar { - .horizontal-menu { - li { - &.active { - > a { - color: $theme-white-active-color; - } - } - a { - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; - &:hover { - color: $theme-white-active-color; - } - } - } - } - } - .demo-choose-skin li.actived:after { - color: #000; - } - - .nav-tabs > li > a:before { - border-bottom: 2px solid $theme-white-active-color; - } - .search-box input#search { - color: gray; - background: #edecec; - } - .settingSidebar ul.choose-theme li.active div::after { - color: #000; - } -} -/*Logo Header Background Color*/ -.logo-white { - .navbar-header { - background-color: $theme-white; - - .logo-name { - color: #000; - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/theme/all-themes.scss b/MyOffice.SPA/src/assets/scss/theme/all-themes.scss deleted file mode 100644 index bd016b3..0000000 --- a/MyOffice.SPA/src/assets/scss/theme/all-themes.scss +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Light / dark RedStar skins only (Phase 3.6 — color skins removed). - */ - -@import "theme-black"; -@import "theme-white"; -@import "dark"; diff --git a/MyOffice.SPA/src/assets/scss/ui/_alerts.scss b/MyOffice.SPA/src/assets/scss/ui/_alerts.scss deleted file mode 100644 index 96edb3e..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_alerts.scss +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Document : alert.scss - * Author : RedStar Template - * Description: This scss file for alert style classes - */ -.alert { - @include border-radius(0); - @include box-shadow(none); - border: none; - color: #fff !important; - - .alert-link { - color: #fff; - text-decoration: underline; - font-weight: bold; - } -} - -.alert-success { - background-color: rgba(24, 206, 15, 0.8); -} - -.alert-info { - background-color: rgba(44, 168, 255, 0.8); -} - -.alert-warning { - background-color: rgba(255, 178, 54, 0.8); -} - -.alert-danger { - background-color: rgba(255, 54, 54, 0.8); -} - -.alert-dismissible { - .close { - color: #fff; - opacity: 1; - border: none; - text-shadow: none; - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_badgelistgroupitem.scss b/MyOffice.SPA/src/assets/scss/ui/_badgelistgroupitem.scss deleted file mode 100644 index 10db563..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_badgelistgroupitem.scss +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Document : badgelistgroupitem.scss - * Author : RedStar Template - * Description: This scss file for badge style classes - */ -.badge { - padding: 5px 8px; - line-height: 12px; - border: 1px solid; - font-weight: 400; - font-size: 13px; -} - -.list-group-item { - @include border-radius(0); - @include transition(0.5s); -} - -.list-group { - .active, - .list-group-item.active { - background-color: #2196f3; - border-color: #2196f3; - - &:hover, - &:focus, - &:active { - background-color: #2196f3; - border-color: #2196f3; - } - - .list-group-item-text { - color: #dfe9f1; - font-size: 13px; - - &:hover, - &:active, - &:focus { - color: #dfe9f1; - } - } - } - a, - button { - &.list-group-item { - color: #555; - } - &.list-group-item.active { - color: #dfe9f1; - } - } - - .list-group-item.active { - &:hover, - &:focus, - &:active { - .list-group-item-text { - color: #dfe9f1; - } - } - } - - .list-group-item { - &:first-child, - &:last-child { - @include border-radius(0); - } - - .list-group-item-heading { - font-weight: bold; - font-size: 17px; - } - text-align: left; - &:focus, - &:hover { - background-color: #f5f5f5; - } - } - - .list-group-item-success { - background-color: #2b982b; - border: none; - color: #fff; - - &:hover, - &:focus { - background-color: #2b982b; - color: #fff; - opacity: 0.8; - } - } - - .list-group-item-info { - background-color: #00b0e4; - border: none; - color: #fff; - - &:hover, - &:focus { - background-color: #00b0e4; - color: #fff; - opacity: 0.8; - } - } - - .list-group-item-warning { - background-color: #ff9600; - border: none; - color: #fff; - - &:hover, - &:focus { - background-color: #ff9600; - color: #fff; - opacity: 0.8; - } - } - - .list-group-item-danger { - background-color: #fb483a; - border: none; - color: #fff; - - &:hover, - &:focus { - background-color: #fb483a; - color: #fff; - opacity: 0.8; - } - } - - @each $key, $val in $colors { - .pl-#{$key} { - stroke: $val; - } - - .list-group-bg-#{$key} { - background-color: $val; - border: none; - color: #fff; - - &:hover, - &:focus { - background-color: $val; - color: #fff; - opacity: 0.8; - } - } - } -} -span.badge { - min-width: auto; - float: none; - font-size: 13px; -} -.list-group span.badge { - float: right; -} -.btn-success .badge { - color: #5cb85c; - background-color: #fff; -} -.btn-primary .badge { - color: #337ab7; - background-color: #fff; -} -.btn-danger .badge { - color: #d9534f; - background-color: #fff; -} -.btn-warning .badge { - color: #f0ad4e; - background-color: #fff; -} -.badge-solid-red { - color: #f11541; - background-color: rgba(241, 21, 65, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} -.badge-solid-purple { - color: #6f42c1; - background-color: rgba(111, 66, 193, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} -.badge-solid-green { - color: #198754; - background-color: rgba(25, 135, 84, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} -.badge-solid-blue { - color: #0d6efd; - background-color: rgba(13, 110, 253, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} -.badge-solid-pink { - color: #fd0dfd; - background-color: rgba(253, 13, 253, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} -.badge-solid-orange { - color: #fd7e14; - background-color: rgba(253, 126, 20, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} -.badge-solid-cyan { - color: #0dcaf0; - background-color: rgba(13, 202, 240, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} -.badge-solid-brown { - color: #964b00; - background-color: rgba(150, 75, 0, 0.15); - border: none; - padding: 5px 12px; - font-weight: 500; - line-height: 1.2; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_buttons.scss b/MyOffice.SPA/src/assets/scss/ui/_buttons.scss deleted file mode 100644 index 40d73d4..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_buttons.scss +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Document : _buttons.scss - * Author : RedStar Template - * Description: This scss file for button style classes - */ -.example-button-row button, -.example-button-row a { - margin-right: 8px; -} - -.btn:focus, -.btn.focus { - box-shadow: none; -} - -.btn-space { - margin-right: 10px !important; -} - -/* Dialog Cancel: readable on dark surfaces, secondary to Save */ -.dialog-btn-cancel.mat-mdc-unelevated-button, -.dialog-btn-cancel.mat-mdc-button, -.dialog-btn-cancel { - background-color: #5a6578 !important; - color: rgba(255, 255, 255, 0.5) !important; - --mdc-filled-button-container-color: #5a6578; - --mdc-filled-button-label-text-color: rgba(255, 255, 255, 0.5); - --mdc-text-button-label-text-color: rgba(255, 255, 255, 0.5); - - .mdc-button__label { - color: rgba(255, 255, 255, 0.5) !important; - } - - &:hover { - background-color: #6b7689 !important; - --mdc-filled-button-container-color: #6b7689; - } -} - -.big-button { - width: 200px !important; - min-width: unset !important; - height: 45px; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_card.scss b/MyOffice.SPA/src/assets/scss/ui/_card.scss deleted file mode 100644 index f5fb0be..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_card.scss +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Document : _card.scss - * Author : RedStar Template - * Description: This scss file for card style classes - */ -.card { - background: #fff; - min-height: 50px; - position: relative; - margin-bottom: 24px; - border: 1px solid #f2f4f9; - border-radius: 10px; - box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); - -webkit-box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); - - .card-inside-title { - margin-top: 25px; - margin-bottom: 15px; - display: block; - font-size: 15px; - color: #000; - - small { - color: #999; - display: block; - font-size: 11px; - margin-top: 5px; - - a { - color: #777; - font-weight: bold; - } - } - } - - .card-inside-title:first-child { - margin-top: 0; - } - - .bg-red, - .bg-pink, - .bg-purple, - .bg-indigo, - .bg-blue, - .bg-cyan, - .bg-teal, - .bg-green, - .bg-yellow, - .bg-orange, - .bg-deep-orange, - .bg-brown, - .bg-grey, - .bg-black { - border-bottom: none !important; - color: #fff !important; - - h2, - small, - .material-icons { - color: #fff !important; - } - - .badge { - background-color: #fff; - color: #555; - } - } - - .header { - position: relative; - display: flex; - width: 100%; - color: #555; - padding: 10px 15px; - line-height: 30px; - border-bottom: 1px solid; - border-color: rgba(82, 63, 105, 0.06); - - .header-dropdown { - position: absolute; - top: 0px; - right: 0px; - list-style: none; - - .dropdown-menu { - li { - display: block !important; - } - } - - li { - display: inline-block; - } - - i { - font-size: 20px; - color: #999; - @include transition(all 0.5s); - - &:hover { - color: #000; - } - } - } - - h2 { - margin: 0; - color: #5b626b; - font-size: 17px; - line-height: 28px; - padding-right: 10px; - font-weight: 500; - - small { - display: block; - font-size: 12px; - margin-top: 5px; - color: #999; - line-height: 15px; - - a { - font-weight: bold; - color: #777; - } - } - } - - .col-xs-12 { - h2 { - margin-top: 5px; - } - } - } - - .body { - font-size: 14px; - color: #555; - padding: 15px; - - @for $i from 1 through 12 { - .col-xs-#{$i}, - .col-sm-#{$i}, - .col-md-#{$i}, - .col-lg-#{$i} { - margin-bottom: 20px; - } - } - } - .list-body { - padding: 0px 10px; - } - &.card-statistic-1 .card-header, - &.card-statistic-2 .card-header { - border-color: transparent; - padding-bottom: 0; - height: auto; - min-height: auto; - display: block; - } - - &.card-statistic-1 .card-icon { - width: 30px; - height: 30px; - margin: 10px 0px 0px 20px; - border-radius: 3px; - line-height: 78px; - text-align: center; - float: left; - font-size: 30px; - } - - &.card-statistic-1 .card-header h4, - &.card-statistic-2 .card-header h4 { - line-height: 1.2; - color: color(muted); - } - - &.card-statistic-1 .card-body, - &.card-statistic-2 .card-body { - padding-top: 0; - } - - &.card-statistic-1 .card-body, - &.card-statistic-2 .card-body { - font-size: 26px; - font-weight: 700; - color: color(fontdark); - padding-bottom: 0; - } - - &.card-statistic-1, - &.card-statistic-2 { - display: inline-block; - width: 100%; - } - - &.card-statistic-1 .card-icon, - &.card-statistic-2 .card-icon { - width: 80px; - height: 80px; - margin: 10px; - border-radius: 3px; - line-height: 94px; - text-align: center; - float: left; - border-radius: 50px; - margin-right: 15px; - - .ion, - .fas, - .far, - .fab, - .fal { - font-size: 22px; - color: #fff; - } - } - - &.card-statistic-1 .card-icon { - line-height: 90px; - } - - &.card-statistic-2 .card-icon { - width: 50px; - height: 50px; - line-height: 50px; - font-size: 22px; - margin: 25px; - box-shadow: 5px 3px 10px 0 rgba(21, 15, 15, 0.3); - border-radius: 10px; - background: #6777ef; - } - &.card-statistic-2 .card-icon-only { - font-size: 35px; - margin: 20px; - } - - &.card-statistic-1 .card-header, - &.card-statistic-2 .card-header { - padding-bottom: 0; - padding-top: 25px; - } - - &.card-statistic-2 .card-header + .card-body, - &.card-statistic-2 .card-body + .card-header { - padding-top: 0; - } - - &.card-statistic-1 .card-header h4, - &.card-statistic-2 .card-header h4 { - font-weight: 600; - font-size: 13px; - letter-spacing: 0.5px; - } - - &.card-statistic-1 .card-header h4 { - margin-bottom: 0; - } - - &.card-statistic-2 .card-header h4 { - text-transform: none; - margin-bottom: 0; - } - - &.card-statistic-1 .card-body { - font-size: 20px; - } - - &.card-statistic-2 { - .card-chart { - margin-left: -10px; - margin-right: -1px; - margin-bottom: -7px; - - canvas { - height: 70px !important; - } - } - .card-right { - float: right; - margin: 15px 15px 15px 0px; - } - } -} -.plain-card { - box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1); - padding: 20px; - border-radius: 10px; - background: #fff; - overflow: hidden; - margin: 0.5rem 0 1rem 0; -} -.card-inner .progress { - height: 10px; - margin: 0px; -} -.col-block { - margin-left: 5px; -} -.card-height-100 { - height: 100px; -} -.doc-card-title { - color: #00bdf2; - font-size: 16px; -} -.doc-card-image { - background: #fff; - position: inherit; - padding: 2px; - box-shadow: 0 5px 25px 0 rgba(0, 0, 0, 0.2); -} -.card-spacing { - padding-right: 0px; -} -.card-bnner { - background: white; - padding: 15px; - border-radius: 10px; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_ckeditor.scss b/MyOffice.SPA/src/assets/scss/ui/_ckeditor.scss deleted file mode 100644 index 2aa06c8..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_ckeditor.scss +++ /dev/null @@ -1,18 +0,0 @@ -.ck.ck-content ul, -.ck.ck-content ul li { - list-style-type: inherit; -} - -.ck.ck-content ul { - /* Default user agent stylesheet, you can change it to your needs. */ - padding-left: 40px; -} -.ck.ck-content ol, -.ck.ck-content ol li { - list-style-type: decimal; -} - -.ck.ck-content ol { - /* Default user agent stylesheet, you can change it to your needs. */ - padding-left: 40px; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_collapse.scss b/MyOffice.SPA/src/assets/scss/ui/_collapse.scss deleted file mode 100644 index 3de6549..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_collapse.scss +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Document : _collapse.scss - * Author : RedStar Template - * Description: This scss file for collapse style classes - */ -.collapse, -.collapse.in, -.collapsing { - .well { - @include border-radius(0); - margin-bottom: 0; - } - &.show { - display: block; - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_dialogs.scss b/MyOffice.SPA/src/assets/scss/ui/_dialogs.scss deleted file mode 100644 index 06d4c71..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_dialogs.scss +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Document : _dialogs.scss - * Author : RedStar Template - * Description: This scss file for dialogs style classes - */ -.sweet-alert { - @include border-radius(0 !important); - - p { - font-size: 14px !important; - } - - .sa-input-error { - top: 23px !important; - right: 13px !important; - } - - h2 { - font-size: 18px !important; - margin: 0 0 5px 0 !important; - line-height: 40px; - } - - button { - font-size: 15px !important; - @include border-radius(0 !important); - padding: 5px 20px !important; - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_expansion.scss b/MyOffice.SPA/src/assets/scss/ui/_expansion.scss deleted file mode 100644 index cc8000b..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_expansion.scss +++ /dev/null @@ -1,13 +0,0 @@ -.main-headers-align .mat-expansion-panel-header-title, -.main-headers-align .mat-expansion-panel-header-description { - flex-basis: 0; -} - -.main-headers-align .mat-expansion-panel-header-description { - justify-content: space-between; - align-items: center; -} - -.main-headers-align .mat-form-field + .mat-form-field { - margin-left: 8px; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_listItems.scss b/MyOffice.SPA/src/assets/scss/ui/_listItems.scss deleted file mode 100644 index aaa37bc..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_listItems.scss +++ /dev/null @@ -1,26 +0,0 @@ -.icon-box { - position: relative; - line-height: 1; - padding: 8px; - border-radius: 5px; -} -.icon-box-orange { - background-color: #ffe3db; -} -.icon-box-green { - background-color: #e1fbe2; -} -.icon-box-purple { - background-color: #dfceff; -} -.icon-box-blue { - background-color: #cbe8ff; -} -.icon-box-red { - background-color: #ffe5e4; -} -.amount-section { - .material-icons { - font-size: 10px; - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_mediaobject.scss b/MyOffice.SPA/src/assets/scss/ui/_mediaobject.scss deleted file mode 100644 index f416071..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_mediaobject.scss +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Document : _mediaobject.scss - * Author : RedStar Template - * Description: This scss file for media object style classes - */ -.media { - margin-bottom: 25px; - margin-top: 15px; - - .media-left { - padding-right: 10px; - } - .media-body { - color: #777; - font-size: 13px; - - .media-heading { - font-size: 16px; - font-weight: bold; - color: #333; - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_modals.scss b/MyOffice.SPA/src/assets/scss/ui/_modals.scss deleted file mode 100644 index 6e9d8ed..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_modals.scss +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Document : _modals.scss - * Author : RedStar Template - * Description: This scss file for modals style classes - */ -.modal { - background-color: rgba(238, 238, 238, 0.41); - //padding: 100px 0 0; - max-height: 100%; - width: 100%; - .modal-header { - border: none; - padding: 0px; - border-bottom: 1px solid #eee; - - .modal-title { - font-weight: bold; - font-size: 16px; - } - } - - .modal-content { - border-radius: 10px; - box-shadow: 0 5px 20px rgba(0, 0, 0, 0.31) !important; - border: none; - padding: 10px; - - .modal-body { - color: #777; - padding: 15px 25px; - } - } - - .modal-footer { - border: none; - background-color: transparent; - .btn { - margin: 10px; - } - } -} -.addContainer { - display: flex; - flex-direction: column; - overflow: hidden; - .form { - display: flex; - padding-top: 6px; - } - - .mat-form-field { - flex-grow: 1; - } - .modalHeader img { - border-radius: 50%; - } -} - -.modalHeader { - display: flex; - align-items: flex-start; - // justify-content: space-between; - padding: 0px 10px 0px 10px; - margin: 10px 10px 0px 10px; - .modal-about { - padding: 5px; - font-weight: 500; - font-size: 16px; - } -} -.modal-close-button { - background-color: transparent !important; - box-shadow: none !important; - color: #161d38; - right: 10px; - position: absolute !important; -} - -@each $key, $val in $colors { - .modal-col-#{$key} { - background-color: $val; - - .modal-body, - .modal-title { - color: #fff !important; - } - - .modal-footer { - background-color: rgba(0, 0, 0, 0.12); - - .btn-link { - color: #fff !important; - - &:hover, - &:active, - &:focus { - background-color: rgba(0, 0, 0, 0.12); - } - } - } - } -} -.cdk-overlay-connected-position-bounding-box { - z-index: 1052 !important; -} -.mat-dialog-content { - margin: 0px !important; - padding: 0px !important; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_pageloader.scss b/MyOffice.SPA/src/assets/scss/ui/_pageloader.scss deleted file mode 100644 index 0246382..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_pageloader.scss +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Document : _pageloader.scss - * Author : RedStar Template - * Description: This scss file for page loader style classes - */ -.page-loader-wrapper { - z-index: 99999999; - position: fixed; - top: 0; - left: 0; - bottom: 0; - right: 0; - width: 100%; - height: 100%; - background: #eee; - overflow: hidden; - text-align: center; - - p { - font-size: 13px; - margin-top: 10px; - font-weight: bold; - color: #444; - } - - .loader { - position: relative; - // top: calc(50% - 30px); - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_pagination.scss b/MyOffice.SPA/src/assets/scss/ui/_pagination.scss deleted file mode 100644 index d07c9a2..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_pagination.scss +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Document : _pagination.scss - * Author : RedStar Template - * Description: This scss file for pagination style classes - */ -.pager { - padding-left: 0; - margin: 20px 0; - text-align: center; - list-style: none; - - li { - display: inline; - - > a { - @include border-radius(0); - border: none; - background-color: transparent; - color: #222; - font-weight: bold; - display: inline-block; - padding: 5px 14px; - } - - a:focus, - a:active { - background-color: transparent; - } - } - .previous { - > a, - > span { - float: left; - } - } - .next { - > a, - > span { - float: right; - } - } -} - -.pagination { - margin: 20px 0; - - .disabled { - a, - a:hover, - a:focus, - a:active { - color: #bbb; - } - } - - li.active { - background-color: transparent !important; - a { - background-color: #ffc107; - border-color: #ffc107; - color: #ffffff; - border-radius: 50%; - box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); - } - } - - li { - @include border-radius(0); - - // a:focus, - // a:active { - // background-color: transparent; - // color: #555; - // } - } - - > li { - > a { - border: none; - font-weight: bold; - color: #555; - font-size: 14px; - margin: 0px 3px; - color: gray; - margin: 5px; - border-radius: 50%; - color: gray; - min-width: 30px; - text-transform: uppercase; - padding: 0.5rem 0.75rem; - line-height: 1.25; - } - } - > li { - > a:hover { - font-weight: bold; - background-color: transparent; - color: #8c8b8b; - border-radius: 50%; - font-size: 14px; - } - } - - > li:first-child, - > li:last-child { - > a { - width: auto; - height: 32px; - @include border-radius(0); - - .material-icons { - position: relative; - bottom: 0px; - } - } - } -} - -.pagination-sm { - > li:first-child, - > li:last-child { - > a { - width: 28px; - height: 28px; - - .material-icons { - position: relative; - top: 4px; - left: -6px; - font-size: 20px; - } - } - } - > li > a, - > li > span { - padding: 5px 10px; - font-size: 12px; - } -} - -.pagination-lg { - > li:first-child, - > li:last-child { - > a { - width: 44px; - height: 44px; - - .material-icons { - font-size: 30px; - position: relative; - top: 0px; - left: -10px; - } - } - } - > li > a, - > li > span { - padding: 10px 16px; - font-size: 18px; - } -} -.page-link:focus, -.page-link:hover { - color: #65686b; - text-decoration: none; - background-color: #e3eaf1; - border-color: #e3eaf1; - border-radius: 50%; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_panels.scss b/MyOffice.SPA/src/assets/scss/ui/_panels.scss deleted file mode 100644 index 8ecbc63..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_panels.scss +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Document : _panels.scss - * Author : RedStar Template - * Description: This scss file for panels style classes - */ -.panel-group { - @each $key, $val in $colors { - .panel-col-#{$key} { - border: 1px solid $val; - - .panel-title { - background-color: $val !important; - color: #fff; - } - - .panel-body { - border-top-color: transparent !important; - } - } - } - - .panel { - @include border-radius(0); - margin-top: 5px; - - .panel-title { - margin-bottom: 0; - font-size: 16px; - .material-icons { - float: left; - line-height: 16px; - margin-right: 8px; - } - > a, - > small, - > .small, - > small > a, - > .small > a { - color: #fff; - } - } - - .panel-heading { - padding: 0; - @include border-radius(0); - - a { - display: block; - padding: 10px 15px; - - &:hover, - &:focus, - &:active { - text-decoration: none; - } - } - } - - .panel-body { - color: #555; - border-top: 1px solid #ddd; - padding: 15px; - } - } - - .panel-primary { - border: none; - - .panel-title { - background-color: #f5f5f5; - a { - color: #757575; - font-weight: 400; - font-size: 16px; - } - } - } - - .panel-success { - border: 1px solid #2b982b; - - .panel-title { - background-color: #2b982b; - color: #fff; - } - } - - .panel-warning { - border: 1px solid #ff9600; - - .panel-title { - background-color: #ff9600; - color: #fff; - } - } - - .panel-danger { - border: 1px solid #fb483a; - - .panel-title { - background-color: #fb483a; - color: #fff; - } - } -} - -.full-body { - @each $key, $val in $colors { - .panel-col-#{$key} { - .panel-body { - border-top-color: #fff !important; - background-color: $val; - color: #fff; - } - } - } - - .panel-primary { - .panel-body { - border-top-color: #fff !important; - background-color: #7861a9; - color: #fff; - } - } - - .panel-success { - .panel-body { - border-top-color: #fff !important; - background-color: #2b982b; - color: #fff; - } - } - - .panel-warning { - .panel-body { - border-top-color: #fff !important; - background-color: #ff9600; - color: #fff; - } - } - - .panel-danger { - .panel-body { - border-top-color: #fff !important; - background-color: #fb483a; - color: #fff; - } - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_preloaders.scss b/MyOffice.SPA/src/assets/scss/ui/_preloaders.scss deleted file mode 100644 index 7a850c8..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_preloaders.scss +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Document : _preloaders.scss - * Author : RedStar Template - * Description: This scss file for preloaders style classes - */ -.md-preloader { - @each $key, $val in $colors { - .pl-#{$key} { - stroke: $val; - } - } -} - -.preloader { - display: inline-block; - position: relative; - width: 50px; - height: 50px; - -webkit-animation: container-rotate 1568ms linear infinite; - -moz-animation: container-rotate 1568ms linear infinite; - -o-animation: container-rotate 1568ms linear infinite; - animation: container-rotate 1568ms linear infinite; - - &.pl-size-xl { - width: 75px; - height: 75px; - } - - &.pl-size-l { - width: 60px; - height: 60px; - } - - &.pl-size-md { - width: 50px; - height: 50px; - } - - &.pl-size-sm { - width: 40px; - height: 40px; - } - - &.pl-size-xs { - width: 25px; - height: 25px; - } -} - -.spinner-layer { - position: absolute; - width: 100%; - height: 100%; - border-color: #f44336; - -ms-opacity: 1; - opacity: 1; - -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) - infinite both; - -moz-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) - infinite both; - -o-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite - both; - animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite - both; - - @each $key, $val in $colors { - &.pl-#{$key} { - border-color: $val; - } - } -} - -.right { - float: right !important; -} - -.gap-patch { - position: absolute; - top: 0; - left: 45%; - width: 10%; - height: 100%; - overflow: hidden; - border-color: inherit; - - &.circle { - width: 1000%; - left: -450%; - } -} - -.circle-clipper { - display: inline-block; - position: relative; - width: 50%; - height: 100%; - overflow: hidden; - border-color: inherit; - - .circle { - width: 200%; - height: 100%; - border-width: 3px; - border-style: solid; - border-color: inherit; - border-bottom-color: transparent !important; - -ms-border-radius: 50%; - border-radius: 50%; - -webkit-animation: none; - animation: none; - position: absolute; - top: 0; - right: 0; - bottom: 0; - } - - &.left { - .circle { - left: 0; - border-right-color: transparent !important; - -webkit-transform: rotate(129deg); - -moz-transform: rotate(129deg); - -ms-transform: rotate(129deg); - -o-transform: rotate(129deg); - transform: rotate(129deg); - -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite - both; - -moz-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite - both; - -o-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - } - } - - &.right { - .circle { - left: -100%; - border-left-color: transparent !important; - -webkit-transform: rotate(-129deg); - -moz-transform: rotate(-129deg); - -ms-transform: rotate(-129deg); - -o-transform: rotate(-129deg); - transform: rotate(-129deg); - -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite - both; - -moz-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite - both; - -o-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - } - } -} - -@-webkit-keyframes container-rotate { - to { - -webkit-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@keyframes container-rotate { - to { - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-webkit-keyframes fill-unfill-rotate { - 12.5% { - -webkit-transform: rotate(135deg); - transform: rotate(135deg); - } - - 25% { - -webkit-transform: rotate(270deg); - transform: rotate(270deg); - } - - 37.5% { - -webkit-transform: rotate(405deg); - transform: rotate(405deg); - } - - 50% { - -webkit-transform: rotate(540deg); - transform: rotate(540deg); - } - - 62.5% { - -webkit-transform: rotate(675deg); - transform: rotate(675deg); - } - - 75% { - -webkit-transform: rotate(810deg); - transform: rotate(810deg); - } - - 87.5% { - -webkit-transform: rotate(945deg); - transform: rotate(945deg); - } - - to { - -webkit-transform: rotate(1080deg); - transform: rotate(1080deg); - } -} - -@keyframes fill-unfill-rotate { - 12.5% { - transform: rotate(135deg); - } - - 25% { - transform: rotate(270deg); - } - - 37.5% { - transform: rotate(405deg); - } - - 50% { - transform: rotate(540deg); - } - - 62.5% { - transform: rotate(675deg); - } - - 75% { - transform: rotate(810deg); - } - - 87.5% { - transform: rotate(945deg); - } - - to { - transform: rotate(1080deg); - } -} - -@-webkit-keyframes left-spin { - from { - -webkit-transform: rotate(130deg); - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - transform: rotate(130deg); - } - - 50% { - -webkit-transform: rotate(-5deg); - -moz-transform: rotate(-5deg); - -ms-transform: rotate(-5deg); - -o-transform: rotate(-5deg); - transform: rotate(-5deg); - } - - to { - -webkit-transform: rotate(130deg); - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - transform: rotate(130deg); - } -} - -@keyframes left-spin { - from { - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - -webkit-transform: rotate(130deg); - transform: rotate(130deg); - } - - 50% { - -moz-transform: rotate(-5deg); - -ms-transform: rotate(-5deg); - -o-transform: rotate(-5deg); - -webkit-transform: rotate(-5deg); - transform: rotate(-5deg); - } - - to { - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - -webkit-transform: rotate(130deg); - transform: rotate(130deg); - } -} - -@-webkit-keyframes right-spin { - from { - -webkit-transform: rotate(-130deg); - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - transform: rotate(-130deg); - } - - 50% { - -webkit-transform: rotate(5deg); - -moz-transform: rotate(5deg); - -ms-transform: rotate(5deg); - -o-transform: rotate(5deg); - transform: rotate(5deg); - } - - to { - -webkit-transform: rotate(-130deg); - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - transform: rotate(-130deg); - } -} - -@-moz-keyframes right-spin { - from { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); - } - - 50% { - -moz-transform: rotate(5deg); - -ms-transform: rotate(5deg); - -o-transform: rotate(5deg); - -webkit-transform: rotate(5deg); - transform: rotate(5deg); - } - - to { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); - } -} - -@keyframes right-spin { - from { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); - } - - 50% { - -moz-transform: rotate(5deg); - -ms-transform: rotate(5deg); - -o-transform: rotate(5deg); - -webkit-transform: rotate(5deg); - transform: rotate(5deg); - } - - to { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_progressbars.scss b/MyOffice.SPA/src/assets/scss/ui/_progressbars.scss deleted file mode 100644 index c597502..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_progressbars.scss +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Document : _progressbars.scss - * Author : RedStar Template - * Description: This scss file for progress bars style classes - */ - -.mat-mdc-progress-bar { - &.progress-xs { - height: 4px; - } - &.progress-s { - height: 5px; - } - &.progress-m { - height: 10px; - .mdc-linear-progress__bar-inner { - border-top-width: var(--mdc-linear-progress-track-height, 10px); - } - } - &.progress-l { - height: 15px; - .mdc-linear-progress__bar-inner { - border-top-width: 15px; - } - } - - &.progress-round { - border-radius: 7px; - } - - &.green-progress .mdc-linear-progress__bar-inner { - border-color: #0af30a !important; - } - &.sky-progress .mdc-linear-progress__bar-inner { - border-color: #248afd !important; - } - &.orange-progress .mdc-linear-progress__bar-inner { - border-color: #ffc100 !important; - } - &.red-progress .mdc-linear-progress__bar-inner { - border-color: #ff4747 !important; - } - - &.l-green-progress .mdc-linear-progress__bar-inner { - background: #11998e; /* fallback for old browsers */ - background: -webkit-linear-gradient( - to right, - #38ef7d, - #11998e - ); /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient( - to right, - #38ef7d, - #11998e - ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ - } - &.l-sky-progress .mat-progress-bar-fill::after { - background: #36d1dc; /* fallback for old browsers */ - background: -webkit-linear-gradient( - to right, - #5b86e5, - #36d1dc - ); /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient( - to right, - #5b86e5, - #36d1dc - ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ - } - &.l-orange-progress .mat-progress-bar-fill::after { - background: #f12711; /* fallback for old browsers */ - background: -webkit-linear-gradient( - to right, - #f5af19, - #f12711 - ); /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient( - to right, - #f5af19, - #f12711 - ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ - } - &.l-red-progress .mat-progress-bar-fill::after { - background: #ff416c; /* fallback for old browsers */ - background: -webkit-linear-gradient( - to right, - #ff4b2b, - #ff416c - ); /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient( - to right, - #ff4b2b, - #ff416c - ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ - } - &.l-purple-progress .mat-progress-bar-fill::after { - background: #7f00ff; /* fallback for old browsers */ - background: -webkit-linear-gradient( - to right, - #e100ff, - #7f00ff - ); /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient( - to right, - #e100ff, - #7f00ff - ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ - } - - &.progress-shadow { - box-shadow: 0.4rem 0.4rem 0.8rem rgb(0 0 0 / 10%); - } -} - -.progress-list { - position: relative; - - .status { - display: inline-block; - font-size: 12px; - padding: 6px; - position: absolute; - right: 0; - top: 0; - } -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_slider.scss b/MyOffice.SPA/src/assets/scss/ui/_slider.scss deleted file mode 100644 index a7b85e1..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_slider.scss +++ /dev/null @@ -1,3 +0,0 @@ -mat-slider { - width: 300px; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_snackbar.scss b/MyOffice.SPA/src/assets/scss/ui/_snackbar.scss deleted file mode 100644 index c845b43..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_snackbar.scss +++ /dev/null @@ -1,19 +0,0 @@ -.mat-mdc-snack-bar-container.snackbar-success .mdc-snackbar__surface { - background-color: rgba(24, 206, 15, 0.8); - color: #ffffff; -} - -.mat-mdc-snack-bar-container.snackbar-info .mdc-snackbar__surface { - background-color: rgba(44, 168, 255, 0.8); - color: #ffffff; -} - -.mat-mdc-snack-bar-container.snackbar-warning .mdc-snackbar__surface { - background-color: rgba(255, 230, 0, 0.8); - color: #ffffff; -} - -.mat-mdc-snack-bar-container.snackbar-danger .mdc-snackbar__surface { - background-color: rgba(255, 0, 0, 0.8); - color: #ffffff; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_tabs.scss b/MyOffice.SPA/src/assets/scss/ui/_tabs.scss deleted file mode 100644 index ff4da90..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_tabs.scss +++ /dev/null @@ -1,29 +0,0 @@ -.example-small-box, -.example-large-box { - display: flex; - align-items: center; - justify-content: center; - margin: 16px; - padding: 16px; - border-radius: 8px; -} - -.example-small-box { - height: 100px; - width: 100px; -} - -.example-large-box { - height: 300px; - width: 300px; -} -.appointment-tab-box { - background-color: #eff1f7; - width: 100%; - padding: 10px; -} -.tab-header { - color: #555; - padding: 15px; - position: relative; -} diff --git a/MyOffice.SPA/src/assets/scss/ui/_tooltippopovers.scss b/MyOffice.SPA/src/assets/scss/ui/_tooltippopovers.scss deleted file mode 100644 index 56e4d01..0000000 --- a/MyOffice.SPA/src/assets/scss/ui/_tooltippopovers.scss +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Document : _tooltippopovers.scss - * Author : RedStar Template - * Description: This scss file for tooltip pop overs style classes - */ -.tooltip { - font-size: 13px; - - .tooltip-inner { - @include border-radius(0); - } -} - -.popover { - @include border-radius(0); - border: 1px solid rgba(0, 0, 0, 0.08); - - .popover-title { - font-weight: bold; - @include border-radius(0); - background-color: #e9e9e9; - border-bottom: 1px solid #ddd; - } - - .popover-content { - font-size: 13px; - color: #777; - @include border-radius(0); - } -} diff --git a/MyOffice.SPA/src/environments/environment.docker.ts b/MyOffice.SPA/src/environments/environment.docker.ts deleted file mode 100644 index cfff301..0000000 --- a/MyOffice.SPA/src/environments/environment.docker.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Browser → host ports (defaults; Docker build may overwrite via API_PUBLIC_URL). -export const environment = { - production: true, - apiUrl: 'http://localhost:32081', - identityServer: 'http://localhost:32081/', - allowedUrls: ['http://localhost:32081'], - // Plain HTTP demo stack — do not require HTTPS for OIDC. - requireHttps: false, - externalLogins: { - google: { - clientId: '' - }, - auth0: { - clientId: '', - domain: '' - } - } -}; diff --git a/MyOffice.SPA/src/environments/environment.proxmox.ts b/MyOffice.SPA/src/environments/environment.proxmox.ts deleted file mode 100644 index 943991a..0000000 --- a/MyOffice.SPA/src/environments/environment.proxmox.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Same-origin Proxmox deploy: API serves SPA from wwwroot (one public URL). -// Empty apiUrl / identityServer / allowedUrls → resolved at runtime from window.location.origin. -export const environment = { - production: true, - apiUrl: '', - identityServer: '', - allowedUrls: [] as string[], - requireHttps: false, - externalLogins: { - google: { - clientId: '' - }, - auth0: { - clientId: '', - domain: '' - } - } -}; diff --git a/MyOffice.SPA/src/environments/environment.sample.ts b/MyOffice.SPA/src/environments/environment.sample.ts deleted file mode 100644 index 66395af..0000000 --- a/MyOffice.SPA/src/environments/environment.sample.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Copy to environment.ts for local development (environment.ts is gitignored). -export const environment = { - production: false, - apiUrl: 'http://localhost:9100', - identityServer: 'http://localhost:9100/', - allowedUrls: ['http://localhost:9100'], - externalLogins: { - google: { - clientId: '' - }, - auth0: { - clientId: '', - domain: '' - } - } -}; diff --git a/MyOffice.SPA/src/favicon.ico b/MyOffice.SPA/src/favicon.ico deleted file mode 100644 index 997406a..0000000 Binary files a/MyOffice.SPA/src/favicon.ico and /dev/null differ diff --git a/MyOffice.SPA/src/index.html b/MyOffice.SPA/src/index.html deleted file mode 100644 index 89b374c..0000000 --- a/MyOffice.SPA/src/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - MyOffice - - - - - - - - - - - diff --git a/MyOffice.SPA/src/main.ts b/MyOffice.SPA/src/main.ts deleted file mode 100644 index 2a48f56..0000000 --- a/MyOffice.SPA/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; - -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig) - .catch(err => console.error(err)); diff --git a/MyOffice.SPA/src/polyfills.ts b/MyOffice.SPA/src/polyfills.ts deleted file mode 100644 index f85b963..0000000 --- a/MyOffice.SPA/src/polyfills.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes recent versions of Safari, Chrome (including - * Opera), Edge on the desktop, and iOS and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js'; // Included with Angular CLI. - - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/MyOffice.SPA/src/proxy.conf.js b/MyOffice.SPA/src/proxy.conf.js deleted file mode 100644 index 62ba391..0000000 --- a/MyOffice.SPA/src/proxy.conf.js +++ /dev/null @@ -1,15 +0,0 @@ -const PROXY_CONFIG = [ - { - context: [ - '/api', - '/authorize', - '/.well-known', - '/connect', - '/weatherforecast', - ], - target: 'http://localhost:9100', - secure: false - } -]; - -module.exports = PROXY_CONFIG; diff --git a/MyOffice.SPA/src/silent-refresh.html b/MyOffice.SPA/src/silent-refresh.html deleted file mode 100644 index 0c2ab58..0000000 --- a/MyOffice.SPA/src/silent-refresh.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - diff --git a/MyOffice.SPA/src/styles.scss b/MyOffice.SPA/src/styles.scss deleted file mode 100644 index 008c901..0000000 --- a/MyOffice.SPA/src/styles.scss +++ /dev/null @@ -1,68 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ - -.mdc-text-field--disabled.mdc-text-field--filled { - background-color: #4c4f57; -} - -@keyframes spinner { - to { - transform: rotate(360deg); - } -} - -.spinner:before { - content: ''; - box-sizing: border-box; - position: absolute; - top: 50%; - left: 50%; - width: 20px; - height: 20px; - margin-top: -10px; - margin-left: -10px; - border-radius: 50%; - border: 2px solid #ffffff; - border-top-color: #000000; - animation: spinner .8s linear infinite; -} - -.mat-dialog-actions { - display: grid !important; - grid-template-columns: 1fr auto !important; - align-items: center !important; -} - -.mat-dialog-actions { - display: grid !important; - grid-template-columns: 1fr auto !important; - align-items: center !important; -} - -.mat-dialog-left { - display: flex !important; - align-items: center !important; -} - -.error-icon { - margin-right: 8px !important; -} - -.error-message { - margin: 0 !important; - overflow: auto !important; -} - -.mat-dialog-right { - display: flex !important; - justify-content: flex-end !important; - align-items: center !important; -} - -.button-bottom { - display: flex !important; - align-items: center !important; -} - -.button-bottom button { - margin-left: 8px !important; -} diff --git a/MyOffice.SPA/src/styles/_variables.scss b/MyOffice.SPA/src/styles/_variables.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/styles/global.scss b/MyOffice.SPA/src/styles/global.scss deleted file mode 100644 index 6c384d0..0000000 --- a/MyOffice.SPA/src/styles/global.scss +++ /dev/null @@ -1,277 +0,0 @@ -@import '@angular/material/theming'; -@include mat-core(); - -/* You can add global styles to this file, and also import other style files */ -html, body { - height: 100%; -} - -body { - margin: 0; - font-family: Roboto, "Helvetica Neue", sans-serif; -} - -.app-header { - justify-content: space-between; - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 2; - box-shadow: 0 3px 5px -1px rgba(0, 0, 0, .2), 0 6px 10px 0 rgba(0, 0, 0, .14), 0 1px 18px 0 rgba(0, 0, 0, .12); -} - -.login-wrapper { - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.mat-card-content-center { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; -} - -.primary-content { - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - min-width: 600px; - padding: 30px 40px 30px 40px; -} - -.box { - position: relative; - top: 0; - opacity: 1; - float: left; - padding: 30px 40px 30px 40px; - width: 100%; - background: #fff; - border-radius: 10px; - transform: scale(1); - -webkit-transform: scale(1); - -ms-transform: scale(1); - z-index: 5; - max-width: 330px; -} - -.box.back { - transform: scale(.95); - -webkit-transform: scale(.95); - -ms-transform: scale(.95); - top: -20px; - opacity: .8; - z-index: -1; -} - -.box:before { - content: ""; - width: 100%; - height: 30px; - border-radius: 10px; - position: absolute; - top: -10px; - background: rgba(255, 255, 255, .6); - left: 0; - transform: scale(.95); - -webkit-transform: scale(.95); - -ms-transform: scale(.95); - z-index: -1; -} - -mat-form-field { - width: 350px !important; -} - -.mat-mdc-form-field-infix { -} - -/* margins */ -.m-5 { - margin: 5px; -} - -.m-10 { - margin: 10px; -} - -.m-15 { - margin: 15px; -} - -.m-20 { - margin: 20px; -} - -.m-25 { - margin: 25px; -} - -.m-30 { - margin: 30px; -} - -.mt-5 { - margin-top: 5px; -} - -.mt-10 { - margin-top: 10px; -} - -.mt-15 { - margin-top: 15px; -} - -.mt-20 { - margin-top: 20px; -} - -.mt-25 { - margin-top: 25px; -} - -.mt-30 { - margin-top: 30px; -} - -.mb-5 { - margin-bottom: 5px; -} - -.mb-10 { - margin-bottom: 10px; -} - -.mb-15 { - margin-bottom: 15px; -} - -.mb-20 { - margin-bottom: 20px; -} - -.mb-25 { - margin-bottom: 25px; -} - -.mb-30 { - margin-bottom: 30px; -} - -.ml-5 { - margin-left: 5px; -} - -.ml-10 { - margin-left: 10px; -} - -.ml-15 { - margin-left: 15px; -} - -.ml-20 { - margin-left: 20px; -} - -.ml-25 { - margin-left: 25px; -} - -.ml-30 { - margin-left: 30px; -} - -.mr-5 { - margin-right: 5px; -} - -.mr-10 { - margin-right: 10px; -} - -.mr-15 { - margin-right: 15px; -} - -.mr-20 { - margin-right: 20px; -} - -.mr-25 { - margin-right: 25px; -} - -.mr-30 { - margin-right: 30px; -} - -.ml-a { - margin-left: auto; -} -/* paddings */ - -/* min-width */ -.w-50 { - width: 50px; -} - -.w-75 { - width: 75px; -} - -.w-100 { - width: 100px; -} - -.w-100p { - width: 100%; -} - -/* min-width */ -.mw-50 { - min-width: 50px; -} - -.mw-75 { - min-width: 75px; -} - -.mw-100 { - min-width: 100px; -} - -.mw-50-imp { - min-width: 50px !important; -} - -.mw-75-imp { - min-width: 75px !important; -} - -.mw-100-imp { - min-width: 100px !important; -} - -.fl-l { - float: left -} - -.fl-r { - float: right -} - -/* colors */ - -$primary: mat-palette($mat-blue,800); - -.color-warn { - color: mat-color($primary, default); -} diff --git a/MyOffice.SPA/src/styles/reset.scss b/MyOffice.SPA/src/styles/reset.scss deleted file mode 100644 index e69de29..0000000 diff --git a/MyOffice.SPA/src/styles/styles.scss b/MyOffice.SPA/src/styles/styles.scss deleted file mode 100644 index b794247..0000000 --- a/MyOffice.SPA/src/styles/styles.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import "src/styles/_variables"; - -// Import functions, variables, and mixins needed by other Bootstrap files -@import "bootstrap/scss/functions"; -@import "bootstrap/scss/variables"; -@import "bootstrap/scss/maps"; -@import "bootstrap/scss/mixins"; - -// Import Bootstrap Reboot -@import "bootstrap/scss/root"; // Contains :root CSS variables used by other Bootstrap files -@import "bootstrap/scss/reboot"; - -@import "bootstrap/scss/containers"; // Add .container and .container-fluid classes -@import "bootstrap/scss/grid"; // Add the grid system - -@import "src/styles/reset"; - -@import "src/styles/global"; diff --git a/MyOffice.SPA/src/test.ts b/MyOffice.SPA/src/test.ts deleted file mode 100644 index ffa954b..0000000 --- a/MyOffice.SPA/src/test.ts +++ /dev/null @@ -1,14 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting(), -); diff --git a/MyOffice.SPA/tsconfig.app.json b/MyOffice.SPA/tsconfig.app.json deleted file mode 100644 index 90880d5..0000000 --- a/MyOffice.SPA/tsconfig.app.json +++ /dev/null @@ -1,15 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./out-tsc/app", - "types": [] - }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] -} diff --git a/MyOffice.SPA/tsconfig.json b/MyOffice.SPA/tsconfig.json deleted file mode 100644 index 1c3bc1b..0000000 --- a/MyOffice.SPA/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "compileOnSave": false, - "compilerOptions": { - "baseUrl": "./", - "outDir": "./dist/out-tsc", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "sourceMap": true, - "declaration": false, - "downlevelIteration": true, - "experimentalDecorators": true, - "moduleResolution": "node", - "importHelpers": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "target": "ES2022", - "module": "es2020", - "lib": [ - "es2020", - "dom" - ], - "useDefineForClassFields": false - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/MyOffice.SPA/tsconfig.spec.json b/MyOffice.SPA/tsconfig.spec.json deleted file mode 100644 index c1fdd7e..0000000 --- a/MyOffice.SPA/tsconfig.spec.json +++ /dev/null @@ -1,18 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./out-tsc/spec", - "types": [ - "jasmine" - ] - }, - "files": [ - "src/test.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/MyOffice.Services/Account/AccountAcl.cs b/MyOffice.Services/Account/AccountAcl.cs deleted file mode 100644 index f1b5eef..0000000 --- a/MyOffice.Services/Account/AccountAcl.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace MyOffice.Services.Account; - -using Data.Models.Accounts; - -/// -/// Account access checks shared by service mutations (motions, settings, invites). -/// -public static class AccountAcl -{ - public static AccountAccess? GetUserAccess(Account account, Guid userId) => - account.AccessRights?.FirstOrDefault(x => x.UserId == userId); - - public static bool CanWrite(Account account, Guid userId) => - GetUserAccess(account, userId)?.IsAllowWrite == true; - - public static bool CanManage(Account account, Guid userId) => - GetUserAccess(account, userId)?.IsAllowManage == true; -} diff --git a/MyOffice.Services/Account/AccountMotionBalancing.cs b/MyOffice.Services/Account/AccountMotionBalancing.cs deleted file mode 100644 index 66870f9..0000000 --- a/MyOffice.Services/Account/AccountMotionBalancing.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace MyOffice.Services.Account; - -/// -/// Rules for counterparty (transfer) motion amounts when balancing between accounts. -/// -public static class AccountMotionBalancing -{ - /// - /// When the primary motion is income (Plus != 0), balancing is expense on the other account. - /// Otherwise balancing is income on the other account. - /// - public static (decimal Plus, decimal Minus) ResolveAmounts(decimal primaryPlus, decimal amountBalancing) - { - if (primaryPlus != 0) - { - return (0, amountBalancing); - } - - return (amountBalancing, 0); - } - - public static string BalancingItemName(string accountName) => $"+{accountName}"; -} diff --git a/MyOffice.Services/Account/AccountService.Access.cs b/MyOffice.Services/Account/AccountService.Access.cs deleted file mode 100644 index 6b8fc4a..0000000 --- a/MyOffice.Services/Account/AccountService.Access.cs +++ /dev/null @@ -1,214 +0,0 @@ -namespace MyOffice.Services.Account; - -using System.Collections.Generic; - -using Core; -using Core.Extensions; -using Data.Models.Accounts; -using Domain; - -public partial class AccountService -{ - public async Task> AccessInviteAsync( - Guid userId, - Guid accountId, - string email, - bool isAllowWrite, - CancellationToken cancellationToken = default) - { - if (email == null) - throw new ArgumentNullException(nameof(email)); - - var result = new Exec(AccessInviteStatus.success); - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(AccessInviteStatus.account_not_found); - } - - if (!CanManage(account, userId)) - { - return result.Set(AccessInviteStatus.forbidden); - } - - if (account.AccessRights!.Any(x => x.User!.Email.EqualsIgnoreCase(email))) - { - return result.Set(AccessInviteStatus.access_exists); - } - - var access = await _accountAccessInviteRepository.GetAsync(userId, email, cancellationToken); - if (access != null) - { - return result.Set(AccessInviteStatus.invite_exists); - } - - var invite = new AccountAccessInvite - { - Id = Guid.NewGuid(), - CreatedOn = DateTime.UtcNow, - UserId = userId, - AccountId = account.Id, - Email = email.SafeTrim()!, - IsAllowWrite = isAllowWrite, - }; - - await _accountAccessInviteRepository.AddAsync(invite, cancellationToken); - - return result.Set(_mapper.Map(invite)); - } - - public async Task> AccessUpdateAsync( - Guid userId, - Guid accountId, - List accesses, - CancellationToken cancellationToken = default) - { - if (accesses == null) - throw new ArgumentNullException(nameof(accesses)); - - var result = new Exec(GeneralExecStatus.success); - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - if (!CanManage(account, userId)) - { - return result.Set(GeneralExecStatus.forbidden); - } - - foreach (var access in account.AccessRights!) - { - var newAccess = accesses.FirstOrDefault(x => x.UserId == access.UserId); - if (newAccess != null && newAccess.IsAllowWrite != access.IsAllowWrite) - { - access.IsAllowWrite = newAccess.IsAllowWrite; - await _accountAccessRepository.UpdateAsync(access, cancellationToken); - } - } - - account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - - return result.Set(_mapper.Map(account)); - } - - public async Task> AccessDeleteAsync( - Guid userId, - Guid accountId, - Guid accessUserId, - CancellationToken cancellationToken = default) - { - var result = new Exec(GeneralExecStatus.success); - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null || !account.AccessRights!.Any() || account.AccessRights!.Count() == 1) - { - return result.Set(GeneralExecStatus.not_found); - } - - if (!CanManage(account, userId)) - { - return result.Set(GeneralExecStatus.forbidden); - } - - var access = account.AccessRights!.FirstOrDefault(x => x.UserId == accessUserId); - if (access == null) - { - return result.Set(GeneralExecStatus.not_found); - } - if (access.OwnerId == access.UserId) - { - return result.Set(GeneralExecStatus.not_found); - } - - await _accountAccessRepository.DeleteAsync(access, cancellationToken); - - account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - - return result.Set(_mapper.Map(account)); - - } - - public async Task> InvitesGetAsync(string email, CancellationToken cancellationToken = default) - { - var invites = await _accountAccessInviteRepository.GetActiveAsync(email, cancellationToken); - - return _mapper.Map>(invites); - } - - public async Task> InviteAcceptAsync( - Guid userId, - Guid id, - string name, - CancellationToken cancellationToken = default) - { - var result = new Exec(InviteAcceptStatus.success); - - var invite = await _accountAccessInviteRepository.GetAsync(id, cancellationToken); - if (invite == null - || !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email) - || invite.AcceptedOn.HasValue - || invite.RejectedOn.HasValue - ) - { - return result.Set(InviteAcceptStatus.invite_not_found); - } - - var account = await _accountRepository.GetAsync(invite.UserId, invite.AccountId, cancellationToken); - if (account == null) - { - return result.Set(InviteAcceptStatus.account_not_found); - } - - if (account.AccessRights!.Any(x => x.UserId == userId)) - { - result.Set(InviteAcceptStatus.already_accepted); - } - else - { - await _accountAccessRepository.AddAsync(new AccountAccess - { - UserId = userId, - AccountId = account.Id, - OwnerId = invite.UserId, - Name = name, - IsAllowRead = true, - IsAllowWrite = invite.IsAllowWrite, - IsAllowManage = false, - Type = AccountAccessTypeEnum.external, - }, cancellationToken); - } - - invite.AcceptedOn = DateTime.UtcNow; - await _accountAccessInviteRepository.UpdateAsync(invite, cancellationToken); - - account = await _accountRepository.GetAsync(userId, account.Id, cancellationToken); - - return result.Set(_mapper.Map(account)); - } - - public async Task> InviteRejectAsync( - Guid id, - CancellationToken cancellationToken = default) - { - var result = new Exec(GeneralExecStatus.success); - - var invite = await _accountAccessInviteRepository.GetAsync(id, cancellationToken); - if (invite == null - || !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email) - || invite.AcceptedOn.HasValue - || invite.RejectedOn.HasValue - ) - { - return result.Set(GeneralExecStatus.not_found); - } - - invite.RejectedOn = DateTime.UtcNow; - await _accountAccessInviteRepository.UpdateAsync(invite, cancellationToken); - - return result.Set(_mapper.Map(invite)); - } -} diff --git a/MyOffice.Services/Account/AccountService.AccessRights.cs b/MyOffice.Services/Account/AccountService.AccessRights.cs deleted file mode 100644 index ea0f42f..0000000 --- a/MyOffice.Services/Account/AccountService.AccessRights.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace MyOffice.Services.Account; - -using Data.Models.Accounts; - -public partial class AccountService -{ - private static AccountAccess? GetUserAccess(Account account, Guid userId) => - AccountAcl.GetUserAccess(account, userId); - - private static bool CanWrite(Account account, Guid userId) => - AccountAcl.CanWrite(account, userId); - - private static bool CanManage(Account account, Guid userId) => - AccountAcl.CanManage(account, userId); -} diff --git a/MyOffice.Services/Account/AccountService.Account.cs b/MyOffice.Services/Account/AccountService.Account.cs deleted file mode 100644 index 13f9a47..0000000 --- a/MyOffice.Services/Account/AccountService.Account.cs +++ /dev/null @@ -1,270 +0,0 @@ -namespace MyOffice.Services.Account; - -using MyOffice.Core; -using MyOffice.Core.Extensions; -using MyOffice.Data.Models.Accounts; -using MyOffice.Services.Account.Domain; - -public partial class AccountService -{ - public async Task> GetAllAccountsAsync(Guid userId, CancellationToken cancellationToken = default) - { - var accounts = await _accountRepository.GetAllAsync(userId, cancellationToken); - - return accounts.ToDto(_mapper); - } - - public async Task> GetByCategoryAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default) - { - var accounts = await _accountRepository.GetByCategoryAsync(userId, categoryId, cancellationToken); - - return accounts.ToDto(_mapper); - } - - public async Task> FindAccountsAsync(Guid userId, string term, CancellationToken cancellationToken = default) - { - var accounts = await _accountRepository.FindAccountsAsync(userId, term, cancellationToken); - - return accounts.ToDto(_mapper); - } - - public List GetByCategoryDetailed(Guid userId, Guid categoryId) - { - return _accountRepository - .GetByCategoryDetailed(userId, categoryId) - .ToDto(_mapper); - } - - public async Task> GetByCategoryDetailedAsync( - Guid userId, - Guid categoryId, - CancellationToken cancellationToken = default - ) - { - var list = await _accountRepository.GetByCategoryDetailedAsync(userId, categoryId, cancellationToken); - return list.ToDto(_mapper); - } - - public Exec GetByIdDetailed(Guid userId, Guid id) - { - var result = new Exec(GeneralExecStatus.success); - - var account = _accountRepository.GetByIdDetailed(userId, id); - if (account == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - return result.Set(account.ToDto(_mapper));; - } - - public async Task> GetByIdDetailedAsync( - Guid userId, - Guid id, - CancellationToken cancellationToken = default - ) - { - var result = new Exec(GeneralExecStatus.success); - - var account = await _accountRepository.GetByIdDetailedAsync(userId, id, cancellationToken); - if (account == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - return result.Set(account.ToDto(_mapper)); - } - - public async Task> AccountAddAsync( - Guid userId, - AccountAdd input, - CancellationToken cancellationToken = default - ) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - var result = new Exec(AccountAddStatus.success); - - var category = await _accountCategoryRepository.GetAsync(userId, input.CategoryId, cancellationToken); - if (category == null) - { - return result.Set(AccountAddStatus.category_not_found); - } - var currency = await _currencyRepository.GetByGlobalCurrencyAsync(userId, input.CurrencyId, cancellationToken); - if (currency == null) - { - return result.Set(AccountAddStatus.currency_not_found); - } - - var account = new Account - { - Id = Guid.NewGuid(), - Name = input.Name, - CurrencyGlobalId = currency.CurrencyGlobalId, - OwnerId = userId, - }; - - account.Categories = new List - { - new() - { - AccountId = account.Id, - CategoryId = category.Id, - } - }; - account.AccessRights = new List - { - new() - { - AccountId = account.Id, - UserId = userId, - OwnerId = userId, - IsAllowManage = true, - IsAllowRead = true, - IsAllowWrite = true, - } - }; - - if (!await _accountRepository.AddAsync(account, cancellationToken)) - { - return result.Set(AccountAddStatus.failure); - } - // TODO: Add category refactoring - if (!await _accountAccountCategoryRepository.AddAsync(account.Categories.FirstOrDefault()!, cancellationToken)) - { - return result.Set(AccountAddStatus.failure); - } - // TODO: Add access refactoring - if (!await _accountAccessRepository.AddAsync(account.AccessRights.FirstOrDefault()!, cancellationToken)) - { - return result.Set(AccountAddStatus.failure); - } - - // TODO: Add account update AccessRights ??? - var access = account.AccessRights!.FirstOrDefault(x => x.UserId == userId); - if (access != null && access.Type.ToString() != input.Type) - { - if (Enum.TryParse(input.Type, out var enumType)) - { - access.Type = enumType; - await _accountAccessRepository.UpdateAsync(access, cancellationToken); - } - } - - return result.Set(account.ToDto(_mapper)); - } - - public async Task> AccountDeleteAsync( - Guid userId, - string id, - CancellationToken cancellationToken = default - ) - { - var result = new Exec(GeneralExecStatus.success); - - var account = await _accountRepository.GetAsync(userId, id.AsGuid(), cancellationToken); - if (account == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - if (!CanManage(account, userId)) - { - return result.Set(GeneralExecStatus.forbidden); - } - - if (account.Motions!.Any()) - { - return result.Set(GeneralExecStatus.not_found); - } - - await _accountRepository.DeleteAsync(account, cancellationToken); - result.Set(account.ToDto(_mapper)); - - return result; - } - - public async Task> AccountUpdateAsync( - Guid userId, - Guid accountId, - AccountEdit input, - CancellationToken cancellationToken = default - ) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - var result = new Exec(AccountEditStatus.success); - - AccountCategory? category = null; - if (input.CategoryId.HasValue) - { - category = await _accountCategoryRepository.GetAsync(userId, input.CategoryId.Value, cancellationToken); - if (category == null) - { - return result.Set(AccountEditStatus.category_not_found); - } - } - - var currency = await _currencyRepository.GetByGlobalCurrencyAsync(userId, input.CurrencyId, cancellationToken); - if (currency == null) - { - return result.Set(AccountEditStatus.currency_not_found); - } - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(AccountEditStatus.not_found); - } - - if (!CanManage(account, userId)) - { - return result.Set(AccountEditStatus.forbidden); - } - - account.Name = input.Name; - if (account.CurrencyGlobalId != currency.CurrencyGlobalId) - { - account.CurrencyGlobalId = currency.CurrencyGlobalId; - } - - AccountAccountCategory? addedLink = null; - if (category != null && account.Categories!.All(x => x.CategoryId != category.Id)) - { - addedLink = new AccountAccountCategory - { - AccountId = account.Id, - CategoryId = category.Id, - Category = category, - }; - await _accountAccountCategoryRepository.AddAsync(addedLink, cancellationToken); - } - - if (!await _accountRepository.UpdateAsync(account, cancellationToken)) - { - return result.Set(AccountEditStatus.failure); - } - - var access = account.AccessRights!.FirstOrDefault(x => x.UserId == userId); - if (access != null && access.Type.ToString() != input.Type) - { - if (Enum.TryParse(input.Type, out var enumType)) - { - access.Type = enumType; - await _accountAccessRepository.UpdateAsync(access, cancellationToken); - } - } - - // AddAsync detaches the link and does not refresh Account.Categories — keep response in sync. - if (addedLink != null && (account.Categories?.All(x => x.CategoryId != addedLink.CategoryId) ?? true)) - { - account.Categories = (account.Categories ?? Enumerable.Empty()) - .Append(addedLink) - .ToList(); - } - - return result.Set(account.ToDto(_mapper)); - } -} diff --git a/MyOffice.Services/Account/AccountService.AccountCategory.cs b/MyOffice.Services/Account/AccountService.AccountCategory.cs deleted file mode 100644 index 028ed68..0000000 --- a/MyOffice.Services/Account/AccountService.AccountCategory.cs +++ /dev/null @@ -1,147 +0,0 @@ -namespace MyOffice.Services.Account; - -using MyOffice.Core; -using MyOffice.Data.Models.Accounts; -using MyOffice.Services.Account.Domain; - -public partial class AccountService -{ - public async Task> GetAllCategoriesAsync(Guid userId, CancellationToken cancellationToken = default) - { - var categories = await _accountCategoryRepository.GetAllAsync(userId, cancellationToken); - - return _mapper.Map>(categories); - } - - public async Task> GetCategoryAsync( - Guid userId, - Guid id, - CancellationToken cancellationToken = default) - { - var result = new Exec(GeneralExecStatus.success); - - var category = await _accountCategoryRepository.GetAsync(userId, id, cancellationToken); - - if (category == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - return result.Set(_mapper.Map(category)); - } - - public async Task> CategoryAddAsync( - Guid userId, - AccountCategoryDto input, - CancellationToken cancellationToken = default) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - var result = new Exec(GeneralExecStatus.success); - - var category = new AccountCategory - { - Id = Guid.NewGuid(), - UserId = userId, - Name = input.Name, - }; - - if (!await _accountCategoryRepository.AddAsync(category, cancellationToken)) - { - return result.Set(GeneralExecStatus.failure); - } - - return result.Set(_mapper.Map(category)); - } - - public async Task> CategoryUpdateAsync( - Guid userId, - Guid id, - AccountCategoryDto input, - CancellationToken cancellationToken = default) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - var result = new Exec(GeneralExecStatus.success); - - var exists = await _accountCategoryRepository.GetAsync(userId, id, cancellationToken); - if (exists == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - exists.Name = input.Name; - - if (!await _accountCategoryRepository.UpdateAsync(exists, cancellationToken)) - { - return result.Set(GeneralExecStatus.failure); - } - - return result.Set(_mapper.Map(exists)); - } - - public async Task> CategoryRemoveAsync( - Guid userId, - Guid id, - CancellationToken cancellationToken = default) - { - var result = new Exec(AccountCategoryRemoveResult.success); - - var exists = await _accountCategoryRepository.GetAsync(userId, id, cancellationToken); - if (exists == null) - { - return result.Set(AccountCategoryRemoveResult.not_found); - } - - if (exists.Accounts?.Any() == true) - { - return result.Set(AccountCategoryRemoveResult.accounts_exists); - } - if (!await _accountCategoryRepository.RemoveAsync(exists, cancellationToken)) - { - return result.Set(AccountCategoryRemoveResult.failure); - } - - return result.Set(_mapper.Map(exists)); - } - - public async Task> AccountCategoryRemoveAsync( - Guid userId, - Guid accountId, - Guid categoryId, - CancellationToken cancellationToken = default) - { - var result = new Exec(GeneralExecStatus.success); - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - if (!CanManage(account, userId)) - { - return result.Set(GeneralExecStatus.forbidden); - } - - var links = await _accountAccountCategoryRepository.GetAsync(userId, accountId, categoryId, cancellationToken); - if (links.Count == 0) - { - return result.Set(GeneralExecStatus.not_found); - } - - foreach (var link in links) - { - await _accountAccountCategoryRepository.RemoveAsync(link, cancellationToken); - } - - // Account stays tracked after Remove; filter in-memory so the response is not stale. - account.Categories = account.Categories? - .Where(c => c.CategoryId != categoryId) - .ToList(); - - return result.Set(account.ToDto(_mapper)); - } -} diff --git a/MyOffice.Services/Account/AccountService.Motion.cs b/MyOffice.Services/Account/AccountService.Motion.cs deleted file mode 100644 index ec030ce..0000000 --- a/MyOffice.Services/Account/AccountService.Motion.cs +++ /dev/null @@ -1,212 +0,0 @@ -namespace MyOffice.Services.Account; - -using System.Collections.Generic; - -using Core; -using Core.Extensions; -using Data.Models.Accounts; -using Domain; -using Item.Domain; - -public partial class AccountService -{ - public async Task, MotionAddStatus>> MotionAddAsync( - Guid userId, - Guid accountId, - MotionAddUpdate motion, - CancellationToken cancellationToken = default - ) - { - if (motion == null) - throw new ArgumentNullException(nameof(motion)); - if (motion.Item == null) - throw new ArgumentNullException(nameof(motion.Item)); - - var result = new Exec, MotionAddStatus>(MotionAddStatus.success); - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(MotionAddStatus.account_not_found); - } - - if (!CanWrite(account, userId)) - { - return result.Set(MotionAddStatus.forbidden); - } - - var itemExec = await _itemService.GetOrCreateAsync(userId, motion.Item, cancellationToken); - if (itemExec.Status != ItemGetOrAddResult.success) - { - return result.Set(MotionAddStatus.failure); - } - - var motionDb = new Motion - { - Id = Guid.NewGuid(), - CreatedOn = DateTime.UtcNow, - DateTime = motion.Date, - AccountId = account.Id, - ItemId = itemExec.Result!.Id, - Description = motion.Description, - AmountPlus = motion.Plus, - AmountMinus = motion.Minus, - }; - - if (!await _motionRepository.AddAsync(motionDb, cancellationToken)) - { - return result.Set(MotionAddStatus.failure); - } - - result.Set(new List()); - result.Result!.Add(_mapper.Map(motionDb)); - - if (motion.AccountId.IsPresent() && motion.AmountBalancing != 0) - { - var accountBalancing = await _accountRepository.GetAsync( - userId, - motion.AccountId!.AsGuid(), - cancellationToken); - if (accountBalancing != null && CanWrite(accountBalancing, userId)) - { - var balancingName = AccountMotionBalancing.BalancingItemName(account.Name); - var itemBalancingExec = await _itemService.GetOrCreateAsync( - userId, - balancingName, - cancellationToken); - var (plus, minus) = AccountMotionBalancing.ResolveAmounts(motion.Plus, motion.AmountBalancing); - var motionBalancing = new Motion - { - Id = Guid.NewGuid(), - CreatedOn = DateTime.UtcNow, - DateTime = motion.Date, - AccountId = accountBalancing.Id, - ItemId = itemBalancingExec.Result!.Id, - Description = motion.Description, - AmountPlus = plus, - AmountMinus = minus, - }; - - if (await _motionRepository.AddAsync(motionBalancing, cancellationToken)) - { - result.Result!.Add(_mapper.Map(motionBalancing)); - } - } - } - - motionDb.Item = itemExec.Result!; - - return result; - } - - public async Task> MotionUpdateAsync( - Guid userId, - Guid accountId, - Guid motionId, - MotionAddUpdate motion, - CancellationToken cancellationToken = default - ) - { - if (motion == null) - throw new ArgumentNullException(nameof(motion)); - if (motion.Item == null) - throw new ArgumentNullException(nameof(motion.Item)); - - var result = new Exec(MotionUpdateStatus.success); - - var exists = await _motionRepository.GetAsync(userId, motionId, cancellationToken); - if (exists == null || exists.AccountId != accountId) - { - return result.Set(MotionUpdateStatus.not_found); - } - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(MotionUpdateStatus.not_found); - } - - if (!CanWrite(account, userId)) - { - return result.Set(MotionUpdateStatus.forbidden); - } - - var itemExec = await _itemService.GetOrCreateAsync(userId, motion.Item, cancellationToken); - if (itemExec.Status != ItemGetOrAddResult.success) - { - return result.Set(MotionUpdateStatus.failure); - } - - exists.Item.Id = itemExec.Result!.Id; - exists.DateTime = motion.Date; - exists.Description = motion.Description; - exists.AmountPlus = motion.Plus; - exists.AmountMinus = motion.Minus; - - if (!await _motionRepository.UpdateAsync(exists, cancellationToken)) - { - return result.Set(MotionUpdateStatus.failure); - } - - return result.Set(_mapper.Map(exists)); - } - - public async Task, GeneralExecStatus>> GetMotionsAsync( - Guid userId, - Guid accountId, - DateTime dateFrom, - DateTime dateTo, - CancellationToken cancellationToken = default - ) - { - var result = new Exec, GeneralExecStatus>(GeneralExecStatus.success); - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - var motions = await _motionRepository.GetByAccountAsync( - accountId, - dateFrom.ToUtc(), - dateTo.ToUtc(), - cancellationToken); - - return result.Set(_mapper.Map>(motions)); - } - - public async Task> MotionRemoveAsync( - Guid userId, - Guid accountId, - Guid motionId, - CancellationToken cancellationToken = default - ) - { - var result = new Exec(MotionDeleteStatus.success); - - var exists = await _motionRepository.GetAsync(userId, motionId, cancellationToken); - if (exists == null || exists.AccountId != accountId) - { - return result.Set(MotionDeleteStatus.not_found); - } - - var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); - if (account == null) - { - return result.Set(MotionDeleteStatus.not_found); - } - - if (!CanWrite(account, userId)) - { - return result.Set(MotionDeleteStatus.forbidden); - } - - if (!await _motionRepository.RemoveAsync(exists, cancellationToken)) - { - return result.Set(MotionDeleteStatus.failure); - } - - return result.Set(_mapper.Map(exists)); - } -} diff --git a/MyOffice.Services/Account/AccountService.cs b/MyOffice.Services/Account/AccountService.cs deleted file mode 100644 index 361d2f1..0000000 --- a/MyOffice.Services/Account/AccountService.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace MyOffice.Services.Account; - -using AutoMapper; -using Microsoft.Extensions.Logging; - -using Identity; -using Data.Repositories.Account; -using Data.Repositories.Currency; -using Data.Repositories.Item; -using Item; - -public partial class AccountService -{ - private ILogger _logger; - private readonly IMapper _mapper; - private readonly IAccountCategoryRepository _accountCategoryRepository; - private readonly IAccountAccessRepository _accountAccessRepository; - private readonly IAccountAccessInviteRepository _accountAccessInviteRepository; - private readonly IAccountRepository _accountRepository; - private readonly ICurrencyRepository _currencyRepository; - private readonly IAccountAccountCategoryRepository _accountAccountCategoryRepository; - private readonly IMotionRepository _motionRepository; - private readonly IItemRepository _itemRepository; - private readonly IItemGlobalRepository _itemGlobalRepository; - private readonly ItemService _itemService; - private readonly IContextProvider _contextProvider; - - public AccountService( - ILogger logger, - IMapper mapper, - IAccountCategoryRepository accountCategoryRepository, - IAccountAccessRepository accountAccessRepository, - IAccountAccessInviteRepository accountAccessInviteRepository, - IAccountRepository accountRepository, - ICurrencyRepository currencyRepository, - IAccountAccountCategoryRepository accountAccountCategoryRepository, - IMotionRepository motionRepository, - IItemRepository itemRepository, - IItemGlobalRepository itemGlobalRepository, - ItemService itemService, - IContextProvider contextProvider - ) - { - _logger = logger; - _mapper = mapper; - _accountCategoryRepository = accountCategoryRepository; - _accountAccessRepository = accountAccessRepository; - _accountAccessInviteRepository = accountAccessInviteRepository; - _accountRepository = accountRepository; - _currencyRepository = currencyRepository; - _accountAccountCategoryRepository = accountAccountCategoryRepository; - _motionRepository = motionRepository; - _itemRepository = itemRepository; - _itemGlobalRepository = itemGlobalRepository; - _itemService = itemService; - _contextProvider = contextProvider; - } -} diff --git a/MyOffice.Services/Account/Domain/AccessInviteStatus.cs b/MyOffice.Services/Account/Domain/AccessInviteStatus.cs deleted file mode 100644 index f058a87..0000000 --- a/MyOffice.Services/Account/Domain/AccessInviteStatus.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -public enum AccessInviteStatus -{ - success, - account_not_found, - access_exists, - invite_exists, - forbidden, -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountAccessDto.cs b/MyOffice.Services/Account/Domain/AccountAccessDto.cs deleted file mode 100644 index a103cd0..0000000 --- a/MyOffice.Services/Account/Domain/AccountAccessDto.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using Data.Models.Accounts; -using MyOffice.Services.Identity; - -public class AccountAccessDto -{ - public Guid AccountId { get; set; } - public AccountDto? Account { get; set; } - - /// - /// User can access to account - /// - public Guid UserId { get; set; } - public UserDto? User { get; set; } - - public bool IsAllowRead { get; set; } - public bool IsAllowWrite { get; set; } - public bool IsAllowManage { get; set; } - public bool IsOwner { get; set; } - public AccountAccessTypeEnum Type { get; set; } - /// - /// Who add access - /// - public Guid OwnerId { get; set; } - public UserDto? Owner { get; set; } - public string? Name { get; set; } -} - -public class AccountAccessDtoProfile : Profile -{ - public AccountAccessDtoProfile() - { - CreateMap() - .AfterMap() - ; - } -} - -public class AccountAccessDtoMappingAction : IMappingAction -{ - private readonly IContextProvider _contextProvider; - public AccountAccessDtoMappingAction(IContextProvider contextProvider) - { - _contextProvider = contextProvider; - } - - public void Process(AccountAccess source, AccountAccessDto destination, ResolutionContext context) - { - destination.IsOwner = destination.OwnerId == _contextProvider.UserId; - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountAccessInviteDto.cs b/MyOffice.Services/Account/Domain/AccountAccessInviteDto.cs deleted file mode 100644 index 8145d76..0000000 --- a/MyOffice.Services/Account/Domain/AccountAccessInviteDto.cs +++ /dev/null @@ -1,22 +0,0 @@ -/// -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using Data.Models.Accounts; - -public class AccountAccessInviteDto -{ - public string Id { get; set; } = null!; - public string Account { get; set; } = null!; - public bool IsAllowWrite { get; set; } -} - -public class AccountAccessInviteDtoProfile: Profile -{ - public AccountAccessInviteDtoProfile() - { - CreateMap() - .ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountAccountCategoryDto.cs b/MyOffice.Services/Account/Domain/AccountAccountCategoryDto.cs deleted file mode 100644 index 1867802..0000000 --- a/MyOffice.Services/Account/Domain/AccountAccountCategoryDto.cs +++ /dev/null @@ -1,19 +0,0 @@ -/// -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Accounts; - -public class AccountAccountCategoryDto -{ - public Guid CategoryId { get; set; } - public AccountCategoryDto? Category { get; set; } = null!; -} - -public class AccountAccountCategoryDtoProfile: Profile -{ - public AccountAccountCategoryDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountAdd.cs b/MyOffice.Services/Account/Domain/AccountAdd.cs deleted file mode 100644 index 1077830..0000000 --- a/MyOffice.Services/Account/Domain/AccountAdd.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Account.Domain -{ - public class AccountAdd - { - public string Name { get; set; } = null!; - public string CurrencyId { get; set; } = null!; - public Guid CategoryId { get; set; } - public string Type { get; set; } = null!; - } -} diff --git a/MyOffice.Services/Account/Domain/AccountAddStatus.cs b/MyOffice.Services/Account/Domain/AccountAddStatus.cs deleted file mode 100644 index b50b045..0000000 --- a/MyOffice.Services/Account/Domain/AccountAddStatus.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Account.Domain -{ - public enum AccountAddStatus - { - success, - failure, - category_not_found, - currency_not_found, - } -} diff --git a/MyOffice.Services/Account/Domain/AccountCategoryDto.cs b/MyOffice.Services/Account/Domain/AccountCategoryDto.cs deleted file mode 100644 index 545115a..0000000 --- a/MyOffice.Services/Account/Domain/AccountCategoryDto.cs +++ /dev/null @@ -1,24 +0,0 @@ -/// -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Accounts; - -public class AccountCategoryDto -{ - public Guid Id { get; set; } - public Guid UserId { get; set; } - public string Name { get; set; } = null!; - public bool AllowDelete { get; set; } -} - -public class AccountCategoryDtoProfile: Profile -{ - public AccountCategoryDtoProfile() - { - CreateMap() - .ForMember(x => x.Id, o => o.MapFrom(x => x.Id)) - .ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Accounts!.Any())) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountCategoryRemoveResult.cs b/MyOffice.Services/Account/Domain/AccountCategoryRemoveResult.cs deleted file mode 100644 index 8f9909c..0000000 --- a/MyOffice.Services/Account/Domain/AccountCategoryRemoveResult.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Account.Domain -{ - public enum AccountCategoryRemoveResult - { - success, - failure, - not_found, - accounts_exists, - } -} diff --git a/MyOffice.Services/Account/Domain/AccountDetailedDto.cs b/MyOffice.Services/Account/Domain/AccountDetailedDto.cs deleted file mode 100644 index 4ed39a6..0000000 --- a/MyOffice.Services/Account/Domain/AccountDetailedDto.cs +++ /dev/null @@ -1,22 +0,0 @@ -/// -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using MyOffice.Core; -using MyOffice.Data.Models.Accounts; - -public class AccountDetailedDto: IDataModelDto -{ - public AccountDto Account { get; set; } = null!; - public decimal TotalPlus { get; set; } - public decimal TotalMinus { get; set; } - public decimal Rest => TotalPlus - TotalMinus; -} - -public class AccountDetailedDtoProfile: Profile -{ - public AccountDetailedDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountDto.cs b/MyOffice.Services/Account/Domain/AccountDto.cs deleted file mode 100644 index ab816d7..0000000 --- a/MyOffice.Services/Account/Domain/AccountDto.cs +++ /dev/null @@ -1,79 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -using System; -using Data.Models.Accounts; -using MyOffice.Services.Currency.Domain; -using AutoMapper; -using MyOffice.Services.Identity; -using MyOffice.Core; -using MyOffice.Services.Mapper; - -[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)] -public class GenerateMappedDtoAttribute: Attribute -{ - public GenerateMappedDtoAttribute() - { - } -} - -[GenerateMappedDto] -public class AccountDto : IDataModelDto -{ - #region Account properties - - public Guid Id { get; set; } - public string CurrencyGlobalId { get; set; } = null!; - public CurrencyGlobalDto? CurrencyGlobal { get; set; } - public string Name { get; set; } = null!; - public Guid OwnerId { get; set; } - public UserDto? Owner { get; set; } - - #endregion Account properties - - #region Dto properties - - public Guid CurrencyId { get; set; } - public CurrencyDto? Currency { get; set; } - public string Type { get; set; } = null!; - public List? Categories { get; set; } - - public bool HasMotions { get; set; } - - #endregion Dto properties - - #region Permissions - - public List? AccessRights { get; set; } - public bool AllowRead { get; set; } - public bool AllowWrite { get; set; } - public bool AllowDelete { get; set; } - public bool AllowManage { get; set; } - - #endregion Permissions -} - -public class AccountDtoProfile : BaseProfile -{ - public AccountDtoProfile() - { - Mapping - .ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any())) - .AfterMap(); - } -} - -public class AccountDtoMappingAction : BaseMappingAction, IMappingAction -{ - public AccountDtoMappingAction(IContextProvider contextProvider) : base(contextProvider) { } - - public void Process(Account source, AccountDto destination, ResolutionContext context) - { - var accessRight = destination.AccessRights?.FirstOrDefault(x => x.UserId == ContextProvider.UserId); - destination.AllowRead = accessRight?.IsAllowRead ?? false; - destination.AllowWrite = accessRight?.IsAllowWrite ?? false; - destination.AllowManage = accessRight?.IsAllowManage ?? false; - destination.AllowDelete = (accessRight?.IsOwner ?? false) && !destination.HasMotions; - destination.Name = accessRight?.Name ?? destination.Name; - destination.Type = accessRight != null ? accessRight.Type.ToString() : destination.Type; - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountEdit.cs b/MyOffice.Services/Account/Domain/AccountEdit.cs deleted file mode 100644 index 8a19d69..0000000 --- a/MyOffice.Services/Account/Domain/AccountEdit.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -public class AccountEdit -{ - public string Name { get; set; } = null!; - public string CurrencyId { get; set; } = null!; - public Guid? CategoryId { get; set; } - public Guid? UserId { get; set; } - public string? Type { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountEditStatus.cs b/MyOffice.Services/Account/Domain/AccountEditStatus.cs deleted file mode 100644 index f74f74a..0000000 --- a/MyOffice.Services/Account/Domain/AccountEditStatus.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -public enum AccountEditStatus -{ - success, - failure, - not_found, - category_not_found, - currency_not_found, - forbidden, -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/InviteAcceptStatus.cs b/MyOffice.Services/Account/Domain/InviteAcceptStatus.cs deleted file mode 100644 index cfec492..0000000 --- a/MyOffice.Services/Account/Domain/InviteAcceptStatus.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Account.Domain -{ - public enum InviteAcceptStatus - { - success, - invite_not_found, - account_not_found, - already_accepted, - } -} diff --git a/MyOffice.Services/Account/Domain/ItemCategoryDto.cs b/MyOffice.Services/Account/Domain/ItemCategoryDto.cs deleted file mode 100644 index c7b76a3..0000000 --- a/MyOffice.Services/Account/Domain/ItemCategoryDto.cs +++ /dev/null @@ -1,23 +0,0 @@ -/// -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Items; - -public class ItemCategoryDto -{ - public Guid Id { get; set; } - public Guid UserId { get; set; } - public UserDto User { get; set; } = null!; - public string Name { get; set; } = null!; - public List Items { get; set; } = null!; - public bool IsInternal { get; set; } -} - -public class ItemCategoryDtoProfile: Profile -{ - public ItemCategoryDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/ItemDto.cs b/MyOffice.Services/Account/Domain/ItemDto.cs deleted file mode 100644 index 357c601..0000000 --- a/MyOffice.Services/Account/Domain/ItemDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -/// -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Items; - -public class ItemDto -{ - public Guid Id { get; set; } - public string? Name { get; set; } - public bool AllowDelete { get; set; } - - public Guid CategoryId { get; set; } - public ItemCategoryDto? Category { get; set; } -} - -public class ItemDtoProfile: Profile -{ - public ItemDtoProfile() - { - CreateMap() - .ForMember(x => x.Id, o => o.MapFrom(x => x.ItemGlobalId)) - .ForMember(x => x.Name, o => o.MapFrom(x => x.ItemGlobal.Name)) - .ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Motions!.Any())) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/MotionAddStatus.cs b/MyOffice.Services/Account/Domain/MotionAddStatus.cs deleted file mode 100644 index b06969a..0000000 --- a/MyOffice.Services/Account/Domain/MotionAddStatus.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -public enum MotionAddStatus -{ - success, - failure, - account_not_found, - forbidden, -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/MotionAddUpdate.cs b/MyOffice.Services/Account/Domain/MotionAddUpdate.cs deleted file mode 100644 index 473dbc9..0000000 --- a/MyOffice.Services/Account/Domain/MotionAddUpdate.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; - -public class MotionAddUpdate -{ - public DateTime Date { get; set; } - public string Item { get; set; } = null!; - public string? ItemId { get; set; } = null!; - public string? AccountId { get; set; } = null!; - public string? Description { get; set; } - public decimal Plus { get; set; } - public decimal Minus { get; set; } - public decimal AmountBalancing { get; set; } -} - -public class MotionAddUpdateProfile: Profile -{ - public MotionAddUpdateProfile() - { - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/MotionDeleteStatus.cs b/MyOffice.Services/Account/Domain/MotionDeleteStatus.cs deleted file mode 100644 index d049b94..0000000 --- a/MyOffice.Services/Account/Domain/MotionDeleteStatus.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -public enum MotionDeleteStatus -{ - success, - failure, - not_found, - forbidden, -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/MotionDto.cs b/MyOffice.Services/Account/Domain/MotionDto.cs deleted file mode 100644 index cc2aaed..0000000 --- a/MyOffice.Services/Account/Domain/MotionDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Accounts; - -public class MotionDto -{ - public Guid Id { get; set; } - public DateTime CreatedOn { get; set; } - public DateTime DateTime { get; set; } - public Guid AccountId { get; set; } - public AccountDto Account { get; set; } = null!; - public int ItemId { get; set; } - public ItemDto Item { get; set; } = null!; - public string? Description { get; set; } - public decimal AmountPlus { get; set; } - public decimal AmountMinus { get; set; } - public DateTime? DeletedOn { get; set; } -} - -public class MotionDtoProfile: Profile -{ - public MotionDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/MotionUpdateStatus.cs b/MyOffice.Services/Account/Domain/MotionUpdateStatus.cs deleted file mode 100644 index f7f1985..0000000 --- a/MyOffice.Services/Account/Domain/MotionUpdateStatus.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MyOffice.Services.Account.Domain; - -public enum MotionUpdateStatus -{ - success, - failure, - not_found, - forbidden, -} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/UserDto.cs b/MyOffice.Services/Account/Domain/UserDto.cs deleted file mode 100644 index b6939e9..0000000 --- a/MyOffice.Services/Account/Domain/UserDto.cs +++ /dev/null @@ -1,28 +0,0 @@ -/// -namespace MyOffice.Services.Account.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Users; -using MyOffice.Services.Currency.Domain; - -public class UserDto -{ - public Guid Id { get; set; } - public string UserName { get; set; } = null!; - public string Email { get; set; } = null!; - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? FullName { get; set; } - public string? Phone { get; set; } - - public string CurrencyId { get; set; } = null!; - public CurrencyGlobalDto? Currency { get; set; } -} - -public class UserDtoProfile : Profile -{ - public UserDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Currency/CurrencyService.cs b/MyOffice.Services/Currency/CurrencyService.cs deleted file mode 100644 index 4662147..0000000 --- a/MyOffice.Services/Currency/CurrencyService.cs +++ /dev/null @@ -1,202 +0,0 @@ -namespace MyOffice.Services.Currency; - -using AutoMapper; - -using Core; -using Data.Models.Currencies; -using Data.Repositories.Currency; -using Domain; - -public class CurrencyService -{ - private readonly ICurrencyGlobalRepository _currencyGlobalRepository; - private readonly ICurrencyRepository _currencyRepository; - private readonly ICurrencyRateRepository _currencyRateRepository; - private readonly IMapper _mapper; - - public CurrencyService( - ICurrencyGlobalRepository currencyGlobalRepository, - ICurrencyRepository currencyRepository, - ICurrencyRateRepository currencyRateRepository, - IMapper mapper - ) - { - _currencyGlobalRepository = currencyGlobalRepository; - _currencyRepository = currencyRepository; - _currencyRateRepository = currencyRateRepository; - _mapper = mapper; - } - - public async Task> GetGlobalAllAsync(CancellationToken cancellationToken = default) - { - return _mapper.Map>(await _currencyGlobalRepository.GetAllAsync(cancellationToken)); - } - - public async Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default) - { - return _mapper.Map>(await _currencyRepository.GetAllAsync(userId, cancellationToken)); - } - - public async Task> GetAllWithRatesAsync(Guid userId, CancellationToken cancellationToken = default) - { - var list = await _currencyRepository.GetAllAsync(userId, cancellationToken); - - var result = new List(list.Count); - foreach (var currency in list) - { - var rates = await _currencyRateRepository.GetLastRatesAsync(currency.Id, cancellationToken: cancellationToken); - result.Add(new CurrencyWithRateDto - { - Currency = _mapper.Map(currency), - Rate = _mapper.Map(rates.FirstOrDefault()), - }); - } - - return result; - } - - public async Task> CurrencyAddAsync( - Guid userId, - CurrencyDto input, - CancellationToken cancellationToken = default) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - var result = new Exec(CurrencyAddStatus.success); - - var exists = await _currencyRepository.GetByGlobalCurrencyAsync(userId, input.CurrencyGlobalId, cancellationToken); - if (exists != null) - { - return result.Set(_mapper.Map(exists), CurrencyAddStatus.exists); - } - - var currency = new Currency - { - Id = Guid.NewGuid(), - UserId = userId, - CurrencyGlobalId = input.CurrencyGlobalId, - Name = input.Name, - ShortName = input.ShortName, - }; - - if (!await _currencyRepository.AddAsync(currency, cancellationToken)) - { - return result.Set(CurrencyAddStatus.failed); - } - - return result.Set(_mapper.Map(currency)); - } - - public async Task> CurrencyUpdateAsync( - Guid userId, - Guid currencyId, - CurrencyEdit currency, - CancellationToken cancellationToken = default) - { - if (currency == null) - throw new ArgumentNullException(nameof(currency)); - - var result = new Exec(CurrencyEditStatus.success); - - var exists = await _currencyRepository.GetAsync(userId, currencyId, cancellationToken); - if (exists == null) - { - return result.Set(CurrencyEditStatus.not_found); - } - - exists.Name = currency.Name; - exists.ShortName = currency.ShortName; - exists.IsPrimary = currency.IsPrimary; - - if (!await _currencyRepository.UpdateAsync(exists, cancellationToken)) - { - return result.Set(CurrencyEditStatus.failed); - } - - if (exists.IsPrimary) - { - var primaries = await _currencyRepository.GetPrimariesAsync(userId, cancellationToken); - foreach (var primary in primaries) - { - if (primary.Id != exists.Id) - { - primary.IsPrimary = false; - await _currencyRepository.UpdateAsync(primary, cancellationToken); - } - } - } - - return result.Set(_mapper.Map(exists)); - } - - public async Task> CurrencyRateAddAsync( - Guid userId, - Guid currencyId, - CurrencyRateDto input, - CancellationToken cancellationToken = default) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - var result = new Exec(CurrencyAddRateStatus.success); - - var currency = await _currencyRepository.GetAsync(userId, currencyId, cancellationToken); - if (currency == null) - { - return result.Set(CurrencyAddRateStatus.not_found); - } - - var currencyRate = new CurrencyRate - { - CurrencyId = currency.Id, - DateTime = input.DateTime.Date, - Rate = input.Rate, - Quantity = input.Quantity, - }; - - var rates = await _currencyRateRepository.GetAtDateAsync(currencyRate.CurrencyId, currencyRate.DateTime, cancellationToken); - var rate = rates.Find(x => x.Rate == currencyRate.Rate); - - if (rate == null) - { - if (!await _currencyRateRepository.AddRateAsync(currencyRate, cancellationToken)) - { - return result.Set(CurrencyAddRateStatus.failed); - } - - // TODO: more logic to fix current rate - if (currencyRate.DateTime.Date == DateTime.UtcNow.Date || !currency.CurrentRateId.HasValue) - { - currency.CurrencyGlobal = null; - currency.CurrentRateId = currencyRate.Id; - await _currencyRepository.UpdateAsync(currency, cancellationToken); - } - - rate = currencyRate; - } - - return result.Set(_mapper.Map(rate)); - } - - public async Task> RemoveAsync( - Guid userId, - Guid id, - CancellationToken cancellationToken = default) - { - var result = new Exec(GeneralExecStatus.success); - - var currency = await _currencyRepository.GetAsync(userId, id, cancellationToken); - if (currency == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - if (!await _currencyRepository.RemoveAsync(currency, cancellationToken)) - { - return result.Set(GeneralExecStatus.failure); - } - - return result.Set(_mapper.Map(currency)); - } -} diff --git a/MyOffice.Services/Currency/Domain/CurrencyAddRateStatus.cs b/MyOffice.Services/Currency/Domain/CurrencyAddRateStatus.cs deleted file mode 100644 index 088ac18..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyAddRateStatus.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace MyOffice.Services.Currency.Domain; - -public enum CurrencyAddRateStatus -{ - not_found, - success, - failed, -} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyAddStatus.cs b/MyOffice.Services/Currency/Domain/CurrencyAddStatus.cs deleted file mode 100644 index 0c375ce..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyAddStatus.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MyOffice.Services.Currency.Domain -{ - public enum CurrencyAddStatus - { - success, - failed, - exists, - } -} diff --git a/MyOffice.Services/Currency/Domain/CurrencyDto.cs b/MyOffice.Services/Currency/Domain/CurrencyDto.cs deleted file mode 100644 index dbedf23..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyDto.cs +++ /dev/null @@ -1,32 +0,0 @@ -/// -namespace MyOffice.Services.Currency.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Currencies; -using MyOffice.Services.Account.Domain; - -public class CurrencyDto -{ - public Guid Id { get; set; } - public string CurrencyGlobalId { get; set; } = null!; - public CurrencyGlobalDto? CurrencyGlobal { get; set; } - public Guid UserId { get; set; } - public UserDto? User { get; set; } - - public string Name { get; set; } = null!; - public string ShortName { get; set; } = null!; - public List? Rates { get; set; } - - public int? CurrentRateId { get; set; } - public CurrencyRateDto? CurrentRate { get; set; } - - public bool IsPrimary { get; set; } -} - -public class CurrencyDtoProfile: Profile -{ - public CurrencyDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyEdit.cs b/MyOffice.Services/Currency/Domain/CurrencyEdit.cs deleted file mode 100644 index ddbdad7..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyEdit.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace MyOffice.Services.Currency.Domain; - -public class CurrencyEdit -{ - public string Name { get; set; } = null!; - public string ShortName { get; set; } = null!; - public bool IsPrimary { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyEditStatus.cs b/MyOffice.Services/Currency/Domain/CurrencyEditStatus.cs deleted file mode 100644 index 6ca41e4..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyEditStatus.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace MyOffice.Services.Currency.Domain; - -public enum CurrencyEditStatus -{ - success, - not_found, - failed, -} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyGlobalDto.cs b/MyOffice.Services/Currency/Domain/CurrencyGlobalDto.cs deleted file mode 100644 index 7cdaa7f..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyGlobalDto.cs +++ /dev/null @@ -1,21 +0,0 @@ -/// -namespace MyOffice.Services.Currency.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Currencies; - -public class CurrencyGlobalDto -{ - public string Id { get; set; } = null!; - public string Name { get; set; } = null!; - public string Symbol { get; set; } = null!; - public int DefaultQuantity { get; set; } -} - -public class CurrencyGlobalDtoProfile: Profile -{ - public CurrencyGlobalDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyRateDto.cs b/MyOffice.Services/Currency/Domain/CurrencyRateDto.cs deleted file mode 100644 index 60e2f07..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyRateDto.cs +++ /dev/null @@ -1,24 +0,0 @@ -/// -namespace MyOffice.Services.Currency.Domain; - -using AutoMapper; -using MyOffice.Data.Models.Currencies; - -public class CurrencyRateDto -{ - public int Id { get; set; } - public Guid CurrencyId { get; set; } - public CurrencyDto? Currency { get; set; } - public DateTime DateTime { get; set; } - public int Quantity { get; set; } - public decimal Rate { get; set; } - public List? Currencies { get; set; } -} - -public class CurrencyRateDtoProfile : Profile -{ - public CurrencyRateDtoProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyWithRateDto.cs b/MyOffice.Services/Currency/Domain/CurrencyWithRateDto.cs deleted file mode 100644 index 3aba6e2..0000000 --- a/MyOffice.Services/Currency/Domain/CurrencyWithRateDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MyOffice.Services.Currency.Domain; - -using MyOffice.Data.Models.Currencies; - -public class CurrencyWithRateDto -{ - public CurrencyDto Currency { get; set; } = null!; - public CurrencyRateDto? Rate { get; set; } -} diff --git a/MyOffice.Services/Dashboard/DashboardService.cs b/MyOffice.Services/Dashboard/DashboardService.cs deleted file mode 100644 index a09d500..0000000 --- a/MyOffice.Services/Dashboard/DashboardService.cs +++ /dev/null @@ -1,160 +0,0 @@ -namespace MyOffice.Services.Dashboard; - -using Core.Extensions; -using Data.Repositories.Account; -using Data.Repositories.Currency; -using MyOffice.Data.Models.Accounts; -using MyOffice.Services.Dashboard.Domain; - -public class DashboardService -{ - private readonly IAccountRepository _accountRepository; - private readonly ICurrencyRateRepository _currencyRateRepository; - - public DashboardService( - IAccountRepository accountRepository, - ICurrencyRateRepository currencyRateRepository - ) - { - _accountRepository = accountRepository; - _currencyRateRepository = currencyRateRepository; - } - - public async Task GetDashboardRestDataAsync( - Guid userId, - CancellationToken cancellationToken = default - ) - { - var rests = await _accountRepository.GetRestAtDateAsync(userId, DateTime.UtcNow, cancellationToken); - - return new DashboardData - { - Balance = rests - .Where(x => (x.Type == AccountAccessTypeEnum.balance || x.Type == AccountAccessTypeEnum.credit) && x.CurrencyRate.HasValue) - .Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)), - - BalanceDebit = rests - .Where(x => x.Type == AccountAccessTypeEnum.balance && x.CurrencyRate.HasValue) - .Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)), - - BalanceCredit = rests - .Where(x => x.Type == AccountAccessTypeEnum.credit && x.CurrencyRate.HasValue) - .Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)), - - BalanceRests = rests - .Where(x => x.Type == AccountAccessTypeEnum.balance) - .Where(x => x.CurrencyRate.HasValue && x.Balance.HasValue && x.Balance != 0) - .Select(x => new DashboardRestData - { - Id = x.Id, - Name = x.Name, - Balance = x.Balance, - CurrencyName = x.CurrencyName!, - CurrencyShortName = x.CurrencyShortName!, - CurrencyRate = x.CurrencyRate, - CurrencyQuantity = x.CurrencyQuantity, - }) - .OrderByDescending(x => x.BalanceAtRate) - .ToList(), - }; - } - - public async Task GetDashboardIncomeDataAsync( - Guid userId, - DateTime from, - DateTime to, - Guid? category, - CancellationToken cancellationToken = default - ) - { - var data = category.HasValue - ? await _accountRepository.GetIncomeByCategoryAsync(userId, category.Value, from.ToUtc(), to.ToUtc(), cancellationToken) - : await _accountRepository.GetIncomeByCategoriesAsync(userId, from.ToUtc(), to.ToUtc(), cancellationToken); - - data = data - .Where(x => x.Amount != 0) - .ToList(); - - var currencies = data - .Select(x => x.CurrencyId) - .Distinct() - .ToList(); - - var rates = (await _currencyRateRepository.GetLastRatesAsync(userId, currencies, to.ToUtc(), cancellationToken)) - .ToDictionary(x => x.Key, x => x.Value.Rate * x.Value.Quantity); - - return BuildIncomeData(data, rates); - } - - public async Task GetDashboardOutcomeDataAsync( - Guid userId, - DateTime from, - DateTime to, - Guid? category, - CancellationToken cancellationToken = default - ) - { - var data = category.HasValue - ? await _accountRepository.GetOutcomeByCategoryAsync(userId, category.Value, from.ToUtc(), to.ToUtc(), cancellationToken) - : await _accountRepository.GetOutcomeByCategoriesAsync(userId, from.ToUtc(), to.ToUtc(), cancellationToken); - - data = data - .Where(x => x.Amount != 0) - .ToList(); - - var currencies = data - .Select(x => x.CurrencyId) - .Distinct() - .ToList(); - - var rates = (await _currencyRateRepository.GetLastRatesAsync(userId, currencies, to.ToUtc(), cancellationToken)) - .ToDictionary(x => x.Key, x => x.Value.Rate * x.Value.Quantity); - - return BuildIncomeData(data, rates); - } - - private static DashboardIncomeData BuildIncomeData( - List data, - Dictionary rates - ) - { - return new DashboardIncomeData - { - Data = data.Select(x => new - { - Id = x.Id.ToShort(), - Name = x.Name, - ValueRaw = x.Amount, - Value = x.Amount * rates.FirstOrDefault(r => r.Key == x.CurrencyId).Value, - }) - .GroupBy(x => new { x.Id, x.Name }) - .Select(x => new DashboardIncomeDataItem - { - Id = x.Key.Id, - Name = x.Key.Name, - Value = x.Sum(s => s.Value), - ValueRaw = x.Sum(s => s.ValueRaw), - }) - .OrderBy(x => x.Name) - .ToList(), - - Details = data.Select(x => new - { - Id = x.CurrencyId, - Name = x.CurrencyName, - ValueRaw = x.Amount, - Value = x.Amount * rates.FirstOrDefault(r => r.Key == x.CurrencyId).Value, - }) - .GroupBy(x => new { x.Id, x.Name }) - .Select(x => new DashboardIncomeDataItem - { - Id = x.Key.Id, - Name = x.Key.Name, - Value = x.Sum(s => s.Value), - ValueRaw = x.Sum(s => s.ValueRaw), - }) - .OrderBy(x => x.Name) - .ToList(), - }; - } -} diff --git a/MyOffice.Services/Dashboard/Domain/DashboardData.cs b/MyOffice.Services/Dashboard/Domain/DashboardData.cs deleted file mode 100644 index 8f34850..0000000 --- a/MyOffice.Services/Dashboard/Domain/DashboardData.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace MyOffice.Services.Dashboard.Domain; - -using System.Collections.Generic; - -public class DashboardData -{ - public decimal IncomeLast { get; set; } - public decimal IncomePrevious { get; set; } - public decimal OutcomeLast { get; set; } - public decimal OutcomePrevious { get; set; } - public decimal? Balance { get; set; } - public decimal? BalanceDebit { get; set; } - public decimal? BalanceCredit { get; set; } - public List BalanceRests { get; set; } = null!; -} - -public class DashboardRestData -{ - public Guid Id { get; set; } - public string Name { get; set; } = null!; - public string CurrencyName { get; set; } = null!; - public string CurrencyShortName { get; set; } = null!; - public decimal? Balance { get; set; } - public decimal? CurrencyRate { get; set; } - public decimal? CurrencyQuantity { get; set; } - - public decimal? BalanceAtRate => Balance * (CurrencyRate * CurrencyQuantity); -} - -public class DashboardIncomeData -{ - public List Data { get; set; } = null!; - public List Details { get; set; } = null!; -} - -public class DashboardIncomeDataItem -{ - public string? Id { get; set; } - public string Currency { get; set; } = null!; - public string Name { get; set; } = null!; - public decimal Value { get; set; } - public decimal ValueRaw { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Services/Identity/IContextProvider.cs b/MyOffice.Services/Identity/IContextProvider.cs deleted file mode 100644 index b57fd11..0000000 --- a/MyOffice.Services/Identity/IContextProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Identity; - -using Data.Models.Users; - -public interface IContextProvider -{ - User User { get; } - Guid UserId { get; } -} - diff --git a/MyOffice.Services/Item/Domain/ItemCategoryRemoveResult.cs b/MyOffice.Services/Item/Domain/ItemCategoryRemoveResult.cs deleted file mode 100644 index e5d73d6..0000000 --- a/MyOffice.Services/Item/Domain/ItemCategoryRemoveResult.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Item.Domain -{ - public enum ItemCategoryRemoveResult - { - success, - failure, - not_found, - accounts_exists, - } -} diff --git a/MyOffice.Services/Item/Domain/ItemGetOrAddResult.cs b/MyOffice.Services/Item/Domain/ItemGetOrAddResult.cs deleted file mode 100644 index f3a22b0..0000000 --- a/MyOffice.Services/Item/Domain/ItemGetOrAddResult.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Services.Item.Domain -{ - public enum ItemGetOrAddResult - { - success, - failure, - not_found, - accounts_exists, - } -} diff --git a/MyOffice.Services/Item/ItemService.cs b/MyOffice.Services/Item/ItemService.cs deleted file mode 100644 index 585d180..0000000 --- a/MyOffice.Services/Item/ItemService.cs +++ /dev/null @@ -1,264 +0,0 @@ -namespace MyOffice.Services.Item; - -using AutoMapper; -using Domain; -using MyOffice.Core; -using MyOffice.Data.Models.Items; -using MyOffice.Data.Repositories.Item; -using MyOffice.Services.Account.Domain; - -public class ItemService -{ - private readonly IItemCategoryRepository _itemCategoryRepository; - private readonly IItemRepository _itemRepository; - private readonly IItemGlobalRepository _itemGlobalRepository; - private readonly IMapper _mapper; - - public ItemService( - IItemCategoryRepository itemCategoryRepository, - IItemRepository itemRepository, - IItemGlobalRepository itemGlobalRepository, - IMapper mapper - ) - { - _itemCategoryRepository = itemCategoryRepository; - _itemRepository = itemRepository; - _itemGlobalRepository = itemGlobalRepository; - _mapper = mapper; - } - - public async Task> GetAllCategoriesAsync(Guid userId, CancellationToken cancellationToken = default) - { - var result = await _itemCategoryRepository.GetAllAsync(userId, cancellationToken); - if (result.All(x => x.Id != userId)) - { - var category = new ItemCategory - { - Id = userId, - UserId = userId, - Name = "UnCategorized", - }; - await _itemCategoryRepository.AddAsync(category, cancellationToken); - - result.Add((await _itemCategoryRepository.GetAsync(userId, userId, cancellationToken))!); - } - return _mapper.Map>(result); - } - - public async Task> CategoryAddAsync( - Guid userId, - ItemCategoryDto input, - CancellationToken cancellationToken = default) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - var result = new Exec(GeneralExecStatus.success); - - var category = new ItemCategory - { - Id = Guid.NewGuid(), - UserId = userId, - Name = input.Name, - IsInternal = input.IsInternal, - }; - - if (!await _itemCategoryRepository.AddAsync(category, cancellationToken)) - { - return result.Set(GeneralExecStatus.failure); - } - - return result.Set(_mapper.Map(category)); - } - - public async Task> CategoryUpdateAsync( - Guid userId, - Guid id, - ItemCategoryDto category, - CancellationToken cancellationToken = default) - { - if (category == null) - throw new ArgumentNullException(nameof(category)); - - var result = new Exec(GeneralExecStatus.success); - - var exists = await _itemCategoryRepository.GetAsync(userId, id, cancellationToken); - if (exists == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - exists.Name = category.Name; - exists.IsInternal = category.IsInternal; - - if (!await _itemCategoryRepository.UpdateAsync(exists, cancellationToken)) - { - return result.Set(GeneralExecStatus.failure); - } - - return result.Set(_mapper.Map(exists)); - } - - public async Task> CategoryRemoveAsync( - Guid userId, - Guid id, - CancellationToken cancellationToken = default) - { - var result = new Exec(ItemCategoryRemoveResult.success); - - var exists = await _itemCategoryRepository.GetAsync(userId, id, cancellationToken); - if (exists == null) - { - return result.Set(ItemCategoryRemoveResult.not_found); - } - - if (exists.Items.Any()) - { - return result.Set(ItemCategoryRemoveResult.accounts_exists); - } - if (!await _itemCategoryRepository.RemoveAsync(exists, cancellationToken)) - { - return result.Set(ItemCategoryRemoveResult.failure); - } - - return result.Set(_mapper.Map(exists)); - } - - public async Task> GetAllAsync(Guid userId, CancellationToken cancellationToken = default) - { - return _mapper.Map>(await _itemRepository.GetAllAsync(userId, cancellationToken)); - } - - public async Task> GetByCategoryAsync( - Guid userId, - Guid categoryId, - CancellationToken cancellationToken = default) - { - return _mapper.Map>(await _itemRepository.GetByCategoryAsync(userId, categoryId, cancellationToken)); - } - - public async Task> GetByUncategorizedAsync(Guid userId, CancellationToken cancellationToken = default) - { - var itemGlobals = await _itemGlobalRepository.GetAvailableToUserAsync(userId, cancellationToken); - foreach (var itemGlobal in itemGlobals) - { - await GetOrCreateAsync(userId, itemGlobal, cancellationToken); - } - - return await GetByCategoryAsync(userId, userId, cancellationToken); - } - - public async Task> UpdateAsync( - Guid userId, - Guid motionId, - Guid categoryId, - CancellationToken cancellationToken = default) - { - var result = new Exec(GeneralExecStatus.success); - - var item = await _itemRepository.GetByGlobalAsync(userId, motionId, cancellationToken); - if (item == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - item.CategoryId = categoryId; - await _itemRepository.UpdateAsync(item, cancellationToken); - - return result.Set(_mapper.Map(item)); - } - - public async Task> GetOrCreateAsync( - Guid userId, - string name, - CancellationToken cancellationToken = default - ) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - - var result = new Exec(ItemGetOrAddResult.success); - - var itemGlobal = await _itemGlobalRepository.GetByNameAsync(name, cancellationToken); - if (itemGlobal == null) - { - itemGlobal = new ItemGlobal - { - Id = Guid.NewGuid(), - Name = name.Trim(), - }; - - if (!await _itemGlobalRepository.AddAsync(itemGlobal, cancellationToken)) - { - return result.Set(ItemGetOrAddResult.failure); - } - - return await GetOrCreateAsync(userId, itemGlobal, cancellationToken); - } - - return await GetOrCreateAsync(userId, itemGlobal, cancellationToken); - } - - private async Task> GetOrCreateAsync( - Guid userId, - ItemGlobal itemGlobal, - CancellationToken cancellationToken = default - ) - { - if (itemGlobal == null) - throw new ArgumentNullException(nameof(itemGlobal)); - - var result = new Exec(ItemGetOrAddResult.success); - - var item = await _itemRepository.GetByGlobalAsync(userId, itemGlobal.Id, cancellationToken); - if (item == null) - { - item = new Item - { - CategoryId = userId, - ItemGlobalId = itemGlobal.Id, - }; - await _itemRepository.AddAsync(item, cancellationToken); - } - - item.ItemGlobal = itemGlobal; - return result.Set(item); - } - - public async Task> FindItemsAsync( - Guid userId, - string term, - int limit = 15, - CancellationToken cancellationToken = default) - { - if (term == null) - throw new ArgumentNullException(nameof(term)); - - return _mapper.Map>(await _itemRepository.FindAsync(userId, term, limit, cancellationToken)); - } - - public async Task UpdateItemsCategoryAsync( - Guid userId, - Guid categoryId, - List items, - CancellationToken cancellationToken = default) - { - var category = await _itemCategoryRepository.GetAsync(userId, categoryId, cancellationToken); - if (category == null) - { - return GeneralExecStatus.not_found; - } - - foreach (var item in items) - { - var dbItem = await _itemRepository.GetByGlobalAsync(userId, item, cancellationToken); - if (dbItem != null) - { - dbItem.CategoryId = category.Id; - await _itemRepository.UpdateAsync(dbItem, cancellationToken); - } - } - - return GeneralExecStatus.success; - } -} diff --git a/MyOffice.Services/Mapper/AutomapperExtensions.cs b/MyOffice.Services/Mapper/AutomapperExtensions.cs deleted file mode 100644 index 9cee4be..0000000 --- a/MyOffice.Services/Mapper/AutomapperExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using AutoMapper; -using MyOffice.Core; - -namespace MyOffice.Services; - -public static class AutomapperExtensions -{ - public static List ToDto(this IEnumerable list, IMapper mapper) - { - return mapper.Map>(list); - } - - public static TTo ToDto(this IDataModel item, IMapper mapper) - { - return mapper.Map(item); - } -} diff --git a/MyOffice.Services/Mapper/BaseMappingAction.cs b/MyOffice.Services/Mapper/BaseMappingAction.cs deleted file mode 100644 index c518055..0000000 --- a/MyOffice.Services/Mapper/BaseMappingAction.cs +++ /dev/null @@ -1,12 +0,0 @@ -using MyOffice.Services.Identity; - -namespace MyOffice.Services.Mapper; - -public class BaseMappingAction -{ - protected readonly IContextProvider ContextProvider; - public BaseMappingAction(IContextProvider contextProvider) - { - ContextProvider = contextProvider; - } -} diff --git a/MyOffice.Services/Mapper/BaseProfile.cs b/MyOffice.Services/Mapper/BaseProfile.cs deleted file mode 100644 index e1932b8..0000000 --- a/MyOffice.Services/Mapper/BaseProfile.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AutoMapper; - -namespace MyOffice.Services.Mapper; - -public class BaseProfile : Profile -{ - protected IMappingExpression Mapping; - - public BaseProfile() - { - Mapping = CreateMap(); - } -} diff --git a/MyOffice.Services/Mapper/UserIdResolver.cs b/MyOffice.Services/Mapper/UserIdResolver.cs deleted file mode 100644 index cd87127..0000000 --- a/MyOffice.Services/Mapper/UserIdResolver.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace MyOffice.Services.Mapper; - -using AutoMapper; -using Identity; - -public class UserIdResolver : IValueResolver -{ - private readonly IContextProvider _contextProvider; - - public UserIdResolver( - IContextProvider contextProvider - ) - { - _contextProvider = contextProvider; - } - - public Guid Resolve(object source, object destination, Guid member, ResolutionContext context) - { - return _contextProvider.UserId; - } -} \ No newline at end of file diff --git a/MyOffice.Services/MyOffice.Services.csproj b/MyOffice.Services/MyOffice.Services.csproj deleted file mode 100644 index f4e8c86..0000000 --- a/MyOffice.Services/MyOffice.Services.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - - - - - - diff --git a/MyOffice.Services/Notifications/EmailNotificationService.cs b/MyOffice.Services/Notifications/EmailNotificationService.cs deleted file mode 100644 index 6374e9b..0000000 --- a/MyOffice.Services/Notifications/EmailNotificationService.cs +++ /dev/null @@ -1,80 +0,0 @@ -namespace MyOffice.Services.Notifications; - -using MyOffice.Core; -using MyOffice.Data.Models.Notifications; -using MyOffice.Data.Models.Users; -using MyOffice.Data.Models.Verifications; -using MyOffice.Data.Repositories.Item; -using MyOffice.Services.Verifications; - -public class EmailNotificationService -{ - private readonly VerificationService _verificationService; - - public EmailNotificationService( - VerificationService verificationService - ) - { - _verificationService = verificationService; - } - - public void PasswordResetEmail(User user) - { - var code = _verificationService.Add( - user, - user.Email, - VerificationCodeTemplateEnum.password_restore, - VerificationCodeTypeEnum.email - ); - - var subject = ""; - var body = ""; - } -} - -public class TemplateSevice -{ - private readonly IEmailTemplateRepository _emailTemplateRepository; - - public TemplateSevice( - IEmailTemplateRepository emailTemplateRepository - ) - { - _emailTemplateRepository = emailTemplateRepository; - } - - public Exec GetTemplate( - EmailTemplateEnum template, - Dictionary tokens - ) - { - var result = new Exec(GeneralExecStatus.success); - - var emailTemplate = _emailTemplateRepository.Get(template); - if (emailTemplate == null) - { - return result.Set(GeneralExecStatus.not_found); - } - - result.Set(new EmailTemplateFormated - { - Subject = emailTemplate.Subject, - Body = emailTemplate.Template, - }); - - return result; - } -} - -public class EmailTemplateFormated -{ - public string Sender { get; set; } - public string SenderName { get; set; } - public string Subject { get; set; } - public string Body { get; set; } -} - -public interface IEmailSender -{ - //Exec Send(string from, string[] to, string subject, string body); -} \ No newline at end of file diff --git a/MyOffice.Services/Users/Domain/AddUserExternalStatusEnum.cs b/MyOffice.Services/Users/Domain/AddUserExternalStatusEnum.cs deleted file mode 100644 index b90155f..0000000 --- a/MyOffice.Services/Users/Domain/AddUserExternalStatusEnum.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace MyOffice.Services.Users.Domain; - -public enum AddUserExternalStatusEnum -{ - success, - externalid_used, - user_not_valid -} \ No newline at end of file diff --git a/MyOffice.Services/Users/UserService.cs b/MyOffice.Services/Users/UserService.cs deleted file mode 100644 index 115b8af..0000000 --- a/MyOffice.Services/Users/UserService.cs +++ /dev/null @@ -1,96 +0,0 @@ -namespace MyOffice.Services.Users; - -using Domain; -using Core; -using Data.Models.Users; -using Data.Repositories.Users; - -public class UserService -{ - private readonly IUserRepository _userRepository; - private readonly IUserExternalRepository _userExternalRepository; - private readonly SemaphoreSlim _addExternalLock = new(1, 1); - - public UserService( - IUserRepository userRepository, - IUserExternalRepository userExternalRepository - ) - { - _userRepository = userRepository; - _userExternalRepository = userExternalRepository; - } - - public async Task Get(Guid id) - { - return await _userRepository.GetUserAsync(id); - } - - public async Task> GetUserExternals(Guid userId) - { - return await _userExternalRepository.GetUserExternalsByUserIdAsync(userId); - } - - public async Task GetUserExternal(Guid userId, string provider) - { - return await _userExternalRepository.GetByUserIdAsync(userId, provider); - } - - public async Task> RemoveUserExternal( - Guid userId, - string provider, - CancellationToken cancellationToken = default) - { - var result = new Exec(); - - var userExternal = await _userExternalRepository.GetByUserIdAsync(userId, provider); - if (userExternal == null) return result.Set(GeneralExecStatus.not_found); - - await _userExternalRepository.RemoveUserExternalAsync(userExternal, cancellationToken); - - return result.Set(userExternal); - } - - public async Task> AddUserExternalAsync( - Guid userId, - string provider, - string externalId, - string email, - CancellationToken cancellationToken = default - ) - { - var result = new Exec(AddUserExternalStatusEnum.success); - - var externalLogin = await _userExternalRepository.GetByUserIdAsync(userId, provider); - - if (externalLogin != null) return result.Set(externalLogin); - - await _addExternalLock.WaitAsync(cancellationToken); - try - { - externalLogin = await _userExternalRepository.GetByUserIdAsync(userId, provider); - if (externalLogin != null) return result.Set(externalLogin); - - externalLogin = await _userExternalRepository.GetByExternalIdAsync(externalId, provider); - if (externalLogin != null) return result.Set(AddUserExternalStatusEnum.externalid_used); - - var user = await _userRepository.GetByUserUserNameAsync(email); - if (user?.Id != userId) return result.Set(AddUserExternalStatusEnum.user_not_valid); - - externalLogin = new UserExternal - { - UserId = userId, - CreatedOn = DateTime.UtcNow, - Provider = provider.ToLower(), - ExternalId = externalId, - Email = email - }; - await _userExternalRepository.AddUserExternalAsync(externalLogin, cancellationToken); - } - finally - { - _addExternalLock.Release(); - } - - return result; - } -} diff --git a/MyOffice.Services/Validators/ContextValidator.cs b/MyOffice.Services/Validators/ContextValidator.cs deleted file mode 100644 index f844d8a..0000000 --- a/MyOffice.Services/Validators/ContextValidator.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyOffice.Services.Validators -{ - public static class ContextValidator - { - } -} diff --git a/MyOffice.Services/Verifications/VerificationService.cs b/MyOffice.Services/Verifications/VerificationService.cs deleted file mode 100644 index 988b11b..0000000 --- a/MyOffice.Services/Verifications/VerificationService.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace MyOffice.Services.Verifications; - -using MyOffice.Core.Helpers; -using MyOffice.Data.Models.Users; -using MyOffice.Data.Models.Verifications; -using MyOffice.Data.Repositories.Item; - -public class VerificationService -{ - private readonly TimeSpan _defaultExpires = TimeSpan.FromDays(1); - - private readonly IVerificationCodeRepository _verificationCodeRepository; - - public VerificationService( - IVerificationCodeRepository verificationCodeRepository - ) - { - _verificationCodeRepository = verificationCodeRepository; - } - - public VerificationCode Add( - User user, - string destination, - VerificationCodeTemplateEnum template, - VerificationCodeTypeEnum type, - DateTime? expiresOn = null, - string? metadata = null - ) - { - if (user == null) - throw new ArgumentNullException(nameof(user)); - if (destination == null) - throw new ArgumentNullException(nameof(destination)); - - var verificationCode = new VerificationCode - { - UserId = user.Id, - Code = RandomizationHelper.Generate(40), - CreatedOn = DateTime.UtcNow, - ExpiresOn = expiresOn ?? DateTime.UtcNow.Add(_defaultExpires), - Template = template.ToString(), - DestinationType = type.ToString(), - Destination = destination, - Metadata = metadata, - }; - - _verificationCodeRepository.Add(verificationCode); - - return verificationCode; - } -} \ No newline at end of file diff --git a/MyOffice.Shared/Configuration.cs b/MyOffice.Shared/Configuration.cs deleted file mode 100644 index 5d75f75..0000000 --- a/MyOffice.Shared/Configuration.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace MyOffice.Shared; - -using Microsoft.Extensions.Configuration; - -public static class SharedConfiguration -{ - public const string BaseFileName = "appsettings.shared.json"; - - /// - /// Adds shared JSON sources to an existing configuration builder (base + environment overlay). - /// - public static IConfigurationBuilder AddSharedAppSettings( - this IConfigurationBuilder builder, - string environmentName, - string? basePath = null, - bool optional = false, - bool reloadOnChange = true - ) - { - basePath ??= AppContext.BaseDirectory; - - builder - .AddJsonFile(Path.Combine(basePath, BaseFileName), optional: optional, reloadOnChange: reloadOnChange) - .AddJsonFile( - Path.Combine(basePath, $"appsettings.shared.{environmentName}.json"), - optional: true, - reloadOnChange: reloadOnChange); - - return builder; - } - - /// - /// Builds a standalone configuration for design-time tools (EF migrations, etc.). - /// Layering: base shared → environment shared → environment variables. - /// - public static IConfiguration Build(string? environmentName = null) - { - environmentName ??= Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") - ?? Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") - ?? "Production"; - - return new ConfigurationBuilder() - .SetBasePath(AppContext.BaseDirectory) - .AddSharedAppSettings(environmentName, optional: false, reloadOnChange: false) - .AddEnvironmentVariables() - .Build(); - } -} diff --git a/MyOffice.Shared/MyOffice.Shared.csproj b/MyOffice.Shared/MyOffice.Shared.csproj deleted file mode 100644 index cc156eb..0000000 --- a/MyOffice.Shared/MyOffice.Shared.csproj +++ /dev/null @@ -1,40 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - - - - Always - true - - - Always - true - PreserveNewest - - - Always - true - - - Always - true - PreserveNewest - - - - - - - - - - diff --git a/MyOffice.Shared/appsettings.shared.Docker.json b/MyOffice.Shared/appsettings.shared.Docker.json deleted file mode 100644 index 86dc9f0..0000000 --- a/MyOffice.Shared/appsettings.shared.Docker.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ConnectionStrings": { - "npgsql": "Host=postgres;Port=5432;Database=myoffice;Username=myoffice;Password=myoffice" - } -} diff --git a/MyOffice.Shared/appsettings.shared.json b/MyOffice.Shared/appsettings.shared.json deleted file mode 100644 index 4c8cd57..0000000 --- a/MyOffice.Shared/appsettings.shared.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ConnectionStrings": { - "sqlite": "Filename=AppDbContext.Dev.db", - "mssql": "", - "npgsql": "" - } -} \ No newline at end of file diff --git a/MyOffice.Tests/Account/AccountAclTests.cs b/MyOffice.Tests/Account/AccountAclTests.cs deleted file mode 100644 index f931d5c..0000000 --- a/MyOffice.Tests/Account/AccountAclTests.cs +++ /dev/null @@ -1,65 +0,0 @@ -using MyOffice.Data.Models.Accounts; -using MyOffice.Services.Account; -using AccountEntity = MyOffice.Data.Models.Accounts.Account; - -namespace MyOffice.Tests.Accounts; - -public class AccountAclTests -{ - private static AccountEntity CreateAccount(Guid userId, bool write, bool manage) - { - return new AccountEntity - { - Id = Guid.NewGuid(), - Name = "Cash", - AccessRights = - [ - new AccountAccess - { - UserId = userId, - IsAllowRead = true, - IsAllowWrite = write, - IsAllowManage = manage, - } - ] - }; - } - - [Fact] - public void CanWrite_true_when_flag_set() - { - var userId = Guid.NewGuid(); - var account = CreateAccount(userId, write: true, manage: false); - - Assert.True(AccountAcl.CanWrite(account, userId)); - Assert.False(AccountAcl.CanManage(account, userId)); - } - - [Fact] - public void CanManage_true_when_flag_set() - { - var userId = Guid.NewGuid(); - var account = CreateAccount(userId, write: false, manage: true); - - Assert.False(AccountAcl.CanWrite(account, userId)); - Assert.True(AccountAcl.CanManage(account, userId)); - } - - [Fact] - public void CanWrite_false_for_other_user() - { - var account = CreateAccount(Guid.NewGuid(), write: true, manage: true); - - Assert.False(AccountAcl.CanWrite(account, Guid.NewGuid())); - Assert.False(AccountAcl.CanManage(account, Guid.NewGuid())); - } - - [Fact] - public void CanWrite_false_when_access_rights_null() - { - var account = new AccountEntity { Id = Guid.NewGuid(), Name = "X", AccessRights = null }; - - Assert.False(AccountAcl.CanWrite(account, Guid.NewGuid())); - Assert.False(AccountAcl.CanManage(account, Guid.NewGuid())); - } -} diff --git a/MyOffice.Tests/Account/AccountMotionBalancingTests.cs b/MyOffice.Tests/Account/AccountMotionBalancingTests.cs deleted file mode 100644 index 4a3163a..0000000 --- a/MyOffice.Tests/Account/AccountMotionBalancingTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -using MyOffice.Services.Account; - -namespace MyOffice.Tests.Accounts; - -public class AccountMotionBalancingTests -{ - [Fact] - public void ResolveAmounts_income_primary_creates_expense_on_balancing() - { - var (plus, minus) = AccountMotionBalancing.ResolveAmounts(primaryPlus: 100m, amountBalancing: 100m); - - Assert.Equal(0m, plus); - Assert.Equal(100m, minus); - } - - [Fact] - public void ResolveAmounts_expense_primary_creates_income_on_balancing() - { - var (plus, minus) = AccountMotionBalancing.ResolveAmounts(primaryPlus: 0m, amountBalancing: 50m); - - Assert.Equal(50m, plus); - Assert.Equal(0m, minus); - } - - [Fact] - public void BalancingItemName_prefixes_account_name() - { - Assert.Equal("+Wallet", AccountMotionBalancing.BalancingItemName("Wallet")); - } -} diff --git a/MyOffice.Tests/Account/MotionAddAclTests.cs b/MyOffice.Tests/Account/MotionAddAclTests.cs deleted file mode 100644 index 7088c74..0000000 --- a/MyOffice.Tests/Account/MotionAddAclTests.cs +++ /dev/null @@ -1,173 +0,0 @@ -using AutoMapper; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using Moq; -using MyOffice.Data.Models.Accounts; -using MyOffice.Data.Models.Items; -using MyOffice.Data.Repositories.Account; -using MyOffice.Data.Repositories.Currency; -using MyOffice.Data.Repositories.Item; -using MyOffice.Services.Account; -using MyOffice.Services.Account.Domain; -using MyOffice.Services.Identity; -using MyOffice.Services.Item; - -using AccountEntity = MyOffice.Data.Models.Accounts.Account; - -namespace MyOffice.Tests.Accounts; - -public class MotionAddAclTests -{ - [Fact] - public async Task MotionAddAsync_returns_forbidden_without_write_access() - { - var userId = Guid.NewGuid(); - var accountId = Guid.NewGuid(); - var account = new AccountEntity - { - Id = accountId, - Name = "Cash", - AccessRights = - [ - new AccountAccess - { - UserId = userId, - IsAllowRead = true, - IsAllowWrite = false, - IsAllowManage = false, - } - ] - }; - - var accountRepo = new Mock(); - accountRepo - .Setup(x => x.GetAsync(userId, accountId, It.IsAny())) - .ReturnsAsync(account); - - var service = CreateService(accountRepo.Object); - - var exec = await service.MotionAddAsync( - userId, - accountId, - new MotionAddUpdate - { - Date = DateTime.UtcNow, - Item = "Coffee", - Plus = 0, - Minus = 10, - }); - - Assert.Equal(MotionAddStatus.forbidden, exec.Status); - } - - [Fact] - public async Task MotionAddAsync_skips_balancing_when_counterparty_not_writable() - { - var userId = Guid.NewGuid(); - var primaryId = Guid.NewGuid(); - var balancingId = Guid.NewGuid(); - - var primary = new AccountEntity - { - Id = primaryId, - Name = "Cash", - AccessRights = - [ - new AccountAccess { UserId = userId, IsAllowRead = true, IsAllowWrite = true } - ] - }; - var balancing = new AccountEntity - { - Id = balancingId, - Name = "Bank", - AccessRights = - [ - new AccountAccess { UserId = userId, IsAllowRead = true, IsAllowWrite = false } - ] - }; - - var accountRepo = new Mock(); - accountRepo - .Setup(x => x.GetAsync(userId, primaryId, It.IsAny())) - .ReturnsAsync(primary); - accountRepo - .Setup(x => x.GetAsync(userId, balancingId, It.IsAny())) - .ReturnsAsync(balancing); - - var motionRepo = new Mock(); - motionRepo - .Setup(x => x.AddAsync(It.IsAny(), It.IsAny())) - .ReturnsAsync(true); - - var service = CreateService(accountRepo.Object, motionRepo.Object); - - var exec = await service.MotionAddAsync( - userId, - primaryId, - new MotionAddUpdate - { - Date = DateTime.UtcNow, - Item = "Transfer", - Plus = 0, - Minus = 25, - AccountId = balancingId.ToString("N"), - AmountBalancing = 25, - }); - - Assert.Equal(MotionAddStatus.success, exec.Status); - Assert.NotNull(exec.Result); - Assert.Single(exec.Result!); - motionRepo.Verify(x => x.AddAsync(It.IsAny(), It.IsAny()), Times.Once); - } - - private static ItemService CreateItemServiceStub() - { - var nextId = 1; - var itemRepo = new Mock(); - var itemGlobalRepo = new Mock(); - - itemGlobalRepo - .Setup(x => x.GetByNameAsync(It.IsAny(), It.IsAny())) - .ReturnsAsync((ItemGlobal?)null); - itemGlobalRepo - .Setup(x => x.AddAsync(It.IsAny(), It.IsAny())) - .ReturnsAsync(true); - itemRepo - .Setup(x => x.GetByGlobalAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync((Item?)null); - itemRepo - .Setup(x => x.AddAsync(It.IsAny(), It.IsAny())) - .ReturnsAsync(true) - .Callback((i, _) => i.Id = nextId++); - - return new ItemService( - Mock.Of(), - itemRepo.Object, - itemGlobalRepo.Object, - new MapperConfiguration(_ => { }, NullLoggerFactory.Instance).CreateMapper()); - } - - private static AccountService CreateService( - IAccountRepository accountRepository, - IMotionRepository? motionRepository = null) - { - var mapper = new MapperConfiguration( - cfg => cfg.AddProfile(), - NullLoggerFactory.Instance).CreateMapper(); - - return new AccountService( - Mock.Of>(), - mapper, - Mock.Of(), - Mock.Of(), - Mock.Of(), - accountRepository, - Mock.Of(), - Mock.Of(), - motionRepository ?? Mock.Of(), - Mock.Of(), - Mock.Of(), - CreateItemServiceStub(), - Mock.Of()); - } -} diff --git a/MyOffice.Tests/Auth/OpenIddictRedirectUriTests.cs b/MyOffice.Tests/Auth/OpenIddictRedirectUriTests.cs deleted file mode 100644 index ac21b6c..0000000 --- a/MyOffice.Tests/Auth/OpenIddictRedirectUriTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -using MyOffice.Web.Auth; - -namespace MyOffice.Tests.Auth; - -public class OpenIddictRedirectUriTests -{ - [Fact] - public void BuildRedirectUri_uses_localhost_when_host_empty() - { - var uri = OpenIddictSeeder.BuildRedirectUri(null); - - Assert.Equal("http://localhost:4300/silent-refresh.html", uri.ToString()); - } - - [Fact] - public void BuildRedirectUri_appends_silent_refresh_and_trims_slash() - { - var uri = OpenIddictSeeder.BuildRedirectUri("https://app.example.com/"); - - Assert.Equal("https://app.example.com/silent-refresh.html", uri.ToString()); - } -} diff --git a/MyOffice.Tests/Auth/PasswordHasherTests.cs b/MyOffice.Tests/Auth/PasswordHasherTests.cs deleted file mode 100644 index 6182366..0000000 --- a/MyOffice.Tests/Auth/PasswordHasherTests.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using MyOffice.Web.Identity.Domain; -using MyOffice.Web.Identity.Repositories; - -namespace MyOffice.Tests.Auth; - -public class PasswordHasherTests -{ - private readonly PasswordHasher _hasher = new(); - private readonly ApplicationUser _user = new() { Id = Guid.NewGuid(), UserName = "test@example.com" }; - - [Fact] - public void HashPassword_then_verify_succeeds_with_identity_format() - { - var hash = _hasher.HashPassword(_user, "P@ssw0rd!"); - - Assert.Equal(PasswordVerificationResult.Success, _hasher.VerifyHashedPassword(_user, hash, "P@ssw0rd!")); - } - - [Fact] - public void VerifyHashedPassword_fails_for_wrong_password() - { - var hash = _hasher.HashPassword(_user, "P@ssw0rd!"); - - Assert.Equal(PasswordVerificationResult.Failed, _hasher.VerifyHashedPassword(_user, hash, "wrong")); - } - - [Fact] - public void HashPassword_produces_distinct_hashes_due_to_salt() - { - var a = _hasher.HashPassword(_user, "same"); - var b = _hasher.HashPassword(_user, "same"); - - Assert.NotEqual(a, b); - } - - [Fact] - public void VerifyHashedPassword_legacy_hash_returns_rehash_needed() - { - var legacy = PasswordHasher.HashLegacyForTests("legacy-secret"); - - Assert.Equal( - PasswordVerificationResult.SuccessRehashNeeded, - _hasher.VerifyHashedPassword(_user, legacy, "legacy-secret")); - } - - [Fact] - public void VerifyHashedPassword_legacy_wrong_password_fails() - { - var legacy = PasswordHasher.HashLegacyForTests("legacy-secret"); - - Assert.Equal( - PasswordVerificationResult.Failed, - _hasher.VerifyHashedPassword(_user, legacy, "nope")); - } -} diff --git a/MyOffice.Tests/Data/DemoDataSeederTests.cs b/MyOffice.Tests/Data/DemoDataSeederTests.cs deleted file mode 100644 index d03991d..0000000 --- a/MyOffice.Tests/Data/DemoDataSeederTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.Data.Sqlite; -using Microsoft.EntityFrameworkCore; -using MyOffice.DbContext; - -namespace MyOffice.Tests.Data; - -public class DemoDataSeederTests -{ - [Fact] - public async Task SeedIfEmpty_creates_demo_users_catalog_and_motions() - { - var path = Path.Combine(Path.GetTempPath(), $"myoffice-seed-{Guid.NewGuid():N}.db"); - var connection = new ConnectionConfiguration("sqlite", $"Data Source={path}"); - var options = new DbContextOptionsBuilder(); - DbContextServiceCollectionExtensions.ConfigureDbContextOptions(options, connection); - - await using (var db = new AppDbContext(AppDbContextProvidersEnum.sqlite, options.Options)) - { - await DatabaseBootstrapper.InitializeAsync(db); - - Assert.Equal(3, await db.Users.CountAsync()); - Assert.Equal(9, await db.Currencies.CountAsync()); - Assert.Equal(9, await db.CurrencyRates.CountAsync()); - Assert.Equal(9, await db.AccountCategories.CountAsync()); - Assert.Equal(27, await db.Accounts.CountAsync()); - Assert.Equal(300, await db.Motions.CountAsync()); - - var uahUser = await db.Users.SingleAsync(x => x.Email == "user_UAH@user_UAH.userUAH"); - Assert.Equal("UAH", uahUser.CurrencyId); - - var uahRates = await db.CurrencyRates - .Include(x => x.Currency) - .Where(x => x.Currency!.UserId == uahUser.Id) - .ToListAsync(); - Assert.Equal(1m, uahRates.Single(x => x.Currency!.CurrencyGlobalId == "UAH").Rate); - Assert.Equal(42m, uahRates.Single(x => x.Currency!.CurrencyGlobalId == "USD").Rate); - Assert.Equal(50m, uahRates.Single(x => x.Currency!.CurrencyGlobalId == "EUR").Rate); - - Assert.Contains(await db.AccountCategories.Where(x => x.UserId == uahUser.Id).Select(x => x.Name).ToListAsync(), - x => x == "Готівка"); - Assert.Contains(await db.ItemCategories.Where(x => x.UserId == uahUser.Id).Select(x => x.Name).ToListAsync(), - x => x == "Доходи"); - - await DemoDataSeeder.SeedIfEmptyAsync(db); - Assert.Equal(3, await db.Users.CountAsync()); - } - - SqliteConnection.ClearAllPools(); - if (File.Exists(path)) - { - File.Delete(path); - } - } -} diff --git a/MyOffice.Tests/MyOffice.Tests.csproj b/MyOffice.Tests/MyOffice.Tests.csproj deleted file mode 100644 index f1d43c2..0000000 --- a/MyOffice.Tests/MyOffice.Tests.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net10.0 - enable - enable - false - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MyOffice.Web/App.Config b/MyOffice.Web/App.Config deleted file mode 100644 index cae4452..0000000 --- a/MyOffice.Web/App.Config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/MyOffice.Web/Controllers/AccountController.cs b/MyOffice.Web/Controllers/AccountController.cs deleted file mode 100644 index c313bea..0000000 --- a/MyOffice.Web/Controllers/AccountController.cs +++ /dev/null @@ -1,187 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using AutoMapper; -using Core; -using Core.Extensions; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Models.Account; -using Models.Item; -using Models.Motion; -using MyOffice.Web.Infrastructure.Attributes; -using Services.Account; -using Services.Account.Domain; -using Services.Item; - -[Authorize] -[ApiController] -[Route("api/accounts")] -[DefaultFromBody] -public class AccountController : BaseApiController -{ - private readonly ILogger _logger; - private readonly IMapper _mapper; - private readonly AccountService _accountService; - private readonly ItemService _itemService; - - public AccountController( - ILogger logger, - IMapper mapper, - AccountService accountService, - ItemService itemService - ) - { - _logger = logger; - _mapper = mapper; - _accountService = accountService; - _itemService = itemService; - } - - [HttpGet] - public async Task AccountsGet([FromQuery] string category) - { - var list = await _accountService.GetByCategoryDetailedAsync(UserId, category!.AsGuid()); - - return OkResponse(_mapper.Map>(list.OrderBy(x => x.Account.Name).ToList())); - } - - [HttpGet("{id}")] - public async Task AccountGet(string id) - { - var exec = await _accountService.GetByIdDetailedAsync(UserId, id!.AsGuid()); - - return MapGeneralExec( - exec, - result => OkResponse(_mapper.Map(result)), - notFoundDetail: "Account not found.", - failureDetail: "Failed to load account."); - } - - [HttpGet("{id}/motions")] - public async Task MotionsGet(string id, [FromQuery] MotionsGetRequest request) - { - var exec = await _accountService.GetMotionsAsync( - UserId, - id!.AsGuid(), - request.From.StartOfDay(), - request.To.EndOfDay()); - - return MapGeneralExec( - exec, - result => OkResponse(_mapper.Map>(result)), - notFoundDetail: "Account not found.", - failureDetail: "Failed to load motions."); - } - - [HttpPost("{id}/motions")] - public async Task MotionsPost(string id, MotionRequest motion) - { - var exec = await _accountService.MotionAddAsync( - UserId, - id.AsGuid(), - _mapper.Map(motion)); - - switch (exec.Status) - { - case MotionAddStatus.account_not_found: - return ProblemNotFoundResponse("Account not found."); - case MotionAddStatus.forbidden: - return ProblemForbiddenResponse("Write access required."); - case MotionAddStatus.failure: - return ProblemBadResponse("Adding motion failed."); - case MotionAddStatus.success: - return Ok(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPut("{id}/motions/{motionId}")] - public async Task MotionsPut(string id, string motionId, MotionRequest motion) - { - var exec = await _accountService.MotionUpdateAsync( - UserId, - id.AsGuid(), - motionId.AsGuid(), - _mapper.Map(motion)); - - switch (exec.Status) - { - case MotionUpdateStatus.not_found: - return ProblemNotFoundResponse("Motion not found."); - case MotionUpdateStatus.forbidden: - return ProblemForbiddenResponse("Write access required."); - case MotionUpdateStatus.failure: - return ProblemBadResponse("Updating motion failed."); - case MotionUpdateStatus.success: - return OkResponse(_mapper.Map>(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpDelete("{id}/motions/{motionId}")] - public async Task MotionsDelete(string id, string motionId) - { - var exec = await _accountService.MotionRemoveAsync( - UserId, - id.AsGuid(), - motionId.AsGuid()); - - switch (exec.Status) - { - case MotionDeleteStatus.not_found: - return ProblemNotFoundResponse("Motion not found."); - case MotionDeleteStatus.forbidden: - return ProblemForbiddenResponse("Write access required."); - case MotionDeleteStatus.failure: - return ProblemBadResponse("Deliting motion failed."); - case MotionDeleteStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpGet("~/api/items")] - public async Task FindItems([FromQuery] string term, CancellationToken cancellationToken) - { - var itemsDto = await _itemService.FindItemsAsync(UserId, term, cancellationToken: cancellationToken); - - var items = _mapper.Map>(itemsDto); - - if (term.StartsWith("+") && term.Length > 1) - { - var foundAccounts = await _accountService.FindAccountsAsync(UserId, term.Substring(1), cancellationToken); - var accounts = foundAccounts.OrderByDescending(x => x.Name); - - foreach (var account in accounts) - { - var accountName = $"+{account.Name}"; - var item = items.FirstOrDefault(x => x.Name.IsPresent() && x.Name!.Length > 1 && x.Name.Substring(1) == accountName); - - if (item == null) - { - items.Add(new ItemViewModel - { - Name = accountName, - AccountId = account.Id.ToShort(), - }); - } - else - { - item.AccountId = account.Id.ToShort(); - } - } - } - - return OkResponse(_mapper - .Map>(items) - .OrderBy(x => x.AccountId) - .ThenBy(x => x.Name) - ); - } -} diff --git a/MyOffice.Web/Controllers/AuthorizationController.cs b/MyOffice.Web/Controllers/AuthorizationController.cs deleted file mode 100644 index 968c32d..0000000 --- a/MyOffice.Web/Controllers/AuthorizationController.cs +++ /dev/null @@ -1,71 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using System.Security.Claims; -using Data.Repositories.Users; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using OpenIddict.Server.AspNetCore; -using OpenIddict.Validation.AspNetCore; -using static OpenIddict.Abstractions.OpenIddictConstants; - -[ApiController] -public sealed class AuthorizationController : ControllerBase -{ - private readonly IUserRepository _userRepository; - - public AuthorizationController(IUserRepository userRepository) - { - _userRepository = userRepository; - } - - [Authorize(AuthenticationSchemes = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)] - [HttpGet("~/connect/authorize")] - [HttpPost("~/connect/authorize")] - public async Task Authorize() - { - var result = await HttpContext.AuthenticateAsync( - OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); - if (!result.Succeeded) - { - return Forbid( - authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary - { - [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, - [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = - "The user is not authenticated." - })); - } - - return SignIn(result.Principal!, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); - } - - [Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)] - [HttpGet("~/connect/userinfo")] - [HttpPost("~/connect/userinfo")] - [Produces("application/json")] - public async Task Userinfo() - { - var userIdValue = User.FindFirstValue(Claims.Subject); - if (!Guid.TryParse(userIdValue, out var userId)) - return Challenge(authenticationSchemes: OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); - - var user = await _userRepository.GetUserAsync(userId); - if (user is null) - return Challenge(authenticationSchemes: OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); - - return Ok(new - { - sub = userIdValue, - id = userIdValue, - email = user.Email, - name = user.FullName ?? user.UserName, - firstName = user.FirstName, - lastName = user.LastName, - fullName = user.FullName, - phone = user.Phone - }); - } -} diff --git a/MyOffice.Web/Controllers/BaseApiController.cs b/MyOffice.Web/Controllers/BaseApiController.cs deleted file mode 100644 index d6131ed..0000000 --- a/MyOffice.Web/Controllers/BaseApiController.cs +++ /dev/null @@ -1,80 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using System.Security.Authentication; -using Microsoft.AspNetCore.Mvc; -using Core; -using Core.Extensions; -using IdentityModel; -using MyOffice.Web.Infrastructure.Attributes; -using MyOffice.Web.Models; - -[DefaultFromBody] -public class BaseApiController : ControllerBase -{ - public Guid UserId - { - get - { - var subject = User.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject)?.Value; - if (subject.IsPresent() && Guid.TryParse(subject, out var guid)) return guid; - - throw new AuthenticationException("Get UserId failed"); - } - } - - [NonAction] - public ObjectResult ProblemBadResponse(string? detail = null) - { - return Problem(detail, statusCode: StatusCodes.Status400BadRequest); - } - - [NonAction] - public ObjectResult ProblemNotFoundResponse(string? detail = null) - { - return Problem(detail ?? "Not found.", statusCode: StatusCodes.Status404NotFound); - } - - [NonAction] - public ObjectResult ProblemForbiddenResponse(string? detail = null) - { - return Problem(detail ?? "Forbidden.", statusCode: StatusCodes.Status403Forbidden); - } - - [NonAction] - public ObjectResult OkResponse(IResponseModel response) - { - return Ok(response); - } - - [NonAction] - public ObjectResult OkResponse(IEnumerable response) where T : IResponseModel - { - return Ok(response); - } - - /// - /// Maps to ProblemDetails status codes: - /// not_found → 404, forbidden → 403, failure → 400. - /// - protected ObjectResult MapGeneralExec( - Exec exec, - Func onSuccess, - string notFoundDetail, - string? failureDetail = null, - string? forbiddenDetail = null) where T : class - { - switch (exec.Status) - { - case GeneralExecStatus.success: - return onSuccess(exec.Result!); - case GeneralExecStatus.not_found: - return ProblemNotFoundResponse(notFoundDetail); - case GeneralExecStatus.forbidden: - return ProblemForbiddenResponse(forbiddenDetail); - case GeneralExecStatus.failure: - return ProblemBadResponse(failureDetail ?? "Operation failed."); - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } -} \ No newline at end of file diff --git a/MyOffice.Web/Controllers/DashboardController.cs b/MyOffice.Web/Controllers/DashboardController.cs deleted file mode 100644 index bd6c188..0000000 --- a/MyOffice.Web/Controllers/DashboardController.cs +++ /dev/null @@ -1,75 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using AutoMapper; -using Core.Extensions; -using Infrastructure.Attributes; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using MyOffice.Web.Models.Dashboard; -using Services.Dashboard; - -[Authorize] -[ApiController] -[Route("api/dashboard")] -[DefaultFromBody] -public class DashboardController : BaseApiController -{ - private readonly ILogger _logger; - private readonly DashboardService _dashboardService; - private readonly IMapper _mapper; - - public DashboardController( - ILogger logger, - DashboardService dashboardService, - IMapper mapper - ) - { - _logger = logger; - _dashboardService = dashboardService; - _mapper = mapper; - } - - [HttpGet] - public async Task Index(CancellationToken cancellationToken) - { - var data = await _dashboardService.GetDashboardRestDataAsync(UserId, cancellationToken); - - return OkResponse(_mapper.Map(data)); - } - - [HttpGet("income")] - public async Task Income( - DateTime from, - DateTime to, - [AsGuid(true)] string? category, - CancellationToken cancellationToken - ) - { - var data = await _dashboardService.GetDashboardIncomeDataAsync( - UserId, - from.StartOfDay(), - to.EndOfDay(), - category?.AsGuidNull(), - cancellationToken); - - return OkResponse(_mapper.Map(data)); - } - - [HttpGet("outcome")] - public async Task Outcome( - DateTime from, - DateTime to, - [AsGuid(true)] string? category, - CancellationToken cancellationToken - ) - { - var data = await _dashboardService.GetDashboardOutcomeDataAsync( - UserId, - from.StartOfDay(), - to.EndOfDay(), - category?.AsGuidNull(), - cancellationToken); - - return OkResponse(_mapper.Map(data)); - } -} diff --git a/MyOffice.Web/Controllers/GeneralController.cs b/MyOffice.Web/Controllers/GeneralController.cs deleted file mode 100644 index e9e8780..0000000 --- a/MyOffice.Web/Controllers/GeneralController.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using AutoMapper; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; -using Models.Currency; -using Services.Currency; -using MyOffice.Web.Infrastructure.Attributes; - -[Authorize] -[ApiController] -[Route("api/general")] -[DefaultFromBody] -public class GeneralController : BaseApiController -{ - private readonly CurrencyService _currencyService; - private readonly IMapper _mapper; - - public GeneralController( - CurrencyService currencyService, - IMapper mapper - ) - { - _currencyService = currencyService; - _mapper = mapper; - } - - [HttpGet("currencies")] - public async Task GetGlobalCurrencies(CancellationToken cancellationToken) - { - var list = await _currencyService.GetGlobalAllAsync(cancellationToken); - - return Ok(_mapper.Map>(list)); - } -} diff --git a/MyOffice.Web/Controllers/SettingsAccountCategoryController.cs b/MyOffice.Web/Controllers/SettingsAccountCategoryController.cs deleted file mode 100644 index bc85edb..0000000 --- a/MyOffice.Web/Controllers/SettingsAccountCategoryController.cs +++ /dev/null @@ -1,122 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using AutoMapper; -using Microsoft.AspNetCore.Authorization; - -using Core; -using Core.Extensions; -using Models.Account; -using Services.Account; -using Services.Account.Domain; -using Infrastructure.Attributes; -using Services.Identity; -using Microsoft.AspNetCore.Mvc; - -[Authorize] -[ApiController] -[Route("api/settings/account-categories")] -[DefaultFromBody] -public class SettingsAccountCategoryController : BaseApiController -{ - private readonly ILogger _logger; - private readonly IMapper _mapper; - private readonly AccountService _accountService; - private readonly IContextProvider _contextProvider; - - public SettingsAccountCategoryController( - ILogger logger, - IMapper mapper, - AccountService accountService, - IContextProvider contextProvider - ) - { - _logger = logger; - _mapper = mapper; - _accountService = accountService; - _contextProvider = contextProvider; - } - - [HttpGet] - public async Task AccountCategories(CancellationToken cancellationToken) - { - var list = await _accountService.GetAllCategoriesAsync(UserId, cancellationToken); - - return OkResponse(_mapper.Map>(list).OrderBy(x => x.Name)); - } - - [HttpGet("{id}")] - public async Task AccountCategory([AsGuid] string id, CancellationToken cancellationToken) - { - var exec = await _accountService.GetCategoryAsync(UserId, id.AsGuid(), cancellationToken); - - switch (exec.Status) - { - case GeneralExecStatus.not_found: - case GeneralExecStatus.failure: - return ProblemNotFoundResponse("Account category not found."); - - case GeneralExecStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPost] - public async Task AccountCategoriesAdd(AccountCategoryViewModel request, CancellationToken cancellationToken) - { - var exec = await _accountService.CategoryAddAsync(UserId, new AccountCategoryDto { Name = request.Name! }, cancellationToken); - switch (exec.Status) - { - case GeneralExecStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - case GeneralExecStatus.failure: - case GeneralExecStatus.not_found: - return ProblemBadResponse("Adding account category failed."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPut("{id}")] - public async Task AccountCategoriesUpdate([AsGuid] string id, AccountCategoryViewModel request, CancellationToken cancellationToken) - { - var exec = await _accountService.CategoryUpdateAsync(UserId, id.AsGuid(), new AccountCategoryDto { Name = request.Name! }, cancellationToken); - switch (exec.Status) - { - case GeneralExecStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - case GeneralExecStatus.failure: - case GeneralExecStatus.not_found: - return ProblemBadResponse("Update account category failed."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpDelete("{id}")] - public async Task AccountCategoriesDelete([AsGuid] string id, CancellationToken cancellationToken) - { - var exec = await _accountService.CategoryRemoveAsync(UserId, id.AsGuid(), cancellationToken); - switch (exec.Status) - { - case AccountCategoryRemoveResult.success: - return OkResponse(_mapper.Map(exec.Result!)); - - case AccountCategoryRemoveResult.failure: - return ProblemBadResponse("Remove account category failed."); - case AccountCategoryRemoveResult.not_found: - return ProblemNotFoundResponse("Account category not found."); - case AccountCategoryRemoveResult.accounts_exists: - return ProblemBadResponse("Account category have accounts."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } -} diff --git a/MyOffice.Web/Controllers/SettingsAccountController.cs b/MyOffice.Web/Controllers/SettingsAccountController.cs deleted file mode 100644 index 20a44f5..0000000 --- a/MyOffice.Web/Controllers/SettingsAccountController.cs +++ /dev/null @@ -1,226 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using AutoMapper; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; - -using Core; -using Core.Extensions; -using Models.Account; -using Services.Account; -using Services.Account.Domain; -using Infrastructure.Attributes; -using Services.Identity; - -[Authorize] -[ApiController] -[Route("api/settings/accounts")] -[DefaultFromBody] -public class SettingsAccountController : BaseApiController -{ - private readonly ILogger _logger; - private readonly IMapper _mapper; - private readonly AccountService _accountService; - private readonly IContextProvider _contextProvider; - - public SettingsAccountController( - ILogger logger, - IMapper mapper, - AccountService accountService, - IContextProvider contextProvider - ) - { - _logger = logger; - _mapper = mapper; - _accountService = accountService; - _contextProvider = contextProvider; - } - - [HttpGet("invites")] - public async Task AccountInvites(CancellationToken cancellationToken) - { - var invites = await _accountService.InvitesGetAsync(_contextProvider.User.Email, cancellationToken); - - return OkResponse(_mapper.Map>(invites)); - } - - [HttpPost("invites/{id}/accept")] - public async Task AccountInviteAccept([AsGuid] string id, AccountInviteAcceptRequest request, CancellationToken cancellationToken) - { - var exec = await _accountService.InviteAcceptAsync(UserId, id.AsGuid(), request.Name, cancellationToken); - - switch (exec.Status) - { - case InviteAcceptStatus.invite_not_found: - return ProblemNotFoundResponse("Invite not found."); - case InviteAcceptStatus.account_not_found: - return ProblemNotFoundResponse("Account not found."); - - case InviteAcceptStatus.already_accepted: - case InviteAcceptStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPost("invites/{id}/reject")] - public async Task AccountInviteReject([AsGuid] string id, CancellationToken cancellationToken) - { - var exec = await _accountService.InviteRejectAsync(id.AsGuid(), cancellationToken); - - return MapGeneralExec( - exec, - result => OkResponse(_mapper.Map(result)), - notFoundDetail: "Invite not found.", - failureDetail: "Invite reject failed."); - } - - [HttpGet] - public async Task AccountsGet([FromQuery][AsGuid(true)] string? category, CancellationToken cancellationToken) - { - var list = category.IsPresent() - ? await _accountService.GetByCategoryAsync(UserId, category!.AsGuid(), cancellationToken) - : await _accountService.GetAllAccountsAsync(UserId, cancellationToken); - - return OkResponse(_mapper.Map>(list.OrderBy(x => x.Name))); - } - - [HttpPost] - public async Task AccountsAdd(AccountViewModel request, CancellationToken cancellationToken) - { - var exec = await _accountService.AccountAddAsync(UserId, new AccountAdd - { - Name = request.Name, - CurrencyId = request.CurrencyId, - CategoryId = request.CategoryId.AsGuid(), - Type = request.Type, - }, cancellationToken); - - switch (exec.Status) - { - case AccountAddStatus.category_not_found: - return ProblemNotFoundResponse("Category not found."); - case AccountAddStatus.currency_not_found: - return ProblemNotFoundResponse("Currency not found."); - case AccountAddStatus.failure: - return ProblemBadResponse("Adding account failed."); - case AccountAddStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPut("{id}")] - public async Task AccountsUpdate([AsGuid] string id, AccountEditRequestModel request, CancellationToken cancellationToken) - { - var exec = await _accountService.AccountUpdateAsync(UserId, id.AsGuid(), new AccountEdit - { - Name = request.Name, - CurrencyId = request.CurrencyId, - CategoryId = request.CategoryId?.AsGuidNull(), - UserId = request.UserId?.AsGuidNull(), - Type = request.Type, - }, cancellationToken); - - switch (exec.Status) - { - case AccountEditStatus.not_found: - return ProblemNotFoundResponse("Account not found."); - case AccountEditStatus.forbidden: - return ProblemForbiddenResponse("Manage access required."); - case AccountEditStatus.category_not_found: - return ProblemNotFoundResponse("Category not found."); - case AccountEditStatus.currency_not_found: - return ProblemNotFoundResponse("Currency not found."); - case AccountEditStatus.failure: - return ProblemBadResponse("Adding account failed."); - case AccountEditStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpDelete("{id}")] - public async Task AccountsDelete([AsGuid] string id, CancellationToken cancellationToken) - { - var exec = await _accountService.AccountDeleteAsync(UserId, id, cancellationToken); - return MapGeneralExec( - exec, - result => OkResponse(_mapper.Map(result)), - notFoundDetail: "Account not found.", - forbiddenDetail: "Manage access required."); - } - - [HttpDelete("{id}/category/{categoryId}")] - public async Task AccountsCategoryDelete([AsGuid] string id, [AsGuid] string categoryId, CancellationToken cancellationToken) - { - var exec = await _accountService.AccountCategoryRemoveAsync(UserId, id.AsGuid(), categoryId.AsGuid(), cancellationToken); - - return MapGeneralExec( - exec, - result => OkResponse(_mapper.Map(result)), - notFoundDetail: "Category not found.", - failureDetail: "Category remove failed.", - forbiddenDetail: "Manage access required."); - } - - [HttpPost("{id}/access")] - public async Task AccountsAccessAdd([AsGuid] string id, AccountAccessViewModel request, CancellationToken cancellationToken) - { - var model = _mapper.Map>(request.Accesses); - - var exec = await _accountService.AccessUpdateAsync(UserId, id.AsGuid(), model, cancellationToken); - - if (exec.Status != GeneralExecStatus.success) - { - return MapGeneralExec( - exec, - _ => OkResponse(_mapper.Map(exec.Result!)), - notFoundDetail: "Account not found.", - failureDetail: "Access update failed.", - forbiddenDetail: "Manage access required."); - } - - if (!request.Email.IsPresent()) - { - return OkResponse(_mapper.Map(exec.Result!)); - } - - var inviteExec = await _accountService.AccessInviteAsync(UserId, id.AsGuid(), request.Email!, request.AllowWrite, cancellationToken); - - switch (inviteExec.Status) - { - case AccessInviteStatus.account_not_found: - return ProblemNotFoundResponse("Account not found."); - case AccessInviteStatus.forbidden: - return ProblemForbiddenResponse("Manage access required."); - - case AccessInviteStatus.access_exists: - case AccessInviteStatus.invite_exists: - case AccessInviteStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpDelete("{id}/access/{userId}")] - public async Task AccountsAccessDelete([AsGuid] string id, [AsGuid] string userId, CancellationToken cancellationToken) - { - var exec = await _accountService.AccessDeleteAsync(UserId, id.AsGuid(), userId.AsGuid(), cancellationToken); - - return MapGeneralExec( - exec, - result => OkResponse(_mapper.Map(result)), - notFoundDetail: "Account not found.", - failureDetail: "Access delete failed.", - forbiddenDetail: "Manage access required."); - } -} diff --git a/MyOffice.Web/Controllers/SettingsCurrencyController.cs b/MyOffice.Web/Controllers/SettingsCurrencyController.cs deleted file mode 100644 index 9d45e6d..0000000 --- a/MyOffice.Web/Controllers/SettingsCurrencyController.cs +++ /dev/null @@ -1,142 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using AutoMapper; -using Core; -using Core.Extensions; -using Infrastructure.Attributes; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; -using Models.Currency; -using Services.Currency; -using Services.Currency.Domain; - -[Authorize] -[ApiController] -[Route("api/settings/currencies")] -[DefaultFromBody] -public class SettingCurrencyController : BaseApiController -{ - private readonly CurrencyService _currencyService; - private readonly ILogger _logger; - private readonly IMapper _mapper; - - public SettingCurrencyController( - CurrencyService currencyService, - ILogger logger, - IMapper mapper - ) - { - _currencyService = currencyService; - _logger = logger; - _mapper = mapper; - } - - [HttpGet] - public async Task Get(CancellationToken cancellationToken) - { - var list = await _currencyService.GetAllWithRatesAsync(UserId, cancellationToken); - - return OkResponse(_mapper.Map>(list).OrderBy(x => x.Id)); - } - - [HttpPost] - public async Task Add(CurrencyAddModel currency, CancellationToken cancellationToken) - { - var exec = await _currencyService.CurrencyAddAsync(UserId, new CurrencyDto - { - UserId = UserId, - CurrencyGlobalId = currency.Id, - Name = currency.Name, - ShortName = currency.ShortName, - }, cancellationToken); - - switch (exec.Status) - { - case CurrencyAddStatus.success: - case CurrencyAddStatus.exists: - await _currencyService.CurrencyRateAddAsync(UserId, exec.Result!.Id, new CurrencyRateDto - { - CurrencyId = exec.Result!.Id, - Rate = currency.Rate, - Quantity = currency.Quantity, - DateTime = currency.RateDate.Date, - }, cancellationToken); - return OkResponse(_mapper.Map(exec.Result!)); - - case CurrencyAddStatus.failed: - return ProblemBadResponse("Adding currency failed."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPut("{id}")] - public async Task Update(string id, CurrencyEditModel currency, CancellationToken cancellationToken) - { - var exec = await _currencyService.CurrencyUpdateAsync( - UserId, - id.AsGuid(), - new CurrencyEdit { Name = currency.Name, ShortName = currency.ShortName, IsPrimary = currency.IsPrimary }, - cancellationToken - ); - - switch (exec.Status) - { - case CurrencyEditStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - case CurrencyEditStatus.not_found: - case CurrencyEditStatus.failed: - return ProblemNotFoundResponse("Currency not found."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpDelete("{id}")] - public async Task Delete([AsGuid] string id, CancellationToken cancellationToken) - { - var exec = await _currencyService.RemoveAsync(UserId, id.AsGuid(), cancellationToken); - - switch (exec.Status) - { - case GeneralExecStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - case GeneralExecStatus.not_found: - case GeneralExecStatus.failure: - return ProblemNotFoundResponse("Currency not found."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPost("{id}/rate")] - public async Task AddRate(string id, CurrencyRateModel currencyRate, CancellationToken cancellationToken) - { - var exec = await _currencyService.CurrencyRateAddAsync(UserId, id.AsGuid(), new CurrencyRateDto - { - CurrencyId = id.AsGuid(), - Quantity = currencyRate.Quantity, - Rate = currencyRate.Rate, - DateTime = currencyRate.RateDate.Date, - }, cancellationToken); - - switch (exec.Status) - { - case CurrencyAddRateStatus.failed: - return ProblemBadResponse("Adding currency rate failed."); - case CurrencyAddRateStatus.not_found: - return ProblemNotFoundResponse("Currency not found."); - - case CurrencyAddRateStatus.success: - return OkResponse(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } -} diff --git a/MyOffice.Web/Controllers/SettingsItemController.cs b/MyOffice.Web/Controllers/SettingsItemController.cs deleted file mode 100644 index a03ba98..0000000 --- a/MyOffice.Web/Controllers/SettingsItemController.cs +++ /dev/null @@ -1,163 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using AutoMapper; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; - -using Models.Item; -using Core.Extensions; -using Core; -using Infrastructure.Attributes; -using Services.Item; -using Services.Item.Domain; - -[Authorize] -[ApiController] -[Route("api/settings")] -[DefaultFromBody] -public class SettingsItemController : BaseApiController -{ - private ILogger _logger; - private IMapper _mapper; - private ItemService _itemService; - - public SettingsItemController( - ILogger logger, - ItemService itemService, - IMapper mapper - ) - { - _itemService = itemService; - _logger = logger; - _mapper = mapper; - } - - [HttpGet("item-categories")] - public async Task ItemsCategories(CancellationToken cancellationToken) - { - var list = await _itemService.GetAllCategoriesAsync(UserId, cancellationToken); - - return Ok(_mapper.Map>(list) - .OrderByDescending(x => x.SortOrder) - .ThenBy(x => x.Name)); - } - - [HttpPost("item-categories")] - public async Task ItemCategoriesAdd(ItemCategoryViewModel request, CancellationToken cancellationToken) - { - var exec = await _itemService.CategoryAddAsync(UserId, request.FromModel(), cancellationToken); - - switch (exec.Status) - { - case GeneralExecStatus.success: - return Ok(_mapper.Map(exec.Result!)); - - case GeneralExecStatus.failure: - case GeneralExecStatus.not_found: - return ProblemBadResponse("Adding item category failed."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPut("item-categories/{id}")] - public async Task ItemCategoriesUpdate( - [AsGuid] string id, - ItemCategoryViewModel request, - CancellationToken cancellationToken) - { - var exec = await _itemService.CategoryUpdateAsync(UserId, id.AsGuid(), request.FromModel(), cancellationToken); - - switch (exec.Status) - { - case GeneralExecStatus.success: - return Ok(_mapper.Map(exec.Result!)); - - case GeneralExecStatus.failure: - case GeneralExecStatus.not_found: - return ProblemBadResponse("Update item category failed."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpDelete("item-categories/{id}")] - public async Task ItemCategoriesDelete([AsGuid] string id, CancellationToken cancellationToken) - { - var exec = await _itemService.CategoryRemoveAsync(UserId, id.AsGuid(), cancellationToken); - switch (exec.Status) - { - case ItemCategoryRemoveResult.success: - return Ok(_mapper.Map(exec.Result!)); - - case ItemCategoryRemoveResult.failure: - return ProblemBadResponse("Remove item category failed."); - case ItemCategoryRemoveResult.not_found: - return ProblemNotFoundResponse("Account item not found."); - case ItemCategoryRemoveResult.accounts_exists: - return ProblemBadResponse("Account motion have accounts."); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpGet("items")] - public async Task Items([FromQuery][AsGuid] string category, CancellationToken cancellationToken) - { - var categoryId = category.AsGuid(); - - var list = categoryId != UserId - ? await _itemService.GetByCategoryAsync(UserId, categoryId, cancellationToken) - : await _itemService.GetByUncategorizedAsync(UserId, cancellationToken); - - return Ok(_mapper.Map>(list.OrderBy(x => x.Name))); - } - - [HttpPut("items/{id}")] - public async Task ItemsUpdate( - [AsGuid] string id, - ItemEditModel request, - CancellationToken cancellationToken) - { - var exec = await _itemService.UpdateAsync(UserId, id.AsGuid(), request.Category.AsGuid(), cancellationToken); - - switch (exec.Status) - { - case GeneralExecStatus.not_found: - return ProblemNotFoundResponse("Item not found."); - case GeneralExecStatus.failure: - return ProblemBadResponse("Item update failed."); - case GeneralExecStatus.success: - return Ok(_mapper.Map(exec.Result!)); - - default: - throw new NotSupportedException(exec.Status.ToString()); - } - } - - [HttpPost("items")] - public async Task ItemsPost(ItemChangeCategoryModel request, CancellationToken cancellationToken) - { - var exec = await _itemService.UpdateItemsCategoryAsync( - UserId, - request.category.AsGuid(), - request.Items.Select(x => x.AsGuid()).ToList(), - cancellationToken); - - switch (exec) - { - case GeneralExecStatus.not_found: - return ProblemNotFoundResponse("Category not found."); - case GeneralExecStatus.failure: - return ProblemBadResponse("Update failed."); - case GeneralExecStatus.success: - return Ok(new {}); - - default: - throw new NotSupportedException(exec.ToString()); - } - } -} diff --git a/MyOffice.Web/Controllers/UserController.cs b/MyOffice.Web/Controllers/UserController.cs deleted file mode 100644 index d4044c7..0000000 --- a/MyOffice.Web/Controllers/UserController.cs +++ /dev/null @@ -1,189 +0,0 @@ -namespace MyOffice.Web.Controllers; - -using Models.Auth; -using Identity.Domain; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Mvc; -using System; -using System.ComponentModel.DataAnnotations; -using Microsoft.AspNetCore.Authorization; -using MyOffice.Data.Models.Users; -using Core.Extensions; -using MyOffice.Core.Identity; -using Core; -using Services.Users; -using Services.Users.Domain; -using MyOffice.Data.Models.Currencies; -using MyOffice.Web.Infrastructure.Attributes; - -[ApiController] -[Route("api/user")] -[DefaultFromBody] -public class UserController : BaseApiController -{ - private readonly UserManager> _userManager; - private readonly UserService _userService; - private readonly IEnumerable _externalProviderValidators; - - public UserController( - UserManager> userManager, - UserService userService, - IEnumerable externalProviderValidators - ) - { - _userManager = userManager; - _userService = userService; - _externalProviderValidators = externalProviderValidators; - } - - [AllowAnonymous] - [HttpPost("register")] - public async Task Register([FromBody] RegisterModel request) - { - if (!ModelState.IsValid) - return BadRequest(new - { - Succeeded = false, - Errors = ModelState.Values - .SelectMany(v => v.Errors) - .Select(e => new { Code = "Validation", Description = e.ErrorMessage }) - }); - - var email = request.UserName.Trim(); - var user = new ApplicationUser - { - Id = Guid.NewGuid(), - UserName = email, - Email = email, - IsEmailConfirmed = true, - CurrencyId = CurrencyGlobalIdEnum.USD.ToString(), - }; - - var result = await _userManager.CreateAsync(user, request.Password); - - return Ok(new - { - result.Succeeded, - Errors = result.Errors - .Where(x => !x.Code.Equals("DuplicateUserName")) - .Select(x => new { x.Code, x.Description }) - }); - } - - [Authorize] - [HttpGet("profile")] - public async Task ProfileGet() - { - var user = await _userManager.FindByIdAsync(UserId.ToString()); - - return user.ToModel(await _userService.GetUserExternals(user.Id)); - } - - [Authorize] - [HttpPost("profile")] - public async Task ProfileUpdate([FromBody] ProfileModel model) - { - var user = await _userManager.FindByIdAsync(UserId.ToString()); ; - - user.FirstName = model.FirstName; - user.LastName = model.LastName; - user.FullName = model.FullName.NullIfEmpty() ?? $"{model.FirstName} {model.LastName}"; - user.CurrencyId = model.Currency; - - await _userManager.UpdateAsync(user); - - return user.ToModel(await _userService.GetUserExternals(user.Id)); - } - - [Authorize] - [HttpPost("attach")] - public async Task AttachProvider([FromBody] AttachModel model) - { - var validator = _externalProviderValidators.FirstOrDefault(x => x.Provider.EqualsIgnoreCase(model.Provider)); - if (validator == null) return ProblemBadResponse("Provider not supported"); - - var result = await validator.ValidateAsync(model.Token); - if (!result.IsSuccessed) return ProblemBadResponse("Token not valid"); - - var execResult = await _userService.AddUserExternalAsync(UserId, model.Provider, result.ExternalId!, result.Email!); - switch (execResult.Status) - { - case AddUserExternalStatusEnum.success: - return Ok(new - { - success = true - }); - - case AddUserExternalStatusEnum.externalid_used: - case AddUserExternalStatusEnum.user_not_valid: - return ProblemBadResponse("Provider already connected"); - - default: - throw new NotSupportedException(execResult.Status.ToString()); - } - } - - [Authorize] - [HttpPost("deattach")] - public async Task DeattachProvider([FromBody] DeattachModel model) - { - var exec = await _userService.RemoveUserExternal(UserId, model.Provider); - - if (exec.Status == GeneralExecStatus.not_found) return ProblemBadResponse("Provider not connected"); - - return Ok(new - { - success = true - }); - } -} - -public class DeattachModel -{ - [Required] public string Provider { get; set; } = null!; -} - -public class AttachModel -{ - [Required] public string Provider { get; set; } = null!; - [Required] public string Token { get; set; } = null!; -} - -public class ProfileModel -{ - public class ProviderModel - { - public string Provider { get; set; } = null!; - - public DateTime CreatedOn { get; set; } - } - - public string? Email { get; set; } - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? FullName { get; set; } - public bool? IsEmailConfirmed { get; set; } - public string? Currency { get; set; } - public List? Providers { get; set; } -} - -public static class ProfileModelExtensions -{ - public static ProfileModel ToModel(this ApplicationUser user, List userClaims) - { - return new ProfileModel - { - Email = user.Email, - FirstName = user.FirstName, - LastName = user.LastName, - FullName = user.FullName, - IsEmailConfirmed = user.IsEmailConfirmed, - Currency = user.CurrencyId, - Providers = userClaims?.Select(x => new ProfileModel.ProviderModel - { - Provider = x.Provider, - CreatedOn = x.CreatedOn - }).ToList() - }; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ContextProvider.cs b/MyOffice.Web/Identity/ContextProvider.cs deleted file mode 100644 index 8ad8e1e..0000000 --- a/MyOffice.Web/Identity/ContextProvider.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace MyOffice.Web.Identity; - -using Data.Repositories.Users; -using MyOffice.Data.Models.Users; -using MyOffice.Services.Identity; - -public class ContextProvider : IContextProvider -{ - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly IUserRepository _userRepository; - - public ContextProvider( - IHttpContextAccessor httpContextAccessor, - IUserRepository userRepository - ) - { - _httpContextAccessor = httpContextAccessor; - _userRepository = userRepository; - } - - private User? _user = null; - public User User - { - get - { - _user ??= _userRepository.GetUser(UserId); - - return _user!; - } - } - - public Guid UserId - { - get - { - return Guid.Parse(_httpContextAccessor!.HttpContext!.User!.Claims!.FirstOrDefault(x => x.Type == "sub")!.Value); - } - } -} diff --git a/MyOffice.Web/Identity/Domain/ApplicationRole.cs b/MyOffice.Web/Identity/Domain/ApplicationRole.cs deleted file mode 100644 index ddd8f96..0000000 --- a/MyOffice.Web/Identity/Domain/ApplicationRole.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace MyOffice.Web.Identity.Domain; - -public class ApplicationRole -{ -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Domain/ApplicationUser.cs b/MyOffice.Web/Identity/Domain/ApplicationUser.cs deleted file mode 100644 index c4f63d4..0000000 --- a/MyOffice.Web/Identity/Domain/ApplicationUser.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Web.Identity.Domain; - -public class ApplicationUser -{ -#pragma warning disable CS8618 // Non-nullable property 'Id' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. - public TKey Id { get; set; } -#pragma warning restore CS8618 // Non-nullable property 'Id' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. - public string UserName { get; set; } = null!; - public string Email { get; set; } = null!; - public string PasswordHash { get; set; } = null!; - - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? FullName { get; set; } - public bool IsEmailConfirmed { get; set; } - public string? CurrencyId { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Domain/ExternalProvidersConfig.cs b/MyOffice.Web/Identity/Domain/ExternalProvidersConfig.cs deleted file mode 100644 index af1b964..0000000 --- a/MyOffice.Web/Identity/Domain/ExternalProvidersConfig.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MyOffice.Web.Identity.Domain; - -public class ExternalProvidersConfig -{ - public class Auth0Config - { - public string? ClientId { get; set; } - public string? Domain { get; set; } - public string? SecretKey { get; set; } - } - - public class GoogleConfig - { - public string? ClientId { get; set; } - } - - public Auth0Config? Auth0 { get; set; } - public GoogleConfig? Google { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorAuth0.cs b/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorAuth0.cs deleted file mode 100644 index efff106..0000000 --- a/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorAuth0.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace MyOffice.Web.Identity.ExternalProviders; - -using Domain; -using Microsoft.Extensions.Options; -using Microsoft.IdentityModel.Protocols; -using Microsoft.IdentityModel.Protocols.OpenIdConnect; -using Microsoft.IdentityModel.Tokens; -using System.IdentityModel.Tokens.Jwt; -using System.Text; -using Core.Extensions; -using Core.Identity; - -public class ExternalProviderValidatorAuth0 : IExternalProviderValidator -{ - private readonly ExternalProvidersConfig _externalProvidersConfig; - private readonly ILogger _logger; - - public ExternalProviderValidatorAuth0( - ILogger logger, - IOptions externalProvidersConfig - ) - { - _externalProvidersConfig = externalProvidersConfig.Value; - _logger = logger; - - Provider = ExternalProvidersConst.PROVIDER_AUTH0; - IsConfigured = _externalProvidersConfig.IsAuth0Configured(); - } - - public string Provider { get; } - public bool IsConfigured { get; } - - public async Task ValidateAsync(string token) - { - var auth0Domain = _externalProvidersConfig.Auth0!.Domain!; - var secretKey = _externalProvidersConfig.Auth0!.SecretKey!; - var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)); - var configurationManager = new ConfigurationManager( - $"{auth0Domain}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever()); - var openIdConfig = await configurationManager.GetConfigurationAsync(CancellationToken.None); - - var validations = new TokenValidationParameters - { - ValidIssuer = auth0Domain, - ValidAudiences = new[] { _externalProvidersConfig.Auth0!.ClientId }, - IssuerSigningKeys = openIdConfig.SigningKeys, - TokenDecryptionKey = securityKey - }; - - var tokenHandler = new JwtSecurityTokenHandler(); - var user = tokenHandler.ValidateToken(token, validations, out var validatedToken); - if (user.Identity?.IsAuthenticated != true) - { - return ExternalProviderValidatorResult.Failed(); - } - - var email = user.Claims.GetEmail(); - var emailVerified = user.Claims.GetValue("email_verified").AsBool(); - var fullName = user.Claims.GetValue("name")?.ToString(); - var externalId = user.Claims.GetSID(); - - if (email == null || externalId == null) - { - return ExternalProviderValidatorResult.Failed(); - } - - return ExternalProviderValidatorResult.Success(email, emailVerified, externalId, fullName); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorGoogle.cs b/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorGoogle.cs deleted file mode 100644 index d5e6c4d..0000000 --- a/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorGoogle.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace MyOffice.Web.Identity.ExternalProviders; - -using MyOffice.Core.Identity; -using Domain; -using Google.Apis.Auth; -using Microsoft.Extensions.Options; - -public class ExternalProviderValidatorGoogle : IExternalProviderValidator -{ - private readonly ExternalProvidersConfig _externalProvidersConfig; - - public ExternalProviderValidatorGoogle( - IOptions externalProvidersConfig - ) - { - _externalProvidersConfig = externalProvidersConfig.Value; - - Provider = ExternalProvidersConst.PROVIDER_GOOGLE; - IsConfigured = _externalProvidersConfig.IsGoogleConfigured(); - } - - public string Provider { get; } - public bool IsConfigured { get; } - - public async Task ValidateAsync(string token) - { - var settings = new GoogleJsonWebSignature.ValidationSettings() - { - Audience = new List() { _externalProvidersConfig.Google!.ClientId! } - }; - var result = await GoogleJsonWebSignature.ValidateAsync(token, settings); - if (!result.EmailVerified) return ExternalProviderValidatorResult.Failed(); - - return ExternalProviderValidatorResult.Success(result.Email, result.EmailVerified, result.Subject, result.Name); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProviders/ExternalProvidersConst.cs b/MyOffice.Web/Identity/ExternalProviders/ExternalProvidersConst.cs deleted file mode 100644 index 261bc0a..0000000 --- a/MyOffice.Web/Identity/ExternalProviders/ExternalProvidersConst.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MyOffice.Web.Identity.ExternalProviders; - -public class ExternalProvidersConst -{ - public const string PROVIDER_GOOGLE = "google"; - public const string PROVIDER_AUTH0 = "auth0"; -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProvidersConfigExtensions.cs b/MyOffice.Web/Identity/ExternalProvidersConfigExtensions.cs deleted file mode 100644 index 49c8a0d..0000000 --- a/MyOffice.Web/Identity/ExternalProvidersConfigExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using MyOffice.Web.Identity.Domain; - -namespace MyOffice.Web.Identity; - -using Core.Extensions; - -public static class ExternalProvidersConfigExtensions -{ - public static bool IsGoogleConfigured(this ExternalProvidersConfig? config) - { - return config != null - && config.Google != null - && config.Google.ClientId.IsPresent(); - } - - public static bool IsAuth0Configured(this ExternalProvidersConfig? config) - { - return config != null - && config.Auth0 != null - && config.Auth0.ClientId.IsPresent() - && config.Auth0.Domain.IsPresent() - && config.Auth0.SecretKey.IsPresent(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/OpenIddict/ExternalGrantHandler.cs b/MyOffice.Web/Identity/OpenIddict/ExternalGrantHandler.cs deleted file mode 100644 index 7cdf7cc..0000000 --- a/MyOffice.Web/Identity/OpenIddict/ExternalGrantHandler.cs +++ /dev/null @@ -1,137 +0,0 @@ -namespace MyOffice.Web.Auth; - -using Core.Extensions; -using Core.Identity; -using Data.Models.Users; -using Data.Repositories.Users; -using Identity.Domain; -using Identity.ExternalProviders; -using Identity.Repositories; -using Microsoft.Extensions.Options; -using OpenIddict.Abstractions; -using OpenIddict.Server; -using static OpenIddict.Abstractions.OpenIddictConstants; -using static OpenIddict.Server.OpenIddictServerEvents; - -public sealed class ExternalGrantHandler : IOpenIddictServerHandler -{ - private readonly AppUserManager _userManager; - private readonly IUserExternalRepository _userExternalRepository; - private readonly IEnumerable _externalProviderValidators; - private readonly IHttpContextAccessor _httpContextAccessor; - - public ExternalGrantHandler( - AppUserManager userManager, - IUserExternalRepository userExternalRepository, - IEnumerable externalProviderValidators, - IHttpContextAccessor httpContextAccessor - ) - { - _userManager = userManager; - _userExternalRepository = userExternalRepository; - _externalProviderValidators = externalProviderValidators; - _httpContextAccessor = httpContextAccessor; - } - - public async ValueTask HandleAsync(HandleTokenRequestContext context) - { - if (!string.Equals(context.Request.GrantType, OpenIddictAuthConstants.ExternalGrantType, StringComparison.Ordinal)) - return; - - var provider = context.Request.GetParameter("provider")?.ToString(); - if (provider.IsMissing()) - { - context.Reject(Errors.InvalidRequest, "The provider parameter is required."); - return; - } - - var validator = _externalProviderValidators.FirstOrDefault(x => x.Provider.EqualsIgnoreCase(provider)); - if (validator is null || !validator.IsConfigured) - { - context.Reject(Errors.InvalidRequest, $"Provider not supported: {provider}"); - return; - } - - var token = context.Request.GetParameter("token")?.ToString(); - if (token.IsMissing()) - { - context.Reject(Errors.InvalidRequest, "The token parameter is required."); - return; - } - - var validationResult = await validator.ValidateAsync(token); - if (!validationResult.IsSuccessed) - { - context.Reject(Errors.InvalidGrant, "Token not valid."); - return; - } - - if (_httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated == true) - { - context.Reject(Errors.InvalidGrant, "Authentication failed."); - return; - } - - var user = await _userManager.FindByEmailAsync(validationResult.Email!); - if (user is null) - { - if (!validationResult.EmailVerified) - { - context.Reject(Errors.InvalidGrant, "Email not confirmed."); - return; - } - - user = await CreateUserAsync(validationResult.Email!, validationResult.EmailVerified, validationResult.FullName); - if (user is null) - { - context.Reject(Errors.InvalidGrant, "Unable to create user."); - return; - } - } - - var externalLogin = await _userExternalRepository.GetByUserIdAsync(user.Id, provider) - ?? AddExternalLogin(user, validationResult.Email!, validationResult.ExternalId!, provider); - - context.SignIn(OpenIddictClaimsHelper.CreatePrincipal(user, context.Request.GetScopes())); - } - - private async Task?> CreateUserAsync(string email, bool isEmailConfirmed, string? fullName) - { - var user = new ApplicationUser - { - Id = Guid.NewGuid(), - UserName = email, - Email = email, - IsEmailConfirmed = isEmailConfirmed, - FullName = fullName - }; - - var password = "Qq1!_" + Guid.NewGuid(); - var result = await _userManager.CreateAsync(user, password); - return result.Succeeded ? user : null; - } - - private UserExternal AddExternalLogin( - ApplicationUser user, - string email, - string externalId, - string provider - ) - { - var existing = _userExternalRepository.GetByUserId(user.Id, provider); - if (existing is not null) - return existing; - - var claim = new UserExternal - { - UserId = user.Id, - CreatedOn = DateTime.UtcNow, - Provider = provider.ToLower(), - ExternalId = externalId, - Email = email - }; - _userExternalRepository.AddUserExternal(claim); - - return claim; - } -} diff --git a/MyOffice.Web/Identity/OpenIddict/OpenIddictClaimsHelper.cs b/MyOffice.Web/Identity/OpenIddict/OpenIddictClaimsHelper.cs deleted file mode 100644 index 3cdbdb6..0000000 --- a/MyOffice.Web/Identity/OpenIddict/OpenIddictClaimsHelper.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace MyOffice.Web.Auth; - -using System.Security.Claims; -using Identity.Domain; -using Microsoft.IdentityModel.Tokens; -using OpenIddict.Abstractions; -using static OpenIddict.Abstractions.OpenIddictConstants; - -public static class OpenIddictClaimsHelper -{ - public static ClaimsPrincipal CreatePrincipal( - ApplicationUser user, - IEnumerable scopes - ) - { - var identity = new ClaimsIdentity( - authenticationType: TokenValidationParameters.DefaultAuthenticationType, - nameType: Claims.Name, - roleType: Claims.Role); - - var userId = user.Id.ToString(); - identity.SetClaim(Claims.Subject, userId); - identity.SetClaim(Claims.Name, user.UserName); - identity.SetClaim(Claims.PreferredUsername, user.UserName); - identity.SetClaim(Claims.Email, user.Email); - identity.SetClaim(Claims.EmailVerified, user.IsEmailConfirmed); - - if (!string.IsNullOrWhiteSpace(user.FullName)) - identity.SetClaim(Claims.GivenName, user.FullName); - - identity.SetScopes(scopes); - identity.SetDestinations(static claim => claim.Type switch - { - Claims.Name or Claims.PreferredUsername or Claims.Email or Claims.EmailVerified or Claims.GivenName - => [Destinations.AccessToken, Destinations.IdentityToken], - _ => [Destinations.AccessToken] - }); - - return new ClaimsPrincipal(identity); - } -} diff --git a/MyOffice.Web/Identity/OpenIddict/OpenIddictConstants.cs b/MyOffice.Web/Identity/OpenIddict/OpenIddictConstants.cs deleted file mode 100644 index 62689d0..0000000 --- a/MyOffice.Web/Identity/OpenIddict/OpenIddictConstants.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MyOffice.Web.Auth; - -public static class OpenIddictAuthConstants -{ - public const string ApiScope = "api"; - public const string ApiFriendlyName = "MyOffice.Web API"; - public const string SpaClientId = "angulartemplate_spa"; - public const string ExternalGrantType = "external"; - public const string RolesScope = "roles"; -} diff --git a/MyOffice.Web/Identity/OpenIddict/OpenIddictSeeder.cs b/MyOffice.Web/Identity/OpenIddict/OpenIddictSeeder.cs deleted file mode 100644 index a095cd3..0000000 --- a/MyOffice.Web/Identity/OpenIddict/OpenIddictSeeder.cs +++ /dev/null @@ -1,130 +0,0 @@ -namespace MyOffice.Web.Auth; - -using DbContext; -using Infrastructure; -using Microsoft.Extensions.Options; -using OpenIddict.Abstractions; -using static OpenIddict.Abstractions.OpenIddictConstants; - -public sealed class OpenIddictSeeder : IHostedService -{ - private readonly IServiceProvider _serviceProvider; - private readonly IConfiguration _configuration; - private readonly ILogger _logger; - - public OpenIddictSeeder( - IServiceProvider serviceProvider, - IConfiguration configuration, - ILogger logger - ) - { - _serviceProvider = serviceProvider; - _configuration = configuration; - _logger = logger; - } - - public async Task StartAsync(CancellationToken cancellationToken) - { - await using var scope = _serviceProvider.CreateAsyncScope(); - - await RegisterScopesAsync(scope.ServiceProvider, cancellationToken); - await RegisterClientAsync(scope.ServiceProvider, cancellationToken); - } - - public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; - - private async Task RegisterScopesAsync(IServiceProvider provider, CancellationToken cancellationToken) - { - var manager = provider.GetRequiredService(); - - if (await manager.FindByNameAsync(OpenIddictAuthConstants.ApiScope, cancellationToken) is null) - { - await manager.CreateAsync(new OpenIddictScopeDescriptor - { - Name = OpenIddictAuthConstants.ApiScope, - DisplayName = OpenIddictAuthConstants.ApiFriendlyName, - Resources = { OpenIddictAuthConstants.ApiScope } - }, cancellationToken); - - _logger.LogInformation("Created OpenIddict scope {Scope}.", OpenIddictAuthConstants.ApiScope); - } - - if (await manager.FindByNameAsync(OpenIddictAuthConstants.RolesScope, cancellationToken) is null) - { - await manager.CreateAsync(new OpenIddictScopeDescriptor - { - Name = OpenIddictAuthConstants.RolesScope, - DisplayName = "User roles" - }, cancellationToken); - - _logger.LogInformation("Created OpenIddict scope {Scope}.", OpenIddictAuthConstants.RolesScope); - } - } - - private async Task RegisterClientAsync(IServiceProvider provider, CancellationToken cancellationToken) - { - var manager = provider.GetRequiredService(); - var globalSettings = provider.GetRequiredService(); - - var redirectUri = BuildRedirectUri(globalSettings.Host); - var existing = await manager.FindByClientIdAsync(OpenIddictAuthConstants.SpaClientId, cancellationToken); - var descriptor = CreateSpaClientDescriptor(redirectUri); - - if (existing is null) - { - await manager.CreateAsync(descriptor, cancellationToken); - _logger.LogInformation("Created OpenIddict client {ClientId}.", OpenIddictAuthConstants.SpaClientId); - return; - } - - var currentRedirectUris = await manager.GetRedirectUrisAsync(existing, cancellationToken); - foreach (var uri in currentRedirectUris) - { - if (!string.Equals(uri, redirectUri.ToString(), StringComparison.Ordinal)) - descriptor.RedirectUris.Add(new Uri(uri, UriKind.Absolute)); - } - - await manager.UpdateAsync(existing, descriptor, cancellationToken); - _logger.LogInformation("Updated OpenIddict client {ClientId}.", OpenIddictAuthConstants.SpaClientId); - } - - internal static OpenIddictApplicationDescriptor CreateSpaClientDescriptor(Uri redirectUri) - { - var descriptor = new OpenIddictApplicationDescriptor - { - ClientId = OpenIddictAuthConstants.SpaClientId, - DisplayName = "MyOffice SPA", - ClientType = ClientTypes.Public, - ConsentType = ConsentTypes.Implicit, - Permissions = - { - Permissions.Endpoints.Authorization, - Permissions.Endpoints.Token, - Permissions.Endpoints.EndSession, - Permissions.GrantTypes.AuthorizationCode, - Permissions.GrantTypes.Password, - Permissions.GrantTypes.RefreshToken, - Permissions.Prefixes.GrantType + OpenIddictAuthConstants.ExternalGrantType, - Permissions.ResponseTypes.Code, - Permissions.Scopes.Email, - Permissions.Scopes.Profile, - Permissions.Scopes.Roles, - Permissions.Prefixes.Scope + Scopes.OpenId, - Permissions.Prefixes.Scope + Scopes.OfflineAccess, - Permissions.Prefixes.Scope + OpenIddictAuthConstants.ApiScope, - Permissions.Prefixes.Scope + OpenIddictAuthConstants.RolesScope - } - }; - - descriptor.RedirectUris.Add(redirectUri); - return descriptor; - } - - internal static Uri BuildRedirectUri(string? host) - { - if (string.IsNullOrWhiteSpace(host)) - return new Uri("http://localhost:4300/silent-refresh.html"); - - return new Uri($"{host.TrimEnd('/')}/silent-refresh.html"); - } -} diff --git a/MyOffice.Web/Identity/OpenIddict/OpenIddictServiceCollectionExtensions.cs b/MyOffice.Web/Identity/OpenIddict/OpenIddictServiceCollectionExtensions.cs deleted file mode 100644 index 44942fd..0000000 --- a/MyOffice.Web/Identity/OpenIddict/OpenIddictServiceCollectionExtensions.cs +++ /dev/null @@ -1,192 +0,0 @@ -namespace MyOffice.Web.Auth; - -using System.Security.Cryptography; -using DbContext; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.IdentityModel.Tokens; -using OpenIddict.Server; -using OpenIddict.Validation.AspNetCore; -using static OpenIddict.Abstractions.OpenIddictConstants; -using static OpenIddict.Server.OpenIddictServerEvents; - -public static class OpenIddictServiceCollectionExtensions -{ - public static IServiceCollection AddMyOfficeOpenIddict( - this IServiceCollection services, - IConfiguration configuration, - IHostEnvironment environment - ) - { - services.AddOpenIddict() - .AddCore(options => - { - options.UseEntityFrameworkCore() - .UseDbContext(); - }) - .AddServer(options => - { - options.SetAuthorizationEndpointUris("/connect/authorize") - .SetTokenEndpointUris("/connect/token") - .SetUserInfoEndpointUris("/connect/userinfo") - .SetEndSessionEndpointUris("/connect/logout"); - - options.AllowAuthorizationCodeFlow() - .AllowPasswordFlow() - .AllowRefreshTokenFlow() - .AllowCustomFlow(OpenIddictAuthConstants.ExternalGrantType); - - options.RegisterScopes( - Scopes.OpenId, - Scopes.Email, - Scopes.Profile, - Scopes.Roles, - Scopes.OfflineAccess, - OpenIddictAuthConstants.ApiScope, - OpenIddictAuthConstants.RolesScope); - - ConfigureCryptography(options, configuration, environment); - - var aspNetCoreBuilder = options.UseAspNetCore() - .EnableAuthorizationEndpointPassthrough() - .EnableUserInfoEndpointPassthrough() - .EnableEndSessionEndpointPassthrough(); - - // Local HTTP only. In production nginx terminates TLS and - // ForwardedHeaders restores https:// for OpenIddict. - // Docker demo also serves plain HTTP (OpenIddict:AllowHttp / Environment=Docker). - if (environment.IsDevelopment() - || IsDockerEnvironment(environment) - || configuration.GetValue("OpenIddict:AllowHttp", false)) - { - aspNetCoreBuilder.DisableTransportSecurityRequirement(); - } - - // Password and external grants need custom handlers (separate registrations — - // a second UseScopedHandler() on the same builder replaces the first). - options.AddEventHandler(builder => - builder.UseScopedHandler()); - - options.AddEventHandler(builder => - builder.UseScopedHandler()); - }) - .AddValidation(options => - { - options.UseLocalServer(); - options.UseAspNetCore(); - }); - - services.AddAuthentication(options => - { - options.DefaultScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme; - options.DefaultAuthenticateScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme; - }); - - services.AddHostedService(); - - return services; - } - - private static void ConfigureCryptography( - OpenIddictServerBuilder options, - IConfiguration configuration, - IHostEnvironment environment - ) - { - // Dev: certs in the user profile. Docker/demo: ephemeral keys (no cert store in containers). - if (string.IsNullOrWhiteSpace(configuration["OpenIddict:SigningKeyPath"]) - && (environment.IsDevelopment() - || IsDockerEnvironment(environment) - || configuration.GetValue("OpenIddict:UseEphemeralKeys", false))) - { - if (IsDockerEnvironment(environment) - || configuration.GetValue("OpenIddict:UseEphemeralKeys", false)) - { - options.AddEphemeralEncryptionKey() - .AddEphemeralSigningKey(); - } - else - { - options.AddDevelopmentEncryptionCertificate() - .AddDevelopmentSigningCertificate(); - } - - return; - } - - var contentRoot = configuration.GetValue(WebHostDefaults.ContentRootKey) - ?? throw new InvalidOperationException("Content root path is not configured."); - - var signingPath = ResolveKeyPath( - configuration["OpenIddict:SigningKeyPath"], - contentRoot, - "keys/signing.pem"); - var encryptionPath = ResolveKeyPath( - configuration["OpenIddict:EncryptionKeyPath"], - contentRoot, - "keys/encryption.pem"); - - if (!File.Exists(signingPath)) - { - throw new InvalidOperationException( - $"OpenIddict signing key not found at '{signingPath}'. " + - "Set OpenIddict:SigningKeyPath or place keys/signing.pem under the content root."); - } - - options.AddSigningKey(LoadRsaSecurityKey(signingPath)); - - if (File.Exists(encryptionPath) && - !string.Equals(encryptionPath, signingPath, StringComparison.OrdinalIgnoreCase)) - { - options.AddEncryptionKey(LoadRsaSecurityKey(encryptionPath)); - } - else - { - // Prefer a dedicated encryption key. Fallback keeps older single-key setups working. - options.AddEncryptionKey(LoadRsaSecurityKey(signingPath)); - } - } - - private static bool IsDockerEnvironment(IHostEnvironment environment) => - string.Equals(environment.EnvironmentName, "Docker", StringComparison.OrdinalIgnoreCase); - - private static string ResolveKeyPath(string? configuredPath, string contentRoot, string defaultRelative) - { - if (!string.IsNullOrWhiteSpace(configuredPath)) - { - return Path.IsPathRooted(configuredPath) - ? configuredPath - : Path.GetFullPath(Path.Combine(contentRoot, configuredPath)); - } - - return Path.GetFullPath(Path.Combine(contentRoot, defaultRelative)); - } - - private static RsaSecurityKey LoadRsaSecurityKey(string path) - { - var privateKey = File.ReadAllText(path) - .Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty, StringComparison.Ordinal) - .Replace("-----END RSA PRIVATE KEY-----", string.Empty, StringComparison.Ordinal) - .Replace("-----BEGIN PRIVATE KEY-----", string.Empty, StringComparison.Ordinal) - .Replace("-----END PRIVATE KEY-----", string.Empty, StringComparison.Ordinal) - .Replace("\r", string.Empty, StringComparison.Ordinal) - .Replace("\n", string.Empty, StringComparison.Ordinal); - - var rsa = RSA.Create(); - var keyBytes = Convert.FromBase64String(privateKey); - - try - { - rsa.ImportRSAPrivateKey(keyBytes, out _); - } - catch (CryptographicException) - { - rsa.ImportPkcs8PrivateKey(keyBytes, out _); - } - - return new RsaSecurityKey(rsa); - } -} diff --git a/MyOffice.Web/Identity/OpenIddict/PasswordGrantHandler.cs b/MyOffice.Web/Identity/OpenIddict/PasswordGrantHandler.cs deleted file mode 100644 index ce48be5..0000000 --- a/MyOffice.Web/Identity/OpenIddict/PasswordGrantHandler.cs +++ /dev/null @@ -1,70 +0,0 @@ -namespace MyOffice.Web.Auth; - -using Identity.Domain; -using Identity.Repositories; -using Microsoft.AspNetCore.Identity; -using OpenIddict.Abstractions; -using OpenIddict.Server; -using OpenIddict.Server.AspNetCore; -using static OpenIddict.Abstractions.OpenIddictConstants; -using static OpenIddict.Server.OpenIddictServerEvents; - -public sealed class PasswordGrantHandler : IOpenIddictServerHandler -{ - private readonly AppUserManager _userManager; - private readonly SignInManager> _signInManager; - - public PasswordGrantHandler( - AppUserManager userManager, - SignInManager> signInManager - ) - { - _userManager = userManager; - _signInManager = signInManager; - } - - public async ValueTask HandleAsync(HandleTokenRequestContext context) - { - if (!string.Equals(context.Request.GrantType, GrantTypes.Password, StringComparison.Ordinal)) - return; - - var username = context.Request.Username?.Trim(); - if (string.IsNullOrWhiteSpace(username)) - { - context.Reject(Errors.InvalidGrant, "Invalid username or password."); - return; - } - - var user = await _userManager.FindByNameAsync(username) - ?? await _userManager.FindByEmailAsync(username); - if (user is null) - { - context.Reject(Errors.InvalidGrant, "Invalid username or password."); - return; - } - - if (!await _signInManager.CanSignInAsync(user)) - { - context.Reject(Errors.InvalidGrant, "The specified user cannot sign in."); - return; - } - - if (_userManager.SupportsUserLockout && await _userManager.IsLockedOutAsync(user)) - { - context.Reject(Errors.InvalidGrant, "The specified user is locked out."); - return; - } - - var result = await _signInManager.CheckPasswordSignInAsync(user, context.Request.Password!, lockoutOnFailure: true); - if (!result.Succeeded) - { - context.Reject(Errors.InvalidGrant, "Invalid username or password."); - return; - } - - if (_userManager.SupportsUserLockout) - await _userManager.ResetAccessFailedCountAsync(user); - - context.SignIn(OpenIddictClaimsHelper.CreatePrincipal(user, context.Request.GetScopes())); - } -} diff --git a/MyOffice.Web/Identity/Repositories/AppUserManager.cs b/MyOffice.Web/Identity/Repositories/AppUserManager.cs deleted file mode 100644 index bbdf67e..0000000 --- a/MyOffice.Web/Identity/Repositories/AppUserManager.cs +++ /dev/null @@ -1,133 +0,0 @@ -namespace MyOffice.Web.Identity.Repositories; - -using System.Security.Cryptography; -using Domain; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Options; - -/// -/// Identity V3 hasher for new passwords; still verifies the legacy -/// (16-byte salt + 20-byte PBKDF2-SHA1 @ 100k) format and signals rehash. -/// -public class PasswordHasher : IPasswordHasher> -{ - private const int LegacySaltSize = 16; - private const int LegacyHashSize = 20; - private const int LegacyIterations = 100_000; - private const int LegacyPayloadSize = LegacySaltSize + LegacyHashSize; - - private readonly PasswordHasher> _identityHasher = new(); - - public string HashPassword(ApplicationUser user, string password) => - _identityHasher.HashPassword(user, password); - - public PasswordVerificationResult VerifyHashedPassword( - ApplicationUser user, - string hashedPassword, - string providedPassword - ) - { - if (string.IsNullOrEmpty(hashedPassword) || providedPassword == null) - { - return PasswordVerificationResult.Failed; - } - - // Prefer modern Identity format when payload is not the legacy 36-byte blob. - if (!IsLegacyPayload(hashedPassword)) - { - return _identityHasher.VerifyHashedPassword(user, hashedPassword, providedPassword); - } - - if (VerifyLegacyHash(providedPassword, hashedPassword)) - { - return PasswordVerificationResult.SuccessRehashNeeded; - } - - return PasswordVerificationResult.Failed; - } - - private static bool IsLegacyPayload(string hashedPassword) - { - try - { - var bytes = Convert.FromBase64String(hashedPassword); - return bytes.Length == LegacyPayloadSize; - } - catch (FormatException) - { - return false; - } - } - - internal static string HashLegacyForTests(string password) - { - var salt = RandomNumberGenerator.GetBytes(LegacySaltSize); - var hash = Rfc2898DeriveBytes.Pbkdf2( - password, - salt, - LegacyIterations, - HashAlgorithmName.SHA1, - LegacyHashSize); - - var payload = new byte[LegacyPayloadSize]; - Buffer.BlockCopy(salt, 0, payload, 0, LegacySaltSize); - Buffer.BlockCopy(hash, 0, payload, LegacySaltSize, LegacyHashSize); - return Convert.ToBase64String(payload); - } - - private static bool VerifyLegacyHash(string password, string passwordHash) - { - byte[] hashBytes; - try - { - hashBytes = Convert.FromBase64String(passwordHash); - } - catch (FormatException) - { - return false; - } - - if (hashBytes.Length != LegacyPayloadSize) - { - return false; - } - - var salt = hashBytes.AsSpan(0, LegacySaltSize); - var expected = hashBytes.AsSpan(LegacySaltSize, LegacyHashSize); - var actual = Rfc2898DeriveBytes.Pbkdf2( - password, - salt, - LegacyIterations, - HashAlgorithmName.SHA1, - LegacyHashSize); - - return CryptographicOperations.FixedTimeEquals(expected, actual); - } -} - -public class AppUserManager : UserManager> -{ - public AppUserManager( - IUserStore> store, - IOptions optionsAccessor, - IPasswordHasher> passwordHasher, - IEnumerable>> userValidators, - IEnumerable>> passwordValidators, - ILookupNormalizer keyNormalizer, - IdentityErrorDescriber errors, - IServiceProvider services, - ILogger>> logger) : - base( - store, - optionsAccessor, - passwordHasher, - userValidators, - passwordValidators, - keyNormalizer, - errors, - services, - logger - ) - { - } -} diff --git a/MyOffice.Web/Identity/Repositories/RoleStore.cs b/MyOffice.Web/Identity/Repositories/RoleStore.cs deleted file mode 100644 index 285f433..0000000 --- a/MyOffice.Web/Identity/Repositories/RoleStore.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace MyOffice.Web.Identity.Repositories; - -using Domain; -using Microsoft.AspNetCore.Identity; - -public class RoleStore : IRoleStore -{ - public void Dispose() - { - } - - public Task CreateAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task UpdateAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task DeleteAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task GetRoleIdAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task GetRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task SetRoleNameAsync(ApplicationRole role, string roleName, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task GetNormalizedRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task SetNormalizedRoleNameAsync(ApplicationRole role, string normalizedName, - CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task FindByIdAsync(string roleId, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Repositories/UserStore.cs b/MyOffice.Web/Identity/Repositories/UserStore.cs deleted file mode 100644 index 881d42a..0000000 --- a/MyOffice.Web/Identity/Repositories/UserStore.cs +++ /dev/null @@ -1,198 +0,0 @@ -namespace MyOffice.Web.Identity.Repositories; - -using Data.Models.Users; -using Data.Repositories.Users; -using Domain; -using Microsoft.AspNetCore.Identity; - -public class UserStore : - IUserStore>, - IUserPasswordStore>, - IUserEmailStore> -{ - private readonly IUserRepository _userRepository; - - public UserStore( - IUserRepository userRepository - ) - { - _userRepository = userRepository; - } - - public void Dispose() - { - } - - public Task GetUserIdAsync(ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(user.Id.ToString()); - } - - public Task GetUserNameAsync(ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(user.UserName); - } - - public Task SetUserNameAsync(ApplicationUser user, string userName, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task GetNormalizedUserNameAsync(ApplicationUser user, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task SetNormalizedUserNameAsync(ApplicationUser user, string normalizedName, - CancellationToken cancellationToken) - { - user.UserName = normalizedName; - return Task.FromResult(0); - } - - public Task CreateAsync(ApplicationUser user, CancellationToken cancellationToken) - { - var result = _userRepository.AddUser(new User - { - Id = user.Id, - UserName = user.UserName, - Email = user.Email, - PasswordHash = user.PasswordHash, - FirstName = user.FirstName, - LastName = user.LastName, - FullName = user.FullName, - CurrencyId = user.CurrencyId!, - IsEmailConfirmed = user.IsEmailConfirmed - }); - - return Task.FromResult(result == 1 ? IdentityResult.Success : IdentityResult.Failed()); - } - - public Task UpdateAsync(ApplicationUser user, CancellationToken cancellationToken) - { - var userDb = new User - { - Id = user.Id, - UserName = user.UserName, - Email = user.Email, - PasswordHash = user.PasswordHash, - FirstName = user.FirstName, - LastName = user.LastName, - FullName = user.FullName, - CurrencyId = user.CurrencyId!, - IsEmailConfirmed = user.IsEmailConfirmed - }; - - var result = _userRepository.UpdateUser(userDb); - return Task.FromResult(result == 1 ? IdentityResult.Success : IdentityResult.Failed()); - } - - public Task DeleteAsync(ApplicationUser user, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public async Task> FindByIdAsync(string userId, CancellationToken cancellationToken) - { - var user = await _userRepository.GetUserAsync(Guid.Parse(userId)); - if (user == null) - { -#pragma warning disable CS8603 // Possible null reference return. - return null; -#pragma warning restore CS8603 // Possible null reference return. - } - - return new ApplicationUser - { - Id = user.Id, - UserName = user.UserName, - Email = user.Email, - PasswordHash = user.PasswordHash, - FirstName = user.FirstName, - LastName = user.LastName, - FullName = user.FullName, - CurrencyId = user.CurrencyId, - IsEmailConfirmed = user.IsEmailConfirmed - }; - } - - public async Task> FindByNameAsync(string normalizedUserName, - CancellationToken cancellationToken) - { - var user = await _userRepository.GetByUserUserNameAsync(normalizedUserName); - if (user == null) - { -#pragma warning disable CS8603 // Possible null reference return. - return null; -#pragma warning restore CS8603 // Possible null reference return. - } - - return new ApplicationUser - { - Id = user.Id, - UserName = user.UserName, - Email = user.Email, - PasswordHash = user.PasswordHash, - FirstName = user.FirstName, - LastName = user.LastName, - FullName = user.FullName, - CurrencyId = user.CurrencyId, - IsEmailConfirmed = user.IsEmailConfirmed - }; - } - - public Task SetPasswordHashAsync(ApplicationUser user, string passwordHash, - CancellationToken cancellationToken) - { - user.PasswordHash = passwordHash; - return Task.FromResult(0); - } - - public Task GetPasswordHashAsync(ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(user.PasswordHash); - } - - public Task HasPasswordAsync(ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(!string.IsNullOrEmpty(user.PasswordHash)); - } - - public Task SetEmailAsync(ApplicationUser user, string email, CancellationToken cancellationToken) - { - user.Email = email; - return Task.CompletedTask; - } - - public Task GetEmailAsync(ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(user.Email); - } - - public Task GetEmailConfirmedAsync(ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(user.IsEmailConfirmed); - } - - public Task SetEmailConfirmedAsync(ApplicationUser user, bool confirmed, CancellationToken cancellationToken) - { - user.IsEmailConfirmed = confirmed; - return Task.CompletedTask; - } - - public Task> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken) - { - return FindByNameAsync(normalizedEmail, cancellationToken); - } - - public Task GetNormalizedEmailAsync(ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(user?.Email); - } - - public Task SetNormalizedEmailAsync(ApplicationUser user, string normalizedEmail, - CancellationToken cancellationToken) - { - return Task.FromResult(0); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Infrastructure/Attributes/AsGuidAttribute.cs b/MyOffice.Web/Infrastructure/Attributes/AsGuidAttribute.cs deleted file mode 100644 index 1439835..0000000 --- a/MyOffice.Web/Infrastructure/Attributes/AsGuidAttribute.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace MyOffice.Web.Infrastructure.Attributes -{ - using System.ComponentModel.DataAnnotations; - using Core.Extensions; - - public class AsGuidAttribute: ValidationAttribute - { - private readonly bool _nullable; - - public AsGuidAttribute(bool nullable = false) - { - _nullable = nullable; - } - - protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) - { - if (value == null && _nullable) - { - return ValidationResult.Success; - } - - if (value == null || value.ToString().IsMissing()) - { - return new ValidationResult("Id parameter is not valid"); - } - - if (!Guid.TryParse(value.ToString(), out _)) - { - return new ValidationResult("Id parameter is not valid"); - } - - return ValidationResult.Success; - } - } -} diff --git a/MyOffice.Web/Infrastructure/Attributes/DefaultFromBodyAttribute.cs b/MyOffice.Web/Infrastructure/Attributes/DefaultFromBodyAttribute.cs deleted file mode 100644 index 4ef604e..0000000 --- a/MyOffice.Web/Infrastructure/Attributes/DefaultFromBodyAttribute.cs +++ /dev/null @@ -1,71 +0,0 @@ -namespace MyOffice.Web.Infrastructure.Attributes; - -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ApplicationModels; -using Microsoft.AspNetCore.Mvc.ModelBinding; - -[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] -public sealed class DefaultFromBodyAttribute : Attribute -{ -} - -public class DefaultFromBodyBindingConvention : IActionModelConvention -{ - public void Apply(ActionModel action) - { - if (action == null) - { - throw new ArgumentNullException(nameof(action)); - } - - if (action.Controller.Attributes.Any(x => x is DefaultFromBodyAttribute)) - { - foreach (var parameter in action.Parameters) - { - if (parameter.Attributes.Any(x => - x is FromQueryAttribute - or FromRouteAttribute - or FromHeaderAttribute - or FromFormAttribute - or FromServicesAttribute)) - { - continue; - } - - // Already bound (e.g. CancellationToken → Special) — do not force Body. - if (parameter.BindingInfo?.BindingSource is { } existing - && existing != BindingSource.ModelBinding - && existing != BindingSource.Custom) - { - continue; - } - - var paramType = parameter.ParameterInfo.ParameterType; - if (paramType == typeof(CancellationToken) - || Nullable.GetUnderlyingType(paramType) == typeof(CancellationToken)) - { - continue; - } - - var isSimpleType = paramType.IsPrimitive - || paramType.IsEnum - || paramType == typeof(string) - || paramType == typeof(decimal) - || paramType == typeof(Guid) - || paramType == typeof(Guid?) - || paramType == typeof(DateTime) - || paramType == typeof(DateTime?) - || paramType == typeof(DateOnly) - || paramType == typeof(DateOnly?) - || paramType == typeof(TimeOnly) - || paramType == typeof(TimeOnly?); - - if (!isSimpleType) - { - parameter.BindingInfo ??= new BindingInfo(); - parameter.BindingInfo.BindingSource = BindingSource.Body; - } - } - } - } -} diff --git a/MyOffice.Web/Infrastructure/Attributes/GlobalModelStateValidatorAttribute.cs b/MyOffice.Web/Infrastructure/Attributes/GlobalModelStateValidatorAttribute.cs deleted file mode 100644 index fa8d645..0000000 --- a/MyOffice.Web/Infrastructure/Attributes/GlobalModelStateValidatorAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace MyOffice.Web.Infrastructure.Attributes; - -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.AspNetCore.Mvc.Infrastructure; - -public class GlobalModelStateValidatorAttribute : ActionFilterAttribute -{ - private readonly ProblemDetailsFactory _problemDetailsFactory; - - public GlobalModelStateValidatorAttribute(ProblemDetailsFactory problemDetailsFactory) - { - _problemDetailsFactory = problemDetailsFactory; - } - - public override void OnActionExecuting(ActionExecutingContext context) - { - if (!context.ModelState.IsValid) - { - context.Result = new ObjectResult(_problemDetailsFactory.CreateValidationProblemDetails(context.HttpContext, context.ModelState)) - { - StatusCode = StatusCodes.Status400BadRequest - }; - } - - base.OnActionExecuting(context); - } -} diff --git a/MyOffice.Web/Infrastructure/CustomProblemDetailsFactory.cs b/MyOffice.Web/Infrastructure/CustomProblemDetailsFactory.cs deleted file mode 100644 index 9b37b12..0000000 --- a/MyOffice.Web/Infrastructure/CustomProblemDetailsFactory.cs +++ /dev/null @@ -1,95 +0,0 @@ -namespace MyOffice.Web.Infrastructure; - -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Infrastructure; -using Microsoft.AspNetCore.Mvc.ModelBinding; -using Microsoft.Extensions.Options; - -public class CustomProblemDetailsFactory : ProblemDetailsFactory -{ - private readonly ApiBehaviorOptions options; - private readonly JsonOptions jsonOptions; - - public CustomProblemDetailsFactory(IOptions options, IOptions jsonOptions) - { - this.options = options?.Value ?? throw new ArgumentNullException(nameof(options)); - this.jsonOptions = jsonOptions?.Value ?? throw new ArgumentNullException(nameof(jsonOptions)); - } - - public override ProblemDetails CreateProblemDetails( - HttpContext httpContext, - int? statusCode = null, - string? title = null, - string? type = null, - string? detail = null, - string? instance = null) - { - statusCode ??= 500; - - var problemDetails = new ProblemDetails - { - Status = statusCode, - Title = title, - Type = type, - Detail = detail, - Instance = instance, - }; - - ApplyProblemDetailsDefaults(httpContext, problemDetails, statusCode.Value); - - return problemDetails; - } - - public override ValidationProblemDetails CreateValidationProblemDetails( - HttpContext httpContext, - ModelStateDictionary modelStateDictionary, - int? statusCode = null, - string? title = null, - string? type = null, - string? detail = null, - string? instance = null) - { - if (modelStateDictionary == null) - { - throw new ArgumentNullException(nameof(modelStateDictionary)); - } - - statusCode ??= 400; - - var errors = modelStateDictionary - .Where(x => x.Value?.Errors.Any() == true) - .ToDictionary( - kvp => jsonOptions?.JsonSerializerOptions?.PropertyNamingPolicy?.ConvertName(kvp.Key) ?? kvp.Key, - kvp => kvp.Value!.Errors.Select(x => x.ErrorMessage).ToArray() - ); - - var problemDetails = new ValidationProblemDetails(errors) - { - Status = statusCode, - Type = type, - Detail = detail, - Instance = instance, - }; - - if (title != null) - { - // For validation problem details, don't overwrite the default title with null. - problemDetails.Title = title; - } - - ApplyProblemDetailsDefaults(httpContext, problemDetails, statusCode.Value); - - return problemDetails; - } - - private void ApplyProblemDetailsDefaults(HttpContext httpContext, ProblemDetails problemDetails, int statusCode) - { - problemDetails.Status ??= statusCode; - - if (options.ClientErrorMapping.TryGetValue(statusCode, out var clientErrorData)) - { - problemDetails.Title ??= clientErrorData.Title; - problemDetails.Type ??= clientErrorData.Link; - } - } -} diff --git a/MyOffice.Web/Infrastructure/DatabaseInitializerHostedService.cs b/MyOffice.Web/Infrastructure/DatabaseInitializerHostedService.cs deleted file mode 100644 index b18e96a..0000000 --- a/MyOffice.Web/Infrastructure/DatabaseInitializerHostedService.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace MyOffice.Web.Infrastructure; - -using DbContext; - -/// -/// Runs EF migrate + seed on startup with a scoped DbContext. -/// -public sealed class DatabaseInitializerHostedService : IHostedService -{ - private readonly IServiceProvider _serviceProvider; - private readonly ILogger _logger; - - public DatabaseInitializerHostedService( - IServiceProvider serviceProvider, - ILogger logger - ) - { - _serviceProvider = serviceProvider; - _logger = logger; - } - - public async Task StartAsync(CancellationToken cancellationToken) - { - await using var scope = _serviceProvider.CreateAsyncScope(); - var db = scope.ServiceProvider.GetRequiredService(); - - _logger.LogInformation("Applying database migrations and seed data…"); - await DatabaseBootstrapper.InitializeAsync(db, cancellationToken); - _logger.LogInformation("Database ready."); - } - - public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; -} diff --git a/MyOffice.Web/Infrastructure/Filters/ResponseFilter.cs b/MyOffice.Web/Infrastructure/Filters/ResponseFilter.cs deleted file mode 100644 index dda3f3d..0000000 --- a/MyOffice.Web/Infrastructure/Filters/ResponseFilter.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace MyOffice.Web.Infrastructure.Filters; - -using System.Collections; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using MyOffice.Web.Models; - -public class ResponseFilter : IActionFilter -{ - private readonly ILogger _logger; - - public ResponseFilter(ILogger logger) - { - _logger = logger; - } - - public void OnActionExecuting(ActionExecutingContext context) - { - } - - public void OnActionExecuted(ActionExecutedContext context) - { - // TODO: restore - /*var route = $"{context.Controller.GetType().Name}.{context.ActionDescriptor.DisplayName}"; - if (context.Result == null) - throw new NotSupportedException($"[{route}] Response required"); - if (!(context.Result is ObjectResult result)) - throw new NotSupportedException($"[{route}] Response must be an ObjectResult - {context.Result?.GetType().Name}"); - if (result.Value == null) - throw new NotSupportedException($"[{route}] Response must be an ObjectResult with value"); - - if (result.Value is IResponseModel) - { - return; - } - - var type = result.Value.GetType(); - if (type.IsGenericType - && result.Value is IEnumerable - && type.GenericTypeArguments.Any(x => x.GetInterfaces().Any(y => y == typeof(IResponseModel)))) - { - return; - } - - throw new NotSupportedException($"[{route}] Response must be an ObjectResult with an IResponseModel - {result.Value?.GetType().Name}");*/ - } -} \ No newline at end of file diff --git a/MyOffice.Web/Infrastructure/GlobalSettings.cs b/MyOffice.Web/Infrastructure/GlobalSettings.cs deleted file mode 100644 index afa20c2..0000000 --- a/MyOffice.Web/Infrastructure/GlobalSettings.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyOffice.Web.Infrastructure; - -public class GlobalSettings -{ - public string? Host { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Web/Infrastructure/RouteHelper.cs b/MyOffice.Web/Infrastructure/RouteHelper.cs deleted file mode 100644 index d021e0d..0000000 --- a/MyOffice.Web/Infrastructure/RouteHelper.cs +++ /dev/null @@ -1,50 +0,0 @@ -namespace MyOffice.Web.Infrastructure; - -using System.Linq.Expressions; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; - -public static class RouteHelperExtensions -{ - public static void Bind(this IRouteBuilder routeBuilder, Expression> expression) - { - System.Console.WriteLine("Bind"); - System.Console.WriteLine(expression.Name); - System.Console.WriteLine(expression.Body.ToString()); - routeBuilder.MapRoute("SettingsAccountAccountsGet", "api/settings/accounts", new { controller = "SettingsAccount", action = "AccountsGet" }); - } -} - -public class CustomRouter : IRouter -{ - private readonly IRouter _defaultRouter; - private readonly string _controller; - private readonly string _action; - - public CustomRouter(IRouter defaultRouter, string controller, string action) - { - _defaultRouter = defaultRouter; - _controller = controller; - _action = action; - } - - public VirtualPathData? GetVirtualPath(VirtualPathContext context) - { - Console.WriteLine($"1:{context.RouteName}"); - return null; - } - - public async Task RouteAsync(RouteContext context) - { - var headers = context.HttpContext.Request.Headers; - var path = context.HttpContext.Request.Path.Value!.Split('/'); - - Console.WriteLine($"CustomRouter:{context.HttpContext.Request.Path.Value}"); - - context.RouteData.Values["controller"] = _controller; - context.RouteData.Values["action"] = _action; - - await _defaultRouter.RouteAsync(context); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Infrastructure/UnhandledExceptionHandler.cs b/MyOffice.Web/Infrastructure/UnhandledExceptionHandler.cs deleted file mode 100644 index 24cf6b8..0000000 --- a/MyOffice.Web/Infrastructure/UnhandledExceptionHandler.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace MyOffice.Web.Infrastructure; - -using Microsoft.AspNetCore.Diagnostics; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Infrastructure; - -/// -/// Returns ProblemDetails for unhandled exceptions (replaces missing /Error page). -/// -public sealed class UnhandledExceptionHandler : IExceptionHandler -{ - private readonly IHostEnvironment _environment; - private readonly ILogger _logger; - private readonly ProblemDetailsFactory _problemDetailsFactory; - - public UnhandledExceptionHandler( - IHostEnvironment environment, - ILogger logger, - ProblemDetailsFactory problemDetailsFactory - ) - { - _environment = environment; - _logger = logger; - _problemDetailsFactory = problemDetailsFactory; - } - - public async ValueTask TryHandleAsync( - HttpContext httpContext, - Exception exception, - CancellationToken cancellationToken - ) - { - _logger.LogError(exception, "Unhandled exception for {Method} {Path}", - httpContext.Request.Method, - httpContext.Request.Path); - - var problem = _problemDetailsFactory.CreateProblemDetails( - httpContext, - statusCode: StatusCodes.Status500InternalServerError, - title: "An unexpected error occurred.", - detail: _environment.IsDevelopment() ? exception.Message : null); - - httpContext.Response.StatusCode = problem.Status ?? StatusCodes.Status500InternalServerError; - httpContext.Response.ContentType = "application/problem+json"; - await httpContext.Response.WriteAsJsonAsync(problem, cancellationToken); - return true; - } -} diff --git a/MyOffice.Web/Models/Account/AccessRightsViewModel.cs b/MyOffice.Web/Models/Account/AccessRightsViewModel.cs deleted file mode 100644 index 108f2f8..0000000 --- a/MyOffice.Web/Models/Account/AccessRightsViewModel.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -using AutoMapper; -using MyOffice.Services.Account.Domain; -using MyOffice.Services.Identity; -using User; - -public class AccessRightsViewModel -{ - public UserViewModel? User { get; set; } = null!; - public bool AllowRead { get; set; } - public bool AllowWrite { get; set; } - public bool AllowManage { get; set; } - public bool AllowDelete { get; set; } - public bool IsOwner { get; set; } -} - -public class AccessRightsViewModelProfile : Profile -{ - public AccessRightsViewModelProfile() - { - CreateMap() - .AfterMap() - ; - - } -} - -public class AccessRightsViewModelMappingAction : IMappingAction -{ - private readonly IContextProvider _contextProvider; - - public AccessRightsViewModelMappingAction(IContextProvider contextProvider) - { - _contextProvider = contextProvider; - } - - public void Process(AccountAccessDto source, AccessRightsViewModel destination, ResolutionContext context) - { - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountAccessInviteViewModel.cs b/MyOffice.Web/Models/Account/AccountAccessInviteViewModel.cs deleted file mode 100644 index b691570..0000000 --- a/MyOffice.Web/Models/Account/AccountAccessInviteViewModel.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -using AutoMapper; -using MyOffice.Services.Account.Domain; - -public class AccountAccessInviteViewModel: IResponseModel -{ - public string? Id { get; set; } - public string? Account { get; set; } - public bool? AllowWrite { get; set; } -} - -public class AccountAccessInviteViewModelProfile: Profile -{ - public AccountAccessInviteViewModelProfile() - { - CreateMap() - .ForMember(x => x.AllowWrite, o => o.MapFrom(x => x.IsAllowWrite)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountAccessViewModel.cs b/MyOffice.Web/Models/Account/AccountAccessViewModel.cs deleted file mode 100644 index 90046b7..0000000 --- a/MyOffice.Web/Models/Account/AccountAccessViewModel.cs +++ /dev/null @@ -1,24 +0,0 @@ -using AutoMapper; -using MyOffice.Services.Account.Domain; - -namespace MyOffice.Web.Models.Account; - -public class AccountAccessViewModel -{ - public class AccountAccessItemViewModel - { - public string UserId { get; set; } = null!; - public bool AllowWrite { get; set; } - } - - public string? Email { get; set; } - public bool AllowWrite { get; set; } - public List Accesses { get; set; } = null!; -} - -public class AccountAccessItemViewModelProfile : Profile -{ - public AccountAccessItemViewModelProfile() - { - } -} diff --git a/MyOffice.Web/Models/Account/AccountCategoryViewModel.cs b/MyOffice.Web/Models/Account/AccountCategoryViewModel.cs deleted file mode 100644 index b36df26..0000000 --- a/MyOffice.Web/Models/Account/AccountCategoryViewModel.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -using System.ComponentModel.DataAnnotations; -using AutoMapper; -using MyOffice.Services.Account.Domain; - -public class AccountCategoryViewModel: IResponseModel -{ - public string? Id { get; set; } - - [Required] - public string? Name { get; set; } - - public bool? AllowDelete { get; set; } -} - -public class AccountCategoryViewModelProfile: Profile -{ - public AccountCategoryViewModelProfile() - { - CreateMap() - .ForMember(x => x.Id, o => o.MapFrom(x => x.CategoryId)) - .ForMember(x => x.Name, o => o.MapFrom(x => x.Category!.Name)) - ; - CreateMap() - .ForMember(x => x.Id, o => o.MapFrom(x => x.Id)) - .ForMember(x => x.Name, o => o.MapFrom(x => x.Name)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountDetailedViewModel.cs b/MyOffice.Web/Models/Account/AccountDetailedViewModel.cs deleted file mode 100644 index 63b1448..0000000 --- a/MyOffice.Web/Models/Account/AccountDetailedViewModel.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -using AutoMapper; -using MyOffice.Services.Account.Domain; - -public class AccountDetailedViewModel: BaseViewModel -{ - public AccountViewModel Account { get; set; } = null!; - public decimal Rest { get; set; } -} - -public class AccountDetailedViewModelProfile: Profile -{ - public AccountDetailedViewModelProfile() - { - CreateMap() - .ForMember(x => x.Account, o => o.MapFrom(x => x.Account)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountEditRequestModel.cs b/MyOffice.Web/Models/Account/AccountEditRequestModel.cs deleted file mode 100644 index 07ee7c9..0000000 --- a/MyOffice.Web/Models/Account/AccountEditRequestModel.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -using System.ComponentModel.DataAnnotations; - -public class AccountEditRequestModel -{ - [Required] - public string Name { get; set; } = null!; - [Required] - public string CurrencyId { get; set; } = null!; - public string? CategoryId { get; set; } - public string? UserId { get; set; } - public string? Type { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountInviteAcceptRequest.cs b/MyOffice.Web/Models/Account/AccountInviteAcceptRequest.cs deleted file mode 100644 index 246160f..0000000 --- a/MyOffice.Web/Models/Account/AccountInviteAcceptRequest.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -public class AccountInviteAcceptRequest -{ - public string Name { get; set; } = null!; -} diff --git a/MyOffice.Web/Models/Account/AccountViewModel.cs b/MyOffice.Web/Models/Account/AccountViewModel.cs deleted file mode 100644 index 5ee5a51..0000000 --- a/MyOffice.Web/Models/Account/AccountViewModel.cs +++ /dev/null @@ -1,61 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -using AutoMapper; -using MyOffice.Services.Account.Domain; -using MyOffice.Services.Identity; -using Newtonsoft.Json; -using System.ComponentModel.DataAnnotations; - -public class AccountViewModel: IResponseModel -{ - public string? Id { get; set; } - - [Required] - public string Name { get; set; } = null!; - public string Type { get; set; } = null!; - - [Required] - public string CurrencyId { get; set; } = null!; - public string? CurrencyName { get; set; } - - public List? Categories { get; set; } - - [Required] - public string CategoryId { get; set; } = null!; - - #region Permissions - - public List? AccessRights { get; set; } - public bool AllowRead { get; set; } - public bool AllowWrite { get; set; } - public bool AllowDelete { get; set; } - public bool AllowManage { get; set; } - - #endregion Permissions -} - -public class AccountViewModelProfile : Profile -{ - public AccountViewModelProfile() - { - CreateMap() - .ForMember(x => x.CurrencyId, o => o.MapFrom(x => x.CurrencyGlobalId)) - .ForMember(x => x.CurrencyName, o => o.MapFrom(x => x.Currency!.Name)) - .AfterMap() - ; - } -} - -public class AccountViewModelMappingAction : IMappingAction -{ - private readonly IContextProvider _contextProvider; - - public AccountViewModelMappingAction(IContextProvider contextProvider) - { - _contextProvider = contextProvider; - } - - public void Process(AccountDto source, AccountViewModel destination, ResolutionContext context) - { - } -} diff --git a/MyOffice.Web/Models/Account/AccountViewModelProfile.cs b/MyOffice.Web/Models/Account/AccountViewModelProfile.cs deleted file mode 100644 index 5a8b582..0000000 --- a/MyOffice.Web/Models/Account/AccountViewModelProfile.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace MyOffice.Web.Models.Account; - -using AutoMapper; - -using MyOffice.Services.Currency.Domain; -using Currency; -using Item; -using Motion; -using Services.Account.Domain; -using User; -using MyOffice.Services.Identity; - -/*public class CustomResolver : IValueResolver -{ - private readonly ILogger _logger; - private readonly IContextProvider _contextProvider; - - public CustomResolver( - ILogger logger, - IContextProvider contextProvider - ) - { - _logger = logger; - _contextProvider = contextProvider; - } - - public bool Resolve(AccountAccessDto source, AccessRightsViewModel destination, bool member, ResolutionContext context) - { - return source.OwnerId == _contextProvider.UserId; - } -}*/ - -/*public class PublicationSystemResolver : IMemberValueResolver -{ - private readonly IContextProvider _contextProvider; - - public PublicationSystemResolver( - IContextProvider contextProvider - ) - { - this._contextProvider = contextProvider; - } - - public bool Resolve(object source, object destination, string sourceMember, bool destMember, ResolutionContext context) - { - return true; - } -}*/ \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/MotionsGetRequest.cs b/MyOffice.Web/Models/Account/MotionsGetRequest.cs deleted file mode 100644 index 4c7bcd3..0000000 --- a/MyOffice.Web/Models/Account/MotionsGetRequest.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MyOffice.Web.Models.Account -{ - using System.ComponentModel.DataAnnotations; - - public class MotionsGetRequest - { - [Required] - public DateTime From { get; set; } - [Required] - public DateTime To { get; set; } - } -} diff --git a/MyOffice.Web/Models/Auth/LoginModel.cs b/MyOffice.Web/Models/Auth/LoginModel.cs deleted file mode 100644 index 7127c9c..0000000 --- a/MyOffice.Web/Models/Auth/LoginModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MyOffice.Web.Models.Auth; - -public class LoginModel -{ - public string? UserName { get; set; } - public string? Password { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Auth/RegisterModel.cs b/MyOffice.Web/Models/Auth/RegisterModel.cs deleted file mode 100644 index 086c364..0000000 --- a/MyOffice.Web/Models/Auth/RegisterModel.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace MyOffice.Web.Models.Auth; - -using System.ComponentModel.DataAnnotations; - -public class RegisterModel -{ - [Required] - [EmailAddress] - public string UserName { get; set; } = null!; - - [Required] - [MinLength(8)] - public string Password { get; set; } = null!; - - [Required] - [Compare(nameof(Password))] - public string ConfirmPassword { get; set; } = null!; -} diff --git a/MyOffice.Web/Models/BaseViewModel.cs b/MyOffice.Web/Models/BaseViewModel.cs deleted file mode 100644 index 8a65a94..0000000 --- a/MyOffice.Web/Models/BaseViewModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyOffice.Web.Models; - -public class BaseViewModel : IResponseModel -{ - -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Currency/CurrencyAddModel.cs b/MyOffice.Web/Models/Currency/CurrencyAddModel.cs deleted file mode 100644 index cdb00e5..0000000 --- a/MyOffice.Web/Models/Currency/CurrencyAddModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MyOffice.Web.Models.Currency -{ - public class CurrencyAddModel - { - public string Id { get; set; } = null!; - public string Name { get; set; } = null!; - public string ShortName { get; set; } = null!; - public int Quantity { get; set; } - public decimal Rate { get; set; } - public DateTime RateDate { get; set; } - } - - public class CurrencyRateModel - { - public int Quantity { get; set; } - public decimal Rate { get; set; } - public DateTime RateDate { get; set; } - } -} diff --git a/MyOffice.Web/Models/Currency/CurrencyEditModel.cs b/MyOffice.Web/Models/Currency/CurrencyEditModel.cs deleted file mode 100644 index 412607a..0000000 --- a/MyOffice.Web/Models/Currency/CurrencyEditModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MyOffice.Web.Models.Currency; - -public class CurrencyEditModel -{ - public string Name { get; set; } = null!; - public string ShortName { get; set; } = null!; - public int Quantity { get; set; } - public decimal Rate { get; set; } - public DateTime RateDate { get; set; } - public bool IsPrimary { get; set; } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Currency/CurrencyGlobalViewModel.cs b/MyOffice.Web/Models/Currency/CurrencyGlobalViewModel.cs deleted file mode 100644 index 6b71f9a..0000000 --- a/MyOffice.Web/Models/Currency/CurrencyGlobalViewModel.cs +++ /dev/null @@ -1,22 +0,0 @@ -/// -/// -namespace MyOffice.Web.Models.Currency; - -using AutoMapper; -using MyOffice.Services.Currency.Domain; - -public class CurrencyGlobalViewModel: IResponseModel -{ - public string Id { get; set; } = null!; - public string Name { get; set; } = null!; - public int Quantity { get; set; } - public string Symbol { get; set; } = null!; -} - -public class CurrencyGlobalViewModelProfile : Profile -{ - public CurrencyGlobalViewModelProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Currency/CurrencyRateViewModel.cs b/MyOffice.Web/Models/Currency/CurrencyRateViewModel.cs deleted file mode 100644 index 0b6f26c..0000000 --- a/MyOffice.Web/Models/Currency/CurrencyRateViewModel.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace MyOffice.Web.Models.Currency; - -using AutoMapper; -using MyOffice.Services.Currency.Domain; - -public class CurrencyRateViewModel: BaseViewModel -{ - public string Currency { get; set; } = null!; - public DateTime DateTime { get; set; } - public int Quantity { get; set; } - public decimal Rate { get; set; } -} - -public class CurrencyRateViewModelProfile: Profile -{ - public CurrencyRateViewModelProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Currency/CurrencyViewModel.cs b/MyOffice.Web/Models/Currency/CurrencyViewModel.cs deleted file mode 100644 index efade2f..0000000 --- a/MyOffice.Web/Models/Currency/CurrencyViewModel.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace MyOffice.Web.Models.Currency; - -using AutoMapper; -using MyOffice.Services.Currency.Domain; - -public class CurrencyViewModel: BaseViewModel -{ - public string Id { get; set; } = null!; - public string Code { get; set; } = null!; - public string Symbol { get; set; } = null!; - public string Name { get; set; } = null!; - public string ShortName { get; set; } = null!; - public decimal? Rate { get; set; } - public int? Quantity { get; set; } - public DateTime? RateDate { get; set; } - public bool IsPrimary { get; set; } -} - -public class CurrencyViewModelProfile: Profile -{ - public CurrencyViewModelProfile() - { - CreateMap(); - - CreateMap() - .ForMember(x => x.Id, o => o.MapFrom(x => x.Currency.Id)) - .ForMember(x => x.Code, o => o.MapFrom(x => x.Currency.CurrencyGlobalId)) - .ForMember(x => x.Name, o => o.MapFrom(x => x.Currency.Name)) - .ForMember(x => x.ShortName, o => o.MapFrom(x => x.Currency.ShortName)) - .ForMember(x => x.Rate, o => o.MapFrom(x => x.Rate == null ? (decimal?)null : x.Rate.Rate)) - .ForMember(x => x.IsPrimary, o => o.MapFrom(x => x.Currency.IsPrimary)) - .ForMember(x => x.Quantity, o => o.MapFrom(x => x.Rate == null ? (int?)null : x.Rate.Quantity)) - .ForMember(x => x.RateDate, o => o.MapFrom(x => x.Rate == null ? (DateTime?)null : x.Rate.DateTime)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Dashboard/DashboardIncomeDataViewModel.cs b/MyOffice.Web/Models/Dashboard/DashboardIncomeDataViewModel.cs deleted file mode 100644 index 8af7fb0..0000000 --- a/MyOffice.Web/Models/Dashboard/DashboardIncomeDataViewModel.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Web.Models.Dashboard; - -using AutoMapper; -using MyOffice.Services.Dashboard.Domain; - -public class DashboardIncomeDataViewModel : DashboardIncomeData, IResponseModel -{ - -} - -public class DashboardIncomeDataViewModelProfile : Profile -{ - public DashboardIncomeDataViewModelProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Dashboard/DashboardViewModel.cs b/MyOffice.Web/Models/Dashboard/DashboardViewModel.cs deleted file mode 100644 index 42d4b46..0000000 --- a/MyOffice.Web/Models/Dashboard/DashboardViewModel.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MyOffice.Web.Models.Dashboard; - -using AutoMapper; -using MyOffice.Services.Dashboard.Domain; - -public class DashboardViewModel : DashboardData, IResponseModel -{ - -} - -public class DashboardViewModelProfile : Profile -{ - public DashboardViewModelProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/IRequestModel.cs b/MyOffice.Web/Models/IRequestModel.cs deleted file mode 100644 index 95ac4db..0000000 --- a/MyOffice.Web/Models/IRequestModel.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace MyOffice.Web.Models; - -public interface IRequestModel -{ -} diff --git a/MyOffice.Web/Models/IResponseModel.cs b/MyOffice.Web/Models/IResponseModel.cs deleted file mode 100644 index c1948e0..0000000 --- a/MyOffice.Web/Models/IResponseModel.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace MyOffice.Web.Models; - -public interface IResponseModel -{ -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Item/ItemCategoryViewModel.cs b/MyOffice.Web/Models/Item/ItemCategoryViewModel.cs deleted file mode 100644 index d6596d5..0000000 --- a/MyOffice.Web/Models/Item/ItemCategoryViewModel.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace MyOffice.Web.Models.Item; - -using System.ComponentModel.DataAnnotations; -using AutoMapper; -using Services.Account.Domain; - -public class ItemCategoryViewModel: IResponseModel -{ - public string? Id { get; set; } - - [Required] - public string Name { get; set; } = null!; - - public bool AllowDelete { get; set; } - public int SortOrder { get; set; } - public bool Internal { get; set; } -} - -//TODO: REMOVE -public static class ItemCategoryViewModelExtensions -{ - public static ItemCategoryDto FromModel(this ItemCategoryViewModel input) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - return new ItemCategoryDto - { - Name = input.Name, - IsInternal = input.Internal, - }; - } -} - -public class ItemCategoryViewModelProfile: Profile -{ - public ItemCategoryViewModelProfile() - { - CreateMap() - .ForMember(x => x.Internal, o => o.MapFrom(x => x.IsInternal)) - .ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Items.Any() && x.Id != x.UserId)) - .ForMember(x => x.SortOrder, o => o.MapFrom(x => x.Id == x.UserId ? 1 : 0)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Item/ItemChangeCategoryModel.cs b/MyOffice.Web/Models/Item/ItemChangeCategoryModel.cs deleted file mode 100644 index 104544d..0000000 --- a/MyOffice.Web/Models/Item/ItemChangeCategoryModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MyOffice.Web.Models.Item; - -public class ItemChangeCategoryModel -{ - public string category { get; set; } = null!; - public List Items { get; set; } = null!; -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Item/ItemEditModel.cs b/MyOffice.Web/Models/Item/ItemEditModel.cs deleted file mode 100644 index 43f161a..0000000 --- a/MyOffice.Web/Models/Item/ItemEditModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MyOffice.Web.Models.Item; - -public class ItemEditModel -{ - public string Id { get; set; } = null!; - public string Category { get; set; } = null!; -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Item/ItemViewModel.cs b/MyOffice.Web/Models/Item/ItemViewModel.cs deleted file mode 100644 index 33a0a12..0000000 --- a/MyOffice.Web/Models/Item/ItemViewModel.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace MyOffice.Web.Models.Item; - -using System.ComponentModel.DataAnnotations; -using AutoMapper; -using MyOffice.Services.Account.Domain; - -public class ItemViewModel : BaseViewModel -{ - public string? Id { get; set; } - [Required] - public string? Name { get; set; } - - public bool AllowDelete { get; set; } - - public string CategoryId { get; set; } = null!; - public string? Category { get; set; } = null!; - - public string? AccountId { get; set; } -} - -public class ItemViewModelProfile: Profile -{ - public ItemViewModelProfile() - { - CreateMap() - .ForMember(x => x.Category, o => o.MapFrom(x => x.Category!.Name)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Motion/AccountControllerProfile.cs b/MyOffice.Web/Models/Motion/AccountControllerProfile.cs deleted file mode 100644 index c976d20..0000000 --- a/MyOffice.Web/Models/Motion/AccountControllerProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace MyOffice.Web.Models.Motion; - -using AutoMapper; -using Data.Models.Accounts; -using Services.Account.Domain; - -public class AccountControllerProfile : Profile -{ - public AccountControllerProfile() - { - CreateMap() - .ForMember(x => x.Date, o => o.MapFrom(x => x.DateTime)) - .ForMember(x => x.Item, o => o.MapFrom(x => x.Item.ItemGlobal.Name)) - .ForMember(x => x.Plus, o => o.MapFrom(x => x.AmountPlus)) - .ForMember(x => x.Minus, o => o.MapFrom(x => x.AmountMinus)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Motion/MotionRequest.cs b/MyOffice.Web/Models/Motion/MotionRequest.cs deleted file mode 100644 index a4f2bc8..0000000 --- a/MyOffice.Web/Models/Motion/MotionRequest.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace MyOffice.Web.Models.Motion; - -using AutoMapper; -using MyOffice.Services.Account.Domain; - -public class MotionRequest -{ - public DateTime Date { get; set; } - public string Item { get; set; } = null!; - public string? ItemId { get; set; } = null!; - public string? AccountId { get; set; } = null!; - public string? Description { get; set; } - public decimal? Plus { get; set; } - public decimal? Minus { get; set; } - public decimal? AmountBalancing { get; set; } -} - -public class MotionRequestProfile : Profile -{ - public MotionRequestProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/Motion/MotionViewModel.cs b/MyOffice.Web/Models/Motion/MotionViewModel.cs deleted file mode 100644 index c5a0f11..0000000 --- a/MyOffice.Web/Models/Motion/MotionViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace MyOffice.Web.Models.Motion; - -using AutoMapper; -using MyOffice.Services.Account.Domain; - -public class MotionViewModel : BaseViewModel -{ - public string Id { get; set; } = null!; - public DateTime Date { get; set; } - public string AccountId { get; set; } = null!; - public string Item { get; set; } = null!; - public string? Description { get; set; } - public decimal Plus { get; set; } - public decimal Minus { get; set; } -} - -public class MotionViewModelProfile : Profile -{ - public MotionViewModelProfile() - { - CreateMap() - .ForMember(x => x.Item, x => x.MapFrom(m => m.Item.Name)) - .ForMember(x => x.Minus, x => x.MapFrom(m => m.AmountMinus)) - .ForMember(x => x.Plus, x => x.MapFrom(m => m.AmountPlus)) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/User/UserViewModel.cs b/MyOffice.Web/Models/User/UserViewModel.cs deleted file mode 100644 index 03d8b8b..0000000 --- a/MyOffice.Web/Models/User/UserViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MyOffice.Web.Models.User; - -using AutoMapper; -using MyOffice.Services.Account.Domain; - -public class UserViewModel -{ - public string Id { get; set; } = null!; - public string UserName { get; set; } = null!; - public string Email { get; set; } = null!; -} - -public class UserViewModelProfile: Profile -{ - public UserViewModelProfile() - { - CreateMap(); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Models/ViewModelProfile.cs b/MyOffice.Web/Models/ViewModelProfile.cs deleted file mode 100644 index a5e4db6..0000000 --- a/MyOffice.Web/Models/ViewModelProfile.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MyOffice.Web.Models; - -using AutoMapper; -using Core.Extensions; - -public class ViewModelProfile : Profile -{ - public ViewModelProfile() - { - CreateMap().ConvertUsing(x => x.ToShort()); - } -} \ No newline at end of file diff --git a/MyOffice.Web/MyOffice.Web.csproj b/MyOffice.Web/MyOffice.Web.csproj deleted file mode 100644 index 4456927..0000000 --- a/MyOffice.Web/MyOffice.Web.csproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - net10.0 - enable - enable - - - - - - - - - - - - - - - - - - - - - - Never - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MyOffice.Web/Program.Routes.cs b/MyOffice.Web/Program.Routes.cs deleted file mode 100644 index 9ec95fe..0000000 --- a/MyOffice.Web/Program.Routes.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace MyOffice.Web; - -public partial class Program -{ - /// - /// Legacy imperative MapRoute table removed — API controllers use attribute routing. - /// Kept as a no-op so call sites stay stable while Routes constants remain for SPA/docs. - /// - private static void MapRoutes(WebApplication app) - { - } -} - -/// -/// Canonical API path constants (also used by SPA clients / docs). -/// -public static class Routes -{ - public static readonly string GlobalCurrencies = "api/general/currencies"; - public static readonly string SettingsCurrencies = "api/settings/currencies"; - public static readonly string SettingsCurrency = "api/settings/currencies/{id}"; - public static readonly string SettingsCurrencyRate = "api/settings/currencies/{id}/rate"; - - public static readonly string SettingsAccountCategories = "api/settings/account-categories"; - public static readonly string SettingsAccountCategory = "api/settings/account-categories/{id}"; - - public static readonly string SettingsAccounts = "api/settings/accounts"; - public static readonly string SettingsAccount = "api/settings/accounts/{id}"; - public static readonly string SettingsAccountAccountCategory = "api/settings/accounts/{id}/category/{categoryId}"; - - public static readonly string SettingsAccountAccesses = "api/settings/accounts/{id}/access"; - public static readonly string SettingsAccountAccess = "api/settings/accounts/{id}/access/{userId}"; - public static readonly string SettingsAccountInvites = "api/settings/accounts/invites"; - public static readonly string SettingsAccountInviteAccept = "api/settings/accounts/invites/{id}/accept"; - public static readonly string SettingsAccountInviteReject = "api/settings/accounts/invites/{id}/reject"; - - public static readonly string SettingsItemCategories = "api/settings/item-categories"; - public static readonly string SettingsItemCategory = "api/settings/item-categories/{id}"; - public static readonly string SettingsItems = "api/settings/items"; - public static readonly string SettingsItem = "api/settings/items/{id}"; - - public static readonly string Accounts = "api/accounts"; - public static readonly string Account = "api/accounts/{id}"; - public static readonly string AccountMotions = "api/accounts/{id}/motions"; - public static readonly string AccountMotion = "api/accounts/{id}/motions/{motionId}"; - public static readonly string Items = "api/items"; - - public static readonly string Dashboard = "api/dashboard"; - public static readonly string DashboardIncome = "api/dashboard/income"; - public static readonly string DashboardOutcome = "api/dashboard/outcome"; - - public static readonly string UserRegister = "api/user/register"; - public static readonly string UserProfile = "api/user/profile"; - public static readonly string UserAttach = "api/user/attach"; - public static readonly string UserDeattach = "api/user/deattach"; -} diff --git a/MyOffice.Web/Program.cs b/MyOffice.Web/Program.cs deleted file mode 100644 index 4aabbda..0000000 --- a/MyOffice.Web/Program.cs +++ /dev/null @@ -1,449 +0,0 @@ -namespace MyOffice.Web; - -using System.IO; -using System.Linq; -using System.Collections.Concurrent; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.FileProviders.Physical; -using Microsoft.Extensions.Logging; -using Microsoft.IdentityModel.Logging; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging.Console; -using System.Text.Json.Serialization; - -using Identity; -using Identity.Domain; -using Identity.ExternalProviders; -using Identity.Repositories; -using Auth; -using Core.Identity; -using Core.Extensions; -using Data.Repositories.Account; -using Data.Repositories.Currency; -using Data.Repositories.Item; -using Data.Repositories.Users; -using DbContext; -using Services.Users; -using Shared; -using Infrastructure; -using Models.Account; -using MyOffice.Services.Currency; -using Services.Account; -using Services.Item; -using MyOffice.Services.Dashboard; -using MyOffice.Services.Identity; -using MyOffice.Services.Account.Domain; -using MyOffice.Web.Infrastructure.Attributes; -using System.Text.Json; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Infrastructure; -using MyOffice.Web.Infrastructure.Filters; - -//TODO: Data.Model only Repository and Service, response <-> mapper <-> web <-> mapper <-> service <-> repository -//TODO: Project management -//TODO: Model names. Controller = xxxRequest/xxxResponse. Service xxxInput/xxxOutput. -//TODO: Validate string as Guid when id -//TODO: Test back -//TODO: Test front -//TODO: Test DB ??? -//TODO: Email confirmation -//TODO: Password recovery -//TODO: Account sharing -//TODO: /dashboard/dashboard -> /dashboard/main or /dashboard -//TODO: SPA load categories twice menu + setting (cache) -//TODO: SPA update account category -> update menu -//TODO: Response model from base type -//TODO: XXXResult -> XXXStatus -//TODO: SPA isAllowDelete -> allowDelete (remove is) -//TODO: Repository auto registration -//TODO: Services auto registration -//TODO: openid-configuration failed - lock login -//TODO: BUG some times after login redirect to dashboard but exists return url -//TODO: automapper -> Extension ToModel() ToDbo() FromModel() FromDbo() -//TODO: SPA all http requests -> services -//TODO: Items, select category -> save url to allow refresh -//TODO: Accounts, select category -> save url to allow refresh - -public partial class Program -{ - public static void Main(string[] args) - { - var builder = WebApplication.CreateBuilder(args); - AddServices(builder, args); - - var app = builder.Build(); - Configure(app); - - app.Run(); - } - - private static void AddServices(WebApplicationBuilder builder, string[] args) - { - #region Loging - - builder.Services.AddLogging(logging => - logging.AddSimpleConsole(options => - { - //options.SingleLine = true; - options.TimestampFormat = "[HH:mm:ss] "; - options.ColorBehavior = LoggerColorBehavior.Enabled; - }) - ); - //File Logger - builder.Logging.AddFile(builder.Configuration.GetSection("Logging")); - - #endregion Loging - - builder.Services.Configure(options => - { - options.AddFilter("OpenIddict", LogLevel.Warning); - }); - - // Shared JSON after appsettings.*, then restore higher-priority sources - builder.Configuration.AddSharedAppSettings(builder.Environment.EnvironmentName); - builder.Configuration.AddEnvironmentVariables(); - builder.Configuration.AddCommandLine(args); - - #region Database - - var databaseProvider = builder.Configuration["DatabaseProvider"]; - if (databaseProvider == null) - throw new NullReferenceException($"Configuration DatabaseProvider {databaseProvider}"); - - var connectionString = builder.Configuration.GetConnectionString(databaseProvider); - if (connectionString == null) - throw new NullReferenceException($"Configuration ConnectionString {databaseProvider}"); - - var connectionConfiguration = new ConnectionConfiguration(databaseProvider, connectionString); - RepositoryInitializer.Initialize(builder.Services, connectionConfiguration); - // Before OpenIddictSeeder so the schema exists when clients/scopes are registered. - builder.Services.AddHostedService(); - - #endregion Database - - // Configurations - builder.Services.Configure( - builder.Configuration.GetSection("ExternalProviders") - ); - - InitializeGlobalSettings(builder); - - AddIdentityServices(builder); - - builder.Services.AddScoped(); - - AddAutoMapper(builder); - - AddRepositories(builder); - - AddBusinessServices(builder); - - builder.Services - .AddControllers() - .AddJsonOptions(options => - { - options.AllowInputFormatterExceptionMessages = builder.Environment.IsDevelopment(); - options.JsonSerializerOptions.MaxDepth = 0; - options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; - options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; - options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; - options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase; - }); - - builder.Services.AddCors(); - - builder.Services.AddControllersWithViews(options => - { - options.Conventions.Add(new DefaultFromBodyBindingConvention()); - options.Filters.Add(typeof(GlobalModelStateValidatorAttribute)); - options.Filters.Add(typeof(ResponseFilter)); - }); - - builder.Services.Configure(options => - { - }); - - builder.Services.Configure(x => { - }); - - builder.Services.AddProblemDetails(); - builder.Services.AddExceptionHandler(); - builder.Services.AddSingleton(); - } - - private static void InitializeGlobalSettings(WebApplicationBuilder builder) - { - var frontEndHost = builder.Configuration.GetValue("FrontEnd:Host"); - if (frontEndHost.IsMissing()) - { - frontEndHost = "http://localhost:4300"; - if (!builder.Environment.IsDevelopment()) - { - throw new InvalidOperationException( - "FrontEnd:Host must be set outside Development (do not derive it from Referer)."); - } - } - - frontEndHost = frontEndHost!.TrimEnd('/'); - builder.Services.Configure(options => options.Host = frontEndHost); - builder.Services.AddSingleton(resolver => resolver.GetRequiredService>().Value); - } - - private static void AddIdentityServices(WebApplicationBuilder builder) - { - builder.Services.AddHttpContextAccessor(); - - // add identity - builder.Services - .AddIdentity, ApplicationRole>() - .AddUserStore() - .AddRoleStore() - .AddUserManager() - .AddSignInManager>>() - .AddDefaultTokenProviders(); - - builder.Services.AddScoped>, PasswordHasher>(); - - // Identity Services - builder.Services.AddScoped>, UserStore>(); - builder.Services.AddScoped, RoleStore>(); - - // External providers - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - // Configure Identity options and password complexity here - builder.Services.Configure(options => - { - // User settings - options.User.RequireUniqueEmail = true; - - // Email+password accounts can sign in immediately after register - options.SignIn.RequireConfirmedAccount = false; - options.SignIn.RequireConfirmedEmail = false; - - // Password settings - options.Password.RequireDigit = true; - options.Password.RequiredLength = 8; - options.Password.RequireNonAlphanumeric = true; - options.Password.RequireUppercase = true; - options.Password.RequireLowercase = true; - - // Lockout settings - options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); - options.Lockout.MaxFailedAccessAttempts = 10; - }); - - builder.Services.Configure(options => - { - options.ForwardedHeaders = - ForwardedHeaders.XForwardedFor - | ForwardedHeaders.XForwardedProto - | ForwardedHeaders.XForwardedHost; - // Trust nginx in Docker; headers are only present behind the proxy. - options.KnownNetworks.Clear(); - options.KnownProxies.Clear(); - }); - - builder.Services.AddMyOfficeOpenIddict(builder.Configuration, builder.Environment); - } - - private static void AddAutoMapper(WebApplicationBuilder builder) - { - // AutoMapper 15+ dual license: runs without a key (warning logs only). - // Set AutoMapper:LicenseKey (or AUTOMAPPER_LICENSE_KEY) from https://automapper.io — free Community tier if under $5M revenue. - var licenseKey = builder.Configuration["AutoMapper:LicenseKey"]; - - builder.Services.AddAutoMapper( - c => - { - if (!string.IsNullOrWhiteSpace(licenseKey)) - { - c.LicenseKey = licenseKey; - } - - c.AllowNullCollections = true; - c.AllowNullDestinationValues = true; - }, - typeof(AccountDto).Assembly, - typeof(AccountViewModel).Assembly - ); - } - - private static void AddRepositories(WebApplicationBuilder builder) - { - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - } - - private static void AddBusinessServices(WebApplicationBuilder builder) - { - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - } - - private static readonly ConcurrentDictionary _staticFilesCache = new(); - - private static void Configure(WebApplication app) - { - // nginx (prod) terminates TLS and forwards X-Forwarded-Proto/Host - app.UseForwardedHeaders(); - - // Configure the HTTP request pipeline. - if (app.Environment.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - IdentityModelEventSource.ShowPII = true; - } - else - { - app.UseExceptionHandler(); - app.UseStatusCodePages(); - } - - // Explicit routing so CORS runs before endpoint matching (preflight / OPTIONS). - app.UseRouting(); - ConfigureCors(app); - - app.UseDefaultFiles(); - app.UseStaticFiles(); - - var logger = app.Logger; - var globalSettings = app.Services.GetRequiredService(); - logger.LogInformation("FrontEnd host: {Host}", globalSettings.Host); - - // send index.html / static files for non-API routes - var coreRoutes = new[] - { - // API routes - new PathString("/api"), - // Identity server routes - new PathString("/.well-known"), - new PathString("/connect"), - new PathString("/silent-refresh.html") - }; - - var webRootPath = app.Configuration.GetValue(WebHostDefaults.ContentRootKey); - var wwwrootPath = Path.Combine(webRootPath!, "wwwroot"); - app.Use(async (context, next) => - { - var path = context.Request.Path; - - if (path.Value == null) - { - await next(); - return; - } - - if (coreRoutes.Any(x => path.StartsWithSegments(x, StringComparison.OrdinalIgnoreCase))) - { - await next(); - return; - } - - if (!_staticFilesCache.TryGetValue(path.Value, out var physicalFileInfo)) - { - var segments = path.Value.Split('/', '\\'); - var fileName = segments.LastOrDefault(); - var fileInfo = string.IsNullOrEmpty(fileName) - ? null - : new FileInfo(Path.Combine(wwwrootPath, fileName)); - - if (fileInfo is null || !fileInfo.Exists) - { - // SPA deep link fallback - var indexInfo = new FileInfo(Path.Combine(wwwrootPath, "index.html")); - if (!indexInfo.Exists) - { - context.Response.StatusCode = StatusCodes.Status404NotFound; - return; - } - - physicalFileInfo = new PhysicalFileInfo(indexInfo); - } - else - { - physicalFileInfo = new PhysicalFileInfo(fileInfo); - _staticFilesCache.TryAdd(path.Value, physicalFileInfo); - } - } - - await context.Response.SendFileAsync(physicalFileInfo); - }); - - app.UseAuthentication(); - app.UseAuthorization(); - - MapRoutes(app); - - app.MapControllers(); - } - - private static void ConfigureCors(WebApplication app) - { - var allowedOrigins = (app.Configuration.GetSection("Cors:AllowedOrigins").Get() ?? []) - .Where(x => !string.IsNullOrWhiteSpace(x)) - .Select(x => x.Trim().TrimEnd('/')) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - var frontEndHost = app.Configuration.GetValue("FrontEnd:Host")?.Trim().TrimEnd('/'); - if (!string.IsNullOrWhiteSpace(frontEndHost) - && !allowedOrigins.Contains(frontEndHost, StringComparer.OrdinalIgnoreCase)) - { - allowedOrigins.Add(frontEndHost); - } - - var isDocker = string.Equals( - app.Environment.EnvironmentName, - "Docker", - StringComparison.OrdinalIgnoreCase); - - app.Logger.LogInformation( - "CORS origins: {Origins}", - allowedOrigins.Count > 0 ? string.Join(", ", allowedOrigins) : "(none)"); - - app.UseCors(policy => - { - if (allowedOrigins.Count > 0) - { - policy.WithOrigins(allowedOrigins.ToArray()) - .AllowAnyHeader() - .AllowAnyMethod(); - } - else if (app.Environment.IsDevelopment() || isDocker) - { - // Demo / local: SPA and API are on different host ports. - policy.AllowAnyOrigin() - .AllowAnyHeader() - .AllowAnyMethod(); - } - }); - } -} \ No newline at end of file diff --git a/MyOffice.Web/Properties/launchSettings.json b/MyOffice.Web/Properties/launchSettings.json deleted file mode 100644 index 833dff2..0000000 --- a/MyOffice.Web/Properties/launchSettings.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "profiles": { - "MyOffice.Web": { - "commandName": "Project", - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:9100", - "dotnetRunMessages": true - }, - "MyOffice.SPA": { - "commandName": "Project" - }, - "IIS Express": { - "commandName": "IISExpress", - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS": { - "commandName": "IIS", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "watch": { - "commandName": "Executable", - "executablePath": "dotnet", - "workingDirectory": "$(ProjectDir)", - "hotReloadEnabled": true, - "hotReloadProfile": "aspnetcore", - "commandLineArgs": "watch run", - "launchBrowser": false, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - }, - "$schema": "https://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iis": { - "applicationUrl": "http://localhost:9300" - }, - "iisExpress": { - "applicationUrl": "http://localhost:9300", - "sslPort": 0 - }, - "watch": { - "applicationUrl": "http://localhost:9300" - } - } -} diff --git a/MyOffice.Web/appsettings.Docker.json b/MyOffice.Web/appsettings.Docker.json deleted file mode 100644 index 88a0d2c..0000000 --- a/MyOffice.Web/appsettings.Docker.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "DatabaseProvider": "npgsql", - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "Kestrel": { - "EndPoints": { - "Http": { - "Url": "http://*:8080" - } - } - }, - "FrontEnd": { - "Host": "http://localhost:32080" - }, - "Cors": { - "AllowedOrigins": [ - "http://localhost:32080", - "http://127.0.0.1:32080" - ] - }, - "OpenIddict": { - "SigningKeyPath": "", - "EncryptionKeyPath": "", - "UseEphemeralKeys": true, - "AllowHttp": true - } -} diff --git a/MyOffice.Web/appsettings.json b/MyOffice.Web/appsettings.json deleted file mode 100644 index df31feb..0000000 --- a/MyOffice.Web/appsettings.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "DatabaseProvider": "npgsql", - /*"DatabaseProvider": "sqlite",*/ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "Kestrel": { - "EndPoints": { - "Http": { - "Url": "http://*:9100" - } - /*, - "Https": { - "Url": "https://*:9101" - }*/ - } - }, - "AllowedHosts": "*", - "FrontEnd": { - "Host": "http://localhost:4300" - }, - "AutoMapper": { - "LicenseKey": "" - }, - "OpenIddict": { - "SigningKeyPath": "", - "EncryptionKeyPath": "" - }, - "Cors": { - "AllowedOrigins": [ - "http://localhost:4300" - ] - }, - "ExternalProviders": { - "Auth0": { - "ClientId": "", - "Domain": "", - "SecretKey": "" - }, - "Google": { - "ClientId": "" - } - } -} \ No newline at end of file diff --git a/MyOffice.Web/web.Release.config b/MyOffice.Web/web.Release.config deleted file mode 100644 index a7c2127..0000000 --- a/MyOffice.Web/web.Release.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MyOffice.Web/web.config b/MyOffice.Web/web.config deleted file mode 100644 index add3e64..0000000 --- a/MyOffice.Web/web.config +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MyOffice.Web/wwwroot/index.html b/MyOffice.Web/wwwroot/index.html deleted file mode 100644 index 80b20c7..0000000 --- a/MyOffice.Web/wwwroot/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - MyOffice - - - - - - -

DEVELOPER INDEX.HTML

- - \ No newline at end of file diff --git a/MyOffice.sln b/MyOffice.sln deleted file mode 100644 index a49c3e3..0000000 --- a/MyOffice.sln +++ /dev/null @@ -1,196 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.8.12009.203 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "MyOffice.SPA", "MyOffice.SPA\MyOffice.SPA.esproj", "{B02D9868-26CB-4E98-95D8-7286BF255F89}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Web", "MyOffice.Web\MyOffice.Web.csproj", "{BCF0590C-5F6A-49BA-A05B-F333865ABEDB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Core", "MyOffice.Core\MyOffice.Core.csproj", "{0347A25D-12D5-4FE0-92F3-102F9F35DCE9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Data.Models", "MyOffice.Data.Models\MyOffice.Data.Models.csproj", "{3D1626CF-1FC3-45D5-A479-65EB955CCFD9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Data.Repositories", "MyOffice.Data.Repositories\MyOffice.Data.Repositories.csproj", "{B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Services", "MyOffice.Services\MyOffice.Services.csproj", "{0442839B-7509-4E76-9EA9-66DAD9F74031}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EF", "EF", "{89463832-F443-478A-AF0D-F2BC209237C8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Migrations.Sqlite", "MyOffice.Migration.Sqlite\MyOffice.Migrations.Sqlite.csproj", "{4CAEC4BF-E3BA-4027-8628-F307075C1D9F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Migrations.Postgres", "MyOffice.Migration.Postgres\MyOffice.Migrations.Postgres.csproj", "{030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.DbContext", "MyOffice.DbContext\MyOffice.DbContext.csproj", "{1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Shared", "MyOffice.Shared\MyOffice.Shared.csproj", "{8D8D816F-837D-43CA-8F59-3C78DEB9D48A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{06517FE0-8E41-4124-A482-F21382A62687}" - ProjectSection(SolutionItems) = preProject - gulpfile.js = gulpfile.js - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PostgresPgAdmin", "PostgresPgAdmin", "{D22C304C-7187-46B9-A059-47F557FAE764}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docker", "Docker", "{C2361FAE-1865-44C2-94AA-1ED41EDAE973}" - ProjectSection(SolutionItems) = preProject - Docker\dc-postgres-pgadmin.yml = Docker\dc-postgres-pgadmin.yml - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyOffice.Tests", "MyOffice.Tests\MyOffice.Tests.csproj", "{3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|x64.ActiveCfg = Debug|x64 - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|x86.ActiveCfg = Debug|x86 - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|Any CPU.Build.0 = Release|Any CPU - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|Any CPU.Deploy.0 = Release|Any CPU - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|x64.ActiveCfg = Release|x64 - {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|x86.ActiveCfg = Release|x86 - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|x64.ActiveCfg = Debug|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|x64.Build.0 = Debug|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|x86.ActiveCfg = Debug|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|x86.Build.0 = Debug|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|Any CPU.Build.0 = Release|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|x64.ActiveCfg = Release|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|x64.Build.0 = Release|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|x86.ActiveCfg = Release|Any CPU - {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|x86.Build.0 = Release|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|x64.ActiveCfg = Debug|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|x64.Build.0 = Debug|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|x86.ActiveCfg = Debug|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|x86.Build.0 = Debug|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|Any CPU.Build.0 = Release|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|x64.ActiveCfg = Release|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|x64.Build.0 = Release|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|x86.ActiveCfg = Release|Any CPU - {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|x86.Build.0 = Release|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|x64.ActiveCfg = Debug|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|x64.Build.0 = Debug|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|x86.ActiveCfg = Debug|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|x86.Build.0 = Debug|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|Any CPU.Build.0 = Release|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|x64.ActiveCfg = Release|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|x64.Build.0 = Release|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|x86.ActiveCfg = Release|Any CPU - {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|x86.Build.0 = Release|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|x64.ActiveCfg = Debug|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|x64.Build.0 = Debug|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|x86.ActiveCfg = Debug|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|x86.Build.0 = Debug|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|Any CPU.Build.0 = Release|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|x64.ActiveCfg = Release|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|x64.Build.0 = Release|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|x86.ActiveCfg = Release|Any CPU - {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|x86.Build.0 = Release|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|x64.ActiveCfg = Debug|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|x64.Build.0 = Debug|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|x86.ActiveCfg = Debug|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|x86.Build.0 = Debug|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|Any CPU.Build.0 = Release|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|x64.ActiveCfg = Release|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|x64.Build.0 = Release|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|x86.ActiveCfg = Release|Any CPU - {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|x86.Build.0 = Release|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|x64.ActiveCfg = Debug|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|x64.Build.0 = Debug|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|x86.ActiveCfg = Debug|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|x86.Build.0 = Debug|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|Any CPU.Build.0 = Release|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|x64.ActiveCfg = Release|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|x64.Build.0 = Release|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|x86.ActiveCfg = Release|Any CPU - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|x86.Build.0 = Release|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|Any CPU.Build.0 = Debug|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|x64.ActiveCfg = Debug|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|x64.Build.0 = Debug|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|x86.ActiveCfg = Debug|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|x86.Build.0 = Debug|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|Any CPU.ActiveCfg = Release|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|Any CPU.Build.0 = Release|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|x64.ActiveCfg = Release|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|x64.Build.0 = Release|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|x86.ActiveCfg = Release|Any CPU - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|x86.Build.0 = Release|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|x64.ActiveCfg = Debug|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|x64.Build.0 = Debug|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|x86.ActiveCfg = Debug|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|x86.Build.0 = Debug|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|Any CPU.Build.0 = Release|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|x64.ActiveCfg = Release|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|x64.Build.0 = Release|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|x86.ActiveCfg = Release|Any CPU - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|x86.Build.0 = Release|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|x64.ActiveCfg = Debug|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|x64.Build.0 = Debug|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|x86.ActiveCfg = Debug|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|x86.Build.0 = Debug|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|Any CPU.Build.0 = Release|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|x64.ActiveCfg = Release|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|x64.Build.0 = Release|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|x86.ActiveCfg = Release|Any CPU - {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|x86.Build.0 = Release|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Debug|x64.ActiveCfg = Debug|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Debug|x64.Build.0 = Debug|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Debug|x86.ActiveCfg = Debug|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Debug|x86.Build.0 = Debug|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Release|Any CPU.Build.0 = Release|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Release|x64.ActiveCfg = Release|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Release|x64.Build.0 = Release|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Release|x86.ActiveCfg = Release|Any CPU - {3E7C3005-275C-4AD5-AAAA-0B9C4D1F0111}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {4CAEC4BF-E3BA-4027-8628-F307075C1D9F} = {89463832-F443-478A-AF0D-F2BC209237C8} - {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18} = {89463832-F443-478A-AF0D-F2BC209237C8} - {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF} = {89463832-F443-478A-AF0D-F2BC209237C8} - {D22C304C-7187-46B9-A059-47F557FAE764} = {06517FE0-8E41-4124-A482-F21382A62687} - {C2361FAE-1865-44C2-94AA-1ED41EDAE973} = {06517FE0-8E41-4124-A482-F21382A62687} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {6EAF5FD7-426A-4EA9-9A73-63854C47CDED} - EndGlobalSection -EndGlobal diff --git a/PUBLIC.md b/PUBLIC.md new file mode 100644 index 0000000..b3a38fa --- /dev/null +++ b/PUBLIC.md @@ -0,0 +1,8 @@ +# MyOffice public tree + +This repository is a **filtered** mirror for Proxmox CT install scripts and Docker demo files. +Application **source** stays in the private developer repository. +Runnable app binaries are published as **Gitea Releases** (`myoffice-publish.tar.gz`). + +See [proxmox/README.md](proxmox/README.md). + diff --git a/README.md b/README.md new file mode 100644 index 0000000..faf6a8b --- /dev/null +++ b/README.md @@ -0,0 +1,110 @@ +# MyOffice + +**Layers** +Frontend <-> Backend <-> Services <-> Repositories <-> Database + +*1. MyOffice.SPA* +Frontend layer +Angular + +*2. MyOffice.Web* +Backend layer +ASP Core + +*3. MyOffice.Data.Services* +Services layer + +*5. MyOffice.Data.Models* +Models + +*6. MyOffice.Data.Repositories* +Database layer + +*7. MyOffice.DbContext* +AppDbContext +EntityFramework Core + +*8. MyOffice.Migrations.Postgres* +Postgres Migrations + +*9. MyOffice.Migrations.Sqlite* +Sqlite Migrations + + +**DataBase** +1. SQLite +2. PostgreSql +3. MS SQL + +**Develompent** +1. Local IIS +2. Express IIS + +**Authentication & Authorization** + +1. OpenIddict (replaces IdentityServer4) +2. Custom UserStore + Identity V3 password hashes (legacy hashes rehashed on login) +3. SPA: email/password via ROPC (kept); Authorization Code + PKCE configured for interactive OIDC +4. Login with Google / Auth0 (`external` grant) +5. Details: [docs/AUTH.md](docs/AUTH.md), refactoring: [docs/REFACTORING_PLAN.md](docs/REFACTORING_PLAN.md) + +**Build & Deploy** +1. Build with .bat +2. Deploy to Linux + +**Get started** +1. Restore / build: `dotnet build MyOffice.Web/MyOffice.Web.csproj` +2. SPA: `cd MyOffice.SPA && npm install && npm start` (default http://localhost:4300) +3. Set startup project to `MyOffice.Web`, run (API default http://localhost:9100) +4. Ensure `FrontEnd:Host` matches the SPA origin (`appsettings.json`) +5. Tests: `dotnet test MyOffice.Tests/MyOffice.Tests.csproj` +6. Empty DB is auto-filled with demo users (rates at Jan 1, sample accounts/items/motions): + - `user_UAH@user_UAH.userUAH` / `user_UAH` + - `user_USD@user_USD.userUSD` / `user_USD` + - `user_EUR@user_EUR.userEUR` / `user_EUR` + +**add site to IIS** +1. add +Site name:myproject +Physical path:...\MyProject\MyProject.Web +Port:9100 +2. Select 'IIS', Run Backend (F5) + +**Settings** +1. launchSettings.json +2. appsettings +appsettings.json +appsettings.Development.json +appsettings.Production.json +3. Optional: `AutoMapper:LicenseKey` (or env `AUTOMAPPER_LICENSE_KEY`) — free Community key from https://automapper.io if under ~$5M revenue. Empty works; you only get license warning logs. + +**External providers** +1. Auth0 +appsettings ExternalProviders:Auth0 +2. Google +appsettings ExternalProviders:Google + +**PowerShell scripts** +1. use 'Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass' to allow run *.ps1 +2. params.txt +2.1. publish_folder=_Published (folder to publish) +2.2. linux_user=root (linux user) +2.3. linux_host=192.168.1.215 (linux host) +2.4. linux_folder=/var/www/MyProject (folder in linux) + +**Build** +1. .\build.ps1 +1.1. '.\build.ps1' - build Backend + Frontend +1.2. '.\build.ps1 dotnet' build Backend +1.3. '.\build.ps1 spa' build Frontend + +**Docker demo** (SPA + API + Postgres + pgAdmin) +1. `cd Docker` then `.\build.ps1` (defaults :32080 / :32081 / :32082) +2. After code changes: `.\build.ps1 rebuild` (or `.\build.ps1 reset` to wipe DB + re-seed) +3. Details: [Docker/README.md](Docker/README.md) + +**Proxmox** (Gitea public scripts + release artifact) +1. Maintainer: `.\proxmox\publish.ps1 -Tar` → `.\proxmox\release.ps1` → `.\proxmox\sync-public.ps1 -Push` (or Gitea Actions) +2. User on Proxmox: set `GITEA_URL` / `GITEA_OWNER` / `REPO_RAW_BASE`, run `myoffice.sh` (see [proxmox/README.md](proxmox/README.md)) +3. Proxy nginx to `http://:9100` +4. Lab SSH (no Gitea): `.\proxmox\deploy.ps1 -TargetHost ` diff --git a/proxmox/README.md b/proxmox/README.md new file mode 100644 index 0000000..77a5f60 --- /dev/null +++ b/proxmox/README.md @@ -0,0 +1,136 @@ +# MyOffice on Proxmox (Gitea releases) + +Three-tier setup on **your Gitea**: + +| Tier | Repo | Visibility | Contents | +|------|------|------------|----------| +| 1. Dev | `myoffice` | Private | Full source | +| 2. Public code | `myoffice-public` | Public | Allowlisted scripts (`proxmox/`, `Docker/`, README) | +| 3. Published app | Releases on `myoffice-public` | Public | `myoffice-publish.tar.gz` | + +CT install downloads the release tarball (not source). No Docker/nginx/SDK/Node inside the CT — proxy with your existing nginx LXC to Kestrel `:9100`. + +```text +[private myoffice] --sync-public--> [myoffice-public raw scripts] +[private myoffice] --publish+release--> [Gitea Release .tar.gz] + | +[User Proxmox] curl myoffice.sh ----------> [LXC: Postgres + ASP.NET + app] + ^ +[User nginx] proxy_pass http://ct-ip:9100 ----+ +``` + +## End user: create CT + +```bash +export GITEA_URL="https://gitea.example.com" +export GITEA_OWNER="org" +export GITEA_REPO="myoffice-public" # optional, default +export RELEASE_TAG="latest" # or v1.2.3 +export REPO_RAW_BASE="${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/main" + +bash -c "$(curl -fsSL ${REPO_RAW_BASE}/proxmox/myoffice.sh)" +``` + +Or copy `proxmox/` to the host and run `bash myoffice.sh` with the same env vars. + +Whiptail: Default / Advanced (Public URL, release tag) → creates CT → installs Postgres + ASP.NET runtime → downloads release → configures FrontEnd/CORS + local Postgres → systemd. + +## Maintainer: publish a release + +On the private repo (build PC): + +```powershell +$env:GITEA_TOKEN = '' + +.\proxmox\publish.ps1 -Tar +.\proxmox\release.ps1 -GiteaUrl https://gitea.example.com -Owner org -Repo myoffice-public -Tag v1.2.3 +.\proxmox\sync-public.ps1 -GiteaUrl https://gitea.example.com -Owner org -Repo myoffice-public -Push +``` + +- `proxmox/publish.ps1` → `_Published/` + `myoffice-publish.tar.gz` +- `proxmox/release.ps1` → Gitea Release asset +- `proxmox/sync-public.ps1` → push allowlisted files to public repo (scripts users curl) + +Or via Gitea Actions on the private repo (`.gitea/workflows/publish.yml`): push `master` → tag `latest`, or push tag `v*` / manual dispatch. + +Lab-only SSH deploy (no Gitea): `.\proxmox\deploy.ps1 -TargetHost ` + +## What runs inside the CT + +| Service | How | Port | +|---------|-----|------| +| PostgreSQL | apt + systemd | `127.0.0.1:5432` | +| MyOffice API + SPA | `dotnet` via `myoffice-api.service` | **9100** | + +```text +/opt/myoffice/api # extracted release (API + wwwroot) +/opt/myoffice/proxmox # install/update helpers + env +``` + +Config chain: + +- **Front → API:** same-origin SPA (`environment.proxmox.ts`) +- **API → Postgres:** CT `appsettings.shared.Production.json` +- **Browser → app:** nginx → `http://:9100` + +## Proxy (your nginx LXC) + +```nginx +location / { + proxy_pass http://:9100; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} +``` + +In Advanced install, set **Public URL** to the browser URL so CORS / `FrontEnd:Host` match. + +## Update later + +```bash +pct enter +/opt/myoffice/proxmox/update.sh # re-download RELEASE_TAG + restart +/opt/myoffice/proxmox/update.sh logs +/opt/myoffice/proxmox/update.sh status +``` + +Release settings are stored in `/opt/myoffice/proxmox/env`. + +## Gitea ops checklist + +- Create private `myoffice` and public `myoffice-public` +- Raise release attachment size limit if needed +- Token for maintainers: `write:repository` on public repo +- TLS (or trust custom CA) so Proxmox/`curl` can download +- Private repo secret `PUBLIC_TOKEN` for Actions (`.gitea/workflows/publish.yml`) + +## Gitea runner caching + +Three layers (independent): + +| Layer | What | How | +|-------|------|-----| +| Toolcache | .NET SDK / Node binaries | `setup-dotnet` / `setup-node` write to `/opt/hostedtoolcache`. Persist it on the **act_runner** host so the next job reuses downloads (steps still run, but skip re-download — you already saw `Found in cache @ /opt/hostedtoolcache/...`). | +| Actions cache | NuGet + npm packages | Workflow uses `actions/cache@v4` for `~/.nuget/packages` and `~/.npm`. Needs the runner cache server (default on act_runner). | +| Skip setup | No setup steps at all | Bake SDK + Node into the job Docker image (or host runner), then set job env `SKIP_SETUP_DOTNET=true` and `SKIP_SETUP_NODE=true`. | + +Example act_runner volume (compose): + +```yaml +volumes: + - /var/run/docker.sock:/var/run/docker.sock + - act-toolcache:/opt/hostedtoolcache # persist SDK/Node between jobs +``` + +If jobs use ephemeral containers without that volume, SDKs download every run. + +- Debian 12 LXC, unprivileged, `--onboot 1` +- 2 vCPU / 4096 MiB / 20G / `vmbr0` / DHCP +- Listen `:9100` + +## Demo logins + +- App: `user_UAH@user_UAH.userUAH` / `user_UAH` (also USD, EUR) +- Postgres: user/db/password `myoffice` diff --git a/proxmox/deploy.ps1 b/proxmox/deploy.ps1 new file mode 100644 index 0000000..f449299 --- /dev/null +++ b/proxmox/deploy.ps1 @@ -0,0 +1,138 @@ +# Deploy prebuilt MyOffice artifacts to a Proxmox CT (or any Linux host). +# Usage: +# .\proxmox\publish.ps1 +# .\proxmox\deploy.ps1 -TargetHost 192.168.1.120 +# .\proxmox\deploy.ps1 -TargetHost 192.168.1.120 -User root -RemotePath /opt/myoffice/api +# +# Requires OpenSSH client (ssh/scp). Prefers rsync if available (Git Bash / WSL / cwRsync). +# Preserves CT-owned appsettings.Production.json / appsettings.shared.Production.json. + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [Alias('ComputerName', 'Host')] + [string]$TargetHost, + + [string]$User = 'root', + + [Alias('Path')] + [string]$RemotePath = '/opt/myoffice/api', + + [string]$Service = 'myoffice-api', + + [string]$PublishDir = '', + + [int]$Port = 22 +) + +$ErrorActionPreference = 'Stop' + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$repoRoot = Resolve-Path (Join-Path $scriptDir '..') + +if (-not $PublishDir) { + $PublishDir = Join-Path $repoRoot '_Published' +} +if (-not (Test-Path $PublishDir)) { + throw "Publish folder not found: $PublishDir — run .\proxmox\publish.ps1 first." +} +if (-not (Test-Path (Join-Path $PublishDir 'MyOffice.Web.dll'))) { + throw "MyOffice.Web.dll missing in $PublishDir — run .\proxmox\publish.ps1 first." +} + +$ctOwnedSettings = @( + 'appsettings.Production.json', + 'appsettings.shared.Production.json' +) + +$remote = "${User}@${TargetHost}" +$sshTarget = @('-p', "$Port", $remote) +$scpTarget = @('-P', "$Port") + +function Invoke-Remote { + param([Parameter(Mandatory = $true)][string]$Command) + & ssh @sshTarget $Command + if ($LASTEXITCODE -ne 0) { + throw "ssh failed (exit $LASTEXITCODE): $Command" + } +} + +function Test-Rsync { + return [bool](Get-Command rsync -ErrorAction SilentlyContinue) +} + +function ConvertTo-RsyncPath([string]$WindowsPath) { + $p = ($WindowsPath.TrimEnd('\', '/') + '/') -replace '\\', '/' + if ($p -match '^[A-Za-z]:') { + $drive = $p.Substring(0, 1).ToLower() + $p = "/$drive" + $p.Substring(2) + } + return $p +} + +Write-Host "-----------------------------------------------" +Write-Host "Deploy $PublishDir -> ${remote}:${RemotePath}" +Write-Host "-----------------------------------------------" + +Write-Host "Stopping $Service..." +Invoke-Remote "systemctl stop $Service || true" + +Invoke-Remote "mkdir -p '$RemotePath'" + +$rsync = Test-Rsync +if ($rsync) { + Write-Host "Copying with rsync (preserve CT Production appsettings)..." + $rsyncSrc = ConvertTo-RsyncPath $PublishDir + $rsyncArgs = @( + '-r', '--info=progress2', + '--exclude', 'appsettings.Production.json', + '--exclude', 'appsettings.shared.Production.json', + '-e', "ssh -p $Port", + $rsyncSrc, + "${remote}:${RemotePath}/" + ) + & rsync @rsyncArgs + if ($LASTEXITCODE -ne 0) { + throw "rsync failed with exit code $LASTEXITCODE" + } +} +else { + Write-Host "rsync not found — using tar+scp fallback..." + $staging = Join-Path $env:TEMP ("myoffice-deploy-" + [guid]::NewGuid().ToString('N')) + New-Item -ItemType Directory -Path $staging | Out-Null + try { + Get-ChildItem -Path $PublishDir -Force | Where-Object { + $_.Name -notin $ctOwnedSettings + } | ForEach-Object { + Copy-Item $_.FullName -Destination $staging -Recurse -Force + } + + $tarLocal = Join-Path $env:TEMP 'myoffice-deploy.tar.gz' + if (Test-Path $tarLocal) { Remove-Item -Force $tarLocal } + Push-Location $staging + try { + tar -czf $tarLocal * + if ($LASTEXITCODE -ne 0) { throw "tar create failed" } + } + finally { + Pop-Location + } + + & scp @scpTarget $tarLocal "${remote}:/tmp/myoffice-deploy.tar.gz" + if ($LASTEXITCODE -ne 0) { throw "scp failed" } + + Invoke-Remote "tar -xzf /tmp/myoffice-deploy.tar.gz -C '$RemotePath' && rm -f /tmp/myoffice-deploy.tar.gz" + } + finally { + Remove-Item -Recurse -Force $staging -ErrorAction SilentlyContinue + Remove-Item -Force (Join-Path $env:TEMP 'myoffice-deploy.tar.gz') -ErrorAction SilentlyContinue + } +} + +Write-Host "Starting $Service..." +Invoke-Remote "systemctl start $Service" +Invoke-Remote "systemctl --no-pager --full status $Service || true" + +Write-Host "" +Write-Host "Deployed to http://${TargetHost}:9100 (or your nginx public URL)" +Write-Host "" diff --git a/proxmox/fetch-release.sh b/proxmox/fetch-release.sh new file mode 100644 index 0000000..9d6ce5f --- /dev/null +++ b/proxmox/fetch-release.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +# Download myoffice-publish.tar.gz from a Gitea release into API_DIR. +# Env: +# GITEA_URL, GITEA_OWNER, GITEA_REPO, RELEASE_TAG (latest|v1.2.3) +# API_DIR (default /opt/myoffice/api) +# RELEASE_ASSET_URL — optional direct override (skips API resolve) +# GITEA_TOKEN — optional for private release downloads + +set -euo pipefail + +API_DIR="${API_DIR:-/opt/myoffice/api}" +GITEA_URL="${GITEA_URL:-}" +GITEA_OWNER="${GITEA_OWNER:-}" +GITEA_REPO="${GITEA_REPO:-myoffice-public}" +RELEASE_TAG="${RELEASE_TAG:-latest}" +RELEASE_ASSET_URL="${RELEASE_ASSET_URL:-}" +ASSET_NAME="${ASSET_NAME:-myoffice-publish.tar.gz}" +GITEA_TOKEN="${GITEA_TOKEN:-}" + +msg() { echo -e " ==> $*"; } + +curl_auth() { + if [[ -n "$GITEA_TOKEN" ]]; then + curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" "$@" + else + curl -fsSL "$@" + fi +} + +json_first_string() { + # Extract first "key":"value" for key=$1 from JSON on stdin (no jq/python required). + local key="$1" + tr -d '\n' | sed -n "s/.*\"${key}\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -1 +} + +resolve_asset_url() { + if [[ -n "$RELEASE_ASSET_URL" ]]; then + echo "$RELEASE_ASSET_URL" + return 0 + fi + + if [[ -z "$GITEA_URL" || -z "$GITEA_OWNER" ]]; then + echo "Set GITEA_URL + GITEA_OWNER (and GITEA_REPO), or RELEASE_ASSET_URL." >&2 + exit 1 + fi + + local base api_json tag browser_url + base="${GITEA_URL%/}" + + if [[ "$RELEASE_TAG" == "latest" ]]; then + api_json=$(curl_auth "${base}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/latest") + tag=$(printf '%s' "$api_json" | json_first_string tag_name) + if [[ -z "$tag" ]]; then + echo "Could not resolve latest release tag from Gitea API." >&2 + exit 1 + fi + else + tag="$RELEASE_TAG" + api_json=$(curl_auth "${base}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/tags/${tag}" || true) + fi + + # Prefer browser_download_url that ends with the asset name + browser_url=$(printf '%s' "${api_json:-}" | tr '"' '\n' | grep -F "/${ASSET_NAME}" | grep -E '^https?://' | head -1 || true) + + if [[ -z "$browser_url" ]]; then + browser_url="${base}/${GITEA_OWNER}/${GITEA_REPO}/releases/download/${tag}/${ASSET_NAME}" + fi + + echo "$browser_url" +} + +download_and_extract() { + local url tar_path staging + url=$(resolve_asset_url) + msg "Downloading release asset: $url" + + mkdir -p "$API_DIR" + tar_path="/tmp/${ASSET_NAME}" + curl_auth -o "$tar_path" "$url" + + staging=$(mktemp -d /tmp/myoffice-extract.XXXXXX) + tar -xzf "$tar_path" -C "$staging" + rm -f "$tar_path" + + local prod="${API_DIR}/appsettings.Production.json" + local shared_prod="${API_DIR}/appsettings.shared.Production.json" + local prod_bak="" shared_bak="" + if [[ -f "$prod" ]]; then + prod_bak=$(mktemp) + cp -a "$prod" "$prod_bak" + fi + if [[ -f "$shared_prod" ]]; then + shared_bak=$(mktemp) + cp -a "$shared_prod" "$shared_bak" + fi + + local top_count top_dir + top_count=$(find "$staging" -mindepth 1 -maxdepth 1 | wc -l) + top_dir="" + if [[ "$top_count" -eq 1 ]]; then + local only + only=$(find "$staging" -mindepth 1 -maxdepth 1 | head -1) + if [[ -d "$only" ]]; then + top_dir="$only" + fi + fi + + find "$API_DIR" -mindepth 1 -maxdepth 1 \ + ! -name 'appsettings.Production.json' \ + ! -name 'appsettings.shared.Production.json' \ + -exec rm -rf {} + + + if [[ -n "$top_dir" ]]; then + cp -a "$top_dir"/. "$API_DIR"/ + else + cp -a "$staging"/. "$API_DIR"/ + fi + rm -rf "$staging" + + rm -f "$API_DIR/appsettings.Production.json" "$API_DIR/appsettings.shared.Production.json" 2>/dev/null || true + if [[ -n "$prod_bak" ]]; then + mv "$prod_bak" "$prod" + fi + if [[ -n "$shared_bak" ]]; then + mv "$shared_bak" "$shared_prod" + fi + + if [[ ! -f "${API_DIR}/MyOffice.Web.dll" ]]; then + echo "Extracted archive but MyOffice.Web.dll is missing in ${API_DIR}" >&2 + exit 1 + fi + msg "App extracted to ${API_DIR}" +} + +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + download_and_extract +fi diff --git a/proxmox/install-in-ct.sh b/proxmox/install-in-ct.sh new file mode 100644 index 0000000..47a352b --- /dev/null +++ b/proxmox/install-in-ct.sh @@ -0,0 +1,194 @@ +#!/usr/bin/env bash +# Runs inside the MyOffice LXC: PostgreSQL + ASP.NET Core runtime + app from Gitea Release. +# No Docker, no nginx, no git, no SDK, no Node. +# +# Env (from proxmox/myoffice.sh): +# APP_DIR, PUBLIC_URL, API_PORT, ASSETS_DIR +# GITEA_URL, GITEA_OWNER, GITEA_REPO, RELEASE_TAG, RELEASE_ASSET_URL, GITEA_TOKEN + +set -euo pipefail + +APP_DIR="${APP_DIR:-/opt/myoffice}" +API_DIR="${APP_DIR}/api" +ASSETS_DIR="${ASSETS_DIR:-/tmp/myoffice-proxmox}" +PUBLIC_URL="${PUBLIC_URL:-}" +API_PORT="${API_PORT:-9100}" +PG_DB="myoffice" +PG_USER="myoffice" +PG_PASS="myoffice" +SKIP_FETCH="${SKIP_FETCH:-0}" + +export DEBIAN_FRONTEND=noninteractive +export API_DIR + +msg() { echo -e " ==> $*"; } + +detect_public_url() { + if [[ -n "$PUBLIC_URL" ]]; then + PUBLIC_URL=$(echo "$PUBLIC_URL" | sed 's:/*$::') + return 0 + fi + local ip + ip=$(ip -4 -o addr show eth0 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -1 || true) + if [[ -z "$ip" ]]; then + ip=$(hostname -I 2>/dev/null | awk '{print $1}') + fi + if [[ -z "$ip" ]]; then + echo "Could not detect CT IP. Set PUBLIC_URL." >&2 + exit 1 + fi + PUBLIC_URL="http://${ip}:${API_PORT}" +} + +install_base() { + msg "Installing base packages" + apt-get update -y + apt-get install -y ca-certificates curl gnupg postgresql postgresql-contrib +} + +install_aspnet_runtime() { + if command -v dotnet >/dev/null 2>&1 && dotnet --list-runtimes 2>/dev/null | grep -q 'Microsoft.AspNetCore.App 10\.'; then + msg "ASP.NET Core 10 runtime already installed" + return 0 + fi + msg "Installing ASP.NET Core 10 runtime" + curl -fsSL https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -o /tmp/packages-microsoft-prod.deb + dpkg -i /tmp/packages-microsoft-prod.deb + apt-get update -y + apt-get install -y aspnetcore-runtime-10.0 +} + +setup_postgres() { + msg "Configuring PostgreSQL" + systemctl enable --now postgresql + if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='${PG_USER}'" | grep -q 1; then + sudo -u postgres psql -c "CREATE USER ${PG_USER} WITH PASSWORD '${PG_PASS}';" + else + sudo -u postgres psql -c "ALTER USER ${PG_USER} WITH PASSWORD '${PG_PASS}';" + fi + if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname='${PG_DB}'" | grep -q 1; then + sudo -u postgres psql -c "CREATE DATABASE ${PG_DB} OWNER ${PG_USER};" + fi + sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE ${PG_DB} TO ${PG_USER};" + sudo -u postgres psql -d "$PG_DB" -c "GRANT ALL ON SCHEMA public TO ${PG_USER};" || true + msg "PostgreSQL ready (db/user/pass=${PG_DB})" +} + +write_runtime_config() { + mkdir -p "$API_DIR" + if [[ ! -f "$API_DIR/appsettings.Production.json" ]]; then + cat >"$API_DIR/appsettings.Production.json" <"$API_DIR/appsettings.shared.Production.json" <&2 + exit 1 + fi + # shellcheck disable=SC1090 + source "$fetch_script" + download_and_extract +} + +install_systemd() { + msg "Configuring systemd unit myoffice-api" + local unit_src="${ASSETS_DIR}/myoffice-api.service" + if [[ ! -f "$unit_src" ]]; then + unit_src="${APP_DIR}/proxmox/myoffice-api.service" + fi + if [[ ! -f "$unit_src" ]]; then + echo "Missing myoffice-api.service" >&2 + exit 1 + fi + sed -e "s|__API_DIR__|${API_DIR}|g" -e "s|__API_PORT__|${API_PORT}|g" \ + "$unit_src" >/etc/systemd/system/myoffice-api.service + + mkdir -p "${APP_DIR}/proxmox" + if [[ -d "$ASSETS_DIR" ]]; then + cp -a "${ASSETS_DIR}/." "${APP_DIR}/proxmox/" + fi + chmod +x "${APP_DIR}/proxmox/"*.sh 2>/dev/null || true + + cat >"${APP_DIR}/proxmox/env" </dev/null || true + msg "App DLL missing — service not started" + fi +} + +print_done() { + echo + echo " MyOffice CT is ready:" + echo " Public URL ${PUBLIC_URL}" + echo " Listen 0.0.0.0:${API_PORT} (proxy this from your nginx LXC)" + echo " Postgres 127.0.0.1:5432 db/user/pass=${PG_DB}" + echo " App dir ${API_DIR}" + echo + echo " Update later: ${APP_DIR}/proxmox/update.sh" + echo " Demo login: user_UAH@user_UAH.userUAH / user_UAH" + echo +} + +detect_public_url +install_base +install_aspnet_runtime +setup_postgres +write_runtime_config +fetch_app +install_systemd +print_done diff --git a/proxmox/myoffice-api.service b/proxmox/myoffice-api.service new file mode 100644 index 0000000..047b732 --- /dev/null +++ b/proxmox/myoffice-api.service @@ -0,0 +1,19 @@ +[Unit] +Description=MyOffice ASP.NET Core (API + SPA) +After=network.target postgresql.service +Wants=postgresql.service + +[Service] +WorkingDirectory=__API_DIR__ +ExecStart=/usr/bin/dotnet __API_DIR__/MyOffice.Web.dll +Restart=always +RestartSec=5 +KillSignal=SIGINT +SyslogIdentifier=myoffice-api +User=root +Environment=ASPNETCORE_ENVIRONMENT=Production +Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false +Environment=ASPNETCORE_URLS=http://*:__API_PORT__ + +[Install] +WantedBy=multi-user.target diff --git a/proxmox/myoffice.sh b/proxmox/myoffice.sh new file mode 100644 index 0000000..1ad48e6 --- /dev/null +++ b/proxmox/myoffice.sh @@ -0,0 +1,490 @@ +#!/usr/bin/env bash +# MyOffice Proxmox LXC installer (community-scripts style). +# Run on the Proxmox host (public Gitea repo raw URL): +# export GITEA_URL="https://gitea.example.com" +# export GITEA_OWNER="org" +# export GITEA_REPO="myoffice-public" +# export REPO_RAW_BASE="${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/main" +# bash -c "$(curl -fsSL ${REPO_RAW_BASE}/proxmox/myoffice.sh)" +# +# Creates one LXC with PostgreSQL + ASP.NET runtime + app from Gitea Release. +# No Docker, no nginx, no git/SDK/Node in the CT (use your existing proxy LXC in front). + +set -euo pipefail + +GITEA_URL="${GITEA_URL:-}" +GITEA_OWNER="${GITEA_OWNER:-}" +GITEA_REPO="${GITEA_REPO:-myoffice-public}" +RELEASE_TAG="${RELEASE_TAG:-latest}" +RELEASE_ASSET_URL="${RELEASE_ASSET_URL:-}" +GITEA_TOKEN="${GITEA_TOKEN:-}" + +if [[ -z "${REPO_RAW_BASE:-}" ]]; then + if [[ -n "$GITEA_URL" && -n "$GITEA_OWNER" ]]; then + REPO_RAW_BASE="${GITEA_URL%/}/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/main" + else + REPO_RAW_BASE="https://gitea.example.com/OWNER/myoffice-public/raw/branch/main" + fi +fi + +# Derive GITEA_* from REPO_RAW_BASE when only raw base is set: +# https://host/owner/repo/raw/branch/main +if [[ -z "$GITEA_URL" || -z "$GITEA_OWNER" ]]; then + if [[ "$REPO_RAW_BASE" =~ ^(https?://[^/]+)/([^/]+)/([^/]+)/raw/ ]]; then + [[ -z "$GITEA_URL" ]] && GITEA_URL="${BASH_REMATCH[1]}" + [[ -z "$GITEA_OWNER" ]] && GITEA_OWNER="${BASH_REMATCH[2]}" + [[ "$GITEA_REPO" == "myoffice-public" ]] && GITEA_REPO="${BASH_REMATCH[3]}" + fi +fi + +APP="MyOffice" +APP_DIR="/opt/myoffice" + +YW=$'\033[33m' +BL=$'\033[36m' +RD=$'\033[01;31m' +BGN=$'\033[4;92m' +GN=$'\033[1;92m' +DGN=$'\033[32m' +CL=$'\033[m' +BOLD=$'\033[1m' +BFR=$'\r\033[K' +TAB=$' ' + +CM="${TAB}✔️${TAB}${CL}" +CROSS="${TAB}✖️${TAB}${CL}" +INFO="${TAB}💡${TAB}${CL}" +OS="${TAB}🖥️${TAB}${CL}" +CONTAINERTYPE="${TAB}📦${TAB}${CL}" +DISKSIZE="${TAB}💾${TAB}${CL}" +CPUCORE="${TAB}🧠${TAB}${CL}" +RAMSIZE="${TAB}🛠️${TAB}${CL}" +CONTAINERID="${TAB}🆔${TAB}${CL}" +HOSTNAME="${TAB}🏠${TAB}${CL}" +BRIDGE="${TAB}🌉${TAB}${CL}" +GATEWAY="${TAB}🌐${TAB}${CL}" +DEFAULT="${TAB}⚙️${TAB}${CL}" +CREATING="${TAB}🚀${TAB}${CL}" +ADVANCED="${TAB}🧩${TAB}${CL}" + +header_info() { + clear + cat <<"EOF" + __ ___ ____ ____________ + / |/ /_ __/ __ \/ __/ __/ _/______ + / /|_/ / / / / / / / /_/ /_ / // ___/ _ \ + / / / / /_/ / /_/ / __/ __// // /__/ __/ +/_/ /_/\__, /\____/_/ /_/ /___/\___/\___/ + /____/ Proxmox LXC (Gitea release) +EOF +} + +msg_info() { echo -ne "${TAB}${YW}${1}${CL}"; } +msg_ok() { echo -e "${BFR}${CM}${GN}${1}${CL}"; } +msg_error() { echo -e "${BFR}${CROSS}${RD}${1}${CL}"; } + +error_handler() { + local exit_code=$? + local line_number=$1 + local command=$2 + echo -e "\n${RD}[ERROR]${CL} line ${RD}${line_number}${CL}: exit ${RD}${exit_code}${CL}: ${YW}${command}${CL}\n" + if [[ -n "${CTID:-}" ]] && pct status "$CTID" &>/dev/null; then + echo -e "${INFO}CT ${CTID} exists; destroy with: pct stop ${CTID}; pct destroy ${CTID}" + fi + exit "$exit_code" +} +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +exit_script() { + clear + echo -e "\n${CROSS}${RD}User exited script${CL}\n" + exit 0 +} + +check_root() { + if [[ "$(id -u)" -ne 0 ]]; then + msg_error "Please run this script as root on the Proxmox host." + exit 1 + fi +} + +pve_check() { + if ! command -v pveversion >/dev/null 2>&1; then + msg_error "This script must run on a Proxmox VE host (pveversion not found)." + exit 1 + fi + if ! command -v whiptail >/dev/null 2>&1; then + msg_error "whiptail is required (apt install whiptail)." + exit 1 + fi +} + +arch_check() { + if [[ "$(dpkg --print-architecture)" != "amd64" ]]; then + msg_error "Only amd64 is supported." + exit 1 + fi +} + +get_valid_nextid() { + local try_id + try_id=$(pvesh get /cluster/nextid) + while true; do + if [[ -f "/etc/pve/qemu-server/${try_id}.conf" ]] || [[ -f "/etc/pve/lxc/${try_id}.conf" ]]; then + try_id=$((try_id + 1)) + continue + fi + break + done + echo "$try_id" +} + +select_storage() { + local STORAGE_MENU=() + local MSG_MAX_LENGTH=0 + local line TAG TYPE FREE ITEM OFFSET VALID + while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + TYPE=$(echo "$line" | awk '{printf "%-10s", $2}') + FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f 2>/dev/null | awk '{printf("%9sB", $6)}' || echo "?") + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + OFFSET)) -gt ${MSG_MAX_LENGTH:-0} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") + done < <(pvesm status -content rootdir | awk 'NR>1') + + VALID=$(pvesm status -content rootdir | awk 'NR>1') + if [[ -z "$VALID" ]]; then + msg_error "Unable to detect a valid storage location (rootdir)." + exit 1 + elif [[ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]]; then + STORAGE=${STORAGE_MENU[0]} + else + while [[ -z "${STORAGE:+x}" ]]; do + STORAGE=$(whiptail --backtitle "MyOffice Proxmox" --title "Storage Pools" --radiolist \ + "Which storage pool for ${HN}?\n(Spacebar to select)\n" \ + 16 $((MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit_script + done + fi + msg_ok "Using ${CL}${BL}${STORAGE}${CL}${GN} for storage." +} + +default_settings() { + CTID=$(get_valid_nextid) + HN="myoffice" + CORE_COUNT="2" + RAM_SIZE="4096" + DISK_SIZE="20" + BRG="vmbr0" + NET="dhcp" + GATEWAY_IP="" + API_PORT="9100" + PUBLIC_URL="" # filled after CT IP known + START_CT="yes" + METHOD="default" + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CTID}${CL}" + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}" + echo -e "${OS}${BOLD}${DGN}OS: ${BGN}Debian 12${CL}" + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM: ${BGN}${RAM_SIZE} MiB${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk: ${BGN}${DISK_SIZE}G${CL}" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}" + echo -e "${GATEWAY}${BOLD}${DGN}IP: ${BGN}DHCP${CL}" + echo -e "${DEFAULT}${BOLD}${DGN}API listen: ${BGN}:${API_PORT}${CL} (SPA from release wwwroot)" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Stack: ${BGN}PostgreSQL + ASP.NET + Gitea release${CL}" + echo -e "${CREATING}${BOLD}${DGN}Creating MyOffice LXC with default settings${CL}" +} + +advanced_settings() { + METHOD="advanced" + [[ -z "${CTID:-}" ]] && CTID=$(get_valid_nextid) + + while true; do + if CTID=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Set Container ID" 8 58 "$CTID" --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + [[ -z "$CTID" ]] && CTID=$(get_valid_nextid) + if pct status "$CTID" &>/dev/null || qm status "$CTID" &>/dev/null; then + echo -e "${CROSS}${RD}ID $CTID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CTID}${CL}" + break + else + exit_script + fi + done + + if HN_IN=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Set Hostname" 8 58 myoffice --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + HN=$(echo "${HN_IN:-myoffice}" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9-' '-' | sed 's/^-//;s/-$//' || true) + [[ -z "$HN" ]] && HN="myoffice" + echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}" + else + exit_script + fi + + while true; do + if CORE_COUNT=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + [[ -z "$CORE_COUNT" ]] && CORE_COUNT="2" + if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" + break + fi + whiptail --backtitle "MyOffice Proxmox" --title "INVALID" --msgbox "CPU cores must be a positive integer." 8 58 + else + exit_script + fi + done + + while true; do + if RAM_SIZE=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + [[ -z "$RAM_SIZE" ]] && RAM_SIZE="4096" + if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${RAMSIZE}${BOLD}${DGN}RAM: ${BGN}${RAM_SIZE} MiB${CL}" + break + fi + whiptail --backtitle "MyOffice Proxmox" --title "INVALID" --msgbox "RAM must be a positive integer (MiB)." 8 58 + else + exit_script + fi + done + + while true; do + if DISK_SIZE=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Disk size in GiB" 8 58 20 --title "DISK" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + DISK_SIZE=$(echo "${DISK_SIZE:-20}" | tr -d ' Gg') + if [[ "$DISK_SIZE" =~ ^[1-9][0-9]*$ ]]; then + echo -e "${DISKSIZE}${BOLD}${DGN}Disk: ${BGN}${DISK_SIZE}G${CL}" + break + fi + whiptail --backtitle "MyOffice Proxmox" --title "INVALID" --msgbox "Disk must be a positive integer (GiB)." 8 58 + else + exit_script + fi + done + + if BRG=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + [[ -z "$BRG" ]] && BRG="vmbr0" + echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}" + else + exit_script + fi + + if whiptail --backtitle "MyOffice Proxmox" --title "NETWORK" --yesno "Use DHCP?" --yes-button DHCP --no-button Static 10 58; then + NET="dhcp" + GATEWAY_IP="" + echo -e "${GATEWAY}${BOLD}${DGN}IP: ${BGN}DHCP${CL}" + else + if NET=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Static IP CIDR (e.g. 192.168.1.120/24)" 8 58 --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + : + else + exit_script + fi + if GATEWAY_IP=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Gateway (e.g. 192.168.1.1)" 8 58 --title "GATEWAY" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + : + else + exit_script + fi + echo -e "${GATEWAY}${BOLD}${DGN}IP: ${BGN}${NET} gw ${GATEWAY_IP}${CL}" + fi + + if API_PORT=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Kestrel listen port" 8 58 9100 --title "API PORT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + [[ -z "$API_PORT" ]] && API_PORT="9100" + else + exit_script + fi + echo -e "${DEFAULT}${BOLD}${DGN}API listen: ${BGN}:${API_PORT}${CL}" + + if PUBLIC_URL=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Browser public URL (empty = http://CT_IP:PORT). Use your nginx proxy URL if any." 10 70 "" --title "PUBLIC URL" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + PUBLIC_URL=$(echo "$PUBLIC_URL" | sed 's:/*$::') + else + exit_script + fi + + if RELEASE_TAG=$(whiptail --backtitle "MyOffice Proxmox" --inputbox "Gitea release tag (latest or v1.2.3)" 8 58 "${RELEASE_TAG}" --title "RELEASE TAG" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + [[ -z "$RELEASE_TAG" ]] && RELEASE_TAG="latest" + else + exit_script + fi + echo -e "${DEFAULT}${BOLD}${DGN}Release: ${BGN}${RELEASE_TAG}${CL}" + + if whiptail --backtitle "MyOffice Proxmox" --title "START CONTAINER" --yesno "Start CT when created?" 10 58; then + START_CT="yes" + else + START_CT="no" + fi + + if whiptail --backtitle "MyOffice Proxmox" --title "ADVANCED SETTINGS" --yesno "Ready to create MyOffice LXC?" --no-button Do-Over 10 58; then + echo -e "${CREATING}${BOLD}${DGN}Creating MyOffice LXC with advanced settings${CL}" + else + header_info + echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +start_script() { + if whiptail --backtitle "MyOffice Proxmox" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58; then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +ensure_template() { + local template="debian-12-standard" + local store="local" + msg_info "Ensuring Debian 12 LXC template..." + if ! pveam list "$store" 2>/dev/null | grep -q "$template"; then + pveam update >/dev/null + local remote + remote=$(pveam available -section system | awk '/debian-12-standard/ {print $2; exit}') + if [[ -z "$remote" ]]; then + msg_error "Could not find debian-12-standard template in pveam available." + exit 1 + fi + pveam download "$store" "$remote" + fi + TEMPLATE_REF=$(pveam list "$store" | awk '/debian-12-standard/ {print $1; exit}') + if [[ -z "${TEMPLATE_REF:-}" ]]; then + msg_error "Debian 12 template not found after download." + exit 1 + fi + msg_ok "Template ${CL}${BL}${TEMPLATE_REF}${CL}" +} + +create_container() { + local net_cfg + if [[ "$NET" == "dhcp" ]]; then + net_cfg="name=eth0,bridge=${BRG},ip=dhcp" + else + net_cfg="name=eth0,bridge=${BRG},ip=${NET},gw=${GATEWAY_IP}" + fi + + msg_info "Creating LXC ${CTID} (${HN})..." + pct create "$CTID" "$TEMPLATE_REF" \ + --hostname "$HN" \ + --cores "$CORE_COUNT" \ + --memory "$RAM_SIZE" \ + --swap 512 \ + --rootfs "${STORAGE}:${DISK_SIZE}" \ + --net0 "$net_cfg" \ + --unprivileged 1 \ + --ostype debian \ + --onboot 1 \ + --timezone host \ + --tags "myoffice" \ + --description "MyOffice: PostgreSQL + ASP.NET Core from Gitea release. Proxy via external nginx LXC." + msg_ok "Created CT ${CL}${BL}${CTID}${CL}" + + if [[ "$START_CT" == "yes" ]]; then + msg_info "Starting CT ${CTID}..." + pct start "$CTID" + msg_ok "Started CT ${CTID}" + else + msg_error "CT created but not started (Start=no). Start with: pct start ${CTID}" + exit 0 + fi +} + +wait_for_network() { + msg_info "Waiting for CT network..." + local i ip + for i in $(seq 1 60); do + ip=$(pct exec "$CTID" -- bash -c "ip -4 -o addr show eth0 2>/dev/null | awk '{print \$4}' | cut -d/ -f1 | head -1" 2>/dev/null || true) + if [[ -n "$ip" ]]; then + CT_IP="$ip" + msg_ok "CT IP ${CL}${BL}${CT_IP}${CL}" + return 0 + fi + sleep 2 + done + msg_error "Timed out waiting for CT IP." + exit 1 +} + +resolve_script_dir() { + if [[ -n "${BASH_SOURCE[0]:-}" && -f "${BASH_SOURCE[0]}" ]]; then + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + else + SCRIPT_DIR="" + fi +} + +push_install_assets() { + local dest_dir="/tmp/myoffice-proxmox" + pct exec "$CTID" -- mkdir -p "$dest_dir" + + if [[ -n "${SCRIPT_DIR}" && -f "${SCRIPT_DIR}/install-in-ct.sh" ]]; then + for f in install-in-ct.sh fetch-release.sh myoffice-api.service update.sh; do + pct push "$CTID" "${SCRIPT_DIR}/${f}" "${dest_dir}/${f}" + done + else + msg_info "Downloading install assets from REPO_RAW_BASE..." + for f in install-in-ct.sh fetch-release.sh myoffice-api.service update.sh; do + curl -fsSL "${REPO_RAW_BASE}/proxmox/${f}" -o "/tmp/${f}" + pct push "$CTID" "/tmp/${f}" "${dest_dir}/${f}" + done + msg_ok "Downloaded install assets" + fi + pct exec "$CTID" -- chmod +x "${dest_dir}/install-in-ct.sh" "${dest_dir}/fetch-release.sh" "${dest_dir}/update.sh" +} + +run_ct_install() { + if [[ -z "${PUBLIC_URL}" ]]; then + PUBLIC_URL="http://${CT_IP}:${API_PORT}" + fi + if [[ -z "${GITEA_URL}" || -z "${GITEA_OWNER}" ]] && [[ -z "${RELEASE_ASSET_URL}" ]]; then + msg_error "Set GITEA_URL + GITEA_OWNER (and GITEA_REPO), or RELEASE_ASSET_URL, before install." + exit 1 + fi + msg_info "Installing PostgreSQL + ASP.NET runtime + Gitea release..." + pct exec "$CTID" -- env \ + REPO_RAW_BASE="$REPO_RAW_BASE" \ + APP_DIR="$APP_DIR" \ + PUBLIC_URL="$PUBLIC_URL" \ + API_PORT="$API_PORT" \ + ASSETS_DIR="/tmp/myoffice-proxmox" \ + GITEA_URL="$GITEA_URL" \ + GITEA_OWNER="$GITEA_OWNER" \ + GITEA_REPO="$GITEA_REPO" \ + RELEASE_TAG="$RELEASE_TAG" \ + RELEASE_ASSET_URL="$RELEASE_ASSET_URL" \ + GITEA_TOKEN="$GITEA_TOKEN" \ + bash /tmp/myoffice-proxmox/install-in-ct.sh + msg_ok "Stack installed" +} + +# --- main --- +header_info +echo -e "\n Loading..." +check_root +arch_check +pve_check + +if ! whiptail --backtitle "MyOffice Proxmox" --title "MyOffice LXC" --yesno \ + "This will create a new LXC with:\n\n • PostgreSQL\n • ASP.NET Core runtime\n • App from Gitea Release\n\nNo Docker, no nginx (point your proxy LXC at :9100).\n\nProceed?" 16 58; then + exit_script +fi + +start_script +select_storage +ensure_template +resolve_script_dir +create_container +wait_for_network +push_install_assets +run_ct_install + +echo -e "\n${GN}${BOLD}Completed successfully!${CL}\n" +echo -e "${INFO}${YW}Stack in CT ${CTID}:${CL} PostgreSQL + ASP.NET + release ${RELEASE_TAG}" +echo -e "${GATEWAY}${BGN}Public URL ${PUBLIC_URL}${CL}" +echo -e "${GATEWAY}${BGN}Upstream http://${CT_IP}:${API_PORT}${CL} (for your nginx proxy)" +echo -e "${INFO}Demo login: user_UAH@user_UAH.userUAH / user_UAH" +echo -e "${INFO}Update: pct enter ${CTID} then ${APP_DIR}/proxmox/update.sh" +echo diff --git a/proxmox/publish.ps1 b/proxmox/publish.ps1 new file mode 100644 index 0000000..ee4d98a --- /dev/null +++ b/proxmox/publish.ps1 @@ -0,0 +1,166 @@ +# Publish MyOffice API + SPA for Proxmox (artifacts only, no source). +# Usage (from repo root): +# .\proxmox\publish.ps1 +# .\proxmox\publish.ps1 -OutDir D:\builds\myoffice +# .\proxmox\publish.ps1 -Tar # also write myoffice-publish.tar.gz next to OutDir +# +# Before build: +# 1) copy appsettings.shared.json → Development + Production overlays (only if missing) +# 2) restore NuGet + npm +# +# Output: / with MyOffice.Web.dll + wwwroot/ (SPA, same-origin URLs) + +[CmdletBinding()] +param( + [string]$OutDir = '', + [switch]$Tar +) + +$ErrorActionPreference = 'Stop' + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$repoRoot = Resolve-Path (Join-Path $scriptDir '..') +Set-Location $repoRoot + +if (-not $OutDir) { + $OutDir = Join-Path $repoRoot '_Published' +} +$OutDir = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutDir) + +$sharedDir = Join-Path $repoRoot 'MyOffice.Shared' +$sharedBase = Join-Path $sharedDir 'appsettings.shared.json' +if (-not (Test-Path $sharedBase)) { + throw "Missing $sharedBase" +} + +Write-Host "-----------------------------------------------" +Write-Host "Copy appsettings.shared.json -> Development + Production (if missing)" +Write-Host "-----------------------------------------------" +foreach ($name in @('appsettings.shared.Development.json', 'appsettings.shared.Production.json')) { + $dest = Join-Path $sharedDir $name + if (Test-Path $dest) { + Write-Host "Skip (exists): $name" + } + else { + Copy-Item $sharedBase $dest + Write-Host "Created: $name" + } +} + +Write-Host "-----------------------------------------------" +Write-Host "Restore NuGet packages" +Write-Host "-----------------------------------------------" +dotnet restore 'MyOffice.Web\MyOffice.Web.csproj' --nologo +if ($LASTEXITCODE -ne 0) { + throw "dotnet restore failed with exit code $LASTEXITCODE" +} + +$spaDir = Join-Path $repoRoot 'MyOffice.SPA' +$envSample = Join-Path $spaDir 'src\environments\environment.sample.ts' +$envLocal = Join-Path $spaDir 'src\environments\environment.ts' +if (-not (Test-Path $envLocal) -and (Test-Path $envSample)) { + Copy-Item $envSample $envLocal +} + +Write-Host "-----------------------------------------------" +Write-Host "Restore npm packages (MyOffice.SPA)" +Write-Host "-----------------------------------------------" +Push-Location $spaDir +try { + if (Test-Path (Join-Path $spaDir 'package-lock.json')) { + npm ci + } + else { + npm install + } + if ($LASTEXITCODE -ne 0) { + throw "npm restore failed with exit code $LASTEXITCODE" + } +} +finally { + Pop-Location +} + +Write-Host "-----------------------------------------------" +Write-Host "dotnet publish -> $OutDir" +Write-Host "-----------------------------------------------" + +if (Test-Path $OutDir) { + Remove-Item -Recurse -Force $OutDir +} +New-Item -ItemType Directory -Path $OutDir | Out-Null + +dotnet publish 'MyOffice.Web\MyOffice.Web.csproj' -c Release -o $OutDir --no-restore --nologo +if ($LASTEXITCODE -ne 0) { + throw "dotnet publish failed with exit code $LASTEXITCODE" +} + +# CT owns Production overlays — do not ship local env-specific appsettings. +# Keep appsettings.json + appsettings.shared.json (required at runtime). +Get-ChildItem -Path $OutDir -Filter 'appsettings*.json' -File -ErrorAction SilentlyContinue | + Where-Object { + $_.Name -notin @('appsettings.json', 'appsettings.shared.json') + } | + Remove-Item -Force + +Write-Host "-----------------------------------------------" +Write-Host "ng build (proxmox) -> $OutDir\wwwroot" +Write-Host "-----------------------------------------------" + +Push-Location $spaDir +try { + $spaOut = Join-Path $env:TEMP ("myoffice-spa-" + [guid]::NewGuid().ToString('N')) + + npx ng build --configuration proxmox --output-path $spaOut + if ($LASTEXITCODE -ne 0) { + throw "ng build failed with exit code $LASTEXITCODE" + } + + $wwwroot = Join-Path $OutDir 'wwwroot' + if (Test-Path $wwwroot) { + Remove-Item -Recurse -Force $wwwroot + } + New-Item -ItemType Directory -Path $wwwroot | Out-Null + + $browser = Join-Path $spaOut 'browser' + if (Test-Path $browser) { + Copy-Item -Path (Join-Path $browser '*') -Destination $wwwroot -Recurse -Force + } + else { + Copy-Item -Path (Join-Path $spaOut '*') -Destination $wwwroot -Recurse -Force + } + Remove-Item -Recurse -Force $spaOut -ErrorAction SilentlyContinue +} +finally { + Pop-Location +} + +if ($Tar) { + $tarPath = Join-Path (Split-Path -Parent $OutDir) 'myoffice-publish.tar.gz' + if (Test-Path $tarPath) { + Remove-Item -Force $tarPath + } + Write-Host "-----------------------------------------------" + Write-Host "tar -> $tarPath" + Write-Host "-----------------------------------------------" + # Windows 10+ tar; paths relative to OutDir parent + Push-Location (Split-Path -Parent $OutDir) + try { + $leaf = Split-Path -Leaf $OutDir + tar -czf $tarPath $leaf + if ($LASTEXITCODE -ne 0) { + throw "tar failed with exit code $LASTEXITCODE" + } + } + finally { + Pop-Location + } + Write-Host "Archive: $tarPath" +} + +Write-Host "" +Write-Host "Published to $OutDir" +Write-Host "Next (Gitea): .\proxmox\publish.ps1 -Tar ; .\proxmox\release.ps1 -GiteaUrl ... -Owner ... -Tag v1.2.3" +Write-Host "Linux/CI: ./proxmox/publish.sh --tar ; ./proxmox/release.sh ..." +Write-Host "Lab SSH: .\proxmox\deploy.ps1 -TargetHost " +Write-Host "" diff --git a/proxmox/publish.sh b/proxmox/publish.sh new file mode 100755 index 0000000..48fd84c --- /dev/null +++ b/proxmox/publish.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# Publish MyOffice API + SPA for Proxmox (artifacts only, no source). +# Usage (from repo root): +# ./proxmox/publish.sh +# ./proxmox/publish.sh --out-dir /tmp/myoffice-out +# ./proxmox/publish.sh --tar +# +# Output: / with MyOffice.Web.dll + wwwroot/ (SPA, same-origin URLs) + +set -euo pipefail + +script_dir="$(cd "$(dirname "$0")" && pwd)" +repo_root="$(cd "$script_dir/.." && pwd)" +cd "$repo_root" + +out_dir="${OUT_DIR:-_Published}" +do_tar=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --tar | -Tar) + do_tar=true + shift + ;; + --out-dir) + out_dir="$2" + shift 2 + ;; + -h | --help) + echo "Usage: $0 [--tar] [--out-dir DIR]" + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + exit 1 + ;; + esac +done + +# Resolve relative out_dir against repo root +if [[ "$out_dir" != /* ]]; then + out_dir="$repo_root/$out_dir" +fi + +shared_dir="$repo_root/MyOffice.Shared" +shared_base="$shared_dir/appsettings.shared.json" +if [[ ! -f "$shared_base" ]]; then + echo "Missing $shared_base" >&2 + exit 1 +fi + +echo "-----------------------------------------------" +echo "Copy appsettings.shared.json -> Development + Production (if missing)" +echo "-----------------------------------------------" +for name in appsettings.shared.Development.json appsettings.shared.Production.json; do + dest="$shared_dir/$name" + if [[ -f "$dest" ]]; then + echo "Skip (exists): $name" + else + cp "$shared_base" "$dest" + echo "Created: $name" + fi +done + +echo "-----------------------------------------------" +echo "Restore NuGet packages" +echo "-----------------------------------------------" +dotnet restore MyOffice.Web/MyOffice.Web.csproj --nologo + +spa_dir="$repo_root/MyOffice.SPA" +env_sample="$spa_dir/src/environments/environment.sample.ts" +env_local="$spa_dir/src/environments/environment.ts" +if [[ ! -f "$env_local" && -f "$env_sample" ]]; then + cp "$env_sample" "$env_local" +fi + +echo "-----------------------------------------------" +echo "Restore npm packages (MyOffice.SPA)" +echo "-----------------------------------------------" +pushd "$spa_dir" >/dev/null +if [[ -f package-lock.json ]]; then + npm ci +else + npm install +fi +popd >/dev/null + +echo "-----------------------------------------------" +echo "dotnet publish -> $out_dir" +echo "-----------------------------------------------" +rm -rf "$out_dir" +mkdir -p "$out_dir" + +dotnet publish MyOffice.Web/MyOffice.Web.csproj -c Release -o "$out_dir" --no-restore --nologo + +# CT owns Production overlays — do not ship local env-specific appsettings. +while IFS= read -r -d '' f; do + base="$(basename "$f")" + if [[ "$base" != appsettings.json && "$base" != appsettings.shared.json ]]; then + rm -f "$f" + fi +done < <(find "$out_dir" -maxdepth 1 -name 'appsettings*.json' -print0) + +echo "-----------------------------------------------" +echo "ng build (proxmox) -> $out_dir/wwwroot" +echo "-----------------------------------------------" +spa_out="$(mktemp -d /tmp/myoffice-spa.XXXXXX)" +pushd "$spa_dir" >/dev/null +npx ng build --configuration proxmox --output-path "$spa_out" +popd >/dev/null + +wwwroot="$out_dir/wwwroot" +rm -rf "$wwwroot" +mkdir -p "$wwwroot" + +if [[ -d "$spa_out/browser" ]]; then + cp -a "$spa_out/browser/." "$wwwroot/" +else + cp -a "$spa_out/." "$wwwroot/" +fi +rm -rf "$spa_out" + +if [[ "$do_tar" == true ]]; then + out_parent="$(cd "$(dirname "$out_dir")" && pwd)" + out_leaf="$(basename "$out_dir")" + tar_path="$out_parent/myoffice-publish.tar.gz" + rm -f "$tar_path" + echo "-----------------------------------------------" + echo "tar -> $tar_path" + echo "-----------------------------------------------" + pushd "$out_parent" >/dev/null + tar -czf "$tar_path" "$out_leaf" + popd >/dev/null + echo "Archive: $tar_path" +fi + +echo "" +echo "Published to $out_dir" +echo "Next (Gitea): ./proxmox/publish.sh --tar ; ./proxmox/release.sh ..." +echo "Lab SSH: ./proxmox/deploy.ps1 -TargetHost " +echo "" diff --git a/proxmox/release.ps1 b/proxmox/release.ps1 new file mode 100644 index 0000000..6d215f5 --- /dev/null +++ b/proxmox/release.ps1 @@ -0,0 +1,154 @@ +# Upload myoffice-publish.tar.gz to a Gitea Release on the public repo. +# Usage: +# $env:GITEA_TOKEN = '' +# .\proxmox\publish.ps1 -Tar +# .\proxmox\release.ps1 -GiteaUrl https://gitea.example.com -Owner org -Repo myoffice-public -Tag v1.2.3 +# +# Token needs write:repository on the public repo. + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [string]$GiteaUrl, + + [Parameter(Mandatory = $true)] + [string]$Owner, + + [string]$Repo = 'myoffice-public', + + [Parameter(Mandatory = $true)] + [string]$Tag, + + [string]$Token = $env:GITEA_TOKEN, + + [string]$AssetPath = '', + + [string]$Title = '', + + [string]$Body = 'MyOffice published API + SPA (Proxmox CT artifact).', + + [string]$Target = 'main' +) + +$ErrorActionPreference = 'Stop' + +if (-not $Token) { + throw 'GITEA_TOKEN (or -Token) is required.' +} + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$repoRoot = Resolve-Path (Join-Path $scriptDir '..') + +if (-not $AssetPath) { + $AssetPath = Join-Path $repoRoot 'myoffice-publish.tar.gz' +} +if (-not (Test-Path $AssetPath)) { + throw "Asset not found: $AssetPath — run .\proxmox\publish.ps1 -Tar first." +} + +$GiteaUrl = $GiteaUrl.TrimEnd('/') +$api = "$GiteaUrl/api/v1" +$assetName = 'myoffice-publish.tar.gz' +if (-not $Title) { $Title = $Tag } + +$headers = @{ + Authorization = "token $Token" + Accept = 'application/json' +} + +function Invoke-GiteaJson { + param( + [string]$Method, + [string]$Uri, + [object]$BodyObject = $null + ) + $params = @{ + Method = $Method + Uri = $Uri + Headers = $headers + } + if ($null -ne $BodyObject) { + $params.ContentType = 'application/json' + $params.Body = ($BodyObject | ConvertTo-Json -Depth 6) + } + return Invoke-RestMethod @params +} + +Write-Host "-----------------------------------------------" +Write-Host "Gitea release $Owner/$Repo tag $Tag" +Write-Host "-----------------------------------------------" + +$release = $null +try { + $release = Invoke-GiteaJson -Method GET -Uri "$api/repos/$Owner/$Repo/releases/tags/$Tag" + Write-Host "Release $Tag already exists (id $($release.id))." +} +catch { + Write-Host "Creating release $Tag..." + $release = Invoke-GiteaJson -Method POST -Uri "$api/repos/$Owner/$Repo/releases" -BodyObject @{ + tag_name = $Tag + target_commitish = $Target + name = $Title + body = $Body + draft = $false + prerelease = $false + } + Write-Host "Created release id $($release.id)." +} + +# Remove existing asset with the same name so re-upload works +$existing = @($release.assets) | Where-Object { $_.name -eq $assetName } +foreach ($a in $existing) { + Write-Host "Deleting existing asset id $($a.id) ($($a.name))..." + Invoke-GiteaJson -Method DELETE -Uri "$api/repos/$Owner/$Repo/releases/$($release.id)/assets/$($a.id)" | Out-Null +} + +$uploadUrl = "$api/repos/$Owner/$Repo/releases/$($release.id)/assets?name=$assetName" +Write-Host "Uploading $AssetPath ..." + +# Prefer curl multipart (reliable on Windows PowerShell 5 + 7) +$curl = Get-Command curl.exe -ErrorAction SilentlyContinue +if ($curl) { + $args = @( + '-fsS', '-X', 'POST', + '-H', "Authorization: token $Token", + '-F', "attachment=@$AssetPath", + $uploadUrl + ) + & curl.exe @args + if ($LASTEXITCODE -ne 0) { + throw "curl upload failed with exit code $LASTEXITCODE" + } +} +else { + # Fallback: .NET multipart + Add-Type -AssemblyName System.Net.Http + $handler = [System.Net.Http.HttpClientHandler]::new() + $client = [System.Net.Http.HttpClient]::new($handler) + $client.DefaultRequestHeaders.Add('Authorization', "token $Token") + $content = [System.Net.Http.MultipartFormDataContent]::new() + $fs = [System.IO.File]::OpenRead($AssetPath) + try { + $streamContent = [System.Net.Http.StreamContent]::new($fs) + $streamContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse('application/octet-stream') + $content.Add($streamContent, 'attachment', $assetName) + $resp = $client.PostAsync($uploadUrl, $content).Result + if (-not $resp.IsSuccessStatusCode) { + $err = $resp.Content.ReadAsStringAsync().Result + throw "Upload failed: $($resp.StatusCode) $err" + } + } + finally { + $fs.Dispose() + $content.Dispose() + $client.Dispose() + } +} + +$downloadUrl = "$GiteaUrl/$Owner/$Repo/releases/download/$Tag/$assetName" +Write-Host "" +Write-Host "Uploaded. Download URL:" +Write-Host " $downloadUrl" +Write-Host "Latest API:" +Write-Host " $api/repos/$Owner/$Repo/releases/latest" +Write-Host "" diff --git a/proxmox/release.sh b/proxmox/release.sh new file mode 100755 index 0000000..9f566f3 --- /dev/null +++ b/proxmox/release.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +# Upload myoffice-publish.tar.gz to a Gitea Release on the public repo. +# Usage: +# export GITEA_TOKEN='' +# ./proxmox/publish.sh --tar +# ./proxmox/release.sh --gitea-url https://gitea.example.com --owner org --repo myoffice-public --tag v1.2.3 +# +# Token needs write:repository on the public repo. + +set -euo pipefail + +script_dir="$(cd "$(dirname "$0")" && pwd)" +repo_root="$(cd "$script_dir/.." && pwd)" + +gitea_url="${GITEA_URL:-}" +owner="${GITEA_OWNER:-}" +repo="${GITEA_REPO:-myoffice-public}" +tag="${TAG:-}" +token="${GITEA_TOKEN:-}" +asset_path="${ASSET_PATH:-}" +title="${TITLE:-}" +body="${BODY:-MyOffice published API + SPA (Proxmox CT artifact).}" +target="${TARGET:-main}" + +usage() { + echo "Usage: $0 --gitea-url URL --owner OWNER --tag TAG [--repo REPO] [--asset-path PATH]" >&2 + exit 1 +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --gitea-url) + gitea_url="$2" + shift 2 + ;; + --owner) + owner="$2" + shift 2 + ;; + --repo) + repo="$2" + shift 2 + ;; + --tag) + tag="$2" + shift 2 + ;; + --asset-path) + asset_path="$2" + shift 2 + ;; + --title) + title="$2" + shift 2 + ;; + --body) + body="$2" + shift 2 + ;; + --target) + target="$2" + shift 2 + ;; + -h | --help) + usage + ;; + *) + echo "Unknown argument: $1" >&2 + usage + ;; + esac +done + +if [[ -z "$token" ]]; then + echo "GITEA_TOKEN (or export before run) is required." >&2 + exit 1 +fi +if [[ -z "$gitea_url" || -z "$owner" || -z "$tag" ]]; then + usage +fi + +if [[ -z "$asset_path" ]]; then + asset_path="$repo_root/myoffice-publish.tar.gz" +fi +if [[ ! -f "$asset_path" ]]; then + echo "Asset not found: $asset_path — run ./proxmox/publish.sh --tar first." >&2 + exit 1 +fi + +gitea_url="${gitea_url%/}" +api="$gitea_url/api/v1" +asset_name="myoffice-publish.tar.gz" +if [[ -z "$title" ]]; then + title="$tag" +fi + +auth_header="Authorization: token $token" + +api_call() { + local method="$1" + local uri="$2" + local payload="${3:-}" + if [[ -n "$payload" ]]; then + curl -fsS -X "$method" -H "$auth_header" -H "Accept: application/json" \ + -H "Content-Type: application/json" -d "$payload" "$uri" + else + curl -fsS -X "$method" -H "$auth_header" -H "Accept: application/json" "$uri" + fi +} + +release_json="" +if release_json="$(api_call GET "$api/repos/$owner/$repo/releases/tags/$tag" 2>/dev/null)"; then + release_id="$(python3 -c "import json,sys; print(json.load(sys.stdin)['id'])" <<<"$release_json")" + echo "Release $tag already exists (id $release_id)." +else + echo "Creating release $tag..." + payload="$(TAG="$tag" TITLE="$title" BODY="$body" TARGET="$target" python3 <<'PY' +import json, os +print(json.dumps({ + "tag_name": os.environ["TAG"], + "target_commitish": os.environ["TARGET"], + "name": os.environ["TITLE"], + "body": os.environ["BODY"], + "draft": False, + "prerelease": False, +})) +PY +)" + release_json="$(api_call POST "$api/repos/$owner/$repo/releases" "$payload")" + release_id="$(python3 -c "import json,sys; print(json.load(sys.stdin)['id'])" <<<"$release_json")" + echo "Created release id $release_id." +fi + +asset_ids="$(python3 -c " +import json, sys +data = json.load(sys.stdin) +for a in data.get('assets', []): + if a.get('name') == '$asset_name': + print(a['id']) +" <<<"$release_json")" + +while IFS= read -r asset_id; do + [[ -z "$asset_id" ]] && continue + echo "Deleting existing asset id $asset_id ($asset_name)..." + api_call DELETE "$api/repos/$owner/$repo/releases/$release_id/assets/$asset_id" >/dev/null || true +done <<<"$asset_ids" + +upload_url="$api/repos/$owner/$repo/releases/$release_id/assets?name=$asset_name" +echo "Uploading $asset_path ..." +curl -fsS -X POST -H "$auth_header" -F "attachment=@$asset_path" "$upload_url" + +download_url="$gitea_url/$owner/$repo/releases/download/$tag/$asset_name" +echo "" +echo "Uploaded. Download URL:" +echo " $download_url" +echo "Latest API:" +echo " $api/repos/$owner/$repo/releases/latest" +echo "" diff --git a/proxmox/sync-public.ps1 b/proxmox/sync-public.ps1 new file mode 100644 index 0000000..124f4eb --- /dev/null +++ b/proxmox/sync-public.ps1 @@ -0,0 +1,161 @@ +# Sync allowlisted paths from the private repo to the public Gitea repo (no full source). +# Usage: +# $env:GITEA_TOKEN = '' # optional if using SSH remote +# .\proxmox\sync-public.ps1 -GiteaUrl https://gitea.example.com -Owner org -Repo myoffice-public -Push +# +# Allowlist: proxmox/, Docker/, README.md, LICENSE (if present). +# Never syncs MyOffice.* source, _Published, secrets, node_modules, etc. + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [string]$GiteaUrl, + + [Parameter(Mandatory = $true)] + [string]$Owner, + + [string]$Repo = 'myoffice-public', + + [string]$Branch = 'main', + + [string]$Token = $env:GITEA_TOKEN, + + [string]$WorkDir = '', + + [switch]$Push +) + +$ErrorActionPreference = 'Stop' + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$repoRoot = Resolve-Path (Join-Path $scriptDir '..') +Set-Location $repoRoot + +$GiteaUrl = $GiteaUrl.TrimEnd('/') + +if (-not $WorkDir) { + $WorkDir = Join-Path $env:TEMP 'myoffice-public-sync' +} + +$allowDirs = @('proxmox', 'Docker') +$allowFiles = @('README.md', 'LICENSE', 'LICENSE.md') +$excludeNames = @('.git', '_Published', 'myoffice-publish.tar.gz', 'node_modules', 'data', '.env', 'env.local') + +function Test-Excluded([string]$Name) { + return $excludeNames -contains $Name +} + +function Copy-Allowlisted { + param([string]$DestRoot) + + foreach ($dir in $allowDirs) { + $src = Join-Path $repoRoot $dir + if (-not (Test-Path $src)) { + Write-Host "Skip missing dir: $dir" + continue + } + $dest = Join-Path $DestRoot $dir + if (Test-Path $dest) { + Remove-Item -Recurse -Force $dest + } + New-Item -ItemType Directory -Path $dest -Force | Out-Null + + Get-ChildItem -Path $src -Force | Where-Object { -not (Test-Excluded $_.Name) } | ForEach-Object { + if ($dir -eq 'Docker' -and $_.Name -eq 'data') { return } + Copy-Item $_.FullName -Destination (Join-Path $dest $_.Name) -Recurse -Force + } + Write-Host "Synced $dir/" + } + + foreach ($file in $allowFiles) { + $src = Join-Path $repoRoot $file + if (Test-Path $src) { + Copy-Item $src -Destination (Join-Path $DestRoot $file) -Force + Write-Host "Synced $file" + } + } + + $publicNote = Join-Path $DestRoot 'PUBLIC.md' + @( + '# MyOffice public tree', + '', + 'This repository is a **filtered** mirror for Proxmox CT install scripts and Docker demo files.', + 'Application **source** stays in the private developer repository.', + 'Runnable app binaries are published as **Gitea Releases** (`myoffice-publish.tar.gz`).', + '', + 'See [proxmox/README.md](proxmox/README.md).', + '' + ) | Set-Content -Path $publicNote -Encoding utf8 +} + +if ($Token) { + $hostPart = $GiteaUrl -replace '^https://', '' -replace '^http://', '' + $scheme = if ($GiteaUrl -match '^http://') { 'http' } else { 'https' } + $remote = "${scheme}://oauth2:${Token}@${hostPart}/${Owner}/${Repo}.git" +} +else { + $remote = "${GiteaUrl}/${Owner}/${Repo}.git" + Write-Host "No token — using remote as-is (SSH URL recommended): $remote" +} + +Write-Host "-----------------------------------------------" +Write-Host "Sync allowlist -> $Owner/$Repo ($Branch)" +Write-Host "WorkDir: $WorkDir" +Write-Host "-----------------------------------------------" + +if (Test-Path $WorkDir) { + Remove-Item -Recurse -Force $WorkDir +} +New-Item -ItemType Directory -Path $WorkDir | Out-Null + +$cloned = $false +git clone --depth 1 --branch $Branch $remote $WorkDir 2>$null +if ($LASTEXITCODE -eq 0) { + $cloned = $true +} + +if (-not $cloned) { + Write-Host "Clone failed or empty repo — initializing new git repo..." + git -C $WorkDir init -b $Branch + if ($LASTEXITCODE -ne 0) { + git -C $WorkDir init + git -C $WorkDir checkout -b $Branch 2>$null + } + git -C $WorkDir remote remove origin 2>$null + git -C $WorkDir remote add origin $remote +} + +Get-ChildItem -Path $WorkDir -Force | Where-Object { $_.Name -ne '.git' } | ForEach-Object { + Remove-Item $_.FullName -Recurse -Force +} + +Copy-Allowlisted -DestRoot $WorkDir + +git -C $WorkDir add -A +$status = git -C $WorkDir status --porcelain +if (-not $status) { + Write-Host "No changes to commit." +} +else { + git -C $WorkDir -c user.email='myoffice-sync@local' -c user.name='myoffice-sync' ` + commit -m "sync public allowlist from private myoffice" + Write-Host "Committed allowlist snapshot." +} + +if ($Push) { + Write-Host "Pushing to origin $Branch..." + git -C $WorkDir push -u origin "HEAD:$Branch" + if ($LASTEXITCODE -ne 0) { + throw "git push failed with exit code $LASTEXITCODE" + } + Write-Host "Pushed." +} +else { + Write-Host "Dry run (no push). Re-run with -Push to publish." + Write-Host "Work tree left at: $WorkDir" +} + +Write-Host "" +Write-Host "Raw base for CT install:" +Write-Host " $GiteaUrl/$Owner/$Repo/raw/branch/$Branch" +Write-Host "" diff --git a/proxmox/sync-public.sh b/proxmox/sync-public.sh new file mode 100755 index 0000000..40ecbd3 --- /dev/null +++ b/proxmox/sync-public.sh @@ -0,0 +1,183 @@ +#!/usr/bin/env bash +# Sync allowlisted paths from the private repo to the public Gitea repo (no full source). +# Usage: +# export GITEA_TOKEN='' +# ./proxmox/sync-public.sh --gitea-url https://gitea.example.com --owner org --repo myoffice-public --push +# +# Allowlist: proxmox/, Docker/, README.md, LICENSE (if present). + +set -euo pipefail + +script_dir="$(cd "$(dirname "$0")" && pwd)" +repo_root="$(cd "$script_dir/.." && pwd)" +cd "$repo_root" + +gitea_url="${GITEA_URL:-}" +owner="${GITEA_OWNER:-}" +repo="${GITEA_REPO:-myoffice-public}" +branch="${BRANCH:-main}" +token="${GITEA_TOKEN:-}" +work_dir="${WORK_DIR:-}" +do_push=false + +usage() { + echo "Usage: $0 --gitea-url URL --owner OWNER [--repo REPO] [--branch BRANCH] [--push]" >&2 + exit 1 +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --gitea-url) + gitea_url="$2" + shift 2 + ;; + --owner) + owner="$2" + shift 2 + ;; + --repo) + repo="$2" + shift 2 + ;; + --branch) + branch="$2" + shift 2 + ;; + --work-dir) + work_dir="$2" + shift 2 + ;; + --push) + do_push=true + shift + ;; + -h | --help) + usage + ;; + *) + echo "Unknown argument: $1" >&2 + usage + ;; + esac +done + +if [[ -z "$gitea_url" || -z "$owner" ]]; then + usage +fi + +gitea_url="${gitea_url%/}" + +if [[ -z "$work_dir" ]]; then + work_dir="${TMPDIR:-/tmp}/myoffice-public-sync" +fi + +allow_dirs=(proxmox Docker) +allow_files=(README.md LICENSE LICENSE.md) +exclude_names=('.git' '_Published' 'myoffice-publish.tar.gz' 'node_modules' 'data' '.env' 'env.local') + +is_excluded() { + local name="$1" + for x in "${exclude_names[@]}"; do + [[ "$name" == "$x" ]] && return 0 + done + return 1 +} + +if [[ -n "$token" ]]; then + host_part="${gitea_url#https://}" + host_part="${host_part#http://}" + if [[ "$gitea_url" == http://* ]]; then + scheme=http + else + scheme=https + fi + remote="${scheme}://oauth2:${token}@${host_part}/${owner}/${repo}.git" +else + remote="${gitea_url}/${owner}/${repo}.git" + echo "No token — using remote as-is (SSH URL recommended): $remote" +fi + +echo "-----------------------------------------------" +echo "Sync allowlist -> $owner/$repo ($branch)" +echo "WorkDir: $work_dir" +echo "-----------------------------------------------" + +rm -rf "$work_dir" +mkdir -p "$work_dir" + +if git clone --depth 1 --branch "$branch" "$remote" "$work_dir" 2>/dev/null; then + : +else + echo "Clone failed or empty repo — initializing new git repo..." + git -C "$work_dir" init -b "$branch" 2>/dev/null || { + git -C "$work_dir" init + git -C "$work_dir" checkout -b "$branch" 2>/dev/null || true + } + git -C "$work_dir" remote remove origin 2>/dev/null || true + git -C "$work_dir" remote add origin "$remote" +fi + +find "$work_dir" -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + + +for dir in "${allow_dirs[@]}"; do + src="$repo_root/$dir" + if [[ ! -d "$src" ]]; then + echo "Skip missing dir: $dir" + continue + fi + dest="$work_dir/$dir" + mkdir -p "$dest" + while IFS= read -r -d '' item; do + name="$(basename "$item")" + if is_excluded "$name"; then + continue + fi + if [[ "$dir" == Docker && "$name" == data ]]; then + continue + fi + cp -a "$item" "$dest/" + done < <(find "$src" -mindepth 1 -maxdepth 1 -print0) + echo "Synced $dir/" +done + +for file in "${allow_files[@]}"; do + src="$repo_root/$file" + if [[ -f "$src" ]]; then + cp -a "$src" "$work_dir/$file" + echo "Synced $file" + fi +done + +cat >"$work_dir/PUBLIC.md" <<'EOF' +# MyOffice public tree + +This repository is a **filtered** mirror for Proxmox CT install scripts and Docker demo files. +Application **source** stays in the private developer repository. +Runnable app binaries are published as **Gitea Releases** (`myoffice-publish.tar.gz`). + +See [proxmox/README.md](proxmox/README.md). + +EOF + +git -C "$work_dir" add -A +if [[ -z "$(git -C "$work_dir" status --porcelain)" ]]; then + echo "No changes to commit." +else + git -C "$work_dir" -c user.email='myoffice-sync@local' -c user.name='myoffice-sync' \ + commit -m "sync public allowlist from private myoffice" + echo "Committed allowlist snapshot." +fi + +if [[ "$do_push" == true ]]; then + echo "Pushing to origin $branch..." + git -C "$work_dir" push -u origin "HEAD:$branch" + echo "Pushed." +else + echo "Dry run (no push). Re-run with --push to publish." + echo "Work tree left at: $work_dir" +fi + +echo "" +echo "Raw base for CT install:" +echo " $gitea_url/$owner/$repo/raw/branch/$branch" +echo "" diff --git a/proxmox/update.sh b/proxmox/update.sh new file mode 100644 index 0000000..3b4dfa0 --- /dev/null +++ b/proxmox/update.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# Helpers inside an existing MyOffice LXC (runtime + Postgres + Gitea release app). +# Usage: +# /opt/myoffice/proxmox/update.sh # download latest/tag release + restart +# /opt/myoffice/proxmox/update.sh upgrade +# /opt/myoffice/proxmox/update.sh logs +# /opt/myoffice/proxmox/update.sh restart +# /opt/myoffice/proxmox/update.sh status + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +APP_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +API_DIR="${APP_DIR}/api" +ACTION="${1:-upgrade}" + +# shellcheck disable=SC1091 +[[ -f "${SCRIPT_DIR}/env" ]] && . "${SCRIPT_DIR}/env" + +export APP_DIR API_DIR +export GITEA_URL="${GITEA_URL:-}" +export GITEA_OWNER="${GITEA_OWNER:-}" +export GITEA_REPO="${GITEA_REPO:-myoffice-public}" +export RELEASE_TAG="${RELEASE_TAG:-latest}" +export RELEASE_ASSET_URL="${RELEASE_ASSET_URL:-}" +export GITEA_TOKEN="${GITEA_TOKEN:-}" + +upgrade_app() { + systemctl stop myoffice-api 2>/dev/null || true + # shellcheck disable=SC1091 + source "${SCRIPT_DIR}/fetch-release.sh" + download_and_extract + systemctl start myoffice-api + systemctl status myoffice-api --no-pager || true +} + +case "$ACTION" in + upgrade | update | rebuild | up) + upgrade_app + ;; + logs) + journalctl -u myoffice-api -f + ;; + restart) + systemctl restart myoffice-api + systemctl status myoffice-api --no-pager + ;; + status) + systemctl status myoffice-api --no-pager || true + if [[ ! -f "${API_DIR}/MyOffice.Web.dll" ]]; then + echo + echo "No app binaries. Run: $0 upgrade" + echo "Or set GITEA_URL / GITEA_OWNER / RELEASE_TAG in ${SCRIPT_DIR}/env" + fi + ;; + *) + echo "Usage: $0 [upgrade|status|logs|restart]" >&2 + exit 1 + ;; +esac