Merge pull request #1636 from molecula/feature/syang/diskusage-lastupdated

CLOUD-78: Add 'last updated' info to tables UI
This commit is contained in:
Stephanie Yang 2021-06-14 16:25:22 -05:00 committed by GitHub
commit 25bf4fdaa7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 151 additions and 9 deletions

View file

@ -126,3 +126,15 @@
}
}
}
.infoMessage {
padding: 16px;
border: 1px solid rgba(var(--primary-rgb), 0.5);
background: rgba(var(--primary-rgb), 0.1);
border-radius: 4px;
margin: 4px 0 16px;
.infoTooltip {
border-bottom: 1px dashed rgba(var(--primary-rgb), 0.7);
}
}

View file

@ -4,8 +4,10 @@ import Breadcrumbs from '@material-ui/core/Breadcrumbs';
import classNames from 'classnames';
import Fuse from 'fuse.js';
import Highlighter from 'react-highlight-words';
import isEmpty from 'lodash/isEmpty';
import Link from '@material-ui/core/Link';
import map from 'lodash/map';
import moment from 'moment';
import OrderBy from 'lodash/orderBy';
import Reduce from 'lodash/reduce';
import Table from '@material-ui/core/Table';
@ -14,6 +16,7 @@ import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import TextField from '@material-ui/core/TextField';
import Tooltip from '@material-ui/core/Tooltip';
import Typography from '@material-ui/core/Typography';
import { Block } from 'shared/Block';
import { Pager } from 'shared/Pager';
@ -23,11 +26,13 @@ import css from './MoleculaTable.module.scss';
type MoleculaTableProps = {
table: any;
dataDistribution: any;
lastUpdated: string;
};
export const MoleculaTable: FC<MoleculaTableProps> = ({
table,
dataDistribution
dataDistribution,
lastUpdated
}) => {
const [page, setPage] = useState<number>(1);
const [resultsPerPage, setResultsPerPage] = useState<number>(10);
@ -38,9 +43,10 @@ export const MoleculaTable: FC<MoleculaTableProps> = ({
const [maxFieldSize, setMaxFieldSize] = useState<number>(0);
const [sort, setSort] = useState<string>('total');
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc');
const lastUpdatedMoment = lastUpdated ? moment(lastUpdated).utc() : undefined;
useEffect(() => {
if (dataDistribution) {
if (dataDistribution && !dataDistribution.uncached) {
const aggregatedFieldsData = Reduce(
dataDistribution.fields,
(result, value) => {
@ -77,7 +83,7 @@ export const MoleculaTable: FC<MoleculaTableProps> = ({
threshold: 0
});
const result = fuse.search(searchText);
let resultsArray: any[] = [];
result.forEach((r: any) => {
resultsArray.push({ ...r?.item, ...fieldsData[r?.item.name] });
@ -125,6 +131,46 @@ export const MoleculaTable: FC<MoleculaTableProps> = ({
<Typography variant="h5" color="textSecondary">
{table.name}
</Typography>
{lastUpdatedMoment ? (
<div className={css.infoMessage}>
{dataDistribution && dataDistribution.uncached ? (
<Fragment>
Disk usage will be calculated at the next{` `}
<Tooltip
title={
<Fragment>
Disk and memory information shown here are read from a
cache, the behavior of which can be controlled with the{` `}
<code style={{ whiteSpace: 'nowrap' }}>
--usage-duty-cycle
</code>{' '}
command line flag.
</Fragment>
}
placement="top"
arrow
>
<span className={css.infoTooltip}>cache refresh</span>
</Tooltip>
.
</Fragment>
) : (
<Fragment>
Disk usage last updated{' '}
<Tooltip
title={`${lastUpdatedMoment.format('M/D/YYYY hh:mm a')} UTC`}
placement="top"
arrow
>
<span className={css.infoTooltip}>
{lastUpdatedMoment.fromNow()}
</span>
</Tooltip>
.
</Fragment>
)}
</div>
) : null}
<div className={css.layout}>
<div>
<label className={css.label}>keys</label>
@ -251,7 +297,15 @@ export const MoleculaTable: FC<MoleculaTableProps> = ({
</TableCell>
<TableCell className={css.tableCell}>
<UsageBreakdown
data={field}
data={
isEmpty(field)
? field
: dataDistribution
? dataDistribution.uncached
? dataDistribution
: field
: field
}
width={`${(field.total / maxFieldSize) * 150}px`}
showLabel={false}
usageValueSize="small"

View file

@ -69,3 +69,15 @@
.pilosaError {
padding: 8px 16px;
}
.infoMessage {
padding: 16px;
border: 1px solid rgba(var(--primary-rgb), 0.5);
background: rgba(var(--primary-rgb), 0.1);
border-radius: 4px;
margin: 4px 0 16px;
.infoTooltip {
border-bottom: 1px dashed rgba(var(--primary-rgb), 0.7);
}
}

View file

@ -1,8 +1,10 @@
import React, { FC, Fragment, useEffect, useState } from 'react';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import moment from 'moment';
import OrderBy from 'lodash/orderBy';
import Paper from '@material-ui/core/Paper';
import Tooltip from '@material-ui/core/Tooltip';
import Typography from '@material-ui/core/Typography';
import { Block } from 'shared/Block';
import { SortBy } from 'shared/SortBy';
@ -13,16 +15,19 @@ import css from './MoleculaTables.module.scss';
type MoleculaTablesProps = {
tables: any;
dataDistribution: any;
lastUpdated: string;
maxSize: number;
};
export const MoleculaTables: FC<MoleculaTablesProps> = ({
tables,
dataDistribution,
lastUpdated,
maxSize
}) => {
const history = useHistory();
const [sortedTables, setSortedTables] = useState<any>([]);
const lastUpdatedMoment = lastUpdated ? moment(lastUpdated).utc() : undefined;
useEffect(() => {
if (tables && dataDistribution) {
@ -51,6 +56,38 @@ export const MoleculaTables: FC<MoleculaTablesProps> = ({
<Typography variant="h5" color="textSecondary">
Tables
</Typography>
{lastUpdatedMoment ? (
<div className={css.infoMessage}>
Disk usage last updated{' '}
<Tooltip
title={`${lastUpdatedMoment.format('M/D/YYYY hh:mm a')} UTC`}
placement="top"
arrow
>
<span className={css.infoTooltip}>
{lastUpdatedMoment.fromNow()}
</span>
</Tooltip>
. Disk usage for new tables will be calculated at the next{` `}
<Tooltip
title={
<Fragment>
Disk and memory information shown here are read from a cache,
the behavior of which can be controlled with the{` `}
<code style={{ whiteSpace: 'nowrap' }}>
--usage-duty-cycle
</code>{' '}
command line flag.
</Fragment>
}
placement="top"
arrow
>
<span className={css.infoTooltip}>cache refresh</span>
</Tooltip>
.
</div>
) : null}
<div className={css.actions}>
<SortBy
options={[
@ -77,10 +114,14 @@ export const MoleculaTables: FC<MoleculaTablesProps> = ({
<div className={css.section}>
<UsageBreakdown
data={
dataDistribution ? dataDistribution[name] : undefined
dataDistribution
? dataDistribution[name]
? dataDistribution[name]
: { uncached: true }
: undefined
}
width={
dataDistribution
dataDistribution && dataDistribution[name]
? `${(dataDistribution[name].total / maxSize) * 100}%`
: '0px'
}

View file

@ -14,6 +14,7 @@ export const MoleculaTablesContainer = () => {
const [selectedTable, setSelectedTable] = useState<any>();
const [dataDistribution, setDataDistribution] = useState<any>();
const [maxSize, setMaxSize] = useState<number>(0);
const [lastUpdated, setLastUpdated] = useState<string>('');
useEffectOnce(() => {
pilosa.get
@ -25,7 +26,7 @@ export const MoleculaTablesContainer = () => {
.then((res) => setTables(res.data.indexes))
.catch((err) => console.log(err))
);
pilosa.get.usage().then((res) => {
const nodes = Object.keys(res.data);
let data = {};
@ -54,6 +55,10 @@ export const MoleculaTablesContainer = () => {
};
}
});
if(!lastUpdated) {
setLastUpdated(res.data[node].lastUpdated);
}
});
const sorted = OrderBy(data, ['total'], ['desc']);
@ -83,13 +88,19 @@ export const MoleculaTablesContainer = () => {
<MoleculaTable
table={selectedTable}
dataDistribution={
dataDistribution ? dataDistribution[selectedTable.name] : undefined
dataDistribution
? dataDistribution[selectedTable.name]
? dataDistribution[selectedTable.name]
: { uncached: true }
: undefined
}
lastUpdated={lastUpdated}
/>
) : (
<MoleculaTables
tables={tables}
dataDistribution={dataDistribution}
lastUpdated={lastUpdated}
maxSize={maxSize}
/>
);

View file

@ -18,7 +18,15 @@ export const UsageBreakdown: FC<UsageBreakdownProps> = ({
showLabel = true,
usageValueSize = 'medium'
}) => {
const { total, fieldKeysTotal, indexKeys, fragments, metadata, keys } = data;
const {
total,
fieldKeysTotal,
indexKeys,
fragments,
metadata,
keys,
uncached
} = data;
const fieldKeysPercentage =
fieldKeysTotal && total ? (fieldKeysTotal / total) * 100 : 0;
const indexKeysPercentage = indexKeys ? (indexKeys / total) * 100 : 0;
@ -160,6 +168,10 @@ export const UsageBreakdown: FC<UsageBreakdownProps> = ({
) : null}
</div>
</Fragment>
) : uncached ? (
<Typography variant="caption" component="div">
Waiting...
</Typography>
) : (
<Typography variant="caption" component="div">
Calculating...