@plutonhq/core-frontend 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist-lib/@types/backups.d.ts +1 -1
  2. package/dist-lib/@types/backups.d.ts.map +1 -1
  3. package/dist-lib/components/Plan/BackupEvents/BackupEvents.d.ts.map +1 -1
  4. package/dist-lib/components/Plan/BackupEvents/BackupEvents.js +27 -27
  5. package/dist-lib/components/Plan/BackupEvents/BackupEvents.js.map +1 -1
  6. package/dist-lib/components/Plan/Backups/Backups.d.ts.map +1 -1
  7. package/dist-lib/components/Plan/Backups/Backups.js +189 -159
  8. package/dist-lib/components/Plan/Backups/Backups.js.map +1 -1
  9. package/dist-lib/components/Plan/PlanPruneModal/PlanPruneModal.d.ts.map +1 -1
  10. package/dist-lib/components/Plan/PlanPruneModal/PlanPruneModal.js +62 -26
  11. package/dist-lib/components/Plan/PlanPruneModal/PlanPruneModal.js.map +1 -1
  12. package/dist-lib/components/Plan/PlanSettings/PlanPruneSettings.d.ts.map +1 -1
  13. package/dist-lib/components/Plan/PlanSettings/PlanPruneSettings.js +138 -62
  14. package/dist-lib/components/Plan/PlanSettings/PlanPruneSettings.js.map +1 -1
  15. package/dist-lib/components/Plan/PlanSettings/PlanSettings.module.scss.js +42 -42
  16. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.d.ts +32 -0
  17. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.d.ts.map +1 -0
  18. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.js +252 -0
  19. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.js.map +1 -0
  20. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.d.ts +23 -0
  21. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.d.ts.map +1 -0
  22. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.js +72 -0
  23. package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.js.map +1 -0
  24. package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.d.ts.map +1 -1
  25. package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.js +188 -198
  26. package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.js.map +1 -1
  27. package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.module.scss.js +20 -64
  28. package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.module.scss.js.map +1 -1
  29. package/dist-lib/components/Restore/RestoredFileBrowser/RestoredFileBrowser.d.ts.map +1 -1
  30. package/dist-lib/components/Restore/RestoredFileBrowser/RestoredFileBrowser.js +125 -159
  31. package/dist-lib/components/Restore/RestoredFileBrowser/RestoredFileBrowser.js.map +1 -1
  32. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowser.module.scss.js +74 -0
  33. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowser.module.scss.js.map +1 -0
  34. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.d.ts +17 -0
  35. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.d.ts.map +1 -0
  36. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.js +57 -0
  37. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.js.map +1 -0
  38. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.d.ts +18 -0
  39. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.d.ts.map +1 -0
  40. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.js +24 -0
  41. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.js.map +1 -0
  42. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.d.ts +18 -0
  43. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.d.ts.map +1 -0
  44. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.js +37 -0
  45. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.js.map +1 -0
  46. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.d.ts +9 -0
  47. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.d.ts.map +1 -0
  48. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.js +15 -0
  49. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.js.map +1 -0
  50. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.d.ts +11 -0
  51. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.d.ts.map +1 -0
  52. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.js +18 -0
  53. package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.js.map +1 -0
  54. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.d.ts +12 -0
  55. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.d.ts.map +1 -0
  56. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.js +70 -0
  57. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.js.map +1 -0
  58. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.d.ts +22 -0
  59. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.d.ts.map +1 -0
  60. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.js +79 -0
  61. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.js.map +1 -0
  62. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.d.ts +6 -0
  63. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.d.ts.map +1 -0
  64. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.js +18 -0
  65. package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.js.map +1 -0
  66. package/dist-lib/components/common/SnapshotBrowser/index.d.ts +11 -0
  67. package/dist-lib/components/common/SnapshotBrowser/index.d.ts.map +1 -0
  68. package/dist-lib/components/common/StatusLabel/StatusLabel.d.ts +1 -1
  69. package/dist-lib/components/common/StatusLabel/StatusLabel.d.ts.map +1 -1
  70. package/dist-lib/components/common/StatusLabel/StatusLabel.js +17 -12
  71. package/dist-lib/components/common/StatusLabel/StatusLabel.js.map +1 -1
  72. package/dist-lib/components/common/form/NumberInput/NumberInput.module.scss.js +4 -4
  73. package/dist-lib/components/index.d.ts +10 -0
  74. package/dist-lib/components/index.d.ts.map +1 -1
  75. package/dist-lib/components.js +152 -132
  76. package/dist-lib/components.js.map +1 -1
  77. package/dist-lib/hooks/usePlanSingleActions.d.ts.map +1 -1
  78. package/dist-lib/hooks/usePlanSingleActions.js +21 -21
  79. package/dist-lib/hooks/usePlanSingleActions.js.map +1 -1
  80. package/dist-lib/services/backups.d.ts +4 -0
  81. package/dist-lib/services/backups.d.ts.map +1 -1
  82. package/dist-lib/services/backups.js +34 -25
  83. package/dist-lib/services/backups.js.map +1 -1
  84. package/dist-lib/services.js +113 -112
  85. package/dist-lib/styles/core-frontend.css +1 -1
  86. package/dist-lib/utils/index.d.ts +1 -0
  87. package/dist-lib/utils/index.d.ts.map +1 -1
  88. package/dist-lib/utils/snapshotDatabase.d.ts +16 -0
  89. package/dist-lib/utils/snapshotDatabase.d.ts.map +1 -0
  90. package/dist-lib/utils/snapshotDatabase.js +105 -0
  91. package/dist-lib/utils/snapshotDatabase.js.map +1 -0
  92. package/dist-lib/utils.js +24 -22
  93. package/dist-lib/utils.js.map +1 -1
  94. package/package.json +1 -1
  95. package/src/@types/backups.ts +1 -1
  96. package/src/components/Plan/BackupEvents/BackupEvents.tsx +5 -3
  97. package/src/components/Plan/Backups/Backups.tsx +40 -1
  98. package/src/components/Plan/PlanPruneModal/PlanPruneModal.tsx +54 -11
  99. package/src/components/Plan/PlanSettings/PlanPruneSettings.tsx +145 -61
  100. package/src/components/Plan/PlanSettings/PlanSettings.module.scss +5 -0
  101. package/src/components/Plan/SnapshotViewer/SnapshotViewer.tsx +344 -0
  102. package/src/components/Plan/SnapshotViewer/SnapshotViewerFile.tsx +89 -0
  103. package/src/components/Restore/RestoreFileSelector/RestoreFileSelector.tsx +82 -145
  104. package/src/components/Restore/RestoredFileBrowser/RestoredFileBrowser.tsx +71 -156
  105. package/src/components/common/SnapshotBrowser/SnapshotBrowser.module.scss +376 -0
  106. package/src/components/common/SnapshotBrowser/SnapshotBrowserDirectories.tsx +84 -0
  107. package/src/components/common/SnapshotBrowser/SnapshotBrowserFileList.tsx +52 -0
  108. package/src/components/common/SnapshotBrowser/SnapshotBrowserFileRow.tsx +44 -0
  109. package/src/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.tsx +22 -0
  110. package/src/components/common/SnapshotBrowser/SnapshotBrowserToolbar.tsx +29 -0
  111. package/src/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.ts +130 -0
  112. package/src/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.ts +154 -0
  113. package/src/components/common/SnapshotBrowser/hooks/useSnapshotSort.ts +24 -0
  114. package/src/components/common/SnapshotBrowser/index.ts +13 -0
  115. package/src/components/common/StatusLabel/StatusLabel.tsx +7 -1
  116. package/src/components/common/form/NumberInput/NumberInput.module.scss +1 -0
  117. package/src/components/index.ts +13 -0
  118. package/src/hooks/usePlanSingleActions.tsx +5 -3
  119. package/src/services/backups.ts +12 -0
  120. package/src/utils/index.ts +1 -0
  121. package/src/utils/snapshotDatabase.ts +201 -0
