Use Fluxor for state management

This commit is contained in:
Neil Brommer 2021-12-03 16:44:02 -08:00
parent 437e90039f
commit 560c25b4e8
27 changed files with 823 additions and 210 deletions

View file

@ -0,0 +1,34 @@
namespace Start.Client.Store.Features.DeleteContainer {
public class ShowDeleteContainerFormAction {
public int ContainerIdToDelete { get; init; }
public string ContainerTitleToDelete { get; init; }
public ShowDeleteContainerFormAction(int containerIdToDelete,
string containerTitleToDelete) {
this.ContainerIdToDelete = containerIdToDelete;
this.ContainerTitleToDelete = containerTitleToDelete;
}
}
public class HideDeleteContainerFormAction { }
public class FetchDeleteContainerFormAction { }
public class SubmitDeleteContainerAction {
public int ContainerIdToDelete { get; init; }
public SubmitDeleteContainerAction(int containerIdToDelete) {
this.ContainerIdToDelete = containerIdToDelete;
}
}
public class RecievedDeleteContainerAction { }
public class ErrorFetchingDeleteContainerAction {
public string ErrorMessage { get; init; }
public ErrorFetchingDeleteContainerAction(string errorMessage) {
this.ErrorMessage = errorMessage;
}
}
}

View file

@ -0,0 +1,56 @@
using System.Threading.Tasks;
using Fluxor;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Start.Client.Store.Features.CurrentContainer;
using Start.Shared.Api;
using System.Net;
using Start.Client.Store.State;
using Start.Client.Store.Features.ContainersList;
namespace Start.Client.Store.Features.DeleteContainer {
public class DeleteContainerEffects {
public IBookmarkContainersApi BookmarkContainersApi { get; init; }
public IState<RootState> RootState { get; set; }
public DeleteContainerEffects(IBookmarkContainersApi bookmarkContainersApi,
IState<RootState> rootState) {
this.BookmarkContainersApi = bookmarkContainersApi;
this.RootState = rootState;
}
[EffectMethod]
public async Task SubmitDeleteContainer(SubmitDeleteContainerAction action,
IDispatcher dispatch) {
dispatch.Dispatch(new FetchDeleteContainerFormAction());
try {
System.Net.Http.HttpResponseMessage? apiResponse = await this.BookmarkContainersApi
.DeleteBookmarkContainer(action.ContainerIdToDelete);
if (apiResponse == null) {
dispatch.Dispatch(
new ErrorFetchingDeleteContainerAction("Failed to submit request"));
return;
}
if (apiResponse.StatusCode == HttpStatusCode.NotFound) {
dispatch.Dispatch(new ErrorFetchingDeleteContainerAction(
"The bookmark container to delete doesn't exist"));
return;
}
if (!apiResponse.IsSuccessStatusCode) {
dispatch.Dispatch(new ErrorFetchingDeleteContainerAction(
"There was an error deleting the bookmark container"));
return;
}
dispatch.Dispatch(new RemoveContainerFromListAction(action.ContainerIdToDelete));
dispatch.Dispatch(new FixCurrentContainerAction());
dispatch.Dispatch(new RecievedDeleteContainerAction());
} catch (AccessTokenNotAvailableException e) {
e.Redirect();
}
}
}
}

View file

@ -0,0 +1,11 @@
using Fluxor;
namespace Start.Client.Store.Features.DeleteContainer {
public class DeleteContainerFeature : Feature<DeleteContainerState> {
public override string GetName() => "Delete Container";
protected override DeleteContainerState GetInitialState() {
return new DeleteContainerState();
}
}
}

View file

@ -0,0 +1,50 @@
using Fluxor;
namespace Start.Client.Store.Features.DeleteContainer {
public static class DeleteContainerReducers {
[ReducerMethod]
public static DeleteContainerState ShowDeleteContainerForm(DeleteContainerState state,
ShowDeleteContainerFormAction action) {
return state with {
ShowDeleteContainerForm = true,
BookmarkContainerIdToDelete = action.ContainerIdToDelete,
BookmarkContainerTitleToDelete = action.ContainerTitleToDelete,
DeleteContainerErrorMessage = null
};
}
[ReducerMethod(typeof(HideDeleteContainerFormAction))]
public static DeleteContainerState HideDeleteContainerForm(DeleteContainerState state) {
return state with {
ShowDeleteContainerForm = false,
DeleteContainerErrorMessage = null
};
}
[ReducerMethod(typeof(FetchDeleteContainerFormAction))]
public static DeleteContainerState FetchDeleteContainerForm(DeleteContainerState state) {
return state with {
IsLoadingDeleteContainer = true,
DeleteContainerErrorMessage = null
};
}
[ReducerMethod(typeof(RecievedDeleteContainerAction))]
public static DeleteContainerState ReceivedDeleteContainer(DeleteContainerState state) {
return state with {
IsLoadingDeleteContainer = false,
DeleteContainerErrorMessage = null,
ShowDeleteContainerForm = false
};
}
[ReducerMethod]
public static DeleteContainerState ErrorFetchingDeleteContainer(DeleteContainerState state,
ErrorFetchingDeleteContainerAction action) {
return state with {
DeleteContainerErrorMessage = action.ErrorMessage,
IsLoadingDeleteContainer = false
};
}
}
}

View file

@ -0,0 +1,28 @@
using Start.Client.Store.State;
namespace Start.Client.Store.Features.DeleteContainer {
public record DeleteContainerState : RootState {
public bool ShowDeleteContainerForm { get; set; }
public int BookmarkContainerIdToDelete { get; set; }
public string BookmarkContainerTitleToDelete { get; set; }
public bool IsLoadingDeleteContainer { get; set; }
public string? DeleteContainerErrorMessage { get; set; }
public DeleteContainerState() {
this.BookmarkContainerIdToDelete = 0;
this.BookmarkContainerTitleToDelete = "";
}
public DeleteContainerState(ContainerListState containerList,
CurrentContainerState currentContainer, bool showDeleteContainerForm,
int containerIdToDelete, string containerTitleToDelete, bool isLoadingDeleteContainer,
string? errorMessage)
: base(containerList, currentContainer) {
this.ShowDeleteContainerForm = showDeleteContainerForm;
this.BookmarkContainerIdToDelete = containerIdToDelete;
this.BookmarkContainerTitleToDelete = containerTitleToDelete;
this.IsLoadingDeleteContainer = isLoadingDeleteContainer;
this.DeleteContainerErrorMessage = errorMessage;
}
}
}