Skip to content

Commit

Permalink
refactor(run): [results] use extracted drawer dialog for preview
Browse files Browse the repository at this point in the history
Signed-off-by: Danil Kostromin <[email protected]>
  • Loading branch information
okt-limonikas committed Nov 28, 2024
1 parent 93ba14b commit 01f6c5d
Showing 1 changed file with 13 additions and 197 deletions.
210 changes: 13 additions & 197 deletions libs/bublik/features/result-links/src/lib/result-links.container.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,17 @@
/* SPDX-License-Identifier: Apache-2.0 */
/* SPDX-FileCopyrightText: 2021-2023 OKTET Labs Ltd. */
import { useCallback, useState } from 'react';
import { Link } from 'react-router-dom';

import {
HistoryMode,
RunDataResults,
RunDetailsAPIResponse
} from '@/shared/types';
import {
getErrorMessage,
useGetLogJsonQuery,
useGetRunDetailsQuery,
useGetTreeByRunIdQuery,
usePrefetch
} from '@/services/bublik-api';
import { useGetRunDetailsQuery, usePrefetch } from '@/services/bublik-api';
import { routes } from '@/router';
import {
ButtonTw,
CardHeader,
cn,
DialogClose,
DialogOverlay,
dialogOverlayStyles,
DialogPortal,
DrawerContent,
DrawerRoot,
DrawerTrigger,
getBugProps,
Icon,
NewBugButton,
Skeleton
} from '@/shared/tailwind-ui';
import { Icon } from '@/shared/tailwind-ui';
import { useUserPreferences } from '@/bublik/features/user-preferences';
import {
LogTableContextProvider,
SessionRoot
} from '@/bublik/features/session-log';
import { LogPreviewContainer } from '@/bublik/features/log-preview-drawer';

import { LinkToHistory } from './link-to-history';

Expand Down Expand Up @@ -113,181 +88,22 @@ export const ResultLinks = (props: ResultLinksProps) => {
logName={result.name}
resultId={resultId}
runId={Number(runId)}
/>
>
<button className="flex items-center w-full gap-1">
<Icon
name="ExpandSelection"
size={20}
className="grid place-items-center"
/>
<span>Preview</span>
</button>
</LogPreviewContainer>
</li>
</ul>
</div>
);
};

interface LogPreviewContainerProps {
resultId: number;
runId: number;
logName: string;
}

function LogPreviewContainer(props: LogPreviewContainerProps) {
const { resultId, runId, logName } = props;
const [open, setOpen] = useState(false);

return (
<DrawerRoot onOpenChange={setOpen}>
<DrawerTrigger asChild>
<button className="flex items-center w-full gap-1">
<Icon
name="ExpandSelection"
size={20}
className="grid place-items-center"
/>
<span>Preview</span>
</button>
</DrawerTrigger>
<DialogOverlay className={dialogOverlayStyles()} />
<DialogPortal>
<DrawerContent asChild>
<div className="bg-white flex flex-col h-[95vh] w-[80vw]">
{/* To fetch only on mount. Do not remove check */}
{open ? (
<div className="h-full flex flex-col overflow-hidden">
<div className="flex-1">
<CardHeader label={logName}>
<div className="flex items-center gap-4">
<ButtonTw asChild variant="secondary" size="xss">
<Link
to={routes.log({ runId, focusId: resultId })}
target="_blank"
>
<Icon name="BoxArrowRight" className="mr-1.5" />
Log
</Link>
</ButtonTw>
<NewBug runId={runId} resultId={resultId} />
<DialogClose asChild>
<ButtonTw variant={'secondary'} size={'xss'}>
<Icon name="CrossSimple" size={20} />
</ButtonTw>
</DialogClose>
</div>
</CardHeader>
</div>
<LogPreview resultId={resultId} />
</div>
) : null}
</div>
</DrawerContent>
</DialogPortal>
</DrawerRoot>
);
}

interface NewBugProps {
runId: number;
resultId: number;
}

function NewBug(props: NewBugProps) {
const { data: details } = useGetRunDetailsQuery(props.runId);
const { data: log } = useGetLogJsonQuery({ id: props.resultId });
const { data: tree } = useGetTreeByRunIdQuery(String(props.runId));

if (!details || !tree || !log) return null;

return (
<NewBugButton
{...getBugProps({
runId: props.runId,
id: props.resultId ?? Number(props.runId),
log,
tree,
details
})}
/>
);
}

interface LogPreviewProps {
resultId: number;
}

function LogPreview(props: LogPreviewProps) {
const { resultId } = props;
const [page, setPage] = useState<number | undefined>();
const { data, error, isLoading, isFetching } = useGetLogJsonQuery({
id: resultId,
page: typeof page !== 'undefined' ? page.toString() : undefined
});

const handlePageClick = useCallback(
(_: string, page: number) => {
setPage(page);
},
[setPage]
);

if (isLoading) {
return <LogPreviewLoading />;
}

if (error) {
return <LogPreviewError error={error} />;
}

if (!data) {
return <LogPreviewEmpty />;
}

return (
<div
className={cn(
'overflow-auto flex-grow px-2 isolate',
isFetching && 'pointer-events-none opacity-40'
)}
>
<LogTableContextProvider onPageClick={handlePageClick}>
<SessionRoot root={data} />
</LogTableContextProvider>
</div>
);
}

interface LogPreviewErrorProps {
error: unknown;
}

function LogPreviewError({ error }: LogPreviewErrorProps) {
const { description, status, title } = getErrorMessage(error);

return (
<div className="mx-auto w-full h-full grid place-items-center">
<div className="flex items-center gap-4">
<Icon
name="TriangleExclamationMark"
size={48}
className="text-text-unexpected"
/>
<div className="">
<h1 className="text-2xl font-semibold">
{status} {title}
</h1>
<p>{description}</p>
</div>
</div>
</div>
);
}

function LogPreviewLoading() {
return (
<div className="w-full h-full p-2">
<Skeleton className="w-full h-full rounded" />
</div>
);
}

function LogPreviewEmpty() {
return <div>No log data...</div>;
}

export interface ActionLinksProps {
runId: string;
resultId: number;
Expand Down

0 comments on commit 01f6c5d

Please sign in to comment.