From 93888369ceb22a266765ad27332960a94b0812e3 Mon Sep 17 00:00:00 2001 From: Neil Brommer Date: Thu, 16 Dec 2021 10:46:22 -0800 Subject: [PATCH] Add deleting bookmarks --- Start/Client/Components/Bookmark.razor | 29 ++++++- Start/Client/Components/DeleteBookmark.razor | 75 +++++++++++++++++++ Start/Client/Pages/Index.razor | 3 + Start/Client/Sass/app.scss | 8 +- Start/Client/Start.Client.csproj | 2 + .../DeleteBookmark/DeleteBookmarkActions.cs | 33 ++++++++ .../DeleteBookmark/DeleteBookmarkEffects.cs | 50 +++++++++++++ .../DeleteBookmark/DeleteBookmarkFeature.cs | 11 +++ .../DeleteBookmark/DeleteBookmarkReducers.cs | 39 ++++++++++ .../DeleteBookmark/DeleteBookmarkState.cs | 21 ++++++ 10 files changed, 266 insertions(+), 5 deletions(-) create mode 100644 Start/Client/Components/DeleteBookmark.razor create mode 100644 Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkActions.cs create mode 100644 Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkEffects.cs create mode 100644 Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkFeature.cs create mode 100644 Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkReducers.cs create mode 100644 Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkState.cs diff --git a/Start/Client/Components/Bookmark.razor b/Start/Client/Components/Bookmark.razor index e2ae192..9560da2 100644 --- a/Start/Client/Components/Bookmark.razor +++ b/Start/Client/Components/Bookmark.razor @@ -1,20 +1,41 @@ -
  • +@using Start.Client.Store.State +@using Start.Client.Store.Features.DeleteBookmark +@using Fluxor + +@inherits Fluxor.Blazor.Web.Components.FluxorComponent + +@inject IDispatcher dispatch +@inject IState state + +
  • @if (!String.IsNullOrEmpty(this.Model.Notes)) { -
    +
    @this.Model.Title - @this.Model.Notes +
    @this.Model.Notes
    } else { - @this.Model.Title + @this.Model.Title + } + + @if (this.state.Value.EditMode) + { + }
  • @code { [Parameter] public BookmarkDto Model { get; set; } = null!; + + public void OnDeleteBookmarkClick() + { + this.dispatch.Dispatch(new ShowDeleteBookmarkFormAction(this.Model)); + } } diff --git a/Start/Client/Components/DeleteBookmark.razor b/Start/Client/Components/DeleteBookmark.razor new file mode 100644 index 0000000..20443b8 --- /dev/null +++ b/Start/Client/Components/DeleteBookmark.razor @@ -0,0 +1,75 @@ +@using Start.Client.Store.Features.DeleteBookmark +@using Fluxor + +@inherits Fluxor.Blazor.Web.Components.FluxorComponent + +@inject IDispatcher dispatch +@inject IState state + +@{ string title = $"Delete Bookmark \"{this.state.Value.BookmarkToDelete?.Title}\""; } + + + @if (this.state.Value.DeleteBookmarkErrorMessage != null) + { + + @this.state.Value.DeleteBookmarkErrorMessage + + } + + @if (this.state.Value.BookmarkToDelete == null) + { + + There is no bookmark to delete selected + + } + else + { +

    Are you sure you want to delete this bookmark?

    +
    +
    Title
    +
    @this.state.Value.BookmarkToDelete.Title
    + +
    URL
    +
    @this.state.Value.BookmarkToDelete.Url
    + + @if (!string.IsNullOrWhiteSpace(this.state.Value.BookmarkToDelete.Notes)) + { +
    Notes
    +
    @this.state.Value.BookmarkToDelete.Notes
    + } +
    + +
    + @if (!this.state.Value.IsLoadingDeleteBookmark) + { + + + } + else + { + + + } +
    + } +
    + +@code { + private void OnClose() + { + this.dispatch.Dispatch(new HideDeleteBookmarkFormAction()); + } + + private void OnConfirmDelete() + { + if (this.state.Value.BookmarkToDelete == null) + { + dispatch.Dispatch(new ErrorFetchingDeleteBookmarkAction( + "No bookmark to delete is selected")); + return; + } + + this.dispatch.Dispatch(new SubmitDeleteBookmarkFormAction( + this.state.Value.BookmarkToDelete.BookmarkId)); + } +} diff --git a/Start/Client/Pages/Index.razor b/Start/Client/Pages/Index.razor index 227fcd6..96a793e 100644 --- a/Start/Client/Pages/Index.razor +++ b/Start/Client/Pages/Index.razor @@ -75,6 +75,8 @@ else + @* Data management forms *@ + @@ -82,6 +84,7 @@ else + } diff --git a/Start/Client/Sass/app.scss b/Start/Client/Sass/app.scss index 08c1eb0..7538403 100644 --- a/Start/Client/Sass/app.scss +++ b/Start/Client/Sass/app.scss @@ -195,8 +195,14 @@ ul.bookmarks { .bookmark { margin-top: 0; + display: flex; + flex-direction: row; - a { + .bookmarkDetails { + flex: 1; + } + + .bookmarkLink { display: inline-block; width: 100%; padding: 0.5em 0.83em; diff --git a/Start/Client/Start.Client.csproj b/Start/Client/Start.Client.csproj index 56ef6d0..125eba0 100644 --- a/Start/Client/Start.Client.csproj +++ b/Start/Client/Start.Client.csproj @@ -131,6 +131,7 @@ + @@ -149,5 +150,6 @@ + diff --git a/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkActions.cs b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkActions.cs new file mode 100644 index 0000000..d019efc --- /dev/null +++ b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkActions.cs @@ -0,0 +1,33 @@ +using Start.Shared; + +namespace Start.Client.Store.Features.DeleteBookmark { + public class ShowDeleteBookmarkFormAction { + public BookmarkDto BookmarkToDelete { get; init; } + + public ShowDeleteBookmarkFormAction(BookmarkDto bookmarkToDelete) { + this.BookmarkToDelete = bookmarkToDelete; + } + } + + public class HideDeleteBookmarkFormAction { } + + public class FetchDeleteBookmarkAction { } + + public class RecievedDeleteBookmarkAction { } + + public class ErrorFetchingDeleteBookmarkAction { + public string ErrorMessage { get; init; } + + public ErrorFetchingDeleteBookmarkAction(string errorMessage) { + this.ErrorMessage = errorMessage; + } + } + + public class SubmitDeleteBookmarkFormAction { + public int BookmarkIdToDelete { get; init; } + + public SubmitDeleteBookmarkFormAction(int bookmarkIdToDelete) { + this.BookmarkIdToDelete = bookmarkIdToDelete; + } + } +} diff --git a/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkEffects.cs b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkEffects.cs new file mode 100644 index 0000000..682365d --- /dev/null +++ b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkEffects.cs @@ -0,0 +1,50 @@ +using System.Threading.Tasks; +using Fluxor; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Start.Client.Store.Features.CurrentContainer; +using Start.Shared.Api; + +namespace Start.Client.Store.Features.DeleteBookmark { + public class DeleteBookmarkEffects { + public IBookmarksApi BookmarksApi { get; init; } + + public DeleteBookmarkEffects(IBookmarksApi bookmarksApi) { + this.BookmarksApi = bookmarksApi; + } + + [EffectMethod] + public async Task SubmitDeleteBookmarkForm(SubmitDeleteBookmarkFormAction action, + IDispatcher dispatch) { + dispatch.Dispatch(new FetchDeleteBookmarkAction()); + + try { + System.Net.Http.HttpResponseMessage? apiResponse = await this.BookmarksApi + .DeleteBookmark(action.BookmarkIdToDelete); + + if (apiResponse == null) { + dispatch.Dispatch(new ErrorFetchingDeleteBookmarkAction( + "Failed to make submit request")); + return; + } + + if (apiResponse.StatusCode == System.Net.HttpStatusCode.NotFound) { + dispatch.Dispatch(new ErrorFetchingDeleteBookmarkAction( + "The bookmark to delete doesn't exist")); + return; + } + + if (!apiResponse.IsSuccessStatusCode) { + dispatch.Dispatch(new ErrorFetchingDeleteBookmarkAction( + "There was an error deleting the bookmark")); + return; + } + + dispatch.Dispatch(new RemoveBookmarkAction(action.BookmarkIdToDelete)); + dispatch.Dispatch(new RecievedDeleteBookmarkAction()); + dispatch.Dispatch(new HideDeleteBookmarkFormAction()); + } catch (AccessTokenNotAvailableException e) { + e.Redirect(); + } + } + } +} diff --git a/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkFeature.cs b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkFeature.cs new file mode 100644 index 0000000..a014cb2 --- /dev/null +++ b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkFeature.cs @@ -0,0 +1,11 @@ +using Fluxor; + +namespace Start.Client.Store.Features.DeleteBookmark { + public class DeleteBookmarkFeature : Feature { + public override string GetName() => "Delete Bookmark"; + + protected override DeleteBookmarkState GetInitialState() { + return new DeleteBookmarkState(); + } + } +} diff --git a/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkReducers.cs b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkReducers.cs new file mode 100644 index 0000000..bc983fb --- /dev/null +++ b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkReducers.cs @@ -0,0 +1,39 @@ +using Fluxor; + +namespace Start.Client.Store.Features.DeleteBookmark { + public static class DeleteBookmarkReducers { + [ReducerMethod] + public static DeleteBookmarkState ShowDeleteBookmarkForm(DeleteBookmarkState state, + ShowDeleteBookmarkFormAction action) { + return state with { + ShowDeleteBookmarkForm = true, + BookmarkToDelete = action.BookmarkToDelete, + IsLoadingDeleteBookmark = false, + DeleteBookmarkErrorMessage = null + }; + } + + [ReducerMethod(typeof(HideDeleteBookmarkFormAction))] + public static DeleteBookmarkState HideDeleteBookmarkForm(DeleteBookmarkState state) { + return state with { + ShowDeleteBookmarkForm = false + }; + } + + [ReducerMethod(typeof(FetchDeleteBookmarkAction))] + public static DeleteBookmarkState FetchDeleteBookmark(DeleteBookmarkState state) { + return state with { + IsLoadingDeleteBookmark = true, + DeleteBookmarkErrorMessage = null + }; + } + + [ReducerMethod(typeof(RecievedDeleteBookmarkAction))] + public static DeleteBookmarkState RecievedDeleteBookmark(DeleteBookmarkState state) { + return state with { + IsLoadingDeleteBookmark = false, + DeleteBookmarkErrorMessage = null + }; + } + } +} diff --git a/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkState.cs b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkState.cs new file mode 100644 index 0000000..e120095 --- /dev/null +++ b/Start/Client/Store/Features/DeleteBookmark/DeleteBookmarkState.cs @@ -0,0 +1,21 @@ +using Start.Client.Store.State; +using Start.Shared; + +namespace Start.Client.Store.Features.DeleteBookmark { + public record DeleteBookmarkState : RootState { + public bool ShowDeleteBookmarkForm { get; init; } + public BookmarkDto? BookmarkToDelete { get; init; } + public bool IsLoadingDeleteBookmark { get; init; } + public string? DeleteBookmarkErrorMessage { get; init; } + + public DeleteBookmarkState() { } + + public DeleteBookmarkState(bool showDeleteBookmarkForm, BookmarkDto bookmarkToDelete, + bool isLoadingDeleteBookmark, string? deleteBookmarkErrorMessage) { + this.ShowDeleteBookmarkForm = showDeleteBookmarkForm; + this.BookmarkToDelete = bookmarkToDelete; + this.IsLoadingDeleteBookmark = isLoadingDeleteBookmark; + this.DeleteBookmarkErrorMessage = deleteBookmarkErrorMessage; + } + } +}