Revize 430cdbe6
Přidáno uživatelem Dominik Chlouba před téměř 4 roky(ů)
src/Core/Application/Leuze.Core.Application.UI/App.razor | ||
---|---|---|
5 | 5 |
<Found Context="routeData"> |
6 | 6 |
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> |
7 | 7 |
<NotAuthorized> |
8 |
<p>Nemáte potřebná oprávnění</p>
|
|
8 |
<RedirectToLogin/>
|
|
9 | 9 |
</NotAuthorized> |
10 | 10 |
<Authorizing> |
11 | 11 |
<p>Just checking with the boss you can come in.</p> |
src/Core/Application/Leuze.Core.Application.UI/Components/Login/Form.razor | ||
---|---|---|
101 | 101 |
height: 24px; |
102 | 102 |
</Styled> |
103 | 103 |
|
104 |
<form @onsubmit="Login" class="@_form">
|
|
104 |
<form @onsubmit="Change" class="@_form">
|
|
105 | 105 |
<div class="@_row"> |
106 |
<label class="@_label">@T["Email"]</label>
|
|
107 |
<input class="@_input" type="email" @bind-value="Email" />
|
|
106 |
<label class="@_label">@T["Password"]</label>
|
|
107 |
<input class="@_input" type="password" @bind-value="Password" />
|
|
108 | 108 |
</div> |
109 | 109 |
<div class="@_row"> |
110 | 110 |
<label class="@_label">@T["Password"]</label> |
111 |
<input class="@_input" type="password" @bind-value="Password" /> |
|
111 |
<input class="@_input" type="password" @bind-value="PasswordAgain" />
|
|
112 | 112 |
</div> |
113 | 113 |
<p>@Error</p> |
114 |
<button @onclick="Login" class="@_button" @onkeypress:preventDefault>@T["Login"]</button> |
|
115 |
<div class="@_or"> |
|
116 |
<div class="@_orText">@T["Or"]</div> |
|
117 |
</div> |
|
118 |
<div class="@_adWrapper"> |
|
119 |
<a href="MicrosoftIdentity/Account/SignIn"> |
|
120 |
<img class="@_microsoft" src="/Resources/Icons/microsoft-logo.svg" /> |
|
121 |
</a> |
|
122 |
</div> |
|
114 |
<button @onclick="Change" class="@_button" @onkeypress:preventDefault>@T["Change"]</button> |
|
123 | 115 |
</form> |
124 | 116 |
|
125 | 117 |
@code { |
... | ... | |
133 | 125 |
private string _adWrapper = null!; |
134 | 126 |
private string _microsoft = null!; |
135 | 127 |
|
136 |
private string Email { get; set; } = string.Empty; |
|
137 | 128 |
private string Password { get; set; } = string.Empty; |
129 |
private string PasswordAgain { get; set; } = string.Empty; |
|
138 | 130 |
|
139 | 131 |
private string Error { get; set; } = string.Empty; |
140 | 132 |
|
141 |
private async Task Login()
|
|
133 |
private async Task Change()
|
|
142 | 134 |
{ |
143 |
var result = await _mediator.Send(new VerifyLocalUser.Command(Email, Password)); |
|
135 |
/*var result = await _mediator.Send(new VerifyLocalUser.Command(Email, Password));
|
|
144 | 136 |
|
145 | 137 |
if (!result.IsSuccess) Error = result.Errors.First(); |
146 |
else _navManager.NavigateTo("/"); |
|
138 |
else _navManager.NavigateTo("/");*/ |
|
139 |
|
|
140 |
//TODO: Change password |
|
147 | 141 |
|
148 | 142 |
} |
149 | 143 |
|
src/Core/Application/Leuze.Core.Application.UI/Shared/NavMenu.razor | ||
---|---|---|
6 | 6 |
<span>Přehled</span> |
7 | 7 |
</div> |
8 | 8 |
</NavLink> |
9 |
<NavLink href="/goals"> |
|
10 |
<div class="item"> |
|
11 |
<img src="/Resources/Icons/clipboard-list-check.svg" class="item_icon nav_icon_2" /> |
|
12 |
<span>Správa cílů</span> |
|
13 |
</div> |
|
14 |
</NavLink> |
|
15 |
<NavLink href="/my-goals"> |
|
16 |
<div class="item"> |
|
17 |
<img src="/Resources/Icons/clipboard-list-check.svg" class="item_icon nav_icon_2" /> |
|
18 |
<span>Mé cíle</span> |
|
19 |
</div> |
|
20 |
</NavLink> |
|
21 |
<NavLink href="/users"> |
|
22 |
<div class="item"> |
|
23 |
<img src="/Resources/Icons/user.svg" class="item_icon nav_icon_3" /> |
|
24 |
<span>Uživatelé</span> |
|
25 |
</div> |
|
26 |
</NavLink> |
|
9 |
<AuthorizeView Roles="Admin, TL"> |
|
10 |
<NavLink href="/goals"> |
|
11 |
<div class="item"> |
|
12 |
<img src="/Resources/Icons/clipboard-list-check.svg" class="item_icon nav_icon_2" /> |
|
13 |
<span>Správa cílů</span> |
|
14 |
</div> |
|
15 |
</NavLink> |
|
16 |
</AuthorizeView> |
|
17 |
<AuthorizeView Roles="TL, MA"> |
|
18 |
<NavLink href="/my-goals"> |
|
19 |
<div class="item"> |
|
20 |
<img src="/Resources/Icons/clipboard-list-check.svg" class="item_icon nav_icon_2" /> |
|
21 |
<span>Mé cíle</span> |
|
22 |
</div> |
|
23 |
</NavLink> |
|
24 |
</AuthorizeView> |
|
25 |
<AuthorizeView Roles="Admin"> |
|
26 |
<NavLink href="/users"> |
|
27 |
<div class="item"> |
|
28 |
<img src="/Resources/Icons/user.svg" class="item_icon nav_icon_3" /> |
|
29 |
<span>Uživatelé</span> |
|
30 |
</div> |
|
31 |
</NavLink> |
|
32 |
</AuthorizeView> |
|
27 | 33 |
</nav> |
28 | 34 |
</aside> |
29 | 35 |
|
src/Modules/Goal/Application/Leuze.Modules.Goal.Application.UI/Pages/GoalDefinitionDetail.razor | ||
---|---|---|
1 | 1 |
@page "/goals/detail/{Id:guid}" |
2 |
@attribute [Authorize] |
|
2 |
@attribute [Authorize(Roles = "TL,MA")]
|
|
3 | 3 |
@layout MainLayout |
4 | 4 |
@inject IMediator _mediator |
5 |
@inject IStringLocalizer<GoalDefinitionDetail> T |
|
5 |
@inject IJSRuntime JsRuntime |
|
6 |
@inject IStringLocalizer<GoalDefinitionDetail> T |
|
6 | 7 |
|
7 | 8 |
<div class="section_header"> |
8 | 9 |
<div> |
... | ... | |
21 | 22 |
</div> |
22 | 23 |
@if (Goals is not null) |
23 | 24 |
{ |
24 |
<table class="actions" style="width:100%"> |
|
25 |
<tr> |
|
26 |
<th>@T["Name"]</th> |
|
27 |
<th>@T["CreatedBy"]</th> |
|
28 |
<th>@T["ResultUser"]</th> |
|
29 |
<th>@T["ResultSenior"]</th> |
|
30 |
<th>@T["Actions"]</th> |
|
31 |
</tr> |
|
32 |
@foreach (var range in Goals) |
|
33 |
{ |
|
34 |
<tr> |
|
35 |
<td>@range.Name</td> |
|
36 |
<td>@range.Creator.Name</td> |
|
37 |
<td>@range.PercentileUser</td> |
|
38 |
<td>@range.PercentileFinal</td> |
|
39 |
<td> |
|
40 |
<div class="flex"> |
|
41 |
<div></div> |
|
42 |
<div @onclick='() => SetDetailId(range.Id)'> |
|
43 |
<i class="fal fa-eye"></i> |
|
44 |
@T["Open"] |
|
45 |
</div> |
|
46 |
<div> |
|
47 |
<i class="fal fa-edit"></i> |
|
48 |
@T["Edit"] |
|
49 |
</div> |
|
50 |
<div> |
|
51 |
<i class="fal fa-trash"></i> |
|
52 |
@T["Remove"] |
|
53 |
</div> |
|
54 |
</div> |
|
55 |
</td> |
|
56 |
</tr> |
|
57 |
} |
|
58 |
</table> |
|
59 |
} |
|
60 |
else |
|
61 |
{ |
|
62 |
<div>@T["Loading"]</div> |
|
63 |
} |
|
25 |
<table class="actions" style="width:100%"> |
|
26 |
<tr> |
|
27 |
<th>@T["Name"]</th> |
|
28 |
<th>@T["CreatedBy"]</th> |
|
29 |
<th>@T["ResultUser"]</th> |
|
30 |
<th>@T["ResultSenior"]</th> |
|
31 |
<th>@T["Actions"]</th> |
|
32 |
</tr> |
|
33 |
@foreach (var range in Goals) |
|
34 |
{ |
|
35 |
<tr> |
|
36 |
<td>@range.Name</td> |
|
37 |
<td>@range.Creator.Name</td> |
|
38 |
<td>@range.PercentileUser</td> |
|
39 |
<td>@range.PercentileFinal</td> |
|
40 |
<td> |
|
41 |
<div class="flex"> |
|
42 |
<div></div> |
|
43 |
<div @onclick='() => SetDetailId(range.Id)'> |
|
44 |
<i class="fal fa-eye"></i> |
|
45 |
@T["Open"] |
|
46 |
</div> |
|
47 |
<div @onclick="() => RemoveGoal(range.Id)"> |
|
48 |
<i class="fal fa-trash"></i> |
|
49 |
@T["Remove"] |
|
50 |
</div> |
|
51 |
</div> |
|
52 |
</td> |
|
53 |
</tr>} |
|
54 |
</table> } |
|
55 |
else |
|
56 |
{ |
|
57 |
<div>@T["Loading"]</div>} |
|
64 | 58 |
|
65 | 59 |
<Leuze.Modules.Goal.Application.UI.Pages.Components.GoalDetailAside Show="DetailId != default(Guid)" DetailId="DetailId" CloseAside="CloseDetailAside" /> |
66 | 60 |
<Leuze.Modules.Goal.Application.UI.Pages.Components.CreateGoalAside Show="ShowCreate" DefinitionId="Id" CloseAside="CloseCreateAside" LoadGoalsInDefinitionView="GetGoals" /> |
... | ... | |
174 | 168 |
} |
175 | 169 |
</BlazorStyled.Styled> |
176 | 170 |
|
177 |
@code { |
|
171 |
@code { [Parameter] |
|
172 |
public Guid Id { get; set; } |
|
178 | 173 |
|
179 |
[Parameter] |
|
180 |
public Guid Id { get; set; } |
|
174 |
private GoalDefinition _definition = GoalDefinition.Default(); |
|
181 | 175 |
|
182 |
private GoalDefinition _definition = GoalDefinition.Default();
|
|
176 |
public List<GoalItem> Goals { get; set; } = new();
|
|
183 | 177 |
|
184 |
public List<GoalItem> Goals { get; set; } = new();
|
|
178 |
public Guid DetailId { get; set; } = default(Guid);
|
|
185 | 179 |
|
186 |
public Guid DetailId { get; set; } = default(Guid);
|
|
180 |
public bool ShowCreate { get; set; } = false;
|
|
187 | 181 |
|
188 |
public bool ShowCreate { get; set; } = false;
|
|
182 |
private void SetDetailId(Guid id) => DetailId = id;
|
|
189 | 183 |
|
190 |
private void SetDetailId(Guid id) => DetailId = id;
|
|
184 |
private void CloseDetailAside() => DetailId = default(Guid);
|
|
191 | 185 |
|
192 |
private void CloseDetailAside() => DetailId = default(Guid);
|
|
186 |
private void OpenCreateAside() => ShowCreate = true;
|
|
193 | 187 |
|
194 |
private void OpenCreateAside() => ShowCreate = true;
|
|
188 |
private void CloseCreateAside() => ShowCreate = false;
|
|
195 | 189 |
|
196 |
private void CloseCreateAside() => ShowCreate = false; |
|
190 |
private async Task GetDefinitionInfo() |
|
191 |
{ |
|
192 |
var response = await _mediator.Send(new GetGoalDefinitionById.Query(Id)); |
|
197 | 193 |
|
198 |
private async Task GetDefinitionInfo() |
|
199 |
{ |
|
200 |
var response = await _mediator.Send(new GetGoalDefinitionById.Query(Id)); |
|
194 |
if (response.IsSuccess) |
|
195 |
{ |
|
196 |
_definition = response.Result.item; |
|
197 |
} |
|
198 |
} |
|
201 | 199 |
|
202 |
if (response.IsSuccess) |
|
203 |
{ |
|
204 |
_definition = response.Result.item; |
|
205 |
} |
|
206 |
} |
|
200 |
private async Task RemoveGoal(Guid id) |
|
201 |
{ |
|
202 |
bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Are you sure?"); |
|
203 |
if (confirmed) |
|
204 |
{ |
|
205 |
var response = await _mediator.Send(new RemoveGoal.Command(id)); |
|
206 |
await GetGoals(); |
|
207 |
} |
|
208 |
} |
|
207 | 209 |
|
208 |
private async Task GetGoals() |
|
209 |
{ |
|
210 |
var response = await _mediator.Send(new GetGoalsForDefinition.Query(Id)); |
|
211 |
|
|
212 |
if (response.IsSuccess) |
|
213 |
{ |
|
214 |
Goals = response.Result.list; |
|
215 |
} |
|
216 |
} |
|
217 |
|
|
218 |
protected async override Task OnInitializedAsync() |
|
219 |
{ |
|
220 |
await base.OnInitializedAsync(); |
|
221 |
await GetDefinitionInfo(); |
|
222 |
await GetGoals(); |
|
223 |
} |
|
210 |
private async Task GetGoals() |
|
211 |
{ |
|
212 |
var response = await _mediator.Send(new GetGoalsForDefinition.Query(Id)); |
|
224 | 213 |
|
214 |
if (response.IsSuccess) |
|
215 |
{ |
|
216 |
Goals = response.Result.list; |
|
217 |
} |
|
218 |
} |
|
225 | 219 |
|
226 |
} |
|
220 |
protected async override Task OnInitializedAsync() |
|
221 |
{ |
|
222 |
await base.OnInitializedAsync(); |
|
223 |
await GetDefinitionInfo(); |
|
224 |
await GetGoals(); |
|
225 |
} } |
src/Modules/Goal/Application/Leuze.Modules.Goal.Application.UI/Pages/GoalRanges.razor | ||
---|---|---|
1 | 1 |
@page "/goals" |
2 | 2 |
@attribute [Authorize] |
3 | 3 |
@layout MainLayout |
4 |
@inject IJSRuntime JsRuntime |
|
4 | 5 |
@inject IMediator _mediator |
5 |
@inject NavigationManager _nav
|
|
6 |
@inject IStringLocalizer<GoalRanges> T
|
|
6 |
@inject NavigationManager _nav |
|
7 |
@inject IStringLocalizer<GoalRanges> T |
|
7 | 8 |
|
8 | 9 |
<div class="section_header"> |
9 | 10 |
<h2>@T["Title"]</h2> |
... | ... | |
14 | 15 |
</div> |
15 | 16 |
@if (Ranges is not null) |
16 | 17 |
{ |
17 |
<table class="actions" style="width:100%"> |
|
18 |
<tr> |
|
19 |
<th>@T["Start"]</th> |
|
20 |
<th>@T["End"]</th> |
|
21 |
<th>@T["Result"]</th> |
|
22 |
<th>@T["Actions"]</th> |
|
23 |
</tr> |
|
24 |
@foreach (var range in Ranges) |
|
25 |
{ |
|
26 |
<tr> |
|
27 |
<td>@range.From.ToShortDateString()</td> |
|
28 |
<td>@range.To.ToShortDateString()</td> |
|
29 |
<td>@(range.VariCompanySuccess ?? 0)</td> |
|
30 |
<td> |
|
31 |
<div class="flex"> |
|
32 |
<div> |
|
33 |
<i class="fal fa-download"></i> |
|
34 |
@T["Export"] |
|
35 |
</div> |
|
36 |
<div @onclick='() => _nav.NavigateTo($"/goals/overview/{range.Id}")'> |
|
37 |
<i class="fal fa-eye"></i> |
|
38 |
@T["Open"] |
|
39 |
</div> |
|
40 |
<div @onclick="() => OpenAside(range.Id)"> |
|
41 |
<i class="fal fa-edit"></i> |
|
42 |
@T["Edit"] |
|
43 |
</div> |
|
44 |
<div> |
|
45 |
<i class="fal fa-trash"></i> |
|
46 |
@T["Remove"] |
|
47 |
</div> |
|
48 |
</div> |
|
49 |
</td> |
|
50 |
</tr> |
|
51 |
} |
|
52 |
</table> |
|
53 |
@if (Ranges.Count > 0) |
|
18 |
<table class="actions" style="width:100%"> |
|
19 |
<tr> |
|
20 |
<th>@T["Start"]</th> |
|
21 |
<th>@T["End"]</th> |
|
22 |
<th>@T["Result"]</th> |
|
23 |
<th>@T["Actions"]</th> |
|
24 |
</tr> |
|
25 |
@foreach (var range in Ranges) |
|
54 | 26 |
{ |
55 |
<!--<div class="pagination"> |
|
56 |
<div class="left"> |
|
57 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-left.svg" /></button> |
|
58 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-left.svg" /></button> |
|
59 |
<input type="number" @bind-value="PageNumber" /> |
|
60 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-right.svg" /></button> |
|
61 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-right.svg" /></button> |
|
27 |
<tr> |
|
28 |
<td>@range.From.ToShortDateString()</td> |
|
29 |
<td>@range.To.ToShortDateString()</td> |
|
30 |
<td>@(range.VariCompanySuccess ?? 0)</td> |
|
31 |
<td> |
|
32 |
<div class="flex"> |
|
33 |
<div> |
|
34 |
<i class="fal fa-download"></i> |
|
35 |
@T["Export"] |
|
62 | 36 |
</div> |
63 |
<div class="right">@T["Show"] <b>@Ranges.Count @T["From"] @Total</b></div> |
|
64 |
</div>--> |
|
65 |
} |
|
66 |
} |
|
67 |
else |
|
68 |
{ |
|
69 |
<div>Loading...</div> |
|
70 |
} |
|
37 |
|
|
38 |
<div @onclick='() => _nav.NavigateTo($"/goals/overview/{range.Id}")'> |
|
39 |
<i class="fal fa-eye"></i> |
|
40 |
@T["Open"] |
|
41 |
</div> |
|
42 |
<div @onclick="() => OpenAside(range.Id)"> |
|
43 |
<i class="fal fa-edit"></i> |
|
44 |
@T["Edit"] |
|
45 |
</div> |
|
46 |
<div @onclick="() => RemoveArea(range.Id)"> |
|
47 |
<i class="fal fa-trash"></i> |
|
48 |
@T["Remove"] |
|
49 |
</div> |
|
50 |
</div> |
|
51 |
</td> |
|
52 |
</tr>} |
|
53 |
</table> |
|
54 |
@if (Ranges.Count > 0) |
|
55 |
{ |
|
56 |
<!--<div class="pagination"> |
|
57 |
<div class="left"> |
|
58 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-left.svg" /></button> |
|
59 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-left.svg" /></button> |
|
60 |
<input type="number" @bind-value="PageNumber" /> |
|
61 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-right.svg" /></button> |
|
62 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-right.svg" /></button> |
|
63 |
</div> |
|
64 |
<div class="right">@T["Show"] <b>@Ranges.Count @T["From"] @Total</b></div> |
|
65 |
</div>-->} } |
|
66 |
else |
|
67 |
{ |
|
68 |
<div>Loading...</div>} |
|
71 | 69 |
<Leuze.Modules.Goal.Application.UI.Pages.Components.CreateDefinitionRangeAside Show="ShowAside" AsideId="AsideId" LoadAreasInView="LoadAreas" CloseAside="CloseAside" /> |
72 | 70 |
|
73 | 71 |
<BlazorStyled.Styled> |
... | ... | |
181 | 179 |
} |
182 | 180 |
</BlazorStyled.Styled> |
183 | 181 |
|
184 |
@code { |
|
185 |
|
|
186 |
[Parameter] |
|
187 |
public string Id { get; set; } = null!; |
|
182 |
@code { [Parameter] |
|
183 |
public string Id { get; set; } = null!; |
|
188 | 184 |
|
189 |
private List<GlobalDefinitionArea> Ranges { get; set; } = new() { }; |
|
185 |
private List<GlobalDefinitionArea> Ranges { get; set; } = new() { };
|
|
190 | 186 |
|
191 |
private int PageNumber { get; set; } = 1; |
|
187 |
private int PageNumber { get; set; } = 1;
|
|
192 | 188 |
|
193 |
private int PageSize { get; set; } = 12; |
|
189 |
private int PageSize { get; set; } = 12;
|
|
194 | 190 |
|
195 |
private int Total { get; set; } = 0; |
|
191 |
private int Total { get; set; } = 0;
|
|
196 | 192 |
|
197 |
private Guid AsideId { get; set; } = default(Guid); |
|
193 |
private Guid AsideId { get; set; } = default(Guid);
|
|
198 | 194 |
|
199 |
private bool ShowAside { get; set; } = false; |
|
195 |
private bool ShowAside { get; set; } = false;
|
|
200 | 196 |
|
201 |
private void OpenAside(Guid id) => (AsideId, ShowAside) = (id, true); |
|
197 |
private void OpenAside(Guid id) => (AsideId, ShowAside) = (id, true);
|
|
202 | 198 |
|
203 |
private void CloseAside() => (AsideId, ShowAside) = (default(Guid), false); |
|
199 |
private void CloseAside() => (AsideId, ShowAside) = (default(Guid), false);
|
|
204 | 200 |
|
205 |
private async Task LoadAreas() |
|
206 |
{ |
|
207 |
var response = await _mediator.Send(new GetAllAreas.Query()); |
|
201 |
private async Task LoadAreas()
|
|
202 |
{
|
|
203 |
var response = await _mediator.Send(new GetAllAreas.Query());
|
|
208 | 204 |
|
209 |
if (response.IsSuccess) |
|
210 |
{ |
|
211 |
Ranges = response.Result.list; |
|
212 |
} |
|
213 |
} |
|
205 |
if (response.IsSuccess)
|
|
206 |
{
|
|
207 |
Ranges = response.Result.list;
|
|
208 |
}
|
|
209 |
}
|
|
214 | 210 |
|
215 |
protected async override Task OnInitializedAsync() |
|
216 |
{ |
|
217 |
await base.OnInitializedAsync(); |
|
218 |
await LoadAreas(); |
|
219 |
} |
|
211 |
private async Task RemoveArea(Guid id) |
|
212 |
{ |
|
213 |
bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Are you sure?"); |
|
214 |
if (confirmed) |
|
215 |
{ |
|
216 |
var response = await _mediator.Send(new RemoveArea.Command(id)); |
|
217 |
await LoadAreas(); |
|
218 |
} |
|
219 |
} |
|
220 | 220 |
|
221 |
} |
|
221 |
protected async override Task OnInitializedAsync() |
|
222 |
{ |
|
223 |
await base.OnInitializedAsync(); |
|
224 |
await LoadAreas(); |
|
225 |
} } |
src/Modules/Goal/Application/Leuze.Modules.Goal.Application.UI/Pages/GoalsManagement.razor | ||
---|---|---|
3 | 3 |
@layout MainLayout |
4 | 4 |
@inject IMediator _mediator |
5 | 5 |
@inject NavigationManager _nav |
6 |
@inject IStringLocalizer<GoalsManagement> T |
|
6 |
@inject IJSRuntime JsRuntime |
|
7 |
@inject IStringLocalizer<GoalsManagement> T |
|
7 | 8 |
|
8 | 9 |
<div class="section_header"> |
9 | 10 |
<h2>@T["Title"]</h2> |
... | ... | |
12 | 13 |
<i class="fal fa-layer-plus"></i> |
13 | 14 |
<span>@T["InitAll"]</span> |
14 | 15 |
</button> |
15 |
<button type="button" @onclick="() => OpenAside(default(Guid))"> |
|
16 |
<i class="fal fa-plus"></i> |
|
17 |
<span>@T["AddDef"]</span> |
|
18 |
</button> |
|
16 |
|
|
17 |
<AuthorizeView Roles="TL"> |
|
18 |
<button type="button" @onclick="() => OpenAside(default(Guid))"> |
|
19 |
<i class="fal fa-plus"></i> |
|
20 |
<span>@T["AddDef"]</span> |
|
21 |
</button> |
|
22 |
</AuthorizeView> |
|
19 | 23 |
</div> |
20 | 24 |
</div> |
21 | 25 |
@if (Definitions is not null) |
22 | 26 |
{ |
23 |
<table class="actions" style="width:100%"> |
|
24 |
<tr> |
|
25 |
<th>@T["Name"]</th> |
|
26 |
<th>@T["User"]</th> |
|
27 |
<th>@T["CreatedBy"]</th> |
|
28 |
<th>@T["Actions"]</th> |
|
29 |
</tr> |
|
30 |
@foreach (var range in Definitions) |
|
31 |
{ |
|
32 |
<tr> |
|
33 |
<td>@range.Name</td> |
|
34 |
<td>@range.Owner.Name</td> |
|
35 |
<td>@range.Creator.Name</td> |
|
36 |
<td> |
|
37 |
<div class="flex"> |
|
38 |
<div @onclick='() => _nav.NavigateTo($"/goals/detail/{range.Id}")'> |
|
39 |
<i class="fal fa-eye"></i> |
|
40 |
@T["Open"] |
|
41 |
</div> |
|
42 |
<div @onclick="() => OpenAside(range.Id)"> |
|
43 |
<i class="fal fa-edit"></i> |
|
44 |
@T["Edit"] |
|
45 |
</div> |
|
46 |
<div> |
|
47 |
<i class="fal fa-trash"></i> |
|
48 |
@T["Remove"] |
|
49 |
</div> |
|
50 |
</div> |
|
51 |
</td> |
|
52 |
</tr> |
|
53 |
} |
|
54 |
</table> |
|
55 |
@if (Definitions.Count > 0) |
|
27 |
<table class="actions" style="width:100%"> |
|
28 |
<tr> |
|
29 |
<th>@T["Name"]</th> |
|
30 |
<th>@T["User"]</th> |
|
31 |
<th>@T["CreatedBy"]</th> |
|
32 |
<th>@T["Actions"]</th> |
|
33 |
</tr> |
|
34 |
@foreach (var range in Definitions) |
|
56 | 35 |
{ |
57 |
<!--<div class="pagination"> |
|
58 |
<div class="left"> |
|
59 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-left.svg" /></button> |
|
60 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-left.svg" /></button> |
|
61 |
<input type="number" @bind-value="PageNumber" /> |
|
62 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-right.svg" /></button> |
|
63 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-right.svg" /></button> |
|
64 |
</div> |
|
65 |
<div class="right">@T["Show"] <b>@Ranges.Count @T["From"] @Total</b></div> |
|
66 |
</div>--> |
|
67 |
} |
|
68 |
} |
|
69 |
else |
|
70 |
{ |
|
71 |
<div>Loading...</div> |
|
72 |
} |
|
36 |
<tr> |
|
37 |
<td>@range.Name</td> |
|
38 |
<td>@range.Owner.Name</td> |
|
39 |
<td>@range.Creator.Name</td> |
|
40 |
<td> |
|
41 |
<div class="flex"> |
|
42 |
<AuthorizeView Roles="TL"> |
|
43 |
<div @onclick='() => _nav.NavigateTo($"/goals/detail/{range.Id}")'> |
|
44 |
<i class="fal fa-eye"></i> |
|
45 |
@T["Open"] |
|
46 |
</div> |
|
47 |
<div @onclick="() => OpenAside(range.Id)"> |
|
48 |
<i class="fal fa-edit"></i> |
|
49 |
@T["Edit"] |
|
50 |
</div> |
|
51 |
<div @onclick="() => RemoveDefinition(range.Id)"> |
|
52 |
<i class="fal fa-trash"></i> |
|
53 |
@T["Remove"] |
|
54 |
</div> |
|
55 |
</AuthorizeView> |
|
56 |
</div> |
|
57 |
</td> |
|
58 |
</tr>} |
|
59 |
</table> |
|
60 |
@if (Definitions.Count > 0) |
|
61 |
{ |
|
62 |
<!--<div class="pagination"> |
|
63 |
<div class="left"> |
|
64 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-left.svg" /></button> |
|
65 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-left.svg" /></button> |
|
66 |
<input type="number" @bind-value="PageNumber" /> |
|
67 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-right.svg" /></button> |
|
68 |
<button class="pagination_button"><img class="pagination_icon" src="/Resources/Icons/chevron-double-right.svg" /></button> |
|
69 |
</div> |
|
70 |
<div class="right">@T["Show"] <b>@Ranges.Count @T["From"] @Total</b></div> |
|
71 |
</div>-->} } |
|
72 |
else |
|
73 |
{ |
|
74 |
<div>Loading...</div>} |
|
73 | 75 |
<Leuze.Modules.Goal.Application.UI.Pages.Components.CreateGoalDefinition Show="ShowAside" CloseAside="CloseAside" /> |
74 | 76 |
|
75 | 77 |
<BlazorStyled.Styled> |
... | ... | |
133 | 135 |
justify-content: right; |
134 | 136 |
} |
135 | 137 |
.header_buttons > button:not(:last-child) { |
136 |
margin-right: 12px;
|
|
138 |
margin-right: 12px; |
|
137 | 139 |
} |
138 | 140 |
.flex{ |
139 | 141 |
display: grid; |
... | ... | |
191 | 193 |
} |
192 | 194 |
</BlazorStyled.Styled> |
193 | 195 |
|
194 |
@code { |
|
196 |
@code { [Parameter] |
|
197 |
public Guid Id { get; set; } = default(Guid); |
|
195 | 198 |
|
196 |
[Parameter] |
|
197 |
public Guid Id { get; set; } = default(Guid); |
|
199 |
private List<GoalDefinition> Definitions { get; set; } = new(); |
|
198 | 200 |
|
199 |
private List<GoalDefinition> Definitions { get; set; } = new();
|
|
201 |
private int PageNumber { get; set; } = 1;
|
|
200 | 202 |
|
201 |
private int PageNumber { get; set; } = 1;
|
|
203 |
private int PageSize { get; set; } = 12;
|
|
202 | 204 |
|
203 |
private int PageSize { get; set; } = 12;
|
|
205 |
private int Total { get; set; } = 0;
|
|
204 | 206 |
|
205 |
private int Total { get; set; } = 0;
|
|
207 |
private bool ShowAside { get; set; } = false;
|
|
206 | 208 |
|
207 |
private bool ShowAside { get; set; } = false;
|
|
209 |
private void OpenAside(Guid id) => (ShowAside) = (true);
|
|
208 | 210 |
|
209 |
private void OpenAside(Guid id) => (ShowAside) = (true);
|
|
211 |
private void CloseAside() => (ShowAside) = (false);
|
|
210 | 212 |
|
211 |
private void CloseAside() => (ShowAside) = (false); |
|
213 |
private async Task GetMyDefinitions() |
|
214 |
{ |
|
215 |
var response = await _mediator.Send(new GetAllForArea.Query(Id)); |
|
212 | 216 |
|
213 |
private async Task GetMyDefinitions() |
|
214 |
{ |
|
215 |
var response = await _mediator.Send(new GetAllForArea.Query(Id)); |
|
217 |
if (response.IsSuccess) |
|
218 |
{ |
|
219 |
Definitions = response.Result.list; |
|
220 |
} |
|
221 |
} |
|
216 | 222 |
|
217 |
if (response.IsSuccess) |
|
218 |
{ |
|
219 |
Definitions = response.Result.list; |
|
220 |
} |
|
221 |
} |
|
222 |
|
|
223 |
protected async override Task OnInitializedAsync() |
|
224 |
{ |
|
225 |
await base.OnInitializedAsync(); |
|
226 |
await GetMyDefinitions(); |
|
227 |
} |
|
223 |
private async Task RemoveDefinition(Guid id) |
|
224 |
{ |
|
225 |
bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Are you sure?"); |
|
226 |
if (confirmed) |
|
227 |
{ |
|
228 |
var response = await _mediator.Send(new RemoveDefinition.Command(id)); |
|
229 |
await GetMyDefinitions(); |
|
230 |
} |
|
231 |
} |
|
228 | 232 |
|
229 |
} |
|
233 |
protected async override Task OnInitializedAsync() |
|
234 |
{ |
|
235 |
await base.OnInitializedAsync(); |
|
236 |
await GetMyDefinitions(); |
|
237 |
} } |
src/Modules/Goal/Application/Leuze.Modules.Goal.Application.UI/_Imports.razor | ||
---|---|---|
27 | 27 |
@using Leuze.Modules.Goal.Application.CQRS.Goals.Commands |
28 | 28 |
@using Leuze.Modules.Goal.Application.CQRS.Goals.Queries |
29 | 29 |
@using Leuze.Modules.Goal.Application.CQRS.GoalDefinitions.Queries |
30 |
@using Leuze.Modules.Goal.Application.CQRS.GoalDefinitions.Commands |
|
30 | 31 |
@using Leuze.Modules.Goal.Application.CQRS.GoalDefinitionAreas.Commands |
31 | 32 |
@using Leuze.Modules.Goal.Application.CQRS.GoalDefinitionAreas.Queries |
32 | 33 |
@using Leuze.Modules.Goal.Domain.Domains |
33 |
@using Leuze.Core.Domain.Domains.Users |
|
34 | 34 |
@using Microsoft.Extensions.Localization |
35 | 35 |
@using Microsoft.AspNetCore.Localization |
src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/GoalDefinitionAreas/Commands/RemoveArea.cs | ||
---|---|---|
1 |
using Leuze.Core.Application.CQRS; |
|
2 |
using Leuze.Modules.Goal.Domain.Repositories; |
|
3 |
using System; |
|
4 |
using System.Collections.Generic; |
|
5 |
using System.Linq; |
|
6 |
using System.Text; |
|
7 |
using System.Threading; |
|
8 |
using System.Threading.Tasks; |
|
9 |
|
|
10 |
namespace Leuze.Modules.Goal.Application.CQRS.GoalDefinitionAreas.Commands |
|
11 |
{ |
|
12 |
public static class RemoveArea |
|
13 |
{ |
|
14 |
|
|
15 |
public record Command(Guid Id) : IBaseRequest<Response>; |
|
16 |
|
|
17 |
public record Response(); |
|
18 |
|
|
19 |
public class Handler : IBaseRequestHandler<Command, Response> |
|
20 |
{ |
|
21 |
private readonly IGlobalDefinitionAreaRepository _repository; |
|
22 |
|
|
23 |
public Handler(IGlobalDefinitionAreaRepository repository) |
|
24 |
=> (_repository) = (repository); |
|
25 |
|
|
26 |
public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken) |
|
27 |
{ |
|
28 |
if (!await _repository.RemoveAsync(request.Id)) |
|
29 |
return RequestResponse<Response>.CreateErrorResponse($"Area with ID '{request.Id}' not found"); |
|
30 |
|
|
31 |
return RequestResponse<Response>.CreateSuccessResponse(new()); |
|
32 |
} |
|
33 |
} |
|
34 |
|
|
35 |
} |
|
36 |
} |
src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/GoalDefinitions/Commands/RemoveDefinition.cs | ||
---|---|---|
1 |
using Leuze.Core.Application.CQRS; |
|
2 |
using Leuze.Modules.Goal.Domain.Repositories; |
|
3 |
using System; |
|
4 |
using System.Threading; |
|
5 |
using System.Threading.Tasks; |
|
6 |
|
|
7 |
namespace Leuze.Modules.Goal.Application.CQRS.GoalDefinitions.Commands |
|
8 |
{ |
|
9 |
public static class RemoveDefinition |
|
10 |
{ |
|
11 |
|
|
12 |
public record Command(Guid Id) : IBaseRequest<Response>; |
|
13 |
|
|
14 |
public record Response(); |
|
15 |
|
|
16 |
public class Handler : IBaseRequestHandler<Command, Response> |
|
17 |
{ |
|
18 |
private readonly IGoalDefinitionRepository _repository; |
|
19 |
|
|
20 |
public Handler(IGoalDefinitionRepository repository) |
|
21 |
=> (_repository) = (repository); |
|
22 |
|
|
23 |
public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken) |
|
24 |
{ |
|
25 |
if (!await _repository.RemoveAsync(request.Id)) |
|
26 |
return RequestResponse<Response>.CreateErrorResponse($"Definition with ID '{request.Id}' not found"); |
|
27 |
|
|
28 |
return RequestResponse<Response>.CreateSuccessResponse(new()); |
|
29 |
} |
|
30 |
} |
|
31 |
|
|
32 |
} |
|
33 |
} |
src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/RemoveGoal.cs | ||
---|---|---|
1 |
using Leuze.Core.Application.CQRS; |
|
2 |
using Leuze.Modules.Goal.Domain.Repositories; |
|
3 |
using System; |
|
4 |
using System.Threading; |
|
5 |
using System.Threading.Tasks; |
|
6 |
|
|
7 |
namespace Leuze.Modules.Goal.Application.CQRS.Goals.Commands |
|
8 |
{ |
|
9 |
public static class RemoveGoal |
|
10 |
{ |
|
11 |
|
|
12 |
public record Command(Guid Id) : IBaseRequest<Response>; |
|
13 |
|
|
14 |
public record Response(); |
|
15 |
|
|
16 |
public class Handler : IBaseRequestHandler<Command, Response> |
|
17 |
{ |
|
18 |
private readonly IGoalItemRepository _repository; |
|
19 |
|
|
20 |
public Handler(IGoalItemRepository repository) |
|
21 |
=> (_repository) = (repository); |
|
22 |
|
|
23 |
public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken) |
|
24 |
{ |
|
25 |
if (!await _repository.RemoveAsync(request.Id)) |
|
26 |
return RequestResponse<Response>.CreateErrorResponse($"Goal with ID '{request.Id}' not found"); |
|
27 |
|
|
28 |
return RequestResponse<Response>.CreateSuccessResponse(new()); |
|
29 |
} |
|
30 |
} |
|
31 |
|
|
32 |
} |
|
33 |
} |
tests/Core/Leuze.Tests.Core/RoleTests.cs | ||
---|---|---|
38 | 38 |
var AuthenticationStateProviderMock = new Mock<AuthenticatedUserProvider>(); |
39 | 39 |
AuthenticationStateProviderMock.Setup(e => e.RequiredUserId).Returns(user.Id); |
40 | 40 |
|
41 |
var handler = new GetUsersList.Handler(DatabaseFixture.UserManager)
|
|
41 |
//var handler = new GetUsersList.Handler(DatabaseFixture.UserManager);
|
|
42 | 42 |
|
43 | 43 |
_semaphore.Release(); |
44 | 44 |
} |
Také k dispozici: Unified diff
Bug and UI fixes, removing areas, definitions and goals, authorize view restrictions