Skip to content

Commit

Permalink
Kurtosis package page
Browse files Browse the repository at this point in the history
  • Loading branch information
Dartoxian committed Nov 30, 2023
1 parent dda8edf commit 2437c06
Show file tree
Hide file tree
Showing 23 changed files with 407 additions and 122 deletions.
61 changes: 34 additions & 27 deletions enclave-manager/web/src/components/KurtosisBreadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { ReactElement, useMemo } from "react";
import { BsCaretDownFill } from "react-icons/bs";
import { Link, Params, UIMatch, useMatches } from "react-router-dom";
import { CatalogState, useCatalogContext } from "../emui/catalog/CatalogContext";
import { EnclavesState, useEnclavesContext } from "../emui/enclaves/EnclavesContext";
import { isDefined } from "../utils";
import { RemoveFunctions } from "../utils/types";
Expand All @@ -33,7 +34,7 @@ export type KurtosisEnclavesBreadcrumbsHandle = KurtosisBaseBreadcrumbsHandle &

export type KurtosisCatalogBreadcrumbsHandle = {
type: "catalogHandle";
crumb?: () => KurtosisBreadcrumb | KurtosisBreadcrumb[];
crumb?: (state: RemoveFunctions<CatalogState>, params: Params<string>) => KurtosisBreadcrumb | KurtosisBreadcrumb[];
};

export type KurtosisBreadcrumbsHandle = KurtosisEnclavesBreadcrumbsHandle | KurtosisCatalogBreadcrumbsHandle;
Expand Down Expand Up @@ -151,16 +152,18 @@ type KurtosisCatalogBreadcrumbsProps = {
};

