feat(ui): Make timeline items more compact

#500
This commit is contained in:
FoxxMD
2026-07-14 15:23:37 +00:00
parent a9d91c2c8a
commit 41ea9e0aa7
5 changed files with 54 additions and 27 deletions
+18 -18
View File
@@ -1,4 +1,4 @@
import type { Collapsible} from '@chakra-ui/react';
import type { Collapsible, IconProps} from '@chakra-ui/react';
import { Card, Icon, SkeletonCircle, SkeletonText, Span, Tabs, Timeline, type HTMLChakraProps } from '@chakra-ui/react';
import type { Dayjs } from "dayjs";
import dayjs from "dayjs";
@@ -12,7 +12,7 @@ import { CLIENT_DEAD_QUEUE, CLIENT_INGRESS_QUEUE, QUEUE_STATUS_COMPLETED, QUEUE_
import { sortByNewestDate } from "../../core/PlayUtils";
import { capitalizeWords } from "../../core/StringUtils";
import { shortTodayAwareFormat } from "../../core/TimeUtils";
import { activityTransformHasIssue, timelineTextFormatting } from "../utils/ComponentUtils";
import { activityTransformHasIssue, timelineTextFormatting, timelineIconProps } from "../utils/ComponentUtils";
import { ChakraCodeBlockShort } from "./CodeBlock";
import { ErrorAlert } from "./ErrorAlert";
import { MSErrorBoundary } from "./ErrorBoundary";
@@ -42,7 +42,7 @@ const TimelineLoading = () => (
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<Icon fontSize="lg">
<Icon {...timelineIconProps}>
<SkeletonCircle />
</Icon>
</Timeline.Indicator>
@@ -62,10 +62,10 @@ const QueuedCreatedItem = (props: { dead?: boolean, datetime: string }) => (
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<TimelineIndicatorIconQueued fontSize="lg" />
<TimelineIndicatorIconQueued {...timelineIconProps} />
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
<Timeline.Content>
<Timeline.Title>
<ItemSummaryText>{props.dead ? 'Dead ' : ''}Queued <Muted>at</Muted> {shortTodayAwareFormat(dayjs(props.datetime))}</ItemSummaryText>
</Timeline.Title>
@@ -98,7 +98,7 @@ const NewItem = (props: Pick<ActivityDetailProps, 'collapsibleOpen' | 'activity'
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<Icon fontSize="lg">
<Icon {...timelineIconProps}>
<IoMdCodeDownload />
</Icon>
</Timeline.Indicator>
@@ -157,12 +157,12 @@ const TransformsItem = (props: Pick<ActivityDetailProps, 'activity' | 'collapsib
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<Icon fontSize="lg">
<Icon {...timelineIconProps}>
<BiWrench />
</Icon>
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
<Timeline.Content>
<Timeline.Title>
<MSCollapsible
triggerProps={timelineCollapsibleProps}
@@ -186,12 +186,12 @@ const NoTransformsItem = () => (
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<Icon fontSize="lg">
<Icon {...timelineIconProps}>
<BiWrench />
</Icon>
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
<Timeline.Content>
<Timeline.Title >
<ItemSummaryText>Play <Muted>was</Muted> not transformed <Muted>because no</Muted> Transform Rules <Muted> were used/configured.</Muted></ItemSummaryText>
</Timeline.Title>
@@ -210,12 +210,12 @@ const ScrobbleMatchItem = (props: Pick<ActivityDetailProps, 'collapsibleOpen'> &
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<Icon fontSize="lg" color={`${match.match ? 'orange' : 'green'}.focusRing`}>
<Icon {...timelineIconProps} color={`${match.match ? 'orange' : 'green'}.focusRing`}>
<HiMiniMagnifyingGlass />
</Icon>
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
<Timeline.Content>
<Timeline.Title>
<MSCollapsible
triggerProps={timelineCollapsibleProps}
@@ -268,13 +268,13 @@ const ScrobbleResponseItem = (props: Pick<ActivityDetailProps, 'collapsibleOpen'
<Timeline.Separator />
<Timeline.Indicator>
{error !== undefined ? <TimelineErrorIcon /> : (
<Icon fontSize="lg" {...scrobbleIconProps}>
<Icon {...timelineIconProps} {...scrobbleIconProps}>
<TbDatabaseEdit />
</Icon>
)}
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
<Timeline.Content >
<Timeline.Title>
<MSCollapsible
triggerProps={timelineCollapsibleProps}
@@ -305,7 +305,7 @@ const QueueTimelineItem = (props: {queueState: QueueStateApi, collapsibleOpen: b
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<TimelineIndicatorIconQueued fontSize="lg"/>
<TimelineIndicatorIconQueued {...timelineIconProps}/>
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
@@ -323,7 +323,7 @@ const QueueTimelineItem = (props: {queueState: QueueStateApi, collapsibleOpen: b
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<CheckIcon fontSize="lg"/>
<CheckIcon {...timelineIconProps}/>
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
@@ -356,10 +356,10 @@ const QueueTimelineItem = (props: {queueState: QueueStateApi, collapsibleOpen: b
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<CheckIcon fontSize="lg"/>
<CheckIcon {...timelineIconProps}/>
</Timeline.Indicator>
</Timeline.Connector>
<Timeline.Content gap="4">
<Timeline.Content >
<Timeline.Title>
{titleContent}
</Timeline.Title>
+10 -2
View File
@@ -20,7 +20,15 @@ export interface MSCollapsibleExternalProps {
export const timelineCollapsibleProps = {
indicatorProps: { paddingBottom: '4px' },
triggerProps: { paddingBlockStart: "0.3em" }
triggerProps: { paddingBlockStart: "0.3em" },
triggerPropsClosed: {
//paddingBlockStart: "0.3em",
paddingBlock: 'initial'
},
triggerPropsOpen: {
paddingBlock: 'initial',
paddingBlockEnd: "var(--chakra-spacing-3)"
}
}
export type MSCollapsibleProps = PropsWithChildren<ComponentProps<typeof Collapsible.Root>> & MSCollapsibleInternalProps;
@@ -104,7 +112,7 @@ export const MSCollapsible = (props: MSCollapsibleProps) => {
iProps.display = 'none';
}
const tProps = { ...(timeline ? timelineCollapsibleProps.triggerProps : {}), ...triggerProps }
const tProps = { ...(timeline ? (open? timelineCollapsibleProps.triggerPropsOpen : timelineCollapsibleProps.triggerPropsClosed) : {}), ...triggerProps }
return (
<Collapsible.Root open={open} onOpenChange={(val) => setOpen(val.open)} flexGrow="1" disabled={isDisabled} {...rest}>
+16 -1
View File
@@ -1,6 +1,7 @@
"use client"
import { ChakraProvider, createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
import { ChakraProvider, createSystem, defaultConfig, defineConfig, defineSlotRecipe } from "@chakra-ui/react"
import { timelineAnatomy } from "@chakra-ui/react/anatomy";
import {
QueryClient,
QueryClientProvider
@@ -11,6 +12,15 @@ import {
type ColorModeProviderProps,
} from "./Color-Mode"
const timelineSlotRecipe = defineSlotRecipe({
slots: timelineAnatomy.keys(),
base: {
item: {
"--timeline-content-gap": "spacing.5" // was spacing.6
}
}
});
const queryClient = new QueryClient()
const customConfig = defineConfig({
@@ -37,6 +47,11 @@ const customConfig = defineConfig({
color: "gray.500"
}
},
theme: {
slotRecipes: {
timeline: timelineSlotRecipe
}
}
})
export const system = createSystem(defaultConfig, customConfig)
+5 -5
View File
@@ -1,10 +1,10 @@
import { Heading, Icon, Span, Stack, Text, Timeline } from '@chakra-ui/react';
import { Heading, Icon, Span, Stack, Text, Timeline} from '@chakra-ui/react';
import React, { Fragment, useMemo } from "react";
import { BsExclamationTriangle, BsSkipForward, BsStoplights } from "react-icons/bs";
import { MdMusicNote } from "react-icons/md";
import type {JsonPlayObject, LifecycleStep} from "../../core/Atomic";
import { patchObject } from "../../core/DataUtils";
import { timelineTextFormatting } from "../utils/ComponentUtils";
import { timelineIconProps, timelineTextFormatting } from "../utils/ComponentUtils";
import { ChakraCodeBlockShort } from "./CodeBlock";
import { ErrorAlert } from "./ErrorAlert";
import { MSCollapsible, type MSCollapsibleExternalProps } from "./MSCollapsible";
@@ -84,7 +84,7 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => {
const [diffs, finalPlay] = useMemo(() => diffElements(original, steps), [steps, original]);
return (
<Timeline.Root variant="subtle" css={{ "--timeline-separator-display": 'block' }}>
<Timeline.Root variant="subtle" size="lg" css={{ "--timeline-separator-display": 'block' }}>
{steps.map((x, index) => {
const {
patch,
@@ -137,7 +137,7 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => {
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<Icon fontSize="lg" {...iconProps}>
<Icon {...timelineIconProps} {...iconProps}>
{timelineIcon}
</Icon>
</Timeline.Indicator>
@@ -175,7 +175,7 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => {
<Timeline.Connector>
<Timeline.Separator />
<Timeline.Indicator>
<Icon fontSize="lg">
<Icon {...timelineIconProps}>
<MdMusicNote />
</Icon>
</Timeline.Indicator>
+5 -1
View File
@@ -1,4 +1,4 @@
import type { Card} from '@chakra-ui/react';
import type { Card, IconProps} from '@chakra-ui/react';
import type {HTMLChakraProps} from '@chakra-ui/react';
import type {PlayApiCommonDetailed} from '../../core/Api';
import { type LifecycleStep, QUEUE_STATUS_COMPLETED, QUEUE_STATUS_FAILED } from '../../core/Atomic';
@@ -13,6 +13,10 @@ export const timelineTextFormatting: HTMLChakraProps<"span"> = {
textWrap: "balance"
}
export const timelineIconProps: IconProps = {
fontSize: 'md'
}
export const activityTransformHasIssue = (steps: LifecycleStep[]): 'warn' | 'error' | undefined => {
for(const step of steps) {
if(step.flowKnownState === 'prereq') {