Skip to content

Commit 3546f35

Browse files
Merge pull request #13466 from lokanandaprabhu/feature/ODC-7465
ODC-7465: Update Getting started section in Openshift UI to use expandable section
2 parents 4f44914 + 8178523 commit 3546f35

13 files changed

Lines changed: 197 additions & 68 deletions

File tree

frontend/packages/console-shared/locales/en/console-shared.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,12 @@
152152
"Switching to form view will delete any invalid YAML.": "Switching to form view will delete any invalid YAML.",
153153
"Switch and delete": "Switch and delete",
154154
"Form view is disabled for this chart because the schema is not available": "Form view is disabled for this chart because the schema is not available",
155+
"Getting started resources": "Getting started resources",
156+
"Use our collection of resources to help you get started with the Console.": "Use our collection of resources to help you get started with the Console.",
157+
"More info": "More info",
155158
"You can always bring these getting started resources back into view by clicking Show getting started resources in the page heading.": "You can always bring these getting started resources back into view by clicking Show getting started resources in the page heading.",
156159
"Hide from view": "Hide from view",
157-
"Getting started resources": "Getting started resources",
158160
"Use our collection of resources to help you get started with the Console.\n\nNote: This card can be hidden at any time.": "Use our collection of resources to help you get started with the Console.\n\nNote: This card can be hidden at any time.",
159-
"More info": "More info",
160161
"View all quick starts": "View all quick starts",
161162
"Build with guided documentation": "Build with guided documentation",
162163
"Follow guided documentation to build applications and familiarize yourself with key features.": "Follow guided documentation to build applications and familiarize yourself with key features.",
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
.ocs-getting-started-expandable-grid {
2+
--min-column-width: 220px;
3+
4+
// Increase css specificity to override a generic [class*="pf-v5-c-"] rule.
5+
&__header.pf-v5-c-card__header {
6+
// Use padding sm instead of lg to fix alignment of the KebabToggle action button.
7+
padding-right: var(--pf-v5-global--spacer--sm);
8+
}
9+
&__tooltip {
10+
white-space: pre-line;
11+
}
12+
&__tooltip-icon {
13+
margin-left: var(--pf-v5-global--spacer--sm);
14+
}
15+
16+
// Increase css specificity to override a generic [class*="pf-v5-c-"] rule.
17+
&__content.pf-v5-c-card__body {
18+
display: grid;
19+
grid-template-columns: repeat(auto-fit, minmax(var(--min-column-width), 1fr));
20+
21+
// Keep only additional spacing at the bottom. Horizontal spacing is added to the child elements.
22+
padding: 0 0 calc(var(--pf-v5-c-card--child--PaddingBottom) / 2) 0;
23+
// Hide the border on the right side of the content. Works together wie negative margin below.
24+
overflow: hidden;
25+
padding-top: 0 !important;
26+
27+
// Increase css specificity to override a generic [class*="pf-v5-c-"] rule.
28+
> .pf-v5-l-flex.pf-m-grow.pf-m-column {
29+
// Show a divider on the right side and hide them in the latest column.
30+
border-right: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--100);
31+
margin-right: calc(-1 * var(--pf-v5-global--BorderWidth--sm));
32+
// Padding around the card. Vertical spacing is splitted on the card and the grid.
33+
padding-top: calc(var(--pf-v5-c-card--first-child--PaddingTop) / 2);
34+
padding-bottom: calc(var(--pf-v5-c-card--child--PaddingBottom) / 2);
35+
padding-left: var(--pf-v5-c-card--child--PaddingLeft);
36+
padding-right: var(--pf-v5-c-card--child--PaddingRight);
37+
}
38+
}
39+
}
40+
41+
.ocs-getting-started-expandable-section {
42+
background-color: var(--pf-v5-global--BackgroundColor--100);
43+
&__toggle-text {
44+
color: var(--pf-v5-global--Color--dark-100);
45+
&.is-dark {
46+
color: var(--pf-v5-global--Color--light-100);
47+
}
48+
font-size: var(--pf-v5-global--icon--FontSize--md);
49+
font-weight: var(--pf-v5-global--FontWeight--bold);
50+
}
51+
}
52+
53+
.pf-v5-c-expandable-section__toggle {
54+
align-items: center;
55+
}
56+
57+
.pf-v5-c-expandable-section__content {
58+
padding: 0 !important;
59+
}
60+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import * as React from 'react';
2+
import {
3+
Card,
4+
CardBody,
5+
Title,
6+
TitleSizes,
7+
Popover,
8+
ExpandableSection,
9+
} from '@patternfly/react-core';
10+
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons/dist/esm/icons/outlined-question-circle-icon';
11+
import { useTranslation } from 'react-i18next';
12+
13+
import './GettingStartedExpandableGrid.scss';
14+
15+
interface GettingStartedExpandableGridProps {
16+
children?: React.ReactNodeArray;
17+
isOpen?: boolean;
18+
setIsOpen?: (isOpen: boolean) => void;
19+
}
20+
21+
export const GettingStartedExpandableGrid: React.FC<GettingStartedExpandableGridProps> = ({
22+
children,
23+
isOpen,
24+
setIsOpen,
25+
}) => {
26+
const { t } = useTranslation();
27+
28+
const title = t('console-shared~Getting started resources');
29+
const titleTooltip = (
30+
<span className="ocs-getting-started-expandable-grid__tooltip">
31+
{t(
32+
'console-shared~Use our collection of resources to help you get started with the Console.',
33+
)}
34+
</span>
35+
);
36+
37+
return (
38+
<ExpandableSection
39+
onToggle={() => setIsOpen(!isOpen)}
40+
isExpanded={isOpen}
41+
displaySize="lg"
42+
className="ocs-getting-started-expandable-section"
43+
toggleContent={
44+
<div className="ocs-getting-started-expandable-section__toggle-text">
45+
<Title headingLevel="h2" size={TitleSizes.lg} data-test="title">
46+
{title}{' '}
47+
<Popover bodyContent={titleTooltip} triggerAction="hover">
48+
<span
49+
role="button"
50+
aria-label={t('console-shared~More info')}
51+
className="ocs-getting-started-expandable-grid__tooltip-icon"
52+
>
53+
<OutlinedQuestionCircleIcon />
54+
</span>
55+
</Popover>
56+
</Title>
57+
</div>
58+
}
59+
>
60+
<Card
61+
className="ocs-getting-started-expandable-grid"
62+
data-test="getting-started"
63+
isClickable
64+
isSelectable
65+
>
66+
<CardBody className="ocs-getting-started-expandable-grid__content">{children}</CardBody>
67+
</Card>
68+
</ExpandableSection>
69+
);
70+
};

