From 38756f08fcfc4797c9fb261763528cad9f284b3f Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Wed, 30 Oct 2024 10:50:08 +0000 Subject: [PATCH] HPCC-32834 Refactor WU Details fullscreen Move fullscreen logic to WU Details to allow switching tabs in fullscreen mode Signed-off-by: Gordon Smith --- esp/src/src-react/components/FileDetails.tsx | 118 ++++++++------- esp/src/src-react/components/Helpers.tsx | 7 +- esp/src/src-react/components/Metrics.tsx | 28 +--- esp/src/src-react/components/QueryDetails.tsx | 76 +++++----- esp/src/src-react/components/Resources.tsx | 8 +- esp/src/src-react/components/Results.tsx | 9 +- .../src-react/components/WorkunitDetails.tsx | 134 +++++++++-------- .../src-react/components/WorkunitSummary.tsx | 15 +- esp/src/src-react/layouts/Fullscreen.tsx | 50 +++++++ esp/src/src-react/routes.tsx | 24 +-- esp/src/src-react/util/hashUrl.ts | 141 ++++++++++++++++++ esp/src/src-react/util/history.ts | 32 ++-- 12 files changed, 426 insertions(+), 216 deletions(-) create mode 100644 esp/src/src-react/layouts/Fullscreen.tsx create mode 100644 esp/src/src-react/util/hashUrl.ts diff --git a/esp/src/src-react/components/FileDetails.tsx b/esp/src/src-react/components/FileDetails.tsx index c936e617142..89c2fb8dc3c 100644 --- a/esp/src/src-react/components/FileDetails.tsx +++ b/esp/src/src-react/components/FileDetails.tsx @@ -3,9 +3,10 @@ import { WsDfu } from "@hpcc-js/comms"; import { SizeMe } from "react-sizeme"; import nlsHPCC from "src/nlsHPCC"; import { QuerySortItem } from "src/store/Store"; -import { FileParts } from "./FileParts"; import { useFile, useDefFile } from "../hooks/file"; -import { pushUrl, replaceUrl } from "../util/history"; +import { pushUrl, replaceUrl, updateFullscreen } from "../util/history"; +import { FullscreenFrame, FullscreenStack } from "../layouts/Fullscreen"; +import { FileParts } from "./FileParts"; import { FileBlooms } from "./FileBlooms"; import { FileHistory } from "./FileHistory"; import { ProtectedBy } from "./ProtectedBy"; @@ -28,6 +29,7 @@ interface FileDetailsProps { cluster?: string; logicalFile: string; tab?: string; + fullscreen?: boolean; sort?: { subfiles?: QuerySortItem, superfiles?: QuerySortItem, parts?: QuerySortItem, graphs?: QuerySortItem, history?: QuerySortItem, blooms?: QuerySortItem, protectby?: QuerySortItem }; queryParams?: { contents?: StringStringMap }; } @@ -36,6 +38,7 @@ export const FileDetails: React.FunctionComponent = ({ cluster, logicalFile, tab = "summary", + fullscreen = false, sort = {}, queryParams = {} }) => { @@ -50,7 +53,8 @@ export const FileDetails: React.FunctionComponent = ({ const onTabSelect = React.useCallback((tab: TabInfo) => { pushUrl(tab.__state ?? `/files/${cluster}/${logicalFile}/${tab.id}`); - }, [cluster, logicalFile]); + updateFullscreen(fullscreen); + }, [fullscreen, cluster, logicalFile]); const tabs = React.useMemo((): TabInfo[] => { return [{ @@ -103,56 +107,60 @@ export const FileDetails: React.FunctionComponent = ({ }]; }, [file]); - return {({ size }) => -
- - - {file?.ContentType === "key" - ? - : file?.isSuperfile - ? - : - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- }
; + return + {({ size }) => +
+ + + + + {file?.ContentType === "key" + ? + : file?.isSuperfile + ? + : + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ }
+
; }; diff --git a/esp/src/src-react/components/Helpers.tsx b/esp/src/src-react/components/Helpers.tsx index 73fed185eca..972a7453a4c 100644 --- a/esp/src/src-react/components/Helpers.tsx +++ b/esp/src/src-react/components/Helpers.tsx @@ -6,6 +6,8 @@ import { HelperRow, useWorkunitHelpers } from "../hooks/workunit"; import { HolyGrail } from "../layouts/HolyGrail"; import { FluentGrid, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid"; import { ShortVerticalDivider } from "./Common"; +import { SearchParams } from "../util/hashUrl"; +import { hashHistory } from "../util/history"; function canShowContent(type: string) { switch (type) { @@ -135,8 +137,11 @@ export const Helpers: React.FunctionComponent = ({ formatter: (Type, row) => { const target = getTarget(row.id, row); if (target) { + const searchParams = new SearchParams(hashHistory.location.search); + searchParams.param("mode", encodeURIComponent(target.sourceMode)); + searchParams.param("src", encodeURIComponent(target.url)); const linkText = Type.replace("Slave", "Worker") + (row?.Description ? " (" + row.Description + ")" : ""); - return {linkText}; + return {linkText}; } return Type; } diff --git a/esp/src/src-react/components/Metrics.tsx b/esp/src/src-react/components/Metrics.tsx index 3d1f91cc2bd..9b430ef6793 100644 --- a/esp/src/src-react/components/Metrics.tsx +++ b/esp/src/src-react/components/Metrics.tsx @@ -15,7 +15,7 @@ import { HolyGrail } from "../layouts/HolyGrail"; import { AutosizeComponent, AutosizeHpccJSComponent } from "../layouts/HpccJSAdapter"; import { DockPanel, DockPanelItem, ResetableDockPanel } from "../layouts/DockPanel"; import { LayoutStatus, MetricGraph, MetricGraphWidget, isGraphvizWorkerResponse, layoutCache } from "../util/metricGraph"; -import { pushUrl as _pushUrl } from "../util/history"; +import { pushUrl } from "../util/history"; import { debounce } from "../util/throttle"; import { ErrorBoundary } from "../util/errorBoundary"; import { ShortVerticalDivider } from "./Common"; @@ -45,7 +45,6 @@ interface MetricsProps { queryId?: string; parentUrl?: string; selection?: string; - fullscreen?: boolean; } export const Metrics: React.FunctionComponent = ({ @@ -53,8 +52,7 @@ export const Metrics: React.FunctionComponent = ({ querySet = "", queryId = "", parentUrl = `/workunits/${wuid}/metrics`, - selection, - fullscreen = false + selection }) => { const [_uiState, _setUIState] = React.useState({ ...defaultUIState }); const [selectedMetricsSource, setSelectedMetricsSource] = React.useState(""); @@ -97,20 +95,11 @@ export const Metrics: React.FunctionComponent = ({ }).catch(err => logger.error(err)); }, [wuid]); - const pushUrl = React.useCallback((selection?: string, fullscreen?: boolean) => { + const pushSelectionUrl = React.useCallback((selection: string) => { const selectionStr = selection?.length ? `/${selection}` : ""; - const fullscreenStr = fullscreen ? "?fullscreen" : ""; - _pushUrl(`${parentUrl}${selectionStr}${fullscreenStr}`); + pushUrl(`${parentUrl}${selectionStr}`); }, [parentUrl]); - const pushSelectionUrl = React.useCallback((selection: string) => { - pushUrl(selection, fullscreen); - }, [fullscreen, pushUrl]); - - const pushFullscreenUrl = React.useCallback((fullscreen: boolean) => { - pushUrl(selection, fullscreen); - }, [pushUrl, selection]); - const onHotspot = React.useCallback(() => { setSelectedMetricsSource("hotspot"); pushSelectionUrl(selection); @@ -532,18 +521,13 @@ export const Metrics: React.FunctionComponent = ({ }] } }, - { key: "divider_2", itemType: ContextualMenuItemType.Divider, onRender: () => }, - { - key: "fullscreen", title: nlsHPCC.MaximizeRestore, iconProps: { iconName: fullscreen ? "ChromeRestore" : "FullScreen" }, - onClick: () => pushFullscreenUrl(!fullscreen) - } - ], [dot, formatColumns, fullscreen, metrics, pushFullscreenUrl, wuid]); + ], [dot, formatColumns, metrics, wuid]); const setShowMetricOptionsHook = React.useCallback((show: boolean) => { setShowMetricOptions(show); }, []); - return