OperationQueueSidePanel.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import {
  2. Button,
  3. KeyboardShortcut,
  4. Sheet,
  5. SheetContent,
  6. SheetDescription,
  7. SheetFooter,
  8. SheetHeader,
  9. SheetSection,
  10. SheetTitle,
  11. } from 'ui'
  12. import { OperationList } from './OperationList'
  13. import { useOperationQueueActions } from '@/components/grid/hooks/useOperationQueueActions'
  14. import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog'
  15. import { useConfirmOnClose } from '@/hooks/ui/useConfirmOnClose'
  16. import { useTableEditorStateSnapshot } from '@/state/table-editor'
  17. import { QueuedOperation } from '@/state/table-editor-operation-queue.types'
  18. export const OperationQueueSidePanel = () => {
  19. const snap = useTableEditorStateSnapshot()
  20. const visible = snap.sidePanel?.type === 'operation-queue'
  21. const operations = snap.operationQueue.operations as readonly QueuedOperation[]
  22. const { handleSave, handleCancel, isSaving } = useOperationQueueActions({
  23. onSaveSuccess: snap.closeSidePanel,
  24. onCancelSuccess: snap.closeSidePanel,
  25. })
  26. const { confirmOnClose, modalProps: closeConfirmationModalProps } = useConfirmOnClose({
  27. checkIsDirty: () => true,
  28. onClose: () => handleCancel(),
  29. })
  30. return (
  31. <>
  32. <Sheet open={visible} onOpenChange={(open) => !open && snap.closeSidePanel()}>
  33. <SheetContent
  34. className="flex flex-col gap-y-0"
  35. onOpenAutoFocus={(event) => event.preventDefault()}
  36. >
  37. <SheetHeader>
  38. <SheetTitle>Pending changes</SheetTitle>
  39. <SheetDescription>
  40. {operations.length} operation{operations.length !== 1 ? 's' : ''}
  41. </SheetDescription>
  42. </SheetHeader>
  43. <SheetSection className="overflow-auto grow p-0">
  44. <OperationList operations={operations} />
  45. </SheetSection>
  46. <SheetFooter className="justify-between!">
  47. <Button
  48. type="default"
  49. onClick={snap.closeSidePanel}
  50. iconRight={<KeyboardShortcut keys={['Meta', '.']} variant="inline" />}
  51. >
  52. Close
  53. </Button>
  54. <div className="flex space-x-3">
  55. <Button
  56. type="default"
  57. onClick={confirmOnClose}
  58. disabled={isSaving || operations.length === 0}
  59. >
  60. Discard
  61. </Button>
  62. <Button
  63. onClick={handleSave}
  64. disabled={isSaving || operations.length === 0}
  65. loading={isSaving}
  66. iconRight={
  67. isSaving ? undefined : <KeyboardShortcut keys={['Meta', 's']} variant="inline" />
  68. }
  69. >
  70. Save
  71. </Button>
  72. </div>
  73. </SheetFooter>
  74. </SheetContent>
  75. </Sheet>
  76. <DiscardChangesConfirmationDialog {...closeConfirmationModalProps} />
  77. </>
  78. )
  79. }