Skip to content

Commit

Permalink
feat(ui): file info modal (#364)
Browse files Browse the repository at this point in the history
  • Loading branch information
bouassaba authored Oct 23, 2024
1 parent 003aeb7 commit 145ffd3
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 28 deletions.
53 changes: 53 additions & 0 deletions ui/src/components/file/file-info.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
} from '@chakra-ui/react'
import cx from 'classnames'
import FileAPI from '@/client/api/file'
import FileInfoEmbed from '@/components/file/info/file-info-embed'
import { useAppDispatch, useAppSelector } from '@/store/hook'
import { infoModalDidClose } from '@/store/ui/files'

const FileInfo = () => {
const dispatch = useAppDispatch()
const isModalOpen = useAppSelector((state) => state.ui.files.isInfoModalOpen)
const id = useAppSelector((state) => state.ui.files.selection[0])
const { data: file } = FileAPI.useGet(id)

if (!file) {
return null
}

return (
<Modal isOpen={isModalOpen} onClose={() => dispatch(infoModalDidClose())}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Info</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FileInfoEmbed file={file} />
</ModalBody>
<ModalFooter>
<div className={cx('flex', 'flex-row', 'items-center', 'gap-1')}>
<Button
type="button"
variant="outline"
colorScheme="blue"
onClick={() => dispatch(infoModalDidClose())}
>
Close
</Button>
</div>
</ModalFooter>
</ModalContent>
</Modal>
)
}

