Files
HKSingleParty/03_source/frontend/src/sections/file-manager/file-manager-grid-view.tsx
louiscklaw b7cd25b614 build ok,
2025-06-15 11:28:24 +08:00

212 lines
6.1 KiB
TypeScript

import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Collapse from '@mui/material/Collapse';
import Divider from '@mui/material/Divider';
import { useBoolean } from 'minimal-shared/hooks';
import { useCallback, useRef, useState } from 'react';
import { Iconify } from 'src/components/iconify';
import type { UseTableReturn } from 'src/components/table';
import type { IFile } from 'src/types/file';
import { FileManagerActionSelected } from './file-manager-action-selected';
import { FileManagerFileItem } from './file-manager-file-item';
import { FileManagerFolderItem } from './file-manager-folder-item';
import { FileManagerNewFolderDialog } from './file-manager-new-folder-dialog';
import { FileManagerPanel } from './file-manager-panel';
import { FileManagerShareDialog } from './file-manager-share-dialog';
// ----------------------------------------------------------------------
type Props = {
table: UseTableReturn;
dataFiltered: IFile[];
onOpenConfirm: () => void;
onDeleteItem: (id: string) => void;
};
export function FileManagerGridView({ table, dataFiltered, onDeleteItem, onOpenConfirm }: Props) {
const { selected, onSelectRow: onSelectItem, onSelectAllRows: onSelectAllItems } = table;
const containerRef = useRef(null);
const shareDialog = useBoolean();
const filesCollapse = useBoolean();
const foldersCollapse = useBoolean();
const newFilesDialog = useBoolean();
const newFolderDialog = useBoolean();
const [folderName, setFolderName] = useState('');
const [inviteEmail, setInviteEmail] = useState('');
const handleChangeInvite = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
setInviteEmail(event.target.value);
}, []);
const handleChangeFolderName = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
setFolderName(event.target.value);
}, []);
const renderShareDialog = () => (
<FileManagerShareDialog
open={shareDialog.value}
inviteEmail={inviteEmail}
onChangeInvite={handleChangeInvite}
onClose={() => {
shareDialog.onFalse();
setInviteEmail('');
}}
/>
);
const renderNewFilesDialog = () => (
<FileManagerNewFolderDialog open={newFilesDialog.value} onClose={newFilesDialog.onFalse} />
);
const renderNewFolderDialog = () => (
<FileManagerNewFolderDialog
open={newFolderDialog.value}
onClose={newFolderDialog.onFalse}
title="New Folder"
onCreate={() => {
newFolderDialog.onFalse();
setFolderName('');
console.info('CREATE NEW FOLDER', folderName);
}}
folderName={folderName}
onChangeFolderName={handleChangeFolderName}
/>
);
const renderFolders = () => (
<>
<FileManagerPanel
title="Folders"
subtitle={`${dataFiltered.filter((item) => item.type === 'folder').length} folders`}
onOpen={newFolderDialog.onTrue}
collapse={foldersCollapse.value}
onCollapse={foldersCollapse.onToggle}
/>
<Collapse in={!foldersCollapse.value} unmountOnExit>
<Box
sx={{
gap: 3,
display: 'grid',
gridTemplateColumns: {
xs: 'repeat(1, 1fr)',
sm: 'repeat(2, 1fr)',
md: 'repeat(3, 1fr)',
lg: 'repeat(4, 1fr)',
},
}}
>
{dataFiltered
.filter((i) => i.type === 'folder')
.map((folder) => (
<FileManagerFolderItem
key={folder.id}
folder={folder}
selected={selected.includes(folder.id)}
onSelect={() => onSelectItem(folder.id)}
onDelete={() => onDeleteItem(folder.id)}
/>
))}
</Box>
</Collapse>
</>
);
const renderFiles = () => (
<>
<FileManagerPanel
title="Files"
subtitle={`${dataFiltered.filter((item) => item.type !== 'folder').length} files`}
onOpen={newFilesDialog.onTrue}
collapse={filesCollapse.value}
onCollapse={filesCollapse.onToggle}
/>
<Collapse in={!filesCollapse.value} unmountOnExit>
<Box
sx={{
gap: 3,
display: 'grid',
gridTemplateColumns: {
xs: 'repeat(1, 1fr)',
sm: 'repeat(2, 1fr)',
md: 'repeat(3, 1fr)',
lg: 'repeat(4, 1fr)',
},
}}
>
{dataFiltered
.filter((i) => i.type !== 'folder')
.map((file) => (
<FileManagerFileItem
key={file.id}
file={file}
selected={selected.includes(file.id)}
onSelect={() => onSelectItem(file.id)}
onDelete={() => onDeleteItem(file.id)}
/>
))}
</Box>
</Collapse>
</>
);
const renderSelectedActions = () =>
!!selected?.length && (
<FileManagerActionSelected
numSelected={selected.length}
rowCount={dataFiltered.length}
selected={selected}
onSelectAllItems={(checked) =>
onSelectAllItems(
checked,
dataFiltered.map((row) => row.id)
)
}
action={
<>
<Button
size="small"
color="error"
variant="contained"
startIcon={<Iconify icon="solar:trash-bin-trash-bold" />}
onClick={onOpenConfirm}
sx={{ mr: 1 }}
>
Delete
</Button>
<Button
color="primary"
size="small"
variant="contained"
startIcon={<Iconify icon="solar:share-bold" />}
onClick={shareDialog.onTrue}
>
Share
</Button>
</>
}
/>
);
return (
<>
<Box ref={containerRef}>
{renderFolders()}
<Divider sx={{ my: 5, borderStyle: 'dashed' }} />
{renderFiles()}
{renderSelectedActions()}
</Box>
{renderShareDialog()}
{renderNewFilesDialog()}
{renderNewFolderDialog()}
</>
);
}