Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPCC-32834 Refactor WU Details fullscreen #19248

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 63 additions & 55 deletions esp/src/src-react/components/FileDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 };
}
Expand All @@ -36,6 +38,7 @@ export const FileDetails: React.FunctionComponent<FileDetailsProps> = ({
cluster,
logicalFile,
tab = "summary",
fullscreen = false,
sort = {},
queryParams = {}
}) => {
Expand All @@ -50,7 +53,8 @@ export const FileDetails: React.FunctionComponent<FileDetailsProps> = ({

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 [{
Expand Down Expand Up @@ -103,56 +107,60 @@ export const FileDetails: React.FunctionComponent<FileDetailsProps> = ({
}];
}, [file]);

return <SizeMe monitorHeight>{({ size }) =>
<div style={{ height: "100%" }}>
<OverflowTabList tabs={tabs} selected={tab} onTabSelect={onTabSelect} size="medium" />
<DelayLoadedPanel visible={tab === "summary"} size={size}>
{file?.ContentType === "key"
? <IndexFileSummary cluster={cluster} logicalFile={logicalFile} />
: file?.isSuperfile
? <SuperFileSummary cluster={cluster} logicalFile={logicalFile} />
: <LogicalFileSummary cluster={cluster} logicalFile={logicalFile} />
}
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "contents"} size={size}>
<Result cluster={cluster} logicalFile={logicalFile} filter={queryParams.contents} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "datapatterns"} size={size}>
<DataPatterns cluster={cluster} logicalFile={logicalFile} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "ecl"} size={size}>
<SourceEditor text={file?.Ecl} mode="ecl" readonly={true} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "def"} size={size}>
<XMLSourceEditor text={defFile} readonly={true} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "xml"} size={size}>
<XMLSourceEditor text={xmlFile} readonly={true} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "subfiles"} size={size}>
<SubFiles cluster={cluster} logicalFile={logicalFile} sort={sort.subfiles} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "superfiles"} size={size}>
<SuperFiles cluster={cluster} logicalFile={logicalFile} sort={sort.superfiles} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "parts"} size={size}>
<FileParts cluster={cluster} logicalFile={logicalFile} sort={sort.parts} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "queries"} size={size}>
<Queries filter={{ FileName: logicalFile }} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "graphs"} size={size}>
<FileDetailsGraph cluster={cluster} logicalFile={logicalFile} sort={sort.graphs} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "history"} size={size}>
<FileHistory cluster={cluster} logicalFile={logicalFile} sort={sort.history} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "blooms"} size={size}>
<FileBlooms cluster={cluster} logicalFile={logicalFile} sort={sort.blooms} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "protectby"} size={size}>
<ProtectedBy cluster={cluster} logicalFile={logicalFile} sort={sort.protectby} />
</DelayLoadedPanel>
</div>
}</SizeMe>;
return <FullscreenFrame fullscreen={fullscreen}>
<SizeMe monitorHeight>{({ size }) =>
<div style={{ height: "100%" }}>
<FullscreenStack fullscreen={fullscreen}>
<OverflowTabList tabs={tabs} selected={tab} onTabSelect={onTabSelect} size="medium" />
</FullscreenStack>
<DelayLoadedPanel visible={tab === "summary"} size={size}>
{file?.ContentType === "key"
? <IndexFileSummary cluster={cluster} logicalFile={logicalFile} />
: file?.isSuperfile
? <SuperFileSummary cluster={cluster} logicalFile={logicalFile} />
: <LogicalFileSummary cluster={cluster} logicalFile={logicalFile} />
}
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "contents"} size={size}>
<Result cluster={cluster} logicalFile={logicalFile} filter={queryParams.contents} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "datapatterns"} size={size}>
<DataPatterns cluster={cluster} logicalFile={logicalFile} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "ecl"} size={size}>
<SourceEditor text={file?.Ecl} mode="ecl" readonly={true} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "def"} size={size}>
<XMLSourceEditor text={defFile} readonly={true} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "xml"} size={size}>
<XMLSourceEditor text={xmlFile} readonly={true} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "subfiles"} size={size}>
<SubFiles cluster={cluster} logicalFile={logicalFile} sort={sort.subfiles} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "superfiles"} size={size}>
<SuperFiles cluster={cluster} logicalFile={logicalFile} sort={sort.superfiles} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "parts"} size={size}>
<FileParts cluster={cluster} logicalFile={logicalFile} sort={sort.parts} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "queries"} size={size}>
<Queries filter={{ FileName: logicalFile }} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "graphs"} size={size}>
<FileDetailsGraph cluster={cluster} logicalFile={logicalFile} sort={sort.graphs} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "history"} size={size}>
<FileHistory cluster={cluster} logicalFile={logicalFile} sort={sort.history} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "blooms"} size={size}>
<FileBlooms cluster={cluster} logicalFile={logicalFile} sort={sort.blooms} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "protectby"} size={size}>
<ProtectedBy cluster={cluster} logicalFile={logicalFile} sort={sort.protectby} />
</DelayLoadedPanel>
</div>
}</SizeMe>
</FullscreenFrame>;
};
7 changes: 6 additions & 1 deletion esp/src/src-react/components/Helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -135,8 +137,11 @@ export const Helpers: React.FunctionComponent<HelpersProps> = ({
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 <Link href={`#/workunits/${row?.workunit?.Wuid}/helpers/${row.Type}?mode=${encodeURIComponent(target.sourceMode)}&src=${encodeURIComponent(target.url)}`}>{linkText}</Link>;
return <Link href={`#/workunits/${row?.workunit?.Wuid}/helpers/${row.Type}?${searchParams.serialize()}`}>{linkText}</Link>;
}
return Type;
}
Expand Down
28 changes: 6 additions & 22 deletions esp/src/src-react/components/Metrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -45,16 +45,14 @@ interface MetricsProps {
queryId?: string;
parentUrl?: string;
selection?: string;
fullscreen?: boolean;
}

