DeleteRowOperationItem.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import { useQueryClient } from '@tanstack/react-query'
  2. import { Undo2 } from 'lucide-react'
  3. import { Card, CardContent, CardHeader } from 'ui'
  4. import { formatOperationItemValue } from './OperationQueueSidePanel.utils'
  5. import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
  6. import { tableRowKeys } from '@/data/table-rows/keys'
  7. import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
  8. import { useTableEditorStateSnapshot } from '@/state/table-editor'
  9. import { DeleteRowPayload } from '@/state/table-editor-operation-queue.types'
  10. interface DeleteRowOperationItemProps {
  11. operationId: string
  12. tableId: number
  13. content: DeleteRowPayload
  14. }
  15. export const DeleteRowOperationItem = ({
  16. operationId,
  17. tableId,
  18. content,
  19. }: DeleteRowOperationItemProps) => {
  20. const { table, rowIdentifiers } = content
  21. const tableSchema = table.schema
  22. const tableName = table.name
  23. const queryClient = useQueryClient()
  24. const { data: project } = useSelectedProjectQuery()
  25. const snap = useTableEditorStateSnapshot()
  26. const fullTableName = `${tableSchema}.${tableName}`
  27. const whereClause = Object.entries(rowIdentifiers)
  28. .map(([key, value]) => `${key} = ${formatOperationItemValue(value)}`)
  29. .join(', ')
  30. const handleDelete = () => {
  31. // Remove the operation from the queue
  32. snap.removeOperation(operationId)
  33. // Invalidate the query to revert the optimistic update
  34. if (project) {
  35. queryClient.invalidateQueries({
  36. queryKey: tableRowKeys.tableRowsAndCount(project.ref, tableId),
  37. })
  38. }
  39. }
  40. return (
  41. <Card className="overflow-hidden border-destructive-500 bg-destructive-500/5">
  42. <CardHeader className="py-2 px-3 flex flex-row gap-2 border-b border-destructive-500 space-y-0 items-center">
  43. <div className="min-w-0 flex-1 flex items-start gap-2">
  44. <div className="min-w-0 flex-1">
  45. <code className="text-code-inline dark:bg-surface-300 dark:border-foreground-muted/50">
  46. {fullTableName}
  47. </code>
  48. <div className="text-xs text-foreground mt-1 ml-0.5">
  49. <span>Delete row</span>
  50. <span className="text-foreground-muted mx-1.5">·</span>
  51. <span>where {whereClause}</span>
  52. </div>
  53. </div>
  54. </div>
  55. <ButtonTooltip
  56. type="text"
  57. aria-label="Discard change"
  58. className="w-7"
  59. icon={<Undo2 />}
  60. onClick={handleDelete}
  61. tooltip={{
  62. content: {
  63. side: 'left',
  64. align: 'end',
  65. text: 'Discard change',
  66. },
  67. }}
  68. />
  69. </CardHeader>
  70. <CardContent className="py-2 px-3 font-mono text-xs bg-destructive-100/30">
  71. <div className="text-destructive py-0.5">Row will be deleted</div>
  72. </CardContent>
  73. </Card>
  74. )
  75. }