未验证 提交 b61595ea 编写于 作者: P Peter Pan 提交者: GitHub

chore: add error tip when nothing get from backend (#659)

上级 ff057a44
import React, {FunctionComponent} from 'react';
import {Trans, useTranslation} from '~/utils/i18n';
import {WithStyled, backgroundColor, em, link, rem, size, textColor, textLightColor} from '~/utils/style';
import styled from 'styled-components';
const Wrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
background-color: ${backgroundColor};
height: 100%;
width: 100%;
> .image {
background-image: url(${`${process.env.PUBLIC_PATH}/images/empty.svg`});
background-repeat: no-repeat;
background-position: center center;
background-size: 100% 100%;
${size(rem(244), rem(280))}
}
> .inner {
width: calc(50% - ${rem(280)});
color: ${textLightColor};
${link}
h4 {
color: ${textColor};
font-size: ${em(18)};
font-weight: 700;
}
p {
margin: 0;
}
ol {
padding-left: 2em;
line-height: 1.857142857;
}
}
`;
const Error: FunctionComponent<WithStyled> = ({className, children}) => {
const {t} = useTranslation('errors');
return (
<Wrapper className={className}>
<div className="image"></div>
<div className="inner">
{children || (
<>
<h4>{t('errors:common.title')}</h4>
<p>{t('errors:common.description')}</p>
<ol>
<li>
<Trans i18nKey="errors:common.1">
Log files are not generated. Please refer to&nbsp;
<a href="https://github.com/PaddlePaddle/VisualDL" target="_blank" rel="noreferrer">
README
</a>
&nbsp;to create log files.
</Trans>
</li>
<li>
<Trans i18nKey="errors:common.2">
Log files are generated but data is not written yet. Please refer to&nbsp;
<a
href="https://github.com/PaddlePaddle/VisualDL/blob/develop/docs/components/README.md"
target="_blank"
rel="noreferrer"
>
VisualDL User Guide
</a>
&nbsp;to write visualized data.
</Trans>
</li>
<li>
<Trans i18nKey="errors:common.3">
Log files are generated and data is writte. Please try to&nbsp;
<a href="javascript:location.reload()">Refresh</a>.
</Trans>
</li>
<li>
<Trans i18nKey="errors:common.4">
Log files are generated but path to log directory is wrong. Please check your
directory and try again.
</Trans>
</li>
</ol>
</>
)}
</div>
</Wrapper>
);
};
export default Error;
...@@ -7,6 +7,7 @@ import {em, rem} from '~/utils/style'; ...@@ -7,6 +7,7 @@ import {em, rem} from '~/utils/style';
import Checkbox from '~/components/Checkbox'; import Checkbox from '~/components/Checkbox';
import Content from '~/components/Content'; import Content from '~/components/Content';
import Error from '~/components/Error';
import Field from '~/components/Field'; import Field from '~/components/Field';
import HighDimensionalChart from '~/components/HighDimensionalPage/HighDimensionalChart'; import HighDimensionalChart from '~/components/HighDimensionalPage/HighDimensionalChart';
import Icon from '~/components/Icon'; import Icon from '~/components/Icon';
...@@ -95,54 +96,55 @@ const HighDimensional: NextI18NextPage = () => { ...@@ -95,54 +96,55 @@ const HighDimensional: NextI18NextPage = () => {
const bottom = useMemo(() => <RunningToggle running={running} onToggle={setRunning} />, [running, setRunning]); const bottom = useMemo(() => <RunningToggle running={running} onToggle={setRunning} />, [running, setRunning]);
const aside = useMemo( const aside = useMemo(
() => ( () =>
<Aside bottom={bottom}> labelList.length ? (
<AsideSection> <Aside bottom={bottom}>
<AsideTitle>{t('common:select-runs')}</AsideTitle> <AsideSection>
<StyledSelect list={labelList} value={label} onChange={setLabel} /> <AsideTitle>{t('common:select-runs')}</AsideTitle>
</AsideSection> <StyledSelect list={labelList} value={label} onChange={setLabel} />
<AsideSection> </AsideSection>
<Field> <AsideSection>
<SearchInput placeholder={t('common:search')} value={search} onChange={setSearch} /> <Field>
</Field> <SearchInput placeholder={t('common:search')} value={search} onChange={setSearch} />
<Field> </Field>
<Checkbox value={labelVisibility} onChange={setLabelVisibility}> <Field>
{t('high-dimensional:display-all-label')} <Checkbox value={labelVisibility} onChange={setLabelVisibility}>
</Checkbox> {t('high-dimensional:display-all-label')}
</Field> </Checkbox>
</AsideSection> </Field>
<AsideSection> </AsideSection>
<AsideTitle> <AsideSection>
<StyledIcon type="dimension" /> <AsideTitle>
{t('high-dimensional:dimension')} <StyledIcon type="dimension" />
</AsideTitle> {t('high-dimensional:dimension')}
<Field> </AsideTitle>
<RadioGroup value={dimension} onChange={value => setDimension(value)}> <Field>
{dimensions.map(item => ( <RadioGroup value={dimension} onChange={value => setDimension(value)}>
<RadioButton key={item} value={item}> {dimensions.map(item => (
{t(item)} <RadioButton key={item} value={item}>
</RadioButton> {t(item)}
))} </RadioButton>
</RadioGroup> ))}
</Field> </RadioGroup>
</AsideSection> </Field>
<AsideSection> </AsideSection>
<AsideTitle> <AsideSection>
<StyledIcon type="reduction" /> <AsideTitle>
{t('high-dimensional:reduction-method')} <StyledIcon type="reduction" />
</AsideTitle> {t('high-dimensional:reduction-method')}
<Field> </AsideTitle>
<RadioGroup value={reduction} onChange={value => setReduction(value)}> <Field>
{reductions.map(item => ( <RadioGroup value={reduction} onChange={value => setReduction(value)}>
<RadioButton key={item} value={item}> {reductions.map(item => (
{t(item)} <RadioButton key={item} value={item}>
</RadioButton> {t(item)}
))} </RadioButton>
</RadioGroup> ))}
</Field> </RadioGroup>
</AsideSection> </Field>
</Aside> </AsideSection>
), </Aside>
) : null,
[t, bottom, dimension, label, labelList, labelVisibility, reduction, search] [t, bottom, dimension, label, labelList, labelVisibility, reduction, search]
); );
...@@ -151,7 +153,9 @@ const HighDimensional: NextI18NextPage = () => { ...@@ -151,7 +153,9 @@ const HighDimensional: NextI18NextPage = () => {
<Preloader url="/runs" /> <Preloader url="/runs" />
<Title>{t('common:high-dimensional')}</Title> <Title>{t('common:high-dimensional')}</Title>
<Content aside={aside} loading={loading}> <Content aside={aside} loading={loading}>
{error ? ( {!loading && !list.length ? (
<Error />
) : error ? (
<div>{t('common:error')}</div> <div>{t('common:error')}</div>
) : loading ? null : ( ) : loading ? null : (
<HighDimensionalChart <HighDimensionalChart
......
...@@ -7,6 +7,7 @@ import React, {useCallback, useMemo, useState} from 'react'; ...@@ -7,6 +7,7 @@ import React, {useCallback, useMemo, useState} from 'react';
import {AsideSection} from '~/components/Aside'; import {AsideSection} from '~/components/Aside';
import Checkbox from '~/components/Checkbox'; import Checkbox from '~/components/Checkbox';
import Content from '~/components/Content'; import Content from '~/components/Content';
import Error from '~/components/Error';
import Field from '~/components/Field'; import Field from '~/components/Field';
import Preloader from '~/components/Preloader'; import Preloader from '~/components/Preloader';
import RunAside from '~/components/RunAside'; import RunAside from '~/components/RunAside';
...@@ -49,31 +50,32 @@ const Samples: NextI18NextPage = () => { ...@@ -49,31 +50,32 @@ const Samples: NextI18NextPage = () => {
const [contrast, setContrast] = useState(1); const [contrast, setContrast] = useState(1);
const aside = useMemo( const aside = useMemo(
() => ( () =>
<RunAside runs.length ? (
runs={runs} <RunAside
selectedRuns={selectedRuns} runs={runs}
onChangeRuns={onChangeRuns} selectedRuns={selectedRuns}
running={running} onChangeRuns={onChangeRuns}
onToggleRunning={setRunning} running={running}
> onToggleRunning={setRunning}
<AsideSection> >
<Checkbox value={showActualSize} onChange={setShowActualSize}> <AsideSection>
{t('samples:show-actual-size')} <Checkbox value={showActualSize} onChange={setShowActualSize}>
</Checkbox> {t('samples:show-actual-size')}
</AsideSection> </Checkbox>
<AsideSection> </AsideSection>
<Field label={t('samples:brightness')}> <AsideSection>
<Slider min={0} max={2} step={0.01} value={brightness} onChange={setBrightness} /> <Field label={t('samples:brightness')}>
</Field> <Slider min={0} max={2} step={0.01} value={brightness} onChange={setBrightness} />
</AsideSection> </Field>
<AsideSection> </AsideSection>
<Field label={t('samples:contrast')}> <AsideSection>
<Slider min={0} max={2} step={0.01} value={contrast} onChange={setContrast} /> <Field label={t('samples:contrast')}>
</Field> <Slider min={0} max={2} step={0.01} value={contrast} onChange={setContrast} />
</AsideSection> </Field>
</RunAside> </AsideSection>
), </RunAside>
) : null,
[t, brightness, contrast, onChangeRuns, running, runs, selectedRuns, showActualSize] [t, brightness, contrast, onChangeRuns, running, runs, selectedRuns, showActualSize]
); );
...@@ -97,12 +99,16 @@ const Samples: NextI18NextPage = () => { ...@@ -97,12 +99,16 @@ const Samples: NextI18NextPage = () => {
<Preloader url="/images/tags" /> <Preloader url="/images/tags" />
<Title>{t('common:samples')}</Title> <Title>{t('common:samples')}</Title>
<Content aside={aside} loading={loadingRuns}> <Content aside={aside} loading={loadingRuns}>
<ChartPage {!loadingRuns && !runs.length ? (
items={ungroupedSelectedTags} <Error />
chartSize={chartSize} ) : (
withChart={withChart} <ChartPage
loading={loadingRuns || loadingTags} items={ungroupedSelectedTags}
/> chartSize={chartSize}
withChart={withChart}
loading={loadingRuns || loadingTags}
/>
)}
</Content> </Content>
</> </>
); );
......
...@@ -6,6 +6,7 @@ import {sortingMethodMap, xAxisMap} from '~/resource/scalars'; ...@@ -6,6 +6,7 @@ import {sortingMethodMap, xAxisMap} from '~/resource/scalars';
import {AsideSection} from '~/components/Aside'; import {AsideSection} from '~/components/Aside';
import Checkbox from '~/components/Checkbox'; import Checkbox from '~/components/Checkbox';
import Content from '~/components/Content'; import Content from '~/components/Content';
import Error from '~/components/Error';
import Field from '~/components/Field'; import Field from '~/components/Field';
import Preloader from '~/components/Preloader'; import Preloader from '~/components/Preloader';
import RadioButton from '~/components/RadioButton'; import RadioButton from '~/components/RadioButton';
...@@ -53,48 +54,49 @@ const Scalars: NextI18NextPage = () => { ...@@ -53,48 +54,49 @@ const Scalars: NextI18NextPage = () => {
const [ignoreOutliers, setIgnoreOutliers] = useState(false); const [ignoreOutliers, setIgnoreOutliers] = useState(false);
const aside = useMemo( const aside = useMemo(
() => ( () =>
<RunAside runs.length ? (
runs={runs} <RunAside
selectedRuns={selectedRuns} runs={runs}
onChangeRuns={onChangeRuns} selectedRuns={selectedRuns}
running={running} onChangeRuns={onChangeRuns}
onToggleRunning={setRunning} running={running}
> onToggleRunning={setRunning}
<AsideSection> >
<Checkbox value={ignoreOutliers} onChange={setIgnoreOutliers}> <AsideSection>
{t('scalars:ignore-outliers')} <Checkbox value={ignoreOutliers} onChange={setIgnoreOutliers}>
</Checkbox> {t('scalars:ignore-outliers')}
<TooltipSortingDiv> </Checkbox>
<span>{t('scalars:tooltip-sorting')}</span> <TooltipSortingDiv>
<Select <span>{t('scalars:tooltip-sorting')}</span>
list={toolTipSortingValues.map(value => ({ <Select
label: t(`tooltip-sorting-value.${value}`), list={toolTipSortingValues.map(value => ({
value label: t(`tooltip-sorting-value.${value}`),
}))} value
value={tooltipSorting} }))}
onChange={setTooltipSorting} value={tooltipSorting}
/> onChange={setTooltipSorting}
</TooltipSortingDiv> />
</AsideSection> </TooltipSortingDiv>
<AsideSection> </AsideSection>
<Field label={t('scalars:smoothing')}> <AsideSection>
<Slider min={0} max={0.99} step={0.01} value={smoothing} onChangeComplete={setSmoothing} /> <Field label={t('scalars:smoothing')}>
</Field> <Slider min={0} max={0.99} step={0.01} value={smoothing} onChangeComplete={setSmoothing} />
</AsideSection> </Field>
<AsideSection> </AsideSection>
<Field label={t('scalars:x-axis')}> <AsideSection>
<RadioGroup value={xAxis} onChange={setXAxis}> <Field label={t('scalars:x-axis')}>
{xAxisValues.map(value => ( <RadioGroup value={xAxis} onChange={setXAxis}>
<RadioButton key={value} value={value}> {xAxisValues.map(value => (
{t(`x-axis-value.${value}`)} <RadioButton key={value} value={value}>
</RadioButton> {t(`x-axis-value.${value}`)}
))} </RadioButton>
</RadioGroup> ))}
</Field> </RadioGroup>
</AsideSection> </Field>
</RunAside> </AsideSection>
), </RunAside>
) : null,
[t, ignoreOutliers, onChangeRuns, running, runs, selectedRuns, smoothing, tooltipSorting, xAxis] [t, ignoreOutliers, onChangeRuns, running, runs, selectedRuns, smoothing, tooltipSorting, xAxis]
); );
...@@ -120,7 +122,11 @@ const Scalars: NextI18NextPage = () => { ...@@ -120,7 +122,11 @@ const Scalars: NextI18NextPage = () => {
<Preloader url="/scalars/tags" /> <Preloader url="/scalars/tags" />
<Title>{t('common:scalars')}</Title> <Title>{t('common:scalars')}</Title>
<Content aside={aside} loading={loadingRuns}> <Content aside={aside} loading={loadingRuns}>
<ChartPage items={tags} withChart={withChart} loading={loadingRuns || loadingTags} /> {!loadingRuns && !runs.length ? (
<Error />
) : (
<ChartPage items={tags} withChart={withChart} loading={loadingRuns || loadingTags} />
)}
</Content> </Content>
</> </>
); );
......
{ {
"error-with-status": "A {{statusCode}} error occurred on server", "error-with-status": "A {{statusCode}} error occurred on server",
"error-without-status": "An error occurred on the server", "error-without-status": "An error occurred on the server",
"page-not-found": "Page Not Found" "page-not-found": "Page Not Found",
"common": {
"title": "No visualized data.",
"description": "Possible reasons are:",
"1": "Log files are not generated. Please refer to <1>README</1> to create log files.",
"2": "Log files are generated but data is not written yet. Please refer to <1>VisualDL User Guide</1> to write visualized data.",
"3": "Log files are generated and data is writte. Please try to <1>Refresh</1>.",
"4": "Log files are generated but path to log directory is wrong. Please check your directory and try again."
}
} }
{ {
"error-with-status": "服务器发生了一个 {{statusCode}} 错误", "error-with-status": "服务器发生了一个 {{statusCode}} 错误",
"error-without-status": "服务器发生了一个错误", "error-without-status": "服务器发生了一个错误",
"page-not-found": "页面不存在" "page-not-found": "页面不存在",
"common": {
"title": "无可视化结果展示",
"description": "有以下几种可能原因,请您参考相应解决方案:",
"1": "未生成日志文件。请参考 <1>README</1> 创建日志文件。",
"2": "已生成日志文件,但尚未打点数据。请参考 <1>VisualDL使用指南</1> ,对需要进行可视化的数据进行打点记录。",
"3": "已生成文件并打点数据,请尝试 <1>刷新</1> 。",
"4": "已生成文件,但日志文件路径错误,请确保文件路径正确。"
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册