From 1481e41e4eddc995b15d139341698d3c8a8ecf71 Mon Sep 17 00:00:00 2001 From: Gabe Womble Date: Wed, 3 Nov 2021 10:33:24 -0700 Subject: [PATCH] feat: add feedback links to bottom of package page (#569) Fixes #552 Screen Shot 2021-11-03 at 9 51 45 AM --- cypress/integration/package-page.spec.ts | 61 +++++++++++++++++++ src/icons/GithubIcon.tsx | 16 +++++ src/views/Package/FeedbackLinks.tsx | 77 ++++++++++++++++++++++++ src/views/Package/PackageDocs.tsx | 3 +- src/views/Package/PackageLayout.tsx | 13 +++- src/views/Package/testIds.ts | 8 +++ 6 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 cypress/integration/package-page.spec.ts create mode 100644 src/icons/GithubIcon.tsx create mode 100644 src/views/Package/FeedbackLinks.tsx create mode 100644 src/views/Package/testIds.ts diff --git a/cypress/integration/package-page.spec.ts b/cypress/integration/package-page.spec.ts new file mode 100644 index 00000000..826029b2 --- /dev/null +++ b/cypress/integration/package-page.spec.ts @@ -0,0 +1,61 @@ +import { getPackagePath } from "util/url"; +import header from "components/Header/testIds"; +import packagePage from "views/Package/testIds"; + +describe("Package Page", () => { + beforeEach(() => { + cy.intercept("**/assembly.json", async (req) => { + req.reply({ + fixture: "assembly", + }); + }); + + cy.intercept("**/metadata.json", async (req) => { + req.reply({ + fixture: "metadata", + }); + }); + + cy.intercept("**/docs-typescript.md", async (req) => { + req.reply({ + fixture: "xss-docs.md", + }); + }).as("getDocs"); + + cy.visit( + getPackagePath({ + name: "construct-hub", + version: "0.2.31", + language: "typescript" as any, + }) + ); + + cy.wait("@getDocs"); + + cy.getByDataTest(header.container).should("be.visible"); + }); + + it("Has feedback and report links", () => { + cy.getByDataTest(packagePage.feedbackLinks) + .should("be.visible") + .within(() => { + cy.getByDataTest(packagePage.reportLink) + .should("be.visible") + .should( + "have.attr", + "href", + `mailto:abuse@amazonaws.com?subject=${encodeURIComponent( + `ConstructHub - Report of abusive package: construct-hub` + )}` + ); + + cy.getByDataTest(packagePage.githubLink) + .should("be.visible") + .should( + "have.attr", + "href", + "https://github.com/cdklabs/construct-hub/issues" + ); + }); + }); +}); diff --git a/src/icons/GithubIcon.tsx b/src/icons/GithubIcon.tsx new file mode 100644 index 00000000..ec3c6508 --- /dev/null +++ b/src/icons/GithubIcon.tsx @@ -0,0 +1,16 @@ +import { Icon } from "@chakra-ui/react"; + +export const GithubIcon: typeof Icon = (props) => ( + + + + +); diff --git a/src/views/Package/FeedbackLinks.tsx b/src/views/Package/FeedbackLinks.tsx new file mode 100644 index 00000000..6aa75210 --- /dev/null +++ b/src/views/Package/FeedbackLinks.tsx @@ -0,0 +1,77 @@ +import { EmailIcon } from "@chakra-ui/icons"; +import { Button, Link, Flex } from "@chakra-ui/react"; +import type { FunctionComponent, ReactNode } from "react"; +import { ExternalLink } from "../../components/ExternalLink"; +import { GithubIcon } from "../../icons/GithubIcon"; +import { usePackageState } from "./PackageState"; +import testIds from "./testIds"; + +const iconProps = { + h: 5, + ml: 2, + w: 5, +}; + +export const FeedbackLinks: FunctionComponent = () => { + const state = usePackageState(); + const metadata = state.metadata.data; + const assembly = state.assembly.data; + + if (!(assembly && metadata)) return null; + + const repo = assembly?.repository ?? {}; + + let repoLink: ReactNode = null; + + if (repo.type === "git") { + let repoUrl = repo.url?.endsWith(".git") + ? repo.url.replace(".git", "") + : repo.url; + + if (repoUrl.endsWith("/")) { + repoUrl = repoUrl.slice(0, repoUrl.length - 1); + } + + repoLink = ( + + ); + } + + return ( + + + + {repoLink} + + ); +}; diff --git a/src/views/Package/PackageDocs.tsx b/src/views/Package/PackageDocs.tsx index 590e25e6..7ce7131b 100644 --- a/src/views/Package/PackageDocs.tsx +++ b/src/views/Package/PackageDocs.tsx @@ -94,8 +94,9 @@ export const PackageDocs: FunctionComponent = ({ display={{ base: "none", md: "flex" }} maxHeight={`calc(100vh - ${TOP_OFFSET})`} overflow="hidden auto" + pl={6} position="sticky" - px={4} + pr={4} top={TOP_OFFSET} > {Object.keys(assembly?.submodules ?? {}).length > 0 && ( diff --git a/src/views/Package/PackageLayout.tsx b/src/views/Package/PackageLayout.tsx index c9d2a97e..e5a5bc77 100644 --- a/src/views/Package/PackageLayout.tsx +++ b/src/views/Package/PackageLayout.tsx @@ -11,11 +11,13 @@ import { } from "@chakra-ui/react"; import { FunctionComponent } from "react"; import { Page } from "../../components/Page"; +import { FeedbackLinks } from "./FeedbackLinks"; import { PackageDocs } from "./PackageDocs"; import { PackageDocsError } from "./PackageDocsError"; import { PackageDocsUnsupported } from "./PackageDocsUnsupported"; import { PackageHeader } from "./PackageHeader"; import { usePackageState } from "./PackageState"; +import testIds from "./testIds"; export const PackageLayout: FunctionComponent = () => { const { @@ -34,12 +36,18 @@ export const PackageLayout: FunctionComponent = () => { meta={{ title: pageTitle, description: pageDescription }} pageName="packageProfile" > - + { Coming Soon + ); diff --git a/src/views/Package/testIds.ts b/src/views/Package/testIds.ts new file mode 100644 index 00000000..a7122ba3 --- /dev/null +++ b/src/views/Package/testIds.ts @@ -0,0 +1,8 @@ +import { createTestIds } from "../../util/createTestIds"; + +export default createTestIds("package-page", [ + "page", + "feedbackLinks", + "reportLink", + "githubLink", +] as const);