Skip to content

Commit 165f5ee

Browse files
authored
Add order button for variants (#2832)
1 parent d82c2d9 commit 165f5ee

File tree

5 files changed

+84
-35
lines changed

5 files changed

+84
-35
lines changed

src/JoinRpg.Helpers/VirtualOrderContainer.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,24 @@ public VirtualOrderContainer<TItem> MoveAfter(TItem field, TItem? afterItem)
157157

158158
return this;
159159
}
160+
161+
public void SortBy<TField>(Func<TItem, TField> selector) where TField : IComparable<TField>
162+
{
163+
Items.Sort(new SortByFieldComparer<TField>(selector));
164+
}
165+
166+
private class SortByFieldComparer<TField>(Func<TItem, TField> selector) : IComparer<TItem>
167+
where TField : IComparable<TField>
168+
{
169+
int IComparer<TItem>.Compare(TItem? x, TItem? y)
170+
{
171+
return (x, y) switch
172+
{
173+
(null, null) => 0,
174+
(null, _) => -1,
175+
(_, null) => 1,
176+
_ => selector(x).CompareTo(selector(y)),
177+
};
178+
}
179+
}
160180
}

src/JoinRpg.Portal/Controllers/GameFieldController.cs

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,23 @@ namespace JoinRpg.Portal.Controllers;
1919

2020
[Authorize]
2121
[Route("{ProjectId}/fields/[action]")]
22-
public class GameFieldController : ControllerGameBase
22+
public class GameFieldController(
23+
IProjectRepository projectRepository,
24+
IProjectService projectService,
25+
IFieldSetupService fieldSetupService,
26+
IUserRepository userRepository,
27+
FieldSetupManager manager,
28+
ICurrentProjectAccessor currentProjectAccessor,
29+
IProjectMetadataRepository projectMetadataRepository
30+
) : ControllerGameBase(projectRepository, projectService, userRepository)
2331
{
24-
private readonly IProjectMetadataRepository projectMetadataRepository;
25-
26-
private IFieldSetupService FieldSetupService { get; }
27-
public FieldSetupManager Manager { get; }
28-
private ICurrentProjectAccessor CurrentProjectAccessor { get; }
29-
30-
public GameFieldController(
31-
IProjectRepository projectRepository,
32-
IProjectService projectService,
33-
IFieldSetupService fieldSetupService,
34-
IUserRepository userRepository,
35-
FieldSetupManager manager,
36-
ICurrentProjectAccessor currentProjectAccessor,
37-
IProjectMetadataRepository projectMetadataRepository
38-
)
39-
: base(projectRepository, projectService, userRepository)
40-
{
41-
FieldSetupService = fieldSetupService;
42-
Manager = manager;
43-
CurrentProjectAccessor = currentProjectAccessor;
44-
this.projectMetadataRepository = projectMetadataRepository;
45-
}
32+
public FieldSetupManager Manager { get; } = manager;
4633

4734
private ActionResult ReturnToIndex()
48-
=> RedirectToAction("Index", new { ProjectId = CurrentProjectAccessor.ProjectId.Value });
35+
=> RedirectToAction("Index", new { ProjectId = currentProjectAccessor.ProjectId.Value });
4936

5037
private ActionResult ReturnToField(ProjectField value)
51-
=> RedirectToAction("Edit", new { ProjectId = CurrentProjectAccessor.ProjectId.Value, projectFieldId = value.ProjectFieldId });
38+
=> RedirectToAction("Edit", new { ProjectId = currentProjectAccessor.ProjectId.Value, projectFieldId = value.ProjectFieldId });
5239

5340

5441
[HttpGet("/{ProjectId}/fields/")]
@@ -133,7 +120,7 @@ public async Task<ActionResult> Create(GameFieldCreateViewModel viewModel)
133120
viewModel.MasterDescriptionEditable,
134121
programmaticValue: null);
135122

136-
await FieldSetupService.AddField(request);
123+
await fieldSetupService.AddField(request);
137124

138125
return ReturnToIndex();
139126
}
@@ -185,7 +172,7 @@ public async Task<ActionResult> Edit(GameFieldEditViewModel viewModel)
185172
field.ProjectFieldId,
186173
viewModel.ProgrammaticValue);
187174

188-
await FieldSetupService.UpdateFieldParams(request);
175+
await fieldSetupService.UpdateFieldParams(request);
189176

