Skip to content

Commit 33615eb

Browse files
authored
Refactor Time Slot Options to use new metadata API (#2408)
* Move TimeSlotOptions to PrimitiveTypes * Add TimeSlotFieldVarian * Add TimeSlotField / RoomField links * Use ProjectFieldInfo in edit viewModels
1 parent 8441ea2 commit 33615eb

File tree

17 files changed

+215
-195
lines changed

17 files changed

+215
-195
lines changed

src/JoinRpg.Dal.Impl/Repositories/ProjectRepository.cs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -358,19 +358,39 @@ IEnumerable<ProjectFieldInfo> CreateFields(Project project, ProjectFieldSettings
358358

359359
IEnumerable<ProjectFieldVariant> CreateVariants(ProjectField field, ProjectFieldIdentification fieldId)
360360
{
361-
foreach (var variant in field.DropdownValues)
361+
if (field.FieldType == ProjectFieldType.ScheduleTimeSlotField)
362362
{
363-
yield return new ProjectFieldVariant(
364-
new(fieldId, variant.ProjectFieldDropdownValueId),
365-
variant.Label,
366-
variant.Price,
367-
variant.PlayerSelectable,
368-
variant.IsActive,
369-
variant.CharacterGroup?.CharacterGroupId,
370-
variant.Description,
371-
variant.MasterDescription,
372-
variant.ProgrammaticValue
373-
);
363+
foreach (var variant in field.DropdownValues)
364+
{
365+
yield return new TimeSlotFieldVariant(
366+
new(fieldId, variant.ProjectFieldDropdownValueId),
367+
variant.Label,
368+
variant.Price,
369+
variant.PlayerSelectable,
370+
variant.IsActive,
371+
variant.CharacterGroup?.CharacterGroupId,
372+
variant.Description,
373+
variant.MasterDescription,
374+
variant.ProgrammaticValue
375+
);
376+
}
377+
}
378+
else
379+
{
380+
foreach (var variant in field.DropdownValues)
381+
{
382+
yield return new ProjectFieldVariant(
383+
new(fieldId, variant.ProjectFieldDropdownValueId),
384+
variant.Label,
385+
variant.Price,
386+
variant.PlayerSelectable,
387+
variant.IsActive,
388+
variant.CharacterGroup?.CharacterGroupId,
389+
variant.Description,
390+
variant.MasterDescription,
391+
variant.ProgrammaticValue
392+
);
393+
}
374394
}
375395
}
376396
}

src/JoinRpg.Domain/Schedules/ScheduleBuilder.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ public class ScheduleBuilder
1111
private readonly ICollection<Character> characters;
1212
private readonly ProjectInfo projectInfo;
1313

14-
private ProjectField TimeSlotField { get; }
14+
private ProjectFieldInfo TimeSlotField { get; }
1515

16-
private ProjectField RoomField { get; }
16+
private ProjectFieldInfo RoomField { get; }
1717

18-
public ScheduleBuilder(Project project, ICollection<Character> characters, ProjectInfo projectInfo)
18+
public ScheduleBuilder(ICollection<Character> characters, ProjectInfo projectInfo)
1919
{
2020
this.characters = characters.Where(ch => ch.IsActive).ToList();
21-
RoomField = project.GetRoomFieldOrDefault() ?? throw new Exception("Schedule not enabled");
22-
TimeSlotField = project.GetTimeSlotFieldOrDefault() ?? throw new Exception("Schedule not enabled");
21+
RoomField = projectInfo.RoomField ?? throw new Exception("Schedule not enabled");
22+
TimeSlotField = projectInfo.TimeSlotField ?? throw new Exception("Schedule not enabled");
2323
this.projectInfo = projectInfo;
2424
}
2525

@@ -46,8 +46,8 @@ public ProgramItemSlot(TimeSlot slot, ScheduleRoom room)
4646

4747
public ScheduleResult Build()
4848
{
49-
Rooms = InitializeScheduleRoomList(RoomField.GetOrderedValues()).ToList();
50-
TimeSlots = InitializeTimeSlotList(TimeSlotField.GetOrderedValues()).ToList();
49+
Rooms = InitializeScheduleRoomList(RoomField.SortedVariants).ToList();
50+
TimeSlots = InitializeTimeSlotList(TimeSlotField.SortedVariants.Cast<TimeSlotFieldVariant>()).ToList();
5151
Slots = InitializeSlots(TimeSlots, Rooms);
5252

5353
var allItems = new List<ProgramItemPlaced>();
@@ -104,12 +104,10 @@ private List<ProgramItemSlot> SelectSlots(ProgramItem programItem, Character cha
104104
{
105105
var fields = character.GetFields(projectInfo);
106106

107-
List<int> GetSlotIndexes(ProjectField field, IEnumerable<ScheduleItemAttribute> items)
107+
List<int> GetSlotIndexes(ProjectFieldInfo field, IEnumerable<ScheduleItemAttribute> items)
108108
{
109-
var variantIds = fields
110-
.Single(f => f.Field.ProjectFieldId == field.ProjectFieldId)
111-
.GetDropdownValues()
112-
.Select(variant => variant.ProjectFieldDropdownValueId)
109+
var variantIds = field.SortedVariants
110+
.Select(variant => variant.Id)
113111
.ToList();
114112
var indexes = (from item in items where variantIds.Contains(item.Id) select item.SeqId).ToList();
115113
if (indexes.Count < variantIds.Count) // Some variants not found, probably deleted
@@ -130,7 +128,7 @@ from roomSeqId in GetSlotIndexes(RoomField, Rooms)
130128
private static List<List<ProgramItemSlot>> InitializeSlots(List<TimeSlot> timeSlots, List<ScheduleRoom> rooms)
131129
=> timeSlots.Select(time => rooms.Select(room => new ProgramItemSlot(time, room)).ToList()).ToList();
132130

133-
private static IEnumerable<ScheduleRoom> InitializeScheduleRoomList(IReadOnlyList<ProjectFieldDropdownValue> readOnlyList)
131+
private static IEnumerable<ScheduleRoom> InitializeScheduleRoomList(IReadOnlyList<ProjectFieldVariant> readOnlyList)
134132
{
135133
var seqId = 0;
136134
foreach (var variant in readOnlyList.Where(x => x.IsActive))
@@ -141,7 +139,7 @@ private static IEnumerable<ScheduleRoom> InitializeScheduleRoomList(IReadOnlyLis
141139
}
142140
}
143141

144-
private static IEnumerable<TimeSlot> InitializeTimeSlotList(IReadOnlyList<ProjectFieldDropdownValue> readOnlyList)
142+
private static IEnumerable<TimeSlot> InitializeTimeSlotList(IEnumerable<TimeSlotFieldVariant> readOnlyList)
145143
{
146144
var seqId = 0;
147145
foreach (var variant in readOnlyList.Where(x => x.IsActive))

src/JoinRpg.Domain/Schedules/ScheduleModels.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using JoinRpg.DataModel;
22
using JoinRpg.Helpers;
3+
using JoinRpg.PrimitiveTypes;
4+
using JoinRpg.PrimitiveTypes.ProjectMetadata;
35

46
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
57

@@ -52,12 +54,12 @@ public record class ScheduleItemAttribute
5254
{
5355
public MarkdownString Description { get; }
5456
public string Name { get; }
55-
public int Id { get; }
57+
public ProjectFieldVariantIdentification Id { get; }
5658
public int SeqId { get; }
5759

58-
public ScheduleItemAttribute(ProjectFieldDropdownValue variant, int seqId)
60+
public ScheduleItemAttribute(ProjectFieldVariant variant, int seqId)
5961
{
60-
Id = variant.ProjectFieldDropdownValueId;
62+
Id = variant.Id;
6163
Name = variant.Label;
6264
Description = variant.Description;
6365
SeqId = seqId;
@@ -66,16 +68,16 @@ public ScheduleItemAttribute(ProjectFieldDropdownValue variant, int seqId)
6668

6769
public record class ScheduleRoom : ScheduleItemAttribute
6870
{
69-
public ScheduleRoom(ProjectFieldDropdownValue variant, int seqId) : base(variant, seqId)
71+
public ScheduleRoom(ProjectFieldVariant variant, int seqId) : base(variant, seqId)
7072
{
7173
}
7274
}
7375

7476
public record class TimeSlot : ScheduleItemAttribute
7577
{
76-
public TimeSlot(ProjectFieldDropdownValue variant, int seqId) : base(variant, seqId)
78+
public TimeSlot(TimeSlotFieldVariant variant, int seqId) : base(variant, seqId)
7779
{
78-
Options = variant.GetTimeSlotOptions();
80+
Options = variant.TimeSlotOptions;
7981
}
8082

8183
public TimeSlotOptions Options { get; }

src/JoinRpg.Domain/Schedules/TimeSlotProgrammaticValue.cs

Lines changed: 0 additions & 123 deletions
This file was deleted.

src/JoinRpg.Portal/Controllers/GameFieldController.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using JoinRpg.Portal.Controllers.Common;
44
using JoinRpg.Portal.Infrastructure;
55
using JoinRpg.Portal.Infrastructure.Authorization;
6+
using JoinRpg.PrimitiveTypes;
67
using JoinRpg.PrimitiveTypes.ProjectMetadata;
78
using JoinRpg.Services.Interfaces;
89
using JoinRpg.Services.Interfaces.Projects;
@@ -20,6 +21,8 @@ namespace JoinRpg.Portal.Controllers;
2021
[Route("{ProjectId}/fields/[action]")]
2122
public class GameFieldController : ControllerGameBase
2223
{
24+
private readonly IProjectMetadataRepository projectMetadataRepository;
25+
2326
private IFieldSetupService FieldSetupService { get; }
2427
public FieldSetupManager Manager { get; }
2528
private ICurrentProjectAccessor CurrentProjectAccessor { get; }
@@ -30,13 +33,15 @@ public GameFieldController(
3033
IFieldSetupService fieldSetupService,
3134
IUserRepository userRepository,
3235
FieldSetupManager manager,
33-
ICurrentProjectAccessor currentProjectAccessor
36+
ICurrentProjectAccessor currentProjectAccessor,
37+
IProjectMetadataRepository projectMetadataRepository
3438
)
3539
: base(projectRepository, projectService, userRepository)
3640
{
3741
FieldSetupService = fieldSetupService;
3842
Manager = manager;
3943
CurrentProjectAccessor = currentProjectAccessor;
44+
this.projectMetadataRepository = projectMetadataRepository;
4045
}
4146

4247
private ActionResult ReturnToIndex()
@@ -217,7 +222,9 @@ public async Task<ActionResult> Delete(int projectId, int projectFieldId, IFormC
217222
[MasterAuthorize(Permission.CanChangeFields)]
218223
public async Task<ActionResult> CreateValue(int projectId, int projectFieldId)
219224
{
220-
var field = await ProjectRepository.GetProjectField(projectId, projectFieldId);
225+
var id = new ProjectFieldIdentification(new(projectId), projectFieldId);
226+
var metadata = await projectMetadataRepository.GetProjectMetadata(id.ProjectId);
227+
var field = metadata.GetFieldById(id);
221228
return View(new GameFieldDropdownValueCreateViewModel(field));
222229
}
223230

@@ -257,13 +264,16 @@ public async Task<ActionResult> CreateValue(GameFieldDropdownValueCreateViewMode
257264
[MasterAuthorize(Permission.CanChangeFields)]
258265
public async Task<ActionResult> EditValue(int projectId, int projectFieldId, int valueId)
259266
{
260-
var field = await ProjectRepository.GetProjectField(projectId, projectFieldId);
261-
var value = await ProjectRepository.GetFieldValue(projectId, projectFieldId, valueId);
262-
if (value == null)
267+
var id = new ProjectFieldIdentification(new(projectId), projectFieldId);
268+
var metadata = await projectMetadataRepository.GetProjectMetadata(id.ProjectId);
269+
270+
var field = metadata.GetFieldById(id);
271+
var variant = field.Variants.SingleOrDefault(v => v.Id.ProjectFieldVariantId == valueId);
272+
if (variant == null)
263273
{
264274
return NotFound();
265275
}
266-
return View(new GameFieldDropdownValueEditViewModel(field, value));
276+
return View(new GameFieldDropdownValueEditViewModel(field, variant));
267277
}
268278

269279
[HttpPost, ValidateAntiForgeryToken]

src/JoinRpg.Portal/Controllers/XGameApi/ProjectScheduleController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private ProgramItemInfoApi ToProgramItemInfoApi(ProgramItemPlaced slot)
6363
EndTime = slot.EndTime,
6464
Rooms = slot.Rooms.Distinct().Select(room => new RoomInfoApi
6565
{
66-
RoomId = room.Id,
66+
RoomId = room.Id.ProjectFieldVariantId,
6767
Name = room.Name,
6868
}),
6969
Description = slot.ProgramItem.Description.ToPlainText().ToString(),

src/JoinRpg.PrimitiveTypes/ProjectMetadata/ProjectFieldInfo.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ private readonly Lazy<VirtualOrderContainer<ProjectFieldVariant>> container
3333

3434
public IReadOnlyList<ProjectFieldVariant> SortedVariants => container.Value.OrderedItems;
3535

36+
public ProjectFieldVariant? LastVariant => SortedVariants.LastOrDefault(x => x.IsActive);
37+
3638
public string GetDisplayValue(string? value, IReadOnlyList<int>? selectedIDs)
3739
{
3840
if (Type == ProjectFieldType.Checkbox)
@@ -70,10 +72,19 @@ public string GetDisplayValue(string? value, IReadOnlyList<int>? selectedIDs)
7072

7173
public bool IsDescription { get; } = FieldSettings.DescriptionField == Id;
7274

75+
/// <summary>
76+
/// Special field - schedule time slot
77+
/// </summary>
78+
public bool IsTimeSlot => Type == ProjectFieldType.ScheduleTimeSlotField;
79+
/// <summary>
80+
/// Special field - schedule room slot
81+
/// </summary>
82+
public bool IsRoomSlot => Type == ProjectFieldType.ScheduleRoomField;
83+
7384
public IEnumerable<ProjectFieldVariant> GetPossibleVariants(
7485
AccessArguments accessArguments,
7586
IReadOnlyCollection<int> selectedIds)
76-
=> Variants.Where(v =>
87+
=> SortedVariants.Where(v =>
7788
selectedIds.Contains(v.Id.ProjectFieldVariantId) ||
7889
(v.IsActive && (v.IsPlayerSelectable || accessArguments.MasterAccess))
7990
);

0 commit comments

Comments
 (0)