const KurtosisCatalogBreadcrumbs = ({ matches }: KurtosisCatalogBreadcrumbsProps) => {
const { catalog, savedPackages } = useCatalogContext();

const matchCrumbs = useMemo(
() =>
matches.flatMap((match) => {
if (isDefined(match.handle?.crumb)) {
const r = match.handle.crumb();
const r = match.handle.crumb({ catalog, savedPackages }, match.params);
return Array.isArray(r) ? r : [r];
}
return [];
}),
[matches],
[matches, catalog, savedPackages],
);

return <KurtosisBreadcrumbsImpl matchCrumbs={matchCrumbs} />;
Expand All @@ -173,32 +176,36 @@ type KurtosisBreadcrumbsImplProps = {

const KurtosisBreadcrumbsImpl = ({ matchCrumbs, extraControls }: KurtosisBreadcrumbsImplProps) => {
return (
<Flex h={BREADCRUMBS_HEIGHT}>
<Flex w={MAIN_APP_MAX_WIDTH_WITHOUT_PADDING} alignItems={"center"} justifyContent={"space-between"}>
<Flex>
<Breadcrumb
variant={"topNavigation"}
separator={
<Text as={"span"} fontSize={"lg"}>
/
</Text>
}
>
<BreadcrumbItem>
<Text fontSize={"xs"} fontWeight={"semibold"} p={"0px 8px"}>
Kurtosis
</Text>
<Flex
flex={"none"}
h={BREADCRUMBS_HEIGHT}
w={MAIN_APP_MAX_WIDTH_WITHOUT_PADDING}
alignItems={"center"}
justifyContent={"space-between"}
>
<Flex>
<Breadcrumb
variant={"topNavigation"}
separator={
<Text as={"span"} fontSize={"lg"}>
/
</Text>
}
>
<BreadcrumbItem>
<Text fontSize={"xs"} fontWeight={"semibold"} p={"0px 8px"}>
Kurtosis
</Text>
</BreadcrumbItem>
{matchCrumbs.map((crumb, i, arr) => (
<BreadcrumbItem key={i} isCurrentPage={i === arr.length - 1}>
<KurtosisBreadcrumbItem {...crumb} key={i} isLastItem={i === arr.length - 1} />
</BreadcrumbItem>
{matchCrumbs.map((crumb, i, arr) => (
<BreadcrumbItem key={i} isCurrentPage={i === arr.length - 1}>
<KurtosisBreadcrumbItem {...crumb} key={i} isLastItem={i === arr.length - 1} />
</BreadcrumbItem>
))}
</Breadcrumb>
&nbsp;
</Flex>
<Flex>{extraControls}</Flex>
))}
</Breadcrumb>
&nbsp;
</Flex>
<Flex>{extraControls}</Flex>
</Flex>
);
};
Expand Down
81 changes: 81 additions & 0 deletions enclave-manager/web/src/components/KurtosisMarkdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Code, Divider, Heading, Image, Link, Table, Tbody, Td, Text, Th, Thead, Tr } from "@chakra-ui/react";
import { DetailedHTMLProps, HTMLAttributes } from "react";
import Markdown, { Components } from "react-markdown";

const heading =
(level: 1 | 2 | 3 | 4 | 5 | 6) =>
({ children }: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) => {
const sizes = ["xl", "lg", "md", "sm", "xs", "xs"];
return (
<Heading my={4} as={`h${level}`} size={sizes[`${level - 1}`]}>
{children}
</Heading>
);
};

const componentStrategy: Components = {
h1: heading(1),
h2: heading(2),
h3: heading(3),
h4: heading(4),
h5: heading(5),
h6: heading(6),
p: (props) => {
const { children } = props;
return <Text mb={2}>{children}</Text>;
},
em: (props) => {
const { children } = props;
return <Text as="em">{children}</Text>;
},
blockquote: (props) => {
const { children } = props;
return (
<Code as="blockquote" p={2}>
{children}
</Code>
);
},
code: ({ children }) => {
return <Code children={children} />;
},
del: (props) => {
const { children } = props;
return <Text as="del">{children}</Text>;
},
hr: (props) => {
return <Divider />;
},
a: Link,
img: (props) => <Image src={props.src} />,
text: (props) => {
const { children } = props;
return <Text as="span">{children}</Text>;
},
pre: (props) => {
const { children } = props;
return (
<Text margin={1} as={"pre"}>
{children}
</Text>
);
},
table: Table,
thead: Thead,
tbody: Tbody,
tr: (props) => <Tr>{props.children}</Tr>,
td: (props) => <Td>{props.children}</Td>,
th: (props) => <Th>{props.children}</Th>,
};

type KurtosisMarkdownProps = {
children?: string;
};

export const KurtosisMarkdown = ({ children }: KurtosisMarkdownProps) => {
return (
<Markdown components={componentStrategy} skipHtml>
{children}
</Markdown>
);
};
2 changes: 0 additions & 2 deletions enclave-manager/web/src/components/KurtosisThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,11 @@ const theme = extendTheme({
},
titledCard: {
container: {
height: "100%",
bgColor: "none",
borderColor: "gray.500",
borderStyle: "solid",
borderWidth: "1px",
borderRadius: "6px",
overflow: "clip",
},
header: {
bg: "gray.850",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { Button, ButtonGroup, ButtonProps, Icon, Spinner, Tag, Tooltip } from "@chakra-ui/react";
import { Button, ButtonGroup, ButtonProps, Icon, Link, Spinner, Tag, Tooltip } from "@chakra-ui/react";
import { PropsWithChildren } from "react";
import { IoLogoGithub } from "react-icons/io";
import { useKurtosisPackageIndexerClient } from "../../../client/packageIndexer/KurtosisPackageIndexerClientContext";
import { isDefined, wrapResult } from "../../../utils";
import { CopyButton } from "../../CopyButton";
import { useKurtosisPackageIndexerClient } from "../client/packageIndexer/KurtosisPackageIndexerClientContext";
import { isDefined, wrapResult } from "../utils";
import { CopyButton } from "./CopyButton";

type EnclaveSourceProps = ButtonProps & {
source: "loading" | string | null;
};
type EnclaveSourceProps = PropsWithChildren<
ButtonProps & {
source: "loading" | string | null;
hideCopy?: boolean;
}
>;

export const EnclaveSourceButton = ({ source, ...buttonProps }: EnclaveSourceProps) => {
export const PackageSourceButton = ({ source, hideCopy, children, ...buttonProps }: EnclaveSourceProps) => {
const kurtosisIndexer = useKurtosisPackageIndexerClient();

if (!isDefined(source)) {
Expand All @@ -20,11 +24,11 @@ export const EnclaveSourceButton = ({ source, ...buttonProps }: EnclaveSourcePro
}

let button = (
<a href={`https://${source}`} target="_blank" rel="noopener noreferrer">
<Link href={`https://${source}`} target="_blank" rel="noopener noreferrer" w={buttonProps.w || buttonProps.width}>
<Button variant={"ghost"} size={"xs"} {...buttonProps}>
{source}
{children || source}
</Button>
</a>
</Link>
);
if (source.startsWith("github.com/")) {
const repositoryResult = wrapResult(() => kurtosisIndexer.parsePackageUrl(source));
Expand All @@ -35,23 +39,23 @@ export const EnclaveSourceButton = ({ source, ...buttonProps }: EnclaveSourcePro
}`;

button = (
<a href={url} target="_blank" rel="noopener noreferrer">
<Link href={url} target="_blank" rel="noopener noreferrer" w={buttonProps.w || buttonProps.width}>
<Button
leftIcon={<Icon as={IoLogoGithub} color={"gray.400"} />}
variant={"ghost"}
size={"xs"}
{...buttonProps}
>
{source.replace("github.com/", "")}
{children || source.replace("github.com/", "")}
</Button>
</a>
</Link>
);
} else {
button = (
<Tooltip shouldWrapChildren label={repositoryResult.error}>
<a href={`https://${source}`} target="_blank" rel="noopener noreferrer">
<Button variant={"ghost"} size={"xs"} {...buttonProps} colorScheme={"red"}>
{source}
{children || source}
</Button>
</a>
</Tooltip>
Expand All @@ -62,13 +66,15 @@ export const EnclaveSourceButton = ({ source, ...buttonProps }: EnclaveSourcePro
return (
<ButtonGroup>
{button}
<CopyButton
contentName={"package id"}
valueToCopy={source}
isIconButton
aria-label={"Copy package id"}
size={buttonProps.size || "xs"}
/>
{!hideCopy && (
<CopyButton
contentName={"package id"}
valueToCopy={source}
isIconButton
aria-label={"Copy package id"}
size={buttonProps.size || "xs"}
/>
)}
</ButtonGroup>
);
};
14 changes: 11 additions & 3 deletions enclave-manager/web/src/components/TitledCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ import { PropsWithChildren, ReactElement } from "react";
type TitledCardProps = CardProps &
PropsWithChildren<{
title: string;
fillContainer?: boolean;
controls?: ReactElement;
rightControls?: ReactElement;
}>;

export const TitledCard = ({ title, controls, rightControls, children, ...cardProps }: TitledCardProps) => {
export const TitledCard = ({
title,
fillContainer,
controls,
rightControls,
children,
...cardProps
}: TitledCardProps) => {
return (
<Card variant={"titledCard"} {...cardProps}>
<Card variant={"titledCard"} overflow={fillContainer ? "clip" : undefined} {...cardProps}>
<CardHeader
display={"flex"}
justifyContent={"space-between"}
Expand All @@ -28,7 +36,7 @@ export const TitledCard = ({ title, controls, rightControls, children, ...cardPr
</Flex>
<Flex>{rightControls}</Flex>
</CardHeader>
<CardBody overflow={"auto"}>{children}</CardBody>
<CardBody overflow={fillContainer ? "auto" : undefined}>{children}</CardBody>
</Card>
);
};
Loading

0 comments on commit 2437c06

Please sign in to comment.