mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-05 08:10:50 +00:00
Merge pull request #1636 from molecula/feature/syang/diskusage-lastupdated
CLOUD-78: Add 'last updated' info to tables UI
This commit is contained in:
commit
25bf4fdaa7
6 changed files with 151 additions and 9 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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...
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue