Add workspaceLastAdminCheckQuery
This commit is contained in:
+2
-9
@@ -28,13 +28,13 @@ import type {
|
||||
} from '~/lib/common/generated/gql/graphql'
|
||||
import { useActiveUser } from '~/lib/auth/composables/activeUser'
|
||||
import type { MaybeNullOrUndefined } from '@speckle/shared'
|
||||
import { Roles } from '@speckle/shared'
|
||||
|
||||
const props = defineProps<{
|
||||
workspace: MaybeNullOrUndefined<
|
||||
| SettingsWorkspacesNewMembersTable_WorkspaceFragment
|
||||
| SettingsWorkspacesMembersNewGuestsTable_WorkspaceFragment
|
||||
>
|
||||
isOnlyAdmin: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -46,13 +46,6 @@ const open = defineModel<boolean>('open', { required: true })
|
||||
const { activeUser } = useActiveUser()
|
||||
const updateUserRole = useWorkspaceUpdateRole()
|
||||
|
||||
const isOnlyAdmin = computed(() => {
|
||||
const adminUsers = props.workspace?.team.items.filter(
|
||||
(user) => user.role === Roles.Workspace.Admin
|
||||
)
|
||||
return adminUsers?.length === 1
|
||||
})
|
||||
|
||||
const handleConfirm = async () => {
|
||||
if (!props.workspace?.id || !activeUser.value?.id) return
|
||||
|
||||
@@ -75,7 +68,7 @@ const dialogButtons = computed((): LayoutDialogButton[] => [
|
||||
{
|
||||
text: 'Leave',
|
||||
onClick: handleConfirm,
|
||||
disabled: isOnlyAdmin.value
|
||||
disabled: props.isOnlyAdmin
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
:workspace="workspace"
|
||||
:new-role="newRole"
|
||||
:is-active-user-target-user="isActiveUserTargetUser"
|
||||
:is-only-admin="isOnlyAdmin"
|
||||
:is-only-admin="hasSingleAdmin"
|
||||
:is-domain-compliant="targetUser.workspaceDomainPolicyCompliant"
|
||||
@success="onDialogSuccess"
|
||||
/>
|
||||
@@ -35,7 +35,7 @@
|
||||
:user="targetUser"
|
||||
:workspace="workspace"
|
||||
:is-active-user-target-user="isActiveUserTargetUser"
|
||||
:is-only-admin="isOnlyAdmin"
|
||||
:is-only-admin="hasSingleAdmin"
|
||||
:action="adminAction"
|
||||
@success="onDialogSuccess"
|
||||
/>
|
||||
@@ -60,6 +60,7 @@
|
||||
v-if="dialogToShow.leaveWorkspace"
|
||||
v-model:open="showDialog"
|
||||
:workspace="workspace"
|
||||
:is-only-admin="hasSingleAdmin"
|
||||
@success="onDialogSuccess"
|
||||
/>
|
||||
</div>
|
||||
@@ -78,6 +79,7 @@ import type {
|
||||
SettingsWorkspacesMembersNewGuestsTable_WorkspaceFragment,
|
||||
SettingsWorkspacesNewMembersTable_WorkspaceFragment
|
||||
} from '~/lib/common/generated/gql/graphql'
|
||||
import { useWorkspaceLastAdminCheck } from '~/lib/workspaces/composables/management'
|
||||
|
||||
const props = defineProps<{
|
||||
targetUser: UserItem
|
||||
@@ -93,6 +95,10 @@ const showMenu = ref(false)
|
||||
const showDialog = ref(false)
|
||||
const dialogType = ref<WorkspaceUserActionTypes>()
|
||||
|
||||
const { hasSingleAdmin } = useWorkspaceLastAdminCheck({
|
||||
workspaceSlug: props.workspace?.slug || ''
|
||||
})
|
||||
|
||||
const isActiveUserWorkspaceAdmin = computed(
|
||||
() => props.workspace?.role === Roles.Workspace.Admin
|
||||
)
|
||||
@@ -116,13 +122,6 @@ const {
|
||||
targetUser: props.targetUser
|
||||
})
|
||||
|
||||
const isOnlyAdmin = computed(() => {
|
||||
const adminUsers = props.workspace?.team.items.filter(
|
||||
(user) => user.role === Roles.Workspace.Admin
|
||||
)
|
||||
return adminUsers?.length === 1
|
||||
})
|
||||
|
||||
const filteredActionsItems = computed(() => {
|
||||
const mainItems: LayoutMenuItem[] = []
|
||||
const footerItems: LayoutMenuItem[] = []
|
||||
|
||||
@@ -378,6 +378,7 @@ type Documents = {
|
||||
"\n fragment WorkspaceInvitedTeam_Workspace on Workspace {\n id\n invitedTeam(filter: $invitesFilter) {\n id\n role\n email\n }\n }\n": typeof types.WorkspaceInvitedTeam_WorkspaceFragmentDoc,
|
||||
"\n fragment WorkspaceTeam_Workspace on Workspace {\n id\n slug\n team(limit: 250) {\n totalCount\n items {\n id\n user {\n id\n name\n ...LimitedUserAvatar\n }\n }\n }\n adminWorkspacesJoinRequests {\n totalCount\n items {\n status\n id\n }\n }\n ...WorkspaceInvitedTeam_Workspace\n }\n": typeof types.WorkspaceTeam_WorkspaceFragmentDoc,
|
||||
"\n fragment WorkspaceSecurity_Workspace on Workspace {\n id\n slug\n domains {\n id\n domain\n }\n }\n": typeof types.WorkspaceSecurity_WorkspaceFragmentDoc,
|
||||
"\n fragment WorkspaceLastAdminCheck_Workspace on Workspace {\n id\n team(limit: 50, filter: { roles: [\"workspace:admin\"] }) {\n items {\n id\n }\n }\n }\n": typeof types.WorkspaceLastAdminCheck_WorkspaceFragmentDoc,
|
||||
"\n mutation UpdateRole($input: WorkspaceRoleUpdateInput!) {\n workspaceMutations {\n updateRole(input: $input) {\n team {\n items {\n id\n role\n }\n }\n }\n }\n }\n": typeof types.UpdateRoleDocument,
|
||||
"\n mutation WorkspacesUpdateSeatType($input: WorkspaceUpdateSeatTypeInput!) {\n workspaceMutations {\n updateSeatType(input: $input) {\n team {\n items {\n id\n seatType\n }\n }\n }\n }\n }\n": typeof types.WorkspacesUpdateSeatTypeDocument,
|
||||
"\n mutation InviteToWorkspace(\n $workspaceId: String!\n $input: [WorkspaceInviteCreateInput!]!\n ) {\n workspaceMutations {\n invites {\n batchCreate(workspaceId: $workspaceId, input: $input) {\n id\n invitedTeam {\n ...SettingsWorkspacesMembersInvitesTable_PendingWorkspaceCollaborator\n }\n }\n }\n }\n }\n": typeof types.InviteToWorkspaceDocument,
|
||||
@@ -404,6 +405,7 @@ type Documents = {
|
||||
"\n query DiscoverableWorkspaces {\n activeUser {\n id\n ...DiscoverableList_Discoverable\n }\n }\n": typeof types.DiscoverableWorkspacesDocument,
|
||||
"\n query DiscoverableWorkspacesRequests {\n activeUser {\n id\n ...DiscoverableList_Requests\n }\n }\n": typeof types.DiscoverableWorkspacesRequestsDocument,
|
||||
"\n query WorkspacePlan($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspacesPlan_Workspace\n }\n }\n": typeof types.WorkspacePlanDocument,
|
||||
"\n query WorkspaceLastAdminCheck($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspaceLastAdminCheck_Workspace\n }\n }\n": typeof types.WorkspaceLastAdminCheckDocument,
|
||||
"\n subscription onWorkspaceUpdated(\n $workspaceId: String\n $workspaceSlug: String\n $invitesFilter: PendingWorkspaceCollaboratorsFilter\n ) {\n workspaceUpdated(workspaceId: $workspaceId, workspaceSlug: $workspaceSlug) {\n id\n workspace {\n id\n ...WorkspaceProjectList_Workspace\n }\n }\n }\n": typeof types.OnWorkspaceUpdatedDocument,
|
||||
"\n query LegacyBranchRedirectMetadata($streamId: String!, $branchName: String!) {\n project(id: $streamId) {\n modelByName(name: $branchName) {\n id\n }\n }\n }\n": typeof types.LegacyBranchRedirectMetadataDocument,
|
||||
"\n query LegacyViewerCommitRedirectMetadata($streamId: String!, $commitId: String!) {\n project(id: $streamId) {\n version(id: $commitId) {\n id\n model {\n id\n }\n }\n }\n }\n": typeof types.LegacyViewerCommitRedirectMetadataDocument,
|
||||
@@ -791,6 +793,7 @@ const documents: Documents = {
|
||||
"\n fragment WorkspaceInvitedTeam_Workspace on Workspace {\n id\n invitedTeam(filter: $invitesFilter) {\n id\n role\n email\n }\n }\n": types.WorkspaceInvitedTeam_WorkspaceFragmentDoc,
|
||||
"\n fragment WorkspaceTeam_Workspace on Workspace {\n id\n slug\n team(limit: 250) {\n totalCount\n items {\n id\n user {\n id\n name\n ...LimitedUserAvatar\n }\n }\n }\n adminWorkspacesJoinRequests {\n totalCount\n items {\n status\n id\n }\n }\n ...WorkspaceInvitedTeam_Workspace\n }\n": types.WorkspaceTeam_WorkspaceFragmentDoc,
|
||||
"\n fragment WorkspaceSecurity_Workspace on Workspace {\n id\n slug\n domains {\n id\n domain\n }\n }\n": types.WorkspaceSecurity_WorkspaceFragmentDoc,
|
||||
"\n fragment WorkspaceLastAdminCheck_Workspace on Workspace {\n id\n team(limit: 50, filter: { roles: [\"workspace:admin\"] }) {\n items {\n id\n }\n }\n }\n": types.WorkspaceLastAdminCheck_WorkspaceFragmentDoc,
|
||||
"\n mutation UpdateRole($input: WorkspaceRoleUpdateInput!) {\n workspaceMutations {\n updateRole(input: $input) {\n team {\n items {\n id\n role\n }\n }\n }\n }\n }\n": types.UpdateRoleDocument,
|
||||
"\n mutation WorkspacesUpdateSeatType($input: WorkspaceUpdateSeatTypeInput!) {\n workspaceMutations {\n updateSeatType(input: $input) {\n team {\n items {\n id\n seatType\n }\n }\n }\n }\n }\n": types.WorkspacesUpdateSeatTypeDocument,
|
||||
"\n mutation InviteToWorkspace(\n $workspaceId: String!\n $input: [WorkspaceInviteCreateInput!]!\n ) {\n workspaceMutations {\n invites {\n batchCreate(workspaceId: $workspaceId, input: $input) {\n id\n invitedTeam {\n ...SettingsWorkspacesMembersInvitesTable_PendingWorkspaceCollaborator\n }\n }\n }\n }\n }\n": types.InviteToWorkspaceDocument,
|
||||
@@ -817,6 +820,7 @@ const documents: Documents = {
|
||||
"\n query DiscoverableWorkspaces {\n activeUser {\n id\n ...DiscoverableList_Discoverable\n }\n }\n": types.DiscoverableWorkspacesDocument,
|
||||
"\n query DiscoverableWorkspacesRequests {\n activeUser {\n id\n ...DiscoverableList_Requests\n }\n }\n": types.DiscoverableWorkspacesRequestsDocument,
|
||||
"\n query WorkspacePlan($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspacesPlan_Workspace\n }\n }\n": types.WorkspacePlanDocument,
|
||||
"\n query WorkspaceLastAdminCheck($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspaceLastAdminCheck_Workspace\n }\n }\n": types.WorkspaceLastAdminCheckDocument,
|
||||
"\n subscription onWorkspaceUpdated(\n $workspaceId: String\n $workspaceSlug: String\n $invitesFilter: PendingWorkspaceCollaboratorsFilter\n ) {\n workspaceUpdated(workspaceId: $workspaceId, workspaceSlug: $workspaceSlug) {\n id\n workspace {\n id\n ...WorkspaceProjectList_Workspace\n }\n }\n }\n": types.OnWorkspaceUpdatedDocument,
|
||||
"\n query LegacyBranchRedirectMetadata($streamId: String!, $branchName: String!) {\n project(id: $streamId) {\n modelByName(name: $branchName) {\n id\n }\n }\n }\n": types.LegacyBranchRedirectMetadataDocument,
|
||||
"\n query LegacyViewerCommitRedirectMetadata($streamId: String!, $commitId: String!) {\n project(id: $streamId) {\n version(id: $commitId) {\n id\n model {\n id\n }\n }\n }\n }\n": types.LegacyViewerCommitRedirectMetadataDocument,
|
||||
@@ -2310,6 +2314,10 @@ export function graphql(source: "\n fragment WorkspaceTeam_Workspace on Workspa
|
||||
* 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 WorkspaceSecurity_Workspace on Workspace {\n id\n slug\n domains {\n id\n domain\n }\n }\n"): (typeof documents)["\n fragment WorkspaceSecurity_Workspace on Workspace {\n id\n slug\n domains {\n id\n domain\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 WorkspaceLastAdminCheck_Workspace on Workspace {\n id\n team(limit: 50, filter: { roles: [\"workspace:admin\"] }) {\n items {\n id\n }\n }\n }\n"): (typeof documents)["\n fragment WorkspaceLastAdminCheck_Workspace on Workspace {\n id\n team(limit: 50, filter: { roles: [\"workspace:admin\"] }) {\n items {\n id\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -2414,6 +2422,10 @@ export function graphql(source: "\n query DiscoverableWorkspacesRequests {\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 query WorkspacePlan($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspacesPlan_Workspace\n }\n }\n"): (typeof documents)["\n query WorkspacePlan($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspacesPlan_Workspace\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 query WorkspaceLastAdminCheck($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspaceLastAdminCheck_Workspace\n }\n }\n"): (typeof documents)["\n query WorkspaceLastAdminCheck($slug: String!) {\n workspaceBySlug(slug: $slug) {\n ...WorkspaceLastAdminCheck_Workspace\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
@@ -156,7 +156,10 @@ export const useSettingsMembersActions = (props: {
|
||||
)
|
||||
|
||||
const canMakeGuest = computed(
|
||||
() => canModifyUser.value && props.targetUser.role !== Roles.Workspace.Guest
|
||||
() =>
|
||||
canModifyUser.value &&
|
||||
props.targetUser.role !== Roles.Workspace.Guest &&
|
||||
props.targetUser.role !== Roles.Workspace.Admin
|
||||
)
|
||||
|
||||
const canMakeMember = computed(
|
||||
|
||||
@@ -5,7 +5,12 @@ import {
|
||||
type Optional,
|
||||
type WorkspaceSeatType
|
||||
} from '@speckle/shared'
|
||||
import { useApolloClient, useMutation, useSubscription } from '@vue/apollo-composable'
|
||||
import {
|
||||
useApolloClient,
|
||||
useMutation,
|
||||
useSubscription,
|
||||
useQuery
|
||||
} from '@vue/apollo-composable'
|
||||
import { graphql } from '~/lib/common/generated/gql'
|
||||
import type {
|
||||
OnWorkspaceUpdatedSubscription,
|
||||
@@ -42,6 +47,7 @@ import { onWorkspaceUpdatedSubscription } from '~/lib/workspaces/graphql/subscri
|
||||
import { useLock } from '~/lib/common/composables/singleton'
|
||||
import type { Get } from 'type-fest'
|
||||
import type { ApolloCache } from '@apollo/client/core'
|
||||
import { workspaceLastAdminCheckQuery } from '../graphql/queries'
|
||||
|
||||
export const useInviteUserToWorkspace = () => {
|
||||
const { activeUser } = useActiveUser()
|
||||
@@ -620,3 +626,20 @@ export const useOnWorkspaceUpdated = (params: {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const useWorkspaceLastAdminCheck = (params: { workspaceSlug: string }) => {
|
||||
const { workspaceSlug } = params
|
||||
|
||||
const { result } = useQuery(workspaceLastAdminCheckQuery, {
|
||||
slug: workspaceSlug
|
||||
})
|
||||
|
||||
const hasSingleAdmin = computed(() => {
|
||||
const admins = result.value?.workspaceBySlug?.team.items || []
|
||||
return admins.length === 1
|
||||
})
|
||||
|
||||
return {
|
||||
hasSingleAdmin
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,3 +71,14 @@ export const workspaceSecurityFragment = graphql(`
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
export const workspaceLastAdminCheckFragment = graphql(`
|
||||
fragment WorkspaceLastAdminCheck_Workspace on Workspace {
|
||||
id
|
||||
team(limit: 50, filter: { roles: ["workspace:admin"] }) {
|
||||
items {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
@@ -149,3 +149,11 @@ export const workspacePlanQuery = graphql(`
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
export const workspaceLastAdminCheckQuery = graphql(`
|
||||
query WorkspaceLastAdminCheck($slug: String!) {
|
||||
workspaceBySlug(slug: $slug) {
|
||||
...WorkspaceLastAdminCheck_Workspace
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
Reference in New Issue
Block a user