Skip to content

feat(vault): Vault File Browser UI — New menu, upload modals & mock service#125

Open
ajinkyap9 wants to merge 3 commits into
tarinagarwal:mainfrom
ajinkyap9:main
Open

feat(vault): Vault File Browser UI — New menu, upload modals & mock service#125
ajinkyap9 wants to merge 3 commits into
tarinagarwal:mainfrom
ajinkyap9:main

Conversation

@ajinkyap9

@ajinkyap9 ajinkyap9 commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Description

Add a Google Drive / Dropbox–style Vault file browser UI and upload workflow for the client (frontend-only, development mode).

Key additions

  • New Vault route & page
    • VaultPage.tsx
  • Sidebar folder tree
    • client/src/components/vault/VaultSidebar.tsx
  • File & folder views
    • Grid view: FileGrid.tsx
    • List view: FileList.tsx
  • Breadcrumb navigation
    • VaultBreadcrumb.tsx
  • “New ▾” header menu
    • New Folder → folder name modal
    • Upload File → modal with centered DropZone + file chooser
    • Upload Folder → modal using webkitdirectory
  • Upload UX
    • Reusable DropZone component
    • UploadFileModal & UploadFolderModal
    • Hidden file input fallback
  • Mock in-memory Vault service
    • client/src/services/vaultService.ts
    • Supports:
      • getChildren
      • getFolderTree
      • createFolder
      • uploadFile
      • rename
      • delete
      • getPath
  • Routing
    • Wired /vault/* route in App.tsx
  • Styling
    • Small UI improvements using existing Tailwind classes

⚠️ Note: Uploads are currently stored in an in-memory mock service.
Backend persistence will be handled in Issue #70.


🔗 Related Issue

Closes: #72


🏷️ Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • 🎨 Style/UI update
  • 🐛 Bug fix
  • 💥 Breaking change
  • 📝 Documentation update
  • ♻️ Code refactoring
  • ⚡ Performance improvement
  • 🧪 Test update

Screenshots (if applicable)

Screenshot_2026-01-23_13_25_22 Screenshot_2026-01-23_13_25_46 Screenshot_2026-01-23_13_25_57 Screenshot_2026-01-23_13_26_08

(Attach UI screenshots in the PR if available)

  • Vault page layout
  • “New ▾” menu
  • Upload File modal
  • Upload Folder modal
  • Grid & List views

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have tested my changes locally
  • Any dependent changes have been merged and published

Testing

How I tested locally

npm run dev

@tarinagarwal

Copy link
Copy Markdown
Owner

@ajinkyap9 please attach relavent screenshots

@ajinkyap9

Copy link
Copy Markdown
Contributor Author

@tarinagarwal Attached now you can check and if any change required let me know

@ajinkyap9

Copy link
Copy Markdown
Contributor Author

@tarinagarwal please can you review the pr

@ajinkyap9

Copy link
Copy Markdown
Contributor Author

@tarinagarwal can you review asap

@tarin-lgtm tarin-lgtm Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes Requested 🐈

This PR adds a new Vault file browser UI with sidebar, file/folder views, and upload modals for the frontend. The implementation is readable and functional, but documentation is lacking for new services and API endpoints. No critical bugs or security issues were found, but documentation improvements are needed for maintainability.

There are a few things I'd like to see addressed before we merge this:

Before merging

  1. Add JSDoc comments to all exported functions and types in vaultService.ts and related files.
  2. Document all new API endpoints in server/routes/vault.js, including method, path, request/response, and authentication.
  3. Update README and .env.example to reflect the new Vault feature and its configuration.
Findings breakdown (25 total)

2 high / 16 medium / 3 low / 4 info

Confidence: 90%


🔗 View Full Review Report — detailed findings, severity breakdown, and agent analysis

Reviewed by Looks Good To Meow — AI-powered code review


💬 You can interact with me directly in this PR:

  • @tarin-lgtm fix [any constraints]
  • @tarin-lgtm explain [your question]
  • @tarin-lgtm improve [focus area]
  • @tarin-lgtm test [what to focus on]

@@ -0,0 +1,188 @@
export type VaultItemBase = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ High — Exported types and functions (VaultItemBase, FolderItem, FileItem, getRootId, getChildren, getPath, createFolder, uploadFile, renameItem, deleteItem, getFolderTree) lack JSDoc documentation. There is no description of their purpose, parameters, or return values.

Add JSDoc comments to all exported types and functions, including @param and @returns for functions, and a description for each type.

documentation

Comment thread server/routes/vault.js
@@ -0,0 +1,296 @@
import express from "express";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ High — All new API endpoints in this file lack documentation. There are no comments describing the HTTP method, path, request/response schema, authentication, or error responses for any route.

Add JSDoc-style or block comments above each route handler describing the endpoint, HTTP method, path, expected request body, response schema, authentication requirements, and possible error responses.

documentation

</div>
<div className="flex-1 bg-[#0f1724] rounded-lg p-4">
<div className="flex items-center justify-between mb-4">
<VaultBreadcrumb currentFolderId={currentFolderId} onNavigate={setCurrentFolderId} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Medium — The storage usage display is hardcoded as '120MB / 2GB'. This is misleading and not dynamic.

Fetch and display the actual storage usage from the backend or mock service instead of hardcoding the values.

readability

<input value={name} onChange={(e) => setName(e.target.value)} className="w-full p-2 rounded bg-[#0b1220] border border-slate-700 text-slate-200" placeholder="Folder name" />
<div className="mt-4 flex justify-end gap-2">
<button className="px-3 py-1 border rounded" onClick={onClose}>Cancel</button>
<button className="px-3 py-1 bg-alien-green text-black rounded" onClick={() => { onCreate(name); setName(""); }}>Create</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Medium — The 'Create' button allows creating a folder with an empty name, which can lead to confusing or invalid folder entries.

Disable the 'Create' button or prevent submission when the folder name is empty or only whitespace.

readability

<div className="mt-4 flex items-center justify-center gap-4">
<input id="upload-files-input" type="file" multiple className="hidden" onChange={(e) => setFiles(e.target.files ? Array.from(e.target.files) : null)} />
<label htmlFor="upload-files-input" className="px-3 py-2 bg-slate-800 text-slate-200 rounded cursor-pointer">Choose files</label>
<button className="px-4 py-2 bg-alien-green text-black rounded" onClick={() => { onUpload(files); }}>Upload</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Medium — The 'Upload' button is always enabled, allowing upload with no files selected. This can cause errors or confusion.

Disable the 'Upload' button when no files are selected.

readability

import React, { useState } from "react";
import DropZone from "../DropZone";

const UploadFileModal: React.FC<{ open: boolean; onClose: () => void; onUpload: (files: File[] | FileList | null) => void }> = ({ open, onClose, onUpload }) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Medium — UploadFileModal is an exported React component but lacks a JSDoc comment describing its purpose and props.

Add a JSDoc comment above UploadFileModal describing its purpose and the props it accepts.

documentation

@@ -0,0 +1,39 @@
import React, { useState } from "react";

const UploadFolderModal: React.FC<{ open: boolean; onClose: () => void; onUpload: (files: File[] | FileList | null) => void }> = ({ open, onClose, onUpload }) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Medium — UploadFolderModal is an exported React component but lacks a JSDoc comment describing its purpose and props.

Add a JSDoc comment above UploadFolderModal describing its purpose and the props it accepts.

documentation

return (
<div className="pl-2">
<div className="flex items-center gap-2 py-1 cursor-pointer hover:bg-slate-800 rounded" onClick={() => { setOpen(!open); onNavigate(node.id); }}>
<div className="w-5 h-5 bg-slate-600 rounded flex items-center justify-center text-xs">F</div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Suggestion — The folder icon is rendered as a literal 'F' character, which is not visually descriptive and may confuse users.

Replace the 'F' with an actual folder icon (e.g., an SVG or emoji like 📁) for better clarity and consistency with other parts of the UI.

readability

<div className="text-sm text-slate-200 truncate">{item.name}</div>
<div className="text-xs text-slate-500 flex justify-between">
<span>{isFolder ? "Folder" : `${(item as FileItem).size} bytes`}</span>
<button className="text-red-400" onClick={(e) => { e.stopPropagation(); onRequestDelete(item.id); }}>Delete</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Suggestion — The 'Delete' button is rendered for both files and folders, but the label does not clarify what is being deleted. This could be confusing in a mixed grid view.

Consider updating the button label or adding a tooltip to clarify whether a file or folder will be deleted.

readability

</div>
<div className="text-xs text-slate-400 flex gap-4 items-center">
<div>{isFolder ? "Folder" : `${(item as FileItem).size} bytes`}</div>
<button className="text-red-400" onClick={() => onRequestDelete(item.id)}>Delete</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Suggestion — The 'Delete' button is rendered for both files and folders, but the label does not clarify what is being deleted. This could be confusing in a mixed list view.

Consider updating the button label or adding a tooltip to clarify whether a file or folder will be deleted.

readability

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Vault 2/13] File Browser UI

2 participants