Implement dynamic group management features with exclusions and mode handling
Enhanced the group management system by introducing dynamic group capabilities, allowing for the exclusion of elements from dynamic groups. Updated the Group and GroupItem models to support a new GroupMode, enabling the distinction between static and dynamic groups. Implemented API endpoints for excluding elements and updated related services to handle group composition based on the selected mode. Improved the frontend to accommodate these changes, including new API functions and UI components for managing exclusions and group modes, thereby enhancing the overall user experience in group management.
This commit is contained in:
+37
-6
@@ -2,26 +2,57 @@ using LiteCqrs;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Common.Models;
|
||||
using TeleWave.Domain.Programming;
|
||||
|
||||
namespace TeleWave.Application.Programming.Groups.UpdateGroup;
|
||||
|
||||
public sealed class UpdateGroupCommandHandler(IAppDbContext dbContext)
|
||||
: ICommandHandler<UpdateGroupCommand, Result>
|
||||
public sealed class UpdateGroupCommandHandler(
|
||||
IAppDbContext dbContext,
|
||||
DynamicGroupResolver dynamicResolver,
|
||||
GroupStatsService stats
|
||||
) : ICommandHandler<UpdateGroupCommand, Result>
|
||||
{
|
||||
public async Task<Result> Handle(
|
||||
UpdateGroupCommand command,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var group = await dbContext.Groups.FirstOrDefaultAsync(
|
||||
g => g.Id == command.GroupId,
|
||||
cancellationToken
|
||||
);
|
||||
var group = await dbContext
|
||||
.Groups.Include(g => g.Items)
|
||||
.FirstOrDefaultAsync(g => g.Id == command.GroupId, cancellationToken);
|
||||
if (group is null)
|
||||
return Result.Failure(GroupErrors.NotFound);
|
||||
|
||||
group.Rename(command.Name, command.Description);
|
||||
group.SetFilter(command.Filter?.ToJson());
|
||||
|
||||
if (command.Mode is { } mode && mode != group.Mode)
|
||||
await SwitchModeAsync(group, mode, cancellationToken);
|
||||
|
||||
await stats.RecomputeAsync(group, cancellationToken);
|
||||
return Result.Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Переход в статический режим материализует вычисленный состав: правило домен не понимает,
|
||||
/// а группа не должна опустеть от смены режима — на неё уже ссылаются слоты. Обратный переход
|
||||
/// домен делает сам (список становится закреплённым).
|
||||
/// </summary>
|
||||
private async Task SwitchModeAsync(
|
||||
Domain.Programming.Group group,
|
||||
GroupMode mode,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
if (mode == GroupMode.Dynamic)
|
||||
{
|
||||
group.SetMode(mode);
|
||||
return;
|
||||
}
|
||||
|
||||
var composition = await dynamicResolver.ResolveAsync(group, cancellationToken);
|
||||
group.SetMode(mode);
|
||||
foreach (var element in composition)
|
||||
group.AddElement(element.Kind, element.Id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user