Skip to content

Commit 1b90515

Browse files
committed
Created EntryForm.razor component representing a form to input entry details.
Added a EditMarketOrder.razor page. Fixed a link on the PortfolioEntryDetail.razor page.
1 parent 5155b40 commit 1b90515

File tree

4 files changed

+189
-112
lines changed

4 files changed

+189
-112
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
@page "/editmarketorder/{orderId:int}"
2+
@using Model
3+
@using Services
4+
@inject IPortfolioService PortfolioService
5+
@inject IPortfolioEntryService PortfolioEntrySerivce
6+
@inject IMarketOrderService MarketOrderService
7+
@inject IMatDialogService MatDialogService
8+
@inject IMatToaster Toaster
9+
@inject Microsoft.AspNetCore.Components.NavigationManager NavigationManager
10+
11+
12+
<style>
13+
.demo-mat-card-content {
14+
padding: 1rem;
15+
}
16+
</style>
17+
18+
<div class="mat-layout-grid">
19+
<div class="mat-layout-grid-inner">
20+
<div class="mat-layout-grid-cell">
21+
<MatButton Outlined="true" Icon="keyboard_arrow_left" Style="margin-bottom: 1rem;" OnClick='() => { NavigationManager.NavigateTo($"/entries/{ActiveEntry.Id}"); }'>Back</MatButton>
22+
<MatCard>
23+
<MatCardContent class="demo-mat-card-content">
24+
<h2>Edit a market order</h2>
25+
<EntryForm Edit="true" FormModel="@InitialOrderModel" Currency="@ActivePortfolio.Currency" Symbol="@ActiveEntry.Symbol" OnSubmitEventHandler="@OnCreateOrderFormSubmit" ></EntryForm>
26+
</MatCardContent>
27+
</MatCard>
28+
</div>
29+
</div>
30+
</div>
31+
32+
33+
@code
34+
{
35+
[Parameter]
36+
public int OrderId { get; set; }
37+
38+
protected EntryForm.NewOrderModel InitialOrderModel;
39+
protected Portfolio ActivePortfolio;
40+
protected PortfolioEntry ActiveEntry;
41+
protected MarketOrder ActiveMarketOrder;
42+
43+
protected override void OnInitialized()
44+
{
45+
ActiveMarketOrder = MarketOrderService.GetMarketOrder(OrderId);
46+
ActiveEntry = PortfolioEntrySerivce.GetPortfolioEntry(ActiveMarketOrder.PortfolioEntryId);
47+
ActivePortfolio = PortfolioService.GetPortfolio(ActiveEntry.PortfolioId);
48+
InitialOrderModel = new();
49+
InitialOrderModel.Fee = ActiveMarketOrder.Fee;
50+
InitialOrderModel.Size = ActiveMarketOrder.Size;
51+
InitialOrderModel.FilledPrice = ActiveMarketOrder.FilledPrice;
52+
InitialOrderModel.OrderDate = ActiveMarketOrder.Date;
53+
}
54+
55+
private void OnCreateOrderFormSubmit(EntryForm.NewOrderModel formModel)
56+
{
57+
// TODO enable adding sells
58+
MarketOrderService.UpdateMarketOrder(ActiveMarketOrder with {
59+
FilledPrice = formModel.FilledPrice,
60+
Fee = formModel.Fee,
61+
Size = formModel.Size,
62+
Date = formModel.OrderDate,
63+
Buy = true
64+
});
65+
Toaster.Add("Order successfully edited", MatToastType.Success, "", "");
66+
NavigationManager.NavigateTo($"/entries/{ActiveEntry.Id}");
67+
}
68+
}
Lines changed: 5 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
@page "/newmarketorder/{entryId:int}"
22
@using Model
33
@using Services
4-
@using Utils
5-
@using System.ComponentModel.DataAnnotations
64
@inject IPortfolioService PortfolioService
75
@inject IPortfolioEntryService PortfolioEntrySerivce
86
@inject IMarketOrderService MarketOrderService
@@ -12,17 +10,9 @@
1210

1311

