+ 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'}?`} +
+- This action cannot be undone.{' '} - {selectedSnippets.length === 1 - ? `Are you sure you want to delete '${selectedSnippets[0]?.name}'?` - : `Are you sure you want to delete the selected ${selectedSnippets.length} quer${selectedSnippets.length > 1 ? 'ies' : 'y'}?`} -
-- {totalNumber} result{totalNumber > 1 ? 's' : ''} found -
- ) : null} - {isLoading ? ( -+ {totalNumber} result{totalNumber > 1 ? 's' : ''} found +
+ ) : null} + {isLoading ? ( +{snippet.name}
- + > ) } diff --git a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/ShareSnippetModal.tsx b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/ShareSnippetModal.tsx new file mode 100644 index 0000000000000..c6e33f9922fa0 --- /dev/null +++ b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/ShareSnippetModal.tsx @@ -0,0 +1,99 @@ +import { Eye, Unlock } from 'lucide-react' +import { toast } from 'sonner' + +import { useParams } from 'common' +import { getContentById } from 'data/content/content-id-query' +import { useContentUpsertMutation } from 'data/content/content-upsert-mutation' +import { Snippet } from 'data/content/sql-folders-query' +import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2' +import { SqlSnippets } from 'types' +import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' + +export const ShareSnippetModal = ({ + snippet, + onClose, + onSuccess, +}: { + snippet?: Snippet + onClose: () => void + onSuccess?: () => void +}) => { + const { ref: projectRef } = useParams() + const snapV2 = useSqlEditorV2StateSnapshot() + + const { mutate: upsertContent, isLoading: isUpserting } = useContentUpsertMutation({ + onError: (error) => { + toast.error(`Failed to update query: ${error.message}`) + }, + }) + + const onShareSnippet = async () => { + if (!projectRef) return console.error('Project ref is required') + if (!snippet) return console.error('Snippet ID is required') + + const storeSnippet = snapV2.snippets[snippet.id] + let snippetContent = storeSnippet?.snippet?.content + + if (snippetContent === undefined) { + const { content } = await getContentById({ projectRef, id: snippet.id }) + snippetContent = content as unknown as SqlSnippets.Content + } + + // [Joshen] Just as a final check - to ensure that the content is minimally there (empty string is fine) + if (snippetContent === undefined) { + return toast.error('Unable to update snippet visibility: Content is missing') + } + + upsertContent( + { + projectRef, + payload: { + ...snippet, + visibility: 'project', + folder_id: null, + content: snippetContent, + }, + }, + { + onSuccess: () => { + snapV2.updateSnippet({ + id: snippet.id, + snippet: { visibility: 'project', folder_id: null }, + skipSave: true, + }) + toast.success('Snippet is now shared to the project') + onSuccess?.() + onClose() + }, + } + ) + } + + return ( +