[SharedUX] SCSS migration kibana_overview plugin (#215942)

## Summary

This PR is a part of SCSS migration of SharedUX team code.
Here is a [meta](https://github.com/elastic/kibana-team/issues/1417)
issue for it.

---------

Co-authored-by: Eyo O. Eyo <7893459+eokoneyo@users.noreply.github.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Alexey Antonov <alexwizp@gmail.com>
Co-authored-by: Sergi Massaneda <sergi.massaneda@elastic.co>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Paulina Shakirova 2025-04-23 08:06:28 +02:00 committed by GitHub
parent ac973560a3
commit cd8254bd26
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 129 additions and 133 deletions

View file

@ -27,11 +27,10 @@ exports[`ManageData render 1`] = `
size="m"
/>
<EuiFlexGroup
className="kbnOverviewDataManage__content"
wrap={true}
>
<EuiFlexItem
className="kbnOverviewDataManage__item"
css="unknown styles"
key="security"
>
<RedirectAppLinks
@ -53,7 +52,7 @@ exports[`ManageData render 1`] = `
</RedirectAppLinks>
</EuiFlexItem>
<EuiFlexItem
className="kbnOverviewDataManage__item"
css="unknown styles"
key="monitoring"
>
<RedirectAppLinks
@ -75,7 +74,7 @@ exports[`ManageData render 1`] = `
</RedirectAppLinks>
</EuiFlexItem>
<EuiFlexItem
className="kbnOverviewDataManage__item"
css="unknown styles"
key="snapshot_restore"
>
<RedirectAppLinks
@ -97,7 +96,7 @@ exports[`ManageData render 1`] = `
</RedirectAppLinks>
</EuiFlexItem>
<EuiFlexItem
className="kbnOverviewDataManage__item"
css="unknown styles"
key="index_lifecycle_management"
>
<RedirectAppLinks

View file

@ -9,7 +9,16 @@
import React, { FC } from 'react';
import PropTypes from 'prop-types';
import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiSpacer, EuiTitle } from '@elastic/eui';
import { css } from '@emotion/react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiHorizontalRule,
EuiSpacer,
EuiTitle,
UseEuiTheme,
useEuiMinBreakpoint,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { CoreStart } from '@kbn/core/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
@ -27,6 +36,7 @@ export const ManageData: FC<Props> = ({ addBasePath, features }) => {
const {
services: { application },
} = useKibana<CoreStart>();
const minBreakpointM = useEuiMinBreakpoint('m');
return (
<>
{features.length > 1 ? <EuiHorizontalRule margin="xl" aria-hidden="true" /> : null}
@ -47,9 +57,20 @@ export const ManageData: FC<Props> = ({ addBasePath, features }) => {
<EuiSpacer size="m" />
<EuiFlexGroup className="kbnOverviewDataManage__content" wrap>
<EuiFlexGroup wrap>
{features.map((feature) => (
<EuiFlexItem className="kbnOverviewDataManage__item" key={feature.id}>
<EuiFlexItem
key={feature.id}
css={({ euiTheme }: UseEuiTheme) =>
css({
':not(:only-child)': {
[minBreakpointM]: {
flex: `0 0 calc(50% - ${euiTheme.size.l})`,
},
},
})
}
>
<RedirectAppLinks
coreStart={{
application,

View file

@ -3,7 +3,6 @@
exports[`FeedItem render 1`] = `
<section
aria-labelledby="kbnOverviewNews__title"
className="kbnOverviewNews"
>
<EuiTitle
size="s"
@ -21,7 +20,7 @@ exports[`FeedItem render 1`] = `
size="m"
/>
<div
className="kbnOverviewNews__content"
css="unknown styles"
>
<article
aria-labelledby="kbnOverviewNews__title0"

View file

@ -8,16 +8,33 @@
*/
import React, { FC } from 'react';
import { EuiLink, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { EuiLink, EuiSpacer, EuiText, EuiTitle, UseEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
import { FormattedMessage } from '@kbn/i18n-react';
import { FetchResult } from '@kbn/newsfeed-plugin/public';
interface Props {
newsFetchResult: FetchResult;
newsFetchResult: FetchResult | null | void;
}
const styles = ({ euiTheme }: UseEuiTheme) =>
css({
article: {
'& + article': {
marginTop: euiTheme.size.l,
},
'&, header': {
'& > * + *': {
marginTop: euiTheme.size.xs,
},
},
h3: {
fontWeight: 'inherit',
},
},
});
export const NewsFeed: FC<Props> = ({ newsFetchResult }) => (
<section aria-labelledby="kbnOverviewNews__title" className="kbnOverviewNews">
<section aria-labelledby="kbnOverviewNews__title">
<EuiTitle size="s">
<h2 id="kbnOverviewNews__title">
<FormattedMessage id="kibanaOverview.news.title" defaultMessage="What's new" />
@ -25,9 +42,8 @@ export const NewsFeed: FC<Props> = ({ newsFetchResult }) => (
</EuiTitle>
<EuiSpacer size="m" />
<div className="kbnOverviewNews__content">
{newsFetchResult.feedItems
<div css={styles}>
{newsFetchResult?.feedItems
.slice(0, 3)
.map(({ title, description, linkUrl, publishOn }, index) => (
<article key={title} aria-labelledby={`kbnOverviewNews__title${index}`}>

View file

@ -1,84 +0,0 @@
.kbnOverviewApps__item {
.kbnOverviewApps__group--primary & {
@include euiBreakpoint('m', 'l', 'xl') {
max-width: calc(50% - #{$euiSizeM * 2});
}
}
.kbnOverviewApps__group--secondary & {
@include euiBreakpoint('m', 'l', 'xl') {
max-width: calc(25% - #{$euiSizeM * 2});
}
}
}
.kbnOverviewNews__content article {
& + article {
margin-top: $euiSizeL;
}
&,
header {
& > * + * {
margin-top: $euiSizeXS;
}
}
h3 {
font-weight: inherit;
}
}
.kbnOverviewMore__item {
@include euiBreakpoint('m', 'l', 'xl') {
max-width: calc(33.333333333333333% - #{$euiSizeM * 2});
}
}
.kbnOverviewSolution {
&.enterpriseSearch {
.euiCard__image {
background-color: $euiColorWarning;
}
}
&.observability {
.euiCard__image {
background-color: $euiColorAccent;
}
}
&.securitySolution {
.euiCard__image {
background-color: $euiColorAccentSecondary;
}
}
}
.kbnOverviewSupplements--noNews .kbnOverviewMore {
h2 {
@include euiBreakpoint('m', 'l', 'xl') {
text-align: center;
}
}
.kbnOverviewMore__content {
@include euiBreakpoint('m', 'l', 'xl') {
justify-content: center;
}
}
}
.kbnOverviewData--expanded {
flex-direction: column;
&,
& > * {
margin-bottom: 0 !important;
margin-top: 0 !important;
}
}
.kbnOverviewDataManage__item:not(:only-child) {
@include euiBreakpoint('m', 'l', 'xl') {
flex: 0 0 calc(50% - #{$euiSizeM * 2});
}
}

View file

@ -7,10 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import './overview.scss';
import { snakeCase } from 'lodash';
import React, { FC, useState, useEffect, useMemo } from 'react';
import { css } from '@emotion/react';
import useObservable from 'react-use/lib/useObservable';
import {
EuiCard,
@ -20,6 +19,9 @@ import {
EuiSpacer,
EuiTitle,
EuiLoadingSpinner,
useEuiMinBreakpoint,
UseEuiTheme,
useEuiTheme,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { CoreStart } from '@kbn/core/public';
@ -41,6 +43,7 @@ import {
FeatureCatalogueCategory,
} from '@kbn/home-plugin/public';
import { withSuspense } from '@kbn/shared-ux-utility';
import classNames from 'classnames';
import { PLUGIN_ID, PLUGIN_PATH } from '../../../common';
import { AppPluginStartDependencies } from '../../types';
import { AddData } from '../add_data';
@ -76,6 +79,8 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
} = services;
const addBasePath = http.basePath.prepend;
const currentTheme = useObservable(theme.theme$, { darkMode: false, name: 'amsterdam' });
const { euiTheme } = useEuiTheme();
const minBreakpointM = useEuiMinBreakpoint('m');
// Home does not have a locator implemented, so hard-code it here.
const addDataHref = addBasePath('/app/integrations/browse');
@ -97,7 +102,6 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
const addDataFeatures = getFeaturesByCategory('data');
const manageDataFeatures = getFeaturesByCategory('admin');
const devTools = findFeatureById('console');
// Show card for console if none of the manage data plugins are available, most likely in OSS
if (manageDataFeatures.length < 1 && devTools) {
manageDataFeatures.push(devTools);
@ -241,6 +245,7 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
return (
<KibanaPageTemplate
css={styles(euiTheme, minBreakpointM)}
pageHeader={{
iconType: 'logoKibana',
pageTitle: <FormattedMessage defaultMessage="Analytics" id="kibanaOverview.header.title" />,
@ -257,11 +262,7 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
}}
panelled={false}
>
<KibanaPageTemplate.Section
bottomBorder
aria-labelledby="kbnOverviewApps__title"
className="kbnOverviewApps"
>
<KibanaPageTemplate.Section bottomBorder aria-labelledby="kbnOverviewApps__title">
<EuiScreenReaderOnly>
<h2 id="kbnOverviewApps__title">
<FormattedMessage id="kibanaOverview.apps.title" defaultMessage="Explore these apps" />
@ -270,10 +271,7 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
{mainAppsUserHasAccessTo.length ? (
<>
<EuiFlexGroup
className="kbnOverviewApps__group kbnOverviewApps__group--primary"
justifyContent="center"
>
<EuiFlexGroup className="kbnOverviewMainApps" justifyContent="center">
{mainAppsUserHasAccessTo.map(renderAppCard)}
</EuiFlexGroup>
@ -282,10 +280,7 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
) : null}
{remainingApps.length ? (
<EuiFlexGroup
className="kbnOverviewApps__group kbnOverviewApps__group--secondary"
justifyContent="center"
>
<EuiFlexGroup className="kbnOverviewRemainingApps" justifyContent="center">
{remainingApps.map(renderAppCard)}
</EuiFlexGroup>
) : null}
@ -294,11 +289,9 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
<KibanaPageTemplate.Section bottomBorder paddingSize="xl">
<EuiFlexGroup
alignItems="flexStart"
className={`kbnOverviewSupplements ${
newsFetchResult && newsFetchResult.feedItems.length
? 'kbnOverviewSupplements--hasNews'
: 'kbnOverviewSupplements--noNews'
}`}
className={classNames({
'kbnOverviewSupplements--noNews': !newsFetchResult?.feedItems?.length,
})}
>
{newsFetchResult && newsFetchResult.feedItems.length ? (
<EuiFlexItem grow={1}>
@ -308,7 +301,7 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
<EuiFlexItem grow={3}>
{solutions.length ? (
<section aria-labelledby="kbnOverviewMore__title" className="kbnOverviewMore">
<section aria-labelledby="kbnOverviewMore__title">
<EuiTitle size="s">
<h2 id="kbnOverviewMore__title">
<FormattedMessage
@ -320,9 +313,13 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
<EuiSpacer size="m" />
<EuiFlexGroup className="kbnOverviewMore__content">
<EuiFlexGroup>
{solutions.map(({ id, title, description, icon, path }) => (
<EuiFlexItem className="kbnOverviewMore__item" key={id}>
<EuiFlexItem
data-test-subj="kbnOverviewItem"
key={id}
className="kbnOverviewItemSolution"
>
<RedirectAppLinksKibanaProvider
coreStart={{
application: {
@ -332,9 +329,9 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
}}
{...application}
>
<RedirectAppLinks>
<RedirectAppLinks className="kbnRedirectAppLinkImage">
<EuiCard
className={`kbnOverviewSolution ${id}`}
className={`kbnOverviewSolution--${id}`}
description={description ? description : ''}
href={addBasePath(path)}
icon={<KibanaSolutionAvatar name={title} iconType={icon} size="xl" />}
@ -354,11 +351,11 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
</section>
) : (
<EuiFlexGroup
className={`kbnOverviewData ${
addDataFeatures.length === 1 && manageDataFeatures.length === 1
? 'kbnOverviewData--compressed'
: 'kbnOverviewData--expanded'
}`}
css={css({
...(addDataFeatures.length > 1 && manageDataFeatures.length > 1
? { flexDirection: 'column' }
: {}),
})}
>
<EuiFlexItem>
<AddData addBasePath={addBasePath} features={addDataFeatures} />
@ -386,3 +383,48 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
</KibanaPageTemplate>
);
};
const styles = (euiTheme: UseEuiTheme['euiTheme'], minBreakpointM: string) =>
css({
'.kbnRedirectAppLinkImage': {
'.enterpriseSearch': {
'.euiCard__image': {
backgroundColor: euiTheme.colors.warning,
},
},
'.observability': {
'.euiCard__image': {
backgroundColor: euiTheme.colors.accent,
},
},
'.securitySolution': {
'.euiCard__image': {
backgroundColor: euiTheme.colors.accentSecondary,
},
},
},
'.kbnOverviewItemSolution': {
[minBreakpointM]: {
maxWidth: `calc(33.333% - ${euiTheme.size.l})`,
},
},
'.kbnOverviewRemainingApps': {
'.kbnOverviewApps__item': {
[minBreakpointM]: {
maxWidth: `calc(25% - ${euiTheme.size.l})`,
},
},
},
'.kbnOverviewMainApps': {
'.kbnOverviewApps__item': {
[minBreakpointM]: {
maxWidth: `calc(50% - ${euiTheme.size.l})`,
},
},
},
'.kbnOverviewSupplements--noNews h2': {
[minBreakpointM]: {
textAlign: 'center',
},
},
});

View file

@ -6,6 +6,7 @@
"include": [
"public/**/*",
"common/**/*",
"../../../../../typings/emotion.d.ts"
],
"kbn_references": [
"@kbn/core",
@ -32,6 +33,6 @@
"@kbn/core-http-browser-mocks",
],
"exclude": [
"target/**/*",
"target/**/*"
]
}

View file

@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const kibanaServer = getService('kibanaServer');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'header']);
const testSubjects = getService('testSubjects');
describe('overview page - solutions', function describeIndexTests() {
before(async () => {
@ -39,7 +40,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('contains Security and Observability solutions', async () => {
const solutionCards = await find.allByCssSelector('.kbnOverviewMore__item');
const solutionCards = await testSubjects.findAll('kbnOverviewItem');
expect(solutionCards.length >= 2).to.be(true);
const imageSrcs = [];