private async Task <T> InvokeAsync <T>(PersistEntitiesRequestModel request, T response)
            where T : ViewCommandResponseModel
        {
            var collection = await _collectionResolver.ResolveSetupAsync(request.ListContext.CollectionAlias);

            var repository = _repositoryResolver.GetRepository(collection);

            var(crudType, entityVariant) = await _buttonInteraction.ValidateButtonInteractionAsync(request);

            switch (crudType)
            {
            case CrudType.Create:
                if (entityVariant == null)
                {
                    throw new InvalidOperationException($"Button of type {CrudType.Create} must have an EntityVariant.");
                }

                if (response is ListViewCommandResponseModel || ShouldFallbackToNavigatingToNodeEditor(collection))
                {
                    _navigationStateProvider.AppendNavigationState(
                        request.NavigationState,
                        new NavigationState(
                            request.ListContext.CollectionAlias,
                            request.ListContext.Parent?.GetParentPath(),
                            entityVariant.Alias,
                            request.Related,
                            UsageType.New));
                }
                else
                {
                    _navigationStateProvider.AppendNavigationState(
                        request.NavigationState,
                        new NavigationState(
                            request.ListContext.CollectionAlias,
                            request.ListContext.Parent?.GetParentPath(),
                            request.Related,
                            UsageType.New,
                            PageType.Collection)
                    {
                        CollectionState = request.NavigationState.CollectionState
                    });
                }
                break;

            case CrudType.Update:
                var affectedEntities = new List <IEntity>();

                foreach (var editContext in request.ListContext.EditContexts.Where(f => f.IsModified() || f.IsReordered()))
                {
                    var innerRequest = new PersistEntityCollectionRequestModel
                    {
                        ActionId    = request.ActionId,
                        CustomData  = request.CustomData,
                        EditContext = editContext,
                        ListContext = request.ListContext
                    };
                    if (!await editContext.IsValidAsync())
                    {
                        throw new InvalidEntityException();
                    }

                    await _buttonInteraction.ValidateButtonInteractionAsync(innerRequest);

                    if (editContext.IsModified())
                    {
                        var wrapper = await _editContextFactory.GetEditContextWrapperAsync(editContext);

                        await _concurrencyService.EnsureCorrectConcurrencyAsync(() => repository.UpdateAsync(wrapper));
                    }
                    if (editContext.IsReordered())
                    {
                        await _concurrencyService.EnsureCorrectConcurrencyAsync(
                            () => repository.ReorderAsync(editContext.ReorderedBeforeId, editContext.Entity.Id !, new ViewContext(null, editContext.Parent)));
                    }

                    affectedEntities.Add(editContext.Entity);
                }

                response.RefreshIds = affectedEntities.SelectNotNull(x => x.Id);

                _mediator.NotifyEvent(this, new CollectionRepositoryEventArgs(
                                          collection.Alias,
                                          collection.RepositoryAlias,
                                          request.ListContext.ProtoEditContext.Parent?.GetParentPath(),
                                          response.RefreshIds,
                                          CrudType.Update));
                break;

            case CrudType.None:
                response.NoOp = true;
                break;

            case CrudType.Refresh:
                break;

            case CrudType.Return:
                if (!_navigationStateProvider.RemoveNavigationState(request.NavigationState))
                {
                    var parentPath = request.ListContext.Parent?.GetParentPath();
                    _navigationStateProvider.AppendNavigationState(
                        request.NavigationState,
                        new NavigationState(
                            request.ListContext.CollectionAlias,
                            parentPath,
                            request.Related,
                            collection.ListEditor == null ? UsageType.View : UsageType.Edit,
                            PageType.Collection));
                }
                break;

            case CrudType.Up:
                var(newParentPath, repositoryAlias, parentId) = ParentPath.RemoveLevel(request.ListContext.Parent?.GetParentPath());

                if (repositoryAlias == null)
                {
                    break;
                }

                var parentCollection = collection.Parent != null && collection.Parent.Type == PageType.Collection ? await _collectionResolver.ResolveSetupAsync(collection.Parent.Alias) : default;

                if (parentCollection == null)
                {
                    throw new InvalidOperationException("Cannot go Up on collection that is root.");
                }

                _navigationStateProvider.AppendNavigationState(
                    request.NavigationState,
                    new NavigationState(
                        request.ListContext.CollectionAlias,
                        newParentPath,
                        parentCollection.EntityVariant.Alias,
                        parentId,
                        collection.ListEditor == null ? UsageType.View : UsageType.Edit));
                break;

            case CrudType.Add when request.Related != null:
                _navigationStateProvider.AppendNavigationState(
                    request.NavigationState,
                    new NavigationState(
                        request.ListContext.CollectionAlias,
                        request.Related,
                        UsageType.Add));
                break;

            default:
                throw new InvalidOperationException();
            }

            await _buttonInteraction.CompleteButtonInteractionAsync(request);

            return(response);
        }
