mirror of
https://github.com/filecoin-project/slate.git
synced 2024-12-23 09:01:56 +03:00
updated data page
This commit is contained in:
parent
0be80de27b
commit
a27ef78ead
@ -699,7 +699,7 @@ export const Book = (props) => (
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const Music = (props) => (
|
||||
export const Sound = (props) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height={props.height}
|
||||
@ -711,9 +711,8 @@ export const Music = (props) => (
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M9 18V5L21 3V16" />
|
||||
<path d="M6 21C7.65685 21 9 19.6569 9 18C9 16.3431 7.65685 15 6 15C4.34315 15 3 16.3431 3 18C3 19.6569 4.34315 21 6 21Z" />
|
||||
<path d="M18 19C19.6569 19 21 17.6569 21 16C21 14.3431 19.6569 13 18 13C16.3431 13 15 14.3431 15 16C15 17.6569 16.3431 19 18 19Z" />
|
||||
<path d="M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z" />
|
||||
<path d="M16.24 7.75999C16.7979 8.31723 17.2404 8.97896 17.5424 9.70735C17.8443 10.4357 17.9997 11.2165 17.9997 12.005C17.9997 12.7935 17.8443 13.5742 17.5424 14.3026C17.2404 15.031 16.7979 15.6928 16.24 16.25M7.76 16.24C7.20214 15.6828 6.75959 15.021 6.45764 14.2926C6.1557 13.5642 6.00028 12.7835 6.00028 11.995C6.00028 11.2065 6.1557 10.4257 6.45764 9.69735C6.75959 8.96896 7.20214 8.30723 7.76 7.74999M19.07 4.92999C20.9447 6.80527 21.9979 9.34835 21.9979 12C21.9979 14.6516 20.9447 17.1947 19.07 19.07M4.93 19.07C3.05529 17.1947 2.00214 14.6516 2.00214 12C2.00214 9.34835 3.05529 6.80527 4.93 4.92999" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@ -1087,6 +1086,7 @@ export const LocationPin = (props) => {
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const MoreHorizontal = (props) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -1103,3 +1103,37 @@ export const MoreHorizontal = (props) => (
|
||||
<path d="M5 13C5.55228 13 6 12.5523 6 12C6 11.4477 5.55228 11 5 11C4.44772 11 4 11.4477 4 12C4 12.5523 4.44772 13 5 13Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const GridView = (props) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
{...props}
|
||||
>
|
||||
<path d="M10 3H3V10H10V3Z" />
|
||||
<path d="M21 3H14V10H21V3Z" />
|
||||
<path d="M21 14H14V21H21V14Z" />
|
||||
<path d="M10 14H3V21H10V14Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ListView = (props) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
{...props}
|
||||
>
|
||||
<path d="M21 3H3V10H21V3Z" />
|
||||
<path d="M21 14H3V21H21V14Z" />
|
||||
</svg>
|
||||
);
|
||||
|
@ -26,7 +26,6 @@ const STYLES_NAVIGATION = css`
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: 24px 0 0 0;
|
||||
font-size: 18px;
|
||||
`;
|
||||
|
||||
const STYLES_NAVIGATION_ITEM = css`
|
||||
|
@ -18,10 +18,10 @@ const STYLES_HEADER = css`
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 64px 24px 48px 42px;
|
||||
padding: 64px 24px 40px 42px;
|
||||
|
||||
@media (max-width: ${Constants.sizes.mobile}px) {
|
||||
padding: 64px 0 48px 16px;
|
||||
padding: 68px 0 56px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -23,7 +23,6 @@ const STYLES_BUTTON = css`
|
||||
:hover {
|
||||
background-color: ${Constants.system.brand};
|
||||
color: ${Constants.system.white};
|
||||
transform: scale(1.2);
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -11,7 +11,7 @@ const MAX_IN_BYTES = 10737418240;
|
||||
const STYLES_CONTAINER = css`
|
||||
border-radius: 4px;
|
||||
border: 1px solid ${Constants.system.border};
|
||||
padding: 24px;
|
||||
padding: 32px;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
`;
|
||||
@ -20,31 +20,23 @@ const STYLES_DATA = css`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 8px;
|
||||
height: 16px;
|
||||
border-radius: 3px;
|
||||
background-color: ${Constants.system.border};
|
||||
background-color: ${Constants.system.foreground};
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const STYLES_DATA_METER = css`
|
||||
flex-shrink: 0;
|
||||
height: 100%;
|
||||
background-color: #2935ff;
|
||||
background-image: linear-gradient(
|
||||
to left,
|
||||
#2935ff,
|
||||
#342fc4,
|
||||
#33288b,
|
||||
#2b2157,
|
||||
#1d1927
|
||||
);
|
||||
height: 16px;
|
||||
background-color: ${Constants.system.brand};
|
||||
`;
|
||||
|
||||
const STYLES_ROW = css`
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
font-family: ${Constants.font.code};
|
||||
font-family: ${Constants.font.text};
|
||||
color: ${Constants.system.darkGray};
|
||||
font-size: 10px;
|
||||
margin-top: 2px;
|
||||
@ -55,7 +47,7 @@ const STYLES_STATS_ROW = css`
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
font-family: ${Constants.font.code};
|
||||
font-family: ${Constants.font.text};
|
||||
color: ${Constants.system.black};
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
@ -71,9 +63,8 @@ const STYLES_RIGHT = css`
|
||||
`;
|
||||
|
||||
const STYLES_TITLE = css`
|
||||
font-family: ${Constants.font.semiBold};
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
font-family: ${Constants.font.medium};
|
||||
font-size: ${Constants.typescale.lvl1};
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
overflow-wrap: break-word;
|
||||
@ -84,15 +75,16 @@ export const DataMeterBar = (props) => {
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div css={STYLES_STATS_ROW}>
|
||||
<div css={STYLES_LEFT}>{Strings.bytesToSize(props.bytes)}</div>
|
||||
<div css={STYLES_RIGHT}>{Strings.bytesToSize(props.maximumBytes)}</div>
|
||||
<div css={STYLES_TITLE}>
|
||||
{Strings.bytesToSize(props.bytes)} of Available{" "}
|
||||
{Strings.bytesToSize(props.maximumBytes)} Used
|
||||
</div>
|
||||
|
||||
<div css={STYLES_ROW}>
|
||||
<div
|
||||
css={STYLES_LEFT}
|
||||
style={{ color: props.failed ? Constants.system.red : null }}>
|
||||
style={{ color: props.failed ? Constants.system.red : null }}
|
||||
>
|
||||
{props.leftLabel}
|
||||
</div>
|
||||
<div css={STYLES_RIGHT}>{props.rightLabel}</div>
|
||||
@ -101,9 +93,10 @@ export const DataMeterBar = (props) => {
|
||||
<div
|
||||
css={STYLES_DATA}
|
||||
style={{
|
||||
marginTop: 4,
|
||||
marginTop: 16,
|
||||
backgroundColor: props.failed ? Constants.system.red : null,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<div
|
||||
css={STYLES_DATA_METER}
|
||||
style={{ width: `${percentage * 100}%` }}
|
||||
@ -117,8 +110,6 @@ export const DataMeter = (props) => {
|
||||
return (
|
||||
<div css={STYLES_CONTAINER} style={props.style}>
|
||||
<DataMeterBar
|
||||
leftLabel="used"
|
||||
rightLabel="total"
|
||||
bytes={props.stats.bytes}
|
||||
maximumBytes={props.stats.maximumBytes}
|
||||
/>
|
||||
|
@ -3,55 +3,98 @@ import * as Constants from "~/common/constants";
|
||||
import * as Strings from "~/common/strings";
|
||||
import * as System from "~/components/system";
|
||||
import * as Actions from "~/common/actions";
|
||||
import * as SVG from "~/common/svg";
|
||||
|
||||
import { css } from "@emotion/react";
|
||||
import { Boundary } from "~/components/system/components/fragments/Boundary";
|
||||
import { PopoverNavigation } from "~/components/system/components/PopoverNavigation";
|
||||
|
||||
import Section from "~/components/core/Section";
|
||||
import SlateMediaObject from "~/components/core/SlateMediaObject";
|
||||
import SlateMediaObjectPreview from "~/components/core/SlateMediaObjectPreview";
|
||||
|
||||
const COLUMNS_SCHEMA = [
|
||||
{ key: "cid", name: "CID", width: "100%" },
|
||||
{
|
||||
key: "name",
|
||||
name: <span style={{ fontSize: "0.9rem" }}>Name</span>,
|
||||
width: "100%",
|
||||
},
|
||||
{
|
||||
key: "size",
|
||||
name: "Size",
|
||||
width: "84px",
|
||||
},
|
||||
{ key: "type", name: "Type", type: "TEXT_TAG", width: "172px" },
|
||||
{
|
||||
key: "networks",
|
||||
name: "Networks",
|
||||
type: "NETWORK_TYPE",
|
||||
name: <span style={{ fontSize: "0.9rem" }}>Size</span>,
|
||||
width: "104px",
|
||||
},
|
||||
{
|
||||
key: "storage",
|
||||
name: "Storage Deal Status",
|
||||
width: "148px",
|
||||
type: "STORAGE_DEAL_STATUS",
|
||||
key: "more",
|
||||
name: <div />,
|
||||
width: "64px",
|
||||
},
|
||||
];
|
||||
|
||||
const STYLES_LINK = css`
|
||||
font-family: ${Constants.font.semiBold};
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
transition: 200ms ease all;
|
||||
font-size: 0.9rem;
|
||||
padding: 12px 0px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
:hover {
|
||||
color: ${Constants.system.brand};
|
||||
}
|
||||
`;
|
||||
|
||||
const STYLES_LABEL = css`
|
||||
letter-spacing: 0.1px;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
font-family: ${Constants.font.semiBold};
|
||||
font-weight: 400;
|
||||
color: ${Constants.system.black};
|
||||
const STYLES_VALUE = css`
|
||||
font-size: 0.9rem;
|
||||
padding: 12px 0px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
const STYLES_SECTION = css`
|
||||
margin: 12px 0 16px 0;
|
||||
const STYLES_TABLE_VALUE = {
|
||||
fontFamily: Constants.font.medium,
|
||||
padding: "0px 24px",
|
||||
};
|
||||
|
||||
const STYLES_TABLE_CONTAINER = css`
|
||||
border: 1px solid rgba(229, 229, 229, 0.75);
|
||||
`;
|
||||
|
||||
const STYLES_ICON_BOX = css`
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
|
||||
:hover {
|
||||
color: ${Constants.system.brand};
|
||||
}
|
||||
`;
|
||||
|
||||
const STYLES_COPY_INPUT = css`
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
`;
|
||||
|
||||
const STYLES_IMAGE_GRID = css`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -27px;
|
||||
`;
|
||||
|
||||
const STYLES_IMAGE_BOX = css`
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin: 27px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0px 0px 0px 1px rgba(229, 229, 229, 0.5) inset;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const delay = (ms) => new Promise((resolve) => window.setTimeout(resolve, ms));
|
||||
@ -70,6 +113,7 @@ const delay = (ms) => new Promise((resolve) => window.setTimeout(resolve, ms));
|
||||
export default class DataView extends React.Component {
|
||||
state = {
|
||||
selectedRowId: null,
|
||||
menu: null,
|
||||
};
|
||||
|
||||
async componentDidMount() {
|
||||
@ -108,14 +152,27 @@ export default class DataView extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
_handleMakeDeal = (data) => {
|
||||
this.props.onAction({
|
||||
type: "SIDEBAR",
|
||||
value: "SIDEBAR_FILE_STORAGE_DEAL",
|
||||
data,
|
||||
// _handleMakeDeal = (data) => {
|
||||
// this.props.onAction({
|
||||
// type: "SIDEBAR",
|
||||
// value: "SIDEBAR_FILE_STORAGE_DEAL",
|
||||
// data,
|
||||
// });
|
||||
// };
|
||||
|
||||
_handleCopy = (e, value) => {
|
||||
this._handleHide();
|
||||
e.stopPropagation();
|
||||
this.setState({ copyValue: value }, () => {
|
||||
this._ref.select();
|
||||
document.execCommand("copy");
|
||||
});
|
||||
};
|
||||
|
||||
_handleHide = (e) => {
|
||||
this.setState({ menu: null });
|
||||
};
|
||||
|
||||
_handleDelete = async (cid) => {
|
||||
this.setState({ loading: true });
|
||||
if (
|
||||
@ -152,6 +209,27 @@ export default class DataView extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.props.view === "grid") {
|
||||
return (
|
||||
<div css={STYLES_IMAGE_GRID}>
|
||||
{this.props.items.map((each, index) => (
|
||||
<div
|
||||
css={STYLES_IMAGE_BOX}
|
||||
onClick={() => this._handleSelect(index)}
|
||||
>
|
||||
<SlateMediaObjectPreview
|
||||
url={`https://${each.ipfs.replace(
|
||||
"/ipfs/",
|
||||
""
|
||||
)}.ipfs.slate.textile.io`}
|
||||
title={each.file || each.name}
|
||||
type={each.type || each.icon}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const columns = COLUMNS_SCHEMA;
|
||||
const rows = this.props.items.map((each, index) => {
|
||||
const cid = each.ipfs.replace("/ipfs/", "");
|
||||
@ -159,32 +237,47 @@ export default class DataView extends React.Component {
|
||||
|
||||
return {
|
||||
...each,
|
||||
cid: (
|
||||
<span css={STYLES_LINK} onClick={() => this._handleSelect(index)}>
|
||||
{cid}
|
||||
</span>
|
||||
name: (
|
||||
<div css={STYLES_LINK} onClick={() => this._handleSelect(index)}>
|
||||
{each.file || each.name}
|
||||
</div>
|
||||
),
|
||||
size: <span>{Strings.bytesToSize(each.size)}</span>,
|
||||
children: (
|
||||
<div>
|
||||
<React.Fragment>
|
||||
<div css={STYLES_LABEL}>Actions</div>
|
||||
<div css={STYLES_SECTION}>
|
||||
<System.ButtonSecondary
|
||||
loading={this.state.loading}
|
||||
onClick={() => this._handleDelete(cid)}
|
||||
>
|
||||
Delete
|
||||
</System.ButtonSecondary>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
{each.error ? (
|
||||
<React.Fragment>
|
||||
<div css={STYLES_LABEL} style={{ marginTop: 24 }}>
|
||||
Errors
|
||||
</div>
|
||||
<div css={STYLES_SECTION}>{each.error}</div>
|
||||
</React.Fragment>
|
||||
size: <div css={STYLES_VALUE}>{Strings.bytesToSize(each.size)}</div>,
|
||||
more: (
|
||||
<div
|
||||
css={STYLES_ICON_BOX}
|
||||
onClick={() => this.setState({ menu: each.id })}
|
||||
>
|
||||
<SVG.MoreHorizontal height="24px" />
|
||||
{this.state.menu === each.id ? (
|
||||
<Boundary
|
||||
captureResize={true}
|
||||
captureScroll={false}
|
||||
enabled
|
||||
onOutsideRectEvent={this._handleHide}
|
||||
>
|
||||
<PopoverNavigation
|
||||
style={{
|
||||
top: "48px",
|
||||
right: "40px",
|
||||
}}
|
||||
navigation={[
|
||||
{
|
||||
text: "Copy CID",
|
||||
onClick: (e) => this._handleCopy(e, cid),
|
||||
},
|
||||
{
|
||||
text: "Delete",
|
||||
onClick: (e) => {
|
||||
e.stopPropagation();
|
||||
this.setState({ menu: null }, () =>
|
||||
this._handleDelete(cid)
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Boundary>
|
||||
) : null}
|
||||
</div>
|
||||
),
|
||||
@ -197,22 +290,32 @@ export default class DataView extends React.Component {
|
||||
};
|
||||
|
||||
return (
|
||||
<Section
|
||||
onAction={this.props.onAction}
|
||||
title={`${Strings.bytesToSize(this.props.viewer.stats.bytes)} uploaded`}
|
||||
style={{ minWidth: "880px" }}
|
||||
buttons={this.props.buttons}
|
||||
>
|
||||
<div css={STYLES_TABLE_CONTAINER}>
|
||||
<System.Table
|
||||
data={data}
|
||||
noColor
|
||||
topRowStyle={{
|
||||
backgroundColor: Constants.system.foreground,
|
||||
...STYLES_TABLE_VALUE,
|
||||
fontFamily: Constants.font.semiBold,
|
||||
padding: "12px 24px",
|
||||
}}
|
||||
rowStyle={STYLES_TABLE_VALUE}
|
||||
selectedRowId={this.state.selectedRowId}
|
||||
name="selectedRowId"
|
||||
onAction={this.props.onAction}
|
||||
onNavigateTo={this.props.onNavigateTo}
|
||||
onChange={this._handleChange}
|
||||
onClick={this._handleClick}
|
||||
/>
|
||||
</Section>
|
||||
<input
|
||||
readOnly
|
||||
ref={(c) => {
|
||||
this._ref = c;
|
||||
}}
|
||||
value={this.state.copyValue}
|
||||
css={STYLES_COPY_INPUT}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import { css } from "@emotion/react";
|
||||
|
||||
const STYLES_PAGE_CONTENT = css`
|
||||
width: 100%;
|
||||
${"" /* max-width: 1074px;
|
||||
padding: 0px 24px; */}
|
||||
max-width: 1024px;
|
||||
padding: 0px;
|
||||
margin: 0 auto;
|
||||
|
@ -78,7 +78,7 @@ export default class SlateMediaObjectPreview extends React.Component {
|
||||
element = (
|
||||
<article css={STYLES_ENTITY} style={this.props.style}>
|
||||
<div>
|
||||
<SVG.Music height="24px" />
|
||||
<SVG.Sound height="24px" />
|
||||
</div>
|
||||
{this.props.title && !this.props.small ? (
|
||||
<div css={STYLES_TITLE}>{title}</div>
|
||||
|
@ -17,7 +17,6 @@ const STYLES_IMAGE_ROW = css`
|
||||
flex-wrap: wrap;
|
||||
height: 160px;
|
||||
overflow: hidden;
|
||||
margin: 0px -18px;
|
||||
|
||||
@media (max-width: ${Constants.sizes.mobile}px) {
|
||||
justify-content: center;
|
||||
@ -41,6 +40,14 @@ const STYLES_ITEM_BOX = css`
|
||||
:hover {
|
||||
color: ${Constants.system.brand};
|
||||
}
|
||||
|
||||
:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
:first-child {
|
||||
margin-left: 0px;
|
||||
}
|
||||
`;
|
||||
|
||||
const STYLES_IMAGE_ROW_SMALL = css`
|
||||
@ -49,7 +56,6 @@ const STYLES_IMAGE_ROW_SMALL = css`
|
||||
flex-wrap: wrap;
|
||||
height: 56px;
|
||||
overflow: hidden;
|
||||
margin: 0px -8px;
|
||||
`;
|
||||
|
||||
const STYLES_ITEM_BOX_SMALL = css`
|
||||
@ -60,6 +66,14 @@ const STYLES_ITEM_BOX_SMALL = css`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0px 0px 0px 1px rgba(229, 229, 229, 0.5) inset;
|
||||
|
||||
:first-child {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
`;
|
||||
|
||||
export function SlatePreviewRow(props) {
|
||||
|
@ -17,7 +17,6 @@ const STYLES_TAB_GROUP = css`
|
||||
const STYLES_TAB = css`
|
||||
padding: 8px 8px 8px 0px;
|
||||
margin-right: 24px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: ${Constants.typescale.lvl1};
|
||||
font-family: ${Constants.font.medium};
|
||||
@ -31,18 +30,22 @@ const STYLES_TAB = css`
|
||||
export class TabGroup extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div css={STYLES_TAB_GROUP}>
|
||||
<div css={STYLES_TAB_GROUP} style={this.props.style}>
|
||||
{this.props.tabs.map((tab, i) => (
|
||||
<div
|
||||
css={STYLES_TAB}
|
||||
key={tab}
|
||||
style={{
|
||||
color:
|
||||
this.props.value === i
|
||||
this.props.disabled || this.props.value === i
|
||||
? Constants.system.black
|
||||
: "rgba(0,0,0,0.25)",
|
||||
cursor: this.props.disabled ? "auto" : "pointer",
|
||||
...this.props.itemStyle,
|
||||
}}
|
||||
onClick={() => this.props.onChange(i)}
|
||||
onClick={
|
||||
this.props.disabled ? () => {} : () => this.props.onChange(i)
|
||||
}
|
||||
>
|
||||
{tab}
|
||||
</div>
|
||||
|
@ -54,7 +54,7 @@ const STYLES_TABLE_ROW = css`
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
padding: 0 8px 0 8px;
|
||||
border-bottom: 1px solid ${Constants.system.gray};
|
||||
border-bottom: 1px solid rgba(229, 229, 229, 0.75);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
@ -69,14 +69,14 @@ const STYLES_TABLE_SELECTED_ROW = css`
|
||||
background-color: ${Constants.system.foreground};
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
border-bottom: 1px solid ${Constants.system.gray};
|
||||
border-bottom: 1px solid rgba(229, 229, 229, 0.75);
|
||||
`;
|
||||
|
||||
const STYLES_TABLE_TOP_ROW = css`
|
||||
box-sizing: border-box;
|
||||
font-family: ${Constants.font.semiBold};
|
||||
padding: 0 8px 0 8px;
|
||||
border-bottom: 1px solid ${Constants.system.gray};
|
||||
border-bottom: 1px solid rgba(229, 229, 229, 0.75);
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: flex-start;
|
||||
@ -130,7 +130,7 @@ export class Table extends React.Component {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{this.props.noLabel ? null : (
|
||||
<div css={STYLES_TABLE_TOP_ROW}>
|
||||
<div css={STYLES_TABLE_TOP_ROW} style={this.props.topRowStyle}>
|
||||
{data.columns.map((c, cIndex) => {
|
||||
const text = c.hideLabel
|
||||
? ""
|
||||
@ -149,7 +149,9 @@ export class Table extends React.Component {
|
||||
key={`table-top-${c.key}-${cIndex}`}
|
||||
style={{
|
||||
width: localWidth,
|
||||
backgroundColor: ac[c.key].color,
|
||||
backgroundColor: this.props.noColor
|
||||
? null
|
||||
: ac[c.key].color,
|
||||
flexShrink,
|
||||
}}
|
||||
tooltip={c.tooltip}
|
||||
@ -169,7 +171,7 @@ export class Table extends React.Component {
|
||||
|
||||
return (
|
||||
<React.Fragment key={`${r.id}-${i}`}>
|
||||
<div css={STYLES_TABLE_ROW}>
|
||||
<div css={STYLES_TABLE_ROW} style={this.props.rowStyle}>
|
||||
{Object.keys(ac).map((each, cIndex) => {
|
||||
const field = ac[each];
|
||||
const text = r[each];
|
||||
|
@ -1,19 +1,74 @@
|
||||
import * as React from "react";
|
||||
import * as Actions from "~/common/actions";
|
||||
import * as System from "~/components/system";
|
||||
import * as SVG from "~/common/svg";
|
||||
import * as Constants from "~/common/constants";
|
||||
|
||||
import { css } from "@emotion/react";
|
||||
import { TabGroup } from "~/components/core/TabGroup";
|
||||
import { ButtonPrimary } from "~/components/system/components/Buttons";
|
||||
|
||||
import ScenePage from "~/components/core/ScenePage";
|
||||
import DataView from "~/components/core/DataView";
|
||||
import DataMeter from "~/components/core/DataMeter";
|
||||
import ScenePageHeader from "~/components/core/ScenePageHeader";
|
||||
import SceneContent from "~/components/core/SceneContent";
|
||||
|
||||
const VIEW_LIMIT = 20;
|
||||
|
||||
const STYLES_ICON_BOX = css`
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
margin-left: 16px;
|
||||
`;
|
||||
|
||||
const STYLES_HEADER_LINE = css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 80px;
|
||||
margin-bottom: 42px;
|
||||
`;
|
||||
|
||||
const STYLES_ARROWS = css`
|
||||
text-align: end;
|
||||
`;
|
||||
|
||||
const STYLES_ICON_ELEMENT = css`
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #565151;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
margin: 16px 8px;
|
||||
|
||||
:hover {
|
||||
color: ${Constants.system.brand};
|
||||
}
|
||||
|
||||
svg {
|
||||
transform: rotate(0deg);
|
||||
transition: 200ms ease transform;
|
||||
}
|
||||
`;
|
||||
|
||||
const POLLING_INTERVAL = 10000;
|
||||
|
||||
export default class SceneFilesFolder extends React.Component {
|
||||
_interval;
|
||||
|
||||
state = {
|
||||
view: "list",
|
||||
startIndex: 0,
|
||||
};
|
||||
|
||||
loop = async () => {
|
||||
let jobs = [];
|
||||
|
||||
@ -46,7 +101,7 @@ export default class SceneFilesFolder extends React.Component {
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this._interval = this.loop();
|
||||
this.loop();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -61,37 +116,120 @@ export default class SceneFilesFolder extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
_increment = (direction) => {
|
||||
if (
|
||||
direction > 0 &&
|
||||
this.state.startIndex + VIEW_LIMIT <
|
||||
this.props.viewer.library[0].children.length
|
||||
) {
|
||||
this.setState({ startIndex: this.state.startIndex + VIEW_LIMIT });
|
||||
} else if (direction < 0 && this.state.startIndex - VIEW_LIMIT >= 0) {
|
||||
this.setState({ startIndex: this.state.startIndex - VIEW_LIMIT });
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ScenePage>
|
||||
<ScenePageHeader title="Data">
|
||||
Manage all the data used across your Slates and archive backups on to
|
||||
the Filecoin Network.
|
||||
</ScenePageHeader>
|
||||
|
||||
<DataMeter
|
||||
stats={this.props.viewer.stats}
|
||||
style={{ margin: "48px 0 48px 0" }}
|
||||
/>
|
||||
|
||||
<DataView
|
||||
buttons={[
|
||||
{
|
||||
name: "Upload data",
|
||||
type: "SIDEBAR",
|
||||
value: "SIDEBAR_ADD_FILE_TO_BUCKET",
|
||||
},
|
||||
/* {
|
||||
name: "Filecoin archive",
|
||||
type: "SIDEBAR",
|
||||
value: "SIDEBAR_FILECOIN_ARCHIVE",
|
||||
}, */
|
||||
]}
|
||||
viewer={this.props.viewer}
|
||||
items={this.props.viewer.library[0].children}
|
||||
onAction={this.props.onAction}
|
||||
onRehydrate={this.props.onRehydrate}
|
||||
<ScenePageHeader
|
||||
title="Data"
|
||||
actions={
|
||||
<ButtonPrimary
|
||||
onClick={() => {
|
||||
this.props.onAction({
|
||||
type: "SIDEBAR",
|
||||
value: "SIDEBAR_ADD_FILE_TO_BUCKET",
|
||||
});
|
||||
}}
|
||||
>
|
||||
Upload Data
|
||||
</ButtonPrimary>
|
||||
}
|
||||
/>
|
||||
<TabGroup disabled tabs={["Usage"]} />
|
||||
<SceneContent>
|
||||
<DataMeter
|
||||
stats={this.props.viewer.stats}
|
||||
style={{ margin: "48px 0 48px 0" }}
|
||||
/>
|
||||
</SceneContent>
|
||||
<div css={STYLES_HEADER_LINE}>
|
||||
<TabGroup disabled tabs={["Uploads"]} style={{ margin: 0 }} />
|
||||
<React.Fragment>
|
||||
<div
|
||||
css={STYLES_ICON_BOX}
|
||||
onClick={() => {
|
||||
this.setState({ view: "list" });
|
||||
}}
|
||||
>
|
||||
<SVG.ListView
|
||||
style={{
|
||||
color:
|
||||
this.state.view === "list"
|
||||
? Constants.system.black
|
||||
: "rgba(0,0,0,0.25)",
|
||||
}}
|
||||
height="24px"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
css={STYLES_ICON_BOX}
|
||||
onClick={() => {
|
||||
this.setState({ view: "grid" });
|
||||
}}
|
||||
>
|
||||
<SVG.GridView
|
||||
style={{
|
||||
color:
|
||||
this.state.view === "grid"
|
||||
? Constants.system.black
|
||||
: "rgba(0,0,0,0.25)",
|
||||
}}
|
||||
height="24px"
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
</div>
|
||||
<SceneContent>
|
||||
<DataView
|
||||
view={this.state.view}
|
||||
viewer={this.props.viewer}
|
||||
items={this.props.viewer.library[0].children.slice(
|
||||
this.state.startIndex,
|
||||
this.state.startIndex + VIEW_LIMIT
|
||||
)}
|
||||
onAction={this.props.onAction}
|
||||
onRehydrate={this.props.onRehydrate}
|
||||
/>
|
||||
<div css={STYLES_ARROWS}>
|
||||
<span
|
||||
css={STYLES_ICON_ELEMENT}
|
||||
style={
|
||||
this.state.startIndex - VIEW_LIMIT >= 0
|
||||
? null
|
||||
: { cursor: "not-allowed", color: Constants.system.border }
|
||||
}
|
||||
onClick={() => this._increment(-1)}
|
||||
>
|
||||
<SVG.NavigationArrow
|
||||
height="24px"
|
||||
style={{ transform: `rotate(180deg)` }}
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
css={STYLES_ICON_ELEMENT}
|
||||
style={
|
||||
this.state.startIndex + VIEW_LIMIT <
|
||||
this.props.viewer.library[0].children.length
|
||||
? null
|
||||
: { cursor: "not-allowed", color: Constants.system.border }
|
||||
}
|
||||
onClick={() => this._increment(1)}
|
||||
>
|
||||
<SVG.NavigationArrow height="24px" />
|
||||
</span>
|
||||
</div>
|
||||
</SceneContent>
|
||||
</ScenePage>
|
||||
);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import Section from "~/components/core/Section";
|
||||
import ScenePage from "~/components/core/ScenePage";
|
||||
import DataView from "~/components/core/DataView";
|
||||
import ScenePageHeader from "~/components/core/ScenePageHeader";
|
||||
import SceneContent from "~/components/core/SceneContent";
|
||||
|
||||
const STYLES_NUMBER = css`
|
||||
font-family: ${Constants.font.semiBold};
|
||||
@ -91,41 +92,33 @@ export default class SceneHome extends React.Component {
|
||||
return (
|
||||
<ScenePage>
|
||||
<ScenePageHeader title="Home">
|
||||
Welcome back! Here is your data and slates.
|
||||
Welcome back! Here is your data.
|
||||
</ScenePageHeader>
|
||||
|
||||
<Section
|
||||
title="Slates"
|
||||
buttons={slateButtons}
|
||||
onAction={this.props.onAction}>
|
||||
<System.Table
|
||||
data={slates}
|
||||
name="slate"
|
||||
onAction={this.props.onAction}
|
||||
onNavigateTo={this.props.onNavigateTo}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
{this.props.viewer.library[0] ? (
|
||||
<DataView
|
||||
buttons={[
|
||||
{
|
||||
name: "View files",
|
||||
type: "NAVIGATE",
|
||||
value: this.props.viewer.library[0].id,
|
||||
},
|
||||
{
|
||||
name: "Upload data",
|
||||
type: "SIDEBAR",
|
||||
value: "SIDEBAR_ADD_FILE_TO_BUCKET",
|
||||
},
|
||||
]}
|
||||
viewer={this.props.viewer}
|
||||
items={this.props.viewer.library[0].children}
|
||||
onAction={this.props.onAction}
|
||||
onRehydrate={this.props.onRehydrate}
|
||||
/>
|
||||
) : null}
|
||||
<SceneContent>
|
||||
{this.props.viewer.library[0] ? (
|
||||
<div style={{ marginTop: "48px" }}>
|
||||
<DataView
|
||||
buttons={[
|
||||
{
|
||||
name: "View files",
|
||||
type: "NAVIGATE",
|
||||
value: this.props.viewer.library[0].id,
|
||||
},
|
||||
{
|
||||
name: "Upload data",
|
||||
type: "SIDEBAR",
|
||||
value: "SIDEBAR_ADD_FILE_TO_BUCKET",
|
||||
},
|
||||
]}
|
||||
viewer={this.props.viewer}
|
||||
items={this.props.viewer.library[0].children}
|
||||
onAction={this.props.onAction}
|
||||
onRehydrate={this.props.onRehydrate}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</SceneContent>
|
||||
</ScenePage>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user