Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Guided tour tile #5822

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/packages/dev-console/src/components/EmptyState.tsx
Expand Up @@ -6,6 +6,7 @@ import { history, PageHeading, useAccessReview } from '@console/internal/compone
import { useExtensions } from '@console/plugin-sdk';
import { RootState } from '@console/internal/redux';
import { isAddAction, AddAction } from '../extensions/add-actions';
import GuidedTourAddAction from './GuidedTourAddAction';
import './EmptyState.scss';
import { ALL_NAMESPACES_KEY } from '@console/shared';

Expand Down Expand Up @@ -83,6 +84,7 @@ const ODCEmptyState: React.FC<Props> = ({
</div>
<div className="odc-empty-state__content">
<Gallery className="co-catalog-tile-view" hasGutter>
<GuidedTourAddAction />
{addActionExtensions.map((action) => (
<Item key={action.properties.id} namespace={activeNamespace} action={action} />
))}
Expand Down
@@ -0,0 +1,10 @@
import * as React from 'react';
import { getGuidedToursWithStatus } from '@console/app/src/components/guided-tours/utils/guided-tour-utils';
import GuidedTourTile from './GuidedTourTile';

const GuidedTourAddAction: React.FC = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why exactly do we need this extra component here? It doesn't seem to be doing anything at the moment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed this

const guidedTourList = getGuidedToursWithStatus();
return guidedTourList.length > 0 ? <GuidedTourTile tours={guidedTourList} /> : null;
};

export default GuidedTourAddAction;
27 changes: 27 additions & 0 deletions frontend/packages/dev-console/src/components/GuidedTourTile.scss
@@ -0,0 +1,27 @@
.odc-guidedtour-tile {
&__card {
height: 100%;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  height: $co-m-catalog-tile-height;
  width: $co-m-catalog-tile-width;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above aligns with the other empty state tile sizes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

}
&__header {
padding: 0px var(--pf-global--spacer--md);
margin: 0px;
}
&__body {
padding: var(--pf-global--spacer--sm);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
&__header {
padding: 0px var(--pf-global--spacer--md);
margin: 0px;
}
&__body {
padding: var(--pf-global--spacer--sm);
}

&__tour {
padding: var(--pf-global--spacer--sm) var(--pf-global--spacer--md);
text-align: left;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
padding: var(--pf-global--spacer--sm) var(--pf-global--spacer--md);
text-align: left;
margin-bottom: var(--pf-global--spacer--sm);

}
&__arrowbtn {
margin-right: var(--pf-global--spacer--md);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
margin-right: var(--pf-global--spacer--md);
margin-right: var(--pf-global--spacer--sm);

}
&__footer {
border-top: 1px solid var(--pf-global--BorderColor--100);
padding: var(--pf-global--spacer--sm) var(--pf-global--spacer--lg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
padding: var(--pf-global--spacer--sm) var(--pf-global--spacer--lg);
padding-top: var(--pf-global--spacer--sm);
padding-bottom: var(--pf-global--spacer--sm);

}
&__title {
font-weight: var(--pf-global--FontWeight--bold);
font-size: var(--pf-global--FontSize--lg);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use a patternfly Title component instead.

Suggested change
&__title {
font-weight: var(--pf-global--FontWeight--bold);
font-size: var(--pf-global--FontSize--lg);
}

}
63 changes: 63 additions & 0 deletions frontend/packages/dev-console/src/components/GuidedTourTile.tsx
@@ -0,0 +1,63 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import {
Card,
CardActions,
CardBody,
CardFooter,
CardHeader,
CardHeaderMain,
Dropdown,
DropdownItem,
GalleryItem,
KebabToggle,
} from '@patternfly/react-core';
import { ArrowRightIcon } from '@patternfly/react-icons';
import {
GuidedTourItem,
TourStatus,
} from '@console/app/src/components/guided-tours/utils/guided-tour-typings';
import './GuidedTourTile.scss';

type TourItem = GuidedTourItem & TourStatus;
type GuidedTourTileProps = {
tours: TourItem[];
};

const GuidedTourTile: React.FC<GuidedTourTileProps> = ({ tours }) => {
const [isOpen, setOpen] = React.useState(false);
const onToggle = () => setOpen(!isOpen);
const actionDropdownItem = [<DropdownItem key="link">Remove guided tours</DropdownItem>];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This action needs to remove the card and save the setting to local storage.

const orderedTours = tours.length > 3 ? tours.slice(0, 3) : tours;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not actually ordered tours.

Suggested change
const orderedTours = tours.length > 3 ? tours.slice(0, 3) : tours;
const slicedTours = tours.length > 3 ? tours.slice(0, 3) : tours;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

return (
<GalleryItem className="odc-guidedtour-tile">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<GalleryItem className="odc-guidedtour-tile">
<GalleryItem>

<Card className="odc-guidedtour-tile__card">
<CardHeader>
<CardHeaderMain className="odc-guidedtour-tile__title">Guided Tours</CardHeaderMain>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<CardHeaderMain className="odc-guidedtour-tile__title">Guided Tours</CardHeaderMain>
<CardHeaderMain>
<Title headingLevel="h1" size="xl">
Guided Tours
</Title>
</CardHeaderMain>

<CardActions>
<Dropdown
toggle={<KebabToggle onToggle={onToggle} />}
isOpen={isOpen}
isPlain
dropdownItems={actionDropdownItem}
position={'right'}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
position={'right'}
position="right"

/>
</CardActions>
</CardHeader>
<CardBody className="odc-guidedtour-tile__body">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<CardBody className="odc-guidedtour-tile__body">
<CardBody>

{orderedTours.map((tour) => (
<div key={tour.name} className="odc-guidedtour-tile__tour">
<Link to="/#">{tour.name}</Link>
</div>
))}
</CardBody>
<CardFooter className="odc-guidedtour-tile__footer">
<ArrowRightIcon className="odc-guidedtour-tile__arrowbtn" />
<Link to="/tours">See all guided tours</Link>
</CardFooter>
</Card>
</GalleryItem>
);
};

export default GuidedTourTile;
@@ -0,0 +1,31 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import { shallow } from 'enzyme';
import GuidedTourTile from '../GuidedTourTile';
import { getGuidedToursWithStatus } from '@console/app/src/components/guided-tours/utils/guided-tour-utils';
import { CardActions, Dropdown, CardBody, CardFooter } from '@patternfly/react-core';

type GuidedTourTileProps = React.ComponentProps<typeof GuidedTourTile>;

describe('GuidedTourTile', () => {
const guidedTourTileProps: GuidedTourTileProps = {
tours: getGuidedToursWithStatus(),
};
const guidedTourTileWrapper = shallow(<GuidedTourTile {...guidedTourTileProps} />);
it('should show proper CardAction', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to have a test for when local storage has removed tile state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

const cardAction = guidedTourTileWrapper.find(CardActions);
expect(cardAction.exists()).toBe(true);
expect(cardAction.find(Dropdown).prop('dropdownItems').length).toEqual(1);
});
it('should show 3 tour links', () => {
const cardBody = guidedTourTileWrapper.find(CardBody);
expect(cardBody.exists()).toBe(true);
expect(cardBody.find(Link).length).toEqual(3);
});
it('should show a footer link to GuidedTourCatalog', () => {
const cardFooter = guidedTourTileWrapper.find(CardFooter);
expect(cardFooter.exists()).toBe(true);
expect(cardFooter.find(Link).exists()).toBe(true);
expect(cardFooter.find(Link).prop('to')).toEqual('/tours');
});
});