1412
<style>
15-
.demo-mat-card {
16-
margin-bottom: 2em;
17-
}
18-
1913
.demo-mat-card-content {
2014
padding: 1rem;
2115
}
22-
23-
.clear-margin {
24-
margin: 0px;
25-
}
2616
</style>
2717

2818
<div class="mat-layout-grid">
@@ -32,47 +22,7 @@
3222
<MatCard>
3323
<MatCardContent class="demo-mat-card-content">
3424
<h2>Create a new market order</h2>
35-
<EditForm Model="FormModel" OnValidSubmit="OnCreateOrderFormSubmit">
36-
<DataAnnotationsValidator/>
37-
<p>
38-
<MatTextField FullWidth="true" Label="@("Price per coin (" + CurrencyUtils.GetCurrencyLabel(ActivePortfolio.Currency) + ")")"
39-
@bind-Value=@FormModel.FilledPrice>
40-
</MatTextField>
41-
<ValidationMessage For="@(() => FormModel.FilledPrice)"/>
42-
</p>
43-
44-
<p>
45-
<MatTextField FullWidth="true" Label="@("Traded size (" + ActiveEntry.Symbol.ToUpper() + ")")"
46-
@bind-Value=@FormModel.Size>
47-
</MatTextField>
48-
<ValidationMessage For="@(() => FormModel.Size)"/>
49-
</p>
50-
51-
<p>
52-
<MatTextField FullWidth="true" Label="@("Fee (" + CurrencyUtils.GetCurrencyLabel(ActivePortfolio.Currency) + ")")"
53-
@bind-Value=@FormModel.Fee>
54-
</MatTextField>
55-
<ValidationMessage For="@(() => FormModel.Fee)"/>
56-
</p>
57-
58-
<p>
59-
<br>
60-
<b>Order date</b>
61-
</p>
62-
<p>
63-
<MatDatePicker FullWidth="true" @bind-Value="@FormModel.OrderDate" Enable24hours="true" Required="true" Format="MM.dd.yy H:mm:ss" EnableTime="true"></MatDatePicker>
64-
<ValidationMessage For="@(() => FormModel.OrderDate)"/>
65-
</p>
66-
<MatCardActions>
67-
<MatCardActionButtons>
68-
<MatButton Type="submit">Create</MatButton>
69-
</MatCardActionButtons>
70-
71-
<MatCardActionIcons>
72-
<MatIconButton Icon="@MatIconNames.Refresh" OnClick="(_) => FormModel.Reset()"></MatIconButton>
73-
</MatCardActionIcons>
74-
</MatCardActions>
75-
</EditForm>
25+
<EntryForm Currency="@ActivePortfolio.Currency" Symbol="@ActiveEntry.Symbol" OnSubmitEventHandler="@OnCreateOrderFormSubmit" ></EntryForm>
7626
</MatCardContent>
7727
</MatCard>
7828
</div>
@@ -87,71 +37,18 @@
8737

8838
protected Portfolio ActivePortfolio = new("", "", Currency.Usd);
8939
protected PortfolioEntry ActiveEntry = new("btc", 1);
90-
protected NewOrderModel FormModel = new();
91-
92-
public class NewOrderModel
93-
{
94-
[Required]
95-
[CustomValidation(typeof(NewOrderModel), nameof(NonZeroValue))]
96-
public decimal FilledPrice { get; set; }
97-
98-
[Required]
99-
[CustomValidation(typeof(NewOrderModel), nameof(NonZeroValue))]
100-
public decimal Size { get; set; }
101-
102-
[Required]
103-
[CustomValidation(typeof(NewOrderModel), nameof(NonNegativeValue))]
104-
public decimal Fee { get; set; }
105-
106-
[Required] public DateTime OrderDate = DateTime.Now;
107-
108-
public void Reset()
109-
{
110-
FilledPrice = 0m;
111-
Size = 0m;
112-
Fee = 0m;
113-
OrderDate = DateTime.Now;
114-
}
115-
116-
public static ValidationResult NonZeroValue(decimal value, ValidationContext vc)
117-
{
118-
return value > 0
119-
? ValidationResult.Success
120-
: new ValidationResult("Value must be non-zero", new[] {vc.MemberName});
121-
}
122-
123-
public static ValidationResult NonNegativeValue(decimal value, ValidationContext vc)
124-
{
125-
return value >= 0
126-
? ValidationResult.Success
127-
: new ValidationResult("Value must be positive", new[] {vc.MemberName});
128-
}
129-
}
13040

