mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Shared UX] Migrate PageTemplate > NoDataPage >ElasticAgent Card (#127505)
* [Shared UX] Migrate PageTemplate > NoDataPage > NoDataCard >ElasticAgentCard to Shared UX * Add more unit tests * Add more unit tests * Fix typescript & unit test * Fix snapshot * Add optional property to no_data_card * update test * Updating snapshot * Integrate RedirectAppLinks * Updating failing snapshots * Add TODO * Removed `renderFooter` prop in favor of hiding if `isDisabled` * Added `max-width` style to NoDataCard * Nit: Change name of illustration from `logo` to `illustration` * Undo generic `.svg` type change Co-authored-by: cchaos <caroline.horn@elastic.co>
This commit is contained in:
parent
c9058b850c
commit
dd3af76aa9
39 changed files with 1251 additions and 18 deletions
|
@ -2,6 +2,14 @@
|
|||
|
||||
exports[`<ExitFullScreenButton /> is rendered 1`] = `
|
||||
<ServicesProvider
|
||||
application={
|
||||
Object {
|
||||
"currentAppId$": Observable {
|
||||
"_isScalar": false,
|
||||
},
|
||||
"navigateToUrl": [Function],
|
||||
}
|
||||
}
|
||||
docLinks={
|
||||
Object {
|
||||
"dataViewsDocsLink": "dummy link",
|
||||
|
@ -12,8 +20,14 @@ exports[`<ExitFullScreenButton /> is rendered 1`] = `
|
|||
"openDataViewEditor": [MockFunction],
|
||||
}
|
||||
}
|
||||
http={
|
||||
Object {
|
||||
"addBasePath": [MockFunction],
|
||||
}
|
||||
}
|
||||
permissions={
|
||||
Object {
|
||||
"canAccessFleet": true,
|
||||
"canCreateNewDataView": true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { NoDataCard } from './no_data_page/no_data_card';
|
||||
export { NoDataCard, ElasticAgentCard } from './no_data_page/no_data_card';
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ElasticAgentCardComponent props button 1`] = `
|
||||
<RedirectAppLinks
|
||||
currentAppId$={
|
||||
Observable {
|
||||
"_isScalar": false,
|
||||
"source": Subject {
|
||||
"_isScalar": false,
|
||||
"closed": false,
|
||||
"hasError": false,
|
||||
"isStopped": false,
|
||||
"observers": Array [],
|
||||
"thrownError": null,
|
||||
},
|
||||
}
|
||||
}
|
||||
navigateToUrl={[MockFunction]}
|
||||
>
|
||||
<NoDataCard
|
||||
button="Button"
|
||||
description="Use Elastic Agent for a simple, unified way to collect data from your machines."
|
||||
image="test-file-stub"
|
||||
title="Add Elastic Agent"
|
||||
/>
|
||||
</RedirectAppLinks>
|
||||
`;
|
||||
|
||||
exports[`ElasticAgentCardComponent props href 1`] = `
|
||||
<RedirectAppLinks
|
||||
currentAppId$={
|
||||
Observable {
|
||||
"_isScalar": false,
|
||||
"source": Subject {
|
||||
"_isScalar": false,
|
||||
"closed": false,
|
||||
"hasError": false,
|
||||
"isStopped": false,
|
||||
"observers": Array [],
|
||||
"thrownError": null,
|
||||
},
|
||||
}
|
||||
}
|
||||
navigateToUrl={[MockFunction]}
|
||||
>
|
||||
<NoDataCard
|
||||
description="Use Elastic Agent for a simple, unified way to collect data from your machines."
|
||||
href="some path"
|
||||
image="test-file-stub"
|
||||
title="Add Elastic Agent"
|
||||
/>
|
||||
</RedirectAppLinks>
|
||||
`;
|
||||
|
||||
exports[`ElasticAgentCardComponent props recommended 1`] = `
|
||||
<RedirectAppLinks
|
||||
currentAppId$={
|
||||
Observable {
|
||||
"_isScalar": false,
|
||||
"source": Subject {
|
||||
"_isScalar": false,
|
||||
"closed": false,
|
||||
"hasError": false,
|
||||
"isStopped": false,
|
||||
"observers": Array [],
|
||||
"thrownError": null,
|
||||
},
|
||||
}
|
||||
}
|
||||
navigateToUrl={[MockFunction]}
|
||||
>
|
||||
<NoDataCard
|
||||
description="Use Elastic Agent for a simple, unified way to collect data from your machines."
|
||||
image="test-file-stub"
|
||||
recommended={true}
|
||||
title="Add Elastic Agent"
|
||||
/>
|
||||
</RedirectAppLinks>
|
||||
`;
|
||||
|
||||
exports[`ElasticAgentCardComponent renders 1`] = `
|
||||
<RedirectAppLinks
|
||||
currentAppId$={
|
||||
Observable {
|
||||
"_isScalar": false,
|
||||
"source": Subject {
|
||||
"_isScalar": false,
|
||||
"closed": false,
|
||||
"hasError": false,
|
||||
"isStopped": false,
|
||||
"observers": Array [],
|
||||
"thrownError": null,
|
||||
},
|
||||
}
|
||||
}
|
||||
navigateToUrl={[MockFunction]}
|
||||
>
|
||||
<NoDataCard
|
||||
description="Use Elastic Agent for a simple, unified way to collect data from your machines."
|
||||
image="test-file-stub"
|
||||
title="Add Elastic Agent"
|
||||
/>
|
||||
</RedirectAppLinks>
|
||||
`;
|
||||
|
||||
exports[`ElasticAgentCardComponent renders with canAccessFleet false 1`] = `
|
||||
<RedirectAppLinks
|
||||
currentAppId$={
|
||||
Observable {
|
||||
"_isScalar": false,
|
||||
"source": Subject {
|
||||
"_isScalar": false,
|
||||
"closed": false,
|
||||
"hasError": false,
|
||||
"isStopped": false,
|
||||
"observers": Array [],
|
||||
"thrownError": null,
|
||||
},
|
||||
}
|
||||
}
|
||||
navigateToUrl={[MockFunction]}
|
||||
>
|
||||
<NoDataCard
|
||||
description={
|
||||
<EuiTextColor
|
||||
color="default"
|
||||
>
|
||||
This integration is not yet enabled. Your administrator has the required permissions to turn it on.
|
||||
</EuiTextColor>
|
||||
}
|
||||
image="test-file-stub"
|
||||
isDisabled={true}
|
||||
title={
|
||||
<EuiTextColor
|
||||
color="default"
|
||||
>
|
||||
Contact your administrator
|
||||
</EuiTextColor>
|
||||
}
|
||||
/>
|
||||
</RedirectAppLinks>
|
||||
`;
|
|
@ -0,0 +1,320 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ElasticAgentCard renders 1`] = `
|
||||
.emotion-0 {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
<ServicesProvider
|
||||
application={
|
||||
Object {
|
||||
"currentAppId$": Observable {
|
||||
"_isScalar": false,
|
||||
},
|
||||
"navigateToUrl": [Function],
|
||||
}
|
||||
}
|
||||
docLinks={
|
||||
Object {
|
||||
"dataViewsDocsLink": "dummy link",
|
||||
}
|
||||
}
|
||||
editors={
|
||||
Object {
|
||||
"openDataViewEditor": [MockFunction],
|
||||
}
|
||||
}
|
||||
http={
|
||||
Object {
|
||||
"addBasePath": [MockFunction],
|
||||
}
|
||||
}
|
||||
intl={
|
||||
Object {
|
||||
"defaultFormats": Object {},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {
|
||||
"date": Object {
|
||||
"full": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"weekday": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"long": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"medium": Object {
|
||||
"day": "numeric",
|
||||
"month": "short",
|
||||
"year": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"day": "numeric",
|
||||
"month": "numeric",
|
||||
"year": "2-digit",
|
||||
},
|
||||
},
|
||||
"number": Object {
|
||||
"currency": Object {
|
||||
"style": "currency",
|
||||
},
|
||||
"percent": Object {
|
||||
"style": "percent",
|
||||
},
|
||||
},
|
||||
"relative": Object {
|
||||
"days": Object {
|
||||
"units": "day",
|
||||
},
|
||||
"hours": Object {
|
||||
"units": "hour",
|
||||
},
|
||||
"minutes": Object {
|
||||
"units": "minute",
|
||||
},
|
||||
"months": Object {
|
||||
"units": "month",
|
||||
},
|
||||
"seconds": Object {
|
||||
"units": "second",
|
||||
},
|
||||
"years": Object {
|
||||
"units": "year",
|
||||
},
|
||||
},
|
||||
"time": Object {
|
||||
"full": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"long": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"medium": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
},
|
||||
},
|
||||
},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": Symbol(react.fragment),
|
||||
"timeZone": null,
|
||||
}
|
||||
}
|
||||
permissions={
|
||||
Object {
|
||||
"canAccessFleet": true,
|
||||
"canCreateNewDataView": true,
|
||||
}
|
||||
}
|
||||
platform={
|
||||
Object {
|
||||
"setIsFullscreen": [MockFunction],
|
||||
}
|
||||
}
|
||||
>
|
||||
<ElasticAgentCard>
|
||||
<ElasticAgentCardComponent
|
||||
canAccessFleet={true}
|
||||
currentAppId$={
|
||||
Observable {
|
||||
"_isScalar": false,
|
||||
}
|
||||
}
|
||||
href="/app/integrations/browse"
|
||||
navigateToUrl={[Function]}
|
||||
>
|
||||
<RedirectAppLinks
|
||||
currentAppId$={
|
||||
Observable {
|
||||
"_isScalar": false,
|
||||
}
|
||||
}
|
||||
navigateToUrl={[Function]}
|
||||
>
|
||||
<div>
|
||||
<NoDataCard
|
||||
description="Use Elastic Agent for a simple, unified way to collect data from your machines."
|
||||
href="/app/integrations/browse"
|
||||
image="test-file-stub"
|
||||
title="Add Elastic Agent"
|
||||
>
|
||||
<EuiCard
|
||||
betaBadgeProps={
|
||||
Object {
|
||||
"label": undefined,
|
||||
}
|
||||
}
|
||||
css={
|
||||
Object {
|
||||
"maxWidth": 400,
|
||||
}
|
||||
}
|
||||
description="Use Elastic Agent for a simple, unified way to collect data from your machines."
|
||||
footer={
|
||||
<EuiButton
|
||||
fill={true}
|
||||
>
|
||||
Add Elastic Agent
|
||||
</EuiButton>
|
||||
}
|
||||
href="/app/integrations/browse"
|
||||
image="test-file-stub"
|
||||
paddingSize="l"
|
||||
title="Add Elastic Agent"
|
||||
>
|
||||
<EuiPanel
|
||||
css="unknown styles"
|
||||
element="div"
|
||||
hasShadow={true}
|
||||
onClick={[Function]}
|
||||
paddingSize="l"
|
||||
>
|
||||
<EuiPanel
|
||||
className="euiCard euiCard--centerAligned euiCard--isClickable emotion-0"
|
||||
element="div"
|
||||
hasShadow={true}
|
||||
onClick={[Function]}
|
||||
paddingSize="l"
|
||||
>
|
||||
<div
|
||||
className="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiPanel--isClickable euiCard euiCard--centerAligned euiCard--isClickable emotion-0"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<div
|
||||
className="euiCard__top"
|
||||
>
|
||||
<div
|
||||
className="euiCard__image"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="euiCard__content"
|
||||
>
|
||||
<EuiTitle
|
||||
className="euiCard__title"
|
||||
id="generated-idTitle"
|
||||
size="s"
|
||||
>
|
||||
<span
|
||||
className="euiTitle euiTitle--small euiCard__title"
|
||||
id="generated-idTitle"
|
||||
>
|
||||
<a
|
||||
aria-describedby="generated-idDescription"
|
||||
className="euiCard__titleAnchor"
|
||||
href="/app/integrations/browse"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Add Elastic Agent
|
||||
</a>
|
||||
</span>
|
||||
</EuiTitle>
|
||||
<EuiText
|
||||
className="euiCard__description"
|
||||
id="generated-idDescription"
|
||||
size="s"
|
||||
>
|
||||
<div
|
||||
className="euiText euiText--small euiCard__description"
|
||||
id="generated-idDescription"
|
||||
>
|
||||
<p>
|
||||
Use Elastic Agent for a simple, unified way to collect data from your machines.
|
||||
</p>
|
||||
</div>
|
||||
</EuiText>
|
||||
</div>
|
||||
<div
|
||||
className="euiCard__footer"
|
||||
>
|
||||
<EuiButton
|
||||
fill={true}
|
||||
>
|
||||
<EuiButtonDisplay
|
||||
baseClassName="euiButton"
|
||||
disabled={false}
|
||||
element="button"
|
||||
fill={true}
|
||||
isDisabled={false}
|
||||
type="button"
|
||||
>
|
||||
<button
|
||||
className="euiButton euiButton--primary euiButton--fill"
|
||||
disabled={false}
|
||||
style={
|
||||
Object {
|
||||
"minWidth": undefined,
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<EuiButtonContent
|
||||
className="euiButton__content"
|
||||
iconSide="left"
|
||||
textProps={
|
||||
Object {
|
||||
"className": "euiButton__text",
|
||||
}
|
||||
}
|
||||
>
|
||||
<span
|
||||
className="euiButtonContent euiButton__content"
|
||||
>
|
||||
<span
|
||||
className="euiButton__text"
|
||||
>
|
||||
Add Elastic Agent
|
||||
</span>
|
||||
</span>
|
||||
</EuiButtonContent>
|
||||
</button>
|
||||
</EuiButtonDisplay>
|
||||
</EuiButton>
|
||||
</div>
|
||||
</div>
|
||||
</EuiPanel>
|
||||
</EuiPanel>
|
||||
</EuiCard>
|
||||
</NoDataCard>
|
||||
</div>
|
||||
</RedirectAppLinks>
|
||||
</ElasticAgentCardComponent>
|
||||
</ElasticAgentCard>
|
||||
</ServicesProvider>
|
||||
`;
|
|
@ -1,8 +1,59 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`NoDataCard props button 1`] = `
|
||||
.emotion-0 {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
<div
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiCard euiCard--centerAligned"
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiCard euiCard--centerAligned emotion-0"
|
||||
>
|
||||
<div
|
||||
class="euiCard__content"
|
||||
>
|
||||
<span
|
||||
class="euiTitle euiTitle--small euiCard__title"
|
||||
id="generated-idTitle"
|
||||
>
|
||||
Card title
|
||||
</span>
|
||||
<div
|
||||
class="euiText euiText--small euiCard__description"
|
||||
id="generated-idDescription"
|
||||
>
|
||||
<p>
|
||||
Description
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="euiCard__footer"
|
||||
>
|
||||
<button
|
||||
class="euiButton euiButton--primary euiButton--fill"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="euiButtonContent euiButton__content"
|
||||
>
|
||||
<span
|
||||
class="euiButton__text"
|
||||
>
|
||||
Button
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`NoDataCard props extends EuiCardProps 1`] = `
|
||||
.emotion-0 {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
<div
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiCard euiCard--centerAligned custom_class emotion-0"
|
||||
>
|
||||
<div
|
||||
class="euiCard__content"
|
||||
|
@ -44,8 +95,12 @@ exports[`NoDataCard props button 1`] = `
|
|||
`;
|
||||
|
||||
exports[`NoDataCard props href 1`] = `
|
||||
.emotion-0 {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
<div
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiPanel--isClickable euiCard euiCard--centerAligned euiCard--isClickable"
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiPanel--isClickable euiCard euiCard--centerAligned euiCard--isClickable emotion-0"
|
||||
>
|
||||
<div
|
||||
class="euiCard__content"
|
||||
|
@ -93,9 +148,48 @@ exports[`NoDataCard props href 1`] = `
|
|||
</div>
|
||||
`;
|
||||
|
||||
exports[`NoDataCard props recommended 1`] = `
|
||||
exports[`NoDataCard props isDisabled 1`] = `
|
||||
.emotion-0 {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
<div
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiCard euiCard--centerAligned euiCard--hasBetaBadge"
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--subdued euiPanel--noShadow euiPanel--noBorder euiCard euiCard--centerAligned euiCard-isDisabled emotion-0"
|
||||
>
|
||||
<div
|
||||
class="euiCard__content"
|
||||
>
|
||||
<span
|
||||
class="euiTitle euiTitle--small euiCard__title"
|
||||
id="generated-idTitle"
|
||||
>
|
||||
<button
|
||||
aria-describedby=" generated-idDescription"
|
||||
class="euiCard__titleButton"
|
||||
disabled=""
|
||||
>
|
||||
Card title
|
||||
</button>
|
||||
</span>
|
||||
<div
|
||||
class="euiText euiText--small euiCard__description"
|
||||
id="generated-idDescription"
|
||||
>
|
||||
<p>
|
||||
Description
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`NoDataCard props recommended 1`] = `
|
||||
.emotion-0 {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
<div
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiCard euiCard--centerAligned euiCard--hasBetaBadge emotion-0"
|
||||
>
|
||||
<div
|
||||
class="euiCard__content"
|
||||
|
@ -126,12 +220,34 @@ exports[`NoDataCard props recommended 1`] = `
|
|||
Recommended
|
||||
</span>
|
||||
</span>
|
||||
<div
|
||||
class="euiCard__footer"
|
||||
>
|
||||
<button
|
||||
class="euiButton euiButton--primary euiButton--fill"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="euiButtonContent euiButton__content"
|
||||
>
|
||||
<span
|
||||
class="euiButton__text"
|
||||
>
|
||||
Card title
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`NoDataCard renders 1`] = `
|
||||
.emotion-0 {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
<div
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiCard euiCard--centerAligned"
|
||||
class="euiPanel euiPanel--paddingLarge euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow euiCard euiCard--centerAligned emotion-0"
|
||||
>
|
||||
<div
|
||||
class="euiCard__content"
|
||||
|
@ -151,5 +267,23 @@ exports[`NoDataCard renders 1`] = `
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="euiCard__footer"
|
||||
>
|
||||
<button
|
||||
class="euiButton euiButton--primary euiButton--fill"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="euiButtonContent euiButton__content"
|
||||
>
|
||||
<span
|
||||
class="euiButton__text"
|
||||
>
|
||||
Card title
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 93 KiB |
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { ElasticAgentCardComponent } from './elastic_agent_card.component';
|
||||
import { NoDataCard } from './no_data_card';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
describe('ElasticAgentCardComponent', () => {
|
||||
const navigateToUrl = jest.fn();
|
||||
const currentAppId$ = new Subject<string | undefined>().asObservable();
|
||||
|
||||
test('renders', () => {
|
||||
const component = shallow(
|
||||
<ElasticAgentCardComponent
|
||||
canAccessFleet={true}
|
||||
navigateToUrl={navigateToUrl}
|
||||
currentAppId$={currentAppId$}
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('renders with canAccessFleet false', () => {
|
||||
const component = shallow(
|
||||
<ElasticAgentCardComponent
|
||||
canAccessFleet={false}
|
||||
navigateToUrl={navigateToUrl}
|
||||
currentAppId$={currentAppId$}
|
||||
/>
|
||||
);
|
||||
expect(component.find(NoDataCard).props().isDisabled).toBe(true);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('props', () => {
|
||||
test('recommended', () => {
|
||||
const component = shallow(
|
||||
<ElasticAgentCardComponent
|
||||
recommended
|
||||
canAccessFleet={true}
|
||||
navigateToUrl={navigateToUrl}
|
||||
currentAppId$={currentAppId$}
|
||||
/>
|
||||
);
|
||||
expect(component.find(NoDataCard).props().recommended).toBe(true);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('button', () => {
|
||||
const component = shallow(
|
||||
<ElasticAgentCardComponent
|
||||
button="Button"
|
||||
canAccessFleet={true}
|
||||
navigateToUrl={navigateToUrl}
|
||||
currentAppId$={currentAppId$}
|
||||
/>
|
||||
);
|
||||
expect(component.find(NoDataCard).props().button).toBe('Button');
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('href', () => {
|
||||
const component = shallow(
|
||||
<ElasticAgentCardComponent
|
||||
canAccessFleet={true}
|
||||
href={'some path'}
|
||||
navigateToUrl={navigateToUrl}
|
||||
currentAppId$={currentAppId$}
|
||||
/>
|
||||
);
|
||||
expect(component.find(NoDataCard).props().href).toBe('some path');
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiTextColor } from '@elastic/eui';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ElasticAgentCardProps } from './types';
|
||||
import { NoDataCard } from './no_data_card';
|
||||
import ElasticAgentCardIllustration from './assets/elastic_agent_card.svg';
|
||||
import { RedirectAppLinks } from '../../../redirect_app_links';
|
||||
|
||||
export type ElasticAgentCardComponentProps = ElasticAgentCardProps & {
|
||||
canAccessFleet: boolean;
|
||||
navigateToUrl: (url: string) => Promise<void>;
|
||||
currentAppId$: Observable<string | undefined>;
|
||||
};
|
||||
|
||||
const noPermissionTitle = i18n.translate(
|
||||
'sharedUX.noDataPage.elasticAgentCard.noPermission.title',
|
||||
{
|
||||
defaultMessage: `Contact your administrator`,
|
||||
}
|
||||
);
|
||||
|
||||
const noPermissionDescription = i18n.translate(
|
||||
'sharedUX.noDataPage.elasticAgentCard.noPermission.description',
|
||||
{
|
||||
defaultMessage: `This integration is not yet enabled. Your administrator has the required permissions to turn it on.`,
|
||||
}
|
||||
);
|
||||
|
||||
const elasticAgentCardTitle = i18n.translate('sharedUX.noDataPage.elasticAgentCard.title', {
|
||||
defaultMessage: 'Add Elastic Agent',
|
||||
});
|
||||
|
||||
const elasticAgentCardDescription = i18n.translate(
|
||||
'sharedUX.noDataPage.elasticAgentCard.description',
|
||||
{
|
||||
defaultMessage: `Use Elastic Agent for a simple, unified way to collect data from your machines.`,
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a specific NoDataCard pointing users to Integrations when `canAccessFleet`
|
||||
*/
|
||||
export const ElasticAgentCardComponent: FunctionComponent<ElasticAgentCardComponentProps> = ({
|
||||
canAccessFleet,
|
||||
title,
|
||||
navigateToUrl,
|
||||
currentAppId$,
|
||||
...cardRest
|
||||
}) => {
|
||||
const noAccessCard = (
|
||||
<NoDataCard
|
||||
image={ElasticAgentCardIllustration}
|
||||
title={<EuiTextColor color="default">{noPermissionTitle}</EuiTextColor>}
|
||||
description={<EuiTextColor color="default">{noPermissionDescription}</EuiTextColor>}
|
||||
isDisabled
|
||||
{...cardRest}
|
||||
/>
|
||||
);
|
||||
const card = (
|
||||
<NoDataCard
|
||||
image={ElasticAgentCardIllustration}
|
||||
title={title || elasticAgentCardTitle}
|
||||
description={elasticAgentCardDescription}
|
||||
{...cardRest}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<RedirectAppLinks navigateToUrl={navigateToUrl} currentAppId$={currentAppId$}>
|
||||
{canAccessFleet ? card : noAccessCard}
|
||||
</RedirectAppLinks>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
ElasticAgentCardComponent,
|
||||
ElasticAgentCardComponentProps,
|
||||
} from './elastic_agent_card.component';
|
||||
import { applicationServiceFactory } from '../../../../services/storybook/application';
|
||||
|
||||
export default {
|
||||
title: 'Elastic Agent Data Card',
|
||||
description: 'A solution-specific wrapper around NoDataCard, to be used on NoData page',
|
||||
};
|
||||
|
||||
type Params = Pick<ElasticAgentCardComponentProps, 'canAccessFleet'>;
|
||||
|
||||
export const PureComponent = (params: Params) => {
|
||||
const { currentAppId$, navigateToUrl } = applicationServiceFactory();
|
||||
return (
|
||||
<ElasticAgentCardComponent
|
||||
{...params}
|
||||
currentAppId$={currentAppId$}
|
||||
navigateToUrl={navigateToUrl}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
PureComponent.argTypes = {
|
||||
canAccessFleet: {
|
||||
control: 'boolean',
|
||||
defaultValue: true,
|
||||
},
|
||||
};
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { ElasticAgentCard } from './elastic_agent_card';
|
||||
|
||||
import { servicesFactory } from '../../../../services/mocks';
|
||||
import { ServicesProvider, SharedUXServices } from '../../../../services';
|
||||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
import { ElasticAgentCardComponent } from './elastic_agent_card.component';
|
||||
|
||||
describe('ElasticAgentCard', () => {
|
||||
let services: SharedUXServices;
|
||||
let mount: (element: JSX.Element) => ReactWrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
services = servicesFactory();
|
||||
mount = (element: JSX.Element) =>
|
||||
mountWithIntl(<ServicesProvider {...services}>{element}</ServicesProvider>);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
test('renders', () => {
|
||||
const component = mount(<ElasticAgentCard />);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('href', () => {
|
||||
test('returns href if href is given', () => {
|
||||
const component = mount(<ElasticAgentCard href={'/take/me/somewhere'} />);
|
||||
expect(component.find(ElasticAgentCardComponent).props().href).toBe('/take/me/somewhere');
|
||||
});
|
||||
|
||||
test('returns prefix + category if href is not given', () => {
|
||||
const component = mount(<ElasticAgentCard category={'solutions'} />);
|
||||
expect(component.find(ElasticAgentCardComponent).props().href).toBe(
|
||||
'/app/integrations/browse/solutions'
|
||||
);
|
||||
});
|
||||
|
||||
test('returns prefix if nor category nor href are given', () => {
|
||||
const component = mount(<ElasticAgentCard />);
|
||||
expect(component.find(ElasticAgentCardComponent).props().href).toBe(
|
||||
'/app/integrations/browse'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('canAccessFleet', () => {
|
||||
test('passes in the right parameter', () => {
|
||||
const component = mount(<ElasticAgentCard />);
|
||||
expect(component.find(ElasticAgentCardComponent).props().canAccessFleet).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ElasticAgentCardProps } from './types';
|
||||
import { useApplication, useHttp, usePermissions } from '../../../../services';
|
||||
import { ElasticAgentCardComponent } from './elastic_agent_card.component';
|
||||
|
||||
export const ElasticAgentCard = (props: ElasticAgentCardProps) => {
|
||||
const { canAccessFleet } = usePermissions();
|
||||
const { addBasePath } = useHttp();
|
||||
const { navigateToUrl, currentAppId$ } = useApplication();
|
||||
|
||||
const createHref = () => {
|
||||
const { href, category } = props;
|
||||
if (href) {
|
||||
return href;
|
||||
}
|
||||
// TODO: get this URL from a locator
|
||||
const prefix = '/app/integrations/browse';
|
||||
if (category) {
|
||||
return addBasePath(`${prefix}/${category}`);
|
||||
}
|
||||
return prefix;
|
||||
};
|
||||
|
||||
return (
|
||||
<ElasticAgentCardComponent
|
||||
{...props}
|
||||
href={createHref()}
|
||||
canAccessFleet={canAccessFleet}
|
||||
navigateToUrl={navigateToUrl}
|
||||
currentAppId$={currentAppId$}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -6,3 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
export { NoDataCard } from './no_data_card';
|
||||
export { ElasticAgentCard } from './elastic_agent_card';
|
||||
|
|
|
@ -18,11 +18,7 @@ export default {
|
|||
type Params = Pick<NoDataCardProps, 'recommended' | 'button' | 'description'>;
|
||||
|
||||
export const PureComponent = (params: Params) => {
|
||||
return (
|
||||
<div style={{ width: '50%' }}>
|
||||
<NoDataCard title={'Add data'} {...params} />
|
||||
</div>
|
||||
);
|
||||
return <NoDataCard title={'Add data'} {...params} />;
|
||||
};
|
||||
|
||||
PureComponent.argTypes = {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export const NO_DATA_CARD_MAX_WIDTH = 400;
|
||||
|
||||
export const NoDataCardStyles = () => {
|
||||
return {
|
||||
maxWidth: NO_DATA_CARD_MAX_WIDTH,
|
||||
};
|
||||
};
|
|
@ -37,5 +37,29 @@ describe('NoDataCard', () => {
|
|||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('isDisabled', () => {
|
||||
const component = render(
|
||||
<NoDataCard
|
||||
isDisabled={true}
|
||||
button="Button"
|
||||
title="Card title"
|
||||
description="Description"
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('extends EuiCardProps', () => {
|
||||
const component = render(
|
||||
<NoDataCard
|
||||
button="Button"
|
||||
title="Card title"
|
||||
description="Description"
|
||||
className="custom_class"
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,13 +10,14 @@ import { i18n } from '@kbn/i18n';
|
|||
import React, { FunctionComponent } from 'react';
|
||||
import { EuiButton, EuiCard } from '@elastic/eui';
|
||||
import type { NoDataCardProps } from './types';
|
||||
import { NoDataCardStyles } from './no_data_card.styles';
|
||||
|
||||
const recommendedLabel = i18n.translate('sharedUX.pageTemplate.noDataPage.recommendedLabel', {
|
||||
defaultMessage: 'Recommended',
|
||||
});
|
||||
|
||||
const defaultDescription = i18n.translate('sharedUX.pageTemplate.noDataCard.description', {
|
||||
defaultMessage: `Proceed without collecting data`,
|
||||
defaultMessage: 'Proceed without collecting data',
|
||||
});
|
||||
|
||||
export const NoDataCard: FunctionComponent<NoDataCardProps> = ({
|
||||
|
@ -24,12 +25,21 @@ export const NoDataCard: FunctionComponent<NoDataCardProps> = ({
|
|||
title,
|
||||
button,
|
||||
description,
|
||||
isDisabled,
|
||||
...cardRest
|
||||
}) => {
|
||||
const styles = NoDataCardStyles();
|
||||
|
||||
const footer = () => {
|
||||
if (typeof button !== 'string') {
|
||||
// Don't render the footer action if disabled
|
||||
if (isDisabled) {
|
||||
return;
|
||||
}
|
||||
// Render a custom footer action if the button is not a simple string
|
||||
if (button && typeof button !== 'string') {
|
||||
return button;
|
||||
}
|
||||
// Default footer action is a button with the provided or default string
|
||||
return <EuiButton fill>{button || title}</EuiButton>;
|
||||
};
|
||||
const label = recommended ? recommendedLabel : undefined;
|
||||
|
@ -37,11 +47,13 @@ export const NoDataCard: FunctionComponent<NoDataCardProps> = ({
|
|||
|
||||
return (
|
||||
<EuiCard
|
||||
css={styles}
|
||||
paddingSize="l"
|
||||
title={title!}
|
||||
description={cardDescription}
|
||||
betaBadgeProps={{ label }}
|
||||
footer={footer()}
|
||||
isDisabled={isDisabled}
|
||||
{...cardRest}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -15,7 +15,8 @@ export type NoDataCardProps = Partial<Omit<EuiCardProps, 'layout'>> & {
|
|||
*/
|
||||
recommended?: boolean;
|
||||
/**
|
||||
* Provide just a string for the button's label, or a whole component
|
||||
* Provide just a string for the button's label, or a whole component;
|
||||
* The button will be hidden completely if `isDisabled=true`
|
||||
*/
|
||||
button?: string | ReactNode;
|
||||
/**
|
||||
|
@ -23,7 +24,15 @@ export type NoDataCardProps = Partial<Omit<EuiCardProps, 'layout'>> & {
|
|||
*/
|
||||
onClick?: MouseEventHandler<HTMLElement>;
|
||||
/**
|
||||
* Description for the card. If not provided, the default will be used.
|
||||
* Description for the card;
|
||||
* If not provided, the default will be used
|
||||
*/
|
||||
description?: string;
|
||||
description?: string | ReactNode;
|
||||
};
|
||||
|
||||
export type ElasticAgentCardProps = NoDataCardProps & {
|
||||
/**
|
||||
* Category to auto-select within Fleet
|
||||
*/
|
||||
category?: string;
|
||||
};
|
||||
|
|
|
@ -44,7 +44,6 @@ export const RedirectAppLinks: FunctionComponent<RedirectAppLinksProps> = ({
|
|||
}) => {
|
||||
const currentAppId = useObservable(currentAppId$, undefined);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const clickHandler = useMemo(
|
||||
() =>
|
||||
containerRef.current && currentAppId
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
|
||||
exports[`<SolutionToolbarButton /> is rendered 1`] = `
|
||||
<ServicesProvider
|
||||
application={
|
||||
Object {
|
||||
"currentAppId$": Observable {
|
||||
"_isScalar": false,
|
||||
},
|
||||
"navigateToUrl": [Function],
|
||||
}
|
||||
}
|
||||
docLinks={
|
||||
Object {
|
||||
"dataViewsDocsLink": "dummy link",
|
||||
|
@ -12,8 +20,14 @@ exports[`<SolutionToolbarButton /> is rendered 1`] = `
|
|||
"openDataViewEditor": [MockFunction],
|
||||
}
|
||||
}
|
||||
http={
|
||||
Object {
|
||||
"addBasePath": [MockFunction],
|
||||
}
|
||||
}
|
||||
permissions={
|
||||
Object {
|
||||
"canAccessFleet": true,
|
||||
"canCreateNewDataView": true,
|
||||
}
|
||||
}
|
||||
|
|
14
src/plugins/shared_ux/public/services/application.ts
Normal file
14
src/plugins/shared_ux/public/services/application.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface SharedUXApplicationService {
|
||||
navigateToUrl: (url: string) => Promise<void>;
|
||||
currentAppId$: Observable<string | undefined>;
|
||||
}
|
11
src/plugins/shared_ux/public/services/http.ts
Normal file
11
src/plugins/shared_ux/public/services/http.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export interface SharedUXHttpService {
|
||||
addBasePath: (url: string) => string;
|
||||
}
|
|
@ -12,6 +12,8 @@ import { servicesFactory } from './stub';
|
|||
import { SharedUXUserPermissionsService } from './permissions';
|
||||
import { SharedUXEditorsService } from './editors';
|
||||
import { SharedUXDocLinksService } from './doc_links';
|
||||
import { SharedUXHttpService } from './http';
|
||||
import { SharedUXApplicationService } from './application';
|
||||
|
||||
/**
|
||||
* A collection of services utilized by SharedUX. This serves as a thin
|
||||
|
@ -26,6 +28,8 @@ export interface SharedUXServices {
|
|||
permissions: SharedUXUserPermissionsService;
|
||||
editors: SharedUXEditorsService;
|
||||
docLinks: SharedUXDocLinksService;
|
||||
http: SharedUXHttpService;
|
||||
application: SharedUXApplicationService;
|
||||
}
|
||||
|
||||
// The React Context used to provide the services to the SharedUX components.
|
||||
|
@ -60,3 +64,7 @@ export const usePermissions = () => useServices().permissions;
|
|||
export const useEditors = () => useServices().editors;
|
||||
|
||||
export const useDocLinks = () => useServices().docLinks;
|
||||
|
||||
export const useHttp = () => useServices().http;
|
||||
|
||||
export const useApplication = () => useServices().application;
|
||||
|
|
24
src/plugins/shared_ux/public/services/kibana/application.ts
Normal file
24
src/plugins/shared_ux/public/services/kibana/application.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { KibanaPluginServiceFactory } from '../types';
|
||||
import { SharedUXPluginStartDeps } from '../../types';
|
||||
import { SharedUXApplicationService } from '../application';
|
||||
|
||||
export type ApplicationServiceFactory = KibanaPluginServiceFactory<
|
||||
SharedUXApplicationService,
|
||||
SharedUXPluginStartDeps
|
||||
>;
|
||||
|
||||
/**
|
||||
* A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`.
|
||||
*/
|
||||
export const applicationServiceFactory: ApplicationServiceFactory = ({ coreStart }) => ({
|
||||
navigateToUrl: coreStart.application.navigateToUrl,
|
||||
currentAppId$: coreStart.application.currentAppId$,
|
||||
});
|
23
src/plugins/shared_ux/public/services/kibana/http.ts
Normal file
23
src/plugins/shared_ux/public/services/kibana/http.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { KibanaPluginServiceFactory } from '../types';
|
||||
import { SharedUXHttpService } from '../http';
|
||||
import { SharedUXPluginStartDeps } from '../../types';
|
||||
|
||||
export type HttpServiceFactory = KibanaPluginServiceFactory<
|
||||
SharedUXHttpService,
|
||||
SharedUXPluginStartDeps
|
||||
>;
|
||||
|
||||
/**
|
||||
* A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`.
|
||||
*/
|
||||
export const httpServiceFactory: HttpServiceFactory = ({ coreStart, startPlugins }) => ({
|
||||
addBasePath: coreStart.http.basePath.prepend,
|
||||
});
|
|
@ -13,6 +13,8 @@ import { platformServiceFactory } from './platform';
|
|||
import { userPermissionsServiceFactory } from './permissions';
|
||||
import { editorsServiceFactory } from './editors';
|
||||
import { docLinksServiceFactory } from './doc_links';
|
||||
import { httpServiceFactory } from './http';
|
||||
import { applicationServiceFactory } from './application';
|
||||
|
||||
/**
|
||||
* A factory function for creating a Kibana-based implementation of `SharedUXServices`.
|
||||
|
@ -25,4 +27,6 @@ export const servicesFactory: KibanaPluginServiceFactory<
|
|||
permissions: userPermissionsServiceFactory(params),
|
||||
editors: editorsServiceFactory(params),
|
||||
docLinks: docLinksServiceFactory(params),
|
||||
http: httpServiceFactory(params),
|
||||
application: applicationServiceFactory(params),
|
||||
});
|
||||
|
|
|
@ -18,6 +18,10 @@ export type UserPermissionsServiceFactory = KibanaPluginServiceFactory<
|
|||
/**
|
||||
* A factory function for creating a Kibana-based implementation of `SharedUXPermissionsService`.
|
||||
*/
|
||||
export const userPermissionsServiceFactory: UserPermissionsServiceFactory = ({ startPlugins }) => ({
|
||||
export const userPermissionsServiceFactory: UserPermissionsServiceFactory = ({
|
||||
coreStart,
|
||||
startPlugins,
|
||||
}) => ({
|
||||
canCreateNewDataView: startPlugins.dataViewEditor.userPermissions.editDataView(),
|
||||
canAccessFleet: coreStart.application.capabilities.navLinks.integrations,
|
||||
});
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { PluginServiceFactory } from '../types';
|
||||
import { SharedUXApplicationService } from '../application';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export type MockApplicationServiceFactory = PluginServiceFactory<SharedUXApplicationService>;
|
||||
|
||||
/**
|
||||
* A factory function for creating a Jest-based implementation of `SharedUXApplicationService`.
|
||||
*/
|
||||
export const applicationServiceFactory: MockApplicationServiceFactory = () => ({
|
||||
navigateToUrl: () => Promise.resolve(),
|
||||
currentAppId$: new Observable(),
|
||||
});
|
19
src/plugins/shared_ux/public/services/mocks/http.mock.ts
Normal file
19
src/plugins/shared_ux/public/services/mocks/http.mock.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { PluginServiceFactory } from '../types';
|
||||
import { SharedUXHttpService } from '../http';
|
||||
|
||||
export type MockHttpServiceFactory = PluginServiceFactory<SharedUXHttpService>;
|
||||
|
||||
/**
|
||||
* A factory function for creating a Jest-based implementation of `SharedUXHttpService`.
|
||||
*/
|
||||
export const httpServiceFactory: MockHttpServiceFactory = () => ({
|
||||
addBasePath: jest.fn((path: string) => (path ? path : 'path')),
|
||||
});
|
|
@ -15,6 +15,8 @@ import { PluginServiceFactory } from '../types';
|
|||
import { platformServiceFactory } from './platform.mock';
|
||||
import { userPermissionsServiceFactory } from './permissions.mock';
|
||||
import { editorsServiceFactory } from './editors.mock';
|
||||
import { httpServiceFactory } from './http.mock';
|
||||
import { applicationServiceFactory } from './application.mock';
|
||||
|
||||
/**
|
||||
* A factory function for creating a Jest-based implementation of `SharedUXServices`.
|
||||
|
@ -24,4 +26,6 @@ export const servicesFactory: PluginServiceFactory<SharedUXServices> = () => ({
|
|||
permissions: userPermissionsServiceFactory(),
|
||||
editors: editorsServiceFactory(),
|
||||
docLinks: docLinksServiceFactory(),
|
||||
http: httpServiceFactory(),
|
||||
application: applicationServiceFactory(),
|
||||
});
|
||||
|
|
|
@ -17,4 +17,5 @@ export type MockUserPermissionsServiceFactory =
|
|||
*/
|
||||
export const userPermissionsServiceFactory: MockUserPermissionsServiceFactory = () => ({
|
||||
canCreateNewDataView: true,
|
||||
canAccessFleet: true,
|
||||
});
|
||||
|
|
|
@ -8,4 +8,5 @@
|
|||
|
||||
export interface SharedUXUserPermissionsService {
|
||||
canCreateNewDataView: boolean;
|
||||
canAccessFleet: boolean;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { PluginServiceFactory } from '../types';
|
||||
import { SharedUXApplicationService } from '../application';
|
||||
|
||||
export type ApplicationServiceFactory = PluginServiceFactory<SharedUXApplicationService>;
|
||||
|
||||
/**
|
||||
* A factory function for creating for creating a storybook implementation of `SharedUXApplicationService`.
|
||||
*/
|
||||
export const applicationServiceFactory: ApplicationServiceFactory = () => ({
|
||||
navigateToUrl: () => {
|
||||
action('NavigateToUrl');
|
||||
return Promise.resolve();
|
||||
},
|
||||
currentAppId$: new BehaviorSubject('123'),
|
||||
});
|
24
src/plugins/shared_ux/public/services/storybook/http.ts
Normal file
24
src/plugins/shared_ux/public/services/storybook/http.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import { PluginServiceFactory } from '../types';
|
||||
import { SharedUXHttpService } from '../http';
|
||||
|
||||
/**
|
||||
* A factory function for creating a Storybook-based implementation of `SharedUXHttpService`.
|
||||
*/
|
||||
export type HttpServiceFactory = PluginServiceFactory<SharedUXHttpService, {}>;
|
||||
|
||||
/**
|
||||
* A factory function for creating a Storybook-based implementation of `SharedUXHttpService`.
|
||||
*/
|
||||
export const httpServiceFactory: HttpServiceFactory = () => ({
|
||||
addBasePath: action('addBasePath') as SharedUXHttpService['addBasePath'],
|
||||
});
|
|
@ -12,6 +12,8 @@ import { platformServiceFactory } from './platform';
|
|||
import { editorsServiceFactory } from './editors';
|
||||
import { userPermissionsServiceFactory } from './permissions';
|
||||
import { docLinksServiceFactory } from './doc_links';
|
||||
import { httpServiceFactory } from './http';
|
||||
import { applicationServiceFactory } from './application';
|
||||
|
||||
/**
|
||||
* A factory function for creating a Storybook-based implementation of `SharedUXServices`.
|
||||
|
@ -21,4 +23,6 @@ export const servicesFactory: PluginServiceFactory<SharedUXServices, {}> = (para
|
|||
permissions: userPermissionsServiceFactory(),
|
||||
editors: editorsServiceFactory(),
|
||||
docLinks: docLinksServiceFactory(),
|
||||
http: httpServiceFactory(params),
|
||||
application: applicationServiceFactory(),
|
||||
});
|
||||
|
|
|
@ -17,4 +17,5 @@ export type SharedUXUserPermissionsServiceFactory =
|
|||
*/
|
||||
export const userPermissionsServiceFactory: SharedUXUserPermissionsServiceFactory = () => ({
|
||||
canCreateNewDataView: true,
|
||||
canAccessFleet: true,
|
||||
});
|
||||
|
|
27
src/plugins/shared_ux/public/services/stub/application.ts
Normal file
27
src/plugins/shared_ux/public/services/stub/application.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { PluginServiceFactory } from '../types';
|
||||
import { SharedUXApplicationService } from '../application';
|
||||
|
||||
export type ApplicationServiceFactory = PluginServiceFactory<SharedUXApplicationService>;
|
||||
|
||||
/**
|
||||
* A factory function for creating for creating a simple stubbed implementation of `SharedUXApplicationService`.
|
||||
*/
|
||||
export const applicationServiceFactory: ApplicationServiceFactory = () => ({
|
||||
navigateToUrl: (url) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(url);
|
||||
return Promise.resolve();
|
||||
},
|
||||
currentAppId$: new Observable((subscriber) => {
|
||||
subscriber.next('123');
|
||||
}),
|
||||
});
|
24
src/plugins/shared_ux/public/services/stub/http.ts
Normal file
24
src/plugins/shared_ux/public/services/stub/http.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { PluginServiceFactory } from '../types';
|
||||
import { SharedUXHttpService } from '../http';
|
||||
|
||||
/**
|
||||
* A factory function for creating a simple stubbed implementation of `SharedUXHttpService`.
|
||||
*/
|
||||
export type HttpServiceFactory = PluginServiceFactory<SharedUXHttpService>;
|
||||
|
||||
/**
|
||||
* A factory function for creating a simple stubbed implementation of `SharedUXHttpService`.
|
||||
*/
|
||||
export const httpServiceFactory: HttpServiceFactory = () => ({
|
||||
addBasePath: (url: string) => {
|
||||
return url;
|
||||
},
|
||||
});
|
|
@ -12,6 +12,8 @@ import { platformServiceFactory } from './platform';
|
|||
import { userPermissionsServiceFactory } from './permissions';
|
||||
import { editorsServiceFactory } from './editors';
|
||||
import { docLinksServiceFactory } from './doc_links';
|
||||
import { httpServiceFactory } from './http';
|
||||
import { applicationServiceFactory } from './application';
|
||||
|
||||
/**
|
||||
* A factory function for creating a simple stubbed implemetation of `SharedUXServices`.
|
||||
|
@ -21,4 +23,6 @@ export const servicesFactory: PluginServiceFactory<SharedUXServices> = () => ({
|
|||
permissions: userPermissionsServiceFactory(),
|
||||
editors: editorsServiceFactory(),
|
||||
docLinks: docLinksServiceFactory(),
|
||||
http: httpServiceFactory(),
|
||||
application: applicationServiceFactory(),
|
||||
});
|
||||
|
|
|
@ -19,4 +19,5 @@ export type UserPermissionsServiceFactory = PluginServiceFactory<SharedUXUserPer
|
|||
*/
|
||||
export const userPermissionsServiceFactory: UserPermissionsServiceFactory = () => ({
|
||||
canCreateNewDataView: true,
|
||||
canAccessFleet: true,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue