@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
JavaScript
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