export default FileInfo
30 changes: 30 additions & 0 deletions ui/src/components/file/file-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
IconFileCopy,
IconGroup,
IconHistory,
IconInfo,
IconModeHeat,
IconMoreVert,
IconSelectCheckBox,
Expand All @@ -56,6 +57,7 @@ import { useAppDispatch, useAppSelector } from '@/store/hook'
import {
copyModalDidOpen,
deleteModalDidOpen,
infoModalDidOpen,
moveModalDidOpen,
renameModalDidOpen,
selectionUpdated,
Expand Down Expand Up @@ -160,6 +162,10 @@ const FileMenu = ({
() => file !== undefined && geEditorPermission(file.permission),
[file],
)
const isInfoAuthorized = useMemo(
() => file !== undefined && geViewerPermission(file.permission),
[file],
)
const isToolsAuthorized = useMemo(
() => isInsightsAuthorized || isMosaicAuthorized,
[isInsightsAuthorized, isMosaicAuthorized],
Expand Down Expand Up @@ -428,6 +434,30 @@ const FileMenu = ({
</MenuItem>
</MenuOptionGroup>
) : null}
<MenuOptionGroup>
<MenuDivider />
<MenuItem
icon={<IconInfo />}
isDisabled={!isInfoAuthorized}
onClick={(event: MouseEvent) => {
event.stopPropagation()
dispatch(infoModalDidOpen())
}}
>
<div className={cx('flex', 'flex-row', 'justify-between')}>
<span>Info</span>
{isMacOS ? (
<div>
<Kbd></Kbd>+<Kbd>E</Kbd>
</div>
) : (
<div>
<Kbd>Ctrl</Kbd>+<Kbd>E</Kbd>
</div>
)}
</div>
</MenuItem>
</MenuOptionGroup>
</MenuList>
</Portal>
</Menu>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/file/file-rename.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const FileRename = () => {
>
<ModalOverlay />
<ModalContent>
<ModalHeader>Rename File</ModalHeader>
<ModalHeader>Rename Item</ModalHeader>
<ModalCloseButton />
<Formik
enableReinitialize={true}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// licenses/AGPL.txt.
import cx from 'classnames'
import { File } from '@/client/api/file'
import FileInfoItemCount from '@/components/file/info/file-info-item-count'
import FileInfoCreateTime from './file-info-create-time'
import FileInfoExtension from './file-info-extension'
import FileInfoImage from './file-info-image'
Expand All @@ -17,25 +18,21 @@ import FileInfoSize from './file-info-size'
import FileInfoStorageUsage from './file-info-storage-usage'
import FileInfoUpdateTime from './file-info-update-time'

export type DrawerFileInfoProps = {
export type FileInfoEmbedProps = {
file: File
}

const DrawerFileInfo = ({ file }: DrawerFileInfoProps) => {
if (!file.snapshot?.original) {
return null
}
return (
<div className={cx('flex', 'flex-col', 'gap-1')}>
<FileInfoImage file={file} />
<FileInfoSize file={file} />
<FileInfoExtension file={file} />
<FileInfoStorageUsage file={file} />
<FileInfoPermission file={file} />
<FileInfoCreateTime file={file} />
<FileInfoUpdateTime file={file} />
</div>
)
}
const FileInfoEmbed = ({ file }: FileInfoEmbedProps) => (
<div className={cx('flex', 'flex-col', 'gap-1')}>
<FileInfoImage file={file} />
<FileInfoSize file={file} />
<FileInfoExtension file={file} />
<FileInfoItemCount file={file} />
<FileInfoStorageUsage file={file} />
<FileInfoPermission file={file} />
<FileInfoCreateTime file={file} />
<FileInfoUpdateTime file={file} />
</div>
)

export default DrawerFileInfo
export default FileInfoEmbed
32 changes: 32 additions & 0 deletions ui/src/components/file/info/file-info-item-count.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Stat, StatLabel, StatNumber } from '@chakra-ui/react'
import cx from 'classnames'
import FileAPI, { File, FileType } from '@/client/api/file'

export type FileInfoItemCountProps = {
file: File
}

const FileInfoItemCount = ({ file }: FileInfoItemCountProps) => {
const { data: count, error } = FileAPI.useGetCount(file.id)

if (file.type !== FileType.Folder) {
return null
}

return (
<Stat>
<StatLabel>Item count</StatLabel>
<StatNumber className={cx('text-base')}>
<div className={cx('flex', 'flex-col', 'gap-0.5')}>
{error ? (
<span className={cx('text-red-500')}>Failed to load.</span>
) : null}
{count && !error ? <span>{count}</span> : null}
{!count && !error ? <span>Calculating…</span> : null}
</div>
</StatNumber>
</Stat>
)
}

export default FileInfoItemCount
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type FileInfoStorageUsageProps = {
}

const FileInfoStorageUsage = ({ file }: FileInfoStorageUsageProps) => {
const { data, error } = StorageAPI.useGetFileUsage(file.id)
const { data: usage, error } = StorageAPI.useGetFileUsage(file.id)
return (
<Stat>
<StatLabel>Storage usage</StatLabel>
Expand All @@ -27,15 +27,15 @@ const FileInfoStorageUsage = ({ file }: FileInfoStorageUsageProps) => {
{error ? (
<span className={cx('text-red-500')}>Failed to load.</span>
) : null}
{data && !error ? (
{usage && !error ? (
<>
<span>
{prettyBytes(data.bytes)} of {prettyBytes(data.maxBytes)} used
{prettyBytes(usage.bytes)} of {prettyBytes(usage.maxBytes)} used
</span>
<Progress size="sm" value={data.percentage} hasStripe />
<Progress size="sm" value={usage.percentage} hasStripe />
</>
) : null}
{!data && !error ? (
{!usage && !error ? (
<>
<span>Calculating…</span>
<Progress size="sm" value={0} hasStripe />
Expand Down
9 changes: 9 additions & 0 deletions ui/src/components/file/list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
contextMenuDidOpen,
copyModalDidOpen,
deleteModalDidOpen,
infoModalDidOpen,
moveModalDidOpen,
multiSelectKeyUpdated,
rangeSelectKeyUpdated,
Expand Down Expand Up @@ -63,6 +64,7 @@ const FileList = ({ list, scale }: FileListProps) => {
state.ui.files.isCreateModalOpen ||
state.ui.files.isShareModalOpen ||
state.ui.files.isRenameModalOpen ||
state.ui.files.isInfoModalOpen ||
state.ui.mosaic.isModalOpen ||
state.ui.insights.isModalOpen,
)
Expand Down Expand Up @@ -170,6 +172,13 @@ const FileList = ({ list, scale }: FileListProps) => {
if (selection.length > 0) {
dispatch(moveModalDidOpen())
}
} else if (
(keyName === 'command+e' && isMacOS()) ||
(keyName === 'ctrl+e' && !isMacOS())
) {
if (selection.length > 0) {
dispatch(infoModalDidOpen())
}
} else if (
(keyName === 'command+e' && isMacOS()) ||
(keyName === 'f2' && !isMacOS())
Expand Down
16 changes: 14 additions & 2 deletions ui/src/components/snapshot/snapshot-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ import {
Tr,
} from '@chakra-ui/react'
import cx from 'classnames'
import SnapshotAPI, { Snapshot, SortOrder } from '@/client/api/snapshot'
import SnapshotAPI, { Snapshot, SortBy, SortOrder } from '@/client/api/snapshot'
import { swrConfig } from '@/client/options'
import Pagination from '@/lib/components/pagination'
import SectionSpinner from '@/lib/components/section-spinner'
import prettyBytes from '@/lib/helpers/pretty-bytes'
import prettyDate from '@/lib/helpers/pretty-date'
import { useAppDispatch, useAppSelector } from '@/store/hook'
import {
Expand All @@ -53,7 +54,13 @@ const SnapshotList = () => {
error,
mutate: snapshotMutate,
} = SnapshotAPI.useList(
{ fileId, page, size: 5, sortOrder: SortOrder.Desc },
{
fileId,
page,
size: 5,
sortBy: SortBy.Version,
sortOrder: SortOrder.Desc,
},
swrConfig(),
)

Expand Down Expand Up @@ -181,6 +188,11 @@ const SnapshotList = () => {
</span>
<div className={cx('flex', 'flex-row', 'gap-1')}>
<Badge variant="outline">{`v${s.version}`}</Badge>
{s.original.size ? (
<Badge variant="outline">
{prettyBytes(s.original.size)}
</Badge>
) : null}
{s.entities ? (
<Badge variant="outline">Insights</Badge>
) : null}
Expand Down
4 changes: 2 additions & 2 deletions ui/src/components/viewer/drawer/drawer-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
import { useContext } from 'react'
import cx from 'classnames'
import { File } from '@/client/api/file'
import FileInfoEmbed from '@/components/file/info/file-info-embed'
import { DrawerContext } from '@/lib/components/drawer'
import { IconInfo } from '@/lib/components/icons'
import SwitchCard from '@/lib/components/switch-card'
import DrawerDownloadButton from './drawer-download-button'
import DrawerOpenNewTabButton from './drawer-open-new-tab-button'
import DrawerFileInfo from './file-info'

export type DrawerContentProps = {
file: File
Expand All @@ -34,7 +34,7 @@ const DrawerContent = ({ file }: DrawerContentProps) => {
localStorageNamespace="file_info"
expandedMinWidth="200px"
>
<DrawerFileInfo file={file} />
<FileInfoEmbed file={file} />
</SwitchCard>
</div>
)
Expand Down
5 changes: 5 additions & 0 deletions ui/src/pages/workspace/workspace-files-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Path from '@/components/common/path'
import FileCopy from '@/components/file/file-copy'
import FileCreate from '@/components/file/file-create'
import FileDelete from '@/components/file/file-delete'
import FileInfo from '@/components/file/file-info'
import FileMove from '@/components/file/file-move'
import FileRename from '@/components/file/file-rename'
import SearchFilter from '@/components/file/file-search-filter'
Expand Down Expand Up @@ -69,6 +70,9 @@ const WorkspaceFilesPage = () => {
const isRenameModalOpen = useAppSelector(
(state) => state.ui.files.isRenameModalOpen,
)
const isInfoModalOpen = useAppSelector(
(state) => state.ui.files.isInfoModalOpen,
)
const isInsightsModalOpen = useAppSelector(
(state) => state.ui.insights.isModalOpen,
)
Expand Down Expand Up @@ -215,6 +219,7 @@ const WorkspaceFilesPage = () => {
{isCreateModalOpen ? <FileCreate /> : null}
{isDeleteModalOpen ? <FileDelete /> : null}
{isRenameModalOpen ? <FileRename /> : null}
{isInfoModalOpen ? <FileInfo /> : null}
{isInsightsModalOpen ? <Insights /> : null}
{isMosaicModalOpen ? <Mosaic /> : null}
{isSearchFilterModalOpen ? <SearchFilter /> : null}
Expand Down
Loading

0 comments on commit 145ffd3

Please sign in to comment.