diff --git a/.github/workflows/deploy-azure-naming-tool-to-azure-webapps-dotnet-core.yml b/.github/workflows/deploy-azure-naming-tool-to-azure-webapps-dotnet-core.yml index 8c881ccd..12dda2d1 100644 --- a/.github/workflows/deploy-azure-naming-tool-to-azure-webapps-dotnet-core.yml +++ b/.github/workflows/deploy-azure-naming-tool-to-azure-webapps-dotnet-core.yml @@ -21,7 +21,7 @@ name: Azure Naming Tool - Build and deploy to an Azure Web App env: AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - DOTNET_VERSION: '8.0.x' # set this to the .NET Core version to use + DOTNET_VERSION: '7.0.x' # set this to the .NET Core version to use on: push: diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3f4985b7..00000000 --- a/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ - -/src/obj -/src/Properties/PublishProfiles -/src/Properties/ServiceDependencies/azurenamingtool-dev - Zip Deploy -/src/.vs -/src/bin diff --git a/src/.dockerignore b/src/.dockerignore index fe1152bd..3729ff0c 100644 --- a/src/.dockerignore +++ b/src/.dockerignore @@ -22,9 +22,4 @@ **/secrets.dev.yaml **/values.dev.yaml LICENSE -README.md -!**/.gitignore -!.git/HEAD -!.git/config -!.git/packed-refs -!.git/refs/heads/** \ No newline at end of file +README.md \ No newline at end of file diff --git a/src/.gitattributes b/src/.gitattributes new file mode 100644 index 00000000..1ff0c423 --- /dev/null +++ b/src/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..2dde792d --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,367 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# Settings files +settings/* +!settings/blank.txt \ No newline at end of file diff --git a/src/App.razor b/src/App.razor new file mode 100644 index 00000000..344f424f --- /dev/null +++ b/src/App.razor @@ -0,0 +1,23 @@ +@using AzureNamingTool.Models; + + + + + + + + + + Not found + + +

Whoa, it looks like that page went and r-u-n-n-o-f-t! Try again!

