Esempio n. 1
0
        /// <summary>
        /// Execute a modal dialog, and wait for it to close.
        /// </summary>
        public Task <TResult> ExecuteModalTemplateAsync <TModel, TResult>(ModalTemplate <TModel, TResult> template, TModel model, TResult initialResult, CancellationToken cancellationToken = default)
        {
            if (IsModalActive(template))
            {
                throw new Exception("Modal already active");
            }

            var completionSource = new TaskCompletionSource <TResult>();

            var obj = new object();

            var context = new ModalTemplate <TModel, TResult> .ModalContext(model, initialResult, result =>
            {
                //notify modal container
                var modal = ActiveModals.FirstOrDefault(m => m.Template == template);
                ActiveModals.Remove(modal);
                OnModalClose?.Invoke(template, new ModalEventArgs
                {
                    Modal = modal
                });


                if (completionSource.Task.IsCompleted)
                {
                    throw new Exception("Trying to close modal twice!");
                }

                //complete task
                completionSource.SetResult(result);
            }, ModalStateHasChanged, cancellationToken);

            //render fragment;
            var newModal = new ActiveModal()
            {
                Type      = null,
                Template  = template,
                ModalBody = template.ChildContent(context),
            };

            ActiveModals.Add(newModal);

            //notify modal container
            OnModalShow?.Invoke(template, new ModalEventArgs
            {
                Modal = newModal,
            });

            //return task, which completes when the modal closes
            return(completionSource.Task);
        }
Esempio n. 2
0
        public Task ShowAsync <TModel>(TModel model)
        {
            model.ThrowIfNull();

            if (ActiveModal != null)
            {
                throw new ApplicationException("Another modal is already active.");
            }

            var completionSource = new TaskCompletionSource <object?>();
            var modelType        = typeof(TModel);

            if (!_modelComponentMapping.TryGetValue(modelType, out var componentType))
            {
                throw new ApplicationException($"No component for model '{modelType.Name}' found.");
            }

            ActiveModal         = new ModalState(componentType, model !);
            ActiveModal.Closed += OnClosed;

            StateChanged?.Invoke();

            return(completionSource.Task);


            // Local event handler
            void OnClosed(ModalState state)
            {
                // Unsubscribe to all trigger and dispose toast
                state.Closed -= OnClosed;

                // Reset active dialog field
                ActiveModal.Dispose();
                ActiveModal = null;

                StateChanged?.Invoke();

                completionSource.SetResult(null);
            }
        }
Esempio n. 3
0
        public Task <TResult> ExecuteModalComponentAsync <TComponent, TModel, TResult>(TModel model, CancellationToken cancellationToken = default) where TComponent : ModalComponentBase <TComponent, TModel, TResult>
        {
            var modalComponent   = typeof(TComponent);
            var completionSource = new TaskCompletionSource <TResult>();

            var obj = new object();

            var context = new ModalComponentBase <TComponent, TModel, TResult> .ModalContext(result =>
            {
                //notify modal container
                var modal = ActiveModals.FirstOrDefault(m => m.Type == modalComponent);
                ActiveModals.Remove(modal);
                OnModalClose?.Invoke(modalComponent, new ModalEventArgs
                {
                    Modal = modal
                });


                if (completionSource.Task.IsCompleted)
                {
                    throw new Exception("Trying to close modal twice!");
                }

                //complete task
                completionSource.SetResult(result);
            }, ModalStateHasChanged, cancellationToken);

            //render fragment;
            ActiveModal newModal = new ActiveModal()
            {
                Type     = modalComponent,
                Template = null,
            };

            newModal.ModalBody = (builder) =>
            {
                builder.OpenComponent <TComponent>(0);
                builder.AddAttribute(1, "Context", context);
                builder.AddAttribute(2, "Model", model);
                builder.AddComponentReferenceCapture(3, value =>
                {
                    var template = value as IModalTemplate;
                    if (template != newModal.Template)
                    {
                        newModal.Template = value as IModalTemplate;

                        //redraw modal container in order to get css class from modal template instance
                        ModalStateHasChanged();
                    }
                });
                builder.CloseComponent();
            };
            ActiveModals.Add(newModal);

            //notify modal container
            OnModalShow?.Invoke(modalComponent, new ModalEventArgs
            {
                Modal = newModal,
            });

            //return task, which completes when the modal closes
            return(completionSource.Task);
        }