export const Metrics: React.FunctionComponent<MetricsProps> = ({
wuid,
querySet = "",
queryId = "",
parentUrl = `/workunits/${wuid}/metrics`,
selection,
fullscreen = false
selection
}) => {
const [_uiState, _setUIState] = React.useState({ ...defaultUIState });
const [selectedMetricsSource, setSelectedMetricsSource] = React.useState<SelectedMetricsSource>("");
Expand Down Expand Up @@ -97,20 +95,11 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
}).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);
Expand Down Expand Up @@ -532,18 +521,13 @@ export const Metrics: React.FunctionComponent<MetricsProps> = ({
}]
}
},
{ key: "divider_2", itemType: ContextualMenuItemType.Divider, onRender: () => <ShortVerticalDivider /> },
{
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 <HolyGrail fullscreen={fullscreen}
return <HolyGrail
header={<>
<CommandBar items={buttons} farItems={rightButtons} />
<AutosizeHpccJSComponent widget={timeline} fixedHeight={`${TIMELINE_FIXEDHEIGHT + 8}px`} padding={4} hidden={!view.showTimeline} />
Expand Down
76 changes: 42 additions & 34 deletions esp/src/src-react/components/QueryDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import * as React from "react";
import { SizeMe } from "react-sizeme";
import nlsHPCC from "src/nlsHPCC";
import * as ESPQuery from "src/ESPQuery";
import { pushUrl } from "../util/history";
import { pushUrl, updateFullscreen } from "../util/history";
import { FullscreenFrame, FullscreenStack } from "../layouts/Fullscreen";
import { QueryErrors } from "./QueryErrors";
import { QueryLibrariesUsed } from "./QueryLibrariesUsed";
import { QueryLogicalFiles } from "./QueryLogicalFiles";
Expand All @@ -18,6 +19,7 @@ interface QueryDetailsProps {
querySet: string;
queryId: string;
tab?: string;
fullscreen?: boolean;
state?: { metricsTab?: string, metricsState?: string, testTab?: string };
queryParams?: { metricsSelection?: string };
}
Expand All @@ -26,6 +28,7 @@ export const QueryDetails: React.FunctionComponent<QueryDetailsProps> = ({
querySet,
queryId,
tab = "summary",
fullscreen = false,
state = {},
queryParams = {}
}) => {
Expand Down Expand Up @@ -63,7 +66,8 @@ export const QueryDetails: React.FunctionComponent<QueryDetailsProps> = ({
pushUrl(tab.__state ?? `/queries/${querySet}/${queryId}/${tab.id}`);
break;
}
}, [queryId, querySet, state.testTab]);
updateFullscreen(fullscreen);
}, [fullscreen, queryId, querySet, state.testTab]);

const tabs = React.useMemo((): TabInfo[] => {
return [{
Expand Down Expand Up @@ -100,36 +104,40 @@ export const QueryDetails: React.FunctionComponent<QueryDetailsProps> = ({
}];
}, [libsUsedCount, logicalFileCount, superFileCount, wuid]);

return <SizeMe monitorHeight>{({ size }) =>
<div style={{ height: "100%" }}>
<OverflowTabList tabs={tabs} selected={tab} onTabSelect={onTabSelect} size="medium" />
<DelayLoadedPanel visible={tab === "summary"} size={size}>
<QuerySummary queryId={queryId} querySet={querySet} isSuspended={suspended} isActivated={activated} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "errors"} size={size}>
<QueryErrors queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "logicalFiles"} size={size}>
<QueryLogicalFiles queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "superfiles"} size={size}>
<QuerySuperFiles queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "librariesUsed"} size={size}>
<QueryLibrariesUsed queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "summaryStatistics"} size={size}>
<QuerySummaryStats queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "metrics"} size={size}>
<QueryMetrics wuid={query?.Wuid} queryId={queryId} querySet={querySet} tab={state.metricsTab} selection={queryParams.metricsSelection} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "resources"} size={size}>
<Resources wuid={wuid} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "testPages"} size={size}>
<QueryTests queryId={queryId} querySet={querySet} tab={state.testTab} />
</DelayLoadedPanel>
</div>
}</SizeMe>;
return <FullscreenFrame fullscreen={fullscreen}>
<SizeMe monitorHeight>{({ size }) =>
<div style={{ height: "100%" }}>
<FullscreenStack fullscreen={fullscreen}>
<OverflowTabList tabs={tabs} selected={tab} onTabSelect={onTabSelect} size="medium" />
</FullscreenStack>
<DelayLoadedPanel visible={tab === "summary"} size={size}>
<QuerySummary queryId={queryId} querySet={querySet} isSuspended={suspended} isActivated={activated} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "errors"} size={size}>
<QueryErrors queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "logicalFiles"} size={size}>
<QueryLogicalFiles queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "superfiles"} size={size}>
<QuerySuperFiles queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "librariesUsed"} size={size}>
<QueryLibrariesUsed queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "summaryStatistics"} size={size}>
<QuerySummaryStats queryId={queryId} querySet={querySet} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "metrics"} size={size}>
<QueryMetrics wuid={query?.Wuid} queryId={queryId} querySet={querySet} tab={state.metricsTab} selection={queryParams.metricsSelection} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "resources"} size={size}>
<Resources wuid={wuid} />
</DelayLoadedPanel>
<DelayLoadedPanel visible={tab === "testPages"} size={size}>
<QueryTests queryId={queryId} querySet={querySet} tab={state.testTab} />
</DelayLoadedPanel>
</div>
}</SizeMe>
</FullscreenFrame>;
};
Loading
Loading