Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/candidate-9.4.x' into candidate-…
Browse files Browse the repository at this point in the history
…9.6.x

Signed-off-by: Jake Smith <[email protected]>
  • Loading branch information
jakesmith committed Sep 13, 2024
2 parents 3a15580 + ea4a2ea commit 0e19669
Show file tree
Hide file tree
Showing 36 changed files with 343 additions and 139 deletions.
2 changes: 1 addition & 1 deletion esp/src/eclwatch/templates/GetDFUWorkunitsWidget.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="${baseClass}">
<div id="${id}BorderContainer" class="${baseClass}BorderContainer" style="width: 100%; height: 100%;" data-dojo-type="dijit.layout.BorderContainer">
<div id="${id}TabContainer" data-dojo-props="region: 'center', tabPosition: 'top'" style="width: 100%; height: 100%" data-dojo-type="dijit.layout.TabContainer">
<div id="${id}_Workunits" style="width: 100%; height: 100%" data-dojo-props='title:"Workunits"' data-dojo-type="dijit.layout.BorderContainer">
<div id="${id}_Workunits" style="width: 100%; height: 100%" data-dojo-props='title:"${i18n.title_GetDFUWorkunits}"' data-dojo-type="dijit.layout.BorderContainer">
<div id="${id}Toolbar" class="topPanel" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
<div id="${id}Refresh" data-dojo-attach-event="onClick:_onRefresh" data-dojo-props="iconClass:'iconRefresh'" data-dojo-type="dijit.form.Button">${i18n.Refresh}</div>
<span data-dojo-type="dijit.ToolbarSeparator"></span>
Expand Down
2 changes: 1 addition & 1 deletion esp/src/eclwatch/templates/HPCCPlatformFilesWidget.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</div>
<div id="${id}_LandingZones" title="${i18n.LandingZones}" data-dojo-props="delayWidget: 'LZBrowseWidget'" data-dojo-type="DelayLoadWidget">
</div>
<div id="${id}_Workunits" title="${i18n.Workunits}" data-dojo-props="delayWidget: 'GetDFUWorkunitsWidget'" data-dojo-type="DelayLoadWidget">
<div id="${id}_Workunits" title="${i18n.title_GetDFUWorkunits}" data-dojo-props="delayWidget: 'GetDFUWorkunitsWidget'" data-dojo-type="DelayLoadWidget">
</div>
<div id="${id}_Xref" title="${i18n.XRef}" data-dojo-props="delayWidget: 'XrefQueryWidget'" data-dojo-type="DelayLoadWidget">
</div>
Expand Down
27 changes: 11 additions & 16 deletions esp/src/src-react/components/InfoGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { formatCost, formatTwoDigits } from "src/Session";
import nlsHPCC from "src/nlsHPCC";
import { useWorkunitExceptions } from "../hooks/workunit";
import { FluentGrid, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid";
import { pivotItemStyle } from "../layouts/pivot";

function extractGraphInfo(msg) {
const regex = /^([a-zA-Z0-9 :]+: )(graph graph(\d+)\[(\d+)\], )(([a-zA-Z]+)\[(\d+)\]: )?(.*)$/gmi;
Expand Down Expand Up @@ -237,23 +236,19 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
}
}, [data.length]);

return <div style={{ height: "100%", overflowY: "hidden" }}>
return <div style={{ height: "100%" }}>
<CommandBar items={buttons} farItems={copyButtons} />
<SizeMe monitorHeight >{({ size }) =>
<div style={{ height: "100%", overflowY: "hidden" }}>
<div style={{ ...pivotItemStyle(size), overflowY: "hidden" }}>
<FluentGrid
data={data}
primaryID={"id"}
columns={columns}
setSelection={_ => { }}
setTotal={setTotal}
refresh={refreshTable}
height={`${size.height - (44 + 8 + 45 + 12)}px`}
selectionMode={SelectionMode.none}
></FluentGrid>
</div>
</div>
<FluentGrid
data={data}
primaryID={"id"}
columns={columns}
setSelection={_ => { }}
setTotal={setTotal}
refresh={refreshTable}
height={`${size.height - (44 + 8 + 45 + 12)}px`}
selectionMode={SelectionMode.none}
></FluentGrid>
}</SizeMe>
</div>;
};
19 changes: 11 additions & 8 deletions esp/src/src-react/components/LogViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,16 @@ export const LogViewer: React.FunctionComponent<LogViewerProps> = ({
return <HolyGrail
header={<CommandBar items={buttons} farItems={copyButtons} />}
main={
<FluentGrid
data={data}
primaryID={"dateTime"}
columns={columns}
setSelection={setSelection}
setTotal={setTotal}
refresh={refreshTable}
></FluentGrid>}
<div style={{ position: "relative", height: "100%" }}>
<FluentGrid
data={data}
primaryID={"dateTime"}
columns={columns}
setSelection={setSelection}
setTotal={setTotal}
refresh={refreshTable}
></FluentGrid>
</div>
}
/>;
};
9 changes: 5 additions & 4 deletions esp/src/src-react/components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useConst } from "@fluentui/react-hooks";
import nlsHPCC from "src/nlsHPCC";
import { hasLogAccess } from "src/ESPLog";
import { containerized, bare_metal } from "src/BuildInfo";
import { navCategory } from "../util/history";
import { MainNav, routes } from "../routes";
import { useFavorite, useFavorites, useHistory } from "../hooks/favorite";
import { useSessionStore } from "../hooks/store";
Expand Down Expand Up @@ -98,7 +99,7 @@ routes.forEach((route: any) => {
});

