Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { useState } from 'react'
import { describe, expect, it, beforeEach, vi } from 'vitest'
import { mockAnimationsApi } from 'jsdom-testing-mocks'
import { screen, waitFor, fireEvent } from '@testing-library/dom'
import { fireEvent, screen, waitFor } from '@testing-library/dom'
import userEvent from '@testing-library/user-event'
import { ProjectContextProvider } from 'components/layouts/ProjectLayout/ProjectContext'
import { mockAnimationsApi } from 'jsdom-testing-mocks'
import { useState } from 'react'
import { render } from 'tests/helpers'
import { addAPIMock } from 'tests/lib/msw'
import { ProjectContextProvider } from 'components/layouts/ProjectLayout/ProjectContext'
import EditSecretModal from '../EditSecretModal'
import { routerMock } from 'tests/lib/route-mock'
import { VaultSecret } from 'types'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import EditSecretModal from '../EditSecretModal'

const secret = {
const secret: VaultSecret = {
id: '47ca58b4-01c5-4a71-8814-c73856b02e0e',
name: 'test',
description: 'new text',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { useRouter } from 'next/router'
import { toast } from 'sonner'

import { useParams } from 'common'
import { useContentDeleteMutation } from 'data/content/content-delete-mutation'
import { Snippet } from 'data/content/sql-folders-query'
import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
import { createTabId, useTabsStateSnapshot } from 'state/tabs'
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'

export const DeleteSnippetsModal = ({
snippets,
visible,
onClose,
}: {
visible: boolean
snippets: Snippet[]
onClose: () => void
}) => {
const router = useRouter()
const { ref: projectRef, id } = useParams()
const tabs = useTabsStateSnapshot()
const snapV2 = useSqlEditorV2StateSnapshot()

const postDeleteCleanup = (ids: string[]) => {
if (!!id && ids.includes(id)) {
const openedSQLTabs = tabs.openTabs.filter((x) => x.startsWith('sql-') && !x.includes(id))
if (openedSQLTabs.length > 0) {
// [Joshen] For simplicity, just opening the first tab for now
const firstTabId = openedSQLTabs[0].split('sql-')[1]
router.push(`/project/${projectRef}/sql/${firstTabId}`)
} else {
router.push(`/project/${projectRef}/sql/new`)
}
}

if (ids.length > 0) ids.forEach((id) => snapV2.removeSnippet(id))
}

const { mutate: deleteContent, isLoading: isDeleting } = useContentDeleteMutation({
onSuccess: (data) => {
toast.success(
`Successfully deleted ${snippets.length.toLocaleString()} quer${snippets.length > 1 ? 'ies' : 'y'}`
)

// Update Tabs state - currently unknown how to differentiate between sql and non-sql content
// so we're just deleting all tabs for with matching IDs
const tabIds = data.map((id) => createTabId('sql', { id }))
tabs.removeTabs(tabIds)

postDeleteCleanup(data)
onClose()
},
onError: (error, data) => {
if (error.message.includes('Contents not found')) {
postDeleteCleanup(data.ids)
onClose()
} else {
toast.error(`Failed to delete query: ${error.message}`)
}
},
})

const onConfirmDelete = () => {
if (!projectRef) return console.error('Project ref is required')
deleteContent({ projectRef, ids: snippets.map((x) => x.id) })
}

return (
<ConfirmationModal
size="small"
visible={visible}
title={`Confirm to delete ${snippets.length === 1 ? 'query' : `${snippets.length.toLocaleString()} quer${snippets.length > 1 ? 'ies' : 'y'}`}`}
confirmLabel={`Delete ${snippets.length.toLocaleString()} quer${snippets.length > 1 ? 'ies' : 'y'}`}
confirmLabelLoading="Deleting query"
loading={isDeleting}
variant="destructive"
onCancel={onClose}
onConfirm={onConfirmDelete}
alert={
(snippets[0]?.visibility as unknown as string) === 'project'
? {
title: 'This SQL snippet will be lost forever',
description:
'Deleting this query will remove it for all members of the project team.',
}
: undefined
}
>
<p className="text-sm">
This action cannot be undone.{' '}
{snippets.length === 1
? `Are you sure you want to delete '${snippets[0]?.name}'?`
: `Are you sure you want to delete the selected ${snippets.length} quer${snippets.length > 1 ? 'ies' : 'y'}?`}
</p>
</ConfirmationModal>
)
}
Loading
Loading