[Dashboard] Refactor Empty Screen (#158496)

Updated Dashboard Empty State
Co-authored-by: Andrea Del Rio <delrio.andre@gmail.com>
This commit is contained in:
Devon Thomson 2023-05-31 18:04:56 -04:00 committed by GitHub
parent 0fb3099620
commit 0e6b153ebe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 567 additions and 253 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 144 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 145 KiB

View file

@ -14,26 +14,21 @@
align-items: center;
}
.dshStartScreen {
text-align: center;
.dshEmptyPromptParent {
flex-grow: 1;
display: flex;
}
.dshStartScreen__pageContent {
padding: $euiSizeXXL;
.dshEmptyPromptPageTemplate {
background-color: inherit;
padding-block-start: 0 !important;
}
.dshStartScreen__panelDesc {
max-width: 260px;
margin: 0 auto;
}
.dshEmptyWidget {
background-color: $euiColorLightestShade;
border: $euiBorderThin;
border-style: dashed;
.dshEmptyWidgetContainer {
padding: $euiSizeXL;
padding-top: 0 !important;
border-radius: $euiBorderRadius;
padding: $euiSizeXXL * 2;
max-width: 400px;
margin-left: $euiSizeS;
text-align: center;
.euiEmptyPrompt__icon {
margin-bottom: 0;
}
}

View file

@ -12,33 +12,46 @@ import { i18n } from '@kbn/i18n';
Empty Screen
*/
export const emptyScreenStrings = {
getEmptyDashboardTitle: () =>
i18n.translate('dashboard.emptyDashboardTitle', {
defaultMessage: 'This dashboard is empty.',
}),
getEmptyDashboardAdditionalPrivilege: () =>
i18n.translate('dashboard.emptyDashboardAdditionalPrivilege', {
defaultMessage: 'You need additional privileges to edit this dashboard.',
}),
getFillDashboardTitle: () =>
i18n.translate('dashboard.fillDashboardTitle', {
// Edit mode
getEditModeTitle: () =>
i18n.translate('dashboard.emptyScreen.editModeTitle', {
defaultMessage: 'This dashboard is empty. Let\u2019s fill it up!',
}),
getHowToStartWorkingOnNewDashboardDescription: () =>
i18n.translate('dashboard.howToStartWorkingOnNewDashboardDescription', {
defaultMessage: 'Click edit in the menu bar above to start adding panels.',
getEditModeSubtitle: () =>
i18n.translate('dashboard.emptyScreen.editModeSubtitle', {
defaultMessage: 'Create a visualization of your data, or add one from the Visualize Library.',
}),
getHowToStartWorkingOnNewDashboardEditLinkAriaLabel: () =>
i18n.translate('dashboard.howToStartWorkingOnNewDashboardEditLinkAriaLabel', {
getAddFromLibraryButtonTitle: () =>
i18n.translate('dashboard.emptyScreen.addFromLibrary', {
defaultMessage: 'Add from library',
}),
getCreateVisualizationButtonTitle: () =>
i18n.translate('dashboard.emptyScreen.createVisualization', {
defaultMessage: 'Create visualization',
}),
// View Mode with permissions
getViewModeWithPermissionsTitle: () =>
i18n.translate('dashboard.emptyScreen.viewModeTitle', {
defaultMessage: 'Add visualizations to your dashboard',
}),
getViewModeWithPermissionsSubtitle: () =>
i18n.translate('dashboard.emptyScreen.viewModeSubtitle', {
defaultMessage: 'Enter edit mode, and then start adding your visualizations.',
}),
getEditLinkTitle: () =>
i18n.translate('dashboard.emptyScreen.editDashboard', {
defaultMessage: 'Edit dashboard',
}),
getEmptyWidgetTitle: () =>
i18n.translate('dashboard.emptyWidget.addPanelTitle', {
defaultMessage: 'Add your first visualization',
// View Mode without permissions
getViewModeWithoutPermissionsTitle: () =>
i18n.translate('dashboard.emptyScreen.noPermissionsTitle', {
defaultMessage: 'This dashboard is empty.',
}),
getEmptyWidgetDescription: () =>
i18n.translate('dashboard.emptyWidget.addPanelDescription', {
defaultMessage: 'Create content that tells a story about your data.',
getViewModeWithoutPermissionsSubtitle: () =>
i18n.translate('dashboard.emptyScreen.noPermissionsSubtitle', {
defaultMessage: 'You need additional privileges to edit this dashboard.',
}),
};

View file

@ -2,121 +2,369 @@
exports[`DashboardEmptyScreen renders correctly with edit mode 1`] = `
<div
class="dshEmptyWidget"
data-test-subj="emptyDashboardWidget"
class="dshEmptyPromptParent"
>
<span
color="subdued"
data-euiicon-type="visAreaStacked"
/>
<div
class="euiSpacer euiSpacer--s emotion-euiSpacer-s"
/>
<h3
class="euiTitle emotion-euiTitle-xs"
class="euiPageTemplate dshEmptyPromptPageTemplate emotion-euiPageOuter-row-grow"
data-test-subj="emptyDashboardWidget"
style="min-block-size: 460px; padding-block-start: 0;"
>
Add your first visualization
</h3>
<main
class="emotion-euiPageInner"
id="EuiPageTemplateInner_generated-id"
>
<section
class="emotion-euiPageSection-grow-l-center-transparent"
>
<div
class="emotion-euiPageSection__content-l-center"
>
<div
class="euiPanel euiPanel--transparent euiEmptyPrompt euiEmptyPrompt--vertical euiEmptyPrompt--paddingLarge dshEmptyWidgetContainer emotion-euiPanel-m-transparent"
>
<div
class="euiEmptyPrompt__main"
>
<div
class="euiEmptyPrompt__icon"
>
<figure
class="euiImageWrapper emotion-euiImageWrapper-fullWidth"
>
<img
alt=""
class="euiImage emotion-euiImage-fullWidth"
src="/plugins/dashboard/assets/dashboards_light.svg"
/>
</figure>
</div>
<div
class="euiEmptyPrompt__content"
>
<div
class="euiEmptyPrompt__contentInner"
>
<h2
class="euiTitle emotion-euiTitle-xs"
>
This dashboard is empty. Lets fill it up!
</h2>
<div
class="euiSpacer euiSpacer--m emotion-euiSpacer-m"
/>
<div
class="euiText emotion-euiText-m-euiTextColor-subdued"
>
<div
class="euiText emotion-euiText-s-euiTextColor-subdued"
>
<span>
Create a visualization of your data, or add one from the Visualize Library.
</span>
</div>
</div>
<div
class="euiSpacer euiSpacer--l emotion-euiSpacer-l"
/>
<div
class="euiFlexGroup emotion-euiFlexGroup-responsive-l-center-center-row"
>
<div
class="euiFlexItem emotion-euiFlexItem-growZero"
>
<button
class="euiButton emotion-euiButtonDisplay-m-defaultMinWidth-m-base-primary"
type="button"
>
<span
class="emotion-euiButtonDisplayContent"
>
<span
color="inherit"
data-euiicon-type="lensApp"
/>
<span
class="eui-textTruncate"
>
Create visualization
</span>
</span>
</button>
</div>
<div
class="euiFlexItem emotion-euiFlexItem-growZero"
>
<button
class="euiButtonEmpty euiButtonEmpty--flushLeft css-9t7nyf-empty-primary"
type="button"
>
<span
class="euiButtonContent euiButtonEmpty__content"
>
<span
class="euiButtonContent__icon"
color="inherit"
data-euiicon-type="folderOpen"
/>
<span
class="euiButtonEmpty__text"
>
Add from library
</span>
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
</div>
</div>
`;
exports[`DashboardEmptyScreen renders correctly with readonly and edit mode 1`] = `
<div
class="dshEmptyPromptParent"
>
<div
class="euiSpacer euiSpacer--s emotion-euiSpacer-s"
/>
<div
class="euiText emotion-euiText-s-euiTextColor-subdued"
class="euiPageTemplate dshEmptyPromptPageTemplate emotion-euiPageOuter-row-grow"
data-test-subj="dashboardEmptyReadOnly"
style="min-block-size: 460px; padding-block-start: 0;"
>
<span>
Create content that tells a story about your data.
</span>
<main
class="emotion-euiPageInner"
id="EuiPageTemplateInner_generated-id"
>
<section
class="emotion-euiPageSection-grow-l-center-transparent"
>
<div
class="emotion-euiPageSection__content-l-center"
>
<div
class="euiPanel euiPanel--transparent euiEmptyPrompt euiEmptyPrompt--vertical euiEmptyPrompt--paddingLarge dshEmptyWidgetContainer emotion-euiPanel-m-transparent"
>
<div
class="euiEmptyPrompt__main"
>
<div
class="euiEmptyPrompt__icon"
>
<figure
class="euiImageWrapper emotion-euiImageWrapper-fullWidth"
>
<img
alt=""
class="euiImage emotion-euiImage-fullWidth"
src="/plugins/dashboard/assets/dashboards_light.svg"
/>
</figure>
</div>
<div
class="euiEmptyPrompt__content"
>
<div
class="euiEmptyPrompt__contentInner"
>
<h2
class="euiTitle emotion-euiTitle-xs"
>
This dashboard is empty.
</h2>
<div
class="euiSpacer euiSpacer--m emotion-euiSpacer-m"
/>
<div
class="euiText emotion-euiText-m-euiTextColor-subdued"
>
<div
class="euiText emotion-euiText-s-euiTextColor-subdued"
>
<span>
You need additional privileges to edit this dashboard.
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
</div>
</div>
`;
exports[`DashboardEmptyScreen renders correctly with readonly mode 1`] = `
<div
class="euiPage dshStartScreen emotion-euiPage-row-grow-restrictWidth"
data-test-subj="dashboardEmptyReadOnly"
style="max-width: 500px;"
class="dshEmptyPromptParent"
>
<div
class="euiPageBody emotion-euiPageBody"
class="euiPageTemplate dshEmptyPromptPageTemplate emotion-euiPageOuter-row-grow"
data-test-subj="dashboardEmptyReadOnly"
style="min-block-size: 460px; padding-block-start: 0;"
>
<div
class="euiPanel euiPanel--plain euiPageContent euiPageContent--verticalCenter euiPageContent--horizontalCenter dshStartScreen__pageContent emotion-euiPanel-grow-m-plain-hasShadow"
role="main"
<main
class="emotion-euiPageInner"
id="EuiPageTemplateInner_generated-id"
>
<figure
class="euiImageWrapper emotion-euiImageWrapper"
<section
class="emotion-euiPageSection-grow-l-center-transparent"
>
<img
alt=""
class="euiImage emotion-euiImage-original"
src="/plugins/home/assets/welcome_graphic_light_2x.png"
/>
</figure>
<div
class="euiText emotion-euiText-m"
>
<p
style="font-weight: bold;"
<div
class="emotion-euiPageSection__content-l-center"
>
This dashboard is empty.
</p>
</div>
<div
class="euiText emotion-euiText-m-euiTextColor-subdued"
>
You need additional privileges to edit this dashboard.
</div>
</div>
<div
class="euiPanel euiPanel--transparent euiEmptyPrompt euiEmptyPrompt--vertical euiEmptyPrompt--paddingLarge dshEmptyWidgetContainer emotion-euiPanel-m-transparent"
>
<div
class="euiEmptyPrompt__main"
>
<div
class="euiEmptyPrompt__icon"
>
<figure
class="euiImageWrapper emotion-euiImageWrapper-fullWidth"
>
<img
alt=""
class="euiImage emotion-euiImage-fullWidth"
src="/plugins/dashboard/assets/dashboards_light.svg"
/>
</figure>
</div>
<div
class="euiEmptyPrompt__content"
>
<div
class="euiEmptyPrompt__contentInner"
>
<h2
class="euiTitle emotion-euiTitle-xs"
>
This dashboard is empty.
</h2>
<div
class="euiSpacer euiSpacer--m emotion-euiSpacer-m"
/>
<div
class="euiText emotion-euiText-m-euiTextColor-subdued"
>
<div
class="euiText emotion-euiText-s-euiTextColor-subdued"
>
<span>
You need additional privileges to edit this dashboard.
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
</div>
</div>
`;
exports[`DashboardEmptyScreen renders correctly with view mode 1`] = `
<div
class="euiPage dshStartScreen emotion-euiPage-row-grow-restrictWidth"
data-test-subj="dashboardEmptyReadWrite"
style="max-width: 500px;"
class="dshEmptyPromptParent"
>
<div
class="euiPageBody emotion-euiPageBody"
class="euiPageTemplate dshEmptyPromptPageTemplate emotion-euiPageOuter-row-grow"
data-test-subj="dashboardEmptyReadWrite"
style="min-block-size: 460px; padding-block-start: 0;"
>
<div
class="euiPanel euiPanel--plain euiPageContent euiPageContent--verticalCenter euiPageContent--horizontalCenter dshStartScreen__pageContent emotion-euiPanel-grow-m-plain-hasShadow"
role="main"
<main
class="emotion-euiPageInner"
id="EuiPageTemplateInner_generated-id"
>
<figure
class="euiImageWrapper emotion-euiImageWrapper"
>
<img
alt=""
class="euiImage emotion-euiImage-original"
src="/plugins/home/assets/welcome_graphic_light_2x.png"
/>
</figure>
<div
class="euiText emotion-euiText-m"
>
<p
style="font-weight: bold;"
>
This dashboard is empty. Lets fill it up!
</p>
</div>
<div
class="euiSpacer euiSpacer--m emotion-euiSpacer-m"
/>
<div
class="dshStartScreen__panelDesc"
<section
class="emotion-euiPageSection-grow-l-center-transparent"
>
<div
class="euiText emotion-euiText-m-euiTextColor-subdued"
class="emotion-euiPageSection__content-l-center"
>
<p>
Click edit in the menu bar above to start adding panels.
</p>
<div
class="euiPanel euiPanel--transparent euiEmptyPrompt euiEmptyPrompt--vertical euiEmptyPrompt--paddingLarge dshEmptyWidgetContainer emotion-euiPanel-m-transparent"
>
<div
class="euiEmptyPrompt__main"
>
<div
class="euiEmptyPrompt__icon"
>
<figure
class="euiImageWrapper emotion-euiImageWrapper-fullWidth"
>
<img
alt=""
class="euiImage emotion-euiImage-fullWidth"
src="/plugins/dashboard/assets/dashboards_light.svg"
/>
</figure>
</div>
<div
class="euiEmptyPrompt__content"
>
<div
class="euiEmptyPrompt__contentInner"
>
<h2
class="euiTitle emotion-euiTitle-xs"
>
Add visualizations to your dashboard
</h2>
<div
class="euiSpacer euiSpacer--m emotion-euiSpacer-m"
/>
<div
class="euiText emotion-euiText-m-euiTextColor-subdued"
>
<div
class="euiText emotion-euiText-s-euiTextColor-subdued"
>
<span>
Enter edit mode, and then start adding your visualizations.
</span>
</div>
</div>
<div
class="euiSpacer euiSpacer--l emotion-euiSpacer-l"
/>
<button
class="euiButton emotion-euiButtonDisplay-m-defaultMinWidth-m-base-primary"
type="button"
>
<span
class="emotion-euiButtonDisplayContent"
>
<span
color="inherit"
data-euiicon-type="pencil"
/>
<span
class="eui-textTruncate"
>
Edit dashboard
</span>
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
</div>
</div>
`;

View file

@ -10,49 +10,76 @@ import React from 'react';
import { mountWithIntl } from '@kbn/test-jest-helpers';
import { findTestSubject } from '@elastic/eui/lib/test';
import { buildMockDashboard } from '../../../mocks';
import { DashboardEmptyScreen } from './dashboard_empty_screen';
import { pluginServices } from '../../../services/plugin_services';
import { DashboardEmptyScreen, DashboardEmptyScreenProps } from './dashboard_empty_screen';
import { DashboardContainerContext } from '../../embeddable/dashboard_container';
import { ViewMode } from '@kbn/embeddable-plugin/public';
pluginServices.getServices().visualizations.getAliases = jest
.fn()
.mockReturnValue([{ name: 'lens' }]);
describe('DashboardEmptyScreen', () => {
const DashboardServicesProvider = pluginServices.getContextProvider();
const defaultProps = {
onLinkClick: jest.fn(),
};
function mountComponent(props?: Partial<DashboardEmptyScreenProps>) {
const compProps = { ...defaultProps, ...props };
function mountComponent(viewMode: ViewMode) {
const dashboardContainer = buildMockDashboard({ viewMode });
return mountWithIntl(
<DashboardServicesProvider>
<DashboardEmptyScreen {...compProps} />
</DashboardServicesProvider>
<DashboardContainerContext.Provider value={dashboardContainer}>
<DashboardEmptyScreen />
</DashboardContainerContext.Provider>
);
}
test('renders correctly with view mode', () => {
const component = mountComponent();
const component = mountComponent(ViewMode.VIEW);
expect(component.render()).toMatchSnapshot();
const enterEditModeParagraph = component.find('.dshStartScreen__panelDesc');
expect(enterEditModeParagraph.length).toBe(1);
const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite');
expect(emptyReadWrite.length).toBe(1);
const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly');
expect(emptyReadOnly.length).toBe(0);
const editingPanel = findTestSubject(component, 'emptyDashboardWidget');
expect(editingPanel.length).toBe(0);
});
test('renders correctly with edit mode', () => {
const component = mountComponent({ isEditMode: true });
const component = mountComponent(ViewMode.EDIT);
expect(component.render()).toMatchSnapshot();
const paragraph = component.find('.dshStartScreen__panelDesc');
expect(paragraph.length).toBe(0);
const emptyPanel = findTestSubject(component, 'emptyDashboardWidget');
expect(emptyPanel.length).toBe(1);
const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite');
expect(emptyReadWrite.length).toBe(0);
const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly');
expect(emptyReadOnly.length).toBe(0);
const editingPanel = findTestSubject(component, 'emptyDashboardWidget');
expect(editingPanel.length).toBe(1);
});
test('renders correctly with readonly mode', () => {
pluginServices.getServices().dashboardCapabilities.showWriteControls = false;
const component = mountComponent();
const component = mountComponent(ViewMode.VIEW);
expect(component.render()).toMatchSnapshot();
const paragraph = component.find('.dshStartScreen__panelDesc');
expect(paragraph.length).toBe(0);
const emptyPanel = findTestSubject(component, 'emptyDashboardWidget');
expect(emptyPanel.length).toBe(0);
const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite');
expect(emptyReadWrite.length).toBe(0);
const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly');
expect(emptyReadOnly.length).toBe(1);
const editingPanel = findTestSubject(component, 'emptyDashboardWidget');
expect(editingPanel.length).toBe(0);
});
// even when in edit mode, readonly users should not have access to the editing buttons in the empty prompt.
test('renders correctly with readonly and edit mode', () => {
pluginServices.getServices().dashboardCapabilities.showWriteControls = false;
const component = mountComponent(ViewMode.EDIT);
expect(component.render()).toMatchSnapshot();
const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite');
expect(emptyReadWrite.length).toBe(0);
const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly');
expect(emptyReadOnly.length).toBe(1);
const editingPanel = findTestSubject(component, 'emptyDashboardWidget');
expect(editingPanel.length).toBe(0);
});
});

View file

@ -6,95 +6,153 @@
* Side Public License, v 1.
*/
import React from 'react';
import { I18nProvider } from '@kbn/i18n-react';
import React, { useCallback, useMemo } from 'react';
import useObservable from 'react-use/lib/useObservable';
import {
EuiIcon,
EuiSpacer,
EuiPageContent_Deprecated as EuiPageContent,
EuiPageBody,
EuiPage,
EuiImage,
EuiText,
EuiTitle,
EuiImage,
EuiButton,
EuiFlexItem,
EuiFlexGroup,
EuiButtonEmpty,
EuiPageTemplate,
} from '@elastic/eui';
import { METRIC_TYPE } from '@kbn/analytics';
import { ViewMode } from '@kbn/embeddable-plugin/public';
import { pluginServices } from '../../../services/plugin_services';
import { emptyScreenStrings } from '../../_dashboard_container_strings';
import { useDashboardContainer } from '../../embeddable/dashboard_container';
import { DASHBOARD_UI_METRIC_ID, DASHBOARD_APP_ID } from '../../../dashboard_constants';
export interface DashboardEmptyScreenProps {
isEditMode?: boolean;
}
export function DashboardEmptyScreen({ isEditMode }: DashboardEmptyScreenProps) {
export function DashboardEmptyScreen() {
const {
dashboardCapabilities: { showWriteControls },
settings: {
theme: { theme$ },
},
usageCollection,
data: { search },
http: { basePath },
settings: { uiSettings },
embeddable: { getStateTransfer },
dashboardCapabilities: { showWriteControls },
visualizations: { getAliases: getVisTypeAliases },
} = pluginServices.getServices();
const isReadonlyMode = !showWriteControls;
const IS_DARK_THEME = uiSettings.get('theme:darkMode');
const emptyStateGraphicURL = IS_DARK_THEME
? '/plugins/home/assets/welcome_graphic_dark_2x.png'
: '/plugins/home/assets/welcome_graphic_light_2x.png';
const page = (mainText: string, showAdditionalParagraph?: boolean, additionalText?: string) => {
return (
<EuiPage
data-test-subj={isReadonlyMode ? 'dashboardEmptyReadOnly' : 'dashboardEmptyReadWrite'}
className="dshStartScreen"
restrictWidth="500px"
>
<EuiPageBody>
<EuiPageContent
verticalPosition="center"
horizontalPosition="center"
paddingSize="none"
className="dshStartScreen__pageContent"
>
<EuiImage url={basePath.prepend(emptyStateGraphicURL)} alt="" />
<EuiText size="m">
<p style={{ fontWeight: 'bold' }}>{mainText}</p>
</EuiText>
{additionalText ? (
<EuiText size="m" color="subdued">
{additionalText}
</EuiText>
) : null}
{showAdditionalParagraph ? (
<React.Fragment>
<EuiSpacer size="m" />
<div className="dshStartScreen__panelDesc">
<EuiText size="m" color="subdued">
<p>{emptyScreenStrings.getHowToStartWorkingOnNewDashboardDescription()}</p>
</EuiText>
</div>
</React.Fragment>
) : null}
</EuiPageContent>
</EuiPageBody>
</EuiPage>
);
};
const readonlyMode = page(
emptyScreenStrings.getEmptyDashboardTitle(),
false,
emptyScreenStrings.getEmptyDashboardAdditionalPrivilege()
const lensAlias = useMemo(
() => getVisTypeAliases().find(({ name }) => name === 'lens'),
[getVisTypeAliases]
);
const viewMode = page(emptyScreenStrings.getFillDashboardTitle(), true);
const editMode = (
<div data-test-subj="emptyDashboardWidget" className="dshEmptyWidget">
<EuiIcon color="subdued" size="xl" type="visAreaStacked" />
<EuiSpacer size="s" />
<EuiTitle size="xs">
<h3>{emptyScreenStrings.getEmptyWidgetTitle()}</h3>
</EuiTitle>
<EuiSpacer size="s" />
const goToLens = useCallback(() => {
if (!lensAlias || !lensAlias.aliasPath) return;
const trackUiMetric = usageCollection.reportUiCounter?.bind(
usageCollection,
DASHBOARD_UI_METRIC_ID
);
if (trackUiMetric) {
trackUiMetric(METRIC_TYPE.CLICK, `${lensAlias.name}:create`);
}
getStateTransfer().navigateToEditor(lensAlias.aliasApp, {
path: lensAlias.aliasPath,
state: {
originatingApp: DASHBOARD_APP_ID,
searchSessionId: search.session.getSessionId(),
},
});
}, [getStateTransfer, lensAlias, search.session, usageCollection]);
const dashboardContainer = useDashboardContainer();
const isDarkTheme = useObservable(theme$)?.darkMode;
const isEditMode =
dashboardContainer.select((state) => state.explicitInput.viewMode) === ViewMode.EDIT;
// TODO replace these SVGs with versions from EuiIllustration as soon as it becomes available.
const imageUrl = basePath.prepend(
`/plugins/dashboard/assets/${isDarkTheme ? 'dashboards_dark' : 'dashboards_light'}.svg`
);
// If the user ends up in edit mode without write privileges, we shouldn't show the edit prompt.
const showEditPrompt = showWriteControls && isEditMode;
const emptyPromptTestSubject = (() => {
if (showEditPrompt) return 'emptyDashboardWidget';
return showWriteControls ? 'dashboardEmptyReadWrite' : 'dashboardEmptyReadOnly';
})();
const title = (() => {
const titleString = showEditPrompt
? emptyScreenStrings.getEditModeTitle()
: showWriteControls
? emptyScreenStrings.getViewModeWithPermissionsTitle()
: emptyScreenStrings.getViewModeWithoutPermissionsTitle();
return <h2>{titleString}</h2>;
})();
const body = (() => {
const bodyString = showEditPrompt
? emptyScreenStrings.getEditModeSubtitle()
: showWriteControls
? emptyScreenStrings.getViewModeWithPermissionsSubtitle()
: emptyScreenStrings.getViewModeWithoutPermissionsSubtitle();
return (
<EuiText size="s" color="subdued">
<span>{emptyScreenStrings.getEmptyWidgetDescription()}</span>
<span>{bodyString}</span>
</EuiText>
);
})();
const actions = (() => {
if (showEditPrompt) {
return (
<EuiFlexGroup justifyContent="center" gutterSize="l" alignItems="center">
<EuiFlexItem grow={false}>
<EuiButton iconType="lensApp" onClick={() => goToLens()}>
{emptyScreenStrings.getCreateVisualizationButtonTitle()}
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
flush="left"
iconType="folderOpen"
onClick={() => dashboardContainer.addFromLibrary()}
>
{emptyScreenStrings.getAddFromLibraryButtonTitle()}
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
);
}
if (showWriteControls) {
return (
<EuiButton
iconType="pencil"
onClick={() => dashboardContainer.dispatch.setViewMode(ViewMode.EDIT)}
>
{emptyScreenStrings.getEditLinkTitle()}
</EuiButton>
);
}
})();
return (
<div className="dshEmptyPromptParent">
<EuiPageTemplate
grow={false}
data-test-subj={emptyPromptTestSubject}
className="dshEmptyPromptPageTemplate"
>
<EuiPageTemplate.EmptyPrompt
icon={<EuiImage size="fullWidth" src={imageUrl} alt="" />}
title={title}
body={body}
actions={actions}
titleSize="xs"
color="transparent"
className="dshEmptyWidgetContainer"
/>
</EuiPageTemplate>
</div>
);
const actionableMode = isEditMode ? editMode : viewMode;
return <I18nProvider>{isReadonlyMode ? readonlyMode : actionableMode}</I18nProvider>;
}

View file

@ -18,10 +18,6 @@
padding-bottom: $euiSizeXS;
}
.dshDashboardEmptyScreen {
margin-top: $euiSizeS;
}
.dashboardViewport--screenshotMode .controlsWrapper--empty {
display:none
}

View file

@ -74,6 +74,7 @@ export const DashboardViewportComponent = () => {
ref={controlsRoot}
/>
) : null}
{panelCount === 0 && <DashboardEmptyScreen />}
<div
ref={resizeRef}
className={classes}
@ -82,11 +83,6 @@ export const DashboardViewportComponent = () => {
data-description={description}
data-shared-items-count={panelCount}
>
{panelCount === 0 && (
<div className="dshDashboardEmptyScreen">
<DashboardEmptyScreen isEditMode={viewMode === ViewMode.EDIT} />
</div>
)}
<DashboardGrid viewportWidth={viewportWidth} />
</div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Before After
Before After

View file

@ -1176,17 +1176,10 @@
"dashboard.embedUrlParamExtension.query": "Requête",
"dashboard.embedUrlParamExtension.timeFilter": "Filtre temporel",
"dashboard.embedUrlParamExtension.topMenu": "Menu supérieur",
"dashboard.emptyDashboardAdditionalPrivilege": "Des privilèges supplémentaires sont requis pour pouvoir modifier ce tableau de bord.",
"dashboard.emptyDashboardTitle": "Ce tableau de bord est vide.",
"dashboard.emptyWidget.addPanelDescription": "Créez du contenu qui raconte une histoire sur vos données.",
"dashboard.emptyWidget.addPanelTitle": "Ajoutez votre première visualisation.",
"dashboard.factory.displayName": "Tableau de bord",
"dashboard.featureCatalogue.dashboardDescription": "Affichez et partagez une collection de visualisations et de recherches enregistrées.",
"dashboard.featureCatalogue.dashboardSubtitle": "Analysez des données à laide de tableaux de bord.",
"dashboard.featureCatalogue.dashboardTitle": "Tableau de bord",
"dashboard.fillDashboardTitle": "Ce tableau de bord est vide. Remplissons-le.",
"dashboard.howToStartWorkingOnNewDashboardDescription": "Cliquez sur Modifier dans la barre de menu ci-dessus pour commencer à ajouter des panneaux.",
"dashboard.howToStartWorkingOnNewDashboardEditLinkAriaLabel": "Modifier le tableau de bord",
"dashboard.labs.enableLabsDescription": "Cet indicateur détermine si l'utilisateur a accès au bouton Ateliers, moyen rapide d'activer et de désactiver les fonctionnalités de la version d'évaluation technique dans le tableau de bord.",
"dashboard.labs.enableUI": "Activer le bouton Ateliers dans le tableau de bord",
"dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription": "Analysez toutes vos données Elastic en un seul endroit, en créant un tableau de bord et en ajoutant des visualisations.",

View file

@ -1176,17 +1176,10 @@
"dashboard.embedUrlParamExtension.query": "クエリ",
"dashboard.embedUrlParamExtension.timeFilter": "時間フィルター",
"dashboard.embedUrlParamExtension.topMenu": "トップメニュー",
"dashboard.emptyDashboardAdditionalPrivilege": "このダッシュボードを編集するには、追加権限が必要です。",
"dashboard.emptyDashboardTitle": "このダッシュボードは空です。",
"dashboard.emptyWidget.addPanelDescription": "データに関するストーリーを伝えるコンテンツを作成します。",
"dashboard.emptyWidget.addPanelTitle": "最初のビジュアライゼーションを追加",
"dashboard.factory.displayName": "ダッシュボード",
"dashboard.featureCatalogue.dashboardDescription": "ビジュアライゼーションと保存された検索のコレクションの表示と共有を行います。",
"dashboard.featureCatalogue.dashboardSubtitle": "ダッシュボードでデータを分析します。",
"dashboard.featureCatalogue.dashboardTitle": "ダッシュボード",
"dashboard.fillDashboardTitle": "このダッシュボードは空です。コンテンツを追加しましょう!",
"dashboard.howToStartWorkingOnNewDashboardDescription": "上のメニューバーで[編集]をクリックすると、パネルの追加を開始します。",
"dashboard.howToStartWorkingOnNewDashboardEditLinkAriaLabel": "ダッシュボードを編集",
"dashboard.labs.enableLabsDescription": "このフラグはビューアーで[ラボ]ボタンを使用できるかどうかを決定します。ダッシュボードで実験的機能を有効および無効にするための簡単な方法です。",
"dashboard.labs.enableUI": "ダッシュボードで[ラボ]ボタンを有効にする",
"dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription": "ダッシュボードを作成し、ビジュアライゼーションを追加して、すべてのElasticデータを1つの場所で分析します。",

View file

@ -1176,17 +1176,10 @@
"dashboard.embedUrlParamExtension.query": "查询",
"dashboard.embedUrlParamExtension.timeFilter": "时间筛选",
"dashboard.embedUrlParamExtension.topMenu": "顶部菜单",
"dashboard.emptyDashboardAdditionalPrivilege": "您还需要其他权限,才能编辑此仪表板。",
"dashboard.emptyDashboardTitle": "此仪表板是空的。",
"dashboard.emptyWidget.addPanelDescription": "创建用于描述您的数据的内容。",
"dashboard.emptyWidget.addPanelTitle": "添加您的首个可视化",
"dashboard.factory.displayName": "仪表板",
"dashboard.featureCatalogue.dashboardDescription": "显示和共享可视化和已保存搜索的集合。",
"dashboard.featureCatalogue.dashboardSubtitle": "在仪表板中分析数据。",
"dashboard.featureCatalogue.dashboardTitle": "仪表板",
"dashboard.fillDashboardTitle": "此仪表板是空的。让我们来填充它!",
"dashboard.howToStartWorkingOnNewDashboardDescription": "单击上面菜单栏中的“编辑”以开始添加面板。",
"dashboard.howToStartWorkingOnNewDashboardEditLinkAriaLabel": "编辑仪表板",
"dashboard.labs.enableLabsDescription": "此标志决定查看者是否有权访问用于在仪表板中快速启用和禁用技术预览功能的“实验”按钮。",
"dashboard.labs.enableUI": "在仪表板中启用实验按钮",
"dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription": "通过创建仪表板并添加可视化,在一个位置分析所有 Elastic 数据。",