more project files - working on cart functionality

This commit is contained in:
Frede Hundewadt 2022-03-14 17:59:22 +01:00
parent 397ff94c5b
commit 690712a7ca
127 changed files with 1304 additions and 1338 deletions

52
.gitignore vendored
View file

@ -1,4 +1,4 @@
*/**/appsettings.json appsettings.json
# ---> JetBrains # ---> JetBrains
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
@ -63,9 +63,6 @@ atlassian-ide-plugin.xml
# Cursive Clojure plugin # Cursive Clojure plugin
.idea/replstate.xml .idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ) # Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml com_crashlytics_export_strings.xml
crashlytics.properties crashlytics.properties
@ -82,7 +79,7 @@ fabric.properties
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.
## ##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files # User-specific files
*.rsuser *.rsuser
@ -287,6 +284,9 @@ PublishScripts/
*.nuget.props *.nuget.props
*.nuget.targets *.nuget.targets
# Nuget personal access tokens and Credentials
nuget.config
# Microsoft Azure Build Output # Microsoft Azure Build Output
csx/ csx/
*.build.csdef *.build.csdef
@ -375,17 +375,6 @@ node_modules/
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw *.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output # Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts **/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts
@ -442,9 +431,6 @@ ASALocalRun/
# Local History for Visual Studio # Local History for Visual Studio
.localhistory/ .localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database # BeatPulse healthcheck temp database
healthchecksdb healthchecksdb
@ -476,32 +462,6 @@ FodyWeavers.xsd
*.msp *.msp
# JetBrains Rider # JetBrains Rider
.idea/
*.sln.iml *.sln.iml
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# ---> AL
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
*.app
.snapshots/*

View file

@ -3,9 +3,9 @@
/workspace.xml /workspace.xml
# Rider ignored files # Rider ignored files
/modules.xml /modules.xml
/contentModel.xml
/projectSettingsUpdater.xml /projectSettingsUpdater.xml
/.idea.Wonky.Client.iml /.idea.Wonky.Client.iml
/contentModel.xml
# Editor-based HTTP Client requests # Editor-based HTTP Client requests
/httpRequests/ /httpRequests/
# Datasource local storage ignored files # Datasource local storage ignored files

View file

@ -1,3 +1,2 @@
# Wonky.Client # Wonky Client
![](./Wonky.Client/wwwroot/wonky-logo.png)

View file

@ -1,34 +1,31 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 17
VisualStudioVersion = 16.0.30114.105 VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wonky.Client", "Wonky.Client\Wonky.Client.csproj", "{A001767F-6CA1-428E-938A-EA491A778D3E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wonky.Client", "Wonky.Client\Wonky.Client.csproj", "{6187227B-D451-4817-B535-743B14E3111D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wonky.Entity", "..\Wonky.Entity\Wonky.Entity\Wonky.Entity.csproj", "{39D1D838-9D6C-41AB-8A77-ABF4ECC35402}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wonky.Entity", "Wonky.Entity\Wonky.Entity.csproj", "{CF421FF4-0AE4-4B8A-997E-C2FD8DC9349F}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wonky.Virk", "..\Wonky.Virk\Wonky.Virk\Wonky.Virk.csproj", "{69A68DBC-1CAF-496D-B8FE-7FB82E7FE0E9}" Global
EndProject GlobalSection(SolutionConfigurationPlatforms) = preSolution
Global Debug|Any CPU = Debug|Any CPU
GlobalSection(SolutionConfigurationPlatforms) = preSolution Release|Any CPU = Release|Any CPU
Debug|Any CPU = Debug|Any CPU EndGlobalSection
Release|Any CPU = Release|Any CPU GlobalSection(ProjectConfigurationPlatforms) = postSolution
EndGlobalSection {6187227B-D451-4817-B535-743B14E3111D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
GlobalSection(SolutionProperties) = preSolution {6187227B-D451-4817-B535-743B14E3111D}.Debug|Any CPU.Build.0 = Debug|Any CPU
HideSolutionNode = FALSE {6187227B-D451-4817-B535-743B14E3111D}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection {6187227B-D451-4817-B535-743B14E3111D}.Release|Any CPU.Build.0 = Release|Any CPU
GlobalSection(ProjectConfigurationPlatforms) = postSolution {CF421FF4-0AE4-4B8A-997E-C2FD8DC9349F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A001767F-6CA1-428E-938A-EA491A778D3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CF421FF4-0AE4-4B8A-997E-C2FD8DC9349F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A001767F-6CA1-428E-938A-EA491A778D3E}.Debug|Any CPU.Build.0 = Debug|Any CPU {CF421FF4-0AE4-4B8A-997E-C2FD8DC9349F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A001767F-6CA1-428E-938A-EA491A778D3E}.Release|Any CPU.ActiveCfg = Release|Any CPU {CF421FF4-0AE4-4B8A-997E-C2FD8DC9349F}.Release|Any CPU.Build.0 = Release|Any CPU
{A001767F-6CA1-428E-938A-EA491A778D3E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection
{39D1D838-9D6C-41AB-8A77-ABF4ECC35402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU GlobalSection(SolutionProperties) = preSolution
{39D1D838-9D6C-41AB-8A77-ABF4ECC35402}.Debug|Any CPU.Build.0 = Debug|Any CPU HideSolutionNode = FALSE
{39D1D838-9D6C-41AB-8A77-ABF4ECC35402}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection
{39D1D838-9D6C-41AB-8A77-ABF4ECC35402}.Release|Any CPU.Build.0 = Release|Any CPU GlobalSection(ExtensibilityGlobals) = postSolution
{69A68DBC-1CAF-496D-B8FE-7FB82E7FE0E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU SolutionGuid = {3FB8FD1A-6DA1-4063-816A-755FD5A93F8E}
{69A68DBC-1CAF-496D-B8FE-7FB82E7FE0E9}.Debug|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection
{69A68DBC-1CAF-496D-B8FE-7FB82E7FE0E9}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobal
{69A68DBC-1CAF-496D-B8FE-7FB82E7FE0E9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View file

@ -1,5 +1,4 @@
@using Wonky.Client.Shared @*
@*
// Copyright (C) 2022 FCS Frede's Computer Services. // Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as // it under the terms of the Affero GNU General Public License as
@ -15,21 +14,23 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
*@ *@
<CascadingAuthenticationState> <CascadingAuthenticationState>
<Router AppAssembly="@typeof(App).Assembly"> <CartStateProvider>
<Found Context="routeData"> <Router AppAssembly="@typeof(App).Assembly">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> <Found Context="routeData">
<Authorizing> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<text>Checker autorisation ...</text> <Authorizing>
</Authorizing> <text>Checker autorisation ...</text>
</AuthorizeRouteView> </Authorizing>
<FocusOnNavigate RouteData="@routeData" Selector="h1" /> </AuthorizeRouteView>
</Found> <FocusOnNavigate RouteData="@routeData" Selector="h1"/>
<NotFound> </Found>
<LayoutView Layout="@typeof(MainLayout)"> <NotFound>
<Page404 /> <LayoutView Layout="@typeof(MainLayout)">
</LayoutView> <Page404/>
</NotFound> </LayoutView>
</Router> </NotFound>
</CascadingAuthenticationState> </Router>
</CartStateProvider>
</CascadingAuthenticationState>

View file

@ -3,6 +3,7 @@ namespace Wonky.Client;
public class AppId public class AppId
{ {
public string Version { get; set; } = "0.2.1"; public string Version { get; set; } = "0.2.1";
public string Name { get; set; } = "Wonky Client"; public string Name { get; set; } = "Inno Client";
public bool IsBeta { get; set; } = false; public bool IsBeta { get; set; } = false;
} }

View file

@ -13,8 +13,12 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;

View file

@ -0,0 +1,4 @@
a, a:link, a:hover, a:visited, a:active {
color: #ffaa00;
}

View file

@ -0,0 +1,25 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
<label for="search-column" class="form-label">Søge kolonne</label>
<select id="search-column" class="form-control" @bind-value="@SearchColumn" @bind-value:event="oninput" @onchange="ApplyFilter">
<option value="name">Navn</option>
<option value="zipCode">Postnr</option>
<option value="city">Bynavn</option>
<option value="account">Konto</option>
<option value="phone">Telefon</option>
</select>

View file

@ -19,15 +19,14 @@ using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
public partial class CompanySearchField public partial class CompanySearchColumn
{ {
[Parameter] [Parameter]
public EventCallback<string> OnFilterChanged { get; set; } public EventCallback<string> OnFilterChanged { get; set; }
private string SearchColumn { get; set; } = "name";
private async Task ApplyFilter(ChangeEventArgs eventArgs) private async Task ApplyFilter(ChangeEventArgs eventArgs)
{ {
if (eventArgs?.Value?.ToString() == "name") await OnFilterChanged.InvokeAsync(SearchColumn);
return;
await OnFilterChanged.InvokeAsync(eventArgs?.Value?.ToString());
} }
} }

View file

@ -1,3 +0,0 @@
.search-field {
margin-bottom: 10px;
}

View file

@ -1,25 +0,0 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
<section>
<select class="form-control" @onchange="ApplySort">
<option value="-1">- sortering -</option>
<option value="name">Navn</option>
<option value="account">Konto</option>
<option value="city">Bynavn</option>
</select>
</section>

View file

@ -15,11 +15,9 @@
// //
*@ *@
<div class="search-field"> <label for="sort-column" class="form-label">Sortering</label>
<select class="form-control" @onchange="ApplyFilter"> <select id="sort-column" class="form-control" @bind-value="@SortColumn" @bind-value:event="oninput" @onchange="ApplySort">
<option value="name" selected>Navn</option> <option value="name">Navn</option>
<option value="zipCode">Postnr</option> <option value="account">Konto</option>
<option value="city">Bynavn</option> <option value="city">Bynavn</option>
<option value="account">Konto</option> </select>
</select>
</div>

View file

@ -19,16 +19,15 @@ using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Components namespace Wonky.Client.Components
{ {
public partial class CompanySort public partial class CompanySortColumn
{ {
[Parameter] [Parameter]
public EventCallback<string> OnSortChanged { get; set; } public EventCallback<string> OnSortChanged { get; set; }
private string SortColumn { get; set; } = "name";
private async Task ApplySort(ChangeEventArgs eventArgs) private async Task ApplySort(ChangeEventArgs eventArgs)
{ {
if (eventArgs?.Value?.ToString() == "-1") await OnSortChanged.InvokeAsync(SortColumn);
return;
await OnSortChanged.InvokeAsync(eventArgs?.Value?.ToString());
} }
} }
} }

View file

@ -14,6 +14,8 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
*@ *@
@using Wonky.Client.Components;
@if (Companies.Any()) @if (Companies.Any())
{ {
<CompanyListHeader /> <CompanyListHeader />

View file

@ -1,43 +0,0 @@
@using Microsoft.Extensions.Logging
@implements IDisposable
<h1>@Title</h1>
<p>Current count: @CurrentCount</p>
@code {
[Parameter] public string Title { get; set; }
[Parameter] public int CurrentCount { get; set; }
[Inject] public ILogger<CounterPrint> Logger { get; set; }
protected override void OnInitialized()
{
Logger.Log(LogLevel.Information,$"OnInitialized => Title: {Title}, CurrentCount: {CurrentCount}");
}
protected override void OnParametersSet()
{
Logger.Log(LogLevel.Information,$"OnParameterSet => Title: {Title}, CurrentCount: {CurrentCount}");
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
Logger.Log(LogLevel.Information,"This is the first render of the component");
}
}
protected override bool ShouldRender()
{
return true;
}
public void Dispose()
{
Logger.Log(LogLevel.Information,"Component removed from the parnet's render tree.");
}
}

View file

@ -15,5 +15,8 @@
// //
*@ *@
<PageTitle>Forside</PageTitle> <PageTitle>Innotec</PageTitle>
<h1>@Title</h1>
<div class="img-fluid text-center">
<img src="wonky-logo.png" alt="Wonky Logo"/>
</div>

View file

@ -20,8 +20,6 @@ namespace Wonky.Client.Components
{ {
public partial class Home public partial class Home
{ {
[Parameter] public string Title { get; set; } = "Hej"; [Parameter] public RenderFragment? LoginContent { get; set; }
[Parameter] public RenderFragment? LoginContent { get; set; }
} }
} }

View file

@ -15,14 +15,15 @@
// //
*@ *@
<div class="group-filter"> <section>
<select class="form-control" @onchange="ApplyGroupFilter"> <label for="group-column" class="form-label">Varegruppe</label>
<option value="-1">standard</option> <select id="group-column" class="form-control" @bind-value="@GroupFilter" @bind-value:event="oninput" @onchange="ApplyGroupFilter">
<option value="1">Lim/Sealer/Rep</option> <option value="all">Alle</option>
<option value="2">Maling/Primer</option> <option value="1">Lim / Sealer / Rep</option>
<option value="2">Maling / Primer</option>
<option value="3">Smøremidler</option> <option value="3">Smøremidler</option>
<option value="4">Polish/Cleaner</option> <option value="4">Polish / Cleaner</option>
<option value="5">Tape</option> <option value="5">Tape</option>
<option value="6">Diverse</option> <option value="6">Diverse</option>
</select> </select>
</div> </section>

View file

@ -13,18 +13,19 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
public partial class SalesItemGroupFilter public partial class ItemGroupFilter
{ {
[Parameter] public EventCallback<string> OnGroupFilterChanged { get; set; } [Parameter] public EventCallback<string> OnGroupFilterChanged { get; set; }
private string GroupFilter { get; set; } = "all";
private async Task ApplyGroupFilter(ChangeEventArgs eventArgs) private async Task ApplyGroupFilter(ChangeEventArgs eventArgs)
{ {
if (eventArgs?.Value?.ToString() == "-1") if (GroupFilter == "all")
return; GroupFilter = "";
await OnGroupFilterChanged.InvokeAsync(eventArgs?.Value?.ToString()); await OnGroupFilterChanged.InvokeAsync(GroupFilter);
} }
} }

View file

@ -15,11 +15,12 @@
// //
*@ *@
<div class="search-field"> <label for="search-column" class="form-label">Søge kolonne</label>
<select class="form-control" @onchange="ApplySearchField"> <select id="search-column" class="form-control"
<option value="-1">standard</option> @bind-value="@SearchColumn"
<option value="name" selected>Navn</option> @bind-value:event="oninput"
<option value="sku">Varenr</option> @onchange="ApplySearchColumn">
<option value="shortName">Fork</option> <option value="name">Navn</option>
</select> <option value="sku">Varenr</option>
</div> <option value="shortName">Fork</option>
</select>

View file

@ -17,14 +17,12 @@ using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
public partial class SalesItemSearchField public partial class ItemSearchColumn
{ {
[Parameter] public EventCallback<string> OnSearchFieldChanged { get; set; } [Parameter] public EventCallback<string> OnSearchColumnChanged { get; set; }
private string SearchColumn { get; set; } = "name";
private async Task ApplySearchField(ChangeEventArgs eventArgs) private async Task ApplySearchColumn(ChangeEventArgs eventArgs)
{ {
if (eventArgs?.Value?.ToString() == "-1") await OnSearchColumnChanged.InvokeAsync(SearchColumn);
return; }
await OnSearchFieldChanged.InvokeAsync(eventArgs?.Value?.ToString());
}
} }

View file

@ -15,10 +15,8 @@
// //
*@ *@
<section> <label for="order-by" class="form-label">Sortering</label>
<select class="form-control" @onchange="ApplySort"> <select id="order-by" class="form-control" @bind-value="@SortColumn" @bind-value:event="oninput" @onchange="ApplySortColumn">
<option value="-1">standard</option> <option value="name">Varenavn</option>
<option value="itemName">Varenavn</option> <option value="sku">Varenr</option>
<option value="sku">Varenr</option> </select>
</select>
</section>

View file

@ -17,15 +17,14 @@ using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
public partial class SalesItemSort public partial class ItemSortColumn
{ {
[Parameter] [Parameter]
public EventCallback<string> OnSortFieldChanged { get; set; } public EventCallback<string> OnSortColumnChanged { get; set; }
private async Task ApplySort(ChangeEventArgs eventArgs) private string SortColumn { get; set; } = "name";
private async Task ApplySortColumn(ChangeEventArgs eventArgs)
{ {
if (eventArgs?.Value?.ToString() == "-1") await OnSortColumnChanged.InvokeAsync(SortColumn);
return; }
await OnSortFieldChanged.InvokeAsync(eventArgs?.Value?.ToString());
}
} }

View file

@ -30,10 +30,10 @@
{ {
<tr> <tr>
<td> <td>
@salesItem.ItemName @salesItem.Name
</td> </td>
<td> <td>
@salesItem.ItemNumber @salesItem.Sku
</td> </td>
<td> <td>
<ul class="list-group"> <ul class="list-group">

View file

@ -19,7 +19,7 @@ using Wonky.Entity.DTO;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
public partial class SalesItemTable public partial class ItemTable
{ {
[Parameter] public List<SalesItemDto> SalesItems { get; set; } = new(); [Parameter] public List<SalesItemDto> SalesItems { get; set; } = new();
[Parameter] public string PoDraftAccount { get; set; } = ""; [Parameter] public string PoDraftAccount { get; set; } = "";

View file

@ -27,10 +27,10 @@
<strong>CVR status @CurrentState</strong> <strong>CVR status @CurrentState</strong>
</div> </div>
<ul class="list-group list-group-flush small"> <ul class="list-group list-group-flush small">
<li class="list-group-item">@(string.IsNullOrEmpty(VirkRegInfo.Name) ? "" : VirkRegInfo.Name)</li> <li class="list-group-item">@VirkRegInfo.Name</li>
<li class="list-group-item">@(string.IsNullOrEmpty(VirkRegInfo.CoName) ? "" : VirkRegInfo.CoName)</li> <li class="list-group-item">@VirkRegInfo.CoName</li>
<li class="list-group-item">@(string.IsNullOrEmpty(VirkRegInfo.Address) ? "" : VirkRegInfo.Address)</li> <li class="list-group-item">@VirkRegInfo.Address</li>
<li class="list-group-item">@(string.IsNullOrEmpty(VirkRegInfo.ZipCode) ? "" : VirkRegInfo.ZipCode) @(string.IsNullOrEmpty(VirkRegInfo.City) ? "" : VirkRegInfo.City)</li> <li class="list-group-item">@VirkRegInfo.ZipCode @VirkRegInfo.City</li>
</ul> </ul>
</div> </div>
</div> </div>

View file

@ -17,7 +17,6 @@ using Microsoft.AspNetCore.Components;
using Wonky.Client.Services; using Wonky.Client.Services;
using Wonky.Entity.Models; using Wonky.Entity.Models;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
using Wonky.Virk.Services;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
@ -30,14 +29,14 @@ public partial class RegInfoCompany
private VirkRegInfo VirkRegInfo { get; set; } = new(); private VirkRegInfo VirkRegInfo { get; set; } = new();
private bool HideMe = true; private bool HideMe = true;
private bool CvrInvalid => string.IsNullOrEmpty(VatNumber); private bool CvrInvalid => string.IsNullOrEmpty(VatNumber);
private VirkParams _virkParams = new(); private VirkParams _VirkParams = new();
private string CurrentState = "UKENDT"; private string CurrentState = "UKENDT";
private async Task GetCvrData() private async Task GetCvrData()
{ {
_virkParams.VatNumber = VatNumber; _VirkParams.VatNumber = VatNumber;
if (string.IsNullOrWhiteSpace(VirkRegInfo.VatNumber)) if (string.IsNullOrWhiteSpace(VirkRegInfo.VatNumber))
{ {
var result = await VirkRegistryService.QueryVirkRegistry(_virkParams); var result = await VirkRegistryService.QueryVirkRegistry(_VirkParams);
if (result.Any()) if (result.Any())
{ {
CurrentState = VirkRegInfo.States[^1].State; CurrentState = VirkRegInfo.States[^1].State;

View file

@ -14,6 +14,8 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
*@ *@
@using Microsoft.VisualBasic
@using System.Diagnostics
<EditForm Model="AdrContext" OnValidSubmit="FetchAddressData"> <EditForm Model="AdrContext" OnValidSubmit="FetchAddressData">
<div class="row mb-3"> <div class="row mb-3">
<DataAnnotationsValidator/> <DataAnnotationsValidator/>

View file

@ -20,7 +20,6 @@ using Wonky.Client.HttpInterceptors;
using Wonky.Client.Services; using Wonky.Client.Services;
using Wonky.Entity.Models; using Wonky.Entity.Models;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
using Wonky.Virk.Services;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;

View file

@ -20,7 +20,6 @@ using Wonky.Client.HttpInterceptors;
using Wonky.Client.Services; using Wonky.Client.Services;
using Wonky.Entity.Models; using Wonky.Entity.Models;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
using Wonky.Virk.Services;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;

View file

@ -18,7 +18,6 @@ using Microsoft.AspNetCore.Components;
using Wonky.Client.Services; using Wonky.Client.Services;
using Wonky.Entity.Models; using Wonky.Entity.Models;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
using Wonky.Virk.Services;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
@ -29,15 +28,15 @@ public partial class RegStateVatNumber
[Parameter] public string VatNumber { get; set; } = ""; [Parameter] public string VatNumber { get; set; } = "";
private VirkRegInfo VirkRegInfo { get; set; } = new(); private VirkRegInfo VirkRegInfo { get; set; } = new();
private readonly VirkParams _virkParams = new(); private readonly VirkParams _VirkParams = new();
private string CurrentRegState = "UKENDT"; private string CurrentRegState = "UKENDT";
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
_virkParams.VatNumber = VatNumber; _VirkParams.VatNumber = VatNumber;
if (!string.IsNullOrEmpty(VatNumber)) if (!string.IsNullOrEmpty(VatNumber))
{ {
var result = await VirkRegistryService.QueryVirkRegistry(_virkParams); var result = await VirkRegistryService.QueryVirkRegistry(_VirkParams);
VirkRegInfo = result.Any() ? result[0] : new VirkRegInfo(); VirkRegInfo = result.Any() ? result[0] : new VirkRegInfo();
if (VirkRegInfo.States.Any()) if (VirkRegInfo.States.Any())
CurrentRegState = VirkRegInfo.States[^1].State; CurrentRegState = VirkRegInfo.States[^1].State;

View file

@ -1,3 +0,0 @@
.group-field {
margin-bottom: 10px;
}

View file

@ -1,3 +0,0 @@
.search-field {
margin-bottom: 10px;
}

View file

@ -15,8 +15,7 @@
// //
*@ *@
<div class="search-input"> <label for="search-input" class="form-label">Søgetekst</label>
<input type="text" class="form-control" placeholder="Tekst ..." <input id="search-input" type="text" class="form-control" placeholder="Søg ..."
@bind-value="@SearchTerm" @bind-value:event="oninput" @bind-value="@SearchTerm" @bind-value:event="oninput"
@onkeyup="SearchChanged"/> @onkeyup="SearchChanged"/>
</div>

View file

@ -22,9 +22,8 @@ namespace Wonky.Client.Components
public partial class SearchPhrase public partial class SearchPhrase
{ {
private Timer _timer = new(); private Timer _timer = new();
public string SearchTerm { get; set; } = ""; private string SearchTerm { get; set; } = "";
[Parameter] public EventCallback<string> OnSearchPhraseChanged { get; set; }
[Parameter] public EventCallback<string> OnSearchChanged { get; set; }
private void SearchChanged() private void SearchChanged()
{ {
@ -36,7 +35,7 @@ namespace Wonky.Client.Components
private void OnTimerElapsed(object? sender, ElapsedEventArgs e) private void OnTimerElapsed(object? sender, ElapsedEventArgs e)
{ {
OnSearchChanged.InvokeAsync(SearchTerm); OnSearchPhraseChanged.InvokeAsync(SearchTerm);
_timer.Enabled = false; _timer.Enabled = false;
_timer.Dispose(); _timer.Dispose();
} }

View file

@ -1,3 +0,0 @@
.search-input {
margin-bottom: 10px;
}

View file

@ -1,56 +0,0 @@
using System.Security.Claims;
using System.Text.Json;
namespace Wonky.Client.Features;
public class JwtParser
{
public static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
{
var claims = new List<Claim>();
var payload = jwt.Split('.')[1];
var jsonBytes = ParseBase64WithoutPadding(payload);
var keyValuePairs = JsonSerializer
.Deserialize<Dictionary<string, object>>(jsonBytes);
ExtractRolesFromJwt(claims, keyValuePairs);
claims.AddRange(keyValuePairs!
.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString())));
return claims;
}
private static void ExtractRolesFromJwt(List<Claim> claims,
Dictionary<string, object>? keyValuePairs)
{
keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);
if (roles == null) return;
var parsedRoles = roles.ToString().Trim()
.TrimStart('[').TrimEnd(']').Split(',');
if (parsedRoles.Length > 1)
{
claims.AddRange(parsedRoles
.Select(parsedRole => new Claim(ClaimTypes.Role, parsedRole.Trim('"'))));
}
else
{
claims.Add(new Claim(ClaimTypes.Role, parsedRoles[0]));
}
keyValuePairs.Remove(ClaimTypes.Role);
}
private static byte[] ParseBase64WithoutPadding(string base64)
{
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return Convert.FromBase64String(base64);
}
}

View file

@ -13,6 +13,7 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Collections.Generic;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
namespace Wonky.Client.Features; namespace Wonky.Client.Features;

View file

@ -13,6 +13,8 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System;
namespace Wonky.Client.Helpers; namespace Wonky.Client.Helpers;
public static class Utils public static class Utils

View file

@ -15,10 +15,12 @@
using System.Net; using System.Net;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Threading.Tasks;
using Blazored.Toast.Services; using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Toolbelt.Blazor;
using Wonky.Client.Services; using Wonky.Client.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
using Toolbelt.Blazor;
namespace Wonky.Client.HttpInterceptors namespace Wonky.Client.HttpInterceptors
{ {

View file

@ -13,6 +13,7 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System;
using System.Runtime.Serialization; using System.Runtime.Serialization;
namespace Wonky.Client.HttpInterceptors namespace Wonky.Client.HttpInterceptors

View file

@ -13,12 +13,17 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks;
using Wonky.Client.Features;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Wonky.Client.Features;
using Wonky.Entity.Configuration; using Wonky.Entity.Configuration;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
@ -55,12 +60,12 @@ public class CompanyHttpRepository : ICompanyHttpRepository
{ {
["pageNumber"] = pagingParameters.PageNumber.ToString(), ["pageNumber"] = pagingParameters.PageNumber.ToString(),
["pageSize"] = pagingParameters.PageSize.ToString(), ["pageSize"] = pagingParameters.PageSize.ToString(),
["searchTerm"] = string.IsNullOrEmpty(pagingParameters.SearchTerm) ? "" : pagingParameters.SearchTerm, ["searchTerm"] = pagingParameters.SearchTerm,
["orderBy"] = string.IsNullOrEmpty(pagingParameters.OrderBy) ? "" : pagingParameters.OrderBy, ["searchColumn"] = pagingParameters.SearchColumn,
["searchColumn"] = string.IsNullOrEmpty(pagingParameters.SearchColumn) ? "" : pagingParameters.SearchColumn ["orderBy"] = pagingParameters.OrderBy
}; };
var response = await _client var response = await _client
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.CrmCompanies}", queryString)); .GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.CrmCompanies}/page", queryString));
var content = await response.Content.ReadAsStringAsync(); var content = await response.Content.ReadAsStringAsync();

View file

@ -13,6 +13,7 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Threading.Tasks;
using Wonky.Client.Features; using Wonky.Client.Features;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;

View file

@ -1,29 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Wonky.Client.Features;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
namespace Wonky.Client.HttpRepository;
public interface IKrvProductHttpRepository
{
Task<PagingResponse<KrvProductDto>> GetProducts(PagingParams pagingParameters);
Task<KrvProductDto> GetProduct(string productId);
Task CreateProduct(KrvProductDto product);
Task<string> UploadImage(MultipartFormDataContent content, string productId);
Task UpdateProduct(KrvProductDto product);
}

View file

@ -1,29 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Wonky.Client.Features;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
namespace Wonky.Client.HttpRepository;
public interface IKrvVariantHttpRepository
{
Task<PagingResponse<KrvVariantDto>> GetVariants(PagingParams pagingParameters);
Task<KrvVariantDto> GetVariant(string variantId);
Task CreateVariant(KrvVariantDto variantDto);
Task<string> UploadImage(MultipartFormDataContent content, string variantId);
Task UpdateVariant(KrvVariantDto variant);
}

View file

@ -13,6 +13,7 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Threading.Tasks;
using Wonky.Client.Features; using Wonky.Client.Features;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;

View file

@ -1,108 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options;
using Wonky.Client.Features;
using Wonky.Entity.Configuration;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
namespace Wonky.Client.HttpRepository;
public class KrvProductHttpRepository : IKrvProductHttpRepository
{
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<KrvProductHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _apiConfig;
public KrvProductHttpRepository(HttpClient client,
ILogger<KrvProductHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
_logger = logger;
_navigation = navigation;
_apiConfig = configuration.Value;
}
public async Task<PagingResponse<KrvProductDto>> GetProducts(PagingParams pagingParameters)
{
var queryString = new Dictionary<string, string>
{
["pageNumber"] = pagingParameters.PageNumber.ToString(),
["pageSize"] = pagingParameters.PageSize.ToString(),
["searchTerm"] = string.IsNullOrEmpty(pagingParameters.SearchTerm) ? "" : pagingParameters.SearchTerm,
["orderBy"] = string.IsNullOrEmpty(pagingParameters.OrderBy) ? "" : pagingParameters.OrderBy
};
var response = await _client
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.KrvProducts}", queryString))
;
var content = await response.Content
.ReadAsStringAsync()
;
var pagingResponse = new PagingResponse<KrvProductDto>
{
Items = JsonSerializer.Deserialize<List<KrvProductDto>>(content, _options),
MetaData = JsonSerializer.Deserialize<MetaData>(
response.Headers.GetValues("X-Pagination").First(), _options)
};
return pagingResponse;
}
public async Task<KrvProductDto> GetProduct(string productId)
{
var product = await _client
.GetFromJsonAsync<KrvProductDto>($"{_apiConfig.KrvProducts}/get/id({productId})")
;
return product ?? new KrvProductDto();
}
public async Task CreateProduct(KrvProductDto productDto)
{
await _client
.PostAsJsonAsync($"{_apiConfig.KrvProducts}", productDto)
;
}
public async Task<string> UploadImage(MultipartFormDataContent content, string productId)
{
var postResult = await _client
.PostAsync($"{_apiConfig.ImageUpload}/products/id({productId})/image", content)
;
var postContent = await postResult.Content.ReadAsStringAsync();
return postContent;
}
public async Task UpdateProduct(KrvProductDto product)
{
Console.WriteLine(product.ProductId);
await _client.PutAsJsonAsync($"{_apiConfig.KrvProducts}/put/id({product.ProductId})", product);
}
}

View file

@ -1,112 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options;
using Wonky.Client.Features;
using Wonky.Entity.Configuration;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
namespace Wonky.Client.HttpRepository;
public class KrvVariantHttpRepository : IKrvVariantHttpRepository
{
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<KrvVariantHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _apiConfig;
public KrvVariantHttpRepository(HttpClient client,
ILogger<KrvVariantHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
_logger = logger;
_navigation = navigation;
_apiConfig = configuration.Value;
}
public async Task<PagingResponse<KrvVariantDto>> GetVariants(PagingParams pagingParameters)
{
var queryString = new Dictionary<string, string>
{
["pageNumber"] = pagingParameters.PageNumber.ToString(),
["pageSize"] = pagingParameters.PageSize.ToString(),
["searchTerm"] = string.IsNullOrEmpty(pagingParameters.SearchTerm) ? "" : pagingParameters.SearchTerm,
["orderBy"] = string.IsNullOrEmpty(pagingParameters.OrderBy) ? "" : pagingParameters.OrderBy
};
var response = await _client
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.KrvVariants}", queryString))
;
var content = await response.Content
.ReadAsStringAsync()
;
var pagingResponse = new PagingResponse<KrvVariantDto>
{
Items = JsonSerializer.Deserialize<List<KrvVariantDto>>(content, _options),
MetaData = JsonSerializer.Deserialize<MetaData>(
response.Headers.GetValues("X-Pagination").First(), _options)
};
return pagingResponse;
}
public async Task<KrvVariantDto> GetVariant(string variantId)
{
var variant = await _client
.GetFromJsonAsync<KrvVariantDto>($"{_apiConfig.KrvVariants}/get/id({variantId})")
;
return variant ?? new KrvVariantDto();
}
public async Task CreateVariant(KrvVariantDto variantDto)
{
await _client
.PostAsJsonAsync($"v2/", variantDto)
;
}
public async Task<string> UploadImage(MultipartFormDataContent content, string variantId)
{
Console.WriteLine($" Repo -> UploadImage -> {variantId}");
var postResult = await _client
.PostAsync($"{_apiConfig.ImageUpload}/variants/id({variantId})/image", content)
;
var postContent = await postResult.Content.ReadAsStringAsync();
Console.WriteLine(postContent);
return postContent;
}
public async Task UpdateVariant(KrvVariantDto variant)
{
Console.WriteLine(variant.VariantId);
await _client.PutAsJsonAsync($"{_apiConfig.KrvVariants}/put/id({variant.VariantId})", variant);
}
}

View file

@ -13,12 +13,16 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks;
using Wonky.Client.Features;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Wonky.Client.Features;
using Wonky.Entity.Configuration; using Wonky.Entity.Configuration;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
@ -53,11 +57,13 @@ public class SalesItemHttpRepository : ISalesItemHttpRepository
{ {
["pageNumber"] = pagingParameters.PageNumber.ToString(), ["pageNumber"] = pagingParameters.PageNumber.ToString(),
["pageSize"] = pagingParameters.PageSize.ToString(), ["pageSize"] = pagingParameters.PageSize.ToString(),
["searchTerm"] = string.IsNullOrEmpty(pagingParameters.SearchTerm) ? "" : pagingParameters.SearchTerm, ["searchTerm"] = pagingParameters.SearchTerm,
["orderBy"] = string.IsNullOrEmpty(pagingParameters.OrderBy) ? "" : pagingParameters.OrderBy ["searchColumn"] = pagingParameters.SearchColumn,
["orderBy"] = pagingParameters.OrderBy,
["selectGroup"] = pagingParameters.SelectGroup
}; };
var response = await _client var response = await _client
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.PriceCatalog}", queryString)); .GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.PriceCatalog}/page", queryString));
var content = await response.Content.ReadAsStringAsync(); var content = await response.Content.ReadAsStringAsync();

View file

@ -13,6 +13,7 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;

View file

@ -13,6 +13,8 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Collections.Generic;
namespace Wonky.Client.Models namespace Wonky.Client.Models
{ {
public class Quote public class Quote

View file

@ -1,6 +1,12 @@
@using Wonky.Client.Components
@page "/About" @page "/About"
<h3>Hvad er Wonky Online</h3> <div class="img-fluid text-center">
<img src="wonky-logo.png" alt="Wonky logo"/>
</div>
Wonky Online er Innotec Danmarks egen udviklede ordresystem. <div class="row">
<div class="col text-center">
<AppVersion />
</div>
</div>
<AppVersion />

View file

@ -1,9 +0,0 @@
@page "/activites"
<h3>Salgs Aktivitet</h3>
<div class="row">
<div class="col">
<ActivityTable ActivityList="Activities" />
</div>
</div>

View file

@ -1,10 +0,0 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Pages;
public partial class ActivityList
{
public List<Activity> Activities { get; set; } = new();
}

View file

@ -17,7 +17,6 @@
@page "/create-company" @page "/create-company"
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components
@attribute [Authorize(Roles = "Adviser")] @attribute [Authorize(Roles = "Adviser")]
<h2>Opret firma</h2> <h2>Opret firma</h2>

View file

@ -13,18 +13,21 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Blazored.Toast.Services; using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Wonky.Client.Services; using Wonky.Client.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.Extensions.Logging;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Models; using Wonky.Entity.Models;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
using Wonky.Virk.Services;
namespace Wonky.Client.Pages namespace Wonky.Client.Pages
{ {

View file

@ -16,21 +16,20 @@
*@ *@
@page "/companies" @page "/companies"
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Adviser")] @attribute [Authorize(Roles = "Adviser")]
<div class="row"> <div class="row mb-3">
<div class="col"> <div class="col">
<CompanySearchField OnFilterChanged="FilterChanged" /> <CompanySearchColumn OnFilterChanged="FilterChanged" />
</div> </div>
<div class="col"> <div class="col">
<SearchPhrase OnSearchChanged="SearchChanged"/> <SearchPhrase OnSearchPhraseChanged="SearchChanged"/>
</div>
<div class="col">
<CompanySort OnSortChanged="SortChanged"/>
</div> </div>
<div class="col"> <div class="col">
<CompanySortColumn OnSortChanged="SortChanged"/>
</div> </div>
<div class="col"> <div class="col">
<a class="btn btn-success mb-1" href="/create-company">Nyt firma</a> <a class="btn btn-success mb-1" href="/create-company">Nyt firma</a>

View file

@ -13,9 +13,12 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using Microsoft.AspNetCore.Components; using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
@ -27,7 +30,7 @@ namespace Wonky.Client.Pages
public MetaData? MetaData { get; set; } = new(); public MetaData? MetaData { get; set; } = new();
private PagingParams _paging = new(); private PagingParams _paging = new();
[Inject] [Inject]
public ICompanyHttpRepository CompanyRepo { get; set; } public ICompanyHttpRepository CompanyRepo { get; set; }
@ -56,6 +59,7 @@ namespace Wonky.Client.Pages
private async Task FilterChanged(string? searchColumn) private async Task FilterChanged(string? searchColumn)
{ {
_paging.SearchTerm = "";
_paging.SearchColumn = searchColumn; _paging.SearchColumn = searchColumn;
_paging.PageNumber = 1; _paging.PageNumber = 1;
await GetCompanies(); await GetCompanies();

View file

@ -17,6 +17,7 @@
@page "/update-company/{account}" @page "/update-company/{account}"
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Components @using Microsoft.AspNetCore.Components
@attribute [Authorize(Roles = "Adviser")] @attribute [Authorize(Roles = "Adviser")]

View file

@ -13,11 +13,14 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System;
using System.Threading.Tasks;
using Blazored.Toast.Services; using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.Extensions.Logging;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;

View file

@ -18,6 +18,7 @@
@page "/company/account/{account}" @page "/company/account/{account}"
@page "/company/{companyId}" @page "/company/{companyId}"
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components;
@attribute [Authorize(Roles = "Adviser")] @attribute [Authorize(Roles = "Adviser")]
<div class="card"> <div class="card">
@ -34,7 +35,7 @@
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<a class="btn btn-info" href="/company/@CompanyDto.Account/offer">Tilbud</a> <a class="btn btn-info" href="/company/account/@CompanyDto.Account/document">Tilbud</a>
<a class="btn btn-info" href="#">Ordre</a> <a class="btn btn-info" href="#">Ordre</a>
<a class="btn btn-info" href="#">Faktura</a> <a class="btn btn-info" href="#">Faktura</a>
<a class="btn btn-info" href="#">Produkter</a> <a class="btn btn-info" href="#">Produkter</a>

View file

@ -13,9 +13,11 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using Microsoft.AspNetCore.Components; using System;
using System.Threading.Tasks;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;

View file

@ -18,8 +18,9 @@
@page "/" @page "/"
@page "/index" @page "/index"
@inject IWebAssemblyHostEnvironment _hostEnvironment @inject IWebAssemblyHostEnvironment _hostEnvironment
@using Wonky.Client.Components;
<Home Title="Hej!"></Home> <Home></Home>
@code{ @code{
} }

View file

@ -31,15 +31,15 @@
<EditForm Model="_userAuthenticationDto" OnValidSubmit="ExecuteLogin" class="card card-body bg-light mt-5"> <EditForm Model="_userAuthenticationDto" OnValidSubmit="ExecuteLogin" class="card card-body bg-light mt-5">
<DataAnnotationsValidator /> <DataAnnotationsValidator />
<div class="form-group row"> <div class="form-group row">
<label for="email" class="col-md-2 col-form-label">Email</label> <label for="email" class="col-md-2 col-form-label">Login</label>
<div class="col-md-10"> <div class="col-md-10">
<InputText id="email" class="form-control" <InputText type="email" id="email" class="form-control"
@bind-Value="_userAuthenticationDto.Email" autocomplete="username" /> @bind-Value="_userAuthenticationDto.Email" autocomplete="username" />
<ValidationMessage For="@(() => _userAuthenticationDto.Email)" /> <ValidationMessage For="@(() => _userAuthenticationDto.Email)" />
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label for="password" class="col-md-2 col-form-label">Adgangskode</label> <label for="password" class="col-md-2 col-form-label">Kode</label>
<div class="col-md-10"> <div class="col-md-10">
<InputText type="password" id="password" class="form-control" <InputText type="password" id="password" class="form-control"
@bind-Value="_userAuthenticationDto.Password" autocomplete="current-password" /> @bind-Value="_userAuthenticationDto.Password" autocomplete="current-password" />
@ -48,7 +48,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12 text-right"> <div class="col-md-12 text-right">
<button type="submit" class="btn btn-success">Login</button> <button type="submit" class="btn btn-success" disabled=@execLogin >Login</button>
</div> </div>
</div> </div>
</EditForm> </EditForm>

View file

@ -13,8 +13,9 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using Microsoft.AspNetCore.Components; using System.Threading.Tasks;
using Wonky.Client.Services; using Wonky.Client.Services;
using Microsoft.AspNetCore.Components;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;
@ -31,20 +32,23 @@ public partial class Login
[Parameter] public string ReturnUrl { get; set; } = ""; [Parameter] public string ReturnUrl { get; set; } = "";
private bool ShowAuthError { get; set; } private bool ShowAuthError { get; set; }
private string? Error { get; set; } private string? Error { get; set; }
private bool execLogin;
private async Task ExecuteLogin() private async Task ExecuteLogin()
{ {
ShowAuthError = false; ShowAuthError = false;
execLogin = true;
var result = await AuthenticationService.Login(_userAuthenticationDto); var result = await AuthenticationService.Login(_userAuthenticationDto);
if (!result.IsSuccess) if (!result.IsSuccess)
{ {
Error = result.ErrorMessage; Error = result.ErrorMessage;
ShowAuthError = true; ShowAuthError = true;
execLogin = false;
} }
else else
{ {
var returnUrl = string.IsNullOrEmpty(ReturnUrl) ? "/companies" : ReturnUrl; var returnUrl = string.IsNullOrEmpty(ReturnUrl) ? "/Companies" : ReturnUrl;
NavigationManager.NavigateTo(returnUrl); NavigationManager.NavigateTo(returnUrl);
} }
} }

View file

@ -13,8 +13,9 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using Microsoft.AspNetCore.Components; using System.Threading.Tasks;
using Wonky.Client.Services; using Wonky.Client.Services;
using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;

View file

@ -1,54 +0,0 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@page "/create-product"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components
@attribute [Authorize(Roles = "Admin")]
<h2>Opret KRV Produkt</h2>
@* <EditForm Model="_company" OnValidSubmit="Create" class="card card-body bg-light mt-5"> *@
<EditForm EditContext="_editContext" OnValidSubmit="Create" class="card card-body bg-light mt-5">
<DataAnnotationsValidator />
@* <ValidationSummary /> *@
<div class="form-group row mb-2">
<label for="name" class="col-md-2 col-form-label">Produkt Navn (Samme navn som på innotec.dk)</label>
<div class="col-md-10">
<InputText id="name" class="form-control" @bind-Value="_productDto.TradingName"/>
<ValidationMessage For="@(() => _productDto.TradingName)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-2">
<label for="category" class="col-md-2 col-form-label">Produkt kategori</label>
<div class="col-md-10">
<InputText id="category" class="form-control" @bind-Value="_productDto.ProductCategoryEnum"/>
</div>
</div>
<div class="form-group row mb-2">
<label for="file-upload" class="col-md-2 col-form-label">Produkt billede</label>
<div class="col-md-10">
<ProductImageUpload OnChange="AssignImageUrl" />
</div>
</div>
<div class="row mb-2">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-success" disabled="@_formInvalid">Opret</button>
</div>
</div>
</EditForm>

View file

@ -1,87 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Wonky.Entity.DTO;
namespace Wonky.Client.Pages
{
public partial class ProductCreate : IDisposable
{
private KrvProductDto _productDto { get; set; } = new();
private EditContext _editContext;
private bool _formInvalid = true;
[Inject]
public IKrvProductHttpRepository ProductRepo { get; set; }
[Inject]
public HttpInterceptorService Interceptor { get; set; }
[Inject]
public IToastService ToastService { get; set; }
[Inject]
public ILogger<ProductCreate> Logger { get; set; }
protected override void OnInitialized()
{
_editContext = new EditContext(_productDto);
_editContext.OnFieldChanged += HandleFieldChanged;
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
}
private async Task Create()
{
Logger.LogDebug($"{_productDto}");
await ProductRepo.CreateProduct(_productDto);
ToastService.ShowSuccess($"Godt så. Produktet '{_productDto.TradingName}' er oprettet.");
_productDto = new KrvProductDto();
_editContext.OnValidationStateChanged += ValidationChanged;
_editContext.NotifyValidationStateChanged();
}
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{
_formInvalid = !_editContext.Validate();
StateHasChanged();
}
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
_formInvalid = true;
_editContext.OnFieldChanged -= HandleFieldChanged;
_editContext = new EditContext(_productDto);
_editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged -= ValidationChanged;
}
public void Dispose()
{
Interceptor.DisposeEvent();
_editContext.OnFieldChanged -= HandleFieldChanged;
_editContext.OnValidationStateChanged -= ValidationChanged;
}
private void AssignImageUrl(string imgUrl) => _productDto.PictureLink = imgUrl;
}
}

View file

@ -18,6 +18,7 @@
@page "/company/{account}/activity" @page "/company/{account}/activity"
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Adviser")] @attribute [Authorize(Roles = "Adviser")]
@using Wonky.Client.Components
<h2>@_purchaseOrder.Name</h2> <h2>@_purchaseOrder.Name</h2>
<EditForm EditContext="_editContext" OnValidSubmit="CreateActivity" class="card card-body bg-light mt-5"> <EditForm EditContext="_editContext" OnValidSubmit="CreateActivity" class="card card-body bg-light mt-5">
@ -104,7 +105,7 @@
<SalesItemSearchField OnSearchFieldChanged="SearchFieldChange"></SalesItemSearchField> <SalesItemSearchField OnSearchFieldChanged="SearchFieldChange"></SalesItemSearchField>
</div> </div>
<div class="col"> <div class="col">
<SearchPhrase OnSearchChanged="SearchTermChanged"></SearchPhrase> <SearchPhrase OnSearchPhraseChanged="SearchTermChanged"></SearchPhrase>
</div> </div>
<div class="col"> <div class="col">
<SalesItemSort OnSortFieldChanged="OrderByChanged"></SalesItemSort> <SalesItemSort OnSortFieldChanged="OrderByChanged"></SalesItemSort>

View file

@ -13,14 +13,17 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Blazored.Toast.Services; using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.Helpers; using Wonky.Client.Helpers;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Wonky.Client.Models; using Wonky.Client.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;

View file

@ -1,66 +0,0 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@page "/register"
@using Microsoft.AspNetCore.Components
<h3>Registration</h3>
@if
(ShowRegistrationErrors)
{
<div class="alert alert-danger" role="alert">
@if (Errors != null)
{
foreach (var error in Errors)
{
<p>@error</p>
}
}
</div>
}
<EditForm Model="_userRegistration" OnValidSubmit="Register" class="card card-body bg-light mt-5">
<DataAnnotationsValidator />
<div class="form-group row">
<label for="email" class="col-md-2 col-form-label">Email</label>
<div class="col-md-10">
<InputText id="email" class="form-control"
@bind-Value="_userRegistration.Email" autocomplete="username" />
<ValidationMessage For="@(() => _userRegistration.Email)" />
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-2 col-form-label">Adgangskode</label>
<div class="col-md-10">
<InputText type="password" id="password" class="form-control"
@bind-Value="_userRegistration.Password" autocomplete="new-password" />
<ValidationMessage For="@(() => _userRegistration.Password)" />
</div>
</div>
<div class="form-group row">
<label for="confirm" class="col-md-2 col-form-label">Gentag adgangskode</label>
<div class="col-md-10">
<InputText type="password" id="confirm" class="form-control"
@bind-Value="_userRegistration.ConfirmPassword" autocomplete="new-password" />
<ValidationMessage For="@(() => _userRegistration.ConfirmPassword)" />
</div>
</div>
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-success">Register</button>
</div>
</div>
</EditForm>

View file

@ -1,54 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Microsoft.AspNetCore.Components;
using Wonky.Client.Services;
using Wonky.Entity.DTO;
namespace Wonky.Client.Pages
{
public partial class Registration
{
private UserRegistrationDto _userRegistration = new ();
[Inject]
public IAuthenticationService AuthenticationService { get; set; }
[Inject]
public NavigationManager NavigationManager { get; set; }
public bool ShowRegistrationErrors { get; set; }
public IEnumerable<string>? Errors { get; set; }
public async Task Register()
{
ShowRegistrationErrors = false;
var result = await AuthenticationService.RegisterUser(_userRegistration);
if (!result.IsSuccess)
{
Errors = result.Errors;
ShowRegistrationErrors = true;
}
else
{
// todo: redirect to login page
// todo: store url
// var returnUrl = NavigationManager.Uri;
NavigationManager.NavigateTo("/login");
}
}
}
}

View file

@ -16,21 +16,23 @@
*@ *@
@page "/price-catalog" @page "/price-catalog"
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Adviser,Admin")] @attribute [Authorize(Roles = "Adviser,Admin")]
<div class="row"> <div class="row mb-3">
<div class="col-md-4"> <div class="col">
<SearchPhrase OnSearchChanged="SearchChanged" /> <ItemSearchColumn OnSearchColumnChanged="SearchColumnChanged" />
</div> </div>
<div class="col-md-4"> <div class="col">
<SalesItemSort OnSortFieldChanged="SortChanged" /> <SearchPhrase OnSearchPhraseChanged="SearchPhraseChanged"/>
</div> </div>
<div class="col-md-2"> <div class="col">
<ItemSortColumn OnSortColumnChanged="SortColumnChanged"/>
</div> </div>
<div class="col-md-2"> <div class="col">
@* <a class="btn btn-success mb-1" href="/createCompany">Nyt firma</a> *@ <ItemGroupFilter OnGroupFilterChanged="GroupFilterChanged" />
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -45,6 +47,6 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<SalesItemTable SalesItems="SalesItemList"></SalesItemTable> <ItemTable SalesItems="SalesItemList"></ItemTable>
</div> </div>
</div> </div>

View file

@ -13,9 +13,12 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using Microsoft.AspNetCore.Components; using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Requests; using Wonky.Entity.Requests;
@ -26,7 +29,6 @@ public partial class SalesItemCatalog : IDisposable
private List<SalesItemDto> SalesItemList { get; set; } = new(); private List<SalesItemDto> SalesItemList { get; set; } = new();
private MetaData? MetaData { get; set; } = new(); private MetaData? MetaData { get; set; } = new();
private PagingParams _paging = new(); private PagingParams _paging = new();
[Inject] public ISalesItemHttpRepository SalesItemRepo { get; set; } [Inject] public ISalesItemHttpRepository SalesItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; } [Inject] public HttpInterceptorService Interceptor { get; set; }
@ -45,12 +47,9 @@ public partial class SalesItemCatalog : IDisposable
private async Task GetSalesItems() private async Task GetSalesItems()
{ {
if (SalesItemRepo != null) var pagingResponse = await SalesItemRepo.GetSalesItems(_paging);
{ SalesItemList = pagingResponse.Items!;
var pagingResponse = await SalesItemRepo.GetSalesItems(_paging); MetaData = pagingResponse.MetaData;
SalesItemList = pagingResponse.Items;
MetaData = pagingResponse.MetaData;
}
} }
private async Task SetPageSize(int pageSize) private async Task SetPageSize(int pageSize)
@ -60,14 +59,27 @@ public partial class SalesItemCatalog : IDisposable
await GetSalesItems(); await GetSalesItems();
} }
private async Task SearchChanged(string? searchTerm) private async Task GroupFilterChanged(string groupFilter)
{
_paging.PageNumber = 1;
_paging.SelectGroup = groupFilter;
await GetSalesItems();
}
private async Task SearchColumnChanged(string columnName)
{
_paging.PageNumber = 1;
_paging.SearchTerm = "";
_paging.SearchColumn = columnName;
await GetSalesItems();
}
private async Task SearchPhraseChanged(string searchTerm)
{ {
_paging.PageNumber = 1; _paging.PageNumber = 1;
_paging.SearchTerm = searchTerm; _paging.SearchTerm = searchTerm;
await GetSalesItems(); await GetSalesItems();
} }
private async Task SortChanged(string? orderBy) private async Task SortColumnChanged(string orderBy)
{ {
_paging.OrderBy = orderBy; _paging.OrderBy = orderBy;
await GetSalesItems(); await GetSalesItems();

View file

@ -20,18 +20,18 @@
@attribute [Authorize(Roles = "Adviser,Admin")] @attribute [Authorize(Roles = "Adviser,Admin")]
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<h1>@Item.ItemName</h1> <h1>@Item.Name</h1>
</div> </div>
<div class="card-body"> <div class="card-body">
<table class="table table-striped table-bordered"> <table class="table table-striped table-bordered">
<tbody> <tbody>
<tr> <tr>
<th scope="row">Navn</th> <th scope="row">Navn</th>
<td>@Item.ItemName</td> <td>@Item.Name</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Varenr</th> <th scope="row">Varenr</th>
<td>@Item.ItemNumber</td> <td>@Item.Sku</td>
</tr> </tr>
<tr> <tr>
<th scope="row"></th> <th scope="row"></th>

View file

@ -13,9 +13,11 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using Microsoft.AspNetCore.Components; using System;
using System.Threading.Tasks;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;

View file

@ -0,0 +1,153 @@
@using Wonky.Entity.Models
@page "/cart"
<h3>ShoppingCart</h3>
@if (AllItems != null)
{
<h2>select item</h2>
<select size="4" style="width:100%" @onchange="ItemSelected">
@foreach (var item in AllItems)
{
<option value="@item.Id.ToString()">@item.Name</option>
}
</select>
<br/>
@if (SelectedItem != null && ShowItem)
{
<div style="padding: 1vw;background-color: lightgray">
<table>
<tr>
<td><strong>Name:</strong></td>
<td>@SelectedItem.Name</td>
</tr>
<tr>
<td><strong>Description:</strong></td>
<td>@SelectedItem.Description</td>
</tr>
<tr>
<td><strong>Price:</strong></td>
<td>$@SelectedItem.Price</td>
</tr>
<tr>
<td><strong>Add To Cart:</strong></td>
<td>
Quantity:
<input @bind="Quantity"/>
<button @onclick="AddToCart">Add</button>
</td>
</tr>
</table>
</div>
}
// Show the cart contents if there are items in it.
@if (CartStateProvider != null && CartStateProvider.ShoppingCart.Items.Count > 0)
{
<br/>
<h3>Your Cart:</h3>
<h4>Total: $@CartStateProvider.ShoppingCart.Total</h4>
<table>
@foreach (var item in CartStateProvider.ShoppingCart.Items)
{
<tr>
<td colspan="2">
<hr/>
</td>
</tr>
<tr>
<td><strong>Name:</strong></td>
<td>@item.Item.Name</td>
</tr>
<tr>
<td><strong>Description:</strong></td>
<td>@item.Item.Description</td>
</tr>
<tr>
<td><strong>Price:</strong></td>
<td>$@item.Item.Price</td>
</tr>
<tr>
<td><strong>Quantity:</strong></td>
<td>@item.Quantity</td>
</tr>
<tr>
<td><strong>Total:</strong></td>
<td>$@item.Total</td>
</tr>
<tr>
<td colspan="2">
@*Clicking this button passes the item so we can remove it*@
<button @onclick="@(() => RemoveItem(@item))">Remove</button>
</td>
</tr>
}
</table>
<br/>
<h4>Total: $@CartStateProvider.ShoppingCart.Total</h4>
}
}
@code {
[CascadingParameter] CartStateProvider CartStateProvider { get; set; }
private bool ShowItem;
private string Quantity = "1";
private List<Item> AllItems { get; set; } = new();
private Item SelectedItem { get; set; } = new();
void ItemSelected(ChangeEventArgs args)
{
// Item has been selected
SelectedItem = (from x in AllItems where x.Id == Convert.ToInt32(args.Value) select x).First();
Quantity = "1";
ShowItem = true;
}
async Task AddToCart()
{
// create a new cart item
var item = new CartItem
{
Item = SelectedItem,
Quantity = Convert.ToInt32(Quantity)
};
// add it to the cart
CartStateProvider.ShoppingCart.Items.Add(item);
// save the item using the CartStateProvider's save method
await CartStateProvider.SaveChangesAsync();
// hide the selected item
ShowItem = false;
}
async Task RemoveItem(CartItem item)
{
// click on remove
CartStateProvider.ShoppingCart.Items.Remove(item);
// save the cart
await CartStateProvider.SaveChangesAsync();
}
protected override void OnInitialized()
{
// TODO load the items from server
// just create some for now
AllItems = new List<Item>();
AllItems.Add(new Item()
{
Id = 1,
Name = "TEST 1",
Description = "Description 1",
Price = (decimal)10.99
});
AllItems.Add(new Item()
{
Id = 2,
Name = "TEST 2",
Description = "Description 2",
Price = (decimal)19.99
});
}
}

View file

@ -1,38 +0,0 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@page "/VirkData"
<PageTitle>Innotec Danmark</PageTitle>
<h2>Virk CVR Database</h2>
<div class="card">
<div class="card-header">
<h2>CVR opslag</h2>
</div>
<div class="card-body">
<RegLookupVatNo />
</div>
</div>
<div class="card">
<div class="card-header">
<h2>Adresse opslag</h2>
</div>
<div class="card-body">
<RegLookupAddress />
</div>
</div>

View file

@ -12,6 +12,7 @@
// You should have received a copy of the Affero GNU General Public License // You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
@ -25,7 +26,6 @@ using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Wonky.Client.Services; using Wonky.Client.Services;
using Wonky.Entity.Configuration; using Wonky.Entity.Configuration;
using Wonky.Virk.Services;
var builder = WebAssemblyHostBuilder.CreateDefault(args); var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<App>("#app");
@ -43,14 +43,11 @@ builder.Services.AddHttpClient("InnoAPI", (sp, cl) =>
}); });
builder.Services.AddBlazoredToast(); builder.Services.AddBlazoredToast();
builder.Services.AddHttpClientInterceptor(); builder.Services.AddHttpClientInterceptor();
builder.Services.Configure<ApiConfig>(builder.Configuration.GetSection("ApiConfig")); builder.Services.Configure<ApiConfig>(builder.Configuration.GetSection("ApiConfig"));
builder.Services.AddScoped<ICompanyHttpRepository, CompanyHttpRepository>(); builder.Services.AddScoped<ICompanyHttpRepository, CompanyHttpRepository>();
builder.Services.AddScoped<IKrvProductHttpRepository, KrvProductHttpRepository>();
builder.Services.AddScoped<IKrvVariantHttpRepository, KrvVariantHttpRepository>();
builder.Services.AddScoped<ISalesItemHttpRepository, SalesItemHttpRepository>(); builder.Services.AddScoped<ISalesItemHttpRepository, SalesItemHttpRepository>();
builder.Services.AddScoped<HttpInterceptorService>(); builder.Services.AddScoped<HttpInterceptorService>();

View file

@ -1,30 +1,30 @@
{ {
"iisSettings": { "iisSettings": {
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:33781", "applicationUrl": "http://localhost:61714",
"sslPort": 44330 "sslPort": 44308
} }
}, },
"profiles": { "profiles": {
"Wonky.Client": { "Wonky.Client": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7207;http://localhost:5101", "applicationUrl": "https://localhost:7174;http://localhost:5280",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
}, },
"IIS Express": { "IIS Express": {
"commandName": "IISExpress", "commandName": "IISExpress",
"launchBrowser": true, "launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
} }
} }
} }

View file

@ -17,9 +17,9 @@ using System.Net.Http.Headers;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Text.Json; using System.Text.Json;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Wonky.Client.AuthProviders;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Wonky.Client.AuthProviders;
using Wonky.Entity.Configuration; using Wonky.Entity.Configuration;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;

View file

@ -13,6 +13,7 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Threading.Tasks;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
namespace Wonky.Client.Services namespace Wonky.Client.Services

View file

@ -13,7 +13,10 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.Logging;
namespace Wonky.Client.Services; namespace Wonky.Client.Services;

View file

@ -0,0 +1,75 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Text.Json;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options;
using Wonky.Entity.Configuration;
using Wonky.Entity.Models;
using Wonky.Entity.Requests;
namespace Wonky.Client.Services;
public class VirkRegistryService
{
private readonly JsonSerializerOptions _options = new() { PropertyNameCaseInsensitive = true };
private readonly HttpClient _client;
private readonly IOptions<ApiConfig> _apiConfig;
private readonly List<VirkRegInfo> _noData = new() { new VirkRegInfo { Name = "INGEN DATA" } };
public VirkRegistryService(HttpClient client, IOptions<ApiConfig> apiConfig)
{
_client = client;
_apiConfig = apiConfig;
}
public async Task<List<VirkRegInfo>> QueryVirkRegistry(VirkParams query)
{
if(!ValidateCvrQuery(query))
{
throw new ArgumentException("CvrQuery does not validate");
}
var queryString = new Dictionary<string, string>
{
["vatNumber"] = query.VatNumber,
["streetName"] = query.StreetName,
["houseNumber"] = query.HouseNumber,
["zipCode"] = query.ZipCode
};
var endpoint = QueryHelpers.AddQueryString(_apiConfig.Value.CvrLookup , queryString);
var response = await _client.GetAsync(endpoint);
var content = await response.Content.ReadAsStringAsync();
var jsonResult = JsonSerializer.Deserialize<List<VirkRegInfo>>(content, _options);
if (string.IsNullOrWhiteSpace(content) || !jsonResult.Any()) return _noData;
if (!string.IsNullOrWhiteSpace(query.VatNumber)) return jsonResult;
var result = jsonResult
.Where(x => x.States[^1].State == "NORMAL")
.OrderBy(x => x.Name).ToList();
return result.Count == 0 ? _noData : result;
}
private static bool ValidateCvrQuery(VirkParams query)
{
if (!string.IsNullOrWhiteSpace(query.VatNumber))
return true;
return !string.IsNullOrWhiteSpace(query.HouseNumber) && !string.IsNullOrWhiteSpace(query.StreetName) &&
!string.IsNullOrWhiteSpace(query.ZipCode);
}
}

View file

@ -15,7 +15,7 @@
// //
*@ *@
@if (hasLoaded) @if (_hasLoaded)
{ {
<CascadingValue Value="@this"> <CascadingValue Value="@this">
@ChildContent @ChildContent
@ -23,5 +23,5 @@
} }
else else
{ {
<p>Indlæser...</p> <p>Indlæser ...</p>
} }

View file

@ -13,33 +13,45 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.Threading.Tasks;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components;
using Wonky.Client.Models; using Wonky.Client.Models;
using Microsoft.AspNetCore.Components;
using Wonky.Entity.Models;
namespace Wonky.Client.Shared; namespace Wonky.Client.Shared;
public partial class PoStateProvider public partial class CartStateProvider
{ {
[Parameter] public RenderFragment ChildContent { get; set; } [Parameter] public RenderFragment ChildContent { get; set; }
public PurchaseOrder PurchaseOrder { get; set; } public Cart ShoppingCart { get; set; }
[Parameter] public string Account { get; set; } = ""; [Parameter] public string Account { get; set; } = "MyCart";
[Inject] public ILocalStorageService LocalStorageService { get; set; } [Inject] public ILocalStorageService LocalStorageService { get; set; }
private bool hasLoaded; private bool _hasLoaded;
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
PurchaseOrder = await LocalStorageService.GetItemAsync<PurchaseOrder>(Account); ShoppingCart = await LocalStorageService.GetItemAsync<Cart>(Account);
if (PurchaseOrder == null || PurchaseOrder.Lines.Count == 0) if (ShoppingCart == null || ShoppingCart.Items.Count == 0)
PurchaseOrder = new PurchaseOrder(); {
ShoppingCart = new Cart();
}
else
{
if (DateTime.Now > ShoppingCart.LastAccessed.AddSeconds(ShoppingCart.TimeToLiveInSeconds))
{
ShoppingCart = new Cart();
}
}
hasLoaded = true; ShoppingCart.LastAccessed = DateTime.Now;
_hasLoaded = true;
} }
public async Task SaveChangesAsync() public async Task SaveChangesAsync()
{ {
await LocalStorageService.SetItemAsync(Account, PurchaseOrder); await LocalStorageService.SetItemAsync(Account, ShoppingCart);
} }
} }

View file

@ -15,6 +15,7 @@
// //
*@ *@
@inherits LayoutComponentBase @inherits LayoutComponentBase
@using Wonky.Client.Components
<div class="page"> <div class="page">
<div class="sidebar"> <div class="sidebar">

View file

@ -9,18 +9,21 @@ main {
} }
.sidebar { .sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); background-image: linear-gradient(180deg, rgb(22, 21, 23) 10%, #ffaa00 100%);
} }
.top-row { .top-row {
background-color: #f7f7f7; color: #ffaa00;
background-color: #0e0e0e;
border-bottom: 1px solid #d6d5d5; border-bottom: 1px solid #d6d5d5;
justify-content: flex-end; justify-content: flex-end;
height: 3.5rem; height: 3.5rem;
display: flex; display: flex;
align-items: center; align-items: center;
} }
a:active, a:visited, a:link {
color: #ffaa00;
}
.top-row ::deep a, .top-row ::deep .btn-link { .top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap; white-space: nowrap;
margin-left: 1.5rem; margin-left: 1.5rem;

View file

@ -16,6 +16,7 @@
*@ *@
@inject IWebAssemblyHostEnvironment HostEnvironment @inject IWebAssemblyHostEnvironment HostEnvironment
@using Wonky.Client.Components;
<div class="top-row ps-3 navbar navbar-dark"> <div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid"> <div class="container-fluid">
@ -33,62 +34,20 @@
<span class="oi oi-home" aria-hidden="true"></span> Start <span class="oi oi-home" aria-hidden="true"></span> Start
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="/VirkData">
<span class="oi oi-plus" aria-hidden="true"></span> CVR Database
</NavLink>
</div>
<AuthorizeView Roles="Adviser,Admin"> <AuthorizeView Roles="Adviser,Admin">
<Authorized> <Authorized>
<div class="px-3">CRM</div>
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="companies"> <NavLink class="nav-link" href="Companies">
<span class="oi oi-list-rich" aria-hidden="true"></span> Firmaer <span class="oi oi-list-rich" aria-hidden="true"></span> Firmaer
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="CompanyActivity">
<span class="oi oi-list-rich" aria-hidden="true"></span> Aktivitet
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="CompanyProducts">
<span class="oi oi-list-rich" aria-hidden="true"></span> Produkter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="CompanyInfo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Stamdata
</NavLink>
</div>
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="price-catalog"> <NavLink class="nav-link" href="price-catalog">
<span class="oi oi-list-rich" aria-hidden="true"></span> Priskatalog <span class="oi oi-list-rich" aria-hidden="true"></span> Priskatalog
</NavLink> </NavLink>
</div> </div>
<div class="px-3">KRK</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="CompanyKApv">
<span class="oi oi-list-rich" aria-hidden="true"></span> APB / APV
</NavLink>
</div>
</Authorized> </Authorized>
</AuthorizeView> </AuthorizeView>
<AuthorizeView Roles="Admin">
<Authorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="krv-products">
<span class="oi oi-list-rich" aria-hidden="true"></span> KRV Produkter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="krv-variants">
<span class="oi oi-list-rich" aria-hidden="true"></span> KRV Varenumre
</NavLink>
</div>
</Authorized>
</AuthorizeView>
</nav> </nav>
</div> </div>

View file

@ -1,62 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpRepository;
namespace Wonky.Client.Shared
{
public partial class ProductImageUpload
{
private string _fileUploadMessage = "Ingen fil valgt";
[Parameter]
public string ImgUrl { get; set; } = "";
[Parameter]
public string ProductId { get; set; } = "";
private EventCallback<string> OnChange { get; set; }
[Inject]
public IKrvProductHttpRepository ProductRepo { get; set; }
private async Task HandleSelected(InputFileChangeEventArgs e)
{
var imageFile = e.File;
if (imageFile.Size == 0)
return;
_fileUploadMessage = string.Empty;
_fileUploadMessage += $"{imageFile.Name}";
var resizedFile = await imageFile.RequestImageFileAsync("image/png", 500, 500);
await using var ms = resizedFile.OpenReadStream(resizedFile.Size);
var content = new MultipartFormDataContent();
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
content.Add(new StreamContent(ms,
Convert.ToInt32(resizedFile.Size)), "image", imageFile.Name);
ImgUrl = await ProductRepo.UploadImage(content, ProductId);
await OnChange.InvokeAsync(ImgUrl);
}
}
}

View file

@ -1,8 +0,0 @@
/* product image upload */
.image-name {
margin-left: 10px;
}
.image-preview {
width: 300px;
margin-top: 15px;
}