function navSelectedKey(hashPath) {
const rootPath = navIdx(`/${hashPath?.split("/")[1]}`);
const rootPath = navIdx(`/${navCategory(hashPath)?.split("/")[1]}`);
if (rootPath?.length) {
return rootPath[0];
}
Expand Down Expand Up @@ -164,7 +165,7 @@ const subMenuItems: SubMenuItems = {
"files": [
{ headerText: nlsHPCC.LogicalFiles, itemKey: "/files" },
{ headerText: nlsHPCC.LandingZones, itemKey: "/landingzone" },
{ headerText: nlsHPCC.Workunits, itemKey: "/dfuworkunits" },
{ headerText: nlsHPCC.title_GetDFUWorkunits, itemKey: "/dfuworkunits" },
{ headerText: nlsHPCC.XRef + " (L)", itemKey: "/xref" },
],
"queries": [
Expand Down Expand Up @@ -215,8 +216,8 @@ for (const key in subMenuItems) {
}

function subNavSelectedKey(hashPath) {
const hashCategory = hashPath.split("/").slice(0, 3).join("/");
return subNavIdx(hashCategory).length ? hashCategory : null;
const category = navCategory(hashPath);
return subNavIdx(category).length ? category : null;
}

interface SubNavigationProps {
Expand Down
11 changes: 4 additions & 7 deletions esp/src/src-react/components/SourceFiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface SourceFilesProps {
}

const emptyFilter: { [id: string]: any } = {};
const defaultSort = { attribute: "Name", descending: false };
const defaultSort = { attribute: undefined, descending: false };

export const SourceFiles: React.FunctionComponent<SourceFilesProps> = ({
wuid,
Expand All @@ -52,7 +52,7 @@ export const SourceFiles: React.FunctionComponent<SourceFilesProps> = ({
selectorType: "checkbox"
},
Name: {
label: "Name", sortable: true,
label: "Name", width: 400, sortable: true,
formatter: (Name, row) => {
let fileUrl = `#/files/${Name}`;
if (row?.FileCluster) {
Expand All @@ -65,11 +65,8 @@ export const SourceFiles: React.FunctionComponent<SourceFilesProps> = ({
</>;
}
},
FileCluster: { label: nlsHPCC.FileCluster, width: 300, sortable: false },
Count: {
label: nlsHPCC.Usage, width: 72, sortable: true,
justify: "right"
}
FileCluster: { label: nlsHPCC.FileCluster, width: 200, sortable: false },
Count: { label: nlsHPCC.Usage, width: 72, sortable: true, justify: "right" }
};
}, []);

Expand Down
47 changes: 12 additions & 35 deletions esp/src/src-react/components/controls/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { DetailsList, DetailsListLayoutMode, Dropdown, IColumn as _IColumn, ICommandBarItemProps, IDetailsHeaderProps, IDetailsListStyles, mergeStyleSets, Selection, Stack, TooltipHost, TooltipOverflowMode, IRenderFunction, IDetailsRowProps, SelectionMode, ConstrainMode, ISelection } from "@fluentui/react";
import { DetailsList, DetailsListLayoutMode, Dropdown, IColumn as _IColumn, ICommandBarItemProps, IDetailsHeaderProps, IDetailsListStyles, mergeStyleSets, Selection, Stack, TooltipHost, TooltipOverflowMode, IRenderFunction, IDetailsRowProps, SelectionMode, ConstrainMode, ISelection, ScrollablePane, Sticky } from "@fluentui/react";
import { Pagination } from "@fluentui/react-experiments/lib/Pagination";
import { useConst } from "@fluentui/react-hooks";
import { BaseStore, Memory, QueryRequest, QuerySortItem } from "src/store/Memory";
Expand Down Expand Up @@ -293,45 +293,22 @@ const FluentStoreGrid: React.FunctionComponent<FluentStoreGridProps> = ({
}, [memoizedColumns]);

const renderDetailsHeader = React.useCallback((props: IDetailsHeaderProps, defaultRender?: any) => {
return defaultRender({
...props,
onRenderColumnHeaderTooltip: (tooltipHostProps) => {
return <TooltipHost {...tooltipHostProps} content={tooltipHostProps?.column?.data?.headerTooltip ?? ""} />;
},
styles: { root: { paddingTop: 1 } }
});
return <Sticky>
{defaultRender({
...props,
onRenderColumnHeaderTooltip: (tooltipHostProps) => {
return <TooltipHost {...tooltipHostProps} content={tooltipHostProps?.column?.data?.headerTooltip ?? ""} />;
},
styles: { root: { paddingTop: 1 } }
})}
</Sticky>;
}, []);

const columnResize = React.useCallback((column: IColumn, newWidth: number, columnIndex?: number) => {
columnWidths.set(column.key, newWidth);
}, [columnWidths]);

/* Monitor Scroll Events (hack)
Essentially we are setting the scrollElement of the DetailsList to the div that contains the DetailsList (rather than a scrollable pane host).
See: https://github.com/microsoft/fluentui/blob/55d3a31042e8972ea373841bef616c68e6ab69f9/packages/react/src/components/List/List.tsx#L355-L369
Note: Not sure if `_onScroll` call is needed, but excluding for now as it seems to work without it and is more performant.
*/
// const id = useId("fluent-store-grid-");
// const detailListScrollComponent = React.useRef<HTMLDivElement | null>(null);
// const detailListComponent = React.useRef<IDetailsListEx | null>(null);
// const [detailListElement, setDetailListElement] = React.useState<HTMLDivElement | null>(null);
// useMount(() => {
// const detailListElement = document.querySelector<HTMLDivElement>(`#${id} .ms-DetailsList`);
// setDetailListElement(detailListElement);
// if (detailListComponent.current?._list?.current) {
// detailListComponent.current._list.current._scrollElement = detailListElement;
// }
// });
// useOnEvent(detailListScrollComponent, "scroll", () => {
// detailListComponent.current?._list?.current?._onScroll();
// });
// useOnEvent(detailListScrollComponent, "scroll", () => {
// detailListComponent.current?._list?.current?._onAsyncScrollDebounced();
// });

return <div data-is-scrollable={"true"} style={{ overflow: "auto" }}>
return <ScrollablePane>
<DetailsList
compact={true}
items={items}
Expand All @@ -348,7 +325,7 @@ const FluentStoreGrid: React.FunctionComponent<FluentStoreGridProps> = ({
styles={gridStyles(height)}
selectionMode={selectionMode}
/>
</div>;
</ScrollablePane>;
};

interface FluentGridProps {
Expand Down
12 changes: 10 additions & 2 deletions esp/src/src-react/components/forms/AddBinding.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { DefaultButton, IDropdownOption, PrimaryButton, TextField, } from "@fluentui/react";
import { DefaultButton, IDropdownOption, PrimaryButton, Spinner, TextField, } from "@fluentui/react";
import { scopedLogger } from "@hpcc-js/util";
import { useForm, Controller } from "react-hook-form";
import { EsdlDefinitionsTextField, EsdlEspProcessesTextField } from "./Fields";
Expand Down Expand Up @@ -39,6 +39,8 @@ export const AddBindingForm: React.FunctionComponent<AddBindingFormProps> = ({
}) => {

const { handleSubmit, control, reset } = useForm<AddBindingFormValues>({ defaultValues });
const [submitDisabled, setSubmitDisabled] = React.useState(false);
const [spinnerHidden, setSpinnerHidden] = React.useState(true);

const closeForm = React.useCallback(() => {
setShowForm(false);
Expand All @@ -47,11 +49,16 @@ export const AddBindingForm: React.FunctionComponent<AddBindingFormProps> = ({
const onSubmit = React.useCallback(() => {
handleSubmit(
(data, evt) => {
setSubmitDisabled(true);
setSpinnerHidden(false);

const request: any = data;
request.Overwrite = true;

WsESDLConfig.PublishESDLBinding({ request: request })
.then(() => {
setSubmitDisabled(false);
setSpinnerHidden(true);
closeForm();
reset(defaultValues);
if (refreshGrid) refreshGrid();
Expand All @@ -66,7 +73,8 @@ export const AddBindingForm: React.FunctionComponent<AddBindingFormProps> = ({
return <MessageBox show={showForm} setShow={closeForm} title={nlsHPCC.AddBinding}
minWidth={minWidth}
footer={<>
<PrimaryButton text={nlsHPCC.Add} onClick={handleSubmit(onSubmit)} />
<Spinner label={nlsHPCC.Loading} labelPosition="right" style={{ display: spinnerHidden ? "none" : "inherit" }} />
<PrimaryButton text={nlsHPCC.Add} disabled={submitDisabled} onClick={handleSubmit(onSubmit)} />
<DefaultButton text={nlsHPCC.Cancel} onClick={() => closeForm()} />
</>}>
<Controller
Expand Down
11 changes: 9 additions & 2 deletions esp/src/src-react/components/forms/AddGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { DefaultButton, PrimaryButton, TextField, } from "@fluentui/react";
import { DefaultButton, PrimaryButton, Spinner, TextField, } from "@fluentui/react";
import { scopedLogger } from "@hpcc-js/util";
import { useForm, Controller } from "react-hook-form";
import nlsHPCC from "src/nlsHPCC";
Expand Down Expand Up @@ -33,6 +33,8 @@ export const AddGroupForm: React.FunctionComponent<AddGroupFormProps> = ({
}) => {

const { handleSubmit, control, reset } = useForm<AddGroupFormValues>({ defaultValues });
const [submitDisabled, setSubmitDisabled] = React.useState(false);
const [spinnerHidden, setSpinnerHidden] = React.useState(true);

const closeForm = React.useCallback(() => {
setShowForm(false);
Expand All @@ -41,10 +43,14 @@ export const AddGroupForm: React.FunctionComponent<AddGroupFormProps> = ({
const onSubmit = React.useCallback(() => {
handleSubmit(
(data, evt) => {
setSubmitDisabled(true);
setSpinnerHidden(false);
const request: any = data;

WsAccess.GroupAdd({ request: request })
.then(() => {
setSubmitDisabled(false);
setSpinnerHidden(true);
closeForm();
reset(defaultValues);
if (refreshGrid) refreshGrid();
Expand All @@ -58,7 +64,8 @@ export const AddGroupForm: React.FunctionComponent<AddGroupFormProps> = ({

return <MessageBox show={showForm} setShow={closeForm} title={nlsHPCC.AddGroup} minWidth={400}
footer={<>
<PrimaryButton text={nlsHPCC.Add} onClick={handleSubmit(onSubmit)} />
<Spinner label={nlsHPCC.Loading} labelPosition="right" style={{ display: spinnerHidden ? "none" : "inherit" }} />
<PrimaryButton text={nlsHPCC.Add} disabled={submitDisabled} onClick={handleSubmit(onSubmit)} />
<DefaultButton text={nlsHPCC.Cancel} onClick={() => { reset(defaultValues); closeForm(); }} />
</>}>
<Controller
Expand Down
11 changes: 9 additions & 2 deletions esp/src/src-react/components/forms/AddGroupResource.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { Checkbox, DefaultButton, PrimaryButton, TextField, } from "@fluentui/react";
import { Checkbox, DefaultButton, PrimaryButton, Spinner, TextField, } from "@fluentui/react";
import { AccessService } from "@hpcc-js/comms";
import { scopedLogger } from "@hpcc-js/util";
import { useForm, Controller } from "react-hook-form";
Expand Down Expand Up @@ -43,6 +43,8 @@ export const AddGroupResourceForm: React.FunctionComponent<AddGroupResourceFormP
}) => {

const { handleSubmit, control, reset } = useForm<AddGroupResourceFormValues>({ defaultValues });
const [submitDisabled, setSubmitDisabled] = React.useState(false);
const [spinnerHidden, setSpinnerHidden] = React.useState(true);

const closeForm = React.useCallback(() => {
setShowForm(false);
Expand All @@ -51,6 +53,8 @@ export const AddGroupResourceForm: React.FunctionComponent<AddGroupResourceFormP
const onSubmit = React.useCallback(() => {
handleSubmit(
(data, evt) => {
setSubmitDisabled(true);
setSpinnerHidden(false);
const request: any = data;

request["action"] = "update";
Expand All @@ -60,6 +64,8 @@ export const AddGroupResourceForm: React.FunctionComponent<AddGroupResourceFormP

service.PermissionAction(request)
.then(() => {
setSubmitDisabled(false);
setSpinnerHidden(true);
closeForm();
reset(defaultValues);
if (refreshGrid) refreshGrid();
Expand All @@ -73,7 +79,8 @@ export const AddGroupResourceForm: React.FunctionComponent<AddGroupResourceFormP

return <MessageBox show={showForm} setShow={closeForm} title={nlsHPCC.AddGroup} minWidth={400}
footer={<>
<PrimaryButton text={nlsHPCC.Add} onClick={handleSubmit(onSubmit)} />
<Spinner label={nlsHPCC.Loading} labelPosition="right" style={{ display: spinnerHidden ? "none" : "inherit" }} />
<PrimaryButton text={nlsHPCC.Add} disabled={submitDisabled} onClick={handleSubmit(onSubmit)} />
<DefaultButton text={nlsHPCC.Cancel} onClick={() => { reset(defaultValues); closeForm(); }} />
</>}>
<Controller
Expand Down
Loading

0 comments on commit 0e19669

Please sign in to comment.