feat(fe/layouts): introduce segments layout, controls, refactor breadcrumb

This commit is contained in:
hexxa 2022-01-12 17:13:09 +08:00 committed by Hexxa
parent f3b65e1bb3
commit 16ff18555a
6 changed files with 99 additions and 43 deletions

View file

@ -88,14 +88,20 @@
} }
.theme-default #breadcrumb { .theme-default #breadcrumb {
padding: 1rem 0;
width: 100%; width: 100%;
} }
.theme-default #breadcrumb .location-item {
margin: 0 0.5rem 0 0;
display: inline-block;
line-height: 3rem;
}
.theme-default #breadcrumb .item { .theme-default #breadcrumb .item {
color: #697384; margin: 0 0.5rem 0 0;
margin-right: 1rem;
max-width: 6rem; max-width: 6rem;
display: inline-block;
line-height: 3rem;
} }
.theme-default #breadcrumb .content { .theme-default #breadcrumb .content {
@ -106,9 +112,10 @@
display: block; display: block;
} }
.theme-default #breadcrumb .item { .theme-default #space-used {
color: #697384; text-align: right;
margin-right: 1rem; line-height: 3rem;
font-size: 1.4rem;
} }
.container { .container {

View file

@ -0,0 +1,7 @@
export const settingsTabsCtrl = "settingsTabs";
export const settingsDialogCtrl = "settingsDialog";
export const sharingCtrl = "sharingCtrl";
export const filesViewCtrl = "filesView";
export const ctrlHidden = "hidden";
export const ctrlOn = "on";
export const ctrlOff = "off";

View file

@ -0,0 +1,43 @@
import * as React from "react";
import { List } from "immutable";
export interface Props {
id?: string;
children: List<React.ReactNode>;
ratios: List<number>;
dir: boolean; // true=left, false=right
className?: string;
}
export const Segments = (props: Props) => {
let sum = 0;
props.ratios.forEach((ratio) => {
sum += Math.trunc(ratio);
});
if (sum > 100) {
throw `segments: ratio sum(${sum}) > 100`;
} else if (props.children.size !== props.ratios.size) {
throw `segments: children size(${props.children.size}) != ratio size(${props.ratios.size})`;
}
const children = props.children.map(
(child: React.ReactNode, i: number): React.ReactNode => {
const width = `${props.ratios.get(i, 0)}%`;
return (
<div
key={`seg-${i}`}
style={{ float: props.dir ? "left" : "right", width: width }}
>
{child}
</div>
);
}
);
return (
<div id={props.id}>
<div className={props.className}>{children}</div>
<div style={{ clear: "both" }}></div>
</div>
);
};

View file

@ -24,6 +24,7 @@ import { MetadataResp, roleVisitor, roleAdmin } from "../client";
import { Flexbox } from "./layout/flexbox"; import { Flexbox } from "./layout/flexbox";
import { Container } from "./layout/container"; import { Container } from "./layout/container";
import { Table, Cell, Head } from "./layout/table"; import { Table, Cell, Head } from "./layout/table";
import { Segments } from "./layout/segments";
import { Rows, Row } from "./layout/rows"; import { Rows, Row } from "./layout/rows";
import { Up } from "../worker/upload_mgr"; import { Up } from "../worker/upload_mgr";
import { UploadEntry, UploadState } from "../worker/interface"; import { UploadEntry, UploadState } from "../worker/interface";
@ -734,15 +735,19 @@ export class FilesPanel extends React.Component<Props, State, {}> {
const breadcrumb = this.props.filesInfo.dirPath.map( const breadcrumb = this.props.filesInfo.dirPath.map(
(pathPart: string, key: number) => { (pathPart: string, key: number) => {
return ( return (
<button <span key={pathPart}>
key={pathPart} <a
onClick={() => onClick={() =>
this.chdir(this.props.filesInfo.dirPath.slice(0, key + 1)) this.chdir(this.props.filesInfo.dirPath.slice(0, key + 1))
} }
className="item" className="item clickable"
> >
<span className="content">{pathPart}</span> <span className="content">{pathPart}</span>
</button> </a>
<span className="item">
<span className="content">{"/"}</span>
</span>
</span>
); );
} }
); );
@ -902,38 +907,30 @@ export class FilesPanel extends React.Component<Props, State, {}> {
/> />
</div> </div>
<Flexbox <Segments
id="breadcrumb"
children={List([ children={List([
<span id="breadcrumb"> <div>
<Flexbox <span className="location-item">
children={List([ <span className="content">
<RiArchiveDrawerFill {`${this.props.msg.pkg.get("breadcrumb.loc")}:`}
size="3rem" </span>
id="icon-home" </span>
className="clickable" {breadcrumb}
onClick={this.goHome} </div>,
/>, <div
<Flexbox children={breadcrumb} />, id="space-used"
])} className="grey0-font"
childrenStyles={List([ >{`${this.props.msg.pkg.get(
{ flex: "0 0 auto" }, "browser.used"
{ flex: "0 0 auto" }, )} ${usedSpace} / ${spaceLimit}`}</div>,
])}
/>
</span>,
<span>
<span
id="space-used"
className="desc-m grey0-font"
>{`${this.props.msg.pkg.get(
"browser.used"
)} ${usedSpace} / ${spaceLimit}`}</span>
</span>,
])} ])}
childrenStyles={List([{}, { justifyContent: "flex-end" }])} ratios={List([60, 40])}
dir={true}
/> />
<div className="hr grey0-bg"></div>
{view} {view}
</Container> </Container>
</div> </div>

View file

@ -131,4 +131,5 @@ export const msgs: Map<string, string> = Map({
"op.truncate": "Truncate", "op.truncate": "Truncate",
"op.submit": "Submit", "op.submit": "Submit",
"term.time": "Time", "term.time": "Time",
"breadcrumb.loc": "Location",
}); });

View file

@ -128,4 +128,5 @@ export const msgs: Map<string, string> = Map({
"op.truncate": "清空", "op.truncate": "清空",
"op.submit": "提交", "op.submit": "提交",
"term.time": "时间", "term.time": "时间",
"breadcrumb.loc": "位置",
}); });