View file

@ -1,64 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Affero GNU General Public License for more details.
//
// You should have received a copy of the Affero GNU General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpRepository;
namespace Wonky.Client.Shared
{
public partial class VariantImageUpload
{
private string _fileUploadMessage = "Ingen fil valgt";
[Parameter]
public EventCallback<string> OnChange { get; set; }
[Parameter]
public string PictureLink { get; set; } = "";
[Parameter]
public string VariantId { get; set; } = "";
[Parameter]
public string ImageFilename { get; set; } = "";
[Inject]
public IKrvVariantHttpRepository VariantRepo { get; set; }
private async Task HandleSelected(InputFileChangeEventArgs e)
{
var imageFile = e.File;
_fileUploadMessage = string.Empty;
if (imageFile.Size == 0)
return;
_fileUploadMessage += $"{imageFile.Name}";
var resizedFile = await imageFile.RequestImageFileAsync("image/png", 500, 500);
await using var ms = resizedFile.OpenReadStream(resizedFile.Size);
var content = new MultipartFormDataContent();
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
content.Add(new StreamContent(ms,
Convert.ToInt32(resizedFile.Size)), "image", $"{ImageFilename}.png");
PictureLink = await VariantRepo.UploadImage(content, VariantId);
Console.WriteLine($"response from api - {PictureLink}");
await OnChange.InvokeAsync(PictureLink);
}
}
}

