Skip to content

Commit

Permalink
frontend: Landing Icons and Single Drawer Item Patch (#2712)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdslaugh authored Jun 30, 2023
1 parent eae16d5 commit 053f319
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 48 deletions.
54 changes: 37 additions & 17 deletions frontend/packages/app/cypress/integration/navigation_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ const DRAWER = "drawer";
const WORKFLOW_GROUP = "workflowGroup";
const WORKFLOW_GROUP_ITEM = "workflowGroupItem";

const ifElementExists = (selector, attempt = 0) => {
if (attempt === 5) {
return null;
}

if (Cypress.$(selector).length === 0) {
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(100, { log: false });
return ifElementExists(selector, attempt + 1);
}

return cy.get(selector, { log: false });
};

describe("Navigation drawer", () => {
before(() => {
cy.visit("localhost:3000");
Expand All @@ -17,30 +31,36 @@ describe("Navigation drawer", () => {
it("displays and hides routes", () => {
cy.element(WORKFLOW_GROUP).each((_, idx) => {
cy.element(WORKFLOW_GROUP).eq(idx).click();
cy.element(WORKFLOW_GROUP_ITEM).each(link => {
cy.wrap(link).should("have.attr", "href");
});
cy.element(WORKFLOW_GROUP).eq(idx).click();
cy.element(WORKFLOW_GROUP).eq(idx).descendent(WORKFLOW_GROUP_ITEM).should("not.exist");
const element = ifElementExists(WORKFLOW_GROUP_ITEM);
if (element) {
element.each(link => {
cy.wrap(link).should("have.attr", "href");
});
cy.element(WORKFLOW_GROUP).eq(idx).click();
cy.element(WORKFLOW_GROUP).eq(idx).descendent(WORKFLOW_GROUP_ITEM).should("not.exist");
}
});
});

describe("routes to workflows", () => {
it("can route correctly", () => {
return cy.element(WORKFLOW_GROUP).each((_, groupIdx) => {
cy.element(WORKFLOW_GROUP).eq(groupIdx).click();
cy.element(WORKFLOW_GROUP_ITEM).each((__, linkIdx) => {
cy.element(WORKFLOW_GROUP_ITEM).eq(linkIdx).should("be.visible");
cy.element(WORKFLOW_GROUP_ITEM)
.eq(linkIdx)
.should("have.attr", "href")
.then(href => {
cy.element(WORKFLOW_GROUP_ITEM).eq(linkIdx).click();
cy.url().should("include", href);
});
cy.element(WORKFLOW_GROUP).eq(groupIdx).click();
// TODO: validate header of workflow here when it's landed
});
const element = ifElementExists(WORKFLOW_GROUP_ITEM);
if (element) {
cy.element(WORKFLOW_GROUP_ITEM).each((__, linkIdx) => {
cy.element(WORKFLOW_GROUP_ITEM).eq(linkIdx).should("be.visible");
cy.element(WORKFLOW_GROUP_ITEM)
.eq(linkIdx)
.should("have.attr", "href")
.then(href => {
cy.element(WORKFLOW_GROUP_ITEM).eq(linkIdx).click();
cy.url().should("include", href);
});
cy.element(WORKFLOW_GROUP).eq(groupIdx).click();
// TODO: validate header of workflow here when it's landed
});
}
});
});
});
Expand Down
17 changes: 14 additions & 3 deletions frontend/packages/core/src/AppLayout/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import _ from "lodash";
import type { WorkflowIcon } from "../AppProvider";
import type { Workflow } from "../AppProvider/workflow";
import { useAppContext } from "../Contexts";
import { useNavigate } from "../navigation";
import type { PopperItemProps } from "../popper";
import { Popper, PopperItem } from "../popper";

Expand All @@ -37,7 +38,7 @@ const GroupList = styled(List)({
padding: "0px",
});

const GroupListItem = styled(ListItemButton)<{ icon: boolean }>(
const GroupListItem = styled(ListItemButton)<{ icon: number }>(
{
flexDirection: "column",
minHeight: "82px",
Expand Down Expand Up @@ -115,7 +116,9 @@ const Group = ({
closeGroup,
children,
}: GroupProps) => {
const navigate = useNavigate();
const anchorRef = React.useRef(null);
const singleChild = React.Children.count(children) === 1;
const validIcon = icon.path && icon.path.length > 0;

// n.b. if a Workflow Grouping has no workflows in it don't display it even if
Expand All @@ -133,8 +136,11 @@ const Group = ({
ref={anchorRef}
aria-controls={open ? "workflow-options" : undefined}
aria-haspopup="true"
icon={validIcon}
icon={+validIcon}
onClick={() => {
if (singleChild) {
navigate(children[0].props.to);
}
updateOpenGroup(heading);
}}
>
Expand All @@ -144,7 +150,12 @@ const Group = ({
<Avatar>{heading.charAt(0)}</Avatar>
)}
<GroupHeading align="center">{heading}</GroupHeading>
<Popper open={open} onClickAway={closeGroup} anchorRef={anchorRef} id="workflow-options">
<Popper
open={open && !singleChild}
onClickAway={closeGroup}
anchorRef={anchorRef}
id="workflow-options"
>
{children}
</Popper>
</GroupListItem>
Expand Down
9 changes: 9 additions & 0 deletions frontend/packages/core/src/AppLayout/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface TrendingWorkflow {
group: string;
description: string;
path: string;
icon: string;
}

const getDisplayName = (workflow: Workflow, route: Route, delimiter: string = ":"): string => {
Expand All @@ -36,6 +37,13 @@ const getDisplayName = (workflow: Workflow, route: Route, delimiter: string = ":

const workflowsByTrending = (workflows: Workflow[]): TrendingWorkflow[] => {
const trending = [];
const trendingIcons = {};

workflows.forEach(workflow => {
if (workflow?.icon?.path && !trendingIcons[workflow.group]) {
trendingIcons[workflow.group] = workflow.icon.path;
}
});

workflows.forEach(workflow => {
workflow.routes.forEach(route => {
Expand All @@ -45,6 +53,7 @@ const workflowsByTrending = (workflows: Workflow[]): TrendingWorkflow[] => {
group: workflow.group,
description: route.description,
path: `${workflow.path}/${route.path}`,
icon: trendingIcons[workflow.group] ?? "",
});
}
});
Expand Down
72 changes: 44 additions & 28 deletions frontend/packages/core/src/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,20 +258,12 @@ const StyledLandingCard = styled(Card)({
lineHeight: "36px",
color: "rgba(13, 16, 48, 0.6)",
},

"& .header .icon .MuiAvatar-root": {
height: "36px",
width: "36px",
marginRight: "8px",
color: "rgba(13, 16, 48, 0.38)",
backgroundColor: "rgba(13, 16, 48, 0.12)",
},
});

const TruncatedText = styled(Typography)({
display: "-webkit-box",
overflow: "hidden",
"-webkit-box-orient": "vertical",
WebkitBoxOrient: "vertical",
"-webkit-line-clamp": "3",
[`@media screen and (max-width: 595px),
screen and (min-width: 900px) and (max-width: 950px),
Expand All @@ -280,31 +272,55 @@ const TruncatedText = styled(Typography)({
},
});

const IconAvatar = styled(Avatar)({
height: "36px",
width: "36px",
marginRight: "8px",
});

const StyledAvatar = styled(IconAvatar)({
color: "rgba(13, 16, 48, 0.38)",
backgroundColor: "rgba(13, 16, 48, 0.12)",
});

export interface LandingCardProps extends Pick<CardActionAreaProps, "onClick"> {
group: string;
title: string;
description: string;
icon: string;
}

export const LandingCard = ({ group, title, description, onClick, ...props }: LandingCardProps) => (
<StyledLandingCard {...props}>
<StyledCardActionArea className="cardActionArea" onClick={onClick}>
<CardContent padding={4}>
<div className="header">
<div className="icon">
<Avatar>{group.charAt(0)}</Avatar>
export const LandingCard = ({
group,
title,
description,
icon,
onClick,
...props
}: LandingCardProps) => {
const validIcon = icon && icon.length > 0;
return (
<StyledLandingCard {...props}>
<StyledCardActionArea className="cardActionArea" onClick={onClick}>
<CardContent padding={4}>
<div className="header">
{validIcon ? (
<IconAvatar src={icon}>{group.charAt(0)}</IconAvatar>
) : (
<StyledAvatar>{group.charAt(0)}</StyledAvatar>
)}
<span>{group}</span>
</div>
<span>{group}</span>
</div>
<div>
<TruncatedText variant="h3">{title}</TruncatedText>
<TruncatedText color="rgba(13, 16, 48, 0.6)" variant="body2">
{description}
</TruncatedText>
</div>
</CardContent>
</StyledCardActionArea>
</StyledLandingCard>
);
<div>
<TruncatedText variant="h3">{title}</TruncatedText>
<TruncatedText color="rgba(13, 16, 48, 0.6)" variant="body2">
{description}
</TruncatedText>
</div>
</CardContent>
</StyledCardActionArea>
</StyledLandingCard>
);
};

export { Card, CardContent, CardHeader };
1 change: 1 addition & 0 deletions frontend/packages/core/src/landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ const Landing: React.FC<{}> = () => {
description={workflow.description}
onClick={() => navigateTo(workflow.path)}
key={workflow.path}
icon={workflow.icon}
/>
</Grid>
))}
Expand Down

0 comments on commit 053f319

Please sign in to comment.