Add creating bookmark groups

This commit is contained in:
Neil Brommer 2021-12-05 15:50:48 -08:00
parent d997655b59
commit 7841d1d1a8
28 changed files with 692 additions and 114 deletions

View file

@ -4,12 +4,11 @@ using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Refit;
using Start.Shared;
using Start.Shared.Api;
using Start.Client.Store.Features.CurrentContainer;
using Start.Client.Store.Features.ContainersList;
namespace Start.Client.Store.Features.CreateContainer {
public class CreateContainerEffects {
public IBookmarkContainersApi BookmarkContainersApi { get; set; }
public IBookmarkContainersApi BookmarkContainersApi { get; init; }
public CreateContainerEffects(IBookmarkContainersApi bookmarkContainersApi) {
this.BookmarkContainersApi = bookmarkContainersApi;
@ -26,15 +25,14 @@ namespace Start.Client.Store.Features.CreateContainer {
BookmarkContainerDto? container = apiResponse.Content;
if (container == null)
if (container == null) {
dispatch.Dispatch(new ErrorFetchingCreateContainerAction(
"Failed to create container"));
else {
dispatch.Dispatch(new AddContainerToListAction(container));
dispatch.Dispatch(new ReceivedCreateContainerAction());
dispatch.Dispatch(new LoadCurrentContainerAction(
container.BookmarkContainerId));
return;
}
dispatch.Dispatch(new AddContainerToListAction(container));
dispatch.Dispatch(new ReceivedCreateContainerAction());
} catch (AccessTokenNotAvailableException e) {
e.Redirect();
}

View file

@ -1,4 +1,5 @@
using Fluxor;
using System;
using Fluxor;
namespace Start.Client.Store.Features.CreateContainer {
public static class CreateContainerReducers {

View file

@ -0,0 +1,35 @@
using Start.Shared;
namespace Start.Client.Store.Features.CreateGroup {
public class ShowCreateGroupFormAction {
public int ContainerId { get; init; }
public string ContainerTitle { get; init; }
public ShowCreateGroupFormAction(int containerId, string containerTitle) {
this.ContainerId = containerId;
this.ContainerTitle = containerTitle;
}
}
public class HideCreateGroupFormAction { }
public class FetchCreateGroupAction { }
public class RecievedCreateGroupAction { }
public class ErrorFetchingCreateGroupAction {
public string ErrorMessage { get; init; }
public ErrorFetchingCreateGroupAction(string errorMessage) {
this.ErrorMessage = errorMessage;
}
}
public class SubmitCreateGroupAction {
public BookmarkGroupDto NewGroup { get; init; }
public SubmitCreateGroupAction(BookmarkGroupDto newGroup) {
this.NewGroup = newGroup;
}
}
}

View file

@ -0,0 +1,44 @@
using Start.Shared.Api;
using Fluxor;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Refit;
using Start.Shared;
using Start.Client.Store.Features.CurrentContainer;
using System;
namespace Start.Client.Store.Features.CreateGroup {
public class CreateGroupEffects {
public IBookmarkGroupsApi BookmarkGroupsApi { get; init; }
public CreateGroupEffects(IBookmarkGroupsApi bookmarksApi) {
this.BookmarkGroupsApi = bookmarksApi;
}
[EffectMethod]
public async Task SubmitCreateBookmarkGroup(SubmitCreateGroupAction action,
IDispatcher dispatch) {
dispatch.Dispatch(new FetchCreateGroupAction());
try {
ApiResponse<BookmarkGroupDto?> apiResponse = await this.BookmarkGroupsApi
.CreateBookmarkGroup(action.NewGroup.Title, action.NewGroup.Color,
action.NewGroup.BookmarkContainerId);
Console.WriteLine("Status code: " + apiResponse.StatusCode);
if (!apiResponse.IsSuccessStatusCode) {
dispatch.Dispatch(new ErrorFetchingCreateGroupAction(
"Error creating bookmark group"));
return;
}
dispatch.Dispatch(new AddBookmarkGroupAction(action.NewGroup));
dispatch.Dispatch(new RecievedCreateGroupAction());
dispatch.Dispatch(new HideCreateGroupFormAction());
} catch (AccessTokenNotAvailableException e) {
e.Redirect();
}
}
}
}

View file

@ -0,0 +1,11 @@
using Fluxor;
namespace Start.Client.Store.Features.CreateGroup {
public class CreateGroupFeature : Feature<CreateGroupState> {
public override string GetName() => "Create Group";
protected override CreateGroupState GetInitialState() {
return new CreateGroupState();
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using Fluxor;
namespace Start.Client.Store.Features.CreateGroup {
public static class CreateGroupReducers {
[ReducerMethod]
public static CreateGroupState ShowCreateGroupForm(CreateGroupState state,
ShowCreateGroupFormAction action) {
return state with {
ShowCreateGroupForm = true,
ContainerId = action.ContainerId,
ContainerTitle = action.ContainerTitle,
IsLoadingCreateGroup = false,
CreateGroupErrorMessage = null
};
}
[ReducerMethod(typeof(HideCreateGroupFormAction))]
public static CreateGroupState HideCreateContainerForm(CreateGroupState state) {
return state with {
ShowCreateGroupForm = false,
IsLoadingCreateGroup = false,
CreateGroupErrorMessage = null,
ContainerId = 0,
ContainerTitle = ""
};
}
[ReducerMethod(typeof(FetchCreateGroupAction))]
public static CreateGroupState FetchCreateGroup(CreateGroupState state) {
return state with {
IsLoadingCreateGroup = true,
CreateGroupErrorMessage = null
};
}
[ReducerMethod(typeof(RecievedCreateGroupAction))]
public static CreateGroupState RecievedCreateGroup(CreateGroupState state) {
return state with {
IsLoadingCreateGroup = false,
CreateGroupErrorMessage = null
};
}
[ReducerMethod]
public static CreateGroupState ErrorFetchingCreateGroup(CreateGroupState state,
ErrorFetchingCreateGroupAction action) {
return state with {
CreateGroupErrorMessage = action.ErrorMessage,
IsLoadingCreateGroup = false
};
}
}
}

View file

@ -0,0 +1,25 @@
using Start.Client.Store.State;
namespace Start.Client.Store.Features.CreateGroup {
public record CreateGroupState : RootState {
public bool ShowCreateGroupForm { get; init; }
public int ContainerId { get; init; }
public string ContainerTitle { get; init; }
public bool IsLoadingCreateGroup { get; init; }
public string? CreateGroupErrorMessage { get; init; }
public CreateGroupState() {
this.ContainerTitle = "";
}
public CreateGroupState(ContainerListState containerList,
CurrentContainerState currentContainer, bool showCreateGroupForm, string containerTitle,
bool isLoadingCreateGroup, string? createGroupErrorMessage)
: base(containerList, currentContainer) {
this.ShowCreateGroupForm = showCreateGroupForm;
this.ContainerTitle = containerTitle;
this.IsLoadingCreateGroup = isLoadingCreateGroup;
this.CreateGroupErrorMessage = createGroupErrorMessage;
}
}
}

View file

@ -28,4 +28,20 @@ namespace Start.Client.Store.Features.CurrentContainer {
}
public class FixCurrentContainerAction { }
public class AddBookmarkGroupAction {
public BookmarkGroupDto BookmarkGroup { get; init; }
public AddBookmarkGroupAction(BookmarkGroupDto bookmarkGroup) {
this.BookmarkGroup = bookmarkGroup;
}
}
public class RemoveBookmarkGroupAction {
public int BookmarkGroupId { get; init; }
public RemoveBookmarkGroupAction(int bookmarkGroupId) {
this.BookmarkGroupId = bookmarkGroupId;
}
}
}

View file

@ -9,6 +9,7 @@ using Start.Client.Store.State;
using Start.Client.Store.Features.CreateContainer;
using Start.Shared;
using Start.Shared.Api;
using System;
namespace Start.Client.Store.Features.CurrentContainer {
public class CurrentContainerEffects {
@ -35,11 +36,17 @@ namespace Start.Client.Store.Features.CurrentContainer {
BookmarkContainerDto? container = response.Content;
if (container == null) {
Console.WriteLine("Error fetching container " + action.BookmarkContainerId);
Console.WriteLine(response);
dispatch.Dispatch(new ErrorFetchingCurrentContainerAction(
"Failed to get current bookmark container"));
return;
}
Console.WriteLine("Recieved container " + action.BookmarkContainerId);
Console.WriteLine(response);
dispatch.Dispatch(new ReceivedCurrentContainerAction(container));
await this.LocalStorage

View file

@ -1,5 +1,8 @@
using Fluxor;
using System.Collections.Generic;
using System.Linq;
using Fluxor;
using Start.Client.Store.State;
using Start.Shared;
namespace Start.Client.Store.Features.CurrentContainer {
public static class CurrentContainerReducers {
@ -37,5 +40,43 @@ namespace Start.Client.Store.Features.CurrentContainer {
}
};
}
[ReducerMethod]
public static RootState AddBookmarkGroup(RootState state, AddBookmarkGroupAction action) {
BookmarkContainerDto? container = state.CurrentContainerState.Container;
if (container == null)
return state;
if (action.BookmarkGroup.BookmarkContainerId != container.BookmarkContainerId)
return state;
return state with {
CurrentContainerState = state.CurrentContainerState with {
Container = new BookmarkContainerDto(container.BookmarkContainerId,
container.Title, container.BookmarkGroups?
.Concat(new List<BookmarkGroupDto> { action.BookmarkGroup })
.ToList())
}
};
}
[ReducerMethod]
public static RootState RemoveBookmarkGroup(RootState state,
RemoveBookmarkGroupAction action) {
BookmarkContainerDto? container = state.CurrentContainerState.Container;
if (container == null)
return state;
return state with {
CurrentContainerState = state.CurrentContainerState with {
Container = new BookmarkContainerDto(container.BookmarkContainerId,
container.Title, container.BookmarkGroups?
.Where(g => g.BookmarkGroupId != action.BookmarkGroupId)
.ToList())
}
};
}
}
}

View file

@ -0,0 +1,41 @@
using System.Threading.Tasks;
using Fluxor;
using Blazored.LocalStorage;
using Start.Client.Store.Features.ContainersList;
using Start.Client.Store.Features.CurrentContainer;
using System.Linq;
namespace Start.Client.Store.State {
public class StoreInitializedEffects {
public IState<RootState> State { get; init; }
public ILocalStorageService LocalStorage { get; init; }
public StoreInitializedEffects(IState<RootState> state, ILocalStorageService localStorage) {
this.State = state;
this.LocalStorage = localStorage;
}
[EffectMethod(typeof(StoreInitializedAction))]
public async Task InitialLoad(IDispatcher dispatch) {
dispatch.Dispatch(new LoadContainerListAction());
dispatch.Dispatch(new LoadCurrentContainerAction(await GetSelectedContainerId()));
}
private async Task<int> GetSelectedContainerId() {
bool hasValue = await this.LocalStorage.ContainKeyAsync("SelectedContainer");
if (hasValue)
return await this.LocalStorage.GetItemAsync<int>("SelectedContainer");
// Default to the first container
int firstContainer = this.State.Value.ContainerListState.Containers
.First().BookmarkContainerId;
await this.SetSelectedContainer(firstContainer);
return firstContainer;
}
protected async Task SetSelectedContainer(int selectedContainerId) {
await this.LocalStorage.SetItemAsync("SelectedContainer", selectedContainerId);
}
}
}