frontend/packages/console-shared/src/components/getting-started/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from './GettingStartedCard';
33
export * from './RestoreGettingStartedButton';
44
export * from './QuickStartGettingStartedCard';
55
export * from './useGettingStartedShowState';
6+
export * from './GettingStartedExpandableGrid';

frontend/packages/console-shared/src/constants/common.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,8 @@ export enum REQUESTER_FILTER {
102102

103103
export const CLUSTER_VERSION_DEFAULT_UPSTREAM_SERVER_URL_PLACEHOLDER =
104104
'https://api.openshift.com/api/upgrades_info/v1/graph';
105+
106+
export const GETTING_STARTED_USER_SETTINGS_KEY_ADD_PAGE =
107+
'devconsole.addPage.gettingStarted.expanded';
108+
export const GETTING_STARTED_USER_SETTINGS_KEY_CLUSTER_DASHBOARD =
109+
'console.clusterDashboard.gettingStarted.expanded';

frontend/packages/dev-console/src/components/add/AddPageLayout.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import { useTranslation } from 'react-i18next';
55
import { AddActionGroup, isAddActionGroup } from '@console/dynamic-plugin-sdk';
66
import { getQueryArgument } from '@console/internal/components/utils';
77
import { useExtensions } from '@console/plugin-sdk/src';
8-
import { PageLayout, useActiveNamespace, RestoreGettingStartedButton } from '@console/shared';
8+
import { PageLayout, useActiveNamespace } from '@console/shared';
99
import TopologyQuickSearch from '@console/topology/src/components/quick-search/TopologyQuickSearch';
1010
import TopologyQuickSearchButton from '@console/topology/src/components/quick-search/TopologyQuickSearchButton';
1111
import { filterNamespaceScopedUrl } from '../../utils/add-page-utils';
1212
import { useAddActionExtensions } from '../../utils/useAddActionExtensions';
1313
import { ResourceQuotaAlert } from '../resource-quota/ResourceQuotaAlert';
1414
import AddCardSection from './AddCardSection';
15-
import { GETTING_STARTED_USER_SETTINGS_KEY } from './constants';
1615
import { GettingStartedSection } from './GettingStartedSection';
1716
import { useAccessFilterExtensions } from './hooks/useAccessFilterExtensions';
1817
import { useShowAddCardItemDetails } from './hooks/useShowAddCardItemDetails';
@@ -66,7 +65,6 @@ const AddPageLayout: React.FC<AddPageLayoutProps> = ({ title, hintBlock: additio
6665
<div className="odc-add-page-layout__resource-quota-message-block">
6766
<ResourceQuotaAlert namespace={activeNamespace} />
6867
</div>
69-
<RestoreGettingStartedButton userSettingsKey={GETTING_STARTED_USER_SETTINGS_KEY} />
7068
<div
7169
className={cx('odc-add-page-layout__hint-block__details-switch', {
7270
'odc-add-page-layout__hint-block__details-switch__loading-state': !extensionsLoaded,

frontend/packages/dev-console/src/components/add/GettingStartedSection.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
11
import * as React from 'react';
2-
import { FLAGS } from '@console/shared';
32
import {
4-
GettingStartedGrid,
5-
useGettingStartedShowState,
6-
GettingStartedShowState,
3+
FLAGS,
4+
GETTING_STARTED_USER_SETTINGS_KEY_ADD_PAGE,
5+
useUserSettings,
6+
} from '@console/shared';
7+
import {
78
QuickStartGettingStartedCard,
9+
GettingStartedExpandableGrid,
810
} from '@console/shared/src/components/getting-started';
911
import { useFlag } from '@console/shared/src/hooks/flag';
10-
import { GETTING_STARTED_USER_SETTINGS_KEY } from './constants';
1112
import { DeveloperFeaturesGettingStartedCard } from './DeveloperFeaturesGettingStartedCard';
1213
import { SampleGettingStartedCard } from './SampleGettingStartedCard';
1314

1415
import './GettingStartedSection.scss';
1516

1617
export const GettingStartedSection: React.FC = () => {
1718
const openshiftFlag = useFlag(FLAGS.OPENSHIFT);
18-
const [showState, setShowState, showStateLoaded] = useGettingStartedShowState(
19-
GETTING_STARTED_USER_SETTINGS_KEY,
19+
const [isGettingStartedSectionOpen, setIsGettingStartedSectionOpen] = useUserSettings<boolean>(
20+
GETTING_STARTED_USER_SETTINGS_KEY_ADD_PAGE,
21+
true,
2022
);
2123

22-
if (!openshiftFlag || !showStateLoaded || showState !== GettingStartedShowState.SHOW) {
24+
if (!openshiftFlag) {
2325
return null;
2426
}
2527

2628
return (
2729
<div className="odc-add-page-getting-started-section">
28-
<GettingStartedGrid onHide={() => setShowState(GettingStartedShowState.HIDE)}>
30+
<GettingStartedExpandableGrid
31+
isOpen={isGettingStartedSectionOpen}
32+
setIsOpen={setIsGettingStartedSectionOpen}
33+
>
2934
<SampleGettingStartedCard featured={['code-with-quarkus', 'java-springboot-basic']} />
3035
<QuickStartGettingStartedCard
3136
featured={[
@@ -45,7 +50,7 @@ export const GettingStartedSection: React.FC = () => {
4550
]}
4651
/>
4752
<DeveloperFeaturesGettingStartedCard />
48-
</GettingStartedGrid>
53+
</GettingStartedExpandableGrid>
4954
</div>
5055
);
5156
};

frontend/packages/dev-console/src/components/add/__tests__/GettingStartedSection.spec.tsx

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import * as React from 'react';
22
import { shallow } from 'enzyme';
3-
import {
4-
GettingStartedGrid,
5-
useGettingStartedShowState,
6-
GettingStartedShowState,
7-
} from '@console/shared/src/components/getting-started';
3+
import { useUserSettings } from '@console/shared';
4+
import { GettingStartedExpandableGrid } from '@console/shared/src/components/getting-started';
85
import { useFlag } from '@console/shared/src/hooks/flag';
96
import { GettingStartedSection } from '../GettingStartedSection';
107

@@ -32,34 +29,30 @@ jest.mock(
3229
},
3330
);
3431

32+
jest.mock('@console/shared/src/hooks/useUserSettings', () => ({
33+
useUserSettings: jest.fn(),
34+
}));
35+
36+
const mockUserSettings = useUserSettings as jest.Mock;
37+
3538
const useFlagMock = useFlag as jest.Mock;
36-
const useGettingStartedShowStateMock = useGettingStartedShowState as jest.Mock;
3739

3840
describe('GettingStartedSection', () => {
3941
it('should render with three child elements', () => {
4042
useFlagMock.mockReturnValue(true);
41-
useGettingStartedShowStateMock.mockReturnValue([GettingStartedShowState.SHOW, jest.fn(), true]);
43+
mockUserSettings.mockReturnValue([true, jest.fn()]);
4244

4345
const wrapper = shallow(<GettingStartedSection />);
4446

45-
expect(wrapper.find(GettingStartedGrid).props().children.length).toEqual(3);
47+
expect(wrapper.find(GettingStartedExpandableGrid).props().children.length).toEqual(3);
4648
});
4749

4850
it('should render nothing when useFlag(FLAGS.OPENSHIFT) return false', () => {
4951
useFlagMock.mockReturnValue(false);
50-
useGettingStartedShowStateMock.mockReturnValue([GettingStartedShowState.SHOW, jest.fn(), true]);
51-
52-
const wrapper = shallow(<GettingStartedSection />);
53-
54-
expect(wrapper.find(GettingStartedGrid).length).toEqual(0);
55-
});
56-
57-
it('should render nothing if user settings hide them', () => {
58-
useFlagMock.mockReturnValue(true);
59-
useGettingStartedShowStateMock.mockReturnValue([GettingStartedShowState.HIDE, jest.fn(), true]);
52+
mockUserSettings.mockReturnValue([true, jest.fn()]);
6053

6154
const wrapper = shallow(<GettingStartedSection />);
6255

63-
expect(wrapper.find(GettingStartedGrid).length).toEqual(0);
56+
expect(wrapper.find(GettingStartedExpandableGrid).length).toEqual(0);
6457
});
6558
});

frontend/packages/dev-console/src/components/add/constants.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import * as React from 'react';
22
import { shallow } from 'enzyme';
33

4+
import { useUserSettings } from '@console/shared';
45
import { useFlag } from '@console/shared/src/hooks/flag';
5-
import {
6-
GettingStartedGrid,
7-
useGettingStartedShowState,
8-
GettingStartedShowState,
9-
} from '@console/shared/src/components/getting-started';
6+
import { GettingStartedExpandableGrid } from '@console/shared/src/components/getting-started';
107

118
import { GettingStartedSection } from '../getting-started-section';
129

@@ -34,35 +31,31 @@ jest.mock(
3431
},
3532
);
3633

34+
jest.mock('@console/shared/src/hooks/useUserSettings', () => ({
35+
useUserSettings: jest.fn(),
36+
}));
37+
38+
const mockUserSettings = useUserSettings as jest.Mock;
39+
3740
const useFlagMock = useFlag as jest.Mock;
38-
const useGettingStartedShowStateMock = useGettingStartedShowState as jest.Mock;
3941

4042
describe('GettingStartedSection', () => {
4143
it('should render with three child elements', () => {
4244
useFlagMock.mockReturnValue(true);
43-
useGettingStartedShowStateMock.mockReturnValue([GettingStartedShowState.SHOW, jest.fn(), true]);
45+
mockUserSettings.mockReturnValue([true, jest.fn()]);
4446

4547
const wrapper = shallow(<GettingStartedSection />);
4648

47-
expect(wrapper.find(GettingStartedGrid).length).toEqual(1);
48-
expect(wrapper.find(GettingStartedGrid).props().children.length).toEqual(3);
49+
expect(wrapper.find(GettingStartedExpandableGrid).length).toEqual(1);
50+
expect(wrapper.find(GettingStartedExpandableGrid).props().children.length).toEqual(3);
4951
});
5052

5153
it('should render nothing when useFlag(FLAGS.OPENSHIFT) return false', () => {
5254
useFlagMock.mockReturnValue(false);
53-
useGettingStartedShowStateMock.mockReturnValue([GettingStartedShowState.SHOW, jest.fn(), true]);
54-
55-
const wrapper = shallow(<GettingStartedSection />);
56-
57-
expect(wrapper.find(GettingStartedGrid).length).toEqual(0);
58-
});
59-
60-
it('should render nothing if user settings hide them', () => {
61-
useFlagMock.mockReturnValue(true);
62-
useGettingStartedShowStateMock.mockReturnValue([GettingStartedShowState.HIDE, jest.fn(), true]);
55+
mockUserSettings.mockReturnValue([true, jest.fn()]);
6356

6457
const wrapper = shallow(<GettingStartedSection />);
6558

66-
expect(wrapper.find(GettingStartedGrid).length).toEqual(0);
59+
expect(wrapper.find(GettingStartedExpandableGrid).length).toEqual(0);
6760
});
6861
});

0 commit comments

Comments
 (0)