From 60ed7e1e7951372c620435f3d050afdabb14afba Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Mon, 14 Jun 2021 21:49:20 -0400 Subject: [PATCH] Complete public search (#5) - Bump version - Define nav between profile and continent/skills - Remove redundant code --- src/JobsJobsJobs/Client/AppState.cs | 2 +- .../Client/Pages/Citizens/Dashboard.razor | 7 ++- .../Client/Pages/HowItWorks.razor | 44 ++++++----------- .../Client/Pages/Profiles/Seeking.razor | 18 ++++--- .../Client/Pages/Profiles/Seeking.razor.cs | 8 ++-- .../Client/Pages/Profiles/View.razor | 2 +- src/JobsJobsJobs/Client/ServerApi.cs | 1 - src/JobsJobsJobs/Directory.Build.props | 4 +- .../Api/Controllers/ProfileController.cs | 4 -- src/JobsJobsJobs/Server/Data/JobsDbContext.cs | 8 +++- .../Server/Data/ProfileExtensions.cs | 48 ++++++------------- .../Server/JobsJobsJobs.Server.csproj.user | 2 +- .../Shared/Api/PublicSearchResult.cs | 13 +++++ src/JobsJobsJobs/Shared/Domain/Profile.cs | 4 +- 14 files changed, 74 insertions(+), 91 deletions(-) create mode 100644 src/JobsJobsJobs/Shared/Api/PublicSearchResult.cs diff --git a/src/JobsJobsJobs/Client/AppState.cs b/src/JobsJobsJobs/Client/AppState.cs index 7a06ab8..8697e59 100644 --- a/src/JobsJobsJobs/Client/AppState.cs +++ b/src/JobsJobsJobs/Client/AppState.cs @@ -22,7 +22,7 @@ namespace JobsJobsJobs.Client /// /// The application version, as a nice display string /// - public static Lazy Version => new Lazy(() => + public static Lazy Version => new(() => { var version = Assembly.GetExecutingAssembly().GetName().Version!; var display = $"v{version.Major}.{version.Minor}"; diff --git a/src/JobsJobsJobs/Client/Pages/Citizens/Dashboard.razor b/src/JobsJobsJobs/Client/Pages/Citizens/Dashboard.razor index 687a58e..059111f 100644 --- a/src/JobsJobsJobs/Client/Pages/Citizens/Dashboard.razor +++ b/src/JobsJobsJobs/Client/Pages/Citizens/Dashboard.razor @@ -11,7 +11,7 @@ {

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

View Your Employment Profile

@if (Profile.SeekingEmployment) @@ -41,7 +41,6 @@

- To see what is currently done, and how this application works, check out “How It Works” in the sidebar. - The application now has 4 of 5 phases complete towards version 1.0; the documentation was last updated January - 31st, 2021. + To see how this application works, check out “How It Works” in the sidebar (last updated June + 14th, 2021).

diff --git a/src/JobsJobsJobs/Client/Pages/HowItWorks.razor b/src/JobsJobsJobs/Client/Pages/HowItWorks.razor index 52f6be0..8070481 100644 --- a/src/JobsJobsJobs/Client/Pages/HowItWorks.razor +++ b/src/JobsJobsJobs/Client/Pages/HowItWorks.razor @@ -4,18 +4,6 @@

How It Works

-

- Phase 4 is complete, which means that the entire logged-in version of the application is now available. There are - GitHub issues for each one - (Phase 1 • - Phase 2 • - Phase 3 • - Phase 4), and if you run into any - issues with it, feel free to - let us know on GitHub, or look up - @("@")danieljsummers on No Agenda Social. -

-

Completing Your Profile

  • @@ -44,11 +32,10 @@ would like it presented to fellow citizens.
  • - Phase 5 includes allowing - public access to the continent, region, and skills fields of Gitmo Nation citizens who indicate that they are both - seeking employment and want their information disclosed to public users. The “Allow my - profile to be searched publicly” checkbox, at the bottom of the page where you edit your employment profile, - is how you opt your profile in to this list. + If you check the “Allow my profile to be searched publicly” checkbox, and you are + seeking employment, your continent, region, and skills fields will be searchable and displayed to public users of + the site. They will not be tied to your No Agenda Social handle or real name; they are there to let people peek + behind the curtain a bit, and hopefully inspire them to join us.
@@ -77,19 +64,18 @@ to read it; if you submitted the story, there will also be an “Edit” link.

-

- Publicly Available Information - (coming in Phase 5) -

+

Publicly Available Information

- The “public” page for profile information will display the following information: + The “Job Seekers” page for profile information will allow users to search for and display the continent, + region, skills, and notes of users who are seeking employment and have opted in to their information + being publicly searchable. If you are a public user, this information is always the latest we have; check out the link + at the top of the search results for how you can learn more about these fine human resources!

-
    -
  • A count of profiles where the citizen is seeking employment
  • -
  • The citizen’s continent and region
  • -
  • The citizen’s skills and notes
  • -
+ +

Help / Suggestions

- This information will be pullled only from profiles where citizens have said can it be publicly available - and are currently seeking employment. + This is open-source software + developed on Github; feel free to + create an issue there, or look up + @("@")danieljsummers on No Agenda Social.

diff --git a/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor b/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor index 06166b1..9fda253 100644 --- a/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor +++ b/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor @@ -23,10 +23,13 @@
@if (SearchResults.Any()) { +

+ These profiles match your search criteria. To learn more about these people, join the merry band of human + resources in the No Agenda tribe! +

- @@ -37,12 +40,15 @@ @foreach (var profile in SearchResults) { - - - + + - - + } diff --git a/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor.cs b/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor.cs index bea3afb..8c3bdea 100644 --- a/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor.cs +++ b/src/JobsJobsJobs/Client/Pages/Profiles/Seeking.razor.cs @@ -39,7 +39,7 @@ namespace JobsJobsJobs.Client.Pages.Profiles /// /// The search results /// - private IEnumerable SearchResults { get; set; } = Enumerable.Empty(); + private IEnumerable SearchResults { get; set; } = Enumerable.Empty(); protected override async Task OnInitializedAsync() { @@ -72,7 +72,7 @@ namespace JobsJobsJobs.Client.Pages.Profiles { var query = SearchQuery(); query.Add("Searched", "True"); - nav.NavigateTo(QueryHelpers.AddQueryString("/profile/search", query)); + nav.NavigateTo(QueryHelpers.AddQueryString("/profile/seeking", query)); await RetrieveProfiles(); } @@ -83,8 +83,8 @@ namespace JobsJobsJobs.Client.Pages.Profiles { Searching = true; - var searchResult = await ServerApi.RetrieveMany(http, - QueryHelpers.AddQueryString("profile/search", SearchQuery())); + var searchResult = await ServerApi.RetrieveMany(http, + QueryHelpers.AddQueryString("profile/public-search", SearchQuery())); if (searchResult.IsOk) { diff --git a/src/JobsJobsJobs/Client/Pages/Profiles/View.razor b/src/JobsJobsJobs/Client/Pages/Profiles/View.razor index 5157a01..d6f3acc 100644 --- a/src/JobsJobsJobs/Client/Pages/Profiles/View.razor +++ b/src/JobsJobsJobs/Client/Pages/Profiles/View.razor @@ -15,7 +15,7 @@ - @if (Profile.Skills.Length > 0) + @if (Profile.Skills.Count > 0) {

Skills

diff --git a/src/JobsJobsJobs/Client/ServerApi.cs b/src/JobsJobsJobs/Client/ServerApi.cs index f02a944..20dcb98 100644 --- a/src/JobsJobsJobs/Client/ServerApi.cs +++ b/src/JobsJobsJobs/Client/ServerApi.cs @@ -2,7 +2,6 @@ using JobsJobsJobs.Shared.Api; using NodaTime; using NodaTime.Serialization.SystemTextJson; -using System; using System.Collections.Generic; using System.Linq; using System.Net; diff --git a/src/JobsJobsJobs/Directory.Build.props b/src/JobsJobsJobs/Directory.Build.props index ea729a1..d7dd852 100644 --- a/src/JobsJobsJobs/Directory.Build.props +++ b/src/JobsJobsJobs/Directory.Build.props @@ -2,7 +2,7 @@ net5.0 enable - 0.9.1.0 - 0.9.1.0 + 1.0.0.0 + 1.0.0.0 diff --git a/src/JobsJobsJobs/Server/Areas/Api/Controllers/ProfileController.cs b/src/JobsJobsJobs/Server/Areas/Api/Controllers/ProfileController.cs index da4e376..3a3352b 100644 --- a/src/JobsJobsJobs/Server/Areas/Api/Controllers/ProfileController.cs +++ b/src/JobsJobsJobs/Server/Areas/Api/Controllers/ProfileController.cs @@ -97,10 +97,6 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers return Ok(); } - [HttpGet("skills")] - public async Task GetSkills() => - Ok(await _db.FindSkillsByCitizen(CurrentCitizenId)); - [HttpGet("count")] public async Task GetProfileCount() => Ok(new Count(await _db.CountProfiles())); diff --git a/src/JobsJobsJobs/Server/Data/JobsDbContext.cs b/src/JobsJobsJobs/Server/Data/JobsDbContext.cs index ee95e39..84b701c 100644 --- a/src/JobsJobsJobs/Server/Data/JobsDbContext.cs +++ b/src/JobsJobsJobs/Server/Data/JobsDbContext.cs @@ -83,8 +83,12 @@ namespace JobsJobsJobs.Server.Data m.Property(e => e.LastUpdatedOn).HasColumnName("last_updated_on").IsRequired(); m.Property(e => e.Experience).HasColumnName("experience") .HasConversion(Converters.OptionalMarkdownStringConverter); - m.Ignore(e => e.Continent); - m.Ignore(e => e.Skills); + m.HasOne(e => e.Continent) + .WithMany() + .HasForeignKey(e => e.ContinentId); + m.HasMany(e => e.Skills) + .WithOne() + .HasForeignKey(e => e.CitizenId); }); modelBuilder.Entity(m => diff --git a/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs b/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs index 7b1d0e7..cac0194 100644 --- a/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs +++ b/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs @@ -18,24 +18,13 @@ namespace JobsJobsJobs.Server.Data /// /// The ID of the citizen whose profile should be retrieved /// The profile, or null if it does not exist - public static async Task FindProfileByCitizen(this JobsDbContext db, CitizenId citizenId) - { - var profile = await db.Profiles.AsNoTracking() + public static async Task FindProfileByCitizen(this JobsDbContext db, CitizenId citizenId) => + await db.Profiles.AsNoTracking() + .Include(p => p.Continent) + .Include(p => p.Skills) .SingleOrDefaultAsync(p => p.Id == citizenId) .ConfigureAwait(false); - if (profile != null) - { - return profile with - { - Continent = await db.FindContinentById(profile.ContinentId).ConfigureAwait(false), - Skills = (await db.FindSkillsByCitizen(citizenId).ConfigureAwait(false)).ToArray() - }; - } - - return null; - } - /// /// Save a profile /// @@ -52,16 +41,6 @@ namespace JobsJobsJobs.Server.Data } } - /// - /// Retrieve all skills for the given citizen - /// - /// The ID of the citizen whose skills should be retrieved - /// The skills defined for this citizen - public static async Task> FindSkillsByCitizen(this JobsDbContext db, CitizenId citizenId) => - await db.Skills.AsNoTracking() - .Where(s => s.CitizenId == citizenId) - .ToListAsync().ConfigureAwait(false); - /// /// Save a skill /// @@ -166,29 +145,30 @@ namespace JobsJobsJobs.Server.Data /// /// The search parameters /// The information for profiles matching the criteria - public static async Task> SearchPublicProfiles(this JobsDbContext db, + public static async Task> SearchPublicProfiles(this JobsDbContext db, PublicSearch search) { var query = db.Profiles - .Join(db.Citizens, p => p.Id, c => c.Id, (p, c) => new { Profile = p, Citizen = c }) - .Where(it => it.Profile.IsPublic); + .Include(it => it.Continent) + .Include(it => it.Skills) + .Where(it => it.IsPublic); var useIds = false; var citizenIds = new List(); if (!string.IsNullOrEmpty(search.ContinentId)) { - query = query.Where(it => it.Profile.ContinentId == ContinentId.Parse(search.ContinentId)); + query = query.Where(it => it.ContinentId == ContinentId.Parse(search.ContinentId)); } if (!string.IsNullOrEmpty(search.Region)) { - query = query.Where(it => it.Profile.Region.ToLower().Contains(search.Region.ToLower())); + query = query.Where(it => it.Region.ToLower().Contains(search.Region.ToLower())); } if (!string.IsNullOrEmpty(search.RemoteWork)) { - query = query.Where(it => it.Profile.RemoteWork == (search.RemoteWork == "yes")); + query = query.Where(it => it.RemoteWork == (search.RemoteWork == "yes")); } if (!string.IsNullOrEmpty(search.Skill)) @@ -202,11 +182,11 @@ namespace JobsJobsJobs.Server.Data if (useIds) { - query = query.Where(it => citizenIds.Contains(it.Citizen.Id)); + query = query.Where(it => citizenIds.Contains(it.Id)); } - return await query.Select(x => new ProfileSearchResult(x.Citizen.Id, x.Citizen.CitizenName, - x.Profile.SeekingEmployment, x.Profile.RemoteWork, x.Profile.FullTime, x.Profile.LastUpdatedOn)) + return await query.Select(x => new PublicSearchResult(x.Continent!.Name, x.Region, x.RemoteWork, + x.Skills.Select(sk => $"{sk.Description} ({sk.Notes})"))) .ToListAsync().ConfigureAwait(false); } diff --git a/src/JobsJobsJobs/Server/JobsJobsJobs.Server.csproj.user b/src/JobsJobsJobs/Server/JobsJobsJobs.Server.csproj.user index 476125d..4aff699 100644 --- a/src/JobsJobsJobs/Server/JobsJobsJobs.Server.csproj.user +++ b/src/JobsJobsJobs/Server/JobsJobsJobs.Server.csproj.user @@ -6,7 +6,7 @@ JobsJobsJobs.Server MvcControllerEmptyScaffolder root/Common/MVC/Controller - C:\Users\danie\Documents\sandbox\jobs-jobs-jobs\src\JobsJobsJobs\Server\Properties\PublishProfiles\FolderProfile.pubxml + FolderProfile ProjectDebugger diff --git a/src/JobsJobsJobs/Shared/Api/PublicSearchResult.cs b/src/JobsJobsJobs/Shared/Api/PublicSearchResult.cs new file mode 100644 index 0000000..ffdcbfa --- /dev/null +++ b/src/JobsJobsJobs/Shared/Api/PublicSearchResult.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace JobsJobsJobs.Shared.Api +{ + /// + /// A public profile search result + /// + public record PublicSearchResult( + string Continent, + string Region, + bool RemoteWork, + IEnumerable Skills); +} diff --git a/src/JobsJobsJobs/Shared/Domain/Profile.cs b/src/JobsJobsJobs/Shared/Domain/Profile.cs index 5ffc0d2..7f03987 100644 --- a/src/JobsJobsJobs/Shared/Domain/Profile.cs +++ b/src/JobsJobsJobs/Shared/Domain/Profile.cs @@ -1,5 +1,5 @@ using NodaTime; -using System; +using System.Collections.Generic; namespace JobsJobsJobs.Shared { @@ -26,6 +26,6 @@ namespace JobsJobsJobs.Shared /// /// Convenience property for skills associated with a profile /// - public Skill[] Skills { get; set; } = Array.Empty(); + public ICollection Skills { get; set; } = new List(); } }
Profile Continent Region Remote?
View@profile.DisplayName@YesOrNo(profile.SeekingEmployment)@profile.Continent@profile.Region @YesOrNo(profile.RemoteWork)@YesOrNo(profile.FullTime) + @foreach (var skill in profile.Skills) + { + @skill.Replace(" ()", "")
+ } +