Skip to content

Commit bd6ee8a

Browse files
committed
Improved the table of market orders on the entry detail.
Added a option to show the detail via a dialog of the market order by clicking on a table row.
1 parent 6c1c0e2 commit bd6ee8a

File tree

3 files changed

+142
-51
lines changed

3 files changed

+142
-51
lines changed

WebFrontend/Pages/PortfolioDetail.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<MatH4 Class="clear-margin">@(CurrencyUtils.Format(PortfolioSummary.MarketValue, ActivePortfolio.Currency))</MatH4>
6262
</div>
6363
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-6" style="text-align: end">
64-
@(PortfolioSummary.RelativeChange * 100m) %
64+
@(DecimalUtils.FormatTwoDecimalPlacesWithPlusSign(PortfolioSummary.RelativeChange * 100m)) %
6565
</div>
6666
}
6767
else

WebFrontend/Pages/PortfolioEntryDetail.razor

Lines changed: 111 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@
5050
<div class="demo-mat-card-content">
5151
<MatHeadline6 class="clear-margin">
5252
<MatChipSet Style="align-items: center">
53-
@if (portfolioEntryName != null)
53+
@if (PortfolioEntryName != null)
5454
{
55-
<MatH5 Class="clear-margin-vertical">@portfolioEntryName</MatH5>
55+
<MatH5 Class="clear-margin-vertical">@PortfolioEntryName</MatH5>
5656
}
5757
else
5858
{
@@ -114,73 +114,112 @@
114114
}
115115
</MatCardContent>
116116
</MatCard>
117-
@if (tableRowsItems == null)
117+
@if (TableRowsItems == null)
118118
{
119119
<MatProgressBar Indeterminate="true"></MatProgressBar>
120120
}
121-
else if (tableRowsItems.Count == 0)
121+
else if (TableRowsItems.Count == 0)
122122
{
123123
<MatH6>No entries found...</MatH6>
124124
}
125125
else
126126
{
127-
<MatTable Items="@tableRowsItems" Striped="true" AllowSelection="true" RowClass="tester" class="mat-elevation-z5" ShowPaging="false" PageSize="9999">
128-
<MatTableHeader>
129-
<th>Date</th>
130-
<th>Size</th>
131-
<th>Market Value</th>
132-
<th>Change</th>
133-
<th>Cost</th>
134-
<th>Fee</th>
135-
<th>Actions</th>
136-
</MatTableHeader>
137-
<MatTableRow>
138-
<td>
139-
<div style="min-width: 9rem">@(String.Format("{0:d.M.yyyy HH:mm:ss}", context.Item1.Date))</div>
140-
</td>
141-
<td>
142-
<div style="min-width: 9rem">@context.Item1.Size @ActivePortfolioEntry.Symbol.ToUpper()</div>
143-
</td>
144-
<td>@CurrencyUtils.Format(context.Item2.MarketValue, ActivePortfolio.Currency)</td>
145-
<td style='color: @(context.Item2.RelativeChange >= 0 ? "#17a104" : "#FF0000")'>
146-
<div style="min-width: 9rem">@CurrencyUtils.Format(context.Item2.AbsoluteChange, ActivePortfolio.Currency) (@(DecimalUtils.FormatTwoDecimalPlaces(context.Item2.RelativeChange * 100))%)</div>
147-
</td>
148-
<td>@CurrencyUtils.Format(context.Item2.Cost, ActivePortfolio.Currency)</td>
149-
<td>@CurrencyUtils.Format(context.Item1.Fee, ActivePortfolio.Currency)</td>
150-
<td>
151-
<MatIconButton Icon="edit" OnClick="EditMarketOrder"></MatIconButton>
152-
<MatIconButton Icon="delete" OnClick="() => DeletePortfolio(context.Item1)"></MatIconButton>
153-
</td>
154-
</MatTableRow>
155-
</MatTable>
127+
<MatTable Items="@TableRowsItems" Striped="true" AllowSelection="true" RowClass="tester" class="mat-elevation-z5" ShowPaging="false" PageSize="9999" SelectionChanged="SelectionChangedEvent">
128+
<MatTableHeader>
129+
<th>Date</th>
130+
<th>Size</th>
131+
<th>Price</th>
132+
<th>Market Value</th>
133+
<th>Change</th>
134+
<th>Actions</th>
135+
</MatTableHeader>
136+
<MatTableRow>
137+
<td>
138+
<div style="min-width: 9rem">@(String.Format("{0:d.M.yyyy HH:mm:ss}", context.Item1.Date))</div>
139+
</td>
140+
<td>
141+
<div style="min-width: 8rem">@context.Item1.Size @ActivePortfolioEntry.Symbol.ToUpper()</div>
142+
</td>
143+
<td>
144+
<div style="min-width: 8rem">@(CurrencyUtils.Format(context.Item1.FilledPrice, ActivePortfolio.Currency))</div>
145+
</td>
146+
<td>
147+
<div style="min-width: 9.2rem">@CurrencyUtils.Format(context.Item2.MarketValue, ActivePortfolio.Currency)</div>
148+
</td>
149+
<td style='color: @(context.Item2.RelativeChange >= 0 ? "#17a104" : "#FF0000")'>
150+
<div style="min-width: 9rem">@CurrencyUtils.Format(context.Item2.AbsoluteChange, ActivePortfolio.Currency) (@(DecimalUtils.FormatTwoDecimalPlaces(context.Item2.RelativeChange * 100))%)</div>
151+
</td>
152+
<td>
153+
<MatIconButton Icon="edit" OnClick="EditMarketOrder"></MatIconButton>
154+
<MatIconButton Icon="delete" OnClick="() => DeletePortfolio(context.Item1)"></MatIconButton>
155+
</td>
156+
</MatTableRow>
157+
</MatTable>
156158
}
157159
</div>
158160
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-2"></div>
159161
</div>
160162
</div>
161163
<MatFAB Class="app-fab--absolute" Icon="@MatIconNames.Add" Label="Add a new order" OnClick='() => { NavigationManager.NavigateTo($"newmarketorder/{ActivePortfolioEntry.Id}");}'></MatFAB>
162164

