2a1273b683
* Added the new colours to the Tailwind config * Fixed Tsailwind compile errors * WIP Geist working in the app * WIP Storybook * Storybook is working again… ouch * Use Geist mono for CodeMirror * Some find/replace class changes * Resizable colours improved * WIP on primary button * Minor style improvements * Improve the side menu header styling * Improved v2 breadcrumbs * Account side menu tweaks * The page now works with the NavBar and UpgradePrompt * Removed unused import * Refactored the buttons to be dry-er * Removed the breadcrumbs * WIP on nav bar * WIP updating the button styles * Fix for the old test page * Fix for type errors * Removed console.log * Colour change in the resizable handle * New loading bar divider * Removed the design plugin * Creating our own storybook pages * Added some “storybook” pages * Added DetailCell storybook * WIP new animation for the loading page * Added the new loading divider * Fix for the time frame filter having a green border * Style improvements to the new test page * Small style improvements * Improvements to the list pagination components * Nav bar back button improved * Improvements to the run page * Lots of v2 style improvements * Help looks better * Improvements to the regenerate API key modal * More general improvements * Added section titles to our storybook * Added form stories * Fix for missing key prop * Loading bar is working * Fixed button submitting state * Fix for the test button icon * Code bg improved * Improved oauth buttons * Integration page header fix * Various improvements, mainly changing button variants * Segmented control style updates * Added an outline of 3px for the segment control * Fixes for the billing pages * More pricing improvements * Added dialog to storybook * Typography now in storybook * Free usage bar added to storybook * Added inline clode to storybook * Separated menu types into a sub section in storybook * NamedIcon now in storybook * Added page header to storybook * Added pricing callout to storybook * Added radio groups to storybook * Added segmented controllers to storybook * Added shortcuts to storybook * Added switches to storybook * Added toast to storybook * Added tooltips to storybook * Added tree view to storybook * Added usage charts to storybook * Tarted up the environment variables page * Fix for the FreePlanUsage panel bg colours * Added new badge variants * Added the <TaskPath /> to the tasks table * Span header improvements * Started work on the timeline * Started work on the timeline * Fix for the run page header * Timeline tick marks are working * Timeline working * Got the durations showing on hover * Button improvements * Experimenting with how the duration should be shown * Lots of refinements to the timeline * Much nicer API for the Timeline * The switch is now purple to match the design, with inverted thumb when on * Removed old stuff * Export the props * Added the span with duration back in * Simplified more and fixed the span durations * Put in some decent dummy data * Rendering defaults * Wip with the mouse cursor * Improvements to the story * Added Slider primitive * Integrated the icons into the slider * Lots of layout improvements * Cleaned up imports * “Root” indicator * Animated background on partials * Pull the styles through to the spans and log dots * Fixed some bugs in the TreeView when nodes get created or destroyed * Fix for incorrect parentTask reference * Added run streaming endpoint for live refreshing * Added the tabs to Storybook * Fix for status font size mismatch * Fix for the misaligned run filter status * Set a minimum duration on the timeline * The TreeView now re-calculates if the number of nodes has changed * Partials now render to the end * Improved the durations gutter * The duration is calculated using the current time if there are partial events * Added the environment label to storybook * Improved the environment label style * Removed bottom margin from badge * Button style improvements * Callouts style fits the new design better * Got the scrollbars to appear on the tree/timeline * Added scroll support * Synced scrolling working * Close button and exit icon for the detail panel * secure field shows start of env * Clipboard improvements * Latest lockfile * Fix for the durations wrapping --------- Co-authored-by: James Ritchie <james@jamesritchie.co.uk>
159 lines
5.1 KiB
TypeScript
159 lines
5.1 KiB
TypeScript
import { ChevronDownIcon, Square2StackIcon } from "@heroicons/react/24/solid";
|
|
import { AnimatePresence, motion } from "framer-motion";
|
|
import { Fragment, useState } from "react";
|
|
import simplur from "simplur";
|
|
import { Paragraph } from "~/components/primitives/Paragraph";
|
|
import { ViewTask } from "~/presenters/RunPresenter.server";
|
|
import { cn } from "~/utils/cn";
|
|
import {
|
|
RunPanel,
|
|
RunPanelBody,
|
|
RunPanelDescription,
|
|
RunPanelError,
|
|
RunPanelHeader,
|
|
RunPanelIconProperty,
|
|
RunPanelIconSection,
|
|
RunPanelIconTitle,
|
|
RunPanelProperties,
|
|
TaskSeparator,
|
|
UpdatingDelay,
|
|
UpdatingDuration,
|
|
} from "./RunCard";
|
|
import { TaskStatusIcon } from "./TaskStatus";
|
|
import { formatDuration } from "@trigger.dev/core/v3";
|
|
|
|
type TaskCardProps = ViewTask & {
|
|
selectedId?: string;
|
|
selectedTask: (id: string) => void;
|
|
isLast: boolean;
|
|
depth: number;
|
|
};
|
|
|
|
export function TaskCard({
|
|
selectedId,
|
|
selectedTask,
|
|
isLast,
|
|
depth,
|
|
id,
|
|
style,
|
|
status,
|
|
icon,
|
|
name,
|
|
startedAt,
|
|
completedAt,
|
|
description,
|
|
displayKey,
|
|
connection,
|
|
properties,
|
|
subtasks,
|
|
error,
|
|
delayUntil,
|
|
}: TaskCardProps) {
|
|
const [expanded, setExpanded] = useState(false);
|
|
const isSelected = id === selectedId;
|
|
|
|
return (
|
|
<Fragment>
|
|
<div style={{ marginLeft: `${depth}rem` }}>
|
|
<RunPanel selected={isSelected} onClick={() => selectedTask(id)} styleName={style?.style}>
|
|
<RunPanelHeader
|
|
icon={
|
|
status === "COMPLETED" ? (
|
|
icon
|
|
) : (
|
|
<TaskStatusIcon
|
|
status={status}
|
|
minimal={true}
|
|
className={cn("h-5 w-5", !isSelected && "text-charcoal-400")}
|
|
/>
|
|
)
|
|
}
|
|
title={status === "COMPLETED" ? name : <RunPanelIconTitle icon={icon} title={name} />}
|
|
accessory={
|
|
<Paragraph variant="extra-small">
|
|
<UpdatingDuration start={startedAt ?? undefined} end={completedAt ?? undefined} />
|
|
</Paragraph>
|
|
}
|
|
styleName={style?.style}
|
|
/>
|
|
<RunPanelBody>
|
|
{error && <RunPanelError text={error.message} stackTrace={error.stack} />}
|
|
{description && <RunPanelDescription text={description} variant={style?.variant} />}
|
|
<RunPanelIconSection>
|
|
{displayKey && <RunPanelIconProperty icon="key" label="Key" value={displayKey} />}
|
|
{delayUntil && !completedAt && (
|
|
<>
|
|
<UpdatingDelay delayUntil={delayUntil} />
|
|
</>
|
|
)}
|
|
{delayUntil && completedAt && (
|
|
<RunPanelIconProperty
|
|
icon="clock"
|
|
label="Delay duration"
|
|
value={formatDuration(startedAt, delayUntil, {
|
|
style: "long",
|
|
maxDecimalPoints: 0,
|
|
})}
|
|
/>
|
|
)}
|
|
{connection && (
|
|
<RunPanelIconProperty
|
|
icon={
|
|
connection.integration.definition.icon ?? connection.integration.definitionId
|
|
}
|
|
label="Connection"
|
|
value={connection.integration.slug}
|
|
/>
|
|
)}
|
|
</RunPanelIconSection>
|
|
{properties.length > 0 && (
|
|
<RunPanelProperties properties={properties} className="mt-4" />
|
|
)}
|
|
</RunPanelBody>
|
|
{subtasks && subtasks.length > 0 && (
|
|
<button
|
|
className="mt-4 flex h-10 w-full items-center justify-between gap-2 bg-charcoal-800 px-2"
|
|
onClick={() => setExpanded((c) => !c)}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<Square2StackIcon className="h-5 w-5 text-charcoal-400" />
|
|
<Paragraph variant="small">
|
|
{simplur`${expanded ? "Hide" : "Show"} ${subtasks.length} subtask[|s]`}
|
|
</Paragraph>
|
|
</div>
|
|
<motion.span
|
|
initial={expanded ? "expanded" : "collapsed"}
|
|
animate={expanded ? "expanded" : "collapsed"}
|
|
variants={{
|
|
collapsed: { rotate: 0, transition: { ease: "anticipate" } },
|
|
expanded: { rotate: 180, transition: { ease: "anticipate" } },
|
|
}}
|
|
>
|
|
<ChevronDownIcon className={"h-5 w-5 text-charcoal-400 transition"} />
|
|
</motion.span>
|
|
</button>
|
|
)}
|
|
</RunPanel>
|
|
</div>
|
|
{(!isLast || expanded) && <TaskSeparator depth={depth + (expanded ? 1 : 0)} />}
|
|
|
|
{subtasks &&
|
|
subtasks.length > 0 &&
|
|
expanded &&
|
|
subtasks.map((subtask, index) => (
|
|
<AnimatePresence key={subtask.id}>
|
|
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 100 }}>
|
|
<TaskCard
|
|
selectedId={selectedId}
|
|
selectedTask={selectedTask}
|
|
isLast={false}
|
|
depth={depth + 1}
|
|
{...subtask}
|
|
/>
|
|
</motion.div>
|
|
</AnimatePresence>
|
|
))}
|
|
</Fragment>
|
|
);
|
|
}
|