View file

@ -1,8 +0,0 @@
/* variant image upload */
.image-name {
margin-left: 10px;
}
.image-preview {
width: 300px;
margin-top: 15px;
}

View file

@ -1,32 +1,63 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> <LangVersion>latestmajor</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="blazored.localstorage" Version="4.2.0" /> <ItemGroup>
<PackageReference Include="blazored.toast" Version="3.2.2" /> <PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
<PackageReference Include="DnetIndexedDb" Version="2.4.1" /> <PackageReference Include="Blazored.Toast" Version="3.2.2" />
<PackageReference Include="microsoft.aspnetcore.authentication" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="microsoft.aspnetcore.authorization" Version="6.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="6.0.2" />
<PackageReference Include="microsoft.aspnetcore.components.authorization" Version="6.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.2" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.2" PrivateAssets="all" />
<PackageReference Include="microsoft.aspnetcore.webutilities" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Include="microsoft.extensions.http" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="microsoft.extensions.logging" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="microsoft.extensions.logging.configuration" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="6.0.0" />
<PackageReference Include="toolbelt.blazor.httpclientinterceptor" Version="10.1.0" /> <PackageReference Include="Toolbelt.Blazor.HttpClientInterceptor" Version="10.1.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Wonky.Entity\Wonky.Entity\Wonky.Entity.csproj" /> <ProjectReference Include="..\Wonky.Entity\Wonky.Entity.csproj" />
<ProjectReference Include="..\..\Wonky.Virk\Wonky.Virk\Wonky.Virk.csproj" /> </ItemGroup>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="wwwroot\scripts" /> <Content Update="wwwroot\appsettings.json">
</ItemGroup> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Project> </Content>
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\scripts" />
</ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="Components\AppVersion.razor" />
<_ContentIncludedByDefault Remove="Components\AuthLinks.razor" />
<_ContentIncludedByDefault Remove="Components\CompanyListHeader.razor" />
<_ContentIncludedByDefault Remove="Components\CompanySearchField.razor" />
<_ContentIncludedByDefault Remove="Components\CompanySort.razor" />
<_ContentIncludedByDefault Remove="Components\CompanyTable.razor" />
<_ContentIncludedByDefault Remove="Components\Home.razor" />
<_ContentIncludedByDefault Remove="Components\PageSizeDropDown.razor" />
<_ContentIncludedByDefault Remove="Components\Pagination.razor" />
<_ContentIncludedByDefault Remove="Components\PoLineCreate.razor" />
<_ContentIncludedByDefault Remove="Components\PurchaseOrderLinesTable.razor" />
<_ContentIncludedByDefault Remove="Components\PurchaseOrderTable.razor" />
<_ContentIncludedByDefault Remove="Components\RegInfoCompany.razor" />
<_ContentIncludedByDefault Remove="Components\RegLookupAddress.razor" />
<_ContentIncludedByDefault Remove="Components\RegLookupVatNo.razor" />
<_ContentIncludedByDefault Remove="Components\RegStateVatNumber.razor" />
<_ContentIncludedByDefault Remove="Components\SalesItemGroupFilter.razor" />
<_ContentIncludedByDefault Remove="Components\SalesItemSearchField.razor" />
<_ContentIncludedByDefault Remove="Components\SalesItemSort.razor" />
<_ContentIncludedByDefault Remove="Components\SalesItemTable.razor" />
<_ContentIncludedByDefault Remove="Components\SearchPhrase.razor" />
</ItemGroup>
</Project>

