UNPKG

@airplane/views

Version:

A React library for building Airplane views. Views components are optimized in style and functionality to produce internal apps that are easy to build and maintain.

136 lines (135 loc) 4.44 kB
import { jsx, jsxs, Fragment } from "react/jsx-runtime"; import { createStyles } from "@mantine/core"; import { useState } from "react"; import { ComponentErrorBoundary } from "../errorBoundary/ComponentErrorBoundary.js"; import { useSetLatestRunInTaskQuery } from "../errorBoundary/LatestRunDetails.js"; import { Skeleton } from "../Skeleton.js"; import { Stack } from "../stack/Stack.js"; import { Text } from "../text/Text.js"; import { displayTaskBackedError } from "../../errors/displayTaskBackedError.js"; import { useTaskQuery } from "../../state/tasks/useTaskQuery.js"; const useStyles = createStyles((theme) => ({ item: { borderTop: theme.other.borderStyles.light, paddingTop: theme.spacing.md, paddingBottom: theme.spacing.md, "&:first-child": { borderTop: "none", paddingTop: 0 }, "&:last-child": { paddingBottom: 0 } }, term: { fontWeight: 500, color: theme.colors.gray[5], paddingRight: theme.spacing.sm }, description: { paddingLeft: theme.spacing.sm } })); const DescriptionListComponent = ({ items, align = "start", loading, ...restProps }) => { const { classes } = useStyles(); const itemsToRender = loading ? [...Array(4)] : items; return /* @__PURE__ */ jsx(Stack, { ...restProps, spacing: 0, children: itemsToRender.map((item, idx) => /* @__PURE__ */ jsx(Stack, { direction: "row", spacing: 0, className: classes.item, align, children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(Skeleton, { height: 16, mx: 16, width: "33%", radius: "sm" }), /* @__PURE__ */ jsx(Skeleton, { height: 16, mx: 16, width: "33%", radius: "sm" }) ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(Text, { className: classes.term, width: "1/3", children: item.term }), /* @__PURE__ */ jsx(Text, { className: classes.description, width: "2/3", children: item.description }) ] }) }, idx)) }); }; const DescriptionListWithTask = ({ task, outputTransform, setLatestRun, ...restProps }) => { const fullQuery = useSetLatestRunInTaskQuery(task, setLatestRun); const { error, loading, output, runID } = useTaskQuery(fullQuery); const items = output ? outputToItems(output, outputTransform) : []; if (error) { return displayTaskBackedError({ error, taskSlug: fullQuery.slug, runID, componentName: "DescriptionList" }); } else { return /* @__PURE__ */ jsx(DescriptionListComponent, { loading, items, ...restProps }); } }; const DescriptionList = (props) => { const [latestRun, setLatestRun] = useState(); if (doesUseTask(props)) { return /* @__PURE__ */ jsx(ComponentErrorBoundary, { componentName: DescriptionList.displayName, latestRun, children: /* @__PURE__ */ jsx(DescriptionListWithTask, { ...props, setLatestRun }) }); } else { return /* @__PURE__ */ jsx(ComponentErrorBoundary, { componentName: DescriptionList.displayName, children: /* @__PURE__ */ jsx(DescriptionListComponent, { ...props }) }); } }; DescriptionList.displayName = "DescriptionList"; function outputToItems(output, outputTransform) { if (!output) { return []; } const unwrappedOutput = unwrapOutput(output); let items = outputTransform ? outputTransform(unwrappedOutput) : unwrappedOutput; if (items && typeof items === "object" && !Array.isArray(items)) { items = Object.keys(items).map((key) => ({ term: key, description: items[key] })); } if (!validateItems(items)) { throw new Error(`Task output must be type Array<{ term: React.ReactNode; description: React.ReactNode; }>. Got ${JSON.stringify(items)}`); } return items; } function unwrapOutput(data) { if (data && !Array.isArray(data) && typeof data === "object") { const keys = Object.keys(data); if (keys.length === 1) { const value = data[keys[0]]; if (Array.isArray(value)) { return value; } } } return data; } function doesUseTask(props) { return Boolean(props.task); } function validateItems(items) { if (!Array.isArray(items)) return false; return items.every((item) => { if (!item || typeof item !== "object") return false; return "term" in item && "description" in item; }); } export { DescriptionList, DescriptionListComponent, DescriptionListWithTask, useStyles }; //# sourceMappingURL=DescriptionList.js.map