Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions client/src/pages/file-manager/create-folder-dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import { useForm } from 'react-hook-form';
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
Input,
Label,
} from '../../components/ui';
import {
handleResponseErrorMessage,
useCreateFolder,
} from '../../services/apis';
import { toast } from '../../hooks';

type Props = {
open: boolean;
onOpenChange: (open: boolean) => void;
parentId: string | null;
onSuccess: () => void;
};

type FormValues = { name: string };

export const CreateFolderDialog: React.FC<Props> = ({
open,
onOpenChange,
parentId,
onSuccess,
}) => {
const {
register,
handleSubmit,
reset,
setError,
formState: { errors },
} = useForm<FormValues>();
const { mutate: createFolder, isPending } = useCreateFolder();

const onSubmit = (values: FormValues) => {
createFolder(
{ name: values.name, parentId },
{
onSuccess: () => {
reset();
onOpenChange(false);
onSuccess();
toast({ title: 'Folder created successfully' });
},
onError: (error) => handleResponseErrorMessage(error, setError),
},
);
};

return (
<Dialog
open={open}
onOpenChange={(o) => {
if (!isPending) {
reset();
onOpenChange(o);
}
}}
>
<DialogContent>
<DialogHeader>
<DialogTitle>New Folder</DialogTitle>
</DialogHeader>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<div className="space-y-1.5">
<Label htmlFor="folder-name">Folder name</Label>
<Input
id="folder-name"
placeholder="My Folder"
{...register('name', { required: 'Folder name is required' })}
/>
{errors.name && (
<p className="text-xs text-destructive">{errors.name.message}</p>
)}
</div>
<DialogFooter>
<Button
type="button"
variant="outline"
disabled={isPending}
onClick={() => onOpenChange(false)}
>
Cancel
</Button>
<Button type="submit" loading={isPending}>
Create
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
};
11 changes: 11 additions & 0 deletions client/src/pages/file-manager/file-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
File as FileIcon,
Info,
MoreVertical,
MoveRight,
Share2,
Trash2,
} from 'lucide-react';
Expand Down Expand Up @@ -33,6 +34,7 @@ type FileCardProps = {
onDelete?: () => void;
onDownload?: () => void;
onManagePermissions?: () => void;
onMove?: () => void;
};

const STATUS_BADGE: Record<
Expand All @@ -49,6 +51,7 @@ export const FileCard: React.FC<FileCardProps> = ({
onDelete,
onDownload,
onManagePermissions,
onMove,
}) => {
// Selectors.
const { canManageFiles } = useAppSelector(selectActiveDrive);
Expand All @@ -59,6 +62,7 @@ export const FileCard: React.FC<FileCardProps> = ({
isComplete && onDownload && file.canDownload !== false;
const canShareFile =
isComplete && canManageFiles && onShare && file.canShare !== false;
const canMoveFile = isComplete && canManageFiles && onMove;
const canDeleteFile = canManageFiles && onDelete && file.canDelete !== false;
const canManagePermissions =
isComplete &&
Expand All @@ -69,6 +73,7 @@ export const FileCard: React.FC<FileCardProps> = ({
const hasNoActions =
!canDownloadFile &&
!canShareFile &&
!canMoveFile &&
!canDeleteFile &&
!canManagePermissions;

Expand Down Expand Up @@ -135,6 +140,12 @@ export const FileCard: React.FC<FileCardProps> = ({
Manage Access
</DropdownMenuItem>
)}
{canMoveFile && (
<DropdownMenuItem onClick={onMove} className="gap-2">
<MoveRight className="size-4" />
Move
</DropdownMenuItem>
)}
{canDeleteFile && (
<DropdownMenuItem
onClick={onDelete}
Expand Down
3 changes: 3 additions & 0 deletions client/src/pages/file-manager/file-upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import {

export type FileUploadProps = {
onFileUploadSuccess: () => void;
folderId?: string | null;
className?: string;
};

export const FileUpload = ({
onFileUploadSuccess,
folderId = null,
className,
}: FileUploadProps) => {
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -45,6 +47,7 @@ export const FileUpload = ({
await uploadFileAsync({
file,
jobId,
folderId,
onProgress: (progress: number) => {
dispatch(updateUploadProgress({ id: jobId, progress }));
},
Expand Down
Loading