190177
return ReturnToIndex();
191178
}
@@ -207,7 +194,7 @@ public async Task<ActionResult> Delete(int projectId, int projectFieldId, IFormC
207194

208195
try
209196
{
210-
await FieldSetupService.DeleteField(projectId, field.ProjectFieldId);
197+
await fieldSetupService.DeleteField(projectId, field.ProjectFieldId);
211198

212199
return ReturnToIndex();
213200
}
@@ -239,7 +226,7 @@ public async Task<ActionResult> CreateValue(GameFieldDropdownValueCreateViewMode
239226
var timeSlotOptions = viewModel.GetTimeSlotRequest(field, Request.Form["TimeSlotStartTime"].FirstOrDefault());
240227

241228
await
242-
FieldSetupService.CreateFieldValueVariant(
229+
fieldSetupService.CreateFieldValueVariant(
243230
new CreateFieldValueVariantRequest(
244231
viewModel.ProjectId,
245232
viewModel.Label,
@@ -283,7 +270,7 @@ public async Task<ActionResult> EditValue(GameFieldDropdownValueEditViewModel vi
283270
try
284271
{
285272
var field = await ProjectRepository.GetProjectField(viewModel.ProjectId, viewModel.ProjectFieldId);
286-
await FieldSetupService.UpdateFieldValueVariant(new UpdateFieldValueVariantRequest(
273+
await fieldSetupService.UpdateFieldValueVariant(new UpdateFieldValueVariantRequest(
287274
viewModel.ProjectId,
288275
viewModel.ProjectFieldDropdownValueId,
289276
viewModel.Label,
@@ -331,7 +318,7 @@ public async Task<ActionResult> DeleteValueEx(int projectId, int projectFieldId,
331318
return NotFound();
332319
}
333320

334-
_ = await FieldSetupService.DeleteFieldValueVariant(value.ProjectId, value.ProjectFieldId, value.ProjectFieldDropdownValueId);
321+
_ = await fieldSetupService.DeleteFieldValueVariant(value.ProjectId, value.ProjectFieldId, value.ProjectFieldDropdownValueId);
335322
return value.IsActive
336323
? Ok()
337324
: StatusCode(250);
@@ -357,7 +344,7 @@ public async Task<ActionResult> Move(int projectId, int listItemId, int directio
357344

358345
try
359346
{
360-
await FieldSetupService.MoveField(projectId, listItemId, (short)direction);
347+
await fieldSetupService.MoveField(projectId, listItemId, (short)direction);
361348

362349
return ReturnToIndex();
363350
}
@@ -381,7 +368,7 @@ public async Task<ActionResult> MoveValue(int projectId, int listItemId, int par
381368

382369
try
383370
{
384-
await FieldSetupService.MoveFieldVariant(projectId, parentObjectId, listItemId, (short)direction);
371+
await fieldSetupService.MoveFieldVariant(projectId, parentObjectId, listItemId, (short)direction);
385372

386373

387374
return ReturnToField(value);
@@ -404,7 +391,7 @@ public async Task<ActionResult> MassCreateValueVariants(int projectId, int proje
404391

405392
try
406393
{
407-
await FieldSetupService.CreateFieldValueVariants(projectId, projectFieldId, valuesToAdd);
394+
await fieldSetupService.CreateFieldValueVariants(projectId, projectFieldId, valuesToAdd);
408395

409396

410397
return ReturnToField(value);
@@ -432,7 +419,31 @@ public async Task<ActionResult> MoveFast(int projectId, int projectFieldId, int?
432419

433420
try
434421
{
435-
await FieldSetupService.MoveFieldAfter(projectId, projectFieldId, afterFieldId);
422+
await fieldSetupService.MoveFieldAfter(projectId, projectFieldId, afterFieldId);
423+
424+
425+
return ReturnToIndex();
426+
}
427+
catch
428+
{
429+
return ReturnToIndex();
430+
}
431+
}
432+
433+
[MasterAuthorize(Permission.CanChangeFields)]
434+
[HttpPost("~/{projectId:int}/fields/{projectFieldId:int}/sortvariants")]
435+
public async Task<ActionResult> SortVariants(int projectId, int projectFieldId)
436+
{
437+
var value = await ProjectRepository.GetProjectField(projectId, projectFieldId);
438+
439+
if (value == null)
440+
{
441+
return NotFound();
442+
}
443+
444+
try
445+
{
446+
await fieldSetupService.SortFieldVariants(projectId, projectFieldId);
436447

437448

438449
return ReturnToIndex();

src/JoinRpg.Portal/Views/GameField/Edit.cshtml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@
175175
{
176176
<button class="btn btn-default" data-toggle="modal" data-target="#massAddValueModal">Добавить несколько значений</button>
177177
}
178+
<form asp-action="SortVariants" asp-route-projectId="@Model.ProjectId" asp-route-projectFieldId="@Model.ProjectFieldId" method="POST" style="display:inline">
179+
<button type="submit" class="btn btn-default" onclick="return confirm('Отсортировать варианты по алфавиту?')">
180+
<i class="glyphicon glyphicon-sort-by-alphabet"></i>Отсортировать по алфавиту
181+
</button>
182+
</form>
178183
</div>
179184
<partial name="ValuesList" for="@Model.DropdownValues" />
180185

src/JoinRpg.Services.Impl/FieldSetupServiceImpl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,18 @@ public async Task SetFieldSettingsAsync(FieldSettingsRequest request)
403403
await UnitOfWork.SaveChangesAsync();
404404
}
405405

406+
public async Task SortFieldVariants(int projectId, int projectFieldId)
407+
{
408+
var project = await ProjectRepository.GetProjectAsync(projectId);
409+
410+
var field = project.RequestMasterAccess(CurrentUserId, acl => acl.CanChangeFields).ProjectFields.Single(f => f.ProjectFieldId == projectFieldId);
411+
var container = field.GetFieldValuesContainer();
412+
container.SortBy(x => x.Label);
413+
field.ValuesOrdering = container.GetStoredOrder();
414+
415+
await UnitOfWork.SaveChangesAsync();
416+
}
417+
406418
private static void SetScheduleStatusBasedOnFields(Project project)
407419
{
408420
project.Details.ScheduleEnabled =

src/JoinRpg.Services.Interfaces/IFieldSetupService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Task CreateFieldValueVariants(int projectId,
3434
Task MoveFieldAfter(int projectId, int projectFieldId, int? afterFieldId);
3535

3636
Task SetFieldSettingsAsync(FieldSettingsRequest request);
37+
Task SortFieldVariants(int projectId, int projectFieldId);
3738
}
3839

3940
public class FieldSettingsRequest

0 commit comments

Comments
 (0)