13141
protected override void OnInitialized()
13242
{
13343
ActiveEntry = PortfolioEntrySerivce.GetPortfolioEntry(EntryId);
13444
ActivePortfolio = PortfolioService.GetPortfolio(ActiveEntry.PortfolioId);
13545
}
13646

137-
protected override async Task OnInitializedAsync()
138-
{
139-
}
140-
141-
private void onCreateOrderClicked()
142-
{
143-
Toaster.Add("New order successfully added", MatToastType.Success, "", "");
144-
}
145-
146-
private void onCreateAndContinueOrderClicked()
147-
{
148-
Toaster.Add("New order successfully added", MatToastType.Danger, "", "");
149-
}
150-
151-
private void OnCreateOrderFormSubmit()
47+
private void OnCreateOrderFormSubmit(EntryForm.NewOrderModel formModel)
15248
{
153-
MarketOrderService.CreateMarketOrder(FormModel.FilledPrice, FormModel.Fee, FormModel.Size, FormModel.OrderDate, true, ActiveEntry.Id);
154-
FormModel.Reset();
49+
Console.WriteLine("OnCreateOrderFormSubmit " + formModel);
50+
MarketOrderService.CreateMarketOrder(formModel.FilledPrice, formModel.Fee, formModel.Size, formModel.OrderDate, true, ActiveEntry.Id);
51+
formModel.Reset();
15552
Toaster.Add("New order successfully added", MatToastType.Success, "", "");
15653
}
15754
}

WebFrontend/Pages/PortfolioEntryDetail.razor

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
<div style="min-width: 9rem">@CurrencyUtils.Format(context.Item2.AbsoluteChange, ActivePortfolio.Currency) (@(DecimalUtils.FormatTwoDecimalPlaces(context.Item2.RelativeChange * 100))%)</div>
151151
</td>
152152
<td>
153-
<MatIconButton Icon="edit" OnClick="EditMarketOrder"></MatIconButton>
153+
<MatIconButton Icon="edit" OnClick="() => EditMarketOrder(context.Item1)"></MatIconButton>
154154
<MatIconButton Icon="delete" OnClick="() => DeletePortfolio(context.Item1)"></MatIconButton>
155155
</td>
156156
</MatTableRow>
@@ -181,7 +181,7 @@
181181
<LabelDecimalValue Smaller="true" Value="@(CurrencyUtils.Format(OrderToBeShown.Item1.Fee, ActivePortfolio.Currency))" Label="Fee"></LabelDecimalValue>
182182
</div>
183183
<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>
184+
<LabelDecimalValue Smaller="true" Value="@(CurrencyUtils.Format(OrderToBeShown.Item2.Cost, ActivePortfolio.Currency))" Label="Cost (fees included)"></LabelDecimalValue>
185185
</div>
186186
</div>
187187
<div class="mat-layout-grid-inner" style="align-items: center;margin-top: 2rem; ">
@@ -273,9 +273,9 @@
273273
EntrySummary = SummaryService.GetPortfolioEntrySummary(entryOrders, CurrentEntryAssetMarketEntry.CurrentPrice);
274274
}
275275

276-
public void EditMarketOrder(MouseEventArgs e)
276+
public void EditMarketOrder(MarketOrder order)
277277
{
278-
NavigationManager.NavigateTo($"editorder");
278+
NavigationManager.NavigateTo($"/editmarketorder/{order.Id}");
279279
}
280280

281281
async void DeletePortfolio(MarketOrder order)