@@ -1 +1 @@
1
- {"version":3,"file":"RestoredFileBrowser.js","sources":["../../../../src/components/Restore/RestoredFileBrowser/RestoredFileBrowser.tsx"],"sourcesContent":["import { useState, useMemo, useEffect } from 'react';\r\nimport { FixedSizeList as List } from 'react-window';\r\nimport Icon from '../../common/Icon/Icon';\r\nimport classes from './RestoredFileBrowser.module.scss';\r\nimport { RestoredFileItem, RestoredItemsStats } from '../../../@types/restores';\r\nimport { formatBytes, formatNumberToK, isMobile } from '../../../utils/helpers';\r\nimport { getParentPath, getPathSeparator, normalizePath, splitPath } from '../../../utils/restore';\r\nimport FileIcon from '../../common/FileIcon/FileIcon';\r\n\r\ninterface RestoredFileBrowserProps {\r\n files: RestoredFileItem[];\r\n stats?: RestoredItemsStats;\r\n isPreview?: boolean;\r\n}\r\n\r\nconst isMobileDevice = isMobile();\r\nconst ITEM_HEIGHT = isMobileDevice ? 65 : 45;\r\n\r\nconst RestoredFileBrowser = ({ files, stats, isPreview = false }: RestoredFileBrowserProps) => {\r\n const [selectedFolder, setSelectedFolder] = useState<string>('');\r\n const [search, setSearch] = useState('');\r\n const [filters, setFilters] = useState({\r\n unchanged: true,\r\n restored: true,\r\n updated: true,\r\n });\r\n\r\n const [expandedFolders, setExpandedFolders] = useState<Set<string>>(() => {\r\n const allPaths = new Set<string>();\r\n files.forEach((file) => {\r\n const separator = getPathSeparator(file.path);\r\n const parts = splitPath(file.path);\r\n let currentPath = '';\r\n\r\n parts.forEach((part, index) => {\r\n currentPath = currentPath ? `${currentPath}${separator}${part}` : part;\r\n // Only expand folders up to 5 levels deep (index < 5)\r\n if (index < 3) {\r\n allPaths.add(currentPath);\r\n }\r\n });\r\n });\r\n return allPaths;\r\n });\r\n\r\n const fileSystem = useMemo(() => {\r\n const system: { [key: string]: RestoredFileItem[] } = {};\r\n\r\n files\r\n .filter((file) => {\r\n const matchesSearch = file.path.toLowerCase().includes(search.toLowerCase());\r\n const matchesFilter = filters[file.action];\r\n return matchesSearch && matchesFilter;\r\n })\r\n .forEach((file) => {\r\n const dirPath = getParentPath(file.path);\r\n // Use the normalized path as key\r\n const normalizedDirPath = normalizePath(dirPath);\r\n\r\n if (normalizedDirPath) {\r\n if (!system[normalizedDirPath]) {\r\n system[normalizedDirPath] = [];\r\n }\r\n system[normalizedDirPath].push(file);\r\n }\r\n });\r\n\r\n return system;\r\n }, [files, search, filters]);\r\n\r\n const directories = useMemo(() => {\r\n const dirs = new Set<string>();\r\n // Derive directories from all files, not filtered fileSystem, to keep tree stable during search\r\n files.forEach((file) => {\r\n const dirPath = getParentPath(file.path);\r\n const separator = getPathSeparator(dirPath);\r\n const parts = splitPath(dirPath);\r\n let currentPath = '';\r\n\r\n parts.forEach((part) => {\r\n currentPath = currentPath ? `${currentPath}${separator}${part}` : part;\r\n if (currentPath) {\r\n dirs.add(currentPath);\r\n }\r\n });\r\n });\r\n return Array.from(dirs);\r\n }, [files]);\r\n\r\n // Set initial selected folder when directories change\r\n useEffect(() => {\r\n if (directories.length > 0 && selectedFolder === '') {\r\n setSelectedFolder(directories[0]);\r\n }\r\n }, [directories, selectedFolder]);\r\n\r\n const hasSubdirectories = (dir: string) => {\r\n const separator = getPathSeparator(dir);\r\n return directories.some((d) => d !== dir && d.startsWith(dir + separator));\r\n };\r\n\r\n const hasUpdatedContent = (dir: string) => {\r\n return Object.entries(fileSystem).some(([path, files]) => {\r\n return path.startsWith(dir) && files.some((f) => f.action === 'restored' || f.action === 'updated');\r\n });\r\n };\r\n\r\n const expandParentDirectories = (dir: string) => {\r\n const newExpanded = new Set(expandedFolders);\r\n const separator = getPathSeparator(dir);\r\n const parts = splitPath(dir);\r\n let currentPath = '';\r\n\r\n // Expand all parent directories\r\n parts.forEach((part, index) => {\r\n currentPath = currentPath ? `${currentPath}${separator}${part}` : part;\r\n if (index < parts.length - 1) {\r\n // Don't expand the target directory itself\r\n newExpanded.add(currentPath);\r\n }\r\n });\r\n\r\n setExpandedFolders(newExpanded);\r\n };\r\n\r\n const toggleFolder = (dir: string) => {\r\n const newExpanded = new Set(expandedFolders);\r\n if (expandedFolders.has(dir)) {\r\n newExpanded.delete(dir);\r\n } else {\r\n newExpanded.add(dir);\r\n }\r\n setExpandedFolders(newExpanded);\r\n };\r\n\r\n const isVisible = (dir: string) => {\r\n const separator = getPathSeparator(dir);\r\n const parts = splitPath(dir);\r\n const parentParts = parts.slice(0, -1);\r\n let parentPath = '';\r\n\r\n // Check if all parent folders are expanded\r\n return parentParts.every((part) => {\r\n parentPath = parentPath ? `${parentPath}${separator}${part}` : part;\r\n return expandedFolders.has(parentPath);\r\n });\r\n };\r\n\r\n const sortedFiles = useMemo(() => {\r\n if (!selectedFolder || !fileSystem[selectedFolder]) return [];\r\n\r\n return fileSystem[selectedFolder].sort((a, b) => {\r\n const normalizedPathA = normalizePath(a.path);\r\n const normalizedPathB = normalizePath(b.path);\r\n const isDirectoryA = directories.includes(normalizedPathA);\r\n const isDirectoryB = directories.includes(normalizedPathB);\r\n\r\n // First sort by type: directories first, then files\r\n if (isDirectoryA && !isDirectoryB) return -1;\r\n if (!isDirectoryA && isDirectoryB) return 1;\r\n\r\n // If both are same type, sort by status priority\r\n const priority = { restored: 0, updated: 1, unchanged: 2 };\r\n return priority[a.action] - priority[b.action];\r\n });\r\n }, [selectedFolder, fileSystem, directories]);\r\n\r\n const showGoUpButton = selectedFolder && getParentPath(selectedFolder) !== selectedFolder && selectedFolder !== '' && selectedFolder !== '/';\r\n const totalItems = sortedFiles.length + (showGoUpButton ? 1 : 0);\r\n\r\n const FileRow = ({ index, style }: { index: number; style: React.CSSProperties }) => {\r\n // If showing go up button and this is the first item\r\n if (showGoUpButton && index === 0) {\r\n return (\r\n <div\r\n style={style}\r\n className={`${classes.file} ${classes.fileIsDir} ${classes.goUpButton}`}\r\n onClick={() => {\r\n const parentPath = getParentPath(selectedFolder);\r\n const normalizedParentPath = normalizePath(parentPath);\r\n console.log('normalizedParentPath :', normalizedParentPath);\r\n if (!normalizedParentPath || normalizedParentPath === '') return;\r\n expandParentDirectories(normalizedParentPath);\r\n setSelectedFolder(normalizedParentPath);\r\n }}\r\n >\r\n <div className={classes.fileName}>...</div>\r\n <div className={classes.status}></div>\r\n <div></div>\r\n </div>\r\n );\r\n }\r\n\r\n const fileIndex = showGoUpButton ? index - 1 : index;\r\n const file = sortedFiles[fileIndex];\r\n\r\n if (!file) return null;\r\n\r\n const parts = splitPath(file.path);\r\n const fileName = parts[parts.length - 1];\r\n const normalizedPath = normalizePath(file.path);\r\n const isDirectory = directories.includes(normalizedPath);\r\n const hasUpdates = hasUpdatedContent(normalizedPath);\r\n const fileAction = file.action;\r\n const isRestored = file.action === 'restored' ? true : false;\r\n const fileActionLabel = isRestored ? 'New' : file.action;\r\n\r\n return (\r\n <div\r\n style={style}\r\n className={`${classes.file} ${isDirectory ? classes.fileIsDir : ''}`}\r\n onClick={() => {\r\n if (isDirectory) {\r\n setSelectedFolder(normalizedPath);\r\n expandParentDirectories(normalizedPath);\r\n }\r\n }}\r\n >\r\n <div className={classes.fileName}>\r\n {isDirectory ? <Icon type={isDirectory ? 'fm-directory' : 'fm-file'} size={16} /> : <FileIcon filename={fileName || ''} />}{' '}\r\n {isRestored && <span className={classes.newFileIndicator} />} {fileName}\r\n {hasUpdates && <i />}\r\n </div>\r\n <div className={`${classes.status} ${classes[fileAction]}`}>\r\n <i>{fileActionLabel}</i>\r\n </div>\r\n <div className={classes.fileSize}>{isDirectory ? '-' : formatBytes(file.size)}</div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className={classes.restoredFileBrowser}>\r\n <div className={classes.toolbar}>\r\n <div className={classes.toolbarLeft}>\r\n {stats && (\r\n <div className={classes.stats}>\r\n <strong>Summary: </strong> {formatNumberToK(stats.total_files)} Items {' • '}\r\n {formatBytes(stats.bytes_restored)}/{formatBytes(stats.total_bytes)}\r\n </div>\r\n )}\r\n </div>\r\n <div className={classes.toolbarRight}>\r\n <div className={classes.filters}>\r\n {(Object.keys(filters) as Array<keyof typeof filters>).map((action) => (\r\n <label key={action}>\r\n <input type=\"checkbox\" checked={filters[action]} onChange={(e) => setFilters({ ...filters, [action]: e.target.checked })} />\r\n {action === 'restored' ? 'New' : action}\r\n </label>\r\n ))}\r\n </div>\r\n <div className={classes.search}>\r\n <Icon type=\"search\" size={16} />\r\n <input type=\"text\" placeholder=\"Search in current Directory...\" value={search} onChange={(e) => setSearch(e.target.value)} />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className={classes.browserContent}>\r\n <div className={`${classes.sidebar} styled__scrollbar`}>\r\n <div className={classes.sidebarHeader}>Directories</div>\r\n {directories.map((dir) => {\r\n const parts = splitPath(dir);\r\n const dirName = parts[parts.length - 1];\r\n const depth = parts.length - 1;\r\n const isExpanded = expandedFolders.has(dir);\r\n const hasUpdates = hasUpdatedContent(dir);\r\n const hasChildren = hasSubdirectories(dir);\r\n\r\n // Only render if parent folders are expanded or if it's a root folder\r\n if (depth === 0 || isVisible(dir)) {\r\n return (\r\n <div\r\n key={dir}\r\n className={`${classes.directory} ${selectedFolder === dir ? classes.selected : ''} ${hasChildren ? '' : classes.directoryEmpty}`}\r\n style={{ paddingLeft: `${depth * 20}px` }}\r\n onClick={() => {\r\n setSelectedFolder(dir);\r\n expandParentDirectories(dir);\r\n }}\r\n >\r\n {hasChildren ? (\r\n <button\r\n className={classes.toggleButton}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n toggleFolder(dir);\r\n }}\r\n >\r\n {isExpanded ? '-' : '+'}\r\n </button>\r\n ) : (\r\n <span className={`${classes.togglePlaceholder}`} />\r\n )}\r\n <span className={classes.dirName}>\r\n <Icon type={'fm-directory'} size={14} /> {dirName}\r\n {hasUpdates && <span className={classes.notification} />}\r\n </span>\r\n </div>\r\n );\r\n }\r\n return null;\r\n })}\r\n </div>\r\n\r\n <div className={classes.content}>\r\n <div className={classes.fileList}>\r\n <div className={classes.header}>\r\n <div>Name</div>\r\n <div>Status</div>\r\n <div>Size</div>\r\n </div>\r\n {selectedFolder && totalItems > 0 ? (\r\n <List\r\n height={window.innerHeight - (isPreview ? 370 : 250)}\r\n itemCount={totalItems}\r\n itemSize={ITEM_HEIGHT}\r\n width=\"100%\"\r\n className={`${classes.fileListVirtualized} styled__scrollbar`}\r\n >\r\n {FileRow}\r\n </List>\r\n ) : (\r\n <div className={classes.fileListEmpty}>Select a folder from the left to browse its content</div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default RestoredFileBrowser;\r\n"],"names":["isMobileDevice","isMobile","ITEM_HEIGHT","RestoredFileBrowser","files","stats","isPreview","selectedFolder","setSelectedFolder","useState","search","setSearch","filters","setFilters","expandedFolders","setExpandedFolders","allPaths","file","separator","getPathSeparator","parts","splitPath","currentPath","part","index","fileSystem","useMemo","system","matchesSearch","matchesFilter","dirPath","getParentPath","normalizedDirPath","normalizePath","directories","dirs","useEffect","hasSubdirectories","dir","d","hasUpdatedContent","path","f","expandParentDirectories","newExpanded","toggleFolder","isVisible","parentParts","parentPath","sortedFiles","a","b","normalizedPathA","normalizedPathB","isDirectoryA","isDirectoryB","priority","showGoUpButton","totalItems","FileRow","style","jsxs","classes","normalizedParentPath","jsx","fileIndex","fileName","normalizedPath","isDirectory","hasUpdates","fileAction","isRestored","fileActionLabel","Icon","FileIcon","formatBytes","formatNumberToK","action","e","dirName","depth","isExpanded","hasChildren","List"],"mappings":";;;;;;;;AAeA,MAAMA,IAAiBC,EAAA,GACjBC,IAAcF,IAAiB,KAAK,IAEpCG,KAAsB,CAAC,EAAE,OAAAC,GAAO,OAAAC,GAAO,WAAAC,IAAY,SAAsC;AAC5F,QAAM,CAACC,GAAgBC,CAAiB,IAAIC,EAAiB,EAAE,GACzD,CAACC,GAAQC,CAAS,IAAIF,EAAS,EAAE,GACjC,CAACG,GAASC,CAAU,IAAIJ,EAAS;AAAA,IACpC,WAAW;AAAA,IACX,UAAU;AAAA,IACV,SAAS;AAAA,EAAA,CACX,GAEK,CAACK,GAAiBC,CAAkB,IAAIN,EAAsB,MAAM;AACvE,UAAMO,wBAAe,IAAA;AACrB,WAAAZ,EAAM,QAAQ,CAACa,MAAS;AACrB,YAAMC,IAAYC,EAAiBF,EAAK,IAAI,GACtCG,IAAQC,EAAUJ,EAAK,IAAI;AACjC,UAAIK,IAAc;AAElB,MAAAF,EAAM,QAAQ,CAACG,GAAMC,MAAU;AAC5B,QAAAF,IAAcA,IAAc,GAAGA,CAAW,GAAGJ,CAAS,GAAGK,CAAI,KAAKA,GAE9DC,IAAQ,KACTR,EAAS,IAAIM,CAAW;AAAA,MAE9B,CAAC;AAAA,IACJ,CAAC,GACMN;AAAA,EACV,CAAC,GAEKS,IAAaC,EAAQ,MAAM;AAC9B,UAAMC,IAAgD,CAAA;AAEtD,WAAAvB,EACI,OAAO,CAACa,MAAS;AACf,YAAMW,IAAgBX,EAAK,KAAK,YAAA,EAAc,SAASP,EAAO,aAAa,GACrEmB,IAAgBjB,EAAQK,EAAK,MAAM;AACzC,aAAOW,KAAiBC;AAAA,IAC3B,CAAC,EACA,QAAQ,CAACZ,MAAS;AAChB,YAAMa,IAAUC,EAAcd,EAAK,IAAI,GAEjCe,IAAoBC,EAAcH,CAAO;AAE/C,MAAIE,MACIL,EAAOK,CAAiB,MAC1BL,EAAOK,CAAiB,IAAI,CAAA,IAE/BL,EAAOK,CAAiB,EAAE,KAAKf,CAAI;AAAA,IAEzC,CAAC,GAEGU;AAAA,EACV,GAAG,CAACvB,GAAOM,GAAQE,CAAO,CAAC,GAErBsB,IAAcR,EAAQ,MAAM;AAC/B,UAAMS,wBAAW,IAAA;AAEjB,WAAA/B,EAAM,QAAQ,CAACa,MAAS;AACrB,YAAMa,IAAUC,EAAcd,EAAK,IAAI,GACjCC,IAAYC,EAAiBW,CAAO,GACpCV,IAAQC,EAAUS,CAAO;AAC/B,UAAIR,IAAc;AAElB,MAAAF,EAAM,QAAQ,CAACG,MAAS;AACrB,QAAAD,IAAcA,IAAc,GAAGA,CAAW,GAAGJ,CAAS,GAAGK,CAAI,KAAKA,GAC9DD,KACDa,EAAK,IAAIb,CAAW;AAAA,MAE1B,CAAC;AAAA,IACJ,CAAC,GACM,MAAM,KAAKa,CAAI;AAAA,EACzB,GAAG,CAAC/B,CAAK,CAAC;AAGV,EAAAgC,EAAU,MAAM;AACb,IAAIF,EAAY,SAAS,KAAK3B,MAAmB,MAC9CC,EAAkB0B,EAAY,CAAC,CAAC;AAAA,EAEtC,GAAG,CAACA,GAAa3B,CAAc,CAAC;AAEhC,QAAM8B,IAAoB,CAACC,MAAgB;AACxC,UAAMpB,IAAYC,EAAiBmB,CAAG;AACtC,WAAOJ,EAAY,KAAK,CAACK,MAAMA,MAAMD,KAAOC,EAAE,WAAWD,IAAMpB,CAAS,CAAC;AAAA,EAC5E,GAEMsB,IAAoB,CAACF,MACjB,OAAO,QAAQb,CAAU,EAAE,KAAK,CAAC,CAACgB,GAAMrC,CAAK,MAC1CqC,EAAK,WAAWH,CAAG,KAAKlC,EAAM,KAAK,CAACsC,MAAMA,EAAE,WAAW,cAAcA,EAAE,WAAW,SAAS,CACpG,GAGEC,IAA0B,CAACL,MAAgB;AAC9C,UAAMM,IAAc,IAAI,IAAI9B,CAAe,GACrCI,IAAYC,EAAiBmB,CAAG,GAChClB,IAAQC,EAAUiB,CAAG;AAC3B,QAAIhB,IAAc;AAGlB,IAAAF,EAAM,QAAQ,CAACG,GAAMC,MAAU;AAC5B,MAAAF,IAAcA,IAAc,GAAGA,CAAW,GAAGJ,CAAS,GAAGK,CAAI,KAAKA,GAC9DC,IAAQJ,EAAM,SAAS,KAExBwB,EAAY,IAAItB,CAAW;AAAA,IAEjC,CAAC,GAEDP,EAAmB6B,CAAW;AAAA,EACjC,GAEMC,IAAe,CAACP,MAAgB;AACnC,UAAMM,IAAc,IAAI,IAAI9B,CAAe;AAC3C,IAAIA,EAAgB,IAAIwB,CAAG,IACxBM,EAAY,OAAON,CAAG,IAEtBM,EAAY,IAAIN,CAAG,GAEtBvB,EAAmB6B,CAAW;AAAA,EACjC,GAEME,IAAY,CAACR,MAAgB;AAChC,UAAMpB,IAAYC,EAAiBmB,CAAG,GAEhCS,IADQ1B,EAAUiB,CAAG,EACD,MAAM,GAAG,EAAE;AACrC,QAAIU,IAAa;AAGjB,WAAOD,EAAY,MAAM,CAACxB,OACvByB,IAAaA,IAAa,GAAGA,CAAU,GAAG9B,CAAS,GAAGK,CAAI,KAAKA,GACxDT,EAAgB,IAAIkC,CAAU,EACvC;AAAA,EACJ,GAEMC,IAAcvB,EAAQ,MACrB,CAACnB,KAAkB,CAACkB,EAAWlB,CAAc,IAAU,CAAA,IAEpDkB,EAAWlB,CAAc,EAAE,KAAK,CAAC2C,GAAGC,MAAM;AAC9C,UAAMC,IAAkBnB,EAAciB,EAAE,IAAI,GACtCG,IAAkBpB,EAAckB,EAAE,IAAI,GACtCG,IAAepB,EAAY,SAASkB,CAAe,GACnDG,IAAerB,EAAY,SAASmB,CAAe;AAGzD,QAAIC,KAAgB,CAACC,EAAc,QAAO;AAC1C,QAAI,CAACD,KAAgBC,EAAc,QAAO;AAG1C,UAAMC,IAAW,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,EAAA;AACvD,WAAOA,EAASN,EAAE,MAAM,IAAIM,EAASL,EAAE,MAAM;AAAA,EAChD,CAAC,GACD,CAAC5C,GAAgBkB,GAAYS,CAAW,CAAC,GAEtCuB,IAAiBlD,KAAkBwB,EAAcxB,CAAc,MAAMA,KAAkBA,MAAmB,MAAMA,MAAmB,KACnImD,IAAaT,EAAY,UAAUQ,IAAiB,IAAI,IAExDE,IAAU,CAAC,EAAE,OAAAnC,GAAO,OAAAoC,QAA2D;AAElF,QAAIH,KAAkBjC,MAAU;AAC7B,aACG,gBAAAqC;AAAA,QAAC;AAAA,QAAA;AAAA,UACE,OAAAD;AAAA,UACA,WAAW,GAAGE,EAAQ,IAAI,IAAIA,EAAQ,SAAS,IAAIA,EAAQ,UAAU;AAAA,UACrE,SAAS,MAAM;AACZ,kBAAMd,IAAajB,EAAcxB,CAAc,GACzCwD,IAAuB9B,EAAce,CAAU;AAErD,YADA,QAAQ,IAAI,0BAA0Be,CAAoB,GACtD,GAACA,KAAwBA,MAAyB,QACtDpB,EAAwBoB,CAAoB,GAC5CvD,EAAkBuD,CAAoB;AAAA,UACzC;AAAA,UAEA,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWF,EAAQ,UAAU,UAAA,OAAG;AAAA,YACrC,gBAAAE,EAAC,OAAA,EAAI,WAAWF,EAAQ,OAAA,CAAQ;AAAA,8BAC/B,OAAA,CAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAKd,UAAMG,IAAYR,IAAiBjC,IAAQ,IAAIA,GACzCP,IAAOgC,EAAYgB,CAAS;AAElC,QAAI,CAAChD,EAAM,QAAO;AAElB,UAAMG,IAAQC,EAAUJ,EAAK,IAAI,GAC3BiD,IAAW9C,EAAMA,EAAM,SAAS,CAAC,GACjC+C,IAAiBlC,EAAchB,EAAK,IAAI,GACxCmD,IAAclC,EAAY,SAASiC,CAAc,GACjDE,IAAa7B,EAAkB2B,CAAc,GAC7CG,IAAarD,EAAK,QAClBsD,IAAatD,EAAK,WAAW,YAC7BuD,IAAkBD,IAAa,QAAQtD,EAAK;AAElD,WACG,gBAAA4C;AAAA,MAAC;AAAA,MAAA;AAAA,QACE,OAAAD;AAAA,QACA,WAAW,GAAGE,EAAQ,IAAI,IAAIM,IAAcN,EAAQ,YAAY,EAAE;AAAA,QAClE,SAAS,MAAM;AACZ,UAAIM,MACD5D,EAAkB2D,CAAc,GAChCxB,EAAwBwB,CAAc;AAAA,QAE5C;AAAA,QAEA,UAAA;AAAA,UAAA,gBAAAN,EAAC,OAAA,EAAI,WAAWC,EAAQ,UACpB,UAAA;AAAA,YAAAM,IAAc,gBAAAJ,EAACS,GAAA,EAAK,MAAML,IAAc,iBAAiB,WAAW,MAAM,GAAA,CAAI,IAAK,gBAAAJ,EAACU,GAAA,EAAS,UAAUR,KAAY,IAAI;AAAA,YAAI;AAAA,YAC3HK,KAAc,gBAAAP,EAAC,QAAA,EAAK,WAAWF,EAAQ,kBAAkB;AAAA,YAAG;AAAA,YAAEI;AAAA,YAC9DG,uBAAe,KAAA,CAAA,CAAE;AAAA,UAAA,GACrB;AAAA,UACA,gBAAAL,EAAC,OAAA,EAAI,WAAW,GAAGF,EAAQ,MAAM,IAAIA,EAAQQ,CAAU,CAAC,IACrD,UAAA,gBAAAN,EAAC,KAAA,EAAG,aAAgB,GACvB;AAAA,UACA,gBAAAA,EAAC,OAAA,EAAI,WAAWF,EAAQ,UAAW,cAAc,MAAMa,EAAY1D,EAAK,IAAI,EAAA,CAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGvF;AAEA,SACG,gBAAA4C,EAAC,OAAA,EAAI,WAAWC,EAAQ,qBACrB,UAAA;AAAA,IAAA,gBAAAD,EAAC,OAAA,EAAI,WAAWC,EAAQ,SACrB,UAAA;AAAA,MAAA,gBAAAE,EAAC,OAAA,EAAI,WAAWF,EAAQ,aACpB,eACE,gBAAAD,EAAC,OAAA,EAAI,WAAWC,EAAQ,OACrB,UAAA;AAAA,QAAA,gBAAAE,EAAC,YAAO,UAAA,YAAA,CAAS;AAAA,QAAS;AAAA,QAAEY,EAAgBvE,EAAM,WAAW;AAAA,QAAE;AAAA,QAAQ;AAAA,QACtEsE,EAAYtE,EAAM,cAAc;AAAA,QAAE;AAAA,QAAEsE,EAAYtE,EAAM,WAAW;AAAA,MAAA,EAAA,CACrE,EAAA,CAEN;AAAA,MACA,gBAAAwD,EAAC,OAAA,EAAI,WAAWC,EAAQ,cACrB,UAAA;AAAA,QAAA,gBAAAE,EAAC,OAAA,EAAI,WAAWF,EAAQ,SACnB,UAAA,OAAO,KAAKlD,CAAO,EAAkC,IAAI,CAACiE,MACzD,gBAAAhB,EAAC,SAAA,EACE,UAAA;AAAA,UAAA,gBAAAG,EAAC,SAAA,EAAM,MAAK,YAAW,SAASpD,EAAQiE,CAAM,GAAG,UAAU,CAACC,MAAMjE,EAAW,EAAE,GAAGD,GAAS,CAACiE,CAAM,GAAGC,EAAE,OAAO,QAAA,CAAS,GAAG;AAAA,UACzHD,MAAW,aAAa,QAAQA;AAAA,QAAA,KAFxBA,CAGZ,CACF,GACJ;AAAA,QACA,gBAAAhB,EAAC,OAAA,EAAI,WAAWC,EAAQ,QACrB,UAAA;AAAA,UAAA,gBAAAE,EAACS,GAAA,EAAK,MAAK,UAAS,MAAM,IAAI;AAAA,UAC9B,gBAAAT,EAAC,SAAA,EAAM,MAAK,QAAO,aAAY,kCAAiC,OAAOtD,GAAQ,UAAU,CAAC,MAAMC,EAAU,EAAE,OAAO,KAAK,EAAA,CAAG;AAAA,QAAA,EAAA,CAC9H;AAAA,MAAA,EAAA,CACH;AAAA,IAAA,GACH;AAAA,IAEA,gBAAAkD,EAAC,OAAA,EAAI,WAAWC,EAAQ,gBACrB,UAAA;AAAA,MAAA,gBAAAD,EAAC,OAAA,EAAI,WAAW,GAAGC,EAAQ,OAAO,sBAC/B,UAAA;AAAA,QAAA,gBAAAE,EAAC,OAAA,EAAI,WAAWF,EAAQ,eAAe,UAAA,eAAW;AAAA,QACjD5B,EAAY,IAAI,CAACI,MAAQ;AACvB,gBAAMlB,IAAQC,EAAUiB,CAAG,GACrByC,IAAU3D,EAAMA,EAAM,SAAS,CAAC,GAChC4D,IAAQ5D,EAAM,SAAS,GACvB6D,IAAanE,EAAgB,IAAIwB,CAAG,GACpC+B,IAAa7B,EAAkBF,CAAG,GAClC4C,IAAc7C,EAAkBC,CAAG;AAGzC,iBAAI0C,MAAU,KAAKlC,EAAUR,CAAG,IAE1B,gBAAAuB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEE,WAAW,GAAGC,EAAQ,SAAS,IAAIvD,MAAmB+B,IAAMwB,EAAQ,WAAW,EAAE,IAAIoB,IAAc,KAAKpB,EAAQ,cAAc;AAAA,cAC9H,OAAO,EAAE,aAAa,GAAGkB,IAAQ,EAAE,KAAA;AAAA,cACnC,SAAS,MAAM;AACZ,gBAAAxE,EAAkB8B,CAAG,GACrBK,EAAwBL,CAAG;AAAA,cAC9B;AAAA,cAEC,UAAA;AAAA,gBAAA4C,IACE,gBAAAlB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACE,WAAWF,EAAQ;AAAA,oBACnB,SAAS,CAACgB,MAAM;AACb,sBAAAA,EAAE,gBAAA,GACFjC,EAAaP,CAAG;AAAA,oBACnB;AAAA,oBAEC,cAAa,MAAM;AAAA,kBAAA;AAAA,gBAAA,IAGvB,gBAAA0B,EAAC,QAAA,EAAK,WAAW,GAAGF,EAAQ,iBAAiB,IAAI;AAAA,gBAEpD,gBAAAD,EAAC,QAAA,EAAK,WAAWC,EAAQ,SACtB,UAAA;AAAA,kBAAA,gBAAAE,EAACS,GAAA,EAAK,MAAM,gBAAgB,MAAM,IAAI;AAAA,kBAAE;AAAA,kBAAEM;AAAA,kBACzCV,KAAc,gBAAAL,EAAC,QAAA,EAAK,WAAWF,EAAQ,aAAA,CAAc;AAAA,gBAAA,EAAA,CACzD;AAAA,cAAA;AAAA,YAAA;AAAA,YAxBKxB;AAAA,UAAA,IA4BP;AAAA,QACV,CAAC;AAAA,MAAA,GACJ;AAAA,MAEA,gBAAA0B,EAAC,SAAI,WAAWF,EAAQ,SACrB,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAWC,EAAQ,UACrB,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAWC,EAAQ,QACrB,UAAA;AAAA,UAAA,gBAAAE,EAAC,SAAI,UAAA,OAAA,CAAI;AAAA,UACT,gBAAAA,EAAC,SAAI,UAAA,SAAA,CAAM;AAAA,UACX,gBAAAA,EAAC,SAAI,UAAA,OAAA,CAAI;AAAA,QAAA,GACZ;AAAA,QACCzD,KAAkBmD,IAAa,IAC7B,gBAAAM;AAAA,UAACmB;AAAAA,UAAA;AAAA,YACE,QAAQ,OAAO,eAAe7E,IAAY,MAAM;AAAA,YAChD,WAAWoD;AAAA,YACX,UAAUxD;AAAA,YACV,OAAM;AAAA,YACN,WAAW,GAAG4D,EAAQ,mBAAmB;AAAA,YAExC,UAAAH;AAAA,UAAA;AAAA,QAAA,IAGJ,gBAAAK,EAAC,OAAA,EAAI,WAAWF,EAAQ,eAAe,UAAA,sDAAA,CAAmD;AAAA,MAAA,EAAA,CAEhG,EAAA,CACH;AAAA,IAAA,EAAA,CACH;AAAA,EAAA,GACH;AAEN;"}
1
+ {"version":3,"file":"RestoredFileBrowser.js","sources":["../../../../src/components/Restore/RestoredFileBrowser/RestoredFileBrowser.tsx"],"sourcesContent":["import { useState, useMemo, useEffect } from 'react';\r\nimport Icon from '../../common/Icon/Icon';\r\nimport FileIcon from '../../common/FileIcon/FileIcon';\r\nimport classes from './RestoredFileBrowser.module.scss';\r\nimport { RestoredFileItem, RestoredItemsStats } from '../../../@types/restores';\r\nimport { formatBytes, formatNumberToK, isMobile } from '../../../utils/helpers';\r\nimport { getParentPath, getPathSeparator, normalizePath, splitPath } from '../../../utils/restore';\r\nimport { SnapshotBrowserToolbar, SnapshotBrowserDirectories, SnapshotBrowserFileList, SnapshotBrowserGoUpRow } from '../../common/SnapshotBrowser';\r\nimport { useSnapshotNavigation } from '../../common/SnapshotBrowser/hooks/useSnapshotNavigation';\r\nimport sbClasses from '../../common/SnapshotBrowser/SnapshotBrowser.module.scss';\r\n\r\ninterface RestoredFileBrowserProps {\r\n files: RestoredFileItem[];\r\n stats?: RestoredItemsStats;\r\n isPreview?: boolean;\r\n}\r\n\r\nconst isMobileDevice = isMobile();\r\nconst ITEM_HEIGHT = isMobileDevice ? 65 : 45;\r\nconst GRID_COLUMNS = '1fr 100px minmax(80px, auto)';\r\n\r\nconst RestoredFileBrowser = ({ files, stats, isPreview = false }: RestoredFileBrowserProps) => {\r\n const [search, setSearch] = useState('');\r\n const [filters, setFilters] = useState({\r\n unchanged: true,\r\n restored: true,\r\n updated: true,\r\n });\r\n\r\n const [expandedFolders, setExpandedFolders] = useState<Set<string>>(() => {\r\n const allPaths = new Set<string>();\r\n files.forEach((file) => {\r\n const separator = getPathSeparator(file.path);\r\n const parts = splitPath(file.path);\r\n let currentPath = '';\r\n\r\n parts.forEach((part, index) => {\r\n currentPath = currentPath ? `${currentPath}${separator}${part}` : part;\r\n if (index < 3) {\r\n allPaths.add(currentPath);\r\n }\r\n });\r\n });\r\n return allPaths;\r\n });\r\n\r\n const fileSystem = useMemo(() => {\r\n const system: { [key: string]: RestoredFileItem[] } = {};\r\n\r\n files\r\n .filter((file) => {\r\n const matchesSearch = file.path.toLowerCase().includes(search.toLowerCase());\r\n const matchesFilter = filters[file.action];\r\n return matchesSearch && matchesFilter;\r\n })\r\n .forEach((file) => {\r\n const dirPath = getParentPath(file.path);\r\n const normalizedDirPath = normalizePath(dirPath);\r\n\r\n if (normalizedDirPath) {\r\n if (!system[normalizedDirPath]) {\r\n system[normalizedDirPath] = [];\r\n }\r\n system[normalizedDirPath].push(file);\r\n }\r\n });\r\n\r\n return system;\r\n }, [files, search, filters]);\r\n\r\n const directories = useMemo(() => {\r\n const dirs = new Set<string>();\r\n files.forEach((file) => {\r\n const dirPath = getParentPath(file.path);\r\n const separator = getPathSeparator(dirPath);\r\n const parts = splitPath(dirPath);\r\n let currentPath = '';\r\n\r\n parts.forEach((part) => {\r\n currentPath = currentPath ? `${currentPath}${separator}${part}` : part;\r\n if (currentPath) {\r\n dirs.add(currentPath);\r\n }\r\n });\r\n });\r\n return Array.from(dirs);\r\n }, [files]);\r\n\r\n const { selectedFolder, setSelectedFolder, hasSubdirectories, isVisible, expandParentFolders, toggleFolder } = useSnapshotNavigation(\r\n directories,\r\n expandedFolders,\r\n setExpandedFolders,\r\n { splitPath, getPathSeparator, hasLeadingSeparator: false },\r\n );\r\n\r\n useEffect(() => {\r\n if (directories.length > 0 && selectedFolder === '') {\r\n setSelectedFolder(directories[0]);\r\n }\r\n }, [directories, selectedFolder, setSelectedFolder]);\r\n\r\n const hasUpdatedContent = (dir: string) => {\r\n return Object.entries(fileSystem).some(([path, dirFiles]) => {\r\n return path.startsWith(dir) && dirFiles.some((f) => f.action === 'restored' || f.action === 'updated');\r\n });\r\n };\r\n\r\n const sortedFiles = useMemo(() => {\r\n if (!selectedFolder || !fileSystem[selectedFolder]) return [];\r\n\r\n return fileSystem[selectedFolder].sort((a, b) => {\r\n const normalizedPathA = normalizePath(a.path);\r\n const normalizedPathB = normalizePath(b.path);\r\n const isDirectoryA = directories.includes(normalizedPathA);\r\n const isDirectoryB = directories.includes(normalizedPathB);\r\n\r\n if (isDirectoryA && !isDirectoryB) return -1;\r\n if (!isDirectoryA && isDirectoryB) return 1;\r\n\r\n const priority = { restored: 0, updated: 1, unchanged: 2 };\r\n return priority[a.action] - priority[b.action];\r\n });\r\n }, [selectedFolder, fileSystem, directories]);\r\n\r\n const showGoUpButton = selectedFolder && getParentPath(selectedFolder) !== selectedFolder && selectedFolder !== '' && selectedFolder !== '/';\r\n const totalItems = sortedFiles.length + (showGoUpButton ? 1 : 0);\r\n\r\n const FileRow = ({ index, style }: { index: number; style: React.CSSProperties }) => {\r\n if (showGoUpButton && index === 0) {\r\n return (\r\n <SnapshotBrowserGoUpRow\r\n style={style}\r\n onGoUp={() => {\r\n const parentPath = getParentPath(selectedFolder);\r\n const normalizedParentPath = normalizePath(parentPath);\r\n if (!normalizedParentPath || normalizedParentPath === '') return;\r\n expandParentFolders(normalizedParentPath);\r\n setSelectedFolder(normalizedParentPath);\r\n }}\r\n gridTemplateColumns={GRID_COLUMNS}\r\n />\r\n );\r\n }\r\n\r\n const fileIndex = showGoUpButton ? index - 1 : index;\r\n const file = sortedFiles[fileIndex];\r\n\r\n if (!file) return null;\r\n\r\n const parts = splitPath(file.path);\r\n const fileName = parts[parts.length - 1];\r\n const normalizedPath = normalizePath(file.path);\r\n const isDirectory = directories.includes(normalizedPath);\r\n const hasUpdates = hasUpdatedContent(normalizedPath);\r\n const fileAction = file.action;\r\n const isRestored = file.action === 'restored';\r\n const fileActionLabel = isRestored ? 'New' : file.action;\r\n\r\n return (\r\n <div\r\n style={{ ...style, gridTemplateColumns: GRID_COLUMNS }}\r\n className={`${sbClasses.snapshotFile} ${isDirectory ? sbClasses.fileIsDir : ''}`}\r\n onClick={() => {\r\n if (isDirectory) {\r\n setSelectedFolder(normalizedPath);\r\n expandParentFolders(normalizedPath);\r\n }\r\n }}\r\n >\r\n <div className={sbClasses.fileName}>\r\n {isDirectory ? <Icon type={'fm-directory'} size={16} /> : <FileIcon filename={fileName || ''} />}{' '}\r\n {isRestored && <span className={classes.newFileIndicator} />} {fileName}\r\n {hasUpdates && <i />}\r\n </div>\r\n <div className={`${classes.status} ${classes[fileAction]}`}>\r\n <i>{fileActionLabel}</i>\r\n </div>\r\n <div className={classes.fileSize}>{isDirectory ? '-' : formatBytes(file.size)}</div>\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className={sbClasses.snapshotBrowser}>\r\n <SnapshotBrowserToolbar\r\n search={search}\r\n onSearchChange={setSearch}\r\n leftContent={\r\n stats && (\r\n <div className={sbClasses.stats}>\r\n <strong>Summary: </strong> {formatNumberToK(stats.total_files)} Items {' • '}\r\n {formatBytes(stats.bytes_restored)}/{formatBytes(stats.total_bytes)}\r\n </div>\r\n )\r\n }\r\n rightContent={\r\n <div className={classes.filters}>\r\n {(Object.keys(filters) as Array<keyof typeof filters>).map((action) => (\r\n <label key={action}>\r\n <input type=\"checkbox\" checked={filters[action]} onChange={(e) => setFilters({ ...filters, [action]: e.target.checked })} />\r\n {action === 'restored' ? 'New' : action}\r\n </label>\r\n ))}\r\n </div>\r\n }\r\n />\r\n\r\n <div className={sbClasses.browserContent}>\r\n <SnapshotBrowserDirectories\r\n directories={directories}\r\n selectedFolder={selectedFolder}\r\n expandedFolders={expandedFolders}\r\n onDirectoryClick={(dir) => {\r\n setSelectedFolder(dir);\r\n expandParentFolders(dir);\r\n }}\r\n onToggleFolder={toggleFolder}\r\n isVisible={isVisible}\r\n hasSubdirectories={hasSubdirectories}\r\n renderDirectoryExtra={(dir) => {\r\n const hasUpdates = hasUpdatedContent(dir);\r\n return hasUpdates ? <span className={classes.notification} /> : null;\r\n }}\r\n />\r\n\r\n <div className={sbClasses.content}>\r\n <SnapshotBrowserFileList\r\n files={Array(totalItems)}\r\n height={window.innerHeight - (isPreview ? 370 : 250)}\r\n itemSize={ITEM_HEIGHT}\r\n headerContent={\r\n <>\r\n <div>Name</div>\r\n <div>Status</div>\r\n <div>Size</div>\r\n </>\r\n }\r\n renderRow={FileRow}\r\n selectedFolder={selectedFolder || null}\r\n gridTemplateColumns={GRID_COLUMNS}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default RestoredFileBrowser;\r\n"],"names":["isMobileDevice","isMobile","ITEM_HEIGHT","GRID_COLUMNS","RestoredFileBrowser","files","stats","isPreview","search","setSearch","useState","filters","setFilters","expandedFolders","setExpandedFolders","allPaths","file","separator","getPathSeparator","parts","splitPath","currentPath","part","index","fileSystem","useMemo","system","matchesSearch","matchesFilter","dirPath","getParentPath","normalizedDirPath","normalizePath","directories","dirs","selectedFolder","setSelectedFolder","hasSubdirectories","isVisible","expandParentFolders","toggleFolder","useSnapshotNavigation","useEffect","hasUpdatedContent","dir","path","dirFiles","f","sortedFiles","a","b","normalizedPathA","normalizedPathB","isDirectoryA","isDirectoryB","priority","showGoUpButton","totalItems","FileRow","style","jsx","SnapshotBrowserGoUpRow","parentPath","normalizedParentPath","fileIndex","fileName","normalizedPath","isDirectory","hasUpdates","fileAction","isRestored","fileActionLabel","jsxs","sbClasses","Icon","FileIcon","classes","formatBytes","SnapshotBrowserToolbar","formatNumberToK","action","e","SnapshotBrowserDirectories","SnapshotBrowserFileList","Fragment"],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ const t = "_snapshotBrowser_wLZ6H", e = "_storageSelect_x5Y34", o = "_toolbar_8CUgH", s = "_toolbarRight_d5DNW", r = "_search_uTjHh", i = "_toolbarLeft_lzMER", a = "_stats_uNive", n = "_browserContent_7EKnV", l = "_loadingState_UrPuT", c = "_sidebar_Dwr4Y", _ = "_sidebarHeader_HSjGb", d = "_noDirectories_xpBll", f = "_directory_j1rhT", g = "_toggleButton_1D4RS", h = "_togglePlaceholder_z6AXP", b = "_dirName_jZCs4", p = "_directoryEmpty_SgiKx", S = "_selected_r7Mw7", u = "_content_wUpVw", y = "_fileList_xL0re", L = "_header_I04uE", m = "_activeSort_Yp9aa", w = "_headerActions_uZpzN", A = "_fileListEmpty_GKzxO", E = "_virtualFileList_xTzAQ", F = "_snapshotFile_TRFxD", N = "_fileIsDir_p0G1c", x = "_fileName_Neb7E", B = "_fileModifiedAt_S6CoI", D = "_fileSize_x6NTv", v = "_fileActions_tyxE6", z = "_goUpButton_gK1aV", M = "_errorState_u2XFr", C = "_restoreModalFile_tuyR4", H = {
2
+ snapshotBrowser: t,
3
+ storageSelect: e,
4
+ toolbar: o,
5
+ toolbarRight: s,
6
+ search: r,
7
+ toolbarLeft: i,
8
+ stats: a,
9
+ browserContent: n,
10
+ loadingState: l,
11
+ sidebar: c,
12
+ sidebarHeader: _,
13
+ noDirectories: d,
14
+ directory: f,
15
+ toggleButton: g,
16
+ togglePlaceholder: h,
17
+ dirName: b,
18
+ directoryEmpty: p,
19
+ selected: S,
20
+ content: u,
21
+ fileList: y,
22
+ header: L,
23
+ activeSort: m,
24
+ headerActions: w,
25
+ fileListEmpty: A,
26
+ virtualFileList: E,
27
+ snapshotFile: F,
28
+ fileIsDir: N,
29
+ fileName: x,
30
+ fileModifiedAt: B,
31
+ fileSize: D,
32
+ fileActions: v,
33
+ goUpButton: z,
34
+ errorState: M,
35
+ restoreModalFile: C
36
+ };
37
+ export {
38
+ m as activeSort,
39
+ n as browserContent,
40
+ u as content,
41
+ H as default,
42
+ b as dirName,
43
+ f as directory,
44
+ p as directoryEmpty,
45
+ M as errorState,
46
+ v as fileActions,
47
+ N as fileIsDir,
48
+ y as fileList,
49
+ A as fileListEmpty,
50
+ B as fileModifiedAt,
51
+ x as fileName,
52
+ D as fileSize,
53
+ z as goUpButton,
54
+ L as header,
55
+ w as headerActions,
56
+ l as loadingState,
57
+ d as noDirectories,
58
+ C as restoreModalFile,
59
+ r as search,
60
+ S as selected,
61
+ c as sidebar,
62
+ _ as sidebarHeader,
63
+ t as snapshotBrowser,
64
+ F as snapshotFile,
65
+ a as stats,
66
+ e as storageSelect,
67
+ g as toggleButton,
68
+ h as togglePlaceholder,
69
+ o as toolbar,
70
+ i as toolbarLeft,
71
+ s as toolbarRight,
72
+ E as virtualFileList
73
+ };
74
+ //# sourceMappingURL=SnapshotBrowser.module.scss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowser.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,17 @@
1
+ import { ReactNode } from 'react';
2
+ interface SnapshotBrowserDirectoriesProps {
3
+ directories: string[];
4
+ selectedFolder: string;
5
+ expandedFolders: Set<string>;
6
+ useProgressiveLoading?: boolean;
7
+ onDirectoryClick: (path: string) => void;
8
+ onToggleFolder: (dir: string) => void;
9
+ isVisible: (dir: string) => boolean;
10
+ hasSubdirectories: (dir: string) => boolean;
11
+ renderDirectoryExtra?: (dir: string) => ReactNode;
12
+ /** Custom function to split a path into parts. Defaults to splitting by / and \ */
13
+ splitPath?: (path: string) => string[];
14
+ }
15
+ declare const SnapshotBrowserDirectories: ({ directories, selectedFolder, expandedFolders, useProgressiveLoading, onDirectoryClick, onToggleFolder, isVisible, hasSubdirectories, renderDirectoryExtra, splitPath: splitPathFn, }: SnapshotBrowserDirectoriesProps) => import("react/jsx-runtime").JSX.Element;
16
+ export default SnapshotBrowserDirectories;
17
+ //# sourceMappingURL=SnapshotBrowserDirectories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserDirectories.d.ts","sourceRoot":"","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserDirectories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlC,UAAU,+BAA+B;IACtC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IAClD,mFAAmF;IACnF,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;CACzC;AAID,QAAA,MAAM,0BAA0B,GAAI,wLAWjC,+BAA+B,4CAkDjC,CAAC;AAEF,eAAe,0BAA0B,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { jsxs as a, jsx as l } from "react/jsx-runtime";
2
+ import C from "../Icon/Icon.js";
3
+ import e from "./SnapshotBrowser.module.scss.js";
4
+ const v = (t) => t.split(/[/\\]/).filter(Boolean), j = ({
5
+ directories: t,
6
+ selectedFolder: h,
7
+ expandedFolders: p,
8
+ useProgressiveLoading: c,
9
+ onDirectoryClick: d,
10
+ onToggleFolder: m,
11
+ isVisible: r,
12
+ hasSubdirectories: f,
13
+ renderDirectoryExtra: o,
14
+ splitPath: N = v
15
+ }) => /* @__PURE__ */ a("div", { className: `${e.sidebar} styled__scrollbar`, children: [
16
+ /* @__PURE__ */ l("div", { className: e.sidebarHeader, children: /* @__PURE__ */ a("h4", { children: [
17
+ "Directories (",
18
+ t.length,
19
+ c && "+",
20
+ ")"
21
+ ] }) }),
22
+ t.length === 0 && /* @__PURE__ */ l("div", { className: e.noDirectories, children: c ? "Loading directories..." : "No directories found" }),
23
+ t.map((s) => {
24
+ const n = N(s), g = n[n.length - 1] || s, u = n.length - 1, b = p.has(s), i = f(s);
25
+ return r(s) ? /* @__PURE__ */ a(
26
+ "div",
27
+ {
28
+ className: `${e.directory} ${h === s ? e.selected : ""} ${i ? "" : e.directoryEmpty}`,
29
+ style: { paddingLeft: `${u * 20}px` },
30
+ onClick: () => d(s),
31
+ children: [
32
+ i ? /* @__PURE__ */ l(
33
+ "button",
34
+ {
35
+ className: e.toggleButton,
36
+ onClick: ($) => {
37
+ $.stopPropagation(), m(s);
38
+ },
39
+ children: b ? "-" : "+"
40
+ }
41
+ ) : /* @__PURE__ */ l("span", { className: e.togglePlaceholder }),
42
+ /* @__PURE__ */ a("span", { className: e.dirName, children: [
43
+ /* @__PURE__ */ l(C, { type: "fm-directory", size: 14 }),
44
+ " ",
45
+ g
46
+ ] }),
47
+ o == null ? void 0 : o(s)
48
+ ]
49
+ },
50
+ s
51
+ ) : null;
52
+ })
53
+ ] });
54
+ export {
55
+ j as default
56
+ };
57
+ //# sourceMappingURL=SnapshotBrowserDirectories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserDirectories.js","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserDirectories.tsx"],"sourcesContent":["import { ReactNode } from 'react';\r\nimport Icon from '../Icon/Icon';\r\nimport classes from './SnapshotBrowser.module.scss';\r\n\r\ninterface SnapshotBrowserDirectoriesProps {\r\n directories: string[];\r\n selectedFolder: string;\r\n expandedFolders: Set<string>;\r\n useProgressiveLoading?: boolean;\r\n onDirectoryClick: (path: string) => void;\r\n onToggleFolder: (dir: string) => void;\r\n isVisible: (dir: string) => boolean;\r\n hasSubdirectories: (dir: string) => boolean;\r\n renderDirectoryExtra?: (dir: string) => ReactNode;\r\n /** Custom function to split a path into parts. Defaults to splitting by / and \\ */\r\n splitPath?: (path: string) => string[];\r\n}\r\n\r\nconst defaultSplitPath = (path: string) => path.split(/[/\\\\]/).filter(Boolean);\r\n\r\nconst SnapshotBrowserDirectories = ({\r\n directories,\r\n selectedFolder,\r\n expandedFolders,\r\n useProgressiveLoading,\r\n onDirectoryClick,\r\n onToggleFolder,\r\n isVisible,\r\n hasSubdirectories,\r\n renderDirectoryExtra,\r\n splitPath: splitPathFn = defaultSplitPath,\r\n}: SnapshotBrowserDirectoriesProps) => {\r\n return (\r\n <div className={`${classes.sidebar} styled__scrollbar`}>\r\n <div className={classes.sidebarHeader}>\r\n <h4>\r\n Directories ({directories.length}\r\n {useProgressiveLoading && '+'})\r\n </h4>\r\n </div>\r\n {directories.length === 0 && (\r\n <div className={classes.noDirectories}>{useProgressiveLoading ? 'Loading directories...' : 'No directories found'}</div>\r\n )}\r\n {directories.map((dir) => {\r\n const parts = splitPathFn(dir);\r\n const dirName = parts[parts.length - 1] || dir;\r\n const depth = parts.length - 1;\r\n const isExpanded = expandedFolders.has(dir);\r\n const hasChildren = hasSubdirectories(dir);\r\n\r\n if (!isVisible(dir)) return null;\r\n\r\n return (\r\n <div\r\n key={dir}\r\n className={`${classes.directory} ${selectedFolder === dir ? classes.selected : ''} ${hasChildren ? '' : classes.directoryEmpty}`}\r\n style={{ paddingLeft: `${depth * 20}px` }}\r\n onClick={() => onDirectoryClick(dir)}\r\n >\r\n {hasChildren ? (\r\n <button\r\n className={classes.toggleButton}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n onToggleFolder(dir);\r\n }}\r\n >\r\n {isExpanded ? '-' : '+'}\r\n </button>\r\n ) : (\r\n <span className={classes.togglePlaceholder} />\r\n )}\r\n <span className={classes.dirName}>\r\n <Icon type={'fm-directory'} size={14} /> {dirName}\r\n </span>\r\n {renderDirectoryExtra?.(dir)}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n\r\nexport default SnapshotBrowserDirectories;\r\n"],"names":["defaultSplitPath","path","SnapshotBrowserDirectories","directories","selectedFolder","expandedFolders","useProgressiveLoading","onDirectoryClick","onToggleFolder","isVisible","hasSubdirectories","renderDirectoryExtra","splitPathFn","classes","jsx","dir","parts","dirName","depth","isExpanded","hasChildren","jsxs","e","Icon"],"mappings":";;;AAkBA,MAAMA,IAAmB,CAACC,MAAiBA,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,GAEvEC,IAA6B,CAAC;AAAA,EACjC,aAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,WAAWC,IAAcZ;AAC5B,wBAEO,OAAA,EAAI,WAAW,GAAGa,EAAQ,OAAO,sBAC/B,UAAA;AAAA,EAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAQ,eACrB,4BAAC,MAAA,EAAG,UAAA;AAAA,IAAA;AAAA,IACaV,EAAY;AAAA,IACzBG,KAAyB;AAAA,IAAI;AAAA,EAAA,EAAA,CACjC,EAAA,CACH;AAAA,EACCH,EAAY,WAAW,KACrB,gBAAAW,EAAC,OAAA,EAAI,WAAWD,EAAQ,eAAgB,UAAAP,IAAwB,2BAA2B,uBAAA,CAAuB;AAAA,EAEpHH,EAAY,IAAI,CAACY,MAAQ;AACvB,UAAMC,IAAQJ,EAAYG,CAAG,GACvBE,IAAUD,EAAMA,EAAM,SAAS,CAAC,KAAKD,GACrCG,IAAQF,EAAM,SAAS,GACvBG,IAAad,EAAgB,IAAIU,CAAG,GACpCK,IAAcV,EAAkBK,CAAG;AAEzC,WAAKN,EAAUM,CAAG,IAGf,gBAAAM;AAAA,MAAC;AAAA,MAAA;AAAA,QAEE,WAAW,GAAGR,EAAQ,SAAS,IAAIT,MAAmBW,IAAMF,EAAQ,WAAW,EAAE,IAAIO,IAAc,KAAKP,EAAQ,cAAc;AAAA,QAC9H,OAAO,EAAE,aAAa,GAAGK,IAAQ,EAAE,KAAA;AAAA,QACnC,SAAS,MAAMX,EAAiBQ,CAAG;AAAA,QAElC,UAAA;AAAA,UAAAK,IACE,gBAAAN;AAAA,YAAC;AAAA,YAAA;AAAA,cACE,WAAWD,EAAQ;AAAA,cACnB,SAAS,CAACS,MAAM;AACb,gBAAAA,EAAE,gBAAA,GACFd,EAAeO,CAAG;AAAA,cACrB;AAAA,cAEC,cAAa,MAAM;AAAA,YAAA;AAAA,UAAA,IAGvB,gBAAAD,EAAC,QAAA,EAAK,WAAWD,EAAQ,kBAAA,CAAmB;AAAA,UAE/C,gBAAAQ,EAAC,QAAA,EAAK,WAAWR,EAAQ,SACtB,UAAA;AAAA,YAAA,gBAAAC,EAACS,GAAA,EAAK,MAAM,gBAAgB,MAAM,IAAI;AAAA,YAAE;AAAA,YAAEN;AAAA,UAAA,GAC7C;AAAA,UACCN,KAAA,gBAAAA,EAAuBI;AAAA,QAAG;AAAA,MAAA;AAAA,MArBtBA;AAAA,IAAA,IAJiB;AAAA,EA4B/B,CAAC;AAAA,GACJ;"}
@@ -0,0 +1,18 @@
1
+ import React, { ReactNode } from 'react';
2
+ interface SnapshotBrowserFileListProps {
3
+ files: any[];
4
+ height: number;
5
+ itemSize?: number;
6
+ headerContent: ReactNode;
7
+ renderRow: (props: {
8
+ index: number;
9
+ style: React.CSSProperties;
10
+ }) => React.ReactElement | null;
11
+ selectedFolder: string | null;
12
+ emptyMessage?: string;
13
+ isLoading?: boolean;
14
+ gridTemplateColumns?: string;
15
+ }
16
+ declare const SnapshotBrowserFileList: ({ files, height, itemSize, headerContent, renderRow, selectedFolder, emptyMessage, isLoading, gridTemplateColumns, }: SnapshotBrowserFileListProps) => import("react/jsx-runtime").JSX.Element;
17
+ export default SnapshotBrowserFileList;
18
+ //# sourceMappingURL=SnapshotBrowserFileList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserFileList.d.ts","sourceRoot":"","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserFileList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQzC,UAAU,4BAA4B;IACnC,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,SAAS,CAAC;IACzB,SAAS,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAA;KAAE,KAAK,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IAC/F,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,QAAA,MAAM,uBAAuB,GAAI,sHAU9B,4BAA4B,4CAmB9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { jsxs as h, jsx as i } from "react/jsx-runtime";
2
+ import { FixedSizeList as d } from "react-window";
3
+ import t from "./SnapshotBrowser.module.scss.js";
4
+ import { isMobile as f } from "../../../utils/helpers.js";
5
+ const v = f(), p = v ? 65 : 46, b = ({
6
+ files: e,
7
+ height: o,
8
+ itemSize: r = p,
9
+ headerContent: n,
10
+ renderRow: a,
11
+ selectedFolder: s,
12
+ emptyMessage: c = "Select a folder from the left to browse its content",
13
+ isLoading: m,
14
+ gridTemplateColumns: l
15
+ }) => /* @__PURE__ */ h("div", { className: t.fileList, children: [
16
+ /* @__PURE__ */ i("div", { className: t.header, style: l ? { gridTemplateColumns: l } : void 0, children: n }),
17
+ s !== null && e.length > 0 && /* @__PURE__ */ i("div", { className: t.virtualFileList, children: /* @__PURE__ */ i(d, { height: o, itemCount: e.length, itemSize: r, width: "100%", overscanCount: 5, children: a }) }),
18
+ s === null && /* @__PURE__ */ i("div", { className: t.fileListEmpty, children: c }),
19
+ s !== null && !m && e.length === 0 && /* @__PURE__ */ i("div", { className: t.fileListEmpty, children: "This folder is empty" })
20
+ ] });
21
+ export {
22
+ b as default
23
+ };
24
+ //# sourceMappingURL=SnapshotBrowserFileList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserFileList.js","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserFileList.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\r\nimport { FixedSizeList as List } from 'react-window';\r\nimport classes from './SnapshotBrowser.module.scss';\r\nimport { isMobile } from '../../../utils';\r\n\r\nconst isMobileDevice = isMobile();\r\nconst DEFAULT_ITEM_HEIGHT = isMobileDevice ? 65 : 46;\r\n\r\ninterface SnapshotBrowserFileListProps {\r\n files: any[];\r\n height: number;\r\n itemSize?: number;\r\n headerContent: ReactNode;\r\n renderRow: (props: { index: number; style: React.CSSProperties }) => React.ReactElement | null;\r\n selectedFolder: string | null;\r\n emptyMessage?: string;\r\n isLoading?: boolean;\r\n gridTemplateColumns?: string;\r\n}\r\n\r\nconst SnapshotBrowserFileList = ({\r\n files,\r\n height,\r\n itemSize = DEFAULT_ITEM_HEIGHT,\r\n headerContent,\r\n renderRow,\r\n selectedFolder,\r\n emptyMessage = 'Select a folder from the left to browse its content',\r\n isLoading,\r\n gridTemplateColumns,\r\n}: SnapshotBrowserFileListProps) => {\r\n return (\r\n <div className={classes.fileList}>\r\n <div className={classes.header} style={gridTemplateColumns ? { gridTemplateColumns } : undefined}>\r\n {headerContent}\r\n </div>\r\n\r\n {selectedFolder !== null && files.length > 0 && (\r\n <div className={classes.virtualFileList}>\r\n <List height={height} itemCount={files.length} itemSize={itemSize} width=\"100%\" overscanCount={5}>\r\n {renderRow}\r\n </List>\r\n </div>\r\n )}\r\n\r\n {selectedFolder === null && <div className={classes.fileListEmpty}>{emptyMessage}</div>}\r\n {selectedFolder !== null && !isLoading && files.length === 0 && <div className={classes.fileListEmpty}>This folder is empty</div>}\r\n </div>\r\n );\r\n};\r\n\r\nexport default SnapshotBrowserFileList;\r\n"],"names":["isMobileDevice","isMobile","DEFAULT_ITEM_HEIGHT","SnapshotBrowserFileList","files","height","itemSize","headerContent","renderRow","selectedFolder","emptyMessage","isLoading","gridTemplateColumns","jsxs","classes","jsx","List"],"mappings":";;;;AAKA,MAAMA,IAAiBC,EAAA,GACjBC,IAAsBF,IAAiB,KAAK,IAc5CG,IAA0B,CAAC;AAAA,EAC9B,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC,IAAWJ;AAAA,EACX,eAAAK;AAAA,EACA,WAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,WAAAC;AAAA,EACA,qBAAAC;AACH,MAEM,gBAAAC,EAAC,OAAA,EAAI,WAAWC,EAAQ,UACrB,UAAA;AAAA,EAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAQ,QAAQ,OAAOF,IAAsB,EAAE,qBAAAA,EAAA,IAAwB,QACnF,UAAAL,EAAA,CACJ;AAAA,EAECE,MAAmB,QAAQL,EAAM,SAAS,KACxC,gBAAAW,EAAC,OAAA,EAAI,WAAWD,EAAQ,iBACrB,UAAA,gBAAAC,EAACC,KAAK,QAAAX,GAAgB,WAAWD,EAAM,QAAQ,UAAAE,GAAoB,OAAM,QAAO,eAAe,GAC3F,UAAAE,EAAA,CACJ,EAAA,CACH;AAAA,EAGFC,MAAmB,QAAQ,gBAAAM,EAAC,SAAI,WAAWD,EAAQ,eAAgB,UAAAJ,GAAa;AAAA,EAChFD,MAAmB,QAAQ,CAACE,KAAaP,EAAM,WAAW,KAAK,gBAAAW,EAAC,OAAA,EAAI,WAAWD,EAAQ,eAAe,UAAA,uBAAA,CAAoB;AAAA,GAC9H;"}
@@ -0,0 +1,18 @@
1
+ import React, { ReactNode } from 'react';
2
+ interface SnapshotBrowserFileRowProps {
3
+ style: React.CSSProperties;
4
+ file: {
5
+ path: string;
6
+ name?: string;
7
+ isDirectory?: boolean;
8
+ };
9
+ isDirectory: boolean;
10
+ onClick?: () => void;
11
+ namePrefix?: ReactNode;
12
+ children?: ReactNode;
13
+ gridTemplateColumns?: string;
14
+ className?: string;
15
+ }
16
+ declare const SnapshotBrowserFileRow: ({ style, file, isDirectory, onClick, namePrefix, children, gridTemplateColumns, className, }: SnapshotBrowserFileRowProps) => import("react/jsx-runtime").JSX.Element;
17
+ export default SnapshotBrowserFileRow;
18
+ //# sourceMappingURL=SnapshotBrowserFileRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserFileRow.d.ts","sourceRoot":"","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserFileRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKzC,UAAU,2BAA2B;IAClC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;IAC3B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7D,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,QAAA,MAAM,sBAAsB,GAAI,8FAS7B,2BAA2B,4CAgB7B,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { jsxs as t, jsx as a } from "react/jsx-runtime";
2
+ import c from "../Icon/Icon.js";
3
+ import d from "../FileIcon/FileIcon.js";
4
+ import e from "./SnapshotBrowser.module.scss.js";
5
+ const I = ({
6
+ style: m,
7
+ file: s,
8
+ isDirectory: o,
9
+ onClick: l,
10
+ namePrefix: p,
11
+ children: n,
12
+ gridTemplateColumns: i,
13
+ className: f
14
+ }) => {
15
+ const r = s.name || s.path.split("/").pop() || "";
16
+ return /* @__PURE__ */ t(
17
+ "div",
18
+ {
19
+ style: { ...m, ...i ? { gridTemplateColumns: i } : {} },
20
+ className: `${e.snapshotFile} ${o ? e.fileIsDir : ""} ${f || ""}`,
21
+ onClick: l,
22
+ children: [
23
+ /* @__PURE__ */ t("div", { className: e.fileName, children: [
24
+ p,
25
+ o ? /* @__PURE__ */ a(c, { type: "fm-directory", size: 16 }) : /* @__PURE__ */ a(d, { filename: r }),
26
+ " ",
27
+ r
28
+ ] }),
29
+ n
30
+ ]
31
+ }
32
+ );
33
+ };
34
+ export {
35
+ I as default
36
+ };
37
+ //# sourceMappingURL=SnapshotBrowserFileRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserFileRow.js","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserFileRow.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\r\nimport Icon from '../Icon/Icon';\r\nimport FileIcon from '../FileIcon/FileIcon';\r\nimport classes from './SnapshotBrowser.module.scss';\r\n\r\ninterface SnapshotBrowserFileRowProps {\r\n style: React.CSSProperties;\r\n file: { path: string; name?: string; isDirectory?: boolean };\r\n isDirectory: boolean;\r\n onClick?: () => void;\r\n namePrefix?: ReactNode;\r\n children?: ReactNode;\r\n gridTemplateColumns?: string;\r\n className?: string;\r\n}\r\n\r\nconst SnapshotBrowserFileRow = ({\r\n style,\r\n file,\r\n isDirectory,\r\n onClick,\r\n namePrefix,\r\n children,\r\n gridTemplateColumns,\r\n className,\r\n}: SnapshotBrowserFileRowProps) => {\r\n const fileName = file.name || file.path.split('/').pop() || '';\r\n\r\n return (\r\n <div\r\n style={{ ...style, ...(gridTemplateColumns ? { gridTemplateColumns } : {}) }}\r\n className={`${classes.snapshotFile} ${isDirectory ? classes.fileIsDir : ''} ${className || ''}`}\r\n onClick={onClick}\r\n >\r\n <div className={classes.fileName}>\r\n {namePrefix}\r\n {isDirectory ? <Icon type={'fm-directory'} size={16} /> : <FileIcon filename={fileName} />} {fileName}\r\n </div>\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\nexport default SnapshotBrowserFileRow;\r\n"],"names":["SnapshotBrowserFileRow","style","file","isDirectory","onClick","namePrefix","children","gridTemplateColumns","className","fileName","jsxs","classes","jsx","Icon","FileIcon"],"mappings":";;;;AAgBA,MAAMA,IAAyB,CAAC;AAAA,EAC7B,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,WAAAC;AACH,MAAmC;AAChC,QAAMC,IAAWP,EAAK,QAAQA,EAAK,KAAK,MAAM,GAAG,EAAE,IAAA,KAAS;AAE5D,SACG,gBAAAQ;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,OAAO,EAAE,GAAGT,GAAO,GAAIM,IAAsB,EAAE,qBAAAA,EAAA,IAAwB,GAAC;AAAA,MACxE,WAAW,GAAGI,EAAQ,YAAY,IAAIR,IAAcQ,EAAQ,YAAY,EAAE,IAAIH,KAAa,EAAE;AAAA,MAC7F,SAAAJ;AAAA,MAEA,UAAA;AAAA,QAAA,gBAAAM,EAAC,OAAA,EAAI,WAAWC,EAAQ,UACpB,UAAA;AAAA,UAAAN;AAAA,UACAF,IAAc,gBAAAS,EAACC,GAAA,EAAK,MAAM,gBAAgB,MAAM,GAAA,CAAI,IAAK,gBAAAD,EAACE,GAAA,EAAS,UAAUL,EAAA,CAAU;AAAA,UAAG;AAAA,UAAEA;AAAA,QAAA,GAChG;AAAA,QACCH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV;"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface SnapshotBrowserGoUpRowProps {
3
+ style: React.CSSProperties;
4
+ onGoUp: () => void;
5
+ gridTemplateColumns?: string;
6
+ }
7
+ declare const SnapshotBrowserGoUpRow: ({ style, onGoUp, gridTemplateColumns }: SnapshotBrowserGoUpRowProps) => import("react/jsx-runtime").JSX.Element;
8
+ export default SnapshotBrowserGoUpRow;
9
+ //# sourceMappingURL=SnapshotBrowserGoUpRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserGoUpRow.d.ts","sourceRoot":"","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,2BAA2B;IAClC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;IAC3B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,QAAA,MAAM,sBAAsB,GAAI,wCAAwC,2BAA2B,4CAUlG,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import s from "./SnapshotBrowser.module.scss.js";
3
+ const l = ({ style: r, onGoUp: i, gridTemplateColumns: o }) => /* @__PURE__ */ e(
4
+ "div",
5
+ {
6
+ style: { ...r, ...o ? { gridTemplateColumns: o } : {} },
7
+ className: `${s.snapshotFile} ${s.fileIsDir} ${s.goUpButton}`,
8
+ onClick: i,
9
+ children: /* @__PURE__ */ e("div", { className: s.fileName, children: "..." })
10
+ }
11
+ );
12
+ export {
13
+ l as default
14
+ };
15
+ //# sourceMappingURL=SnapshotBrowserGoUpRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserGoUpRow.js","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.tsx"],"sourcesContent":["import React from 'react';\r\nimport classes from './SnapshotBrowser.module.scss';\r\n\r\ninterface SnapshotBrowserGoUpRowProps {\r\n style: React.CSSProperties;\r\n onGoUp: () => void;\r\n gridTemplateColumns?: string;\r\n}\r\n\r\nconst SnapshotBrowserGoUpRow = ({ style, onGoUp, gridTemplateColumns }: SnapshotBrowserGoUpRowProps) => {\r\n return (\r\n <div\r\n style={{ ...style, ...(gridTemplateColumns ? { gridTemplateColumns } : {}) }}\r\n className={`${classes.snapshotFile} ${classes.fileIsDir} ${classes.goUpButton}`}\r\n onClick={onGoUp}\r\n >\r\n <div className={classes.fileName}>...</div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default SnapshotBrowserGoUpRow;\r\n"],"names":["SnapshotBrowserGoUpRow","style","onGoUp","gridTemplateColumns","jsx","classes"],"mappings":";;AASA,MAAMA,IAAyB,CAAC,EAAE,OAAAC,GAAO,QAAAC,GAAQ,qBAAAC,QAE3C,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACE,OAAO,EAAE,GAAGH,GAAO,GAAIE,IAAsB,EAAE,qBAAAA,EAAA,IAAwB,GAAC;AAAA,IACxE,WAAW,GAAGE,EAAQ,YAAY,IAAIA,EAAQ,SAAS,IAAIA,EAAQ,UAAU;AAAA,IAC7E,SAASH;AAAA,IAET,UAAA,gBAAAE,EAAC,OAAA,EAAI,WAAWC,EAAQ,UAAU,UAAA,MAAA,CAAG;AAAA,EAAA;AAAA;"}
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+ interface SnapshotBrowserToolbarProps {
3
+ search: string;
4
+ onSearchChange: (value: string) => void;
5
+ isLoading?: boolean;
6
+ leftContent?: ReactNode;
7
+ rightContent?: ReactNode;
8
+ }
9
+ declare const SnapshotBrowserToolbar: ({ search, onSearchChange, isLoading, leftContent, rightContent }: SnapshotBrowserToolbarProps) => import("react/jsx-runtime").JSX.Element;
10
+ export default SnapshotBrowserToolbar;
11
+ //# sourceMappingURL=SnapshotBrowserToolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserToolbar.d.ts","sourceRoot":"","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserToolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlC,UAAU,2BAA2B;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,QAAA,MAAM,sBAAsB,GAAI,kEAAkE,2BAA2B,4CAc5H,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
+ import o from "../Icon/Icon.js";
3
+ import r from "./SnapshotBrowser.module.scss.js";
4
+ const p = ({ search: s, onSearchChange: t, isLoading: l, leftContent: i, rightContent: c }) => /* @__PURE__ */ a("div", { className: r.toolbar, children: [
5
+ /* @__PURE__ */ e("div", { className: r.toolbarLeft, children: i }),
6
+ /* @__PURE__ */ a("div", { className: r.toolbarRight, children: [
7
+ c,
8
+ /* @__PURE__ */ a("div", { className: r.search, children: [
9
+ /* @__PURE__ */ e(o, { type: "search", size: 16 }),
10
+ /* @__PURE__ */ e("input", { type: "text", placeholder: "Search in current Directory...", value: s, onChange: (n) => t(n.target.value) }),
11
+ l && /* @__PURE__ */ e(o, { type: "loading", size: 12 })
12
+ ] })
13
+ ] })
14
+ ] });
15
+ export {
16
+ p as default
17
+ };
18
+ //# sourceMappingURL=SnapshotBrowserToolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotBrowserToolbar.js","sources":["../../../../src/components/common/SnapshotBrowser/SnapshotBrowserToolbar.tsx"],"sourcesContent":["import { ReactNode } from 'react';\r\nimport Icon from '../Icon/Icon';\r\nimport classes from './SnapshotBrowser.module.scss';\r\n\r\ninterface SnapshotBrowserToolbarProps {\r\n search: string;\r\n onSearchChange: (value: string) => void;\r\n isLoading?: boolean;\r\n leftContent?: ReactNode;\r\n rightContent?: ReactNode;\r\n}\r\n\r\nconst SnapshotBrowserToolbar = ({ search, onSearchChange, isLoading, leftContent, rightContent }: SnapshotBrowserToolbarProps) => {\r\n return (\r\n <div className={classes.toolbar}>\r\n <div className={classes.toolbarLeft}>{leftContent}</div>\r\n <div className={classes.toolbarRight}>\r\n {rightContent}\r\n <div className={classes.search}>\r\n <Icon type=\"search\" size={16} />\r\n <input type=\"text\" placeholder=\"Search in current Directory...\" value={search} onChange={(e) => onSearchChange(e.target.value)} />\r\n {isLoading && <Icon type=\"loading\" size={12} />}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default SnapshotBrowserToolbar;\r\n"],"names":["SnapshotBrowserToolbar","search","onSearchChange","isLoading","leftContent","rightContent","jsxs","classes","jsx","Icon","e"],"mappings":";;;AAYA,MAAMA,IAAyB,CAAC,EAAE,QAAAC,GAAQ,gBAAAC,GAAgB,WAAAC,GAAW,aAAAC,GAAa,cAAAC,QAE5E,gBAAAC,EAAC,OAAA,EAAI,WAAWC,EAAQ,SACrB,UAAA;AAAA,EAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAQ,aAAc,UAAAH,GAAY;AAAA,EAClD,gBAAAE,EAAC,OAAA,EAAI,WAAWC,EAAQ,cACpB,UAAA;AAAA,IAAAF;AAAA,IACD,gBAAAC,EAAC,OAAA,EAAI,WAAWC,EAAQ,QACrB,UAAA;AAAA,MAAA,gBAAAC,EAACC,GAAA,EAAK,MAAK,UAAS,MAAM,IAAI;AAAA,MAC9B,gBAAAD,EAAC,SAAA,EAAM,MAAK,QAAO,aAAY,kCAAiC,OAAOP,GAAQ,UAAU,CAACS,MAAMR,EAAeQ,EAAE,OAAO,KAAK,GAAG;AAAA,MAC/HP,KAAa,gBAAAK,EAACC,GAAA,EAAK,MAAK,WAAU,MAAM,GAAA,CAAI;AAAA,IAAA,EAAA,CAChD;AAAA,EAAA,EAAA,CACH;AAAA,GACH;"}
@@ -0,0 +1,12 @@
1
+ import { SnapshotDatabase } from '../../../../utils';
2
+ import { FileItem } from '../../../../@types';
3
+ export declare const useSnapshotDatabase: (files: FileItem[], backupId: string, useProgressiveLoading: boolean) => {
4
+ db: SnapshotDatabase | null;
5
+ initError: string | null;
6
+ discoveredDirectories: string[];
7
+ expandedFolders: Set<string>;
8
+ setExpandedFolders: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
9
+ setDiscoveredDirectories: import("react").Dispatch<import("react").SetStateAction<string[]>>;
10
+ addDirectoriesSorted: (newDirs: string[]) => void;
11
+ };
12
+ //# sourceMappingURL=useSnapshotDatabase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSnapshotDatabase.d.ts","sourceRoot":"","sources":["../../../../../src/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,eAAO,MAAM,mBAAmB,GAAI,OAAO,QAAQ,EAAE,EAAE,UAAU,MAAM,EAAE,uBAAuB,OAAO;;;;;;;oCA6DvF,MAAM,EAAE;CAgEvB,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { useState as p, useCallback as E, useEffect as z } from "react";
2
+ import A from "../../../../utils/snapshotDatabase.js";
3
+ const L = (d, D, m) => {
4
+ const [u, b] = p(null), [g, w] = p(null), [S, l] = p([]), [x, h] = p(/* @__PURE__ */ new Set()), c = E((a) => {
5
+ const t = {}, n = [];
6
+ a.forEach((e) => {
7
+ const s = e.substring(0, e.lastIndexOf("/")) || "";
8
+ t[s] || (t[s] = []), t[s].push(e);
9
+ }), a.forEach((e) => {
10
+ const s = e.substring(0, e.lastIndexOf("/")) || "";
11
+ (s === "" || !a.includes(s)) && n.push(e);
12
+ });
13
+ const o = [], r = (e) => {
14
+ const s = t[e] || [];
15
+ s.sort((i, f) => {
16
+ const v = i.split("/").pop() || "", F = f.split("/").pop() || "";
17
+ return v.localeCompare(F);
18
+ }), s.forEach((i) => {
19
+ o.push(i), r(i);
20
+ });
21
+ };
22
+ return n.sort((e, s) => {
23
+ const i = e.split("/").pop() || "", f = s.split("/").pop() || "";
24
+ return i.localeCompare(f);
25
+ }), n.forEach((e) => {
26
+ o.push(e), r(e);
27
+ }), o;
28
+ }, []), y = E(
29
+ (a) => {
30
+ l((t) => {
31
+ const n = [...t, ...a], o = Array.from(new Set(n));
32
+ return c(o);
33
+ });
34
+ },
35
+ [c]
36
+ );
37
+ return z(() => ((async () => {
38
+ try {
39
+ console.log("Initializing database for", d.length, "files");
40
+ const t = new A(D);
41
+ if (await t.initializeFromFiles(d), b(t), console.log("Database initialized successfully"), m) {
42
+ const n = await t.getTopLevelDirectories(3), o = c(n);
43
+ l(o), console.log("Loaded top-level directories:", o.length);
44
+ const r = /* @__PURE__ */ new Set();
45
+ o.slice(0, 2).forEach((e) => r.add(e)), h(r);
46
+ } else {
47
+ const n = await t.getTopLevelDirectories(999), o = c(n);
48
+ l(o);
49
+ const r = /* @__PURE__ */ new Set();
50
+ o.slice(0, 3).forEach((e) => r.add(e)), h(r);
51
+ }
52
+ } catch (t) {
53
+ console.error("Failed to initialize database:", t), w(t instanceof Error ? t.message : "Unknown error");
54
+ }
55
+ })(), () => {
56
+ u && u.cleanup().catch(console.error);
57
+ }), [d, D, m, c]), {
58
+ db: u,
59
+ initError: g,
60
+ discoveredDirectories: S,
61
+ expandedFolders: x,
62
+ setExpandedFolders: h,
63
+ setDiscoveredDirectories: l,
64
+ addDirectoriesSorted: y
65
+ };
66
+ };
67
+ export {
68
+ L as useSnapshotDatabase
69
+ };
70
+ //# sourceMappingURL=useSnapshotDatabase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSnapshotDatabase.js","sources":["../../../../../src/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.ts"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport { SnapshotDatabase } from '../../../../utils';\r\nimport { FileItem } from '../../../../@types';\r\n\r\nexport const useSnapshotDatabase = (files: FileItem[], backupId: string, useProgressiveLoading: boolean) => {\r\n const [db, setDb] = useState<SnapshotDatabase | null>(null);\r\n const [initError, setInitError] = useState<string | null>(null);\r\n const [discoveredDirectories, setDiscoveredDirectories] = useState<string[]>([]);\r\n const [expandedFolders, setExpandedFolders] = useState<Set<string>>(new Set());\r\n\r\n // Helper function to sort directories in true hierarchical order\r\n const sortDirectoriesHierarchically = useCallback((dirs: string[]): string[] => {\r\n const tree: { [key: string]: string[] } = {};\r\n const roots: string[] = [];\r\n\r\n // Build parent-child relationships\r\n dirs.forEach((dir) => {\r\n const parentPath = dir.substring(0, dir.lastIndexOf('/')) || '';\r\n if (!tree[parentPath]) {\r\n tree[parentPath] = [];\r\n }\r\n tree[parentPath].push(dir);\r\n });\r\n\r\n // Find root directories (those whose parent is not in the list)\r\n dirs.forEach((dir) => {\r\n const parentPath = dir.substring(0, dir.lastIndexOf('/')) || '';\r\n if (parentPath === '' || !dirs.includes(parentPath)) {\r\n roots.push(dir);\r\n }\r\n });\r\n\r\n // Recursively build sorted list\r\n const sortedList: string[] = [];\r\n\r\n const addChildrenRecursively = (parent: string) => {\r\n const children = tree[parent] || [];\r\n children.sort((a, b) => {\r\n const nameA = a.split('/').pop() || '';\r\n const nameB = b.split('/').pop() || '';\r\n return nameA.localeCompare(nameB);\r\n });\r\n\r\n children.forEach((child) => {\r\n sortedList.push(child);\r\n addChildrenRecursively(child);\r\n });\r\n };\r\n\r\n roots.sort((a, b) => {\r\n const nameA = a.split('/').pop() || '';\r\n const nameB = b.split('/').pop() || '';\r\n return nameA.localeCompare(nameB);\r\n });\r\n\r\n roots.forEach((root) => {\r\n sortedList.push(root);\r\n addChildrenRecursively(root);\r\n });\r\n\r\n return sortedList;\r\n }, []);\r\n\r\n // Helper function to add new directories while maintaining sorted order\r\n const addDirectoriesSorted = useCallback(\r\n (newDirs: string[]) => {\r\n setDiscoveredDirectories((prev) => {\r\n const allDirs = [...prev, ...newDirs];\r\n const uniqueDirs = Array.from(new Set(allDirs));\r\n return sortDirectoriesHierarchically(uniqueDirs);\r\n });\r\n },\r\n [sortDirectoriesHierarchically],\r\n );\r\n\r\n // Initialize database\r\n useEffect(() => {\r\n const initDb = async () => {\r\n try {\r\n console.log('Initializing database for', files.length, 'files');\r\n const database = new SnapshotDatabase(backupId);\r\n await database.initializeFromFiles(files);\r\n setDb(database);\r\n console.log('Database initialized successfully');\r\n\r\n if (useProgressiveLoading) {\r\n // Load only top-level directories initially\r\n const topDirs = await database.getTopLevelDirectories(3);\r\n const sortedTopDirs = sortDirectoriesHierarchically(topDirs);\r\n setDiscoveredDirectories(sortedTopDirs);\r\n console.log('Loaded top-level directories:', sortedTopDirs.length);\r\n\r\n const initialExpanded = new Set<string>();\r\n sortedTopDirs.slice(0, 2).forEach((dir) => initialExpanded.add(dir));\r\n setExpandedFolders(initialExpanded);\r\n } else {\r\n // For smaller datasets, load all directories\r\n const allDirs = await database.getTopLevelDirectories(999);\r\n const sortedAllDirs = sortDirectoriesHierarchically(allDirs);\r\n setDiscoveredDirectories(sortedAllDirs);\r\n\r\n const initialExpanded = new Set<string>();\r\n sortedAllDirs.slice(0, 3).forEach((dir) => initialExpanded.add(dir));\r\n setExpandedFolders(initialExpanded);\r\n }\r\n } catch (error) {\r\n console.error('Failed to initialize database:', error);\r\n setInitError(error instanceof Error ? error.message : 'Unknown error');\r\n }\r\n };\r\n\r\n initDb();\r\n\r\n return () => {\r\n if (db) {\r\n db.cleanup().catch(console.error);\r\n }\r\n };\r\n }, [files, backupId, useProgressiveLoading, sortDirectoriesHierarchically]);\r\n\r\n return {\r\n db,\r\n initError,\r\n discoveredDirectories,\r\n expandedFolders,\r\n setExpandedFolders,\r\n setDiscoveredDirectories,\r\n addDirectoriesSorted,\r\n };\r\n};\r\n"],"names":["useSnapshotDatabase","files","backupId","useProgressiveLoading","db","setDb","useState","initError","setInitError","discoveredDirectories","setDiscoveredDirectories","expandedFolders","setExpandedFolders","sortDirectoriesHierarchically","useCallback","dirs","tree","roots","dir","parentPath","sortedList","addChildrenRecursively","parent","children","a","b","nameA","nameB","child","root","addDirectoriesSorted","newDirs","prev","allDirs","uniqueDirs","useEffect","database","SnapshotDatabase","topDirs","sortedTopDirs","initialExpanded","sortedAllDirs","error"],"mappings":"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"}