Skip to content

Commit

Permalink
Use flow list component for rendering operation list (#356)
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-helmich authored Dec 20, 2024
1 parent f9dd00e commit 1367402
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 20 deletions.
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions src/components/openapi/OperationDocCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import AlertBadge from "@mittwald/flow-react-components/AlertBadge";
import { APIVersion, OperationWithMeta } from "@site/src/openapi/specs";
import isDeprecated from "@site/src/openapi/isDeprecated";
import buildDocumentId from "@site/src/openapi/buildDocumentId";
import OperationLink from "@site/src/components/openapi/OperationLink";

interface Props {
apiVersion: APIVersion;
Expand All @@ -19,11 +20,6 @@ export default function OperationDocCard(p: Props) {
const { apiVersion, variant } = p;
const { operation, method, path } = p.operation;
const deprecated = isDeprecated(operation);
const docId = buildDocumentId(operation);

const url = apiVersion.endsWith("-preview")
? `/docs/${apiVersion.replace("-preview", "")}/preview/${docId.replace("reference/", "")}`
: `/docs/${apiVersion}/reference/${docId.replace("reference/", "")}`;

return (
<div
Expand All @@ -35,7 +31,7 @@ export default function OperationDocCard(p: Props) {
variant === "compact" ? styles.compact : null,
)}
>
<Link to={url}>
<OperationLink apiVersion={apiVersion} operation={p.operation}>
<div className={styles.header}>
<HTTPMethod method={method} deprecated={deprecated} />
<div className={styles.headerText}>
Expand All @@ -50,7 +46,7 @@ export default function OperationDocCard(p: Props) {
<AlertBadge status="warning">deprecated!</AlertBadge>
) : null}
</div>
</Link>
</OperationLink>
</div>
);
}
26 changes: 26 additions & 0 deletions src/components/openapi/OperationDocCardList.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.method {
text-transform: uppercase;
color: white;
width: 100px;
border-radius: 4px;
}

.method-get {
background-color: var(--ifm-color-success);
}

.method-post {
background-color: var(--ifm-color-info);
}

.method-delete {
background-color: var(--ifm-color-danger);
}

.method-patch {
background-color: var(--ifm-color-warning);
}

.method-put {
background-color: var(--ifm-color-warning);
}
73 changes: 60 additions & 13 deletions src/components/openapi/OperationDocCardList.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,81 @@
import {
APIVersion,
getOperationByTag,
OperationWithMeta,
useSpec,
} from "@site/src/openapi/specs";
import OperationDocCard from "@site/src/components/openapi/OperationDocCard";
import ColumnLayout from "@mittwald/flow-react-components/ColumnLayout";
import compareOperation from "@site/src/openapi/compareOperation";
import { typedList } from "@mittwald/flow-react-components/List";
import Heading from "@mittwald/flow-react-components/Heading";
import Text from "@mittwald/flow-react-components/Text";
import HTTPMethod from "@site/src/components/openapi/HTTPMethod";
import Avatar from "@mittwald/flow-react-components/Avatar";
import styles from "@site/src/components/openapi/OperationDocCardList.module.css";
import clsx from "clsx";
import AlertBadge from "@mittwald/flow-react-components/AlertBadge";
import OperationLink, {
buildOperationUrl,
} from "@site/src/components/openapi/OperationLink";

interface Props {
apiVersion: APIVersion;
tag: string;
}

type EnrichedOperation = OperationWithMeta & {
deprecationState: "deprecated" | "not deprecated";
};

const OperationList = typedList<EnrichedOperation>();

export default function OperationDocCardList(p: Props) {
const spec = useSpec(p.apiVersion);
const operations = getOperationByTag(spec, p.tag).sort(compareOperation);

const cards = operations.map((operation) => {
return (
<OperationDocCard
key={operation.operation.operationId}
apiVersion={p.apiVersion}
operation={operation}
/>
);
});
const operations: EnrichedOperation[] = getOperationByTag(spec, p.tag)
.sort(compareOperation)
.map((o) => ({
...o,
...o.operation,
deprecationState: o.operation.deprecated
? "deprecated"
: "not deprecated",
}));

return (
<ColumnLayout s={[1]} l={[1, 1]}>
{cards}
</ColumnLayout>
<OperationList.List batchSize={100}>
<OperationList.StaticData data={operations} />
<OperationList.Search autoSubmit />
<OperationList.Sorting property="method" name="Method" />
<OperationList.Sorting property="path" name="Path" defaultEnabled />
<OperationList.Filter property="method" mode="some" name="Method" />
<OperationList.Filter
property="deprecationState"
mode="some"
name="Deprecation"
defaultSelected={["not deprecated"]}
/>
<OperationList.Item
href={(op) => buildOperationUrl(p.apiVersion, op.operation)}
>
{(op) => (
<OperationList.ItemView>
<Avatar
className={clsx(styles.method, styles[`method-${op.method}`])}
>
{op.method}
</Avatar>
<Heading>
{op.operation.summary}
{op.operation.deprecated && (
<AlertBadge status="warning">deprecated</AlertBadge>
)}
</Heading>
<Text>{op.path}</Text>
</OperationList.ItemView>
)}
</OperationList.Item>
</OperationList.List>
);
}
27 changes: 27 additions & 0 deletions src/components/openapi/OperationLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { APIVersion, OperationWithMeta } from "@site/src/openapi/specs";
import { PropsWithChildren } from "react";
import buildDocumentId from "@site/src/openapi/buildDocumentId";
import Link from "@docusaurus/Link";
import { OpenAPIV3 } from "openapi-types";

type Props = PropsWithChildren<{
apiVersion: APIVersion;
operation: OperationWithMeta;
}>;

export const buildOperationUrl = (
apiVersion: APIVersion,
operation: OpenAPIV3.OperationObject,
) => {
const docId = buildDocumentId(operation);
return apiVersion.endsWith("-preview")
? `/docs/${apiVersion.replace("-preview", "")}/preview/${docId.replace("reference/", "")}`
: `/docs/${apiVersion}/reference/${docId.replace("reference/", "")}`;
};

export default function OperationLink(p: Props) {
const { apiVersion } = p;
const { operation } = p.operation;
const url = buildOperationUrl(apiVersion, operation);
return <Link to={url}>{p.children}</Link>;
}

0 comments on commit 1367402

Please sign in to comment.