165+
<MatDialog @bind-IsOpen="@OrderDetailDialogIsOpen">
166+
<MatDialogTitle>Market Order Detail</MatDialogTitle>
167+
<MatDialogContent>
168+
@if (OrderToBeShown != null)
169+
{
170+
<div class="mat-layout-grid">
171+
<div class="mat-layout-grid-inner" style="align-items: center">
172+
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-6">
173+
<LabelDecimalValue Smaller="true" Value="@($"{ActivePortfolioEntry.Symbol.ToUpper()}/{CurrencyUtils.GetCurrencyLabel(ActivePortfolio.Currency)}")" Label="Trading Pair"></LabelDecimalValue>
174+
</div>
175+
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-6" style="text-align: right">
176+
<LabelDecimalValue Smaller="true" Value="@(CurrencyUtils.Format(OrderToBeShown.Item1.FilledPrice, ActivePortfolio.Currency))" Label="Price"></LabelDecimalValue>
177+
</div>
178+
</div>
179+
<div class="mat-layout-grid-inner" style="align-items: center; margin-top: 2rem;">
180+
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-6">
181+
<LabelDecimalValue Smaller="true" Value="@(CurrencyUtils.Format(OrderToBeShown.Item1.Fee, ActivePortfolio.Currency))" Label="Fee"></LabelDecimalValue>
182+
</div>
183+
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-6" style="text-align: right">
184+
<LabelDecimalValue Smaller="true" Value="@(CurrencyUtils.Format(OrderToBeShown.Item2.Cost + OrderToBeShown.Item1.Fee, ActivePortfolio.Currency))" Label="Cost (fees included)"></LabelDecimalValue>
185+
</div>
186+
</div>
187+
<div class="mat-layout-grid-inner" style="align-items: center;margin-top: 2rem; ">
188+
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-6">
189+
<LabelDecimalValue Smaller="true" ValueColorBasedOnValue="true" Positive="@(OrderToBeShown.Item2.RelativeChange >= 0)" Value="@(DecimalUtils.FormatTwoDecimalPlaces(OrderToBeShown.Item2.RelativeChange * 100) + "%")" Label="Change"></LabelDecimalValue>
190+
</div>
191+
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-6" style="text-align: right">
192+
<LabelDecimalValue Smaller="true" Value="@(CurrencyUtils.Format(OrderToBeShown.Item1.Size * CurrentEntryAssetMarketEntry.CurrentPrice, ActivePortfolio.Currency))" Label="Current Value"></LabelDecimalValue>
193+
</div>
194+
</div>
195+
</div>
196+
}
197+
</MatDialogContent>
198+
<MatDialogActions>
199+
<MatButton OnClick="@HideOrderDetail">Close</MatButton>
200+
</MatDialogActions>
201+
</MatDialog>
163202

