-
Notifications
You must be signed in to change notification settings - Fork 33
[PB-5465] Implement file version history actions #1771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PB-5465] Implement file version history actions #1771
Conversation
Deploying drive-web with
|
| Latest commit: |
34d61ea
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://51b05822.drive-web.pages.dev |
| Branch Preview URL: | https://feature-file-version-history-4jkx.drive-web.pages.dev |
…wnload functionality Adds complete file version management system with API integration for viewing, restoring, deleting, and downloading file versions. Updates name collision dialog to use replaceFile endpoint instead of delete-and-reupload for file replacements.
0fc701b to
1612aff
Compare
…itional messages and error handling
| "restoreVersion": "Restore version", | ||
| "downloadVersion": "Download version", | ||
| "deleteVersion": "Delete version" | ||
| "deleteVersion": "Delete version", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining translations are included in this PR: #1773
48361a6 to
f59d219
Compare
| const user = localStorageService.getUser(); | ||
| if (!user) throw new Error('User not found'); | ||
|
|
||
| const fileStream = await downloadFile({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use the multipart download for this? Imagine the file has 5GB or more. It would be better to download it in parallel-small chunks instead of the full file at once. You can do it by using the DownloadManager.downloadItem if I'm not mistaken.
Check that as we need to download the items using the actual method since it solves a lot of speed/memory issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember to add tests to this service.
| }, | ||
| }); | ||
|
|
||
| const blob = await binaryStreamToBlob(fileStream); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Downloading it as blob and then save it will causes memory issues, specially for Firefox. Also, it won't work for big files in Safari - the file will be downloaded but only 700 bytes (or even 0) will be saved to the disk as Safari does not allow saving big blobs.
Try the method I mentioned above as it already handles all these things, such as saving the downloaded + decrypted chunk directly to the user disk instead of saving it in memory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this function in this service? It is a part of file versioning, isn't it? Also, remember to add tests to this service.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This service is used in the name-collision modal, which belongs to Drive and isn’t necessarily part of the file-version history flow. That’s why I placed it inside the Drive module. It could live under Version History as well, but keeping it in Drive makes more sense in this context. What do you think?
The tests will be added in a separate PR.
…etter UX - Replace direct download with DownloadManager for efficient multipart downloads - Add workspace credentials support for version downloads - Position TaskLogger at bottom-right - Refactor: rename service files to camelCase convention (file-version.service.ts → fileVersion.service.ts, replace-file.service.ts → replaceFile.service.ts) - Pass file item and workspace context to downloadVersion for proper credential handling
Remove try-catch block and error handling from useVersionItemActions since DownloadManager already handles error reporting, notifications, and task status updates internally. This prevents duplicate error notifications from being shown to the user.
[PB-5465]: enhance internationalization for version management
…ration - Update @internxt/sdk to 1.11.21 for improved version history support - Add batch delete functionality for multiple version selections - Implement version limits display showing used/total allowed versions - Fix file replace operation to properly upload new file content - Migrate from local FileVersion type to SDK types for better consistency - Add indeterminate checkbox state for partial selections - Improve version restoration to update current version state - Enhance skeleton loading to show more realistic version count - Add getLimits API call to fetch version constraints - Refactor CurrentVersionItem to use version info instead of full item data
…tory menu with lock state Add VersioningLimitsProvider to DriveView and implement version history menu configuration with locked state support. The version history menu now shows a lock icon and handles locked state when versioning is not available or extension is not allowed.
… context API Replace VersioningLimitsContext with Redux store for consistent state management and improved performance. Add fileVersions slice to cache API responses and prevent redundant fetches. - Create fileVersions Redux slice with caching for versions and limits - Add thunks for fetching file versions and versioning limits - Implement cache invalidation on version create, delete, and restore - Optimize Sidebar to use cached data and avoid infinite loops - Memoize VersionItem component to prevent unnecessary re-renders - Remove VersioningLimitsContext and consolidate all state in Redux - Update all components to use Redux selectors instead of context
- Create fileVersions selectors for centralized state access
- Rename state properties for clarity:
- loadingStates → isLoadingByFileId
- errors → errorsByFileId
- limitsLoading → isLimitsLoading
- Update type imports to use FileLimitsResponse (SDK v1.11.24)
- Use NonNullable for Record keys to prevent null index types
- Refactor version history menu config:
- Rename properties: locked → isLocked, allowedExtension → isExtensionAllowed, onLockedClick → onUpgradeClick
- Simplify getVersionHistoryMenuItem with early return pattern
- Replace direct state access with selectors across components
- Export getDaysUntilExpiration utility function
- Add type assertion for restored version fileId
Add unit tests for date service, version history hooks, and file version service to ensure reliability of the file versioning functionality. Tests cover dropdown positioning logic, version history menu configuration, file version operations, and date utility functions including expiration calculations.
…ctions hook Add comprehensive test coverage for fileVersions Redux slice and useVersionItemActions hook. Tests include thunk operations (fetch versions, fetch limits), reducer state management (loading, errors, cache invalidation), and menu action handlers (restore, download, delete). Uses icon-based menu item selection for robust, maintainable tests.
yarn.lock
Outdated
| integrity sha512-91iEUvZizlwX6KBEFJ3JdFiGrhMBQ9R54sTc3Pei9QtV2FYTU8nTVEPYAg39tLOGzT/kVuplYOtBxfk6wFtSDA== | ||
| "@internxt/sdk@1.11.19": | ||
| version "1.11.19" | ||
| resolved "https://npm.pkg.github.com/download/@internxt/sdk/1.11.19/f9033c8bf0849d414a3865806bacd79026a38769#f9033c8bf0849d414a3865806bacd79026a38769" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is breaking your cloudflare build, and it also breaking the PR's that depend on this one. You are using an .npmrc file so you are changing the internxt registry from yarnpkg to github.
You should use this one:
registry=https://registry.yarnpkg.com/
@internxt:registry=https://registry.yarnpkg.com/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Since this is an old PR, I made the change in this one instead: #1779
…prove autosave delete button styling
| <VersionHistorySidebar /> | ||
| </div> | ||
| <TaskLogger /> | ||
| <div className="absolute bottom-0 right-0 z-50 w-80"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this div wrapping the task logger in necessary? I think could cause wrong behaviours
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When downloading a version, the task logger was located under the File Versions sidebar, making it difficult to cancel the download.
| await replaceFileService.replaceFile(itemToReplace.uuid, { | ||
| fileId: itemToReplace.fileId, | ||
| size: file.size, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand this change. The file data is replaced, but when is the new one uploaded?
Maybe is in another PR?d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The backend has that upload new version logic
| name: translate('modals.versionHistory.deleteVersion'), | ||
| icon: Trash, | ||
| action: handleDelete, | ||
| action: handleDeleteClick, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move the hooks and services outside the components folder, add it to Drive services and hooks.
Otherwise, it would be crazy to maintain this. The components would be full of hooks and services, and components should not have business logic or API services
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid conflicts, im going to merge all these approved PRs and then work this comment in a new PR
[PB-5542]: add unit tests for Redux file versions slice and version item actions hook
[PB-5542]: File version history tests
[PB-5542]: add versioning limits context and premium feature gating
[PB-5466]: enhance version history with batch operations and SDK integration
|



Description
Related Issues
Related Pull Requests
Checklist
Testing Process
Additional Notes