Fix: Unable to delete project from workspace settings (#3708)
This commit is contained in:
+5
-15
@@ -13,9 +13,10 @@
|
||||
</FormButton>
|
||||
</template>
|
||||
</ProjectPageSettingsBlock>
|
||||
<ProjectPageSettingsGeneralBlockDeleteDialog
|
||||
<ProjectsDeleteDialog
|
||||
v-if="project"
|
||||
v-model:open="showDeleteDialog"
|
||||
redirect-on-complete
|
||||
:project="project"
|
||||
/>
|
||||
</div>
|
||||
@@ -23,27 +24,16 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { graphql } from '~~/lib/common/generated/gql'
|
||||
import type { ProjectPageSettingsGeneralBlockDelete_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
import type { ProjectsDeleteDialog_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
|
||||
graphql(`
|
||||
fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {
|
||||
id
|
||||
name
|
||||
role
|
||||
models(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
commentThreads(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
workspace {
|
||||
slug
|
||||
}
|
||||
...ProjectsDeleteDialog_Project
|
||||
}
|
||||
`)
|
||||
|
||||
defineProps<{
|
||||
project?: ProjectPageSettingsGeneralBlockDelete_ProjectFragment
|
||||
project?: ProjectsDeleteDialog_ProjectFragment
|
||||
}>()
|
||||
|
||||
const showDeleteDialog = ref(false)
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
<template>
|
||||
<LayoutDialog v-model:open="isOpen" max-width="md" :buttons="dialogButtons">
|
||||
<template #header>Delete project</template>
|
||||
<div class="space-y-4 text-body-xs">
|
||||
<p>
|
||||
Are you sure you want to permanently
|
||||
<strong>delete “{{ project.name }}”</strong>
|
||||
and all its contents, including
|
||||
<strong>{{ project.models.totalCount }} {{ modelText }}</strong>
|
||||
<span v-if="project.commentThreads.totalCount">
|
||||
and
|
||||
<strong>{{ project.commentThreads.totalCount }} {{ discussionText }}</strong>
|
||||
</span>
|
||||
?
|
||||
</p>
|
||||
<p>To confirm deletion, type the project name below.</p>
|
||||
<FormTextInput
|
||||
v-model="projectNameInput"
|
||||
name="projectNameConfirm"
|
||||
label="Project name"
|
||||
size="lg"
|
||||
placeholder="Type the project name here..."
|
||||
full-width
|
||||
hide-error-message
|
||||
class="text-sm"
|
||||
color="foundation"
|
||||
/>
|
||||
</div>
|
||||
</LayoutDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
LayoutDialog,
|
||||
FormTextInput,
|
||||
type LayoutDialogButton
|
||||
} from '@speckle/ui-components'
|
||||
import { useDeleteProject } from '~~/lib/projects/composables/projectManagement'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
import type { ProjectPageSettingsGeneralBlockDelete_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
import { Roles } from '@speckle/shared'
|
||||
|
||||
const isOpen = defineModel<boolean>('open', { required: true })
|
||||
|
||||
const props = defineProps<{
|
||||
project: ProjectPageSettingsGeneralBlockDelete_ProjectFragment
|
||||
}>()
|
||||
|
||||
const projectNameInput = ref('')
|
||||
|
||||
const deleteProject = useDeleteProject()
|
||||
const mp = useMixpanel()
|
||||
|
||||
const modelText = computed(() =>
|
||||
props.project.models.totalCount === 1 ? 'model' : 'models'
|
||||
)
|
||||
const discussionText = computed(() =>
|
||||
props.project.commentThreads.totalCount === 1 ? 'discussion' : 'discussions'
|
||||
)
|
||||
|
||||
const dialogButtons = computed<LayoutDialogButton[]>(() => [
|
||||
{
|
||||
text: 'Cancel',
|
||||
props: { color: 'outline' },
|
||||
onClick: () => {
|
||||
isOpen.value = false
|
||||
projectNameInput.value = ''
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Delete',
|
||||
props: {
|
||||
color: 'danger',
|
||||
|
||||
disabled: projectNameInput.value !== props.project.name
|
||||
},
|
||||
onClick: async () => {
|
||||
if (
|
||||
projectNameInput.value === props.project.name &&
|
||||
props.project.role === Roles.Stream.Owner
|
||||
) {
|
||||
await deleteProject(props.project.id, {
|
||||
goHome: true,
|
||||
workspaceSlug: props.project.workspace?.slug
|
||||
})
|
||||
isOpen.value = false
|
||||
mp.track('Stream Action', { type: 'action', name: 'delete' })
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
</script>
|
||||
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<LayoutDialog v-model:open="isOpen" max-width="sm" :buttons="dialogButtons">
|
||||
<template #header>Delete project</template>
|
||||
<div class="flex flex-col gap-4 text-body-xs text-foreground">
|
||||
<div class="flex flex-col gap-2">
|
||||
<p>
|
||||
Are you sure you want to
|
||||
<span class="font-medium">permanently delete</span>
|
||||
the
|
||||
<span class="font-medium">"{{ project.name }}"</span>
|
||||
project? This action
|
||||
<span class="font-medium">cannot</span>
|
||||
be undone.
|
||||
</p>
|
||||
<CommonCard class="bg-foundation !py-4 text-body-2xs flex flex-row gap-y-2">
|
||||
<p>
|
||||
{{ modelText }}
|
||||
</p>
|
||||
<p>
|
||||
{{ discussionText }}
|
||||
</p>
|
||||
<p>
|
||||
{{ versionsText }}
|
||||
</p>
|
||||
</CommonCard>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p>To confirm, type the project name below.</p>
|
||||
<FormTextInput
|
||||
v-model="projectNameInput"
|
||||
name="projectNameConfirm"
|
||||
label="Project name"
|
||||
size="lg"
|
||||
placeholder="Project name..."
|
||||
full-width
|
||||
hide-error-message
|
||||
class="text-sm"
|
||||
color="foundation"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</LayoutDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LayoutDialog, type LayoutDialogButton } from '@speckle/ui-components'
|
||||
import { useDeleteProject } from '~~/lib/projects/composables/projectManagement'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
import { graphql } from '~~/lib/common/generated/gql'
|
||||
import type { ProjectsDeleteDialog_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
import { Roles } from '@speckle/shared'
|
||||
|
||||
graphql(`
|
||||
fragment ProjectsDeleteDialog_Project on Project {
|
||||
id
|
||||
name
|
||||
role
|
||||
models(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
commentThreads(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
workspace {
|
||||
slug
|
||||
id
|
||||
}
|
||||
versions(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
project: ProjectsDeleteDialog_ProjectFragment
|
||||
redirectOnComplete?: boolean
|
||||
}>()
|
||||
|
||||
const isOpen = defineModel<boolean>('open', { required: true })
|
||||
|
||||
const deleteProject = useDeleteProject()
|
||||
const mixpanel = useMixpanel()
|
||||
const { isAdmin } = useActiveUser()
|
||||
|
||||
const projectNameInput = ref('')
|
||||
|
||||
const modelText = computed(
|
||||
() =>
|
||||
`${props.project.models.totalCount} ${
|
||||
props.project.models.totalCount === 1 ? 'model' : 'models'
|
||||
}`
|
||||
)
|
||||
const versionsText = computed(
|
||||
() =>
|
||||
`${props.project.versions.totalCount} ${
|
||||
props.project.versions.totalCount === 1 ? 'version' : 'versions'
|
||||
}`
|
||||
)
|
||||
const discussionText = computed(
|
||||
() =>
|
||||
`${props.project.commentThreads.totalCount} ${
|
||||
props.project.commentThreads.totalCount === 1 ? 'discussion' : 'discussions'
|
||||
}`
|
||||
)
|
||||
const dialogButtons = computed<LayoutDialogButton[]>(() => [
|
||||
{
|
||||
text: 'Cancel',
|
||||
props: { color: 'outline' },
|
||||
onClick: () => {
|
||||
isOpen.value = false
|
||||
projectNameInput.value = ''
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Delete',
|
||||
props: {
|
||||
color: 'danger',
|
||||
|
||||
disabled: projectNameInput.value !== props.project.name
|
||||
},
|
||||
onClick: async () => {
|
||||
if (
|
||||
projectNameInput.value === props.project.name &&
|
||||
(props.project.role === Roles.Stream.Owner || isAdmin.value)
|
||||
) {
|
||||
const options = {
|
||||
goHome: props.redirectOnComplete,
|
||||
workspaceSlug: props.project.workspace?.slug
|
||||
}
|
||||
|
||||
await deleteProject(props.project.id, options)
|
||||
isOpen.value = false
|
||||
mixpanel.track('Stream Action', {
|
||||
type: 'action',
|
||||
name: 'delete',
|
||||
// eslint-disable-next-line camelcase
|
||||
workspace_id: props.project.workspace?.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
</script>
|
||||
@@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="flex flex-col gap-3 justify-between sm:items-center sm:flex-row px-4 pt-3 pb-4 sm:py-2 transition hover:bg-primary-muted"
|
||||
>
|
||||
<div class="flex gap-2 items-center">
|
||||
<div class="h-8 w-8 flex items-center justify-center">
|
||||
<SparklesIcon class="h-5 w-5 text-primary" />
|
||||
</div>
|
||||
<div class="text-foreground text-sm">Announcing the new Speckle web app</div>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<FormButton color="primary" text @click="emit('dismissed')">Skip</FormButton>
|
||||
<FormButton class="px-4" to="/" @click="showDialog = true">
|
||||
See What's New
|
||||
</FormButton>
|
||||
</div>
|
||||
</div>
|
||||
<ProjectsNewSpeckleDialog v-model:open="showDialog" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SparklesIcon } from '@heroicons/vue/24/solid'
|
||||
|
||||
const emit = defineEmits<{ dismissed: [] }>()
|
||||
|
||||
const showDialog = ref(false)
|
||||
|
||||
watch(showDialog, (newValue, oldValue) => {
|
||||
if (!newValue && oldValue) {
|
||||
showDialog.value = false
|
||||
emit('dismissed')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<LayoutDialog v-model:open="open" max-width="sm" :buttons="dialogButtons">
|
||||
<h2 class="text-heading-lg text-center sm:-mt-2 mt-2 mb-2">
|
||||
What's new in Speckle?
|
||||
</h2>
|
||||
<p class="text-foreground-2 text-center mb-6">A new way to collaborate in AEC.</p>
|
||||
<CommonVimeoEmbed
|
||||
vimeo-id="925455838"
|
||||
title="What's new in Speckle?"
|
||||
autoplay
|
||||
muted
|
||||
/>
|
||||
</LayoutDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/outline'
|
||||
import { CommonVimeoEmbed, type LayoutDialogButton } from '@speckle/ui-components'
|
||||
|
||||
const open = defineModel<boolean>('open', { required: true })
|
||||
|
||||
const dialogButtons = computed((): LayoutDialogButton[] => [
|
||||
{
|
||||
text: 'Close',
|
||||
props: { color: 'outline' },
|
||||
onClick: () => {
|
||||
open.value = false
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Learn more',
|
||||
props: {
|
||||
iconRight: ArrowTopRightOnSquareIcon,
|
||||
to: 'https://speckle.systems/blog/the-new-way-to-collaborate-in-aec/',
|
||||
external: true,
|
||||
target: '_blank'
|
||||
}
|
||||
}
|
||||
])
|
||||
</script>
|
||||
@@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<LayoutDialog v-model:open="isOpen" max-width="sm" :buttons="dialogButtons">
|
||||
<template #header>Delete project</template>
|
||||
<div class="flex flex-col gap-6 text-body-xs text-foreground">
|
||||
<p>
|
||||
Are you sure you want to
|
||||
<span class="font-medium">permanently delete</span>
|
||||
the selected project?
|
||||
</p>
|
||||
<div
|
||||
v-if="project"
|
||||
class="rounded border bg-foundation-2 border-outline-3 text-body-2xs py-3 px-4"
|
||||
>
|
||||
<p class="font-medium">{{ project.name }}</p>
|
||||
<p>
|
||||
{{ project.models.totalCount }} models,
|
||||
{{ project.versions.totalCount }} versions,
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
This action
|
||||
<span class="font-medium">cannot</span>
|
||||
be undone.
|
||||
</p>
|
||||
</div>
|
||||
</LayoutDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMutation } from '@vue/apollo-composable'
|
||||
import { LayoutDialog, type LayoutDialogButton } from '@speckle/ui-components'
|
||||
import type { ProjectItem } from '~~/lib/server-management/helpers/types'
|
||||
import { adminDeleteProjectMutation } from '~~/lib/server-management/graphql/mutations'
|
||||
import { useGlobalToast, ToastNotificationType } from '~~/lib/common/composables/toast'
|
||||
import {
|
||||
ROOT_QUERY,
|
||||
convertThrowIntoFetchResult,
|
||||
getCacheId,
|
||||
getFirstErrorMessage,
|
||||
modifyObjectFields
|
||||
} from '~~/lib/common/helpers/graphql'
|
||||
import type { ProjectCollection } from '~~/lib/common/generated/gql/graphql'
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
project: ProjectItem | null
|
||||
}>()
|
||||
|
||||
const { triggerNotification } = useGlobalToast()
|
||||
const { mutate: adminDeleteMutation } = useMutation(adminDeleteProjectMutation)
|
||||
|
||||
const isOpen = defineModel<boolean>('open', { required: true })
|
||||
|
||||
const deleteConfirmed = async () => {
|
||||
const projectId = props.project?.id
|
||||
if (!projectId) {
|
||||
return
|
||||
}
|
||||
|
||||
const result = await adminDeleteMutation(
|
||||
{
|
||||
ids: [projectId]
|
||||
},
|
||||
{
|
||||
update: (cache, { data }) => {
|
||||
if (data?.projectMutations.batchDelete) {
|
||||
// Remove project from cache
|
||||
const cacheId = getCacheId('Project', projectId)
|
||||
cache.evict({
|
||||
id: cacheId
|
||||
})
|
||||
|
||||
// Modify 'admin' field of ROOT_QUERY so that we can modify all `projectList` instances
|
||||
modifyObjectFields<undefined, { [key: string]: ProjectCollection }>(
|
||||
cache,
|
||||
ROOT_QUERY,
|
||||
(_fieldName, _variables, value, details) => {
|
||||
// Find all `projectList` fields (there can be multiple due to differing variables)
|
||||
const projectListFields = Object.keys(value).filter(
|
||||
(k) =>
|
||||
details.revolveFieldNameAndVariables(k).fieldName === 'projectList'
|
||||
)
|
||||
|
||||
// Being careful not to mutate original `value`
|
||||
const newVal: typeof value = { ...value }
|
||||
|
||||
// Iterate over each and adjust `items` and `totalCount`
|
||||
for (const field of projectListFields) {
|
||||
const oldItems = value[field]?.items || []
|
||||
const newItems = oldItems.filter((i) => i.__ref !== cacheId)
|
||||
|
||||
newVal[field] = {
|
||||
...value[field],
|
||||
...(value[field]?.items ? { items: newItems } : {}),
|
||||
totalCount: Math.max(0, (value[field]?.totalCount || 0) - 1)
|
||||
}
|
||||
}
|
||||
|
||||
return newVal
|
||||
},
|
||||
{ fieldNameWhitelist: ['admin'] }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
).catch(convertThrowIntoFetchResult)
|
||||
|
||||
if (result?.data?.projectMutations.batchDelete) {
|
||||
triggerNotification({
|
||||
type: ToastNotificationType.Success,
|
||||
title: 'Project deleted',
|
||||
description: 'The project has been successfully deleted'
|
||||
})
|
||||
isOpen.value = false
|
||||
} else {
|
||||
const errorMessage = getFirstErrorMessage(result?.errors)
|
||||
triggerNotification({
|
||||
type: ToastNotificationType.Danger,
|
||||
title: 'Failed to delete project',
|
||||
description: errorMessage
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const dialogButtons: LayoutDialogButton[] = [
|
||||
{
|
||||
text: 'Cancel',
|
||||
props: { color: 'outline' },
|
||||
onClick: () => (isOpen.value = false)
|
||||
},
|
||||
{
|
||||
text: 'Delete',
|
||||
props: { color: 'danger' },
|
||||
onClick: deleteConfirmed
|
||||
}
|
||||
]
|
||||
</script>
|
||||
@@ -89,7 +89,8 @@
|
||||
</template>
|
||||
</LayoutTable>
|
||||
|
||||
<SettingsSharedProjectsDeleteDialog
|
||||
<ProjectsDeleteDialog
|
||||
v-if="projectToModify"
|
||||
v-model:open="showProjectDeleteDialog"
|
||||
:project="projectToModify"
|
||||
/>
|
||||
@@ -99,10 +100,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { HorizontalDirection } from '~~/lib/common/composables/window'
|
||||
import type { ItemType, ProjectItem } from '~~/lib/server-management/helpers/types'
|
||||
import type { SettingsSharedProjects_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
import type {
|
||||
SettingsSharedProjects_ProjectFragment,
|
||||
ProjectsDeleteDialog_ProjectFragment
|
||||
} from '~~/lib/common/generated/gql/graphql'
|
||||
import {
|
||||
MagnifyingGlassIcon,
|
||||
EllipsisHorizontalIcon,
|
||||
@@ -116,15 +118,16 @@ import { projectCollaboratorsRoute, projectRoute } from '~/lib/common/helpers/ro
|
||||
|
||||
graphql(`
|
||||
fragment SettingsSharedProjects_Project on Project {
|
||||
...ProjectsDeleteDialog_Project
|
||||
id
|
||||
name
|
||||
visibility
|
||||
createdAt
|
||||
updatedAt
|
||||
models {
|
||||
models(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
versions {
|
||||
versions(limit: 0) {
|
||||
totalCount
|
||||
}
|
||||
team {
|
||||
@@ -151,26 +154,24 @@ const search = defineModel<string>('search')
|
||||
const { on, bind } = useDebouncedTextInput({ model: search })
|
||||
const router = useRouter()
|
||||
|
||||
const projectToModify = ref<ProjectItem | null>(null)
|
||||
const projectToModify = ref<ProjectsDeleteDialog_ProjectFragment | null>(null)
|
||||
const showProjectDeleteDialog = ref(false)
|
||||
const openNewProject = ref(false)
|
||||
|
||||
const openProjectDeleteDialog = (item: ItemType) => {
|
||||
if (isProject(item)) {
|
||||
projectToModify.value = item
|
||||
showProjectDeleteDialog.value = true
|
||||
}
|
||||
const openProjectDeleteDialog = (item: ProjectsDeleteDialog_ProjectFragment) => {
|
||||
projectToModify.value = item
|
||||
showProjectDeleteDialog.value = true
|
||||
}
|
||||
|
||||
const handleProjectClick = (item: ItemType) => {
|
||||
router.push(projectRoute(item.id))
|
||||
const handleProjectClick = (id: string) => {
|
||||
router.push(projectRoute(id))
|
||||
emit('close')
|
||||
}
|
||||
|
||||
enum ActionTypes {
|
||||
ViewProject = 'view-project',
|
||||
EditMembers = 'edit-members',
|
||||
RemoveProject = 'remove-project'
|
||||
DeleteProject = 'delete-project'
|
||||
}
|
||||
|
||||
const showActionsMenu = ref<Record<string, boolean>>({})
|
||||
@@ -179,17 +180,20 @@ const actionItems: LayoutMenuItem[][] = [
|
||||
[
|
||||
{ title: 'View project', id: ActionTypes.ViewProject },
|
||||
{ title: 'Edit members', id: ActionTypes.EditMembers },
|
||||
{ title: 'Remove project...', id: ActionTypes.RemoveProject }
|
||||
{ title: 'Delete project...', id: ActionTypes.DeleteProject }
|
||||
]
|
||||
]
|
||||
|
||||
const onActionChosen = (actionItem: LayoutMenuItem, project: ProjectItem) => {
|
||||
const onActionChosen = (
|
||||
actionItem: LayoutMenuItem,
|
||||
project: ProjectsDeleteDialog_ProjectFragment
|
||||
) => {
|
||||
if (actionItem.id === ActionTypes.EditMembers) {
|
||||
router.push(projectCollaboratorsRoute(project.id))
|
||||
emit('close')
|
||||
} else if (actionItem.id === ActionTypes.ViewProject) {
|
||||
handleProjectClick(project)
|
||||
} else if (actionItem.id === ActionTypes.RemoveProject) {
|
||||
handleProjectClick(project.id)
|
||||
} else if (actionItem.id === ActionTypes.DeleteProject) {
|
||||
openProjectDeleteDialog(project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ const documents = {
|
||||
"\n query ProjectPageSettingsCollaboratorsWorkspace($workspaceId: String!) {\n workspace(id: $workspaceId) {\n ...ProjectPageTeamInternals_Workspace\n }\n }\n": types.ProjectPageSettingsCollaboratorsWorkspaceDocument,
|
||||
"\n query ProjectPageSettingsGeneral($projectId: String!) {\n project(id: $projectId) {\n id\n role\n ...ProjectPageSettingsGeneralBlockProjectInfo_Project\n ...ProjectPageSettingsGeneralBlockAccess_Project\n ...ProjectPageSettingsGeneralBlockDiscussions_Project\n ...ProjectPageSettingsGeneralBlockLeave_Project\n ...ProjectPageSettingsGeneralBlockDelete_Project\n ...ProjectPageTeamInternals_Project\n }\n }\n": types.ProjectPageSettingsGeneralDocument,
|
||||
"\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n }\n": types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
|
||||
"\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n }\n": types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
|
||||
"\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n ...ProjectsDeleteDialog_Project\n }\n": types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
|
||||
"\n fragment ProjectPageSettingsGeneralBlockDiscussions_Project on Project {\n id\n visibility\n allowPublicComments\n }\n": types.ProjectPageSettingsGeneralBlockDiscussions_ProjectFragmentDoc,
|
||||
"\n fragment ProjectPageSettingsGeneralBlockLeave_Project on Project {\n id\n name\n role\n team {\n role\n user {\n ...LimitedUserAvatar\n role\n }\n }\n workspace {\n id\n }\n }\n": types.ProjectPageSettingsGeneralBlockLeave_ProjectFragmentDoc,
|
||||
"\n fragment ProjectPageSettingsGeneralBlockProjectInfo_Project on Project {\n id\n role\n name\n description\n }\n": types.ProjectPageSettingsGeneralBlockProjectInfo_ProjectFragmentDoc,
|
||||
@@ -97,6 +97,7 @@ const documents = {
|
||||
"\n fragment ProjectsDashboardFilledUser on UserProjectCollection {\n items {\n ...ProjectDashboardItem\n }\n }\n": types.ProjectsDashboardFilledUserFragmentDoc,
|
||||
"\n fragment ProjectsDashboardHeaderProjects_User on User {\n projectInvites {\n ...ProjectsInviteBanner\n }\n }\n": types.ProjectsDashboardHeaderProjects_UserFragmentDoc,
|
||||
"\n fragment ProjectsDashboardHeaderWorkspaces_User on User {\n discoverableWorkspaces {\n ...WorkspaceInviteDiscoverableWorkspaceBanner_LimitedWorkspace\n }\n workspaceInvites {\n ...WorkspaceInviteBanner_PendingWorkspaceCollaborator\n }\n }\n": types.ProjectsDashboardHeaderWorkspaces_UserFragmentDoc,
|
||||
"\n fragment ProjectsDeleteDialog_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n id\n }\n versions(limit: 0) {\n totalCount\n }\n }\n": types.ProjectsDeleteDialog_ProjectFragmentDoc,
|
||||
"\n fragment ProjectsHiddenProjectWarning_User on User {\n id\n expiredSsoSessions {\n id\n slug\n name\n logo\n }\n }\n": types.ProjectsHiddenProjectWarning_UserFragmentDoc,
|
||||
"\n fragment ProjectsMoveToWorkspaceDialog_Workspace on Workspace {\n id\n role\n name\n logo\n ...WorkspaceHasCustomDataResidency_Workspace\n ...ProjectsWorkspaceSelect_Workspace\n }\n": types.ProjectsMoveToWorkspaceDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment ProjectsMoveToWorkspaceDialog_User on User {\n workspaces {\n items {\n ...ProjectsMoveToWorkspaceDialog_Workspace\n }\n }\n }\n": types.ProjectsMoveToWorkspaceDialog_UserFragmentDoc,
|
||||
@@ -111,7 +112,7 @@ const documents = {
|
||||
"\n fragment SettingsServerRegionsAddEditDialog_ServerRegionItem on ServerRegionItem {\n id\n name\n description\n key\n }\n": types.SettingsServerRegionsAddEditDialog_ServerRegionItemFragmentDoc,
|
||||
"\n fragment SettingsServerRegionsTable_ServerRegionItem on ServerRegionItem {\n id\n name\n key\n description\n }\n": types.SettingsServerRegionsTable_ServerRegionItemFragmentDoc,
|
||||
"\n fragment SettingsSharedDeleteUserDialog_Workspace on Workspace {\n id\n plan {\n status\n name\n }\n subscription {\n currentBillingCycleEnd\n seats {\n guest\n plan\n }\n }\n }\n": types.SettingsSharedDeleteUserDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsSharedProjects_Project on Project {\n id\n name\n visibility\n createdAt\n updatedAt\n models {\n totalCount\n }\n versions {\n totalCount\n }\n team {\n id\n user {\n name\n id\n avatar\n }\n }\n }\n": types.SettingsSharedProjects_ProjectFragmentDoc,
|
||||
"\n fragment SettingsSharedProjects_Project on Project {\n ...ProjectsDeleteDialog_Project\n id\n name\n visibility\n createdAt\n updatedAt\n models(limit: 0) {\n totalCount\n }\n versions(limit: 0) {\n totalCount\n }\n team {\n id\n user {\n name\n id\n avatar\n }\n }\n }\n": types.SettingsSharedProjects_ProjectFragmentDoc,
|
||||
"\n fragment SettingsUserEmails_User on User {\n id\n emails {\n ...SettingsUserEmailCards_UserEmail\n }\n }\n": types.SettingsUserEmails_UserFragmentDoc,
|
||||
"\n fragment SettingsUserNotifications_User on User {\n id\n notificationPreferences\n }\n": types.SettingsUserNotifications_UserFragmentDoc,
|
||||
"\n fragment SettingsUserProfile_User on User {\n ...SettingsUserProfileChangePassword_User\n ...SettingsUserProfileDeleteAccount_User\n ...SettingsUserProfileDetails_User\n }\n": types.SettingsUserProfile_UserFragmentDoc,
|
||||
@@ -675,7 +676,7 @@ export function graphql(source: "\n fragment ProjectPageSettingsGeneralBlockAcc
|
||||
/**
|
||||
* 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 ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n }\n"): (typeof documents)["\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n }\n"];
|
||||
export function graphql(source: "\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n ...ProjectsDeleteDialog_Project\n }\n"): (typeof documents)["\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n ...ProjectsDeleteDialog_Project\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -728,6 +729,10 @@ export function graphql(source: "\n fragment ProjectsDashboardHeaderProjects_Us
|
||||
* 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 ProjectsDashboardHeaderWorkspaces_User on User {\n discoverableWorkspaces {\n ...WorkspaceInviteDiscoverableWorkspaceBanner_LimitedWorkspace\n }\n workspaceInvites {\n ...WorkspaceInviteBanner_PendingWorkspaceCollaborator\n }\n }\n"): (typeof documents)["\n fragment ProjectsDashboardHeaderWorkspaces_User on User {\n discoverableWorkspaces {\n ...WorkspaceInviteDiscoverableWorkspaceBanner_LimitedWorkspace\n }\n workspaceInvites {\n ...WorkspaceInviteBanner_PendingWorkspaceCollaborator\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 ProjectsDeleteDialog_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n id\n }\n versions(limit: 0) {\n totalCount\n }\n }\n"): (typeof documents)["\n fragment ProjectsDeleteDialog_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n id\n }\n versions(limit: 0) {\n totalCount\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -787,7 +792,7 @@ export function graphql(source: "\n fragment SettingsSharedDeleteUserDialog_Wor
|
||||
/**
|
||||
* 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 SettingsSharedProjects_Project on Project {\n id\n name\n visibility\n createdAt\n updatedAt\n models {\n totalCount\n }\n versions {\n totalCount\n }\n team {\n id\n user {\n name\n id\n avatar\n }\n }\n }\n"): (typeof documents)["\n fragment SettingsSharedProjects_Project on Project {\n id\n name\n visibility\n createdAt\n updatedAt\n models {\n totalCount\n }\n versions {\n totalCount\n }\n team {\n id\n user {\n name\n id\n avatar\n }\n }\n }\n"];
|
||||
export function graphql(source: "\n fragment SettingsSharedProjects_Project on Project {\n ...ProjectsDeleteDialog_Project\n id\n name\n visibility\n createdAt\n updatedAt\n models(limit: 0) {\n totalCount\n }\n versions(limit: 0) {\n totalCount\n }\n team {\n id\n user {\n name\n id\n avatar\n }\n }\n }\n"): (typeof documents)["\n fragment SettingsSharedProjects_Project on Project {\n ...ProjectsDeleteDialog_Project\n id\n name\n visibility\n createdAt\n updatedAt\n models(limit: 0) {\n totalCount\n }\n versions(limit: 0) {\n totalCount\n }\n team {\n id\n user {\n name\n id\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.
|
||||
*/
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -98,8 +98,7 @@ export function useProjectUpdateTracking(
|
||||
if (redirectOnDeletion || notifyOnUpdate) {
|
||||
triggerNotification({
|
||||
type: ToastNotificationType.Info,
|
||||
title: isDeleted ? 'Project deleted' : 'Project updated',
|
||||
description: isDeleted ? 'Redirecting to home' : undefined
|
||||
title: isDeleted ? 'Project deleted' : 'Project updated'
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -423,11 +422,6 @@ export function useDeleteProject() {
|
||||
.catch(convertThrowIntoFetchResult)
|
||||
|
||||
if (result?.data?.projectMutations.delete) {
|
||||
triggerNotification({
|
||||
type: ToastNotificationType.Info,
|
||||
title: 'Project deleted'
|
||||
})
|
||||
|
||||
if (goHome) {
|
||||
if (workspaceSlug) {
|
||||
router.push(workspaceRoute(workspaceSlug))
|
||||
|
||||
Reference in New Issue
Block a user