From a6fd891cc50019e9805f807069fb63e80de3a3a7 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Tue, 26 Jan 2021 22:26:36 -0500 Subject: [PATCH] Add common loading component This has no specific issue associated, but reduces boilerplate in most page components --- .../Client/Pages/Citizen/Dashboard.razor | 69 +++---- .../Client/Pages/Citizen/Dashboard.razor.cs | 18 +- .../Client/Pages/Citizen/EditProfile.razor | 195 +++++++++--------- .../Client/Pages/Citizen/EditProfile.razor.cs | 17 +- .../Client/Pages/Profile/View.razor | 75 +++---- .../Client/Pages/Profile/View.razor.cs | 27 +-- .../Client/Pages/SuccessStory/EditStory.razor | 72 +++---- .../Pages/SuccessStory/EditStory.razor.cs | 17 +- .../Pages/SuccessStory/ListStories.razor | 11 +- .../Pages/SuccessStory/ListStories.razor.cs | 18 +- src/JobsJobsJobs/Client/Shared/Loading.razor | 18 ++ .../Client/Shared/Loading.razor.cs | 58 ++++++ src/JobsJobsJobs/Client/Shared/NavMenu.razor | 4 +- 13 files changed, 299 insertions(+), 300 deletions(-) create mode 100644 src/JobsJobsJobs/Client/Shared/Loading.razor create mode 100644 src/JobsJobsJobs/Client/Shared/Loading.razor.cs diff --git a/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor b/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor index 51a70ee..b8a82c7 100644 --- a/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor +++ b/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor @@ -6,46 +6,39 @@

Welcome, @state.User!.Name!

-@if (RetrievingData) -{ -

Retrieving your employment profile...

-} -else -{ - - @if (Profile != null) - { -

- Your employment profile was last updated . Your profile currently - lists @Profile.Skills.Length skill@(Profile.Skills.Length != 1 ? "s" : ""). -

-

View Your Employment Profile

- @if (Profile.SeekingEmployment) - { -

- Your profile indicates that you are seeking employment. Once you find it, - tell your fellow citizens about it! -

- } - } - else - { -

- You do not have an employment profile established; click “Edit Profile” in the menu to get - started! -

- } -
+ + @if (Profile != null) + {

- There @(ProfileCount == 1 ? "is" : "are") @(ProfileCount == 0 ? "no" : ProfileCount) employment - profile@(ProfileCount != 1 ? "s" : "") from citizens of Gitmo Nation. - @if (ProfileCount > 0) - { - Take a look around and see if you can help them find work! - } + Your employment profile was last updated . Your profile currently + lists @Profile.Skills.Length skill@(Profile.Skills.Length != 1 ? "s" : "").

-
-} +

View Your Employment Profile

+ @if (Profile.SeekingEmployment) + { +

+ Your profile indicates that you are seeking employment. Once you find it, + tell your fellow citizens about it! +

+ } + } + else + { +

+ You do not have an employment profile established; click “Edit Profile” in the menu to get + started! +

+ } +
+

+ There @(ProfileCount == 1 ? "is" : "are") @(ProfileCount == 0 ? "no" : ProfileCount) employment + profile@(ProfileCount != 1 ? "s" : "") from citizens of Gitmo Nation. + @if (ProfileCount > 0) + { + Take a look around and see if you can help them find work! + } +

+

Phase 3 – What Works diff --git a/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor.cs b/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor.cs index 71dccac..dd967e5 100644 --- a/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor.cs +++ b/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor.cs @@ -11,11 +11,6 @@ namespace JobsJobsJobs.Client.Pages.Citizen /// public partial class Dashboard : ComponentBase { - /// - /// Whether the data is being retrieved - /// - private bool RetrievingData { get; set; } = true; - /// /// The user's profile /// @@ -27,11 +22,10 @@ namespace JobsJobsJobs.Client.Pages.Citizen private int ProfileCount { get; set; } /// - /// Error messages from data access + /// Load the user's profile information /// - private IList ErrorMessages { get; } = new List(); - - protected override async Task OnInitializedAsync() + /// A collection to report errors that may be encountered + public async Task LoadProfile(ICollection errors) { if (state.User != null) { @@ -47,7 +41,7 @@ namespace JobsJobsJobs.Client.Pages.Citizen } else { - ErrorMessages.Add(profileTask.Result.Error); + errors.Add(profileTask.Result.Error); } if (profileCountTask.Result.IsOk) @@ -56,10 +50,8 @@ namespace JobsJobsJobs.Client.Pages.Citizen } else { - ErrorMessages.Add(profileCountTask.Result.Error); + errors.Add(profileCountTask.Result.Error); } - - RetrievingData = false; } } } diff --git a/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor b/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor index 2ba8578..05c8047 100644 --- a/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor +++ b/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor @@ -8,118 +8,111 @@