WebFrontend/Shared/EntryForm.razor

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
@using Utils
2+
@using System.ComponentModel.DataAnnotations
3+
@using Model
4+
<EditForm Model="FormModel" OnValidSubmit="OnCreateOrderFormSubmit">
5+
<DataAnnotationsValidator/>
6+
<p>
7+
<MatTextField FullWidth="true" Label="@("Price per coin (" + CurrencyUtils.GetCurrencyLabel(Currency) + ")")"
8+
@bind-Value=@FormModel.FilledPrice>
9+
</MatTextField>
10+
<ValidationMessage For="@(() => FormModel.FilledPrice)"/>
11+
</p>
12+
13+
<p>
14+
<MatTextField FullWidth="true" Label="@("Traded size (" + Symbol.ToUpper() + ")")"
15+
@bind-Value=@FormModel.Size>
16+
</MatTextField>
17+
<ValidationMessage For="@(() => FormModel.Size)"/>
18+
</p>
19+
20+
<p>
21+
<MatTextField FullWidth="true" Label="@("Fee (" + CurrencyUtils.GetCurrencyLabel(Currency) + ")")"
22+
@bind-Value=@FormModel.Fee>
23+
</MatTextField>
24+
<ValidationMessage For="@(() => FormModel.Fee)"/>
25+
</p>
26+
27+
<p>
28+
<br>
29+
<b>Order date</b>
30+
</p>
31+
<p>
32+
<MatDatePicker FullWidth="true" @bind-Value="@FormModel.OrderDate" Enable24hours="true" Required="true" Format="MM.dd.yy H:mm:ss" EnableTime="true"></MatDatePicker>
33+
<ValidationMessage For="@(() => FormModel.OrderDate)"/>
34+
</p>
35+
<MatCardActions>
36+
<MatCardActionButtons>
37+
<MatButton Type="submit">
38+
@if (Edit)
39+
{
40+
<span>Save</span>
41+
}
42+
else
43+
{
44+
<span>Create</span>
45+
}
46+
</MatButton>
47+
</MatCardActionButtons>
48+
49+
<MatCardActionIcons>
50+
<MatIconButton Icon="@MatIconNames.Refresh" OnClick="(_) => FormModel.Reset()"></MatIconButton>
51+
</MatCardActionIcons>
52+
</MatCardActions>
53+
</EditForm>
54+
55+
@code {
56+
[Parameter]
57+
public NewOrderModel FormModel { get; set; } = new ();
58+
59+
[Parameter] public EventCallback<NewOrderModel> OnSubmitEventHandler { get; set; }
60+
61+
[Parameter] public Currency Currency { get; set; }
62+
63+
[Parameter] public string Symbol { get; set; }
64+
65+
[Parameter] public bool Edit { get; set; }
66+
67+
68+
public class NewOrderModel
69+
{
70+
[Required]
71+
[CustomValidation(typeof(NewOrderModel), nameof(NonZeroValue))]
72+
public decimal FilledPrice { get; set; }
73+
74+
[Required]
75+
[CustomValidation(typeof(NewOrderModel), nameof(NonZeroValue))]
76+
public decimal Size { get; set; }
77+
78+
[Required]
79+
[CustomValidation(typeof(NewOrderModel), nameof(NonNegativeValue))]
80+
public decimal Fee { get; set; }
81+
82+
[Required] public DateTime OrderDate = DateTime.Now;
83+
84+
public void Reset()
85+
{
86+
FilledPrice = 0m;
87+
Size = 0m;
88+
Fee = 0m;
89+
OrderDate = DateTime.Now;
90+
}
91+
92+
public static ValidationResult NonZeroValue(decimal value, ValidationContext vc)
93+
{
94+
return value > 0
95+
? ValidationResult.Success
96+
: new ValidationResult("Value must be non-zero", new[] {vc.MemberName});
97+
}
98+
99+
public static ValidationResult NonNegativeValue(decimal value, ValidationContext vc)
100+
{
101+
return value >= 0
102+
? ValidationResult.Success
103+
: new ValidationResult("Value must be positive", new[] {vc.MemberName});
104+
}
105+
}
106+
107+
private async void OnCreateOrderFormSubmit()
108+
{
109+
await OnSubmitEventHandler.InvokeAsync(FormModel);
110+
FormModel.Reset();
111+
}
112+
}

0 commit comments

Comments
 (0)