@flamingo-stack/openframe-frontend-core 0.0.515 → 0.0.517-1651.4264.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7QYBXWYI.cjs → chunk-2LMIHPQH.cjs} +4 -4
- package/dist/{chunk-7QYBXWYI.cjs.map → chunk-2LMIHPQH.cjs.map} +1 -1
- package/dist/{chunk-U7RF7YXN.js → chunk-45TSVW73.js} +2 -2
- package/dist/{chunk-OUPSNYRI.cjs → chunk-476N4NBC.cjs} +26 -26
- package/dist/{chunk-OUPSNYRI.cjs.map → chunk-476N4NBC.cjs.map} +1 -1
- package/dist/{chunk-WQ4QJWEE.js → chunk-A5WEANTA.js} +2 -2
- package/dist/{chunk-UEIW2ISS.cjs → chunk-ARB3MVHH.cjs} +66 -7
- package/dist/chunk-ARB3MVHH.cjs.map +1 -0
- package/dist/{chunk-MHW4WBMB.js → chunk-CJ55TI4A.js} +4 -4
- package/dist/{chunk-5YX7F5G6.cjs → chunk-CV4IMEEH.cjs} +37 -37
- package/dist/{chunk-5YX7F5G6.cjs.map → chunk-CV4IMEEH.cjs.map} +1 -1
- package/dist/{chunk-7PGYALRK.cjs → chunk-GWS2J3VC.cjs} +31 -31
- package/dist/{chunk-7PGYALRK.cjs.map → chunk-GWS2J3VC.cjs.map} +1 -1
- package/dist/{chunk-J4AL3YOT.js → chunk-GXSKS5RO.js} +2 -2
- package/dist/{chunk-AW66QABG.cjs → chunk-HNWJSFEV.cjs} +3 -3
- package/dist/{chunk-AW66QABG.cjs.map → chunk-HNWJSFEV.cjs.map} +1 -1
- package/dist/{chunk-JT7FFD3R.cjs → chunk-HOPPNUGS.cjs} +5 -5
- package/dist/{chunk-JT7FFD3R.cjs.map → chunk-HOPPNUGS.cjs.map} +1 -1
- package/dist/{chunk-S7YXEFDC.js → chunk-I75L6RSN.js} +2 -2
- package/dist/{chunk-YY4FGIRU.cjs → chunk-J4C4IY2F.cjs} +9 -9
- package/dist/{chunk-YY4FGIRU.cjs.map → chunk-J4C4IY2F.cjs.map} +1 -1
- package/dist/{chunk-5WKVLIP3.js → chunk-J6TFTLXF.js} +2 -2
- package/dist/{chunk-E4IB3CTA.cjs → chunk-KG52CG6Y.cjs} +14 -14
- package/dist/{chunk-E4IB3CTA.cjs.map → chunk-KG52CG6Y.cjs.map} +1 -1
- package/dist/{chunk-RK6YSRIC.cjs → chunk-N2LZPULX.cjs} +11 -11
- package/dist/{chunk-RK6YSRIC.cjs.map → chunk-N2LZPULX.cjs.map} +1 -1
- package/dist/{chunk-XAAF6UPI.js → chunk-O3CJ6IWP.js} +2 -2
- package/dist/{chunk-MTII5NXM.js → chunk-OCNHD5XM.js} +6 -6
- package/dist/{chunk-Y4LJ52RB.js → chunk-QRAGH5CS.js} +2 -2
- package/dist/{chunk-QHTFPOEL.cjs → chunk-R7JZC5RX.cjs} +7 -7
- package/dist/{chunk-QHTFPOEL.cjs.map → chunk-R7JZC5RX.cjs.map} +1 -1
- package/dist/{chunk-C646ZLOV.cjs → chunk-SXWPJHP7.cjs} +26 -26
- package/dist/{chunk-C646ZLOV.cjs.map → chunk-SXWPJHP7.cjs.map} +1 -1
- package/dist/{chunk-LBIWRR75.cjs → chunk-U5ZE22FV.cjs} +61 -61
- package/dist/{chunk-LBIWRR75.cjs.map → chunk-U5ZE22FV.cjs.map} +1 -1
- package/dist/{chunk-P57FCOI6.js → chunk-UL7QF323.js} +2 -2
- package/dist/{chunk-NVMRBO7R.js → chunk-V6FISTDB.js} +2 -2
- package/dist/{chunk-IA4USSHI.js → chunk-VGK6CXYG.js} +5 -5
- package/dist/{chunk-B6YOWMZF.cjs → chunk-VSUGMXAV.cjs} +87 -87
- package/dist/{chunk-B6YOWMZF.cjs.map → chunk-VSUGMXAV.cjs.map} +1 -1
- package/dist/{chunk-5RHFQ4JG.js → chunk-VXMKRJYN.js} +65 -6
- package/dist/{chunk-5RHFQ4JG.js.map → chunk-VXMKRJYN.js.map} +1 -1
- package/dist/{chunk-XM5DPWKV.js → chunk-YXF4JKKQ.js} +4 -4
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/floating-walkthrough-video.d.ts.map +1 -1
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +136 -132
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +15 -11
- package/dist/components/index.js.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +34 -34
- package/dist/components/meeting-scheduler/index.js +3 -3
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/index.cjs +6 -2
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.js +5 -1
- package/dist/components/ui/test-run.d.ts +13 -0
- package/dist/components/ui/test-run.d.ts.map +1 -1
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -1
- package/package.json +1 -1
- package/src/components/features/floating-walkthrough-video.tsx +42 -6
- package/src/components/ui/test-run.tsx +59 -6
- package/src/stories/TestRun.stories.tsx +20 -2
- package/dist/chunk-UEIW2ISS.cjs.map +0 -1
- /package/dist/{chunk-U7RF7YXN.js.map → chunk-45TSVW73.js.map} +0 -0
- /package/dist/{chunk-WQ4QJWEE.js.map → chunk-A5WEANTA.js.map} +0 -0
- /package/dist/{chunk-MHW4WBMB.js.map → chunk-CJ55TI4A.js.map} +0 -0
- /package/dist/{chunk-J4AL3YOT.js.map → chunk-GXSKS5RO.js.map} +0 -0
- /package/dist/{chunk-S7YXEFDC.js.map → chunk-I75L6RSN.js.map} +0 -0
- /package/dist/{chunk-5WKVLIP3.js.map → chunk-J6TFTLXF.js.map} +0 -0
- /package/dist/{chunk-XAAF6UPI.js.map → chunk-O3CJ6IWP.js.map} +0 -0
- /package/dist/{chunk-MTII5NXM.js.map → chunk-OCNHD5XM.js.map} +0 -0
- /package/dist/{chunk-Y4LJ52RB.js.map → chunk-QRAGH5CS.js.map} +0 -0
- /package/dist/{chunk-P57FCOI6.js.map → chunk-UL7QF323.js.map} +0 -0
- /package/dist/{chunk-NVMRBO7R.js.map → chunk-V6FISTDB.js.map} +0 -0
- /package/dist/{chunk-IA4USSHI.js.map → chunk-VGK6CXYG.js.map} +0 -0
- /package/dist/{chunk-XM5DPWKV.js.map → chunk-YXF4JKKQ.js.map} +0 -0
|
@@ -698,7 +698,22 @@ export function FloatingWalkthroughVideo({
|
|
|
698
698
|
// receives pointer events — the media layer is pointer-events-none, so
|
|
699
699
|
// a group inside it can never match :hover.
|
|
700
700
|
'group/card pointer-events-auto relative overflow-hidden rounded-lg border border-ods-border bg-ods-card shadow-2xl',
|
|
701
|
-
|
|
701
|
+
// MOBILE = PiP dimensions, not a shrunken desktop card. This is an
|
|
702
|
+
// UNINVITED overlay on the smallest screens, so it is sized against
|
|
703
|
+
// the corner-PiP conventions, NOT against system PiP (which is
|
|
704
|
+
// user-invoked content and is allowed ~60% of the shortest edge):
|
|
705
|
+
// - AOSP's legacy corner spec asks for 23% of screen width, then
|
|
706
|
+
// clamps up to `default_minimal_size_pip_resizable_task` (108dp in
|
|
707
|
+
// BOTH dimensions) — at 16:9 that floor IS 192x108, and on any
|
|
708
|
+
// modern phone the clamp is what actually applies. Hence the cap.
|
|
709
|
+
// - 192x108 lands at ~6% of a 390x844 screen, inside the "small
|
|
710
|
+
// player" band (<=20% of screen) rather than the "large" one.
|
|
711
|
+
// 52vw keeps it proportional on narrow devices (320px -> 166x93) and
|
|
712
|
+
// the 192px cap takes over from ~369px up, i.e. on most phones.
|
|
713
|
+
// Do NOT go below ~150px: the corner chrome (32px transport pair +
|
|
714
|
+
// 32px dismiss + the title pill) stops fitting, and the card's own
|
|
715
|
+
// controls — not the poster — are what set the real floor here.
|
|
716
|
+
'aspect-video w-[min(52vw,192px)] sm:w-80 transition-opacity duration-200',
|
|
702
717
|
footerHidden ? 'opacity-0 pointer-events-none' : 'opacity-100',
|
|
703
718
|
className,
|
|
704
719
|
)}
|
|
@@ -754,7 +769,9 @@ export function FloatingWalkthroughVideo({
|
|
|
754
769
|
isClone={false}
|
|
755
770
|
badge="play"
|
|
756
771
|
fit="cover"
|
|
757
|
-
|
|
772
|
+
// Mirrors the card's own responsive width above — a flat 320px hint
|
|
773
|
+
// made every phone fetch a poster ~1.7x wider than the box.
|
|
774
|
+
posterSizes="(max-width: 639px) 192px, 320px"
|
|
758
775
|
preload="none"
|
|
759
776
|
hideMutedBadge
|
|
760
777
|
onMutedFallbackChange={onCardFallbackChange}
|
|
@@ -804,7 +821,19 @@ export function FloatingWalkthroughVideo({
|
|
|
804
821
|
unmounts and the same click lands on the hit layer and opens the
|
|
805
822
|
theater. `size="icon-glyph"` keeps the glyph at its own 56px instead
|
|
806
823
|
of the DS default `[&_svg]:h-5`; `variant="glyph"` means no button
|
|
807
|
-
surface paints behind a glyph that already carries its own scrim.
|
|
824
|
+
surface paints behind a glyph that already carries its own scrim.
|
|
825
|
+
|
|
826
|
+
BELOW `sm` IT IS NOT RENDERED — see the corner mute button's
|
|
827
|
+
mirrored `sm:hidden` below; the two form ONE breakpoint switch and
|
|
828
|
+
must always be edited together. At the mobile PiP height (~108px)
|
|
829
|
+
the 56px glyph physically cannot clear both the 32px transport band
|
|
830
|
+
and the title pill: the three need ~124px of vertical stack, which
|
|
831
|
+
16:9 does not give back until the card is ~224px wide — i.e. barely
|
|
832
|
+
smaller than the oversized card this sizing exists to fix. Nothing
|
|
833
|
+
is lost, because the ONLY state that shows this glyph is resume mode
|
|
834
|
+
(`cardMode !== 'poster'`), and resume mode always mounts the corner
|
|
835
|
+
transport pair, which offers the same play AND unmute actions at
|
|
836
|
+
32px — above the 24px WCAG 2.5.8 (AA) target floor. */}
|
|
808
837
|
{showBigUnmute && (
|
|
809
838
|
<Button
|
|
810
839
|
variant="glyph"
|
|
@@ -813,7 +842,7 @@ export function FloatingWalkthroughVideo({
|
|
|
813
842
|
title={controlIsPlay ? 'Play' : 'Unmute'}
|
|
814
843
|
onPointerDown={e => e.stopPropagation()}
|
|
815
844
|
onClick={onUnmuteOrPlay}
|
|
816
|
-
className="absolute inset-0 z-30 m-auto"
|
|
845
|
+
className="absolute inset-0 z-30 m-auto hidden sm:inline-flex"
|
|
817
846
|
>
|
|
818
847
|
{controlIsPlay ? <VideoPlayBadge /> : <VideoUnmuteGlyph />}
|
|
819
848
|
</Button>
|
|
@@ -827,7 +856,14 @@ export function FloatingWalkthroughVideo({
|
|
|
827
856
|
{showPlaybackControls && (
|
|
828
857
|
<div className="absolute left-[var(--spacing-system-xsf)] top-[var(--spacing-system-xsf)] z-30 flex items-center gap-[var(--spacing-system-xxs)]">
|
|
829
858
|
{/* Hidden while the big centre glyph owns unmuting, so the two are
|
|
830
|
-
never on screen with the same label and different behaviour
|
|
859
|
+
never on screen with the same label and different behaviour —
|
|
860
|
+
but ONLY from `sm` up, because below `sm` that glyph is not
|
|
861
|
+
rendered at all (see its comment above). `sm:hidden`, not
|
|
862
|
+
`hidden`: a plain `hidden` here would combine with the glyph's
|
|
863
|
+
own `hidden sm:inline-flex` to leave the mobile card with NO
|
|
864
|
+
unmute affordance whatsoever — precisely the self-hiding dead
|
|
865
|
+
end called out in the state-model note at the top of this file.
|
|
866
|
+
These two classNames are ONE switch; never change one alone. */}
|
|
831
867
|
<Button
|
|
832
868
|
variant="overlay"
|
|
833
869
|
size="icon-sm"
|
|
@@ -835,7 +871,7 @@ export function FloatingWalkthroughVideo({
|
|
|
835
871
|
title={cardMuted ? 'Unmute' : 'Mute'}
|
|
836
872
|
onPointerDown={e => e.stopPropagation()}
|
|
837
873
|
onClick={onToggleMute}
|
|
838
|
-
className={cn(showBigUnmute && !controlIsPlay && 'hidden')}
|
|
874
|
+
className={cn(showBigUnmute && !controlIsPlay && 'sm:hidden')}
|
|
839
875
|
>
|
|
840
876
|
{cardMuted ? <VolumeXmarkIcon /> : <VolumeUpIcon />}
|
|
841
877
|
</Button>
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import type { ColumnDef, Row } from '@tanstack/react-table'
|
|
4
4
|
import * as React from 'react'
|
|
5
|
-
import { SearchIcon } from '../icons-v2-generated'
|
|
5
|
+
import { Copy02Icon, SearchIcon } from '../icons-v2-generated'
|
|
6
|
+
import { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard'
|
|
6
7
|
import { cn } from '../../utils/cn'
|
|
7
8
|
import { formatTime } from '../../utils/format-date'
|
|
8
9
|
import { DataTable } from './data-table'
|
|
@@ -10,6 +11,7 @@ import { useDataTable } from './data-table/use-data-table'
|
|
|
10
11
|
import { NoData } from './no-data'
|
|
11
12
|
import type { QueryResultRow } from './query-report-table'
|
|
12
13
|
import { ScrollShadow } from './scroll-fade'
|
|
14
|
+
import { Tag } from './tag'
|
|
13
15
|
|
|
14
16
|
/*
|
|
15
17
|
* Live test-run building blocks: the UI (timing stats, one-row skeleton,
|
|
@@ -129,15 +131,37 @@ export interface TestRunResultsProps {
|
|
|
129
131
|
className?: string
|
|
130
132
|
}
|
|
131
133
|
|
|
134
|
+
/** Red error banner with a copy-to-clipboard action, per the test-run design. */
|
|
135
|
+
export function TestRunErrorBanner({ error, className }: { error: string; className?: string }) {
|
|
136
|
+
const { copy } = useCopyToClipboard({ successDescription: 'Error message copied to clipboard' })
|
|
137
|
+
return (
|
|
138
|
+
<div
|
|
139
|
+
role="alert"
|
|
140
|
+
className={cn(
|
|
141
|
+
'flex items-center justify-between gap-[var(--spacing-system-s)]',
|
|
142
|
+
'rounded-[6px] border border-ods-error bg-ods-error-secondary',
|
|
143
|
+
'px-[var(--spacing-system-mf)] py-[var(--spacing-system-s)]',
|
|
144
|
+
className,
|
|
145
|
+
)}
|
|
146
|
+
>
|
|
147
|
+
<p className="text-h4 text-ods-error min-w-0 break-words">{error}</p>
|
|
148
|
+
<button
|
|
149
|
+
type="button"
|
|
150
|
+
aria-label="Copy error message"
|
|
151
|
+
onClick={() => copy(error)}
|
|
152
|
+
className="shrink-0 text-ods-error hover:opacity-80 transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus rounded-sm"
|
|
153
|
+
>
|
|
154
|
+
<Copy02Icon className="size-5" />
|
|
155
|
+
</button>
|
|
156
|
+
</div>
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
132
160
|
/** Error line + empty state + result table for a finished/running test run. */
|
|
133
161
|
export function TestRunResults({ isActive, displayRows, firstError, className }: TestRunResultsProps) {
|
|
134
162
|
return (
|
|
135
163
|
<div className={cn('flex flex-col gap-[var(--spacing-system-xsf)]', className)}>
|
|
136
|
-
{firstError &&
|
|
137
|
-
<p role="alert" className="text-h6 text-ods-error">
|
|
138
|
-
{firstError}
|
|
139
|
-
</p>
|
|
140
|
-
)}
|
|
164
|
+
{firstError && <TestRunErrorBanner error={firstError} />}
|
|
141
165
|
{!isActive && displayRows.length === 0 ? (
|
|
142
166
|
// With zero rows the error line alone explains the outcome; a
|
|
143
167
|
// "No results returned" empty state next to it would mislead.
|
|
@@ -164,6 +188,30 @@ export function TimingStat({ value, label, className }: { value: string; label:
|
|
|
164
188
|
)
|
|
165
189
|
}
|
|
166
190
|
|
|
191
|
+
/** Overall run outcome shown in a test-run controls row. */
|
|
192
|
+
export type TestRunStatus = 'idle' | 'running' | 'success' | 'error'
|
|
193
|
+
|
|
194
|
+
const TEST_RUN_STATUS_TAGS: Record<Exclude<TestRunStatus, 'idle'>, { label: string; variant: 'warning' | 'success' | 'error' }> = {
|
|
195
|
+
running: { label: 'IN PROCESS', variant: 'warning' },
|
|
196
|
+
success: { label: 'SUCCESS', variant: 'success' },
|
|
197
|
+
error: { label: 'ERROR', variant: 'error' },
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Status stat cell: "-" before the first run, then a colored state tag. */
|
|
201
|
+
export function TestRunStatusStat({ status, className }: { status: TestRunStatus; className?: string }) {
|
|
202
|
+
const tag = status === 'idle' ? null : TEST_RUN_STATUS_TAGS[status]
|
|
203
|
+
return (
|
|
204
|
+
<div className={cn('flex flex-col justify-center items-start min-w-0 gap-[var(--spacing-system-xxs)]', className)}>
|
|
205
|
+
{tag ? (
|
|
206
|
+
<Tag label={tag.label} variant={tag.variant} className="pointer-events-none" />
|
|
207
|
+
) : (
|
|
208
|
+
<span className="text-h4 text-ods-text-secondary truncate">-</span>
|
|
209
|
+
)}
|
|
210
|
+
<span className="text-h6 text-ods-text-secondary truncate">Status</span>
|
|
211
|
+
</div>
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
167
215
|
/**
|
|
168
216
|
* The transport-side contract `useTestRunState` observes. Matches the shape
|
|
169
217
|
* of a live-campaign hook (e.g. Fleet live queries in OpenFrame) without
|
|
@@ -248,6 +296,10 @@ export function useTestRunState(campaign: TestRunCampaignState) {
|
|
|
248
296
|
|
|
249
297
|
const firstError = isFinished && campaign.errors.length > 0 ? campaign.errors[0].error : null
|
|
250
298
|
|
|
299
|
+
// Overall run outcome for the Status stat: '-' until a run starts, then
|
|
300
|
+
// IN PROCESS while active, and SUCCESS/ERROR once the campaign finishes.
|
|
301
|
+
const status: TestRunStatus = isActive ? 'running' : hasRun && isFinished ? (firstError ? 'error' : 'success') : 'idle'
|
|
302
|
+
|
|
251
303
|
// Started/Duration show zeros until the current run's timing is real:
|
|
252
304
|
// hasRun=false after a reset, and campaignStatus resets while the next
|
|
253
305
|
// run is being created, so stale values never linger on screen.
|
|
@@ -271,6 +323,7 @@ export function useTestRunState(campaign: TestRunCampaignState) {
|
|
|
271
323
|
isActive,
|
|
272
324
|
isFinished,
|
|
273
325
|
showResults,
|
|
326
|
+
status,
|
|
274
327
|
firstError,
|
|
275
328
|
startedLabel,
|
|
276
329
|
durationLabel,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
|
2
|
-
import { TestResultsSkeleton, TestRunResults, TimingStat } from '../components/ui/test-run';
|
|
2
|
+
import { TestResultsSkeleton, TestRunResults, TestRunStatusStat, TimingStat } from '../components/ui/test-run';
|
|
3
3
|
|
|
4
4
|
const meta = {
|
|
5
5
|
title: 'UI/TestRun',
|
|
@@ -85,7 +85,7 @@ export const EmptyResult: Story = {
|
|
|
85
85
|
),
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
/** Finished with an error:
|
|
88
|
+
/** Finished with an error: red banner with a copy action replaces the empty state. */
|
|
89
89
|
export const WithError: Story = {
|
|
90
90
|
args: {
|
|
91
91
|
isActive: false,
|
|
@@ -111,8 +111,26 @@ export const TimingAndSkeleton: Story = {
|
|
|
111
111
|
<div className="flex items-center gap-[var(--spacing-system-m)]">
|
|
112
112
|
<TimingStat value="02:15 PM" label="Started" className="flex-1" />
|
|
113
113
|
<TimingStat value="00:00:05" label="Duration" className="flex-1" />
|
|
114
|
+
<TestRunStatusStat status="running" className="flex-1" />
|
|
114
115
|
</div>
|
|
115
116
|
<TestResultsSkeleton />
|
|
116
117
|
</div>
|
|
117
118
|
),
|
|
118
119
|
};
|
|
120
|
+
|
|
121
|
+
/** The four Status stat states: "-" before a run, then a colored tag. */
|
|
122
|
+
export const StatusStates: Story = {
|
|
123
|
+
args: {
|
|
124
|
+
isActive: false,
|
|
125
|
+
displayRows: [],
|
|
126
|
+
firstError: null,
|
|
127
|
+
},
|
|
128
|
+
render: () => (
|
|
129
|
+
<div className="flex max-w-[720px] items-center gap-[var(--spacing-system-l)] bg-ods-bg p-[var(--spacing-system-mf)]">
|
|
130
|
+
<TestRunStatusStat status="idle" />
|
|
131
|
+
<TestRunStatusStat status="running" />
|
|
132
|
+
<TestRunStatusStat status="success" />
|
|
133
|
+
<TestRunStatusStat status="error" />
|
|
134
|
+
</div>
|
|
135
|
+
),
|
|
136
|
+
};
|