mirror of
https://github.com/mudita/mudita-center.git
synced 2025-12-23 22:28:03 -05:00
File manager refactor PoC
This commit is contained in:
@@ -13,7 +13,7 @@ export const GetEntitiesConfigResponseValidator = z.object({
|
||||
fields: z.record(
|
||||
z.string(),
|
||||
z.object({
|
||||
type: z.enum(["id", "object", "string", "array", "boolean"]),
|
||||
type: z.enum(["id", "object", "string", "number", "array", "boolean"]),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
@@ -67,21 +67,11 @@ export const useApiDeviceRouter = (device?: Device) => {
|
||||
path={`${ApiDevicePaths.Index}/${DeviceManageFileFeature.Internal}`}
|
||||
>
|
||||
<Route
|
||||
path={DeviceManageFileFeature.Internal}
|
||||
element={
|
||||
<DeviceManageFilesScreen
|
||||
feature={DeviceManageFileFeature.Internal}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={DeviceManageFileFeature.External}
|
||||
element={
|
||||
<DeviceManageFilesScreen
|
||||
feature={DeviceManageFileFeature.External}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
path={`:feature/:category?`}
|
||||
element={<DeviceManageFilesScreen />}
|
||||
>
|
||||
<Route index element={<DeviceManageFilesScreen.List />} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path={`${ApiDevicePaths.Index}/mc-contacts`}>
|
||||
<Route path={"mc-contacts"} element={<McContactsScreen />} />
|
||||
|
||||
@@ -87,37 +87,35 @@ export const McContactsScreen: FunctionComponent = () => {
|
||||
)
|
||||
}, [contacts])
|
||||
|
||||
if (!feature || !contacts) {
|
||||
return (
|
||||
<LoaderWrapper
|
||||
key="loader"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<Typography.H3 message={messages.loaderTitle.id} />
|
||||
<ProgressBar value={progress} indeterminate={progress === 0} />
|
||||
</LoaderWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
const headerTitle =
|
||||
contacts.length > 0
|
||||
feature && contacts && contacts.length > 0
|
||||
? `${feature.title} (${contacts.length})`
|
||||
: feature.title
|
||||
: feature?.title || "All contacts"
|
||||
|
||||
return (
|
||||
<>
|
||||
<DashboardHeaderTitle title={headerTitle} />
|
||||
<Content
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<Contacts contacts={sortedContacts} onDelete={handleDelete} />
|
||||
</Content>
|
||||
{!feature || !contacts ? (
|
||||
<LoaderWrapper
|
||||
key="loader"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<Typography.H3 message={messages.loaderTitle.id} />
|
||||
<ProgressBar value={progress} indeterminate={progress === 0} />
|
||||
</LoaderWrapper>
|
||||
) : (
|
||||
<Content
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<Contacts contacts={sortedContacts} onDelete={handleDelete} />
|
||||
</Content>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,29 +8,36 @@ import { DashboardHeaderTitle } from "app-routing/feature"
|
||||
import { ApiDevice } from "devices/api-device/models"
|
||||
import { AppResultFactory } from "app-utils/models"
|
||||
import {
|
||||
openFileDialog,
|
||||
useActiveDeviceQuery,
|
||||
useManageFilesSelection,
|
||||
} from "devices/common/feature"
|
||||
import {
|
||||
FileTransferResult,
|
||||
ManageFiles,
|
||||
ManageFiles2,
|
||||
manageFilesMessages,
|
||||
ManageFilesViewProps,
|
||||
} from "devices/common/ui"
|
||||
import { useApiDeviceDeleteEntitiesMutation } from "devices/api-device/feature"
|
||||
import { DeviceManageFilesTableSection } from "./device-manage-files-table-section"
|
||||
import { deviceManageFilesMessages } from "./device-manage-files.messages"
|
||||
import { useDeviceManageFiles } from "./use-device-manage-files"
|
||||
import { OTHER_FILES_LABEL_TEXTS } from "./device-manage-files.config"
|
||||
import {
|
||||
DeviceManageFileFeature,
|
||||
DeviceManageFileFeatureId,
|
||||
} from "./device-manage-files.types"
|
||||
import { ProgressBar, Typography } from "app-theme/ui"
|
||||
import styled from "styled-components"
|
||||
import { motion } from "motion/react"
|
||||
import { Navigate, useParams } from "react-router"
|
||||
import { List } from "./list"
|
||||
import { OTHER_FILES_LABEL_TEXTS } from "./device-manage-files.config"
|
||||
|
||||
export const DeviceManageFilesScreen: FunctionComponent<{
|
||||
feature: DeviceManageFileFeatureId
|
||||
}> = ({ feature }) => {
|
||||
export const DeviceManageFilesScreen: FunctionComponent & {
|
||||
List: typeof List
|
||||
} = () => {
|
||||
const { feature, category } = useParams<{
|
||||
feature: string
|
||||
category?: string
|
||||
}>()
|
||||
const { data: device } = useActiveDeviceQuery<ApiDevice>()
|
||||
const {
|
||||
isLoading,
|
||||
@@ -42,73 +49,137 @@ export const DeviceManageFilesScreen: FunctionComponent<{
|
||||
otherSpaceBytes,
|
||||
refetch,
|
||||
progress,
|
||||
} = useDeviceManageFiles(feature, device)
|
||||
} = useDeviceManageFiles(feature as DeviceManageFileFeatureId, device)
|
||||
|
||||
const { mutateAsync: deleteFilesMutate } =
|
||||
useApiDeviceDeleteEntitiesMutation(device)
|
||||
console.log({
|
||||
segments,
|
||||
categories,
|
||||
categoryFileMap,
|
||||
freeSpaceBytes,
|
||||
usedSpaceBytes,
|
||||
otherSpaceBytes,
|
||||
})
|
||||
|
||||
const { activeCategoryId, setActiveCategoryId, activeFileMap } =
|
||||
useManageFilesSelection({ categories, categoryFileMap })
|
||||
// const { mutateAsync: deleteFilesMutate } =
|
||||
// useApiDeviceDeleteEntitiesMutation(device)
|
||||
|
||||
// const { activeCategoryId, setActiveCategoryId, activeFileMap } =
|
||||
// useManageFilesSelection({ categories, categoryFileMap })
|
||||
|
||||
const summaryHeader =
|
||||
feature === DeviceManageFileFeature.Internal
|
||||
? deviceManageFilesMessages.internalSummaryHeader
|
||||
: deviceManageFilesMessages.externalSummaryHeader
|
||||
|
||||
const addFileButtonText =
|
||||
activeCategoryId === "applicationFiles"
|
||||
? deviceManageFilesMessages.addAppFileButtonText
|
||||
: manageFilesMessages.addFileButtonText
|
||||
// const addFileButtonText =
|
||||
// activeCategoryId === "applicationFiles"
|
||||
// ? deviceManageFilesMessages.addAppFileButtonText
|
||||
// : manageFilesMessages.addFileButtonText
|
||||
|
||||
const messages = {
|
||||
...deviceManageFilesMessages,
|
||||
summaryHeader,
|
||||
addFileButtonText,
|
||||
// addFileButtonText,
|
||||
}
|
||||
|
||||
const transferFile: ManageFilesViewProps["transferFile"] = async (
|
||||
_params
|
||||
): Promise<FileTransferResult> => {
|
||||
// TODO: Implement file transfer logic here
|
||||
return AppResultFactory.success<FileTransferResult>()
|
||||
}
|
||||
|
||||
const deleteFiles: ManageFilesViewProps["deleteFiles"] = async (
|
||||
ids: string[]
|
||||
): Promise<{ failedIds: string[] }> => {
|
||||
const { failedIds = [] } = await deleteFilesMutate({
|
||||
entityType: activeCategoryId,
|
||||
ids,
|
||||
})
|
||||
return { failedIds }
|
||||
}
|
||||
// const transferFile: ManageFilesViewProps["transferFile"] = async (
|
||||
// _params
|
||||
// ): Promise<FileTransferResult> => {
|
||||
// // TODO: Implement file transfer logic here
|
||||
// return AppResultFactory.success<FileTransferResult>()
|
||||
// }
|
||||
//
|
||||
// const deleteFiles: ManageFilesViewProps["deleteFiles"] = async (
|
||||
// ids: string[]
|
||||
// ): Promise<{ failedIds: string[] }> => {
|
||||
// const { failedIds = [] } = await deleteFilesMutate({
|
||||
// entityType: activeCategoryId,
|
||||
// ids,
|
||||
// })
|
||||
// return { failedIds }
|
||||
// }
|
||||
|
||||
console.log({ categories })
|
||||
return (
|
||||
<>
|
||||
<DashboardHeaderTitle title={"Manage Files"} />
|
||||
<ManageFiles
|
||||
activeCategoryId={activeCategoryId}
|
||||
activeFileMap={activeFileMap}
|
||||
onActiveCategoryChange={setActiveCategoryId}
|
||||
segments={segments}
|
||||
categories={categories}
|
||||
freeSpaceBytes={freeSpaceBytes}
|
||||
usedSpaceBytes={usedSpaceBytes}
|
||||
otherSpaceBytes={otherSpaceBytes}
|
||||
deleteFiles={deleteFiles}
|
||||
onDeleteSuccess={refetch}
|
||||
isLoading={isLoading}
|
||||
otherFiles={OTHER_FILES_LABEL_TEXTS}
|
||||
openFileDialog={openFileDialog}
|
||||
transferFile={transferFile}
|
||||
messages={messages}
|
||||
onTransferSuccess={refetch}
|
||||
progress={progress}
|
||||
>
|
||||
{(props) => (
|
||||
<DeviceManageFilesTableSection fileMap={activeFileMap} {...props} />
|
||||
)}
|
||||
</ManageFiles>
|
||||
{!feature || isLoading ? (
|
||||
<LoaderWrapper
|
||||
key="loader"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<Typography.H3 message={messages.loadStateText.id} />
|
||||
<ProgressBar value={progress} indeterminate={progress === 0} />
|
||||
</LoaderWrapper>
|
||||
) : (
|
||||
<>
|
||||
{!category && categories && <Navigate to={categories[0].id} />}
|
||||
<Content
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<ManageFiles2
|
||||
segments={segments}
|
||||
categories={categories}
|
||||
freeSpaceBytes={freeSpaceBytes}
|
||||
usedSpaceBytes={usedSpaceBytes}
|
||||
otherSpaceBytes={otherSpaceBytes}
|
||||
otherFiles={OTHER_FILES_LABEL_TEXTS}
|
||||
messages={messages}
|
||||
/>
|
||||
{/*<ManageFiles*/}
|
||||
{/* activeCategoryId={activeCategoryId}*/}
|
||||
{/* activeFileMap={activeFileMap}*/}
|
||||
{/* onActiveCategoryChange={setActiveCategoryId}*/}
|
||||
{/* segments={segments}*/}
|
||||
{/* categories={categories}*/}
|
||||
{/* freeSpaceBytes={freeSpaceBytes}*/}
|
||||
{/* usedSpaceBytes={usedSpaceBytes}*/}
|
||||
{/* otherSpaceBytes={otherSpaceBytes}*/}
|
||||
{/* deleteFiles={deleteFiles}*/}
|
||||
{/* onDeleteSuccess={refetch}*/}
|
||||
{/* otherFiles={OTHER_FILES_LABEL_TEXTS}*/}
|
||||
{/* openFileDialog={openFileDialog}*/}
|
||||
{/* transferFile={transferFile}*/}
|
||||
{/* messages={messages}*/}
|
||||
{/* onTransferSuccess={refetch}*/}
|
||||
{/*>*/}
|
||||
{/* {(props) => (*/}
|
||||
{/* <DeviceManageFilesTableSection*/}
|
||||
{/* fileMap={activeFileMap}*/}
|
||||
{/* {...props}*/}
|
||||
{/* />*/}
|
||||
{/* )}*/}
|
||||
{/*</ManageFiles>*/}
|
||||
</Content>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
DeviceManageFilesScreen.List = List
|
||||
|
||||
const LoaderWrapper = styled(motion.div)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2.4rem;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
`
|
||||
|
||||
const Content = styled(motion.div)`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: ${({ theme }) => theme.app.color.white};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow-x: hidden;
|
||||
`
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) Mudita sp. z o.o. All rights reserved.
|
||||
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { FunctionComponent } from "react"
|
||||
import { useParams } from "react-router"
|
||||
import { useApiEntitiesDataQuery } from "devices/api-device/feature"
|
||||
import { useActiveDeviceQuery } from "devices/common/feature"
|
||||
import { ApiDevice } from "devices/api-device/models"
|
||||
import { ManageFiles2 } from "devices/common/ui"
|
||||
|
||||
export const List: FunctionComponent = () => {
|
||||
const { category } = useParams()
|
||||
const { data: device } = useActiveDeviceQuery<ApiDevice>()
|
||||
const { data: entities = [] } = useApiEntitiesDataQuery(category, device)
|
||||
|
||||
const files = entities.map((entity) => {
|
||||
return {
|
||||
id: entity.id as string,
|
||||
name: entity.fileName as string,
|
||||
size: entity.fileSize as number,
|
||||
type: entity.extension as string,
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<ManageFiles2.List
|
||||
files={files}
|
||||
onDelete={() => {
|
||||
//
|
||||
}}
|
||||
onAdd={() => {
|
||||
//
|
||||
}}
|
||||
onExport={() => {
|
||||
//
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ export * from "./lib/device-troubleshooting/device-troubleshooting"
|
||||
export * from "./lib/welcome-screen/welcome-screen"
|
||||
export * from "./lib/views/manage-files/manage-files.messages"
|
||||
export * from "./lib/views/manage-files/manage-files"
|
||||
export * from "./lib/views/manage-files/manage-files-2"
|
||||
export * from "./lib/views/manage-files/manage-files.types"
|
||||
export * from "./lib/views/overview/overview"
|
||||
export * from "./lib/views/overview/overview-status-item"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) Mudita sp. z o.o. All rights reserved.
|
||||
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { FunctionComponent, PropsWithChildren } from "react"
|
||||
import { FormProvider, useForm } from "react-hook-form"
|
||||
|
||||
export interface FormValues {
|
||||
selectedFiles: Record<string, boolean>
|
||||
activeFileId?: string
|
||||
}
|
||||
|
||||
export const Form: FunctionComponent<PropsWithChildren> = ({ children }) => {
|
||||
const form = useForm<FormValues>({
|
||||
defaultValues: {
|
||||
selectedFiles: {},
|
||||
activeFileId: undefined,
|
||||
},
|
||||
})
|
||||
|
||||
return <FormProvider {...form}>{children}</FormProvider>
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Copyright (c) Mudita sp. z o.o. All rights reserved.
|
||||
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { FunctionComponent, useCallback } from "react"
|
||||
import styled from "styled-components"
|
||||
import { Form, FormValues } from "./manage-files-2-form"
|
||||
import { useFormContext } from "react-hook-form"
|
||||
import { Checkbox, TableNew, Tooltip } from "app-theme/ui"
|
||||
import { Contact } from "devices/common/models"
|
||||
import {
|
||||
ColumnCheckbox,
|
||||
ColumnMorePhones,
|
||||
ColumnName,
|
||||
ColumnPhone,
|
||||
} from "../contacts/columns"
|
||||
import { CheckboxSize } from "app-theme/models"
|
||||
|
||||
interface File {
|
||||
id: string
|
||||
name: string
|
||||
size: number
|
||||
type: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
files: File[]
|
||||
onAdd: (file: File) => void
|
||||
onDelete?: (fileId: string) => void
|
||||
onSelect?: (fileId: string) => void
|
||||
onExport?: (fileId: string) => void
|
||||
}
|
||||
|
||||
export const ManageFiles2List: FunctionComponent<Props> = (props) => {
|
||||
return (
|
||||
<Form>
|
||||
<ManageFiles2ListInner {...props} />
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
const ManageFiles2ListInner: FunctionComponent<Props> = ({
|
||||
files,
|
||||
onAdd,
|
||||
onDelete,
|
||||
onSelect,
|
||||
onExport,
|
||||
}) => {
|
||||
const { watch, register } = useFormContext<FormValues>()
|
||||
|
||||
const activeFileId = watch("activeFileId")
|
||||
|
||||
const rowRenderer = useCallback(
|
||||
(file: File) => {
|
||||
const onClick = onSelect
|
||||
? () => {
|
||||
onSelect(file.id)
|
||||
}
|
||||
: undefined
|
||||
return (
|
||||
<TableNew.Row
|
||||
key={file.id}
|
||||
onClick={onClick}
|
||||
rowSelectorCheckboxDataAttr={"data-row-checkbox"}
|
||||
active={activeFileId === file.id}
|
||||
>
|
||||
<div style={{ width: 80 }}>
|
||||
<Tooltip placement={"bottom-right"} offset={{ x: 24, y: 5 }}>
|
||||
<Tooltip.Anchor>
|
||||
<CustomCheckbox
|
||||
data-row-checkbox
|
||||
key={file.id}
|
||||
size={CheckboxSize.Small}
|
||||
{...register(`selectedFiles.${file.id}`)}
|
||||
/>
|
||||
</Tooltip.Anchor>
|
||||
<Tooltip.Content>Select</Tooltip.Content>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>{file.name}</div>
|
||||
<div style={{ width: 120 }}>{file.type}</div>
|
||||
<div style={{ width: 120 }}>{file.size} bytes</div>
|
||||
</TableNew.Row>
|
||||
)
|
||||
},
|
||||
[activeFileId, onSelect, register]
|
||||
)
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<TableNew itemIdField={"id"} items={files} rowRenderer={rowRenderer} />
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
|
||||
const Wrapper = styled.div`
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`
|
||||
|
||||
const CustomCheckbox = styled(Checkbox)`
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) Mudita sp. z o.o. All rights reserved.
|
||||
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { ComponentProps, FunctionComponent } from "react"
|
||||
import { Outlet } from "react-router"
|
||||
import styled from "styled-components"
|
||||
import { ManageFilesStorageSummary } from "./manage-files-content/manage-files-storage-summary"
|
||||
import { ManageFilesCategoryList } from "./manage-files-content/manage-files-category-list"
|
||||
import { ManageFilesOtherFiles } from "./manage-files-content/manage-files-other-files"
|
||||
import { ManageFiles2List } from "./manage-files-2-list"
|
||||
|
||||
type Props = ComponentProps<typeof ManageFilesStorageSummary> &
|
||||
ComponentProps<typeof ManageFilesCategoryList> &
|
||||
ComponentProps<typeof ManageFilesOtherFiles>
|
||||
|
||||
export const ManageFiles2: FunctionComponent<Props> & {
|
||||
List: typeof ManageFiles2List
|
||||
} = ({
|
||||
otherFiles,
|
||||
categories,
|
||||
segments,
|
||||
freeSpaceBytes,
|
||||
usedSpaceBytes,
|
||||
otherSpaceBytes,
|
||||
messages,
|
||||
}) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<Sidebar>
|
||||
<ManageFilesStorageSummary
|
||||
freeSpaceBytes={freeSpaceBytes}
|
||||
usedSpaceBytes={usedSpaceBytes}
|
||||
segments={segments}
|
||||
messages={messages}
|
||||
/>
|
||||
<ManageFilesCategoryList categories={categories} />
|
||||
<ManageFilesOtherFiles
|
||||
otherFiles={otherFiles}
|
||||
otherSpaceBytes={otherSpaceBytes}
|
||||
/>
|
||||
</Sidebar>
|
||||
<Content>
|
||||
<Outlet />
|
||||
</Content>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
ManageFiles2.List = ManageFiles2List
|
||||
|
||||
const Wrapper = styled.div`
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 31.2rem 1fr;
|
||||
grid-template-areas: "sidebar content";
|
||||
`
|
||||
|
||||
const Sidebar = styled.div`
|
||||
grid-area: sidebar;
|
||||
flex: 1;
|
||||
border-right: 0.1rem solid ${({ theme }) => theme.app.color.grey4};
|
||||
`
|
||||
|
||||
const Content = styled.div`
|
||||
grid-area: content;
|
||||
flex: 1;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
`
|
||||
@@ -5,53 +5,49 @@
|
||||
|
||||
import { FunctionComponent } from "react"
|
||||
import styled from "styled-components"
|
||||
import { noop } from "lodash"
|
||||
import { formatMessage } from "app-localize/utils"
|
||||
import { Icon, ListItem, Marker, Typography } from "app-theme/ui"
|
||||
import { IconSize } from "app-theme/models"
|
||||
import { FileManagerFileCategory } from "../manage-files.types"
|
||||
import { manageFilesMessages } from "../manage-files.messages"
|
||||
import { NavLink } from "react-router"
|
||||
|
||||
export interface ManageFilesCategoryListProps {
|
||||
categories: FileManagerFileCategory[]
|
||||
activeCategoryId: string
|
||||
onCategoryClick?: (categoryId: string) => void
|
||||
}
|
||||
|
||||
export const ManageFilesCategoryList: FunctionComponent<
|
||||
ManageFilesCategoryListProps
|
||||
> = ({ categories, activeCategoryId, onCategoryClick = noop }) => {
|
||||
> = ({ categories }) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
{categories.map((category) => (
|
||||
<CategoryListItem
|
||||
key={category.id}
|
||||
active={category.id === activeCategoryId}
|
||||
onClick={() => onCategoryClick(category.id)}
|
||||
>
|
||||
<CategoryListItemName>
|
||||
<CategoryListItemNameIcon
|
||||
size={IconSize.Big}
|
||||
type={category.icon}
|
||||
></CategoryListItemNameIcon>
|
||||
<CategoryListItemNameText>
|
||||
{category.label}
|
||||
</CategoryListItemNameText>
|
||||
</CategoryListItemName>
|
||||
<CategoryListItemStorage>
|
||||
<CategoryListItemStorageText>
|
||||
{category.size}
|
||||
</CategoryListItemStorageText>
|
||||
<CategoryListItemStorageMarker
|
||||
$color={category.markerColor}
|
||||
></CategoryListItemStorageMarker>
|
||||
</CategoryListItemStorage>
|
||||
<CategoryListItemCountTextWrapper>
|
||||
{formatMessage(manageFilesMessages.categoryCount, {
|
||||
count: Number(category.count),
|
||||
})}
|
||||
</CategoryListItemCountTextWrapper>
|
||||
</CategoryListItem>
|
||||
<Link to={`../${category.id}`} relative={"path"}>
|
||||
{({ isActive }) => (
|
||||
<CategoryListItem key={category.id} active={isActive}>
|
||||
<CategoryListItemName>
|
||||
<CategoryListItemNameIcon
|
||||
size={IconSize.Big}
|
||||
type={category.icon}
|
||||
/>
|
||||
<CategoryListItemNameText>
|
||||
{category.label}
|
||||
</CategoryListItemNameText>
|
||||
</CategoryListItemName>
|
||||
<CategoryListItemStorage>
|
||||
<CategoryListItemStorageText>
|
||||
{category.size}
|
||||
</CategoryListItemStorageText>
|
||||
<CategoryListItemStorageMarker $color={category.markerColor} />
|
||||
</CategoryListItemStorage>
|
||||
<CategoryListItemCountTextWrapper>
|
||||
{formatMessage(manageFilesMessages.categoryCount, {
|
||||
count: Number(category.count),
|
||||
})}
|
||||
</CategoryListItemCountTextWrapper>
|
||||
</CategoryListItem>
|
||||
)}
|
||||
</Link>
|
||||
))}
|
||||
</Wrapper>
|
||||
)
|
||||
@@ -62,6 +58,11 @@ const Wrapper = styled.div`
|
||||
flex-direction: column;
|
||||
`
|
||||
|
||||
const Link = styled(NavLink)`
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
`
|
||||
|
||||
const CategoryListItem = styled(ListItem)`
|
||||
padding: 1.2rem 3.2rem 1rem 3.2rem;
|
||||
display: grid;
|
||||
|
||||
@@ -40,7 +40,6 @@ interface Props
|
||||
> {
|
||||
selectedFiles: FileManagerFile[]
|
||||
onAddFileClick?: () => void
|
||||
opened: boolean
|
||||
allFilesSelected: boolean
|
||||
messages: ManageFilesStorageSummaryProps["messages"] &
|
||||
ManageFilesFileListEmptyProps["messages"] &
|
||||
@@ -50,7 +49,6 @@ interface Props
|
||||
export const ManageFilesContent: FunctionComponent<
|
||||
Props & PropsWithChildren
|
||||
> = ({
|
||||
opened,
|
||||
categories,
|
||||
segments,
|
||||
activeCategoryId,
|
||||
@@ -74,10 +72,6 @@ export const ManageFilesContent: FunctionComponent<
|
||||
|
||||
const fileListPanelHeader = `${activeCategory?.label} ${activeCategory?.count ? `(${activeCategory.count})` : ""}`
|
||||
|
||||
if (!opened) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<CategoriesSidebar>
|
||||
|
||||
@@ -57,14 +57,14 @@ export interface ManageFilesViewProps
|
||||
> {
|
||||
activeFileMap: FileManagerFileMap
|
||||
onActiveCategoryChange: (categoryId: string) => void
|
||||
isLoading: boolean
|
||||
children: ManageFilesViewChild
|
||||
messages: ManageFilesViewMessages
|
||||
deleteFiles: GenericDeleteFlowProps["deleteItemsAction"]
|
||||
onDeleteSuccess?: VoidFunction
|
||||
progress?: number
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const ManageFiles: FunctionComponent<ManageFilesViewProps> = (props) => {
|
||||
const {
|
||||
messages,
|
||||
@@ -76,7 +76,6 @@ export const ManageFiles: FunctionComponent<ManageFilesViewProps> = (props) => {
|
||||
transferFile,
|
||||
onTransferSuccess,
|
||||
openFileDialog,
|
||||
isLoading,
|
||||
categories,
|
||||
segments,
|
||||
freeSpaceBytes,
|
||||
@@ -84,7 +83,6 @@ export const ManageFiles: FunctionComponent<ManageFilesViewProps> = (props) => {
|
||||
otherSpaceBytes,
|
||||
otherFiles,
|
||||
children,
|
||||
progress,
|
||||
} = props
|
||||
const genericDeleteRef = useRef<GenericDeleteFlow>(null)
|
||||
|
||||
@@ -139,8 +137,6 @@ export const ManageFiles: FunctionComponent<ManageFilesViewProps> = (props) => {
|
||||
[activeCategoryId, onActiveCategoryChange]
|
||||
)
|
||||
|
||||
const loadingState = isLoading || activeCategoryId === undefined
|
||||
|
||||
const finalizeDeleteSuccess: NonNullable<
|
||||
GenericDeleteFlowProps["onDeleteSuccess"]
|
||||
> = useCallback(
|
||||
@@ -172,13 +168,7 @@ export const ManageFiles: FunctionComponent<ManageFilesViewProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<LoadingState
|
||||
opened={loadingState}
|
||||
message={manageFilesMessages.loadStateText.id}
|
||||
progress={progress}
|
||||
/>
|
||||
<ManageFilesContent
|
||||
opened={!loadingState}
|
||||
segments={segments}
|
||||
categories={categories}
|
||||
activeCategoryId={activeCategoryId}
|
||||
|
||||
Reference in New Issue
Block a user