From 49d292b8fe543a6107fc5d5c2ac2e215982524f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Mon, 18 Nov 2024 10:03:26 +0100 Subject: [PATCH] Redirect to log correct page in paginated logs list (#626) We were doing a shitty version of this in the client with a useEffect and I realize that we have a backend. So I just moved to it Also: Make playground resizable and avoid requesting a log when one is in flight --- .../DocumentParams/HistoryLogParams/index.tsx | 63 ++++----- .../HistoryLogParams/useLogHistoryParams.ts | 15 ++- .../DocumentParams/PaginationNav/index.tsx | 13 +- .../DocumentEditor/Editor/index.tsx | 104 ++++++++------- .../DocumentLogBlankSlate/index.tsx | 61 +++++++++ .../logs/_components/DocumentLogs/index.tsx | 41 +----- .../documents/[documentUuid]/logs/page.tsx | 120 +++++++++--------- .../web-ui/src/ds/atoms/SplitPane/index.tsx | 43 +++++-- 8 files changed, 262 insertions(+), 198 deletions(-) create mode 100644 apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/DocumentLogBlankSlate/index.tsx diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/index.tsx index c6870ed94..ea048ef8c 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/index.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/index.tsx @@ -61,7 +61,7 @@ export function HistoryLogParams({
{data.isLoading || hasLogs ? ( <> -
+
{data.isLoadingLog ? (
@@ -69,38 +69,41 @@ export function HistoryLogParams({
) : null} {!data.isLoadingLog && urlData ? ( - -
- {urlData.createdAt} - {urlData.hasError ? ( - - {urlData.shortCode} - - } - > - This log has an error - - ) : ( - {urlData.shortCode} - )} - -
+ + + {urlData.createdAt} + + {urlData.hasError ? ( + {urlData.shortCode} + } + > + This log has an error + + ) : ( + {urlData.shortCode} + )} + ) : null}
-
- -
+ ) : (
diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/useLogHistoryParams.ts b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/useLogHistoryParams.ts index 6c0a38830..3f9ae5d92 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/useLogHistoryParams.ts +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/HistoryLogParams/useLogHistoryParams.ts @@ -98,11 +98,16 @@ export function useLogHistoryParams({ }, }) - const updatePosition = useCallback((position: number) => { - setPosition((prev) => - prev ? { ...prev, position } : { position, page: 1 }, - ) - }, []) + const updatePosition = useCallback( + (position: number) => { + if (isLoadingLog) return + + setPosition((prev) => + prev ? { ...prev, position } : { position, page: 1 }, + ) + }, + [isLoadingLog], + ) const onNextPage = useCallback( (position: number) => updatePosition(position + 1), diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/PaginationNav/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/PaginationNav/index.tsx index 31a19b5fb..a47b3a577 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/PaginationNav/index.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/_components/DocumentEditor/Editor/Playground/DocumentParams/PaginationNav/index.tsx @@ -21,7 +21,7 @@ export function ParametersPaginationNav({ if (currentIndex === undefined || totalCount === undefined) return null return ( -
+
+ } + copilot={{ + isLoading: isCopilotLoading, + requestSuggestion, }} - onClick={() => setRefineDocumentModalOpen(true)} - > - Refine - - } - copilot={{ - isLoading: isCopilotLoading, - requestSuggestion, - }} - /> - -
-
- -
-
+ /> + +
+ + } + rightPane={ + +
+ +
+
+ } + /> ) diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/DocumentLogBlankSlate/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/DocumentLogBlankSlate/index.tsx new file mode 100644 index 000000000..ed0da6e7e --- /dev/null +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/DocumentLogBlankSlate/index.tsx @@ -0,0 +1,61 @@ +import { Commit } from '@latitude-data/core/browser' +import { Button, Text } from '@latitude-data/web-ui' +import { getDocumentByUuidCached } from '$/app/(private)/_data-access' +import { ROUTES } from '$/services/routes' +import Link from 'next/link' + +import { DocumentBlankSlateLayout } from '../../../../../_components/DocumentBlankSlateLayout' +import { DocumentsClient } from '../../../../../_components/DocumentsClient' + +export async function DocumentLogBlankSlate({ + commit, + projectId, + documentUuid, +}: { + commit: Commit + documentUuid: string + projectId: number +}) { + const document = await getDocumentByUuidCached({ + documentUuid, + projectId, + commitUuid: commit.uuid, + }) + return ( + +
+ + To get started, please choose one of the following options: + +
+ + + + Or +
+ Import logs from code + + Run this code snippet to start importing logs into Latitude. Once + done, come back to this page, and you'll be able to evaluate both + existing and incoming logs. + + +
+
+ ) +} diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/index.tsx index f421e8f9d..cbea63d50 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/index.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/index.tsx @@ -1,6 +1,6 @@ 'use client' -import { useCallback, useEffect, useRef, useState } from 'react' +import { useCallback, useRef, useState } from 'react' import { DocumentLogWithMetadataAndError } from '@latitude-data/core/repositories' import { @@ -13,9 +13,7 @@ import { EventArgs, useSockets, } from '$/components/Providers/WebsocketsProvider/useSockets' -import { useGenerateDocumentLogDetailUrl } from '$/hooks/useGenerateDocumentLogDetailUrl' import useDocumentLogs, { documentLogPresenter } from '$/stores/documentLogs' -import useDocumentLogWithPaginationPosition from '$/stores/documentLogWithPaginationPosition' import useProviderLogs from '$/stores/providerLogs' import { useSearchParams } from 'next/navigation' @@ -68,48 +66,12 @@ const useDocumentLogSocket = ( useSockets({ event: 'documentLogCreated', onMessage }) } -/** - * When this page receive ?logUuid=some-uuid it can happen 2 things - * - * 1. The `page=NUMBER` is correct and `selectedLog` is there. - * 2. There is no `page` param or is incorrect `selectedLog` is not there. - * - * We handle (2) here by looking the right page for the `logUuid` in the URL - */ -function useRedirectToLogDetail({ - selectedLog, - documentLogUuid, -}: { - selectedLog: DocumentLogWithMetadataAndError | undefined - documentLogUuid: string | undefined -}) { - const mounted = useRef(false) - const { data: position, isLoading } = useDocumentLogWithPaginationPosition({ - documentLogUuid: selectedLog ? undefined : documentLogUuid, - }) - const { url } = useGenerateDocumentLogDetailUrl({ - documentLogUuid, - page: position?.page, - }) - useEffect(() => { - if (selectedLog) return - if (mounted.current) return - if (isLoading || !url) return - - mounted.current = true - - window.location.href = url - }, [url, isLoading, selectedLog]) -} - export function DocumentLogs({ documentLogs: serverDocumentLogs, selectedLog: serverSelectedLog, - documentLogUuid, }: { documentLogs: DocumentLogWithMetadataAndError[] selectedLog: DocumentLogWithMetadataAndError | undefined - documentLogUuid: string | undefined }) { const tableRef = useRef(null) const sidebarWrapperRef = useRef(null) @@ -140,7 +102,6 @@ export function DocumentLogs({ ) useDocumentLogSocket(document.documentUuid, mutate) - useRedirectToLogDetail({ selectedLog, documentLogUuid }) if (!documentLogs.length) { return ( diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/page.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/page.tsx index 643bada11..7e29aae65 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/page.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/page.tsx @@ -1,18 +1,39 @@ +import { Commit, Workspace } from '@latitude-data/core/browser' import { QueryParams } from '@latitude-data/core/lib/pagination/buildPaginatedUrl' import { computeDocumentLogsWithMetadataQuery } from '@latitude-data/core/services/documentLogs/computeDocumentLogsWithMetadata' -import { Button, TableWithHeader, Text } from '@latitude-data/web-ui' -import { - findCommitCached, - getDocumentByUuidCached, -} from '$/app/(private)/_data-access' +import { fetchDocumentLogWithPosition } from '@latitude-data/core/services/documentLogs/fetchDocumentLogWithPosition' +import { Button, TableWithHeader } from '@latitude-data/web-ui' +import { findCommitCached } from '$/app/(private)/_data-access' +import { DocumentLogBlankSlate } from '$/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/logs/_components/DocumentLogs/DocumentLogBlankSlate' import { getCurrentUser } from '$/services/auth/getCurrentUser' import { ROUTES } from '$/services/routes' import Link from 'next/link' +import { redirect } from 'next/navigation' -import { DocumentBlankSlateLayout } from '../../_components/DocumentBlankSlateLayout' -import { DocumentsClient } from '../../_components/DocumentsClient' import { DocumentLogs } from './_components/DocumentLogs' +async function fetchDocumentLogPage({ + workspace, + commit: _c, // TODO: Add when other PRs are merged + documentLogUuid, +}: { + commit: Commit + workspace: Workspace + documentLogUuid: string | undefined +}) { + if (!documentLogUuid) return undefined + + const result = await fetchDocumentLogWithPosition({ + workspace, + // commit, TODO: Add when other PRs are merged + documentLogUuid, + }) + + if (result.error) return undefined + + return result.value.page.toString() +} + export default async function DocumentPage({ params, searchParams, @@ -23,71 +44,48 @@ export default async function DocumentPage({ const { workspace } = await getCurrentUser() const projectId = Number(params.projectId) const commitUuid = params.commitUuid + const documentUuid = params.documentUuid const commit = await findCommitCached({ projectId, uuid: commitUuid }) + const documentLogUuid = searchParams.logUuid?.toString() + const page = searchParams.page?.toString?.() + const currentLogPage = await fetchDocumentLogPage({ + workspace, + commit, + documentLogUuid, + }) + + if (currentLogPage && currentLogPage !== page) { + const route = ROUTES.projects + .detail({ id: projectId }) + .commits.detail({ uuid: commit.uuid }) + .documents.detail({ uuid: documentUuid }).logs.root + return redirect( + `${route}?page=${currentLogPage}&logUuid=${documentLogUuid}`, + ) + } + const rows = await computeDocumentLogsWithMetadataQuery({ workspaceId: workspace.id, documentUuid: params.documentUuid, draft: commit, - page: searchParams.page as string | undefined, + page, pageSize: searchParams.pageSize as string | undefined, }) - const documentLogUuid = searchParams.logUuid?.toString() - const selectedLog = rows.find((r) => r.uuid === documentLogUuid) - const document = await getDocumentByUuidCached({ - documentUuid: params.documentUuid, - projectId, - commitUuid, - }) + const selectedLog = rows.find((r) => r.uuid === documentLogUuid) return (
- {!rows.length && ( - -
- - To get started, please choose one of the following options: - -
- - - - Or -
- Import logs from code - - Run this code snippet to start importing logs into Latitude. Once - done, come back to this page, and you'll be able to evaluate both - existing and incoming logs. - - -
-
- )} - {rows.length && ( + {!rows.length ? ( + + ) : null} + {rows.length ? ( - } + table={} actions={ } /> - )} + ) : null}
) } diff --git a/packages/web-ui/src/ds/atoms/SplitPane/index.tsx b/packages/web-ui/src/ds/atoms/SplitPane/index.tsx index 82ee33d2f..d2d0ca075 100644 --- a/packages/web-ui/src/ds/atoms/SplitPane/index.tsx +++ b/packages/web-ui/src/ds/atoms/SplitPane/index.tsx @@ -12,6 +12,7 @@ import { import { ResizableBox, ResizeCallbackData, ResizeHandle } from 'react-resizable' +import { useMeasure } from '../../../browser' import { cn } from '../../../lib/utils' const JS_PANEL_CLASS = 'js-pane' @@ -88,7 +89,7 @@ function ResizablePane({ children: ReactNode paneWidth: number onResizePane: (width: number) => void - onResizeStop: (width: number) => void + onResizeStop?: (width: number) => void }) { const onResize = (_: SyntheticEvent, data: ResizeCallbackData) => { const lessThanMinWidth = minWidth ? data.size.width < minWidth : false @@ -100,7 +101,7 @@ function ResizablePane({ } const onStop = useCallback( (_e: SyntheticEvent, data: ResizeCallbackData) => { - onResizeStop(data.size.width) + onResizeStop?.(data.size.width) }, [onResizeStop], ) @@ -125,20 +126,40 @@ function HorizontalSplit({ leftPane, rightPane, initialWidth, + initialPercentage, minWidth, onResizeStop, cssPanelHeight, + className, }: { leftPane: ReactNode rightPane: ReactNode - initialWidth: number + initialWidth?: number + initialPercentage?: number minWidth: number - onResizeStop: (width: number) => void + onResizeStop?: (width: number) => void cssPanelHeight?: string + className?: string }) { - const [paneWidth, setPaneWidth] = useState(initialWidth) + const [ref, { width: initialWidthFromRef }] = useMeasure() + const [paneWidth, setPaneWidth] = useState(initialWidth ?? 0) + useEffect(() => { + if (paneWidth > 0) return + + if (!initialPercentage) return + + const percentage = initialPercentage / 100 + setPaneWidth(initialWidthFromRef * percentage) + }, [initialWidth, initialWidthFromRef, initialPercentage]) + return ( -
+
void + onResizeStop?: (width: number) => void cssPanelHeight?: string + className?: string }) => { return (