|
|
@ -4,20 +4,24 @@ import { |
|
|
|
FormControl, |
|
|
|
FormControl, |
|
|
|
FormControlLabel, |
|
|
|
FormControlLabel, |
|
|
|
FormGroup, |
|
|
|
FormGroup, |
|
|
|
|
|
|
|
Grid, |
|
|
|
styled, |
|
|
|
styled, |
|
|
|
} from '@mui/material'; |
|
|
|
} from '@mui/material'; |
|
|
|
import { |
|
|
|
import { |
|
|
|
Sync as SyncIcon, |
|
|
|
Sync as SyncIcon, |
|
|
|
SyncDisabled as SyncDisabledIcon, |
|
|
|
SyncDisabled as SyncDisabledIcon, |
|
|
|
} from '@mui/icons-material'; |
|
|
|
} from '@mui/icons-material'; |
|
|
|
|
|
|
|
import { ReactElement, useMemo } from 'react'; |
|
|
|
import { v4 as uuidv4 } from 'uuid'; |
|
|
|
import { v4 as uuidv4 } from 'uuid'; |
|
|
|
|
|
|
|
|
|
|
|
import { BLUE, RED, TEXT } from '../../lib/consts/DEFAULT_THEME'; |
|
|
|
import { BLUE, RED, TEXT } from '../../lib/consts/DEFAULT_THEME'; |
|
|
|
import { UPLOAD_FILE_TYPES_ARRAY } from '../../lib/consts/UPLOAD_FILE_TYPES'; |
|
|
|
import { UPLOAD_FILE_TYPES_ARRAY } from '../../lib/consts/UPLOAD_FILE_TYPES'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import List from '../List'; |
|
|
|
import MenuItem from '../MenuItem'; |
|
|
|
import MenuItem from '../MenuItem'; |
|
|
|
import OutlinedInput from '../OutlinedInput'; |
|
|
|
import OutlinedInput from '../OutlinedInput'; |
|
|
|
import OutlinedInputLabel from '../OutlinedInputLabel'; |
|
|
|
import OutlinedInputLabel from '../OutlinedInputLabel'; |
|
|
|
|
|
|
|
import { ExpandablePanel, InnerPanelBody } from '../Panels'; |
|
|
|
import Select from '../Select'; |
|
|
|
import Select from '../Select'; |
|
|
|
|
|
|
|
|
|
|
|
type FileInfoProps = Pick<FileDetailMetadata, 'fileName' | 'fileLocations'> & |
|
|
|
type FileInfoProps = Pick<FileDetailMetadata, 'fileName' | 'fileLocations'> & |
|
|
@ -56,6 +60,34 @@ const FileInfo = ( |
|
|
|
const fileTypeElementId = `file-type-${idExtension}`; |
|
|
|
const fileTypeElementId = `file-type-${idExtension}`; |
|
|
|
const fileTypeElementLabel = 'File type'; |
|
|
|
const fileTypeElementLabel = 'File type'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const anFileLocations = useMemo( |
|
|
|
|
|
|
|
() => |
|
|
|
|
|
|
|
fileLocations.reduce< |
|
|
|
|
|
|
|
Record< |
|
|
|
|
|
|
|
string, |
|
|
|
|
|
|
|
Pick<FileLocation, 'anvilDescription' | 'anvilName' | 'anvilUUID'> & { |
|
|
|
|
|
|
|
flocs: FileLocation[]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
>((previous, fileLocation) => { |
|
|
|
|
|
|
|
const { anvilDescription, anvilName, anvilUUID } = fileLocation; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!previous[anvilUUID]) { |
|
|
|
|
|
|
|
previous[anvilUUID] = { |
|
|
|
|
|
|
|
anvilDescription, |
|
|
|
|
|
|
|
anvilName, |
|
|
|
|
|
|
|
anvilUUID, |
|
|
|
|
|
|
|
flocs: [], |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
previous[anvilUUID].flocs.push(fileLocation); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return previous; |
|
|
|
|
|
|
|
}, {}), |
|
|
|
|
|
|
|
[fileLocations], |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<FormGroup sx={{ '> :not(:first-child)': { marginTop: '1em' } }}> |
|
|
|
<FormGroup sx={{ '> :not(:first-child)': { marginTop: '1em' } }}> |
|
|
|
<FormControl> |
|
|
|
<FormControl> |
|
|
@ -100,37 +132,68 @@ const FileInfo = ( |
|
|
|
</Select> |
|
|
|
</Select> |
|
|
|
</FormControl> |
|
|
|
</FormControl> |
|
|
|
)} |
|
|
|
)} |
|
|
|
{fileLocations.map( |
|
|
|
<List |
|
|
|
( |
|
|
|
listItems={anFileLocations} |
|
|
|
{ anvilName, anvilDescription, anvilUUID, isFileLocationActive }, |
|
|
|
listProps={{ dense: true, disablePadding: true }} |
|
|
|
fileLocationIndex, |
|
|
|
renderListItem={(anvilUUID, { anvilDescription, anvilName, flocs }) => ( |
|
|
|
) => ( |
|
|
|
<ExpandablePanel |
|
|
|
<FormControlLabel |
|
|
|
header={`${anvilName}: ${anvilDescription}`} |
|
|
|
control={ |
|
|
|
panelProps={{ padding: 0, width: '100%' }} |
|
|
|
<FileLocationActiveCheckbox |
|
|
|
> |
|
|
|
checkedIcon={<SyncIcon />} |
|
|
|
<InnerPanelBody> |
|
|
|
defaultChecked={isFileLocationActive} |
|
|
|
<Grid |
|
|
|
disabled={isReadonly} |
|
|
|
columns={{ xs: 1, sm: 2, md: 3, lg: 4, xl: 5 }} |
|
|
|
icon={<SyncDisabledIcon />} |
|
|
|
columnSpacing="1em" |
|
|
|
onChange={({ target: { checked } }) => { |
|
|
|
container |
|
|
|
onChange?.call( |
|
|
|
direction="row" |
|
|
|
null, |
|
|
|
> |
|
|
|
{ |
|
|
|
{flocs.map<ReactElement>( |
|
|
|
isFileLocationActive: |
|
|
|
({ |
|
|
|
checked === isFileLocationActive ? undefined : checked, |
|
|
|
fileLocationUUID: flocUUID, |
|
|
|
}, |
|
|
|
hostName, |
|
|
|
{ fileLocationIndex }, |
|
|
|
hostUUID, |
|
|
|
); |
|
|
|
isFileLocationActive, |
|
|
|
}} |
|
|
|
}) => ( |
|
|
|
/> |
|
|
|
<Grid item key={`floc-${anvilUUID}-${hostUUID}`} xs={1}> |
|
|
|
} |
|
|
|
<FormControlLabel |
|
|
|
key={anvilUUID} |
|
|
|
control={ |
|
|
|
label={`${anvilName}: ${anvilDescription}`} |
|
|
|
<FileLocationActiveCheckbox |
|
|
|
sx={{ color: TEXT }} |
|
|
|
checkedIcon={<SyncIcon />} |
|
|
|
value={`${anvilUUID}-sync`} |
|
|
|
defaultChecked={isFileLocationActive} |
|
|
|
/> |
|
|
|
disabled={isReadonly} |
|
|
|
), |
|
|
|
edge="start" |
|
|
|
)} |
|
|
|
icon={<SyncDisabledIcon />} |
|
|
|
|
|
|
|
onChange={({ target: { checked } }) => { |
|
|
|
|
|
|
|
onChange?.call( |
|
|
|
|
|
|
|
null, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
isFileLocationActive: |
|
|
|
|
|
|
|
checked === isFileLocationActive |
|
|
|
|
|
|
|
? undefined |
|
|
|
|
|
|
|
: checked, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
fileLocationIndex: fileLocations.findIndex( |
|
|
|
|
|
|
|
({ fileLocationUUID }) => |
|
|
|
|
|
|
|
flocUUID === fileLocationUUID, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
label={hostName} |
|
|
|
|
|
|
|
sx={{ color: TEXT }} |
|
|
|
|
|
|
|
value={`${hostUUID}-sync`} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</Grid> |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
</Grid> |
|
|
|
|
|
|
|
</InnerPanelBody> |
|
|
|
|
|
|
|
</ExpandablePanel> |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
/> |
|
|
|
</FormGroup> |
|
|
|
</FormGroup> |
|
|
|
); |
|
|
|
); |
|
|
|
}; |
|
|
|
}; |
|
|
|