Exemplo n.º 2
0
        private async Task <T> InvokeAsync <T>(PersistEntitiesRequestModel request, T response, IPageState pageState)
            where T : ViewCommandResponseModel
        {
            var collection = _collectionResolver.ResolveSetup(request.ListContext.CollectionAlias);
            var repository = _repositoryResolver.GetRepository(collection);

            var(crudType, entityVariant) = await _buttonInteraction.ValidateButtonInteractionAsync(request);

            switch (crudType)
            {
            case CrudType.Create:
                if (entityVariant == null)
                {
                    throw new InvalidOperationException($"Button of type {CrudType.Create} must have an EntityVariant.");
                }
                if (response is ListViewCommandResponseModel)
                {
                    pageState.PushState(new PageStateModel
                    {
                        PageType  = PageType.Node,
                        UsageType = UsageType.New,

                        CollectionAlias = request.ListContext.CollectionAlias,
                        VariantAlias    = entityVariant.Alias,
                        ParentPath      = request.ListContext.Parent?.GetParentPath()
                    });
                }
                else
                {
                    var currentState = pageState.GetCurrentState();

                    pageState.PushState(new PageStateModel
                    {
                        PageType  = PageType.Collection,
                        UsageType = UsageType.New,

                        CollectionAlias = request.ListContext.CollectionAlias,
                        VariantAlias    = entityVariant.Alias,
                        ParentPath      = request.ListContext.Parent?.GetParentPath(),

                        // is this the best place here?
                        ActiveTab   = currentState?.ActiveTab,
                        CurrentPage = currentState?.CurrentPage ?? 1,
                        MaxPage     = currentState?.MaxPage,
                        SearchTerm  = currentState?.SearchTerm,
                    });
                }
                break;

            case CrudType.Update:
                var affectedEntities = new List <IEntity>();

                foreach (var editContext in request.ListContext.EditContexts.Where(f => f.IsModified() || f.IsReordered()))
                {
                    var innerRequest = new PersistEntityCollectionRequestModel
                    {
                        ActionId    = request.ActionId,
                        CustomData  = request.CustomData,
                        EditContext = editContext,
                        ListContext = request.ListContext
                    };

                    await _buttonInteraction.ValidateButtonInteractionAsync(innerRequest);

                    if (editContext.IsModified())
                    {
                        await _concurrencyService.EnsureCorrectConcurrencyAsync(() => repository.UpdateAsync(editContext));
                    }
                    if (editContext.IsReordered())
                    {
                        await _concurrencyService.EnsureCorrectConcurrencyAsync(
                            () => repository.ReorderAsync(editContext.ReorderedBeforeId, editContext.Entity.Id !, editContext.Parent));
                    }

                    affectedEntities.Add(editContext.Entity);
                }

                response.RefreshIds = affectedEntities.SelectNotNull(x => x.Id);
                break;

            case CrudType.None:
                response.NoOp = true;
                break;

            case CrudType.Refresh:
                break;

            case CrudType.Return:
                if (pageState.PopState() == null)
                {
                    pageState.ReplaceState(new PageStateModel
                    {
                        PageType  = PageType.Collection,
                        UsageType = collection.ListEditor == null ? UsageType.View : UsageType.Edit,

                        CollectionAlias = request.ListContext.CollectionAlias,
                        ParentPath      = request.ListContext.Parent?.GetParentPath()
                    });
                }
                break;

            case CrudType.Up:
                if (pageState.PopState() == null)
                {
                    var(newParentPath, parentCollectionAlias, parentId) = ParentPath.RemoveLevel(request.ListContext.Parent?.GetParentPath());

                    if (parentCollectionAlias == null)
                    {
                        break;
                    }

                    var parentCollection = _collectionResolver.ResolveSetup(parentCollectionAlias);

                    pageState.ReplaceState(new PageStateModel
                    {
                        PageType  = PageType.Node,
                        UsageType = parentCollection.NodeEditor == null ? UsageType.View : UsageType.Edit,

                        CollectionAlias = parentCollectionAlias,
                        ParentPath      = newParentPath,
                        VariantAlias    = collection.EntityVariant.Alias,
                        Id = parentId
                    });
                }
                break;

            case CrudType.Add when request.Related != null:
                pageState.PushState(new PageStateModel
                {
                    PageType  = PageType.Collection,
                    UsageType = UsageType.Add,

                    CollectionAlias = request.ListContext.CollectionAlias,
                    Related         = request.Related
                });
                break;

            default:
                throw new InvalidOperationException();
            }

            await _buttonInteraction.CompleteButtonInteractionAsync(request);

            return(response);
        }