View file

@ -6,12 +6,12 @@
@using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using Wonky.Client
@using Wonky.Client.Shared
@using Blazored.Toast @using Blazored.Toast
@using Blazored.Toast.Services @using Blazored.Toast.Services
@using Blazored.Toast.Configuration @using Blazored.Toast.Configuration
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting @using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Authorization
@using DnetIndexedDb
@using Wonky.Entity @using Wonky.Entity
@using Wonky.Virk

View file

@ -1,19 +1,21 @@
{ {
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Debug", "Default": "Debug",
"System": "Debug", "System": "Debug",
"Microsoft": "Information" "Microsoft": "Information"
}
},
"apiConfig": {
"baseAddress": "https://api.innotec.dk",
"tokenPath": "token",
"userInfo": "api/auth/userinfo",
"crmCompanies": "api/v2/crm/companies",
"priceCatalog": "api/v2/crm/catalog",
"cvrLookup": "/api/v2/services/virk",
"krvProducts": "api/v2/admin/q/products",
"krvVariants": "api/v2/admin/q/variants",
"imageUpload": "api/v2/admin/upload2",
"userRegistration": "api/auth/register"
} }
},
"apiConfig": {
"baseAddress": "https://api.innotec.dk",
"tokenPath": "token",
"userInfo": "api/auth/userinfo",
"crmCompanies": "api/v2/crm/companies/page",
"priceCatalog": "api/v2/crm/catalog/page",
"cvrLookup": "/api/v2/services/virk",
"imageUpload": "api/v2/admin/upload2",
"userRegistration": "api/auth/register"
}
} }

View file

@ -22,10 +22,6 @@ a, .btn-link {
border-color: #1861ac; border-color: #1861ac;
} }
.card {
padding: 0;
}
.content { .content {
padding-top: 1.1rem; padding-top: 1.1rem;
} }

Some files were not shown because too many files have changed in this diff Show more