Employment Profile

-@if (AllLoaded) -{ - - - -
-
-
- - - @if (IsSeeking) + + + +
+
+
+ + + @if (IsSeeking) + { +     If you have found employment, consider + telling your fellow citizens about it + + } +
+
+
+
+
+
+ + + + @foreach (var (id, name) in Continents) { -     If you have found employment, consider - telling your fellow citizens about it - + } -
+ + ProfileForm.ContinentId) />
-
-
-
- - - - @foreach (var (id, name) in Continents) - { - - } - - ProfileForm.ContinentId) /> -
-
-
-
- - - ProfileForm.Region) /> -
+
+
+ + + ProfileForm.Region) />
-
-
-
- - - ProfileForm.Biography) /> -
+
+
+
+
+ + + ProfileForm.Biography) />
-
-
-
- - -
-
-
-
- - -
+
+
+
+
+ +
-
-

- Skills   - -

- @foreach (var skill in ProfileForm.Skills) - { - - } -
-

Experience

-

- This application does not have a place to individually list your chronological job history; however, you can - use this area to list prior jobs, their dates, and anything else you want to include that’s not already a - part of your Professional Biography above. -

-
-
- +
+
+ +
-
-
-
- - -
-
-
-
-
-
- -
-
- - @if (!IsNew) +
+
+

+ Skills   + +

+ @foreach (var skill in ProfileForm.Skills) { -

-
View Your User Profile -

+ } - -} -else -{ -

Loading your profile...

-} +
+

Experience

+

+ This application does not have a place to individually list your chronological job history; however, you can + use this area to list prior jobs, their dates, and anything else you want to include that’s not already a + part of your Professional Biography above. +

+
+
+ +
+
+
+
+
+ + +
+
+
+
+
+
+ +
+
+ + @if (!IsNew) + { +

+
View Your User Profile +

+ } + diff --git a/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor.cs b/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor.cs index c62af77..73632db 100644 --- a/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor.cs +++ b/src/JobsJobsJobs/Client/Pages/Citizen/EditProfile.razor.cs @@ -18,11 +18,6 @@ namespace JobsJobsJobs.Client.Pages.Citizen /// private int _newSkillCounter = 0; - /// - /// A flag that indicates all the required API calls have completed, and the form is ready to be displayed - /// - private bool AllLoaded { get; set; } = false; - /// /// Whether the citizen is seeking employment at the time the profile is loaded (used to show success story /// link) @@ -45,11 +40,10 @@ namespace JobsJobsJobs.Client.Pages.Citizen private bool IsNew { get; set; } = false; /// - /// Error messages from API access + /// Set up the data needed to add or edit the user's profile /// - private IList ErrorMessages { get; } = new List(); - - protected override async Task OnInitializedAsync() + /// The collection where errors can be reported + public async Task SetUpProfile(ICollection errors) { ServerApi.SetJwt(http, state); var continentTask = state.GetContinents(http); @@ -75,10 +69,8 @@ namespace JobsJobsJobs.Client.Pages.Citizen } else { - ErrorMessages.Add(profileTask.Result.Error); + errors.Add(profileTask.Result.Error); } - - AllLoaded = true; } /// @@ -118,6 +110,5 @@ namespace JobsJobsJobs.Client.Pages.Citizen toast.ShowError($"{(int)res.StatusCode} {error}"); } } - } } diff --git a/src/JobsJobsJobs/Client/Pages/Profile/View.razor b/src/JobsJobsJobs/Client/Pages/Profile/View.razor index 1909c57..c513cb1 100644 --- a/src/JobsJobsJobs/Client/Pages/Profile/View.razor +++ b/src/JobsJobsJobs/Client/Pages/Profile/View.razor @@ -2,51 +2,44 @@ @inject HttpClient http @inject AppState state -@if (IsLoading) -{ -

Loading profile...

