From 4230674c2cff2252fb136402d10e52bfa49fd3b5 Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Wed, 10 Jun 2026 17:36:53 +0000 Subject: [PATCH] some ui fixes --- src/client/components/ActivityTimeline.tsx | 8 ++- src/client/components/TransformSteps.tsx | 8 ++- .../components/playActivity/PlayList.tsx | 2 +- src/stories/ActivityTimeline.stories.tsx | 59 +++++++++++++++---- src/stories/List.stories.tsx | 21 +++++-- 5 files changed, 75 insertions(+), 23 deletions(-) diff --git a/src/client/components/ActivityTimeline.tsx b/src/client/components/ActivityTimeline.tsx index b358ec50..fe4a3cea 100644 --- a/src/client/components/ActivityTimeline.tsx +++ b/src/client/components/ActivityTimeline.tsx @@ -24,14 +24,16 @@ import { PlayApiCommonDetailed } from "../../core/Api"; export interface ActivityDetailProps { activity: PlayApiCommonDetailed - collapsibleOpen?: boolean + collapsibleOpen?: boolean, + componentType?: 'source' | 'client' } export const ActivityTimeline = (props: ActivityDetailProps) => { const { activity:{ play, - input + input, + seenAt } = {}, collapsibleOpen } = props; @@ -86,7 +88,7 @@ export const ActivityTimeline = (props: ActivityDetailProps) => { - Discovered new (Play) activity from {capitalize(source)} at {shortTodayAwareFormat(dayjs(playDate))} + Discovered new (Play) activity from {capitalize(source)} at {shortTodayAwareFormat(dayjs(seenAt))} } defaultOpen={collapsibleOpen} timeline diff --git a/src/client/components/TransformSteps.tsx b/src/client/components/TransformSteps.tsx index 5e81aabd..b0c5015c 100644 --- a/src/client/components/TransformSteps.tsx +++ b/src/client/components/TransformSteps.tsx @@ -95,7 +95,9 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => { flowKnownState, flowReason, flowResult, - name + stageName, + stageType, + hook } = x; let timelineIcon: React.JSX.Element, @@ -107,7 +109,7 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => { iconProps = flowResult === 'continue' ? {color: "green.focusRing"} : {color: "red.focusRing"}; summary = was completed{flowResult === 'stop' ? and stopped due to onSuccess condition : null}; if(patch === undefined) { - summary = {summary}with no change to Play; + summary = {summary} with no change to Play; } } else { if(flowKnownState === 'skip') { @@ -144,7 +146,7 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => { {name} with {source} {summary}} + indicator={Stage {stageType}-{stageName} in Hook {hook} from {source} {summary}} defaultOpen={collapsibleOpen} disableUntil="md" timeline> diff --git a/src/client/components/playActivity/PlayList.tsx b/src/client/components/playActivity/PlayList.tsx index 1f23bcd5..4da4470c 100644 --- a/src/client/components/playActivity/PlayList.tsx +++ b/src/client/components/playActivity/PlayList.tsx @@ -273,7 +273,7 @@ const VirtualizedAccordian = (props: { data: PlayApiCommon[] }) => { paddingInline: "var(--accordion-padding-x)" }} justify="flex-start" alignItems="flex-end"> - {activity.status === 'error' ? + {activity.state === 'failed' ? : null} diff --git a/src/stories/ActivityTimeline.stories.tsx b/src/stories/ActivityTimeline.stories.tsx index 5e903fcc..891a3e7c 100644 --- a/src/stories/ActivityTimeline.stories.tsx +++ b/src/stories/ActivityTimeline.stories.tsx @@ -10,6 +10,9 @@ import { generatePlayApiCommonDetailed } from "../core/tests/utils/apiFixtures.j import { generatePlayWithLifecycle, playWithLifecycleScrobble } from "../core/tests/utils/fixtures.js"; import { asJsonPlayObject } from '../core/PlayMarshalUtils.js'; +type PropsAndCustomArgs = React.ComponentProps & { + componentType: 'source' | 'client' +}; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = preview.meta({ title: 'Examples/ActivityTimline', @@ -22,9 +25,18 @@ const meta = preview.meta({ tags: ['autodocs'], // More on argTypes: https://storybook.js.org/docs/api/argtypes args: { - activity: generatePlayApiCommonDetailed() + activity: generatePlayApiCommonDetailed(), + //componentType: 'source' }, - render: function Render(args, { loaded: { activity } }) { return () }, + argTypes: { + componentType: { + control: { type: 'select' }, + options: ['source', 'client'], + } + }, + render: function Render(args, { loaded: { activity } }) { + return () + }, decorators: [ (Story) => (), ] @@ -34,7 +46,7 @@ decorators: [ // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args export const ActivityTimelineStory = meta.story({ loaders: [ - async () => { + async (ctx) => { const scrobbleError = asJsonPlayObject(await playWithLifecycleScrobble(generatePlayWithLifecycle( { lifecycleSteps: { @@ -44,10 +56,12 @@ export const ActivityTimelineStory = meta.story({ } ))); - return {activity: generatePlayApiCommonDetailed({ + return { + activity: generatePlayApiCommonDetailed({ playOpts: [{play: scrobbleError}], inputOpts: [{play: scrobbleError}] - })}; + }), + }; } ], }); @@ -56,8 +70,13 @@ export const ScrobbleError = meta.story({ loaders: [ async () => { const scrobbleError = asJsonPlayObject(await playWithLifecycleScrobble(generatePlayWithLifecycle(), {error: true})); - return {play: scrobbleError}; + return { + activity: generatePlayApiCommonDetailed({ + playOpts: [{play: scrobbleError}], + inputOpts: [{play: scrobbleError}] + }) } + } ], }); @@ -70,7 +89,12 @@ export const TransformError = meta.story({ postCompare: [false], } })); - return {play: scrobbleError}; + return { + activity: generatePlayApiCommonDetailed({ + playOpts: [{play: scrobbleError}], + inputOpts: [{play: scrobbleError}] + }) + } } ], }); @@ -83,7 +107,12 @@ export const TransformSkip = meta.story({ preCompare: [true, 'skipped', true], } })); - return {play}; + return { + activity: generatePlayApiCommonDetailed({ + playOpts: [{play}], + inputOpts: [{play}] + }) + } } ], }); @@ -96,7 +125,12 @@ export const TransformPrereq = meta.story({ preCompare: [true, 'prereq'], } })); - return {play}; + return { + activity: generatePlayApiCommonDetailed({ + playOpts: [{play}], + inputOpts: [{play}] + }) + } } ], }); @@ -109,7 +143,12 @@ export const TransformStop = meta.story({ preCompare: [true, 'stop'], } })); - return {play}; + return { + activity: generatePlayApiCommonDetailed({ + playOpts: [{play}], + inputOpts: [{play}] + }) + } } ], }); diff --git a/src/stories/List.stories.tsx b/src/stories/List.stories.tsx index 8a46a92e..f64f9a85 100644 --- a/src/stories/List.stories.tsx +++ b/src/stories/List.stories.tsx @@ -11,6 +11,7 @@ import {playWithLifecycleScrobble, generatePlayWithLifecycle} from '../core/test import { generateArray } from "../core/DataUtils.js"; import dayjs from "dayjs"; import { asJsonPlayObject } from "../core/PlayMarshalUtils.js"; +import { generatePlayApiCommon } from "../core/tests/utils/apiFixtures.js"; const stack = "Scrobble Submit Error: Failed to submit to Listenbrainz (listen_type single)\n at ListenbrainzApiClient.submitListen (/app/src/backend/common/vendor/ListenbrainzApiClient.ts:246:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async ListenbrainzScrobbler.doScrobble (/app/src/backend/scrobblers/ListenbrainzScrobbler.ts:87:28)\n at async ListenbrainzScrobbler.scrobble (/app/src/backend/scrobblers/AbstractScrobbleClient.ts:679:28)\n at async ListenbrainzScrobbler.processDeadLetterScrobble (/app/src/backend/scrobblers/AbstractScrobbleClient.ts:920:39)\n at async ListenbrainzScrobbler.processDeadLetterQueue (/app/src/backend/scrobblers/AbstractScrobbleClient.ts:894:43)\n at async PromisePoolExecutor.handler (/app/src/backend/tasks/heartbeatClients.ts:35:21)\n at async PromisePoolExecutor.waitForActiveTaskToFinish (/app/node_modules/@supercharge/promise-pool/dist/promise-pool-executor.js:375:9)\n at async PromisePoolExecutor.waitForProcessingSlot (/app/node_modules/@supercharge/promise-pool/dist/promise-pool-executor.js:368:13)\n at async PromisePoolExecutor.process (/app/node_modules/@supercharge/promise-pool/dist/promise-pool-executor.js:354:13)"; @@ -55,18 +56,26 @@ decorators: [ export const List = meta.story({ loaders: [ async () => { - const queued = normalizePlays(generateArray(7,() => generatePlayWithLifecycle()), {endDate: dayjs()}).map(x => ({play: asJsonPlayObject(x), status: 'queued'})); + const queued = normalizePlays(generateArray(7,() => generatePlayWithLifecycle()), {endDate: dayjs()}).map(x => generatePlayApiCommon({play: asJsonPlayObject(x), state: 'queued'})); - const scrobbled = asJsonPlayObject(await playWithLifecycleScrobble(generatePlayWithLifecycle({lifecycleSteps: {preCompare: [true, 'skipped', true]}}))); - const scrobbleError = asJsonPlayObject(await playWithLifecycleScrobble(generatePlayWithLifecycle(), {error: true})); + const scrobbled = generatePlayApiCommon({ + play: asJsonPlayObject(await playWithLifecycleScrobble(generatePlayWithLifecycle({lifecycleSteps: {preCompare: [true, 'skipped', true]}}))), + state: 'scrobbled' + }); + const scrobbleError = generatePlayApiCommon({ + play: asJsonPlayObject(await playWithLifecycleScrobble(generatePlayWithLifecycle(), {error: true})), + state: 'failed' + }); const promisedScrobbled = generateArray(10,() => playWithLifecycleScrobble(generatePlayWithLifecycle({lifecycleSteps: {preCompare: [true, 'skipped', true]}}))); const promised = await Promise.all(promisedScrobbled); - const yesterdayScrobbled = normalizePlays(promised, {endDate: dayjs().subtract(1, 'd').subtract(100, 'm')}).map((x) => ({play: asJsonPlayObject(x), status: 'scrobbled'})); + const yesterdayScrobbled = normalizePlays(promised, {endDate: dayjs().subtract(1, 'd').subtract(100, 'm')}).map((x) => generatePlayApiCommon({play: asJsonPlayObject(x), state: 'scrobbled'})); return {data: [ ...queued, - {play: scrobbled, status: 'scrobbled'}, - {play: scrobbleError, status: 'error'}, + scrobbled, + scrobbleError, + // {play: scrobbled, status: 'scrobbled'}, + // {play: scrobbleError, status: 'error'}, ...yesterdayScrobbled ]}; } -- 2.51.2