+
+
+
+
+
+@code { + [Parameter] + public IdentityProviderDetails? identityProviderDetails { get; set; } +} diff --git a/src/AzureNamingTool.csproj b/src/AzureNamingTool.csproj index 76a5a14b..0b58776c 100644 --- a/src/AzureNamingTool.csproj +++ b/src/AzureNamingTool.csproj @@ -1,25 +1,82 @@ - + - net8.0 + 3.3.0 + net7.0 enable enable - 4.0.0 - true - eca63fb9-b7f9-454f-910b-5088ae877085 + 8d243b16-78f2-4542-8f36-682411560b1a Linux . + true + + + + 1591;1701;1702 + + + + 1591;1701;1702 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + Always + + + Never + @@ -30,6 +87,7 @@ + diff --git a/src/AzureNamingTool.csproj.user b/src/AzureNamingTool.csproj.user deleted file mode 100644 index 73821ccb..00000000 --- a/src/AzureNamingTool.csproj.user +++ /dev/null @@ -1,10 +0,0 @@ - - - - https - C:\Projects\AzureNamingTool\.github\workflows\codeql.yml - - - ProjectDebugger - - \ No newline at end of file diff --git a/src/AzureNamingTool.sln b/src/AzureNamingTool.sln index 140a7e60..df78ab4b 100644 --- a/src/AzureNamingTool.sln +++ b/src/AzureNamingTool.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.8.34322.80 +VisualStudioVersion = 17.0.32112.339 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureNamingTool", "AzureNamingTool.csproj", "{B9EC3E06-9B4D-4CA0-ABBD-E4115384B730}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureNamingTool", "AzureNamingTool.csproj", "{611DC036-F19A-4198-A63E-9163B545F59A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B9EC3E06-9B4D-4CA0-ABBD-E4115384B730}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B9EC3E06-9B4D-4CA0-ABBD-E4115384B730}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B9EC3E06-9B4D-4CA0-ABBD-E4115384B730}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B9EC3E06-9B4D-4CA0-ABBD-E4115384B730}.Release|Any CPU.Build.0 = Release|Any CPU + {611DC036-F19A-4198-A63E-9163B545F59A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {611DC036-F19A-4198-A63E-9163B545F59A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {611DC036-F19A-4198-A63E-9163B545F59A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {611DC036-F19A-4198-A63E-9163B545F59A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {903E93DC-11BB-4512-A444-F59A4BE2EEF8} + SolutionGuid = {8C98E701-BDC5-4F6F-9F85-7BEC01C00E51} EndGlobalSection EndGlobal diff --git a/src/Components/Layout/MainLayout.razor.css b/src/Components/Layout/MainLayout.razor.css deleted file mode 100644 index 1b8eba6b..00000000 --- a/src/Components/Layout/MainLayout.razor.css +++ /dev/null @@ -1,97 +0,0 @@ -.page { - position: relative; - display: flex; - flex-direction: column; -} - -main { - flex: 1; -} - -.sidebar { - /*background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);*/ - background-color: #004494; -} - -.top-row { - background-color: #f7f7f7; - border-bottom: 1px solid #d6d5d5; - justify-content: flex-end; - height: 3.5rem; - display: flex; - align-items: center; -} - - .top-row ::deep a, .top-row ::deep .btn-link { - white-space: nowrap; - margin-left: 1.5rem; - text-decoration: none; - } - - .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { - text-decoration: underline; - } - - .top-row ::deep a:first-child { - overflow: hidden; - text-overflow: ellipsis; - } - -@media (max-width: 640.98px) { - .top-row { - justify-content: space-between; - } - - .top-row ::deep a, .top-row ::deep .btn-link { - margin-left: 0; - } -} - -@media (min-width: 641px) { - .page { - flex-direction: row; - } - - .sidebar { - width: 250px; - height: 100vh; - position: sticky; - top: 0; - } - - .top-row { - position: sticky; - top: 0; - z-index: 1; - } - - .top-row.auth ::deep a:first-child { - flex: 1; - text-align: right; - width: 0; - } - - .top-row, article { - padding-left: 2rem !important; - padding-right: 1.5rem !important; - } -} - -#blazor-error-ui { - background: lightyellow; - bottom: 0; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); - display: none; - left: 0; - padding: 0.6rem 1.25rem 0.7rem 1.25rem; - position: fixed; - width: 100%; - z-index: 1000; -} - - #blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; - } diff --git a/src/Components/Layout/NavMenu.razor b/src/Components/Layout/NavMenu.razor deleted file mode 100644 index dcbf3fea..00000000 --- a/src/Components/Layout/NavMenu.razor +++ /dev/null @@ -1,230 +0,0 @@ -@using AzureNamingTool.Helpers -@using AzureNamingTool.Models -@using AzureNamingTool.Components.General -@inject StateContainer state -@inject ProtectedSessionStorage session -@inject IJSRuntime JsRuntime -@inject ILogger Logger -@inject ProtectedLocalStorage storage -@inject NavigationManager NavigationManager - - - -
- -
- -@code { - [Parameter] - public Type? PageType { get; set; } - private bool collapseNavMenu = true; - private ServicesData servicesData = new(); - private SiteConfiguration config = ConfigurationHelper.GetConfigurationData(); - private bool admin; - private string NavMenuCssClass => collapseNavMenu ? "collapse" : String.Empty; - private bool latestnewsenabled = true; - private bool connected = true; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - var result = await session.GetAsync("admin"); - admin = (bool)result.Value; - if (firstRender) - { - if (await ConfigurationHelper.VerifyConnectivity()) - { - servicesData = await ServicesHelper.LoadServicesData(servicesData, admin); - try - { - result = await storage.GetAsync("latestnewsenabled"); - latestnewsenabled = result.Success ? result.Value : true; - } - catch - { - latestnewsenabled = true; - } - state.LatestNewsEnabled = latestnewsenabled; - } - else - { - connected = false; - } - StateHasChanged(); - } - else - { - if ((GeneralHelper.IsNotNull(servicesData)) || (state._reloadnav)) - { - servicesData = await ServicesHelper.LoadServicesData(servicesData, admin); - state.SetNavReload(false); - } - } - } - - private void ToggleNavMenu() - { - collapseNavMenu = !collapseNavMenu; - } - - private async void OnConfigNavClick(string e) - { - await JsRuntime.InvokeVoidAsync("scrollIntoView", e); - } - - private async void NewsChanged(ChangeEventArgs e) - { - if (GeneralHelper.IsNotNull(e.Value)) - { - latestnewsenabled = (bool)e.Value; - await storage.SetAsync("newsenabled", latestnewsenabled); - state.LatestNewsEnabled = latestnewsenabled; - StateHasChanged(); - } - } -} diff --git a/src/Components/Layout/NavMenu.razor.css b/src/Components/Layout/NavMenu.razor.css deleted file mode 100644 index 75cac5de..00000000 --- a/src/Components/Layout/NavMenu.razor.css +++ /dev/null @@ -1,62 +0,0 @@ -.navbar-toggler { - background-color: rgba(255, 255, 255, 0.1); -} - -.top-row { - height: 3.5rem; - background-color: rgba(0,0,0,0.4); -} - -.navbar-brand { - font-size: 1.1rem; -} - -.oi { - width: 2rem; - font-size: 1.1rem; - vertical-align: text-top; - top: -2px; -} - -.nav-item { - font-size: 0.9rem; - padding-bottom: 0.5rem; -} - - .nav-item:first-of-type { - padding-top: 1rem; - } - - .nav-item:last-of-type { - padding-bottom: 1rem; - } - - .nav-item ::deep a { - color: #d7d7d7; - border-radius: 4px; - height: 3rem; - display: flex; - align-items: center; - line-height: 3rem; - } - - .nav-item ::deep a.active { - background-color: rgba(255,255,255,0.25); - color: white; - } - - .nav-item ::deep a:hover { - background-color: rgba(255,255,255,0.1); - color: white; - } - -@media (min-width: 641px) { - .navbar-toggler { - display: none; - } - - .collapse { - /* Never collapse the sidebar for wide screens */ - display: block; - } -} diff --git a/src/Components/Pages/404.razor b/src/Components/Pages/404.razor deleted file mode 100644 index 1819a823..00000000 --- a/src/Components/Pages/404.razor +++ /dev/null @@ -1,6 +0,0 @@ -@page "/404" - -

Whoa, it looks like that page doesn't exist! Please check the URL and try again!

-@code { - -} \ No newline at end of file diff --git a/src/Components/Pages/Error.razor b/src/Components/Pages/Error.razor deleted file mode 100644 index 576cc2d2..00000000 --- a/src/Components/Pages/Error.razor +++ /dev/null @@ -1,36 +0,0 @@ -@page "/Error" -@using System.Diagnostics - -Error - -

Error.

-

An error occurred while processing your request.

- -@if (ShowRequestId) -{ -

- Request ID: @RequestId -

-} - -

Development Mode

-

- Swapping to Development environment will display more detailed information about the error that occurred. -

-

- The Development environment shouldn't be enabled for deployed applications. - It can result in displaying sensitive information from exceptions to end users. - For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development - and restarting the app. -

- -@code{ - [CascadingParameter] - private HttpContext? HttpContext { get; set; } - - private string? RequestId { get; set; } - private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - - protected override void OnInitialized() => - RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; -} diff --git a/src/Components/Routes.razor b/src/Components/Routes.razor deleted file mode 100644 index 074e87df..00000000 --- a/src/Components/Routes.razor +++ /dev/null @@ -1,16 +0,0 @@ -@using AzureNamingTool.Models - - - - - - - - - - - -@code { - [Parameter] - public IdentityProviderDetails? identityProviderDetails { get; set; } -} \ No newline at end of file diff --git a/src/Dockerfile b/src/Dockerfile index d2def0bf..4663c624 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -1,11 +1,11 @@ #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. -FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY ["AzureNamingTool.csproj", "."] RUN dotnet restore "./AzureNamingTool.csproj" @@ -19,4 +19,4 @@ RUN dotnet publish "AzureNamingTool.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "AzureNamingTool.dll"] +ENTRYPOINT ["dotnet", "AzureNamingTool.dll"] \ No newline at end of file diff --git a/src/Helpers/GeneralHelper.cs b/src/Helpers/GeneralHelper.cs index 73907568..9e0cbe80 100644 --- a/src/Helpers/GeneralHelper.cs +++ b/src/Helpers/GeneralHelper.cs @@ -1,7 +1,7 @@ using AzureNamingTool.Models; -using AzureNamingTool.Components.Pages; +using AzureNamingTool.Pages; using AzureNamingTool.Services; -using AzureNamingTool.Components; +using AzureNamingTool.Shared; using Blazored.Modal; using Blazored.Modal.Services; using System; diff --git a/src/Helpers/ModalHelper.cs b/src/Helpers/ModalHelper.cs index 3c5215ed..bd51e93f 100644 --- a/src/Helpers/ModalHelper.cs +++ b/src/Helpers/ModalHelper.cs @@ -1,6 +1,6 @@ using AzureNamingTool.Models; using AzureNamingTool.Services; -using AzureNamingTool.Components.Modals; +using AzureNamingTool.Shared.Modals; using Blazored.Modal; using Blazored.Modal.Services; diff --git a/src/Models/ConfigurationData.cs b/src/Models/ConfigurationData.cs index 72ddc8aa..fc3e75dd 100644 --- a/src/Models/ConfigurationData.cs +++ b/src/Models/ConfigurationData.cs @@ -1,24 +1,24 @@ using AzureNamingTool.Models; -using AzureNamingTool.Components.Pages; +using AzureNamingTool.Pages; using System.Collections.Generic; namespace AzureNamingTool.Models { public class ConfigurationData { - public List ResourceComponents { get; set; } = []; - public List ResourceDelimiters { get; set; } = []; - public List ResourceEnvironments { get; set; } = []; - public List ResourceLocations { get; set; } = []; - public List ResourceOrgs { get; set; } = []; - public List ResourceProjAppSvcs { get; set; } = []; - public List ResourceTypes { get; set; } = []; - public List ResourceUnitDepts { get; set; } = []; - public List ResourceFunctions { get; set; } = []; - public List CustomComponents { get; set; } = []; - public List GeneratedNames { get; set; } = []; - public List? AdminLogs { get; set; } = []; - public List AdminUsers { get; set; } = []; + public List ResourceComponents { get; set; } = new(); + public List ResourceDelimiters { get; set; } = new(); + public List ResourceEnvironments { get; set; } = new(); + public List ResourceLocations { get; set; } = new(); + public List ResourceOrgs { get; set; } = new(); + public List ResourceProjAppSvcs { get; set; } = new(); + public List ResourceTypes { get; set; } = new(); + public List ResourceUnitDepts { get; set; } = new(); + public List ResourceFunctions { get; set; } = new(); + public List CustomComponents { get; set; } = new(); + public List GeneratedNames { get; set; } = new(); + public List? AdminLogs { get; set; } = new(); + public List AdminUsers { get; set; } = new(); public string? SALTKey { get; set; } public string? AdminPassword { get; set; } @@ -31,8 +31,5 @@ public class ConfigurationData public string? IdentityHeaderName { get; set; } public string? ResourceTypeEditingAllowed { get; set; } = "False"; public string? AutoIncrementResourceInstance { get; set; } = "False"; - public string? InstructionsEnabled { get; set; } = "True"; - public string? GeneratedNamesLogEnabled { get; set; } = "True"; - public string? LatestNewsEnabled { get; set; } = "False"; } } diff --git a/src/Models/SiteConfiguration.cs b/src/Models/SiteConfiguration.cs index f2d61a8f..4344692d 100644 --- a/src/Models/SiteConfiguration.cs +++ b/src/Models/SiteConfiguration.cs @@ -15,8 +15,5 @@ public class SiteConfiguration public string? IdentityHeaderName { get; set; } public string? ResourceTypeEditingAllowed { get; set; } = "False"; public string? AutoIncrementResourceInstance { get; set; } = "False"; - public string? InstructionsEnabled { get; set; } = "True"; - public string? GeneratedNamesLogEnabled { get; set; } = "True"; - public string? LatestNewsEnabled { get; set; } = "False"; } } diff --git a/src/Models/StateContainer.cs b/src/Models/StateContainer.cs index fe7af555..db9c259c 100644 --- a/src/Models/StateContainer.cs +++ b/src/Models/StateContainer.cs @@ -6,7 +6,7 @@ public class StateContainer private bool? _admin; private bool? _password; private string _apptheme = String.Empty; - private bool? _latestnewsenabled; + private bool? _newsenabled; public bool _reloadnav; public bool? _configurationdatasynced; @@ -74,19 +74,19 @@ public void SetAppTheme(string value) NotifyStateChanged(); } - public bool LatestNewsEnabled + public bool NewsEnabled { - get => _latestnewsenabled ?? true; + get => _newsenabled ?? true; set { - _latestnewsenabled = value; + _newsenabled = value; NotifyStateChanged(); } } - public void SetLatestNewsEnabled(bool latestnewsenabled) + public void SetNewsEnabled(bool newsenabled) { - _latestnewsenabled = latestnewsenabled; + _newsenabled = newsenabled; NotifyStateChanged(); } diff --git a/src/Components/Pages/Admin.razor b/src/Pages/Admin.razor similarity index 86% rename from src/Components/Pages/Admin.razor rename to src/Pages/Admin.razor index 3b8cae52..c9a89a35 100644 --- a/src/Components/Pages/Admin.razor +++ b/src/Pages/Admin.razor @@ -1,12 +1,10 @@ @page "/admin" -@using AzureNamingTool.Components.Modals @using AzureNamingTool.Helpers; @using AzureNamingTool.Models; @using System.Runtime.Caching; @using AzureNamingTool.Services; @using Blazored.Toast.Configuration; @using Microsoft.AspNetCore.Html -@using Microsoft.AspNetCore.WebUtilities @using Microsoft.Extensions.Logging @using System.Reflection; @inject IJSRuntime JsRuntime @@ -415,69 +413,6 @@ -
- -
-
-

- Enable/Disable the Instructions page for non-admin users. (Documentation links will still be visible.) -

-
-
- - Enable -
-
-
-
- -
-
-

- Enable/Disable the Generated Names Log page for non-admin users. -

-
-
- - Enable -
-
-
-
- -
-
-

- Enable/Disable the Latest News for all users. -

-
-
- - Enable -
-
-
-
-
-

- This will reset all site settings to the default values. This cannot be undone! -

-
-
- -
-
-
} @@ -580,9 +498,6 @@ private bool connectivitycheckenabled = true; private bool resourcetypeeditingallowed = false; private bool autoincrementresourceinstance = false; - private bool instructionsenabled = false; - private bool generatednameslogenabled = false; - private bool latestnewsenabled = false; private string currentgenerationwebhook = String.Empty; private string versionalert = String.Empty; private string appversion = String.Empty; @@ -614,9 +529,6 @@ connectivitycheckenabled = Convert.ToBoolean(ConfigurationHelper.GetAppSetting("ConnectivityCheckEnabled")); resourcetypeeditingallowed = Convert.ToBoolean(ConfigurationHelper.GetAppSetting("ResourceTypeEditingAllowed")); autoincrementresourceinstance = Convert.ToBoolean(ConfigurationHelper.GetAppSetting("AutoIncrementResourceInstance")); - instructionsenabled = Convert.ToBoolean(ConfigurationHelper.GetAppSetting("InstructionsEnabled")); - generatednameslogenabled = Convert.ToBoolean(ConfigurationHelper.GetAppSetting("GeneratedNamesLogEnabled")); - latestnewsenabled = Convert.ToBoolean(ConfigurationHelper.GetAppSetting("LatestNewsEnabled")); currentgenerationwebhook = ConfigurationHelper.GetAppSetting("GenerationWebhook", true); currentidentityheadername = ConfigurationHelper.GetAppSetting("IdentityHeaderName", true); if (GeneralHelper.IsNotNull(identityProviderDetails)) @@ -633,27 +545,11 @@ state.AppTheme = theme.ThemeStyle; StateHasChanged(); - - var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri); - if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("reset", out var _reset)) - { - if (Convert.ToBoolean(_reset)) - { - toastService.ShowSuccess("The site settings have been reset!"); - } - } - } } private async void AdminFormAction(string action, int id = 0) { - var workingmodaloptions = new ModalOptions() - { - HideCloseButton = true, - UseCustomLayout = true - }; - var workingmodal = Modal.Show("Working", workingmodaloptions); message = new ResponseMessage(); message.Header = "INFORMATION"; message.Type = MessageTypesEnum.INFORMATION; @@ -931,28 +827,6 @@ displaymessage = false; } break; - - case "resetsitesettings": - confirm = await ModalHelper.ShowConfirmationModal(Modal!, "ATTENTION", "
This will reset the site settings.
Are you sure?
", "bg-danger", theme); - if (confirm) - { - // Create new default configuration - SiteConfiguration resetconfig = new(); - ConfigurationHelper.SetAppSetting("AutoIncrementResourceInstance", resetconfig.AutoIncrementResourceInstance!, false); - ConfigurationHelper.SetAppSetting("DuplicateNamesAllowed", resetconfig.DuplicateNamesAllowed!, false); - ConfigurationHelper.SetAppSetting("ResourceTypeEditingAllowed", resetconfig.ResourceTypeEditingAllowed!, false); - ConfigurationHelper.SetAppSetting("InstructionsEnabled", resetconfig.InstructionsEnabled!, false); - ConfigurationHelper.SetAppSetting("GeneratedNamesLogEnabled", resetconfig.GeneratedNamesLogEnabled!, false); - ConfigurationHelper.SetAppSetting("LatestNewsEnabled", resetconfig.LatestNewsEnabled!, false); - ConfigurationHelper.SetAppSetting("ConnectivityCheckEnabled", resetconfig.ConnectivityCheckEnabled!, false); - ConfigurationHelper.SetAppSetting("GenerationWebhook", String.Empty, true); - NavigationManager.NavigateTo("/admin?reset=true", true); - } - else - { - displaymessage = false; - } - break; } config = ConfigurationHelper.GetConfigurationData(); @@ -980,11 +854,11 @@ } } + servicesData = await ServicesHelper.LoadServicesData(servicesData, admin); state.SetNavReload(true); StateHasChanged(); - workingmodal.Close(); if (redirect) { if (admin) @@ -1084,27 +958,6 @@ message.Message = "Auto Increment Resource Instance setting updated to " + e.Value?.ToString()!.ToUpper() ?? "" + "!"; } break; - case "instructionsenabled": - if (GeneralHelper.IsNotNull(e.Value)) - { - ConfigurationHelper.SetAppSetting("InstructionsEnabled", e.Value!.ToString() ?? ""); - message.Message = "Instructions Enabled setting updated to " + e.Value?.ToString()!.ToUpper() ?? "" + "!"; - } - break; - case "generatednameslogenabled": - if (GeneralHelper.IsNotNull(e.Value)) - { - ConfigurationHelper.SetAppSetting("GeneratedNamesLogEnabled", e.Value!.ToString() ?? ""); - message.Message = "Generated Names Log Enabled setting updated to " + e.Value?.ToString()!.ToUpper() ?? "" + "!"; - } - break; - case "latestnewsenabled": - if (GeneralHelper.IsNotNull(e.Value)) - { - ConfigurationHelper.SetAppSetting("LatestNewsEnabled", e.Value!.ToString() ?? ""); - message.Message = "Latest News Enabled setting updated to " + e.Value?.ToString()!.ToUpper() ?? "" + "!"; - } - break; } message.Type = MessageTypesEnum.SUCCESS; message.Header = "SUCCESS"; diff --git a/src/Components/Pages/AdminLog.razor b/src/Pages/AdminLog.razor similarity index 100% rename from src/Components/Pages/AdminLog.razor rename to src/Pages/AdminLog.razor diff --git a/src/Components/Pages/Configuration.razor b/src/Pages/Configuration.razor similarity index 99% rename from src/Components/Pages/Configuration.razor rename to src/Pages/Configuration.razor index fde623b5..dda03bb5 100644 --- a/src/Components/Pages/Configuration.razor +++ b/src/Pages/Configuration.razor @@ -3,7 +3,7 @@ @using AzureNamingTool.Models @using AzureNamingTool.Services @using System.IO -@using AzureNamingTool.Components.Modals; +@using AzureNamingTool.Shared.Modals; @using BlazorDownloadFile @using Microsoft.AspNetCore.Components.Authorization @using System.Text.Json diff --git a/src/Pages/Error.cshtml b/src/Pages/Error.cshtml new file mode 100644 index 00000000..3f799b5d --- /dev/null +++ b/src/Pages/Error.cshtml @@ -0,0 +1,42 @@ +@page +@model AzureNamingTool.Pages.ErrorModel + + + + + + + + Error + + + + + +
+
+

Error.

+

An error occurred while processing your request.

+ + @if (Model.ShowRequestId) + { +

+ Request ID: @Model.RequestId +

+ } + +

Development Mode

+

+ Swapping to the Development environment displays detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

+
+
+ + + diff --git a/src/Pages/Error.cshtml.cs b/src/Pages/Error.cshtml.cs new file mode 100644 index 00000000..05d7b96f --- /dev/null +++ b/src/Pages/Error.cshtml.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using System.Diagnostics; + +namespace AzureNamingTool.Pages +{ + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + [IgnoreAntiforgeryToken] + public class ErrorModel : PageModel + { + public string RequestId { get; set; } = String.Empty; + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + private readonly ILogger _logger; + + public ErrorModel(ILogger logger) + { + _logger = logger; + } + + public void OnGet() + { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; + } + } +} \ No newline at end of file diff --git a/src/Components/Pages/Generate.razor b/src/Pages/Generate.razor similarity index 99% rename from src/Components/Pages/Generate.razor rename to src/Pages/Generate.razor index 3b853735..6863639e 100644 --- a/src/Components/Pages/Generate.razor +++ b/src/Pages/Generate.razor @@ -2,9 +2,9 @@ @using AzureNamingTool.Helpers @using AzureNamingTool.Models @using AzureNamingTool.Services -@using AzureNamingTool.Components.Modals; +@using AzureNamingTool.Shared.Modals; @using System.Text; -@using AzureNamingTool.Components.General; +@using AzureNamingTool.Shared.Components; @inject ILogger Logger @inject NavigationManager NavigationManager @inject StateContainer state diff --git a/src/Components/Pages/GeneratedNamesLog.razor b/src/Pages/GeneratedNamesLog.razor similarity index 97% rename from src/Components/Pages/GeneratedNamesLog.razor rename to src/Pages/GeneratedNamesLog.razor index 4c5d115c..39ac163c 100644 --- a/src/Components/Pages/GeneratedNamesLog.razor +++ b/src/Pages/GeneratedNamesLog.razor @@ -199,7 +199,6 @@ public DateTime startdate { get; set; } = DateTime.Today.AddDays(-30); public DateTime enddate { get; set; } = DateTime.Today; private string currentuser = String.Empty; - private SiteConfiguration config = ConfigurationHelper.GetConfigurationData(); protected override async Task OnAfterRenderAsync(bool firstRender) { @@ -208,11 +207,6 @@ { var result = await session.GetAsync("admin"); admin = (bool)result.Value; - if (!Convert.ToBoolean(config.GeneratedNamesLogEnabled) && !admin) - { - toastService.ShowWarning("The Generated Names Log is disabled in the site settings."); - NavigationManager.NavigateTo("/"); - } await LoadData(); duplicatenamesallowed = Convert.ToBoolean(ConfigurationHelper.GetAppSetting("DuplicateNamesAllowed")); StateHasChanged(); @@ -309,7 +303,7 @@ if (confirm) { await LogHelper.PurgeGeneratedNames(); - toastService.ShowSuccess("Generated Names Log purged!"); + toastService.ShowSuccess("Generated Log purged!"); AdminLogService.PostItem(new AdminLogMessage() { Source = currentuser, Title = "INFORMATION", Message = "Generated Names log purged." }); await LoadData(); StateHasChanged(); diff --git a/src/Components/Pages/Index.razor b/src/Pages/Index.razor similarity index 73% rename from src/Components/Pages/Index.razor rename to src/Pages/Index.razor index 4e336058..1170fb03 100644 --- a/src/Components/Pages/Index.razor +++ b/src/Pages/Index.razor @@ -15,28 +15,25 @@

Azure Naming Tool

+

- Disclaimer -
+

Disclaimer

This tool was designed using the best practices in the Azure Cloud Adoption Framework which adheres to a few rules and allows the complete customization of your naming convention. While most of the customizations can be made in your web browser, this tool also includes an API.

- For guidance on the API, review your swagger page at: swagger/index.html + For guidance on the API, review your swagger page at: @(NavigationManager.Uri)swagger/index.html

Admin

The Admin page is used to configure the Azure Naming Tool. This page is only accessible by Admin users.

- @if (Convert.ToBoolean(config.InstructionsEnabled) || admin) - { -

Instructions

-

- The Instructions page provides documentation for the site pages. Each page of the site contains a documentation link (top right) that will open contextual instructions for the current page. -

- } +

Instructions

+

+ The Instructions page provides documentation for the site pages. Each page of the site contains a documentation link (top right) that will open contextual instructions for the current page. +

Configuration

- The Configuration page provides all the data points that make up your naming convention. There are 8 standard components that may be used to name each Azure resource. The data within each of those components can be completely customized, except for the resource types. For the resource types, only the short name, optional, and excluded values may be updated. A delimiter may be selected to separate each component in your resource names. However, the delimiter will be included in a resource name if that character is allowed. The tool also supports the ability to define custom components. This allows administrators to create new components for the naming convention. Your configuration may be exported under the Global Configuration header. We recommend doing that after defining your naming convention as a backup. @*Lastly, use the Policy export feature to create an Azure Policy Definition. That can be applied to your Azure environment to enforce your naming convention.*@ + The Configuration page provides all the data points that make up your naming convention. There are 8 standard components that may be used to name each Azure resource. The data within each of those components can be completely customized, except for the resource types. For the resource types, only the short name, optional, and excluded values may be updated. A delimiter may be selected to separate each component in your resource names. However, the delimiter will be included in a resource name if that character is allowed. The tool also supports the ability to define custom components. This allows administratos to create new components for the naming convention. Your configuration may be exported under the Global Configuration header. We recommend doing that after defining your naming convention as a backup. @*Lastly, use the Policy export feature to create an Azure Policy Definition. That can be applied to your Azure environment to enforce your naming convention.*@

Reference

@@ -47,21 +44,15 @@

The Generate page provides a drop-down menu to select an Azure resource type. Once a resource is selected, the naming component options are provided. Read-only components cannot be changed, like the value for a resource type. Optional components, if unselected, will be null and not shown in the output. Required components do not allow a null value and will require a selection from the menu.

- @if (Convert.ToBoolean(config.GeneratedNamesLogEnabled) || admin) - { -

Generated Names Log

-

- The Generated Names Log contains a record of all names generated in the Azure Naming Tool. This includes the date, user, generated name, resource type, and components selected. This log can be exported to a .csv file. -

- } - @if (Convert.ToBoolean(config.InstructionsEnabled) || admin) - { -

- -

- } +

Generated Names Log

+

+ The Generated Names Log contains a record of all names generated in the Azure Naming Tool. This includes the date, user, generated name, resource type, and components selected. This log can be exported to a .csv file. +

+

+ +

@code { @@ -70,7 +61,6 @@ [CascadingParameter] public IModalService? Modal { get; set; } private bool admin; - private SiteConfiguration config = ConfigurationHelper.GetConfigurationData(); private string appversion = ConfigurationHelper.GetAssemblyVersion(); private string updateurl = "https://github.com/mspnp/AzureNamingTool/wiki/Updating"; @@ -78,11 +68,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { var resultAdmin = await session.GetAsync("admin"); - if (admin != (bool)resultAdmin.Value) - { - admin = (bool)resultAdmin.Value; - StateHasChanged(); - } + admin = (bool)resultAdmin.Value; // Determine if the version notification has been dismissed var resultNotification = await session.GetAsync("versionnotification"); bool notificationshown = resultNotification.Success ? resultNotification.Value : false; diff --git a/src/Components/Pages/Instructions.razor b/src/Pages/Instructions.razor similarity index 83% rename from src/Components/Pages/Instructions.razor rename to src/Pages/Instructions.razor index 955b1168..658cd7e2 100644 --- a/src/Components/Pages/Instructions.razor +++ b/src/Pages/Instructions.razor @@ -1,12 +1,10 @@ @page "/instructions" -@using AzureNamingTool.Components.Instructions @using AzureNamingTool.Helpers @using AzureNamingTool.Models -@using AzureNamingTool.Components.General +@using AzureNamingTool.Shared.Components +@using AzureNamingTool.Shared.Instructions @inject StateContainer state @inject ProtectedSessionStorage session -@inject IToastService toastService -@inject NavigationManager NavigationManager
@@ -34,16 +32,16 @@
-
-
+ -
- -
+ Admin Log + +
+
+ +
+
}
@@ -91,8 +89,8 @@ @code { [CascadingParameter] protected ThemeInfo? theme { get; set; } + private bool admin = false; - private SiteConfiguration config = ConfigurationHelper.GetConfigurationData(); protected override async Task OnAfterRenderAsync(bool firstRender) { @@ -100,11 +98,6 @@ { var result = await session.GetAsync("admin"); admin = (bool)result.Value; - if (!Convert.ToBoolean(config.InstructionsEnabled) && !admin) - { - toastService.ShowWarning("The Instructions page is disabled in the site settings."); - NavigationManager.NavigateTo("/"); - } StateHasChanged(); } } diff --git a/src/Components/Pages/Reference.razor b/src/Pages/Reference.razor similarity index 100% rename from src/Components/Pages/Reference.razor rename to src/Pages/Reference.razor diff --git a/src/Components/App.razor b/src/Pages/_Host.cshtml similarity index 56% rename from src/Components/App.razor rename to src/Pages/_Host.cshtml index f241777a..6787beed 100644 --- a/src/Components/App.razor +++ b/src/Pages/_Host.cshtml @@ -1,25 +1,27 @@ -@using AzureNamingTool.Helpers -@using AzureNamingTool.Models +@page "/" +@namespace AzureNamingTool.Pages +@using AzureNamingTool.Helpers; +@using AzureNamingTool.Models; @inject StateContainer state -@inject IHttpContextAccessor httpContextAccessor; +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ - //Layout = "_Layout"; + Layout = "_Layout"; // Verify the site configration files are present ConfigurationHelper.VerifyConfiguration(state); ConfigurationHelper.VerifySecurity(state); var identityProviderDetails = new IdentityProviderDetails(); - //Check if there is an HttpContext object - if (GeneralHelper.IsNotNull(httpContextAccessor)) + // Check if there is an HttpContext object + if (GeneralHelper.IsNotNull(this.HttpContext)) { - if (GeneralHelper.IsNotNull(httpContextAccessor.HttpContext!.Request.Headers)) + if (GeneralHelper.IsNotNull(this.HttpContext.Request.Headers)) { // Get the Identity provider, if using Azure App Service Authentication - if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("X-MS-CLIENT-PRINCIPAL-IDP")) + if (this.HttpContext.Request.Headers.ContainsKey("X-MS-CLIENT-PRINCIPAL-IDP")) { // Set the identity provider - identityProviderDetails.CurrentIdentityProvider = httpContextAccessor.HttpContext.Request.Headers["X-MS-CLIENT-PRINCIPAL-IDP"]!; + identityProviderDetails.CurrentIdentityProvider = this.HttpContext.Request.Headers["X-MS-CLIENT-PRINCIPAL-IDP"]!; } } @@ -28,16 +30,16 @@ { string headername = ConfigurationHelper.GetAppSetting("IdentityHeaderName", true); // Check if the IdentityHeaderName header is present - if (GeneralHelper.IsNotNull(httpContextAccessor.HttpContext)) + if(GeneralHelper.IsNotNull(this.HttpContext)) { - if (GeneralHelper.IsNotNull(httpContextAccessor.HttpContext.Request)) + if(GeneralHelper.IsNotNull(this.HttpContext.Request)) { - if (GeneralHelper.IsNotNull(httpContextAccessor.HttpContext.Request.Headers)) + if (GeneralHelper.IsNotNull(this.HttpContext.Request.Headers)) { - if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey(headername)) + if (this.HttpContext.Request.Headers.ContainsKey(headername)) { // Set the current user - identityProviderDetails.CurrentUser = httpContextAccessor.HttpContext.Request.Headers[headername]!; + identityProviderDetails.CurrentUser = this.HttpContext.Request.Headers[headername]!; } } } @@ -45,27 +47,11 @@ } } } - - - - - - - - - - - - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/src/Pages/_Layout.cshtml b/src/Pages/_Layout.cshtml new file mode 100644 index 00000000..011b2c95 --- /dev/null +++ b/src/Pages/_Layout.cshtml @@ -0,0 +1,44 @@ +@using AzureNamingTool.Models; +@using Microsoft.AspNetCore.Components.Web +@using AzureNamingTool.Helpers +@inject StateContainer state +@namespace AzureNamingTool.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers + + + + + + + + + + + + + + + + @RenderBody() + +
+ + An error has occurred. This application may no longer respond until reloaded. + + + An unhandled exception has occurred. See browser dev tools for details. + + Reload + 🗙 +
+ + + + + + diff --git a/src/Program.cs b/src/Program.cs index 1cbfff20..dff78406 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -1,30 +1,26 @@ using AzureNamingTool.Attributes; -using AzureNamingTool.Components; -using AzureNamingTool.Helpers; -using AzureNamingTool.Models; using BlazorDownloadFile; -using Blazored.Modal; using Blazored.Toast; using Microsoft.OpenApi.Models; +using Blazored.Modal; using System.Reflection; +using AzureNamingTool.Models; +using AzureNamingTool.Helpers; var builder = WebApplication.CreateBuilder(args); // Add services to the container. -builder.Services.AddRazorComponents() - .AddInteractiveServerComponents().AddHubOptions(options => - { - options.ClientTimeoutInterval = TimeSpan.FromSeconds(30); - options.EnableDetailedErrors = false; - options.HandshakeTimeout = TimeSpan.FromSeconds(15); - options.KeepAliveInterval = TimeSpan.FromSeconds(15); - options.MaximumParallelInvocationsPerClient = 1; - options.MaximumReceiveMessageSize = 102400000; - options.StreamBufferCapacity = 10; - }); - - +builder.Services.AddMvcCore().AddApiExplorer(); +builder.Services.AddRazorPages(); builder.Services.AddHealthChecks(); +if (builder.Environment.IsDevelopment()) +{ + builder.Services.AddServerSideBlazor().AddCircuitOptions(x => x.DetailedErrors = true).AddHubOptions(x => x.MaximumReceiveMessageSize = 102400000); +} +else +{ + builder.Services.AddServerSideBlazor().AddHubOptions(x => x.MaximumReceiveMessageSize = 102400000); +} builder.Services.AddBlazorDownloadFile(); builder.Services.AddBlazoredToast(); builder.Services.AddBlazoredModal(); @@ -32,7 +28,6 @@ builder.Services.AddSingleton(); -builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.OperationFilter(); @@ -47,23 +42,36 @@ c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); }); -// Add services to the container. -//builder.Services.AddMvcCore().AddApiExplorer(); -builder.Services.AddBlazorDownloadFile(); -builder.Services.AddBlazoredToast(); -builder.Services.AddBlazoredModal(); -builder.Services.AddMemoryCache(); -builder.Services.AddMvcCore().AddApiExplorer(); +builder.Services.AddCors(options => +{ + options.AddDefaultPolicy( + builder => + { + builder.WithOrigins("http://localhost:44332") + .AllowAnyHeader() + .AllowAnyMethod(); + }); +}); +builder.Services.AddMemoryCache(); var app = builder.Build(); app.MapHealthChecks("/healthcheck/ping"); // Configure the HTTP request pipeline. -if (!app.Environment.IsDevelopment()) +if (app.Environment.IsDevelopment()) { - app.UseExceptionHandler("/Error", createScopeForErrors: true); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseDeveloperExceptionPage(); + app.UseCors(x => x + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed(origin => true) // allow any origin + .AllowCredentials()); // allow credentials +} +else +{ + app.UseExceptionHandler("/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } @@ -73,12 +81,14 @@ app.UseHttpsRedirection(); app.UseStaticFiles(); -app.UseAntiforgery(); -app.MapRazorComponents() - .AddInteractiveServerRenderMode(); +app.UseRouting(); -app.UseStatusCodePagesWithRedirects("/404"); +//app.UseAuthentication(); +//app.UseAuthorization(); app.MapControllers(); +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + app.Run(); diff --git a/src/Properties/launchSettings.json b/src/Properties/launchSettings.json index 10bb4cb6..a22b73c5 100644 --- a/src/Properties/launchSettings.json +++ b/src/Properties/launchSettings.json @@ -1,49 +1,19 @@ { "profiles": { - "http": { + "AzureNamingTool": { "commandName": "Project", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "dotnetRunMessages": true, - "applicationUrl": "http://localhost:5222" - }, - "https": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "dotnetRunMessages": true, - "applicationUrl": "https://localhost:7184;http://localhost:5222" - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "applicationUrl": "https://localhost:51656;http://localhost:51657" }, "Docker": { "commandName": "Docker", "launchBrowser": true, "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", - "environmentVariables": { - "ASPNETCORE_HTTPS_PORTS": "8081", - "ASPNETCORE_HTTP_PORTS": "8080" - }, "publishAllPorts": true, "useSSL": true } - }, - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:60381", - "sslPort": 44346 - } } } \ No newline at end of file diff --git a/src/Services/AdminLogService.cs b/src/Services/AdminLogService.cs index 629db9ac..cc3f9852 100644 --- a/src/Services/AdminLogService.cs +++ b/src/Services/AdminLogService.cs @@ -1,6 +1,6 @@ using AzureNamingTool.Helpers; using AzureNamingTool.Models; -using AzureNamingTool.Components.Pages; +using AzureNamingTool.Pages; using System.Text.Json; namespace AzureNamingTool.Services diff --git a/src/Services/ImportExportService.cs b/src/Services/ImportExportService.cs index 6fb6c032..5a634d9c 100644 --- a/src/Services/ImportExportService.cs +++ b/src/Services/ImportExportService.cs @@ -110,9 +110,6 @@ public static async Task ExportConfig(bool includeadmin = false configdata.GenerationWebhook = config.GenerationWebhook; configdata.ResourceTypeEditingAllowed = config.ResourceTypeEditingAllowed; configdata.AutoIncrementResourceInstance = config.AutoIncrementResourceInstance; - configdata.InstructionsEnabled = config.InstructionsEnabled; - configdata.GeneratedNamesLogEnabled = config.GeneratedNamesLogEnabled; - configdata.LatestNewsEnabled = config.LatestNewsEnabled; // Get the security settings if (includeadmin) @@ -203,18 +200,6 @@ public static async Task PostConfig(ConfigurationData configdat { config.AutoIncrementResourceInstance = configdata.AutoIncrementResourceInstance; } - if (GeneralHelper.IsNotNull(configdata.InstructionsEnabled)) - { - config.InstructionsEnabled = configdata.InstructionsEnabled; - } - if (GeneralHelper.IsNotNull(configdata.GeneratedNamesLogEnabled)) - { - config.GeneratedNamesLogEnabled = configdata.GeneratedNamesLogEnabled; - } - if (GeneralHelper.IsNotNull(configdata.LatestNewsEnabled)) - { - config.LatestNewsEnabled = configdata.LatestNewsEnabled; - } var jsonWriteOptions = new JsonSerializerOptions() { WriteIndented = true diff --git a/src/Services/ResourceNamingRequestService.cs b/src/Services/ResourceNamingRequestService.cs index 84844382..6223b89c 100644 --- a/src/Services/ResourceNamingRequestService.cs +++ b/src/Services/ResourceNamingRequestService.cs @@ -786,33 +786,31 @@ public static async Task RequestName(ResourceNameRequest r // Check if the request contains Resource Instance is a selected componoent if (!String.IsNullOrEmpty(GeneralHelper.GetPropertyValue(request, "ResourceInstance")?.ToString())) { - // Check if the name should be auto-incremented + // CHeck if the name should be auto-incremented if (Convert.ToBoolean(ConfigurationHelper.GetAppSetting("AutoIncrementResourceInstance"))) { // Check if there was a ResourceInstance value supplied if (GeneralHelper.IsNotNull(GeneralHelper.GetPropertyValue(request, "ResourceInstance"))) { // Attempt to auto-increement the instance - // Set the original name value - string originalname = name; // Get the instance value string originalinstance = GeneralHelper.GetPropertyValue(request, "ResourceInstance")?.ToString() ?? ""; - // Determine the next instance value - string newinstance = String.Empty; - int i = 1; - while (await ConfigurationHelper.CheckIfGeneratedNameExists(name)) + // Increase the instance by 1 + string newinstance = (Convert.ToInt32(originalinstance) + 1).ToString(); + // Make sure the instance pattern matches the entered values (leading zeros) + while (newinstance.Length < originalinstance.Length) { - newinstance = (Convert.ToInt32(originalinstance) + i).ToString(); - // Make sure the instance pattern matches the entered values (leading zeros) - while (newinstance.Length < originalinstance.Length) - { - newinstance = "0" + newinstance; - } - // Replace the new instance in the original name - name = originalname.Replace(originalinstance, newinstance); - // Increase the counter - i += 1; + newinstance = "0" + newinstance; + } + // Update the generated name with the new instance + string newname = name.Replace(originalinstance, newinstance); + // Check to make sure the new name is unique + while (await ConfigurationHelper.CheckIfGeneratedNameExists(newname)) + { + newinstance = (Convert.ToInt32(newinstance) + 1).ToString(); + newname = name.Replace(originalinstance, newinstance); } + name = newname; sbMessage.Append("The resource instance has been auto-incremented to the next value."); sbMessage.Append(Environment.NewLine); } diff --git a/src/Components/General/AnchorNavigation.razor b/src/Shared/Components/AnchorNavigation.razor similarity index 100% rename from src/Components/General/AnchorNavigation.razor rename to src/Shared/Components/AnchorNavigation.razor diff --git a/src/Components/General/ExternalContent.razor b/src/Shared/Components/ExternalContent.razor similarity index 100% rename from src/Components/General/ExternalContent.razor rename to src/Shared/Components/ExternalContent.razor diff --git a/src/Components/General/LatestNews.razor b/src/Shared/Components/LatestNews.razor similarity index 100% rename from src/Components/General/LatestNews.razor rename to src/Shared/Components/LatestNews.razor diff --git a/src/Components/General/NavMenu.razor b/src/Shared/Components/NavMenu.razor similarity index 92% rename from src/Components/General/NavMenu.razor rename to src/Shared/Components/NavMenu.razor index 5da4ba12..be81f064 100644 --- a/src/Components/General/NavMenu.razor +++ b/src/Shared/Components/NavMenu.razor @@ -127,7 +127,7 @@
} - @if ((PageType.ToString() == "AzureNamingTool.Pages.Index") && (connected) && !Convert.ToBoolean(config.LatestNewsEnabled)) + @if ((PageType.ToString() == "AzureNamingTool.Pages.Index") && (connected)) {
diff --git a/src/Components/Modals/WorkingModal.razor b/src/Shared/Modals/WorkingModal.razor similarity index 100% rename from src/Components/Modals/WorkingModal.razor rename to src/Shared/Modals/WorkingModal.razor diff --git a/src/Components/_Imports.razor b/src/_Imports.razor similarity index 77% rename from src/Components/_Imports.razor rename to src/_Imports.razor index 2708462b..8bcd3380 100644 --- a/src/Components/_Imports.razor +++ b/src/_Imports.razor @@ -1,15 +1,15 @@ @using System.Net.Http -@using System.Net.Http.Json +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web -@using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using AzureNamingTool -@using AzureNamingTool.Components +@using AzureNamingTool.Shared @using Blazored.Toast @using Blazored.Toast.Services @using Blazored.Modal @using Blazored.Modal.Services -@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage; +@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage; \ No newline at end of file diff --git a/src/appsettings.Development.json b/src/appsettings.Development.json index f8063ef1..770d3e93 100644 --- a/src/appsettings.Development.json +++ b/src/appsettings.Development.json @@ -1,9 +1,9 @@ { + "DetailedErrors": true, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } - }, - "DetailedErrors": true + } } diff --git a/src/appsettings.json b/src/appsettings.json index 10f68b8c..ed8b1c30 100644 --- a/src/appsettings.json +++ b/src/appsettings.json @@ -1,9 +1,15 @@ { + "ConnectionStrings": { + "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-AzNamingTool-70EEEBD8-2ADB-4EC9-8BEF-04B30513736D;Trusted_Connection=True;MultipleActiveResultSets=true" + }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" -} + "AllowedHosts": "*", + "SALTKey": "", + "AdminPassword": "", + "APIKey": "" +} \ No newline at end of file diff --git a/src/configurationfileversions.json b/src/configurationfileversions.json index 045cc4b8..914d73bd 100644 --- a/src/configurationfileversions.json +++ b/src/configurationfileversions.json @@ -1,4 +1,4 @@ { "resourcetypes": "1.0.1", - "resourcelocations": "2.2.0" + "resourcelocations": "2.1.0" } \ No newline at end of file diff --git a/src/programsettings.json b/src/programsettings.json index 6ed0448b..60443f7b 100644 --- a/src/programsettings.json +++ b/src/programsettings.json @@ -1,5 +1,5 @@ { "FeedbackURL": "https://forms.office.com/r/M2EZLg6zKq", "latestNewsEnabled": "false", - "toolVersion":"4.0.0" + "toolVersion":"3.3.0" } diff --git a/src/repository/appsettings.json b/src/repository/appsettings.json index 27680641..5cf718e4 100644 --- a/src/repository/appsettings.json +++ b/src/repository/appsettings.json @@ -19,8 +19,5 @@ "ConnectivityCheckEnabled": "true", "ResourceTypeEditingAllowed": "false", "AutoIncrementResourceInstance": "false", - "LatestNewsEnabled": "False", - "GeneratedNamesLogEnabled": "True", - "InstructionsEnabled": "True", "IdentityHeaderName": "X-MS-CLIENT-PRINCIPAL-NAME" } \ No newline at end of file diff --git a/src/repository/resourcelocations.json b/src/repository/resourcelocations.json index 9f368de2..5f400ae6 100644 --- a/src/repository/resourcelocations.json +++ b/src/repository/resourcelocations.json @@ -2,132 +2,132 @@ { "id": 1, "name": "Australia Central", - "shortName": "auc" + "shortName": "ac" }, { "id": 2, "name": "Australia Central 2", - "shortName": "auc2" + "shortName": "ac2" }, { "id": 3, "name": "Australia East", - "shortName": "aue" + "shortName": "ae" }, { "id": 4, "name": "Australia Southeast", - "shortName": "aus" + "shortName": "as" }, { "id": 5, "name": "Brazil South", - "shortName": "brs" + "shortName": "bs2" }, { "id": 6, "name": "Brazil Southeast", - "shortName": "brse" + "shortName": "bs" }, { "id": 7, "name": "Canada Central", - "shortName": "cac" + "shortName": "cc" }, { "id": 8, "name": "Canada East", - "shortName": "cae" + "shortName": "ce" }, { "id": 9, "name": "Central India", - "shortName": "inc" + "shortName": "ci" }, { "id": 10, "name": "Central US", - "shortName": "usc" + "shortName": "cu" }, { "id": 11, "name": "China East", - "shortName": "cne" + "shortName": "ce" }, { "id": 12, "name": "China East 2", - "shortName": "cne2" + "shortName": "ce2" }, { "id": 13, "name": "China North", - "shortName": "cnn" + "shortName": "cn" }, { "id": 14, "name": "China North 2", - "shortName": "cnn2" + "shortName": "cn2" }, { "id": 15, "name": "East Asia", - "shortName": "ase" + "shortName": "ea" }, { "id": 16, "name": "East US", - "shortName": "use" + "shortName": "eu" }, { "id": 17, "name": "East US 2", - "shortName": "use2" + "shortName": "eu2" }, { "id": 18, "name": "France Central", - "shortName": "frc" + "shortName": "fc" }, { "id": 19, "name": "France South", - "shortName": "frs" + "shortName": "fs" }, { "id": 20, "name": "Germany North", - "shortName": "den" + "shortName": "gn" }, { "id": 21, "name": "Germany West Central", - "shortName": "dewc" + "shortName": "gwc" }, { "id": 22, "name": "Japan East", - "shortName": "jpe" + "shortName": "je" }, { "id": 23, "name": "Japan West", - "shortName": "jpw" + "shortName": "jw" }, { "id": 24, "name": "Jio India West", - "shortName": "injw" + "shortName": "jiw" }, { "id": 25, "name": "Korea Central", - "shortName": "krc" + "shortName": "kc" }, { "id": 26, "name": "Korea South", - "shortName": "krs" + "shortName": "ks" }, { "id": 27, @@ -137,152 +137,152 @@ { "id": 28, "name": "North Central US", - "shortName": "usnc" + "shortName": "ncu" }, { "id": 29, "name": "North Europe", - "shortName": "eun" + "shortName": "ne2" }, { "id": 30, "name": "Norway East", - "shortName": "noe" + "shortName": "ne" }, { "id": 31, "name": "Norway West", - "shortName": "now" + "shortName": "nw" }, { "id": 32, "name": "South Africa North", - "shortName": "zan" + "shortName": "san" }, { "id": 33, "name": "South Africa West", - "shortName": "zaw" + "shortName": "saw" }, { "id": 34, "name": "South Central US", - "shortName": "ussc" + "shortName": "scu" }, { "id": 35, "name": "South India", - "shortName": "ins" + "shortName": "si" }, { "id": 36, "name": "Southeast Asia", - "shortName": "asse" + "shortName": "sa" }, { "id": 37, "name": "Switzerland North", - "shortName": "chn" + "shortName": "sn" }, { "id": 38, "name": "Switzerland West", - "shortName": "chw" + "shortName": "sw" }, { "id": 39, "name": "UAE Central", - "shortName": "aec" + "shortName": "uc" }, { "id": 40, "name": "UAE North", - "shortName": "aen" + "shortName": "un" }, { "id": 41, "name": "UK South", - "shortName": "uks" + "shortName": "us" }, { "id": 42, "name": "UK West", - "shortName": "ukw" + "shortName": "uw" }, { "id": 43, "name": "USDoD Central", - "shortName": "dodc" + "shortName": "uc" }, { "id": 44, "name": "USDoD East", - "shortName": "dode" + "shortName": "ue" }, { "id": 45, "name": "USGov Arizona", - "shortName": "az" + "shortName": "ua" }, { "id": 46, "name": "USGov Iowa", - "shortName": "ia" + "shortName": "ui" }, { "id": 47, "name": "USGov Texas", - "shortName": "tx" + "shortName": "ut" }, { "id": 48, "name": "USGov Virginia", - "shortName": "va" + "shortName": "uv" }, { "id": 49, "name": "West Central US", - "shortName": "uswc" + "shortName": "wcu" }, { "id": 50, "name": "West Europe", - "shortName": "euw" + "shortName": "we" }, { "id": 51, "name": "West India", - "shortName": "inw" + "shortName": "wi" }, { "id": 52, "name": "West US", - "shortName": "usw" + "shortName": "wu" }, { "id": 53, "name": "West US 2", - "shortName": "usw2" + "shortName": "wu2" }, { "id": 54, "name": "West US 3", - "shortName": "usw3" + "shortName": "wu3" }, { "id": 55, "name": "Sweden Central", - "shortName": "sec" + "shortName": "swc" }, { "id": 56, "name": "Sweden South", - "shortName": "ses" + "shortName": "sws" }, { "id": 57, "name": "Poland Central", - "shortName": "plc" + "shortName": "pol" }, { "id": 58, @@ -297,36 +297,16 @@ { "id": 60, "name": "Israel Central", - "shortName": "ilc" + "shortName": "isc" }, { "id": 61, "name": "China North 3", - "shortName": "cnn3" + "shortName": "cn3" }, { "id": 62, "name": "Jio India Central", - "shortName": "injc" - }, - { - "id": 63, - "name": "US Nat East", - "shortName": "east" - }, - { - "id": 64, - "name": "US Nat West", - "shortName": "west" - }, - { - "id": 65, - "name": "US Sec East", - "shortName": "east" - }, - { - "id": 66, - "name": "US Sec West", - "shortName": "west" + "shortName": "jic" } ] diff --git a/src/wwwroot/app.css b/src/wwwroot/app.css deleted file mode 100644 index d6689573..00000000 --- a/src/wwwroot/app.css +++ /dev/null @@ -1,178 +0,0 @@ -@import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); - -html, body { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; -} - -h1:focus { - outline: none; -} - -a, .btn-link { - color: #6a5eff; -} - -.btn-primary { - color: #fff; - background-color: #1b6ec2; - border-color: #1861ac; -} - -.content { - padding-top: 1.1rem; -} - -.valid.modified:not([type=checkbox]) { - outline: 1px solid #26b050; -} - -.invalid { - outline: 1px solid red; -} - -.validation-message { - color: red; -} - -.warning-message { - color: red; - font-weight: bold; -} - -#blazor-error-ui { - background: lightyellow; - bottom: 0; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); - display: none; - left: 0; - padding: 0.6rem 1.25rem 0.7rem 1.25rem; - position: fixed; - width: 100%; - z-index: 1000; -} - - #blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; - } - -.blazor-error-boundary { - background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; - padding: 1rem 1rem 1rem 3.7rem; - color: white; -} - - .blazor-error-boundary::after { - content: "An error has occurred." - } - -.blazored-toast-container{ - z-index:99999 !important; -} - -#btnScrollToTop { - position: fixed; /* Fixed/sticky position */ - bottom: 20px; /* Place the button at the bottom of the page */ - right: 30px; /* Place the button 30px from the right */ - z-index: 99; /* Make sure it does not overlap */ -} - -.text-white, .link-light, .nav-link, .nav-item { - color: #ffffff !important; -} - -.text-dark, .link-dark { - color: #000000 !important; -} - - -.nav-item a.active, .nav-item a:hover, .nav-link a.active, .nav-link a:hover { - background-color: rgba(0,0,0,0.15) !important; - color: white; -} - -.bg-navcolor { - background-color: #004494; -} - -.bg-dark{ - background: #000000 !important; -} - -/* The switch - the box around the slider */ -.switch { - position: relative; - display: inline-block; - width: 60px; - height: 34px; -} - - /* Hide default HTML checkbox */ - .switch input { - opacity: 0; - width: 0; - height: 0; - } - -/* The slider */ -.slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #ccc; - -webkit-transition: .4s; - transition: .4s; -} - - .slider:before { - position: absolute; - content: ""; - height: 26px; - width: 26px; - left: 4px; - bottom: 4px; - background-color: white; - -webkit-transition: .4s; - transition: .4s; - } - -input:checked + .slider { - background-color: #4C4E52; -} - -input:focus + .slider { - box-shadow: 0 0 1px #2196F3; -} - -input:checked + .slider:before { - -webkit-transform: translateX(26px); - -ms-transform: translateX(26px); - transform: translateX(26px); -} - -/* Rounded sliders */ -.slider.round { - border-radius: 34px; -} - - .slider.round:before { - border-radius: 50%; - } - -.disabled-text { - color: #A9A9A9; -} - -.btn-dummy { - pointer-events: none; - cursor: not-allowed; -} - -.blazored-toast-message { - hyphens:none !important; -} \ No newline at end of file diff --git a/src/wwwroot/favicon.png b/src/wwwroot/favicon.png deleted file mode 100644 index 8422b596..00000000 Binary files a/src/wwwroot/favicon.png and /dev/null differ