Skip to content

Commit 711ff70

Browse files
committed
Improved the NewPortfolioEntry.razor
- removed the table listing all portfolio entries - added an IconButton to Available Cryptocurrencies table that deletes the Cryptocurrency from the portfolio (only if the Cryptocurrency is present in the portfolio)
1 parent b6213a2 commit 711ff70

File tree

1 file changed

+101
-42
lines changed

1 file changed

+101
-42
lines changed

WebFrontend/Pages/NewPortfolioEntry.razor

Lines changed: 101 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
@using System.ComponentModel.DataAnnotations
66
@using CryptoStatsSource
77
@using CryptoStatsSource.model
8+
@using Repository
89
@inject IPortfolioService PortfolioService
910
@inject IPortfolioEntryService PortfolioEntryService
1011
@inject ICryptoStatsSource CryptoStatsSource;
1112
@inject IMatDialogService MatDialogService
1213
@inject IMatToaster Toaster
13-
14+
@inject Microsoft.AspNetCore.Components.NavigationManager NavigationManager
1415

1516
<style>
1617
.demo-mat-card {
@@ -29,50 +30,85 @@
2930

3031
<div class="mat-layout-grid">
3132
<div class="mat-layout-grid-inner">
32-
<div class="mat-layout-grid-cell">
33-
<MatH5>Add a new portfolio entry for @Portfolio.Name</MatH5>
34-
<MatTable Items="@AvailableCryptocurrencies" Striped="true" RowClass="tester" PageSize="10"
35-
FilterByColumnName="Symbol" DebounceMilliseconds="150" class="mat-elevation-z5" OnRowDbClick="(w) => { OnAvailableCurrencyClicked((Cryptocurrency) w); }">
36-
37-
<MatTableHeader>
38-
<th>Name</th>
39-
<th>Symbol</th>
40-
<th></th>
41-
</MatTableHeader>
42-
<MatTableRow>
43-
<td>@context.Name</td>
44-
<td>@context.Symbol</td>
45-
<td><MatButton Icon="add" Alignment OnClick="() => { OnAvailableCurrencyClicked(context);}" Style="float: right"></MatButton></td>
46-
</MatTableRow>
47-
</MatTable>
48-
</div>
49-
<div class="mat-layout-grid-cell">
50-
<MatH5>Current portfolio entries</MatH5>
51-
<MatTable Items="@PortfolioEntries" Striped="true" AllowSelection="true" RowClass="tester" class="mat-elevation-z5" ShowPaging="false" PageSize="9999">
52-
<MatTableHeader>
53-
<th>Name</th>
54-
<th>Symbol</th>
55-
</MatTableHeader>
56-
<MatTableRow>
57-
<td>@context.Symbol</td>
58-
<td>@context.Symbol</td>
59-
</MatTableRow>
60-
</MatTable>
61-
</div>
33+
<div class="mat-layout-grid-cell-span-6">
34+
<MatH5><MatButton Outlined="true" Icon="keyboard_arrow_left" Style="margin-right: 1rem;" OnClick='() => { NavigationManager.NavigateTo($"/portfolio/{Portfolio.Id}"); }'>Back</MatButton>Manage entries of <b>@Portfolio.Name</b></MatH5>
35+
<MatTextField Label="Filter by symbol" Style="margin-bottom: 2rem;" Icon="filter_list" FullWidth="true" @bind-Value="@CryptocurrencyFilter"></MatTextField>
36+
@if (AvailableCryptocurrenciesWithUsage == null)
37+
{
38+
<MatProgressBar Indeterminate="true"></MatProgressBar>
39+
}
40+
else
41+
{
42+
@if (AvailableCryptocurrenciesWithUsage.Count > 0)
43+
{
44+
<MatTable Items="@AvailableCryptocurrenciesWithUsage" Striped="true" RowClass="tester" PageSize="10"
45+
DebounceMilliseconds="150" class="mat-elevation-z5">
6246

47+
<MatTableHeader>
48+
<th>Symbol</th>
49+
<th>Name</th>
50+
<th></th>
51+
</MatTableHeader>
52+
<MatTableRow>
53+
<td>@context.Item1.Symbol</td>
54+
<td>
55+
<div style="min-width: 12em">@context.Item1.Name</div>
56+
</td>
57+
@if (context.Item2)
58+
{
59+
<td>
60+
<MatIconButton Icon="add" Alignment OnClick="() => { OnAddCurrencyClicked(context.Item1); }" Style="float: right"></MatIconButton>
61+
</td>
62+
}
63+
else
64+
{
65+
<td>
66+
<MatIconButton Icon="delete" Alignment OnClick="() => { OnDeleteCurrencyClicked(context.Item1); }" Style="float: right"></MatIconButton>
67+
</td>
68+
}
69+
</MatTableRow>
70+
</MatTable>
71+
}
72+
else
73+
{
74+
<MatH6>No cryptocurrencies match the symbol \"@CryptocurrencyFilter\"</MatH6>
75+
}
76+
}
77+
</div>
6378
</div>
6479
</div>
6580

6681

6782
@code
6883
{
84+
public string CryptocurrencyFilter
85+
{
86+
get => _cryptocurrencyFilter;
87+
set
88+
{
89+
_cryptocurrencyFilter = value;
90+
FilterCurrenciesBySymbol(value);
91+
this.StateHasChanged();
92+
}
93+
}
94+
95+
private void FilterCurrenciesBySymbol(string value)
96+
{
97+
FilteredCryptocurrencies = AvailableCryptocurrencies.FindAll(c => c.Symbol.Contains(value));
98+
UpdateAvailableCryptocurrencies(FilteredCryptocurrencies);
99+
}
100+
101+
private string _cryptocurrencyFilter;
102+
69103
[Parameter]
70104
public int PortfolioId { get; set; }
71105

72106
protected Portfolio Portfolio;
73107
protected List<PortfolioEntry> PortfolioEntries;
74108

75109
protected List<Cryptocurrency> AvailableCryptocurrencies;
110+
protected List<Cryptocurrency> FilteredCryptocurrencies;
111+
protected List<Tuple<Cryptocurrency, bool>> AvailableCryptocurrenciesWithUsage;
76112

77113
protected override void OnInitialized()
78114
{
@@ -82,19 +118,42 @@
82118

83119
protected override async Task OnInitializedAsync()
84120
{
85-
var entriesSymbols = PortfolioEntries.Select(e => e.Symbol);
86-
AvailableCryptocurrencies = (await CryptoStatsSource.GetAvailableCryptocurrencies()).FindAll(
87-
c => !entriesSymbols.Contains(c.Symbol)
88-
).OrderBy(c => c.Symbol.Length).ToList();
89-
90-
121+
AvailableCryptocurrencies = await CryptoStatsSource.GetAvailableCryptocurrencies();
122+
FilteredCryptocurrencies = AvailableCryptocurrencies;
123+
UpdateAvailableCryptocurrencies(AvailableCryptocurrencies);
91124
}
92125

93-
private void OnAvailableCurrencyClicked(Cryptocurrency cryptocurrency)
126+
private void UpdateAvailableCryptocurrencies(List<Cryptocurrency> availableCryptocurrencies)
94127
{
95-
Console.WriteLine("OnAvailableCurrencyClicked");
96-
PortfolioEntryService.CreatePortfolioEntry(cryptocurrency.Symbol, PortfolioId);
97-
AvailableCryptocurrencies.Remove(cryptocurrency);
98-
PortfolioEntries = PortfolioEntryService.GetPortfolioEntries(PortfolioId);
128+
var entriesSymbols = PortfolioEntries.Select(e => e.Symbol.ToLower());
129+
AvailableCryptocurrenciesWithUsage = availableCryptocurrencies.Select(
130+
c => new Tuple<Cryptocurrency, bool>(c, !entriesSymbols.Contains(c.Symbol.ToLower()))
131+
).OrderBy(c => c.Item1.Symbol.Length).ToList();
132+
}
133+
134+
private void OnAddCurrencyClicked(Cryptocurrency cryptocurrency)
135+
{
136+
Console.WriteLine("OnAddCurrencyClicked");
137+
var entry = PortfolioEntryService.CreatePortfolioEntry(cryptocurrency.Symbol, PortfolioId);
138+
PortfolioEntries.Add(entry);
139+
UpdateAvailableCryptocurrencies(FilteredCryptocurrencies);
140+
StateHasChanged();
141+
Toaster.Add($"{cryptocurrency.Symbol.ToUpper()} entry successfully added to {Portfolio.Name}.", MatToastType.Success, "", "");
142+
}
143+
144+
private async void OnDeleteCurrencyClicked(Cryptocurrency cryptocurrency)
145+
{
146+
Console.WriteLine("OnDeleteCurrencyClicked");
147+
// TODO display confirmation dialog only when entry orders exist
148+
var result = await MatDialogService.ConfirmAsync($"Do you really wish to delete {cryptocurrency.Symbol.ToUpper()} entry including all of it's market entries?");
149+
if (result)
150+
{
151+
var entry = PortfolioEntries.Find(entry => entry.Symbol == cryptocurrency.Symbol);
152+
PortfolioEntryService.DeletePortfolioEntry(entry);
153+
PortfolioEntries.Remove(entry);
154+
UpdateAvailableCryptocurrencies(FilteredCryptocurrencies);
155+
StateHasChanged();
156+
Toaster.Add($"{cryptocurrency.Symbol.ToUpper()} entry successfully deleted from {Portfolio.Name}.", MatToastType.Success, "", "");
157+
}
99158
}
100159
}

0 commit comments

Comments
 (0)