public async Task <Unit> Handle(MoveNoteCommand request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } IReturnDbContext dbContext = this._returnDbContextFactory.CreateForEditContext(); // Get data Note?note = await dbContext.Notes .Include(x => x.Lane) .Include(x => x.Group) .Include(x => x.Retrospective) .FirstOrDefaultAsync(x => x.Id == request.NoteId, cancellationToken); if (note == null) { throw new NotFoundException(nameof(Note), request.NoteId); } NoteGroup?newTargetGroup = null; if (request.GroupId != null) { newTargetGroup = await dbContext.NoteGroups.Include(x => x.Lane). FirstOrDefaultAsync(x => x.Id == request.GroupId, cancellationToken); if (newTargetGroup == null) { throw new NotFoundException(nameof(NoteGroup), request.GroupId.Value); } } // Validate if (newTargetGroup != null && note.Lane.Id != newTargetGroup.Lane.Id) { throw new InvalidOperationException("Invalid move command: this would result in a lane change."); } NoteGroup involvedGroup = newTargetGroup ?? note.Group ?? throw new InvalidOperationException("Note move from ungrouped to ungrouped"); await this._securityValidator.EnsureAddOrUpdate(note.Retrospective, involvedGroup); // Update note.GroupId = newTargetGroup?.Id; note.Group = newTargetGroup; await dbContext.SaveChangesAsync(cancellationToken); // Broadcast var broadcast = new NoteMovedNotification(note.Retrospective.UrlId.StringId, (int)note.Lane.Id, note.Id, note.GroupId); await this._mediator.Publish(broadcast, cancellationToken); return(Unit.Value); }
public Task OnNoteMoved(NoteMovedNotification notification) { // Filter out irrelevant notifications if (notification.LaneId != this.Lane.Id || notification.RetroId != this.RetroId.StringId) { return(Task.CompletedTask); } this.InvokeAsync(() => { if (this.ExecuteNoteMove(notification.NoteId, notification.GroupId)) { this.StateHasChanged(); } }); return(Task.CompletedTask); }