-} -else -{ + - -

@Citizen.DisplayName

-

@Profile.Continent!.Name, @Profile.Region

-

@WorkTypes

+

@Citizen.DisplayName

+

@Profile.Continent!.Name, @Profile.Region

+

@WorkTypes

-
+
-
- @(new MarkupString(Profile.Biography.ToHtml())) -
+
+ @(new MarkupString(Profile.Biography.ToHtml())) +
- @if (Profile.Skills.Length > 0) - { -
-

Skills

-
    - @foreach (var skill in Profile.Skills) - { - var notes = skill.Notes == null ? "" : $" ({skill.Notes})"; -
  • @skill.Description@notes
  • - } -
- } + @if (Profile.Skills.Length > 0) + { +
+

Skills

+
    + @foreach (var skill in Profile.Skills) + { + var notes = skill.Notes == null ? "" : $" ({skill.Notes})"; +
  • @skill.Description@notes
  • + } +
+ } - @if (Profile.Experience != null) - { -
-

Experience / Employment History

-
- @(new MarkupString(Profile.Experience.ToHtml())) -
- } + @if (Profile.Experience != null) + { +
+

Experience / Employment History

+
+ @(new MarkupString(Profile.Experience.ToHtml())) +
+ } - @if (Id == state.User!.Id.ToString()) - { -
-

Edit Your Profile

- } -
-} + @if (Id == state.User!.Id.ToString()) + { +
+

Edit Your Profile

+ } +
diff --git a/src/JobsJobsJobs/Client/Pages/Profile/View.razor.cs b/src/JobsJobsJobs/Client/Pages/Profile/View.razor.cs index c9691b6..42e79dd 100644 --- a/src/JobsJobsJobs/Client/Pages/Profile/View.razor.cs +++ b/src/JobsJobsJobs/Client/Pages/Profile/View.razor.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Components; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Domain = JobsJobsJobs.Shared; @@ -8,11 +7,6 @@ namespace JobsJobsJobs.Client.Pages.Profile { public partial class View : ComponentBase { - /// - /// Whether data for this component is loading - /// - private bool IsLoading { get; set; } = true; - /// /// The citizen whose profile is being displayed /// @@ -48,18 +42,17 @@ namespace JobsJobsJobs.Client.Pages.Profile } } - /// - /// Error messages from data retrieval - /// - private IList ErrorMessages { get; } = new List(); - /// /// The ID of the citizen whose profile should be displayed /// [Parameter] public string Id { get; set; } = default!; - protected override async Task OnInitializedAsync() + /// + /// Retrieve the requested profile + /// + /// A collection to report errors that may occur + public async Task RetrieveProfile(ICollection errors) { ServerApi.SetJwt(http, state); var citizenTask = ServerApi.RetrieveOne(http, $"citizen/get/{Id}"); @@ -73,11 +66,11 @@ namespace JobsJobsJobs.Client.Pages.Profile } else if (citizenTask.Result.IsOk) { - ErrorMessages.Add("Citizen not found"); + errors.Add("Citizen not found"); } else { - ErrorMessages.Add(citizenTask.Result.Error); + errors.Add(citizenTask.Result.Error); } if (profileTask.Result.IsOk && profileTask.Result.Ok != null) @@ -86,14 +79,12 @@ namespace JobsJobsJobs.Client.Pages.Profile } else if (profileTask.Result.IsOk) { - ErrorMessages.Add("Profile not found"); + errors.Add("Profile not found"); } else { - ErrorMessages.Add(profileTask.Result.Error); + errors.Add(profileTask.Result.Error); } - - IsLoading = false; } } } diff --git a/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor b/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor index 9cb884a..2b07ccc 100644 --- a/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor +++ b/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor @@ -6,52 +6,44 @@ @inject IToastService toast -

@Title

- - @if (Loading) + + @if (IsNew) { -

Loading...

+

+ Congratulations on your employment! Your fellow citizens would enjoy hearing how it all came about; tell us + about it below! (These will be visible to other users, but not to the general public.) +

} - else - { - @if (IsNew) - { -

- Congratulations on your employment! Your fellow citizens would enjoy hearing how it all came about; tell us - about it below! (These will be visible to other users, but not to the general public.) -

- } - -
-
-
- - -
+ +
+
+
+ +
-
-
-
- - -
+
+
+
+
+ +
-
-
-
- - @if (IsNew) - { -

- (Saving this will set “Seeking Employment” to “No” on your profile.) -

- } -
+
+
+
+
+ + @if (IsNew) + { +

+ (Saving this will set “Seeking Employment” to “No” on your profile.) +

+ }
- - } - +
+ + diff --git a/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor.cs b/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor.cs index 5b9c536..7605576 100644 --- a/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor.cs +++ b/src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor.cs @@ -16,11 +16,6 @@ namespace JobsJobsJobs.Client.Pages.SuccessStory [Parameter] public string? Id { get; set; } - /// - /// Whether we are loading information - /// - private bool Loading { get; set; } = true; - /// /// The page title / header /// @@ -37,11 +32,10 @@ namespace JobsJobsJobs.Client.Pages.SuccessStory private bool IsNew => Form.Id == "new"; /// - /// Error messages from API access + /// Retrieve the story /// - private IList ErrorMessages { get; } = new List(); - - protected override async Task OnInitializedAsync() + /// A collection to use in reporting errors that may occur + public async Task RetrieveStory(ICollection errors) { if (Id != null) { @@ -58,14 +52,13 @@ namespace JobsJobsJobs.Client.Pages.SuccessStory } else if (story.IsOk) { - ErrorMessages.Add($"The success story {Id} does not exist"); + errors.Add($"The success story {Id} does not exist"); } else { - ErrorMessages.Add(story.Error); + errors.Add(story.Error); } } - Loading = false; } /// diff --git a/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor b/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor index bb960ad..6ddebe0 100644 --- a/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor +++ b/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor @@ -3,15 +3,10 @@ @inject AppState state -

Success Stories

- - @if (Loading) - { -

Loading...

- } - else if (Stories.Any()) + + @if (Stories.Any()) { @@ -43,4 +38,4 @@ {

There are no success stories recorded (yet)

} - + diff --git a/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor.cs b/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor.cs index ec33402..0ab0cd7 100644 --- a/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor.cs +++ b/src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor.cs @@ -1,30 +1,22 @@ using JobsJobsJobs.Shared.Api; using Microsoft.AspNetCore.Components; -using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace JobsJobsJobs.Client.Pages.SuccessStory { public partial class ListStories : ComponentBase { - /// - /// Whether we are still loading data - /// - private bool Loading { get; set; } = true; - /// /// The story entries /// private IEnumerable Stories { get; set; } = default!; /// - /// Error messages encountered + /// Load all success stories /// - private IList ErrorMessages { get; set; } = new List(); - - protected override async Task OnInitializedAsync() + /// The collection into which errors can be reported + public async Task LoadStories(ICollection errors) { ServerApi.SetJwt(http, state); var stories = await ServerApi.RetrieveMany(http, "success/list"); @@ -35,10 +27,8 @@ namespace JobsJobsJobs.Client.Pages.SuccessStory } else { - ErrorMessages.Add(stories.Error); + errors.Add(stories.Error); } - - Loading = false; } } } diff --git a/src/JobsJobsJobs/Client/Shared/Loading.razor b/src/JobsJobsJobs/Client/Shared/Loading.razor new file mode 100644 index 0000000..3b977f9 --- /dev/null +++ b/src/JobsJobsJobs/Client/Shared/Loading.razor @@ -0,0 +1,18 @@ +@if (IsLoading) +{ +

@Message

+} +else if (ErrorMessages.Count > 0) +{ +

The following error@(ErrorMessages.Count == 1 ? "" : "s") occurred:

+
    + @foreach (var msg in ErrorMessages) + { +
  • @msg
  • + } +
+} +else +{ + @ChildContent +} diff --git a/src/JobsJobsJobs/Client/Shared/Loading.razor.cs b/src/JobsJobsJobs/Client/Shared/Loading.razor.cs new file mode 100644 index 0000000..0dbaa78 --- /dev/null +++ b/src/JobsJobsJobs/Client/Shared/Loading.razor.cs @@ -0,0 +1,58 @@ +using Microsoft.AspNetCore.Components; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace JobsJobsJobs.Client.Shared +{ + public partial class Loading : ComponentBase + { + /// + /// The delegate to call to load the data for this page + /// + [Parameter] + public EventCallback> OnLoad { get; set; } + + /// + /// The message to display when the page is loading (optional) + /// + [Parameter] + public MarkupString Message { get; set; } = new MarkupString("Loading…"); + + /// + /// The content to be displayed once the data has been loaded + /// + [Parameter] + public RenderFragment ChildContent { get; set; } = default!; + + /// + /// Error messages that may arise from the data loading delegate + /// + private ICollection ErrorMessages { get; set; } = new List(); + + /// + /// Whether we are currently loading data + /// + private bool IsLoading { get; set; } = true; + + protected override async Task OnInitializedAsync() + { + if (OnLoad.HasDelegate) + { + try + { + await OnLoad.InvokeAsync(ErrorMessages); + } + finally + { + IsLoading = false; + } + } + else + { + IsLoading = false; + } + } + } +} diff --git a/src/JobsJobsJobs/Client/Shared/NavMenu.razor b/src/JobsJobsJobs/Client/Shared/NavMenu.razor index b2eda0d..b18d4ac 100644 --- a/src/JobsJobsJobs/Client/Shared/NavMenu.razor +++ b/src/JobsJobsJobs/Client/Shared/NavMenu.razor @@ -9,10 +9,10 @@ -
+