fix(fe/panel_files): key is not defined for file infos

This commit is contained in:
hexxa 2022-04-05 17:53:15 +08:00 committed by Hexxa
parent 40cce63350
commit 503bafb604
3 changed files with 137 additions and 126 deletions

View file

@ -7,6 +7,7 @@ export interface Props {
childrenClassNames?: List<string>; childrenClassNames?: List<string>;
style?: React.CSSProperties; style?: React.CSSProperties;
className?: string; className?: string;
colKey?: string;
} }
export const Columns = (props: Props) => { export const Columns = (props: Props) => {
@ -15,9 +16,10 @@ export const Columns = (props: Props) => {
const cells = row.map((cell: React.ReactNode, j: number) => { const cells = row.map((cell: React.ReactNode, j: number) => {
const width = props.widths.get(j, Math.trunc(100 / row.size)); const width = props.widths.get(j, Math.trunc(100 / row.size));
const className = props.childrenClassNames.get(j, ""); const className = props.childrenClassNames.get(j, "");
return ( return (
<div <div
key={`td-${i}-${j}`} key={`${props.colKey}-${i}-${j}`}
className={`float-l ${className}`} className={`float-l ${className}`}
style={{ width }} style={{ width }}
> >
@ -27,7 +29,7 @@ export const Columns = (props: Props) => {
}); });
return ( return (
<div key={`tr-${i}`}> <div key={`${props.colKey}-${i}`}>
{cells} {cells}
<div className="fix"></div> <div className="fix"></div>
</div> </div>

View file

@ -213,6 +213,7 @@ export class UserForm extends React.Component<
return ( return (
<div className="padding-t-m padding-b-m"> <div className="padding-t-m padding-b-m">
<Columns <Columns
colKey={"paneAdmin"}
rows={List([ rows={List([
List([ List([
<div className="title-m-wrap"> <div className="title-m-wrap">

View file

@ -503,142 +503,150 @@ export class FilesPanel extends React.Component<Props, State, {}> {
? "hidden" ? "hidden"
: ""; : "";
const rows = sortedItems.map((item: MetadataResp): React.ReactNode => { const rows = sortedItems.map(
const isSelected = this.state.selectedItems.has(item.name); (item: MetadataResp, i: number): React.ReactNode => {
const dirPath = this.props.filesInfo.dirPath.join("/"); const isSelected = this.state.selectedItems.has(item.name);
const itemPath = dirPath.endsWith("/") const dirPath = this.props.filesInfo.dirPath.join("/");
? `${dirPath}${item.name}` const itemPath = dirPath.endsWith("/")
: `${dirPath}/${item.name}`; ? `${dirPath}${item.name}`
: `${dirPath}/${item.name}`;
const selectedIconColor = isSelected ? "focus-font" : "minor-font"; const selectedIconColor = isSelected ? "focus-font" : "minor-font";
const descIconColor = this.state.showDetail.has(item.name) const descIconColor = this.state.showDetail.has(item.name)
? "focus-font" ? "focus-font"
: "major-font"; : "major-font";
const icon = item.isDir ? ( const icon = item.isDir ? (
<RiFolder2Fill size="2rem" className="yellow0-font margin-r-m" /> <RiFolder2Fill size="2rem" className="yellow0-font margin-r-m" />
) : ( ) : (
<RiFile2Fill size="2rem" className="focus-font margin-r-m" /> <RiFile2Fill size="2rem" className="focus-font margin-r-m" />
); );
const modTimeDate = new Date(item.modTime); const modTimeDate = new Date(item.modTime);
const modTimeFormatted = `${modTimeDate.getFullYear()}-${ const modTimeFormatted = `${modTimeDate.getFullYear()}-${
modTimeDate.getMonth() + 1 modTimeDate.getMonth() + 1
}-${modTimeDate.getDate()}`; }-${modTimeDate.getDate()}`;
const downloadPath = `/v1/fs/files?fp=${itemPath}`; const downloadPath = `/v1/fs/files?fp=${itemPath}`;
const name = item.isDir ? ( const name = item.isDir ? (
<span className="title-m-wrap"> <span className="title-m-wrap">
<span className="clickable" onClick={() => this.gotoChild(item.name)}> <span
{item.name} className="clickable"
onClick={() => this.gotoChild(item.name)}
>
{item.name}
</span>
<span className="major-font">{` - ${modTimeFormatted}`}</span>
</span> </span>
<span className="major-font">{` - ${modTimeFormatted}`}</span> ) : (
</span> <span className="title-m-wrap">
) : ( <a className="clickable" href={downloadPath} target="_blank">
<span className="title-m-wrap"> {item.name}
<a className="clickable" href={downloadPath} target="_blank"> </a>
{item.name} <span className="major-font">{` - ${modTimeFormatted}`}</span>
</a> </span>
<span className="major-font">{` - ${modTimeFormatted}`}</span> );
</span>
);
const checkIcon = isSelected ? ( const checkIcon = isSelected ? (
<RiCheckboxFill <RiCheckboxFill
size="2rem"
className={`${selectedIconColor} ${shareModeClass}`}
onClick={() => this.select(item.name)}
/>
) : (
<RiCheckboxBlankLine
size="2rem"
className={`${selectedIconColor} ${shareModeClass}`}
onClick={() => this.select(item.name)}
/>
);
const op = item.isDir ? (
<div className={`txt-align-r icon-s ${showOp}`}>{checkIcon}</div>
) : (
<div className={`txt-align-r icon-s ${showOp}`}>
<RiMenuUnfoldFill
size="2rem" size="2rem"
className={`${descIconColor} margin-r-m`} className={`${selectedIconColor} ${shareModeClass}`}
onClick={() => this.toggleDetail(item.name)} onClick={() => this.select(item.name)}
/> />
{checkIcon} ) : (
</div> <RiCheckboxBlankLine
); size="2rem"
className={`${selectedIconColor} ${shareModeClass}`}
onClick={() => this.select(item.name)}
/>
);
const absDownloadURL = `${document.location.protocol}//${document.location.hostname}:${document.location.port}${downloadPath}`; const op = item.isDir ? (
const pathTitle = this.props.msg.pkg.get("item.downloadURL"); <div className={`txt-align-r icon-s ${showOp}`}>{checkIcon}</div>
const modTimeTitle = this.props.msg.pkg.get("item.modTime"); ) : (
const sizeTitle = this.props.msg.pkg.get("item.size"); <div className={`txt-align-r icon-s ${showOp}`}>
const itemSize = FileSize(item.size, { round: 0 }); <RiMenuUnfoldFill
size="2rem"
className={`${descIconColor} margin-r-m`}
onClick={() => this.toggleDetail(item.name)}
/>
{checkIcon}
</div>
);
const descStateClass = this.state.showDetail.has(item.name) const absDownloadURL = `${document.location.protocol}//${document.location.hostname}:${document.location.port}${downloadPath}`;
? "margin-t-m padding-m" const pathTitle = this.props.msg.pkg.get("item.downloadURL");
: "no-height"; const modTimeTitle = this.props.msg.pkg.get("item.modTime");
const desc = ( const sizeTitle = this.props.msg.pkg.get("item.size");
<div className={`${descStateClass} major-font major-bg`}> const itemSize = FileSize(item.size, { round: 0 });
<div className="column">
<div className="card"> const descStateClass = this.state.showDetail.has(item.name)
<span className="title-m minor-font">{pathTitle}</span> ? "margin-t-m padding-m"
<span className="font-s work-break-all">{absDownloadURL}</span> : "no-height";
const desc = (
<div className={`${descStateClass} major-font major-bg`}>
<div className="column">
<div className="card">
<span className="title-m minor-font">{pathTitle}</span>
<span className="font-s work-break-all">{absDownloadURL}</span>
</div>
</div>
<div className="column">
<div className="card">
<span className="title-m minor-font">{modTimeTitle}</span>
<span className="font-s work-break-all">
{modTimeFormatted}
</span>
</div>
<div className="card">
<span className="title-m minor-font">{sizeTitle}</span>
<span className="font-s work-break-all">{itemSize}</span>
</div>
</div>
<div className="fix">
<div className="card">
<Flexbox
children={List([
<span className="title-m minor-font">SHA1</span>,
<RiRestartFill
onClick={() => this.generateHash(itemPath)}
size={"2rem"}
className={`minor-font ${shareModeClass}`}
/>,
])}
childrenStyles={List([{}, { justifyContent: "flex-end" }])}
/>
<div className="info minor-bg">{item.sha1}</div>
</div>
</div> </div>
</div> </div>
);
<div className="column"> const cells = List<React.ReactNode>([
<div className="card"> <div className="icon-s">{icon}</div>,
<span className="title-m minor-font">{modTimeTitle}</span> <div>{name}</div>,
<span className="font-s work-break-all">{modTimeFormatted}</span> <div className="title-m major-font padding-l-s">{itemSize}</div>,
</div> <div className="txt-align-r">{op}</div>,
<div className="card"> ]);
<span className="title-m minor-font">{sizeTitle}</span>
<span className="font-s work-break-all">{itemSize}</span> const tableCols = (
</div> <Columns
rows={List([cells])}
widths={List(["3rem", "calc(100% - 18rem)", "8rem", "7rem"])}
childrenClassNames={List(["", "", "", ""])}
colKey={`filesPanel-${i}`}
/>
);
return (
<div key={`filesPanel-row-${i}`}>
{tableCols}
{desc}
<div className="hr"></div>
</div> </div>
);
<div className="fix"> }
<div className="card"> );
<Flexbox
children={List([
<span className="title-m minor-font">SHA1</span>,
<RiRestartFill
onClick={() => this.generateHash(itemPath)}
size={"2rem"}
className={`minor-font ${shareModeClass}`}
/>,
])}
childrenStyles={List([{}, { justifyContent: "flex-end" }])}
/>
<div className="info minor-bg">{item.sha1}</div>
</div>
</div>
</div>
);
const cells = List<React.ReactNode>([
<div className="icon-s">{icon}</div>,
<div>{name}</div>,
<div className="title-m major-font padding-l-s">{itemSize}</div>,
<div className="txt-align-r">{op}</div>,
]);
const tableCols = (
<Columns
rows={List([cells])}
widths={List(["3rem", "calc(100% - 18rem)", "8rem", "7rem"])}
childrenClassNames={List(["", "", "", ""])}
/>
);
return (
<div>
{tableCols}
{desc}
<div className="hr"></div>
</div>
);
});
return <div>{rows}</div>; return <div>{rows}</div>;
}; };