From e5cacf7a5a6087079ec2ce73e54e762eeed1de93 Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Thu, 10 Apr 2025 12:16:30 -0700 Subject: [PATCH 1/2] Set Org Tag in User search results --- src/Share/Postgres/Users/Queries.hs | 9 ++++++--- src/Share/Web/Share/Impl.hs | 8 +++++--- src/Share/Web/Share/Types.hs | 12 +++++++++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Share/Postgres/Users/Queries.hs b/src/Share/Postgres/Users/Queries.hs index 9758cf8b..4b50bc0a 100644 --- a/src/Share/Postgres/Users/Queries.hs +++ b/src/Share/Postgres/Users/Queries.hs @@ -1,5 +1,6 @@ {-# LANGUAGE DisambiguateRecordFields #-} {-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE TypeOperators #-} -- | Common queries for users. module Share.Postgres.Users.Queries @@ -266,18 +267,20 @@ findOrCreateGithubUser authZReceipt ghu@(GithubUser _login githubUserId _avatarU Nothing -> do New <$> createFromGithubUser authZReceipt ghu primaryEmail -searchUsersByNameOrHandlePrefix :: Query -> Limit -> PG.Transaction e [User] +searchUsersByNameOrHandlePrefix :: Query -> Limit -> PG.Transaction e [(User, Maybe OrgId)] searchUsersByNameOrHandlePrefix (Query prefix) (Limit limit) = do let q = likeEscape prefix <> "%" - PG.queryListRows + PG.queryListRows @(User PG.:. (PG.Only (Maybe OrgId))) [PG.sql| - SELECT u.id, u.name, u.primary_email, u.avatar_url, u.handle, u.private + SELECT u.id, u.name, u.primary_email, u.avatar_url, u.handle, u.private, org.id FROM users u + LEFT JOIN orgs org ON org.user_id = u.id WHERE (u.handle ILIKE #{q} OR u.name ILIKE #{q} ) AND NOT u.private LIMIT #{limit} |] + <&> fmap \(user PG.:. PG.Only mayOrgId) -> (user, mayOrgId) data UserCreationError = UserHandleTaken UserHandle diff --git a/src/Share/Web/Share/Impl.hs b/src/Share/Web/Share/Impl.hs index 636449ae..4a62574a 100644 --- a/src/Share/Web/Share/Impl.hs +++ b/src/Share/Web/Share/Impl.hs @@ -47,7 +47,7 @@ import Share.Web.Share.Branches.Impl qualified as Branches import Share.Web.Share.CodeBrowsing.API (CodeBrowseAPI) import Share.Web.Share.Contributions.Impl qualified as Contributions import Share.Web.Share.DefinitionSearch qualified as DefinitionSearch -import Share.Web.Share.DisplayInfo (UserDisplayInfo (..)) +import Share.Web.Share.DisplayInfo (OrgDisplayInfo (..), UserDisplayInfo (..)) import Share.Web.Share.Orgs.Queries qualified as OrgQ import Share.Web.Share.Orgs.Types (Org (..)) import Share.Web.Share.Projects.Impl qualified as Projects @@ -368,8 +368,10 @@ searchEndpoint (MaybeAuthedUserID callerUserId) (Query query) (fromMaybe (Limit pure (users, projects) let userResults = users - <&> \User {user_name = name, avatar_url = avatarUrl, handle, user_id = userId} -> - SearchResultUser (UserDisplayInfo {handle, name, avatarUrl = unpackURI <$> avatarUrl, userId}) + <&> \(User {user_name = name, avatar_url = avatarUrl, handle, user_id = userId}, mayOrgId) -> + case mayOrgId of + Just orgId -> SearchResultOrg (OrgDisplayInfo {user = UserDisplayInfo {handle, name, avatarUrl = unpackURI <$> avatarUrl, userId}, orgId}) + Nothing -> SearchResultUser (UserDisplayInfo {handle, name, avatarUrl = unpackURI <$> avatarUrl, userId}) let projectResults = projects <&> \(Project {slug, summary, visibility}, ownerHandle) -> diff --git a/src/Share/Web/Share/Types.hs b/src/Share/Web/Share/Types.hs index 4d6299ee..26aefd76 100644 --- a/src/Share/Web/Share/Types.hs +++ b/src/Share/Web/Share/Types.hs @@ -14,7 +14,7 @@ import Share.Project (ProjectVisibility) import Share.Utils.API (NullableUpdate, parseNullableUpdate) import Share.Utils.URI import Share.Web.Authorization.Types (RolePermission) -import Share.Web.Share.DisplayInfo (UserDisplayInfo (..)) +import Share.Web.Share.DisplayInfo (OrgDisplayInfo (..), UserDisplayInfo (..)) import Unison.Name (Name) import Unison.Server.Doc (Doc) import Unison.Server.Share.DefinitionSummary.Types (TermSummary (..), TypeSummary (..)) @@ -105,6 +105,7 @@ data SearchResult = SearchResultUser UserDisplayInfo | -- | shorthand summary visibility SearchResultProject ProjectShortHand (Maybe Text) ProjectVisibility + | SearchResultOrg OrgDisplayInfo deriving (Show) instance ToJSON SearchResult where @@ -117,6 +118,15 @@ instance ToJSON SearchResult where "userId" .= userId, "tag" .= ("User" :: Text) ] + SearchResultOrg (OrgDisplayInfo {user = UserDisplayInfo {handle, name, avatarUrl, userId}, orgId}) -> + Aeson.object + [ "handle" .= fromId @UserHandle @Text handle, + "name" .= name, + "avatarUrl" .= avatarUrl, + "userId" .= userId, + "orgId" .= orgId, + "tag" .= ("Org" :: Text) + ] SearchResultProject shorthand summary visibility -> Aeson.object [ "projectRef" .= shorthand, From d42129fc64b048fa1afeece7851a19ba2304911a Mon Sep 17 00:00:00 2001 From: Chris Penner Date: Thu, 10 Apr 2025 12:25:01 -0700 Subject: [PATCH 2/2] Add transcripts for user search --- .../share-apis/search/omni-search-orgs.json | 23 +++++++++++++++++++ .../share-apis/search/omni-search-users.json | 22 ++++++++++++++++++ transcripts/share-apis/search/run.zsh | 6 +++++ 3 files changed, 51 insertions(+) create mode 100644 transcripts/share-apis/search/omni-search-orgs.json create mode 100644 transcripts/share-apis/search/omni-search-users.json diff --git a/transcripts/share-apis/search/omni-search-orgs.json b/transcripts/share-apis/search/omni-search-orgs.json new file mode 100644 index 00000000..5eb800f1 --- /dev/null +++ b/transcripts/share-apis/search/omni-search-orgs.json @@ -0,0 +1,23 @@ +{ + "body": [ + { + "avatarUrl": "https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?f=y&d=retro", + "handle": "unison", + "name": "Unison Org", + "orgId": "ORG-", + "tag": "Org", + "userId": "U-" + }, + { + "projectRef": "@unison/privateorgproject", + "summary": "Private Unison Project", + "tag": "Project", + "visibility": "private" + } + ], + "status": [ + { + "status_code": 200 + } + ] +} diff --git a/transcripts/share-apis/search/omni-search-users.json b/transcripts/share-apis/search/omni-search-users.json new file mode 100644 index 00000000..9ff75130 --- /dev/null +++ b/transcripts/share-apis/search/omni-search-users.json @@ -0,0 +1,22 @@ +{ + "body": [ + { + "avatarUrl": null, + "handle": "test", + "name": null, + "tag": "User", + "userId": "U-" + }, + { + "projectRef": "@test/publictestproject", + "summary": "test project summary", + "tag": "Project", + "visibility": "public" + } + ], + "status": [ + { + "status_code": 200 + } + ] +} diff --git a/transcripts/share-apis/search/run.zsh b/transcripts/share-apis/search/run.zsh index 0e267b44..7992e74c 100755 --- a/transcripts/share-apis/search/run.zsh +++ b/transcripts/share-apis/search/run.zsh @@ -87,3 +87,9 @@ fetch "$transcript_user" GET 'defn-search-project-filter-sad' '/search-definitio # Release filter fetch "$transcript_user" GET 'defn-search-release-filter-happy' '/search-definitions?query=map&project-filter=@transcripts%2Fsearch&release-filter=1.2.3' fetch "$transcript_user" GET 'defn-search-release-filter-sad' '/search-definitions?query=map&project-filter=@test%2Fpublictestproject&release-filter=1.0.0' + +# Omni search should find org users +fetch "$transcript_user" GET 'omni-search-orgs' '/search?query=%40uni' + +# Omni search should find regular users +fetch "$transcript_user" GET 'omni-search-users' '/search?query=%40tes'