Merge branch 'main' into andrew/placeholder-updates-to-workspace-settings

This commit is contained in:
andrewwallacespeckle
2025-05-23 09:55:05 +02:00
7 changed files with 93 additions and 26 deletions
@@ -1,6 +1,6 @@
<template>
<CommonCard
class="w-full border-outline-2 !p-4"
class="w-full border-outline-2 !py-3 px-4"
:class="{
'cursor-pointer hover:border-outline-3 shadow-sm hover:border-zinc-400 bg-foundation':
clickable
@@ -8,11 +8,13 @@
@click="clickable && onClick"
>
<div class="flex flex-col sm:flex-row justify-between gap-4">
<div class="flex gap-4">
<WorkspaceAvatar :name="name" :logo="logo" size="xl" />
<div class="flex gap-3">
<WorkspaceAvatar :name="name" :logo="logo" size="lg" />
<div class="flex flex-col sm:flex-row gap-4 justify-between flex-1">
<div class="flex flex-col items-start text-body-2xs text-foreground-2">
<h6 class="text-heading-sm text-foreground">{{ name }}</h6>
<h6 class="text-foreground text-body-sm font-medium">
{{ name }}
</h6>
<slot name="text"></slot>
</div>
</div>
@@ -25,12 +25,21 @@
{{ description }}
</p>
<WorkspaceDiscoverableWorkspacesCard
v-for="workspace in discoverableWorkspacesAndJoinRequests"
v-for="workspace in workspacesToShow"
:key="`discoverable-${workspace.id}`"
:workspace="workspace"
:request-status="workspace.requestStatus"
location="workspace_join_page"
/>
<FormButton
v-if="!showAllWorkspaces && discoverableWorkspacesAndJoinRequestsCount > 3"
color="subtle"
size="lg"
full-width
@click="showAllWorkspaces = true"
>
Show all ({{ discoverableWorkspacesAndJoinRequestsCount }})
</FormButton>
<div class="mt-2 w-full flex flex-col gap-2">
<FormButton
v-if="hasDiscoverableJoinRequests && !isWorkspaceNewPlansEnabled"
@@ -77,6 +86,14 @@ const {
hasDiscoverableJoinRequests
} = useDiscoverableWorkspaces()
const showAllWorkspaces = ref(false)
const workspacesToShow = computed(() => {
return showAllWorkspaces.value
? discoverableWorkspacesAndJoinRequests.value
: discoverableWorkspacesAndJoinRequests.value.slice(0, 3)
})
const description = computed(() => {
if (discoverableWorkspacesAndJoinRequestsCount.value === 1) {
return 'We found a workspace that matches your email domain'
@@ -1,11 +1,30 @@
<template>
<WorkspaceCard :logo="workspace.logo ?? ''" :name="workspace.name">
<WorkspaceCard
:logo="workspace.logo ?? ''"
:name="workspace.name"
:class="requestStatus === 'pending' ? '' : 'bg-foundation'"
>
<template #text>
<div class="flex flex-col gap-y-1">
<div class="text-body-2xs line-clamp-3">
<div v-if="workspace.description" class="text-body-2xs line-clamp-3">
{{ workspace.description }}
</div>
<UserAvatarGroup :users="users" :max-count="5" size="sm" />
<div class="flex flex-col gap-2">
<UserAvatarGroup
v-if="members.length > 0 && requestStatus !== 'pending'"
:users="members"
:max-count="5"
size="base"
/>
<div class="flex gap-1 text-body-3xs text-foreground-2">
<span class="font-medium">Admins:</span>
<span v-for="(admin, index) in adminTeam.slice(0, 3)" :key="admin.id">
{{ admin.name
}}{{ index < 2 && index < adminTeam.length - 1 ? ', ' : '' }}
</span>
<span v-if="adminTeam.length > 3">+{{ adminTeam.length - 3 }}</span>
</div>
</div>
</div>
</template>
<template #actions>
@@ -45,7 +64,13 @@ const { requestToJoinWorkspace, dismissDiscoverableWorkspace } =
useDiscoverableWorkspaces()
const mixpanel = useMixpanel()
const users = computed(() => props.workspace.team?.items?.map((u) => u.user) ?? [])
const adminTeam = computed(() => props.workspace.adminTeam?.map((t) => t.user) ?? [])
const adminIds = computed(() => new Set(adminTeam.value.map((admin) => admin.id)))
const members = computed(() =>
(props.workspace.team?.items?.map((u) => u.user) ?? []).filter(
(user) => !adminIds.value.has(user.id)
)
)
const onRequest = () => {
requestToJoinWorkspace(props.workspace.id, props.location || 'discovery_card')
@@ -30,11 +30,20 @@
</div>
</div>
<div v-if="verifiedDomain" class="flex flex-col gap-2 w-full">
<FormCheckbox
v-model="enableDomainDiscoverabilityModel"
name="enableDomainDiscoverability"
:label="`Allow users with the @${verifiedDomain} domain to request to join workspace`"
/>
<CommonCard class="flex flex-col gap-1 !p-3">
<FormCheckbox
v-model="enableDomainDiscoverabilityModel"
name="enableDomainDiscoverability"
:label="`Make workspace discoverable to @${verifiedDomain} users`"
/>
<div class="ml-6 text-body-2xs text-foreground-2 select-none">
<p>
Users signing up with a
<span class="font-medium">@{{ verifiedDomain }}</span>
email will be able to find and request to join this workspace.
</p>
</div>
</CommonCard>
</div>
<div class="flex flex-col gap-3 mt-4 w-full md:max-w-96">
<FormButton size="lg" submit full-width>{{ nextButtonText }}</FormButton>
@@ -361,8 +361,8 @@ type Documents = {
"\n subscription OnViewerCommentsUpdated($target: ViewerUpdateTrackingTarget!) {\n projectCommentsUpdated(target: $target) {\n id\n type\n comment {\n id\n parent {\n id\n }\n ...ViewerCommentThread\n }\n }\n }\n": typeof types.OnViewerCommentsUpdatedDocument,
"\n fragment LinkableComment on Comment {\n id\n viewerResources {\n modelId\n versionId\n objectId\n }\n }\n": typeof types.LinkableCommentFragmentDoc,
"\n fragment ActiveWorkspace_Workspace on Workspace {\n id\n name\n logo\n role\n slug\n }\n": typeof types.ActiveWorkspace_WorkspaceFragmentDoc,
"\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n": typeof types.DiscoverableWorkspace_LimitedWorkspaceFragmentDoc,
"\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n": typeof types.WorkspaceJoinRequests_LimitedWorkspaceJoinRequestFragmentDoc,
"\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n }\n": typeof types.DiscoverableWorkspace_LimitedWorkspaceFragmentDoc,
"\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n": typeof types.WorkspaceJoinRequests_LimitedWorkspaceJoinRequestFragmentDoc,
"\n fragment WorkspacePlanLimits_Workspace on Workspace {\n id\n slug\n plan {\n name\n }\n }\n": typeof types.WorkspacePlanLimits_WorkspaceFragmentDoc,
"\n fragment UseWorkspaceInviteManager_PendingWorkspaceCollaborator on PendingWorkspaceCollaborator {\n id\n token\n workspaceId\n workspaceSlug\n user {\n id\n }\n }\n": typeof types.UseWorkspaceInviteManager_PendingWorkspaceCollaboratorFragmentDoc,
"\n fragment WorkspacesPlan_Workspace on Workspace {\n id\n slug\n plan {\n status\n createdAt\n name\n paymentMethod\n usage {\n projectCount\n modelCount\n }\n }\n seats {\n editors {\n assigned\n available\n }\n viewers {\n assigned\n available\n }\n }\n subscription {\n billingInterval\n currentBillingCycleEnd\n currency\n }\n }\n": typeof types.WorkspacesPlan_WorkspaceFragmentDoc,
@@ -781,8 +781,8 @@ const documents: Documents = {
"\n subscription OnViewerCommentsUpdated($target: ViewerUpdateTrackingTarget!) {\n projectCommentsUpdated(target: $target) {\n id\n type\n comment {\n id\n parent {\n id\n }\n ...ViewerCommentThread\n }\n }\n }\n": types.OnViewerCommentsUpdatedDocument,
"\n fragment LinkableComment on Comment {\n id\n viewerResources {\n modelId\n versionId\n objectId\n }\n }\n": types.LinkableCommentFragmentDoc,
"\n fragment ActiveWorkspace_Workspace on Workspace {\n id\n name\n logo\n role\n slug\n }\n": types.ActiveWorkspace_WorkspaceFragmentDoc,
"\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n": types.DiscoverableWorkspace_LimitedWorkspaceFragmentDoc,
"\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n": types.WorkspaceJoinRequests_LimitedWorkspaceJoinRequestFragmentDoc,
"\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n }\n": types.DiscoverableWorkspace_LimitedWorkspaceFragmentDoc,
"\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n": types.WorkspaceJoinRequests_LimitedWorkspaceJoinRequestFragmentDoc,
"\n fragment WorkspacePlanLimits_Workspace on Workspace {\n id\n slug\n plan {\n name\n }\n }\n": types.WorkspacePlanLimits_WorkspaceFragmentDoc,
"\n fragment UseWorkspaceInviteManager_PendingWorkspaceCollaborator on PendingWorkspaceCollaborator {\n id\n token\n workspaceId\n workspaceSlug\n user {\n id\n }\n }\n": types.UseWorkspaceInviteManager_PendingWorkspaceCollaboratorFragmentDoc,
"\n fragment WorkspacesPlan_Workspace on Workspace {\n id\n slug\n plan {\n status\n createdAt\n name\n paymentMethod\n usage {\n projectCount\n modelCount\n }\n }\n seats {\n editors {\n assigned\n available\n }\n viewers {\n assigned\n available\n }\n }\n subscription {\n billingInterval\n currentBillingCycleEnd\n currency\n }\n }\n": types.WorkspacesPlan_WorkspaceFragmentDoc,
@@ -2259,11 +2259,11 @@ export function graphql(source: "\n fragment ActiveWorkspace_Workspace on Works
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n"): (typeof documents)["\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n"];
export function graphql(source: "\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n }\n"): (typeof documents)["\n fragment DiscoverableWorkspace_LimitedWorkspace on LimitedWorkspace {\n id\n name\n logo\n description\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n"): (typeof documents)["\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n"];
export function graphql(source: "\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n"): (typeof documents)["\n fragment WorkspaceJoinRequests_LimitedWorkspaceJoinRequest on LimitedWorkspaceJoinRequest {\n id\n status\n workspace {\n id\n name\n logo\n slug\n adminTeam {\n user {\n id\n name\n avatar\n }\n }\n team {\n totalCount\n items {\n user {\n id\n name\n avatar\n }\n }\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
File diff suppressed because one or more lines are too long
@@ -30,6 +30,13 @@ graphql(`
}
}
}
adminTeam {
user {
id
name
avatar
}
}
}
`)
@@ -42,6 +49,13 @@ graphql(`
name
logo
slug
adminTeam {
user {
id
name
avatar
}
}
team {
totalCount
items {