Browse Source

Merge pull request #14667 from GordonSmith/HPCC-25481-XMLViewer

HPCC-25481 Add React WU XML Component

Reviewed-By: Jaman Brundage <jaman.brundage@lexisnexisrisk.com>
Reviewed-By: Kunal Aswani <kunal.aswani@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 4 years ago
parent
commit
433147ae5b

+ 61 - 0
esp/src/src-react/components/SourceEditor.tsx

@@ -0,0 +1,61 @@
+import * as React from "react";
+import { CommandBar, ContextualMenuItemType, ICommandBarItemProps } from "@fluentui/react";
+import { useConst } from "@fluentui/react-hooks";
+import { XMLEditor } from "@hpcc-js/codemirror";
+import nlsHPCC from "src/nlsHPCC";
+import { HolyGrail } from "../layouts/HolyGrail";
+import { AutosizeHpccJSComponent } from "../layouts/HpccJSAdapter";
+import { useWorkunitXML } from "../hooks/Workunit";
+import { ShortVerticalDivider } from "./Common";
+
+interface SourceEditorProps {
+    text: string;
+    readonly?: boolean;
+}
+
+export const XMLSourceEditor: React.FunctionComponent<SourceEditorProps> = ({
+    text = "",
+    readonly = false
+}) => {
+
+    //  Command Bar  ---
+    const buttons: ICommandBarItemProps[] = [
+        {
+            key: "copy", text: nlsHPCC.Copy, iconProps: { iconName: "Copy" },
+            onClick: () => {
+                navigator?.clipboard?.writeText(text);
+            }
+        },
+        { key: "divider_1", itemType: ContextualMenuItemType.Divider, onRender: () => <ShortVerticalDivider /> },
+    ];
+
+    const editor = useConst(new XMLEditor());
+    React.useEffect(() => {
+        editor
+            .text(text)
+            .readOnly(readonly)
+            .lazyRender()
+            ;
+
+    }, [editor, readonly, text]);
+
+    return <HolyGrail
+        header={<CommandBar items={buttons} overflowButtonProps={{}} />}
+        main={
+            <AutosizeHpccJSComponent widget={editor} padding={4} />
+        }
+    />;
+};
+
+export interface WUXMLSourceEditorProps {
+    wuid: string;
+}
+
+export const WUXMLSourceEditor: React.FunctionComponent<WUXMLSourceEditorProps> = ({
+    wuid
+}) => {
+
+    const [xml] = useWorkunitXML(wuid);
+
+    return <XMLSourceEditor text={xml} readonly={true} />;
+};

+ 2 - 1
esp/src/src-react/components/WorkunitDetails.tsx

@@ -14,6 +14,7 @@ import { Results } from "./Results";
 import { Variables } from "./Variables";
 import { SourceFiles } from "./SourceFiles";
 import { Details } from "./Details";
+import { WUXMLSourceEditor } from "./SourceEditor";
 import { Workflows } from "./Workflows";
 
 import "react-reflex/styles.css";
@@ -222,7 +223,7 @@ export const WorkunitDetails: React.FunctionComponent<WorkunitDetailsProps> = ({
                 <DojoAdapter widgetClassID="ECLArchiveWidget" params={{ Wuid: wuid }} />
             </PivotItem>
             <PivotItem headerText={nlsHPCC.XML} itemKey="xml" style={pivotItemStyle(size, 0)}>
-                <DojoAdapter widgetClassID="ECLSourceWidget" params={{ Wuid: wuid }} delayProps={{ WUXml: true }} />
+                <WUXMLSourceEditor wuid={wuid} />
             </PivotItem>
         </Pivot>
     }</SizeMe>;

+ 20 - 1
esp/src/src-react/hooks/Workunit.ts

@@ -1,5 +1,6 @@
 import * as React from "react";
-import { Workunit, Result, WUStateID, WUInfo } from "@hpcc-js/comms";
+import { useConst } from "@fluentui/react-hooks";
+import { Workunit, Result, WUStateID, WUInfo, WorkunitsService } from "@hpcc-js/comms";
 import nlsHPCC from "src/nlsHPCC";
 
 export function useCounter(): [number, () => void] {
@@ -148,3 +149,21 @@ export function useWorkunitWorkflows(wuid: string): [WUInfo.ECLWorkflow[], Worku
 
     return [workflows, workunit, increment];
 }
+
+export function useWorkunitXML(wuid: string): [string] {
+
+    const service = useConst(new WorkunitsService({ baseUrl: "" }));
+
+    const [xml, setXML] = React.useState("");
+
+    React.useEffect(() => {
+        service.WUFile({
+            Wuid: wuid,
+            Type: "XML"
+        }).then(response => {
+            setXML(response);
+        });
+    }, [wuid, service]);
+
+    return [xml];
+}

+ 4 - 2
esp/src/src-react/layouts/HpccJSAdapter.tsx

@@ -47,19 +47,21 @@ export const HpccJSComponent: React.FunctionComponent<HpccJSComponentProps> = ({
 export interface AutosizeHpccJSComponentProps {
     widget: Widget;
     fixedHeight?: string;
+    padding?: number;
     debounce?: boolean;
 }
 
 export const AutosizeHpccJSComponent: React.FunctionComponent<AutosizeHpccJSComponentProps> = ({
     widget,
     fixedHeight = "100%",
+    padding = 0,
     debounce = true
 }) => {
 
     return <SizeMe monitorHeight>{({ size }) =>
         <div style={{ width: "100%", height: fixedHeight, position: "relative" }}>
-            <div style={{ position: "absolute" }}>
-                <HpccJSComponent widget={widget} debounce={debounce} width={size.width} height={size.height} />
+            <div style={{ position: "absolute", padding: `${padding}px` }}>
+                <HpccJSComponent widget={widget} debounce={debounce} width={size.width - padding * 2} height={size.height - padding * 2} />
             </div>
         </div>
     }