164203
@code
165204
{
205+
//SummaryService.GetMarketOrderSummary(OrderToBeShown, CurrentEntryAssetMarketEntry.CurrentPrice).RelativeChange, ActivePortfolio.Currency)
166206
[Parameter]
167207
public int EntryId { get; set; }
168208

169209
protected Portfolio ActivePortfolio;
170210
protected PortfolioEntry ActivePortfolioEntry;
171211
protected MarketEntry CurrentEntryAssetMarketEntry;
172-
protected string portfolioEntryName = "Bitcoin";
173-
protected ISummaryService.Summary EntrySummary = new(523m, 0.719m, 1268.89m, 745.58m);
212+
protected string PortfolioEntryName = "Bitcoin";
213+
protected ISummaryService.Summary EntrySummary;
174214
protected decimal TotalHoldings = 0;
215+
216+
217+
protected bool OrderDetailDialogIsOpen;
218+
protected Tuple<MarketOrder, ISummaryService.Summary> OrderToBeShown;
219+
220+
175221

176-
protected List<Tuple<MarketOrder, ISummaryService.Summary>> tableRowsItems = new()
177-
{
178-
new Tuple<MarketOrder, ISummaryService.Summary>(new(18300m, 0.1m, 0.003266m, DateTime.Now.AddMonths(-6), false), new(120m, 2m, 183.00m, 60m)),
179-
new Tuple<MarketOrder, ISummaryService.Summary>(new(21200, 0.3m, 0.002866m, DateTime.Now.AddDays(91), false), new(101m, 2m, 123.00m, 45m)),
180-
new Tuple<MarketOrder, ISummaryService.Summary>(new(18300m, 0.1m, 0.003266m, DateTime.Now.AddMonths(-6), false), new(180m - 30m, 2.3m, 113.00m, 23m)),
181-
new Tuple<MarketOrder, ISummaryService.Summary>(new(18300m, 0.1m, 0.003266m, DateTime.Now.AddMonths(-6), false), new(-60m, -0.6m, 40.00m, 100m)),
182-
};
183-
222+
protected List<Tuple<MarketOrder, ISummaryService.Summary>> TableRowsItems;
184223

185224
protected override void OnInitialized()
186225
{
@@ -194,15 +233,15 @@
194233
protected override async Task OnInitializedAsync()
195234
{
196235
// resolve the name of the cryptocurrency (using the symbol)
197-
portfolioEntryName = await CryptoNameResolver.Resolve(ActivePortfolioEntry.Symbol);
236+
PortfolioEntryName = await CryptoNameResolver.Resolve(ActivePortfolioEntry.Symbol);
198237

199238
await UpdateEntrySummary();
200239
}
201240

202241
private void SetEntryLoading()
203242
{
204243
CurrentEntryAssetMarketEntry = null;
205-
tableRowsItems = null;
244+
TableRowsItems = null;
206245
EntrySummary = null;
207246
StateHasChanged();
208247
}
@@ -214,7 +253,7 @@
214253
// TODO null?
215254
CurrentEntryAssetMarketEntry = (await CryptoStatsSource.GetMarketEntries(
216255
CurrencyUtils.GetCurrencyLabel(ActivePortfolio.Currency).ToLower(),
217-
portfolioEntryName.ToLower()
256+
PortfolioEntryName.ToLower()
218257
))[0];
219258

220259
// get all orders of the portfolio entry
@@ -227,7 +266,7 @@
227266
TotalHoldings = entryOrders.Sum(order => order.Size * (order.Buy ? 1 : -1));
228267

229268
// zip entry orders and summaries into a table rows
230-
tableRowsItems = entryOrders.Zip(entrySummaries)
269+
TableRowsItems = entryOrders.Zip(entrySummaries)
231270
.Select(tuple => new Tuple<MarketOrder, ISummaryService.Summary>(tuple.First, tuple.Second)).ToList();
232271

233272
// compute suummary of this entry
@@ -251,4 +290,29 @@
251290
Toaster.Add("Order successfully deleted", MatToastType.Success, "", "");
252291
}
253292
}
293+
294+
void ShowOrderDetail(Tuple<MarketOrder, ISummaryService.Summary> order)
295+
{
296+
Console.WriteLine("here");
297+
OrderToBeShown = order;
298+
OrderDetailDialogIsOpen = true;
299+
StateHasChanged();
300+
}
301+
302+
void HideOrderDetail()
303+
{
304+
OrderToBeShown = null;
305+
OrderDetailDialogIsOpen = false;
306+
StateHasChanged();
307+
}
308+
309+
private void SelectionChangedEvent(object obj)
310+
{
311+
Console.WriteLine("show dialog");
312+
if (obj != null)
313+
{
314+
Console.WriteLine("showing dialog");
315+
ShowOrderDetail((Tuple<MarketOrder, ISummaryService.Summary>) obj) ;
316+
}
317+
}
254318
}

WebFrontend/Shared/LabelDecimalValue.razor

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,41 @@
55
66
.label {
77
color: #6f6f6f;
8+
9+
text-transform: uppercase;
10+
}
11+
12+
.label-normal {
813
letter-spacing: 0.1rem;
914
font-size: 1.1em;
10-
text-transform: uppercase;
15+
}
16+
17+
.label-small {
18+
letter-spacing: 0.09rem;
19+
font-size: 0.9em;
1120
}
1221
1322
.value {
1423
margin-top: 1rem;
24+
color: #000000;
25+
}
26+
27+
.value-small {
28+
margin-top: 0.3rem;
29+
color: #000000;
1530
}
1631
</style>
17-
<span Class="no-margin label">@Label</span>
18-
<MatH4 Class="no-margin value" style="@(ValueColorBasedOnValue ? !Positive ? "color:red" : "color: #17a104" : "")">@Value</MatH4>
32+
33+
@if (!Smaller)
34+
{
35+
<span Class="no-margin label label-normal">@Label</span>
36+
<MatH4 Class="no-margin value" style="@(ValueColorBasedOnValue ? !Positive ? "color:red" : "color: #17a104" : "")">@Value</MatH4>
37+
}
38+
else
39+
{
40+
<span Class="no-margin label label-small">@Label</span>
41+
<MatH6 Class="no-margin value-small" style="@(ValueColorBasedOnValue ? !Positive ? "color:red" : "color: #17a104" : "")">@Value</MatH6>
42+
}
1943

2044
@code {
2145

@@ -31,4 +55,7 @@
3155
[Parameter]
3256
public bool Positive { get; set; } = true;
3357

58+
[Parameter]
59+
public bool Smaller { get; set; }
60+
3461
}

0 commit comments

Comments
 (0)