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

add original flow input #137

Merged
merged 10 commits into from
Feb 7, 2021
Merged
4 changes: 2 additions & 2 deletions src/Routes/Tables/Jobs/Info.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ const JobInfo = ({ job }) => {
<Trace data={traceData} />
</Tabs.TabPane>
<Tabs.TabPane tab={TABS.INFO} key={TABS.INFO}>
<JsonSwitch obj={userPipeline} options={options} />
<JsonSwitch obj={userPipeline} options={options} jobId={key} />
</Tabs.TabPane>
<Tabs.TabPane tab={TABS.MORE_INFO} key={TABS.MORE_INFO}>
<JsonSwitch obj={pipeline} options={options} />
<JsonSwitch obj={pipeline} options={options} jobId={key} />
</Tabs.TabPane>
</Tabs>
);
Expand Down
14 changes: 6 additions & 8 deletions src/Routes/Tables/Jobs/JobActions.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { Button, Tooltip } from 'antd';
import { useSelector } from 'react-redux';
import { selectors } from 'reducers';
import { USER_GUIDE } from 'const';
import { useActions } from 'hooks';
import { useActions, usePipeline } from 'hooks';

import PropTypes from 'prop-types';
import React, { useCallback, useMemo, useRef } from 'react';
import usePath from './usePath';
Expand All @@ -28,16 +29,13 @@ const JobActions = ({ job }) => {
results,
} = job;

const {
rerunRawPipeline,
stopPipeline,
pausePipeline,
resumePipeline,
} = useActions();
const { rerunRawPipeline } = usePipeline();
const { stopPipeline, pausePipeline, resumePipeline } = useActions();
const downloadLinkRef = useRef();
const onReRun = useCallback(() => rerunRawPipeline(userPipeline), [
const onReRun = useCallback(() => rerunRawPipeline(userPipeline, key), [
userPipeline,
rerunRawPipeline,
key,
]);

const onStop = useCallback(() => stopPipeline(key), [stopPipeline, key]);
Expand Down
52 changes: 52 additions & 0 deletions src/components/DownloadLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useRef,
} from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { selectors } from 'reducers';

/**
* Renders a download link and clicks the link automatically when a non null
* href value is set. accepts a ref with a "download" callback to manually download
*/
// eslint-disable-next-line
const DownloadLink = ({ href, autoDownload }, ref) => {
const { socketUrl } = useSelector(selectors.connection);
const linkRef = useRef();

const download = useCallback(
() => href !== null && linkRef.current && linkRef.current.click(),
[href, linkRef]
);

useEffect(() => {
if (!autoDownload) return;
download();
}, [download, autoDownload]);

useImperativeHandle(ref, () => ({ download }));
return href ? (
<a
style={{ display: 'none' }}
ref={linkRef}
href={`${socketUrl}/${href}`}
download="file.zip">
hidden download link
</a>
) : null;
};

const WrappedDownloadLink = forwardRef(DownloadLink);

WrappedDownloadLink.propTypes = {
href: PropTypes.string,
autoDownload: PropTypes.bool,
};

WrappedDownloadLink.defaultProps = { href: null, autoDownload: true };

export default WrappedDownloadLink;
7 changes: 5 additions & 2 deletions src/components/common/Json/JsonSwitch/JsonSwitch.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const onCopy = () =>
type: notification.TYPES.SUCCESS,
});

const JsonSwitch = ({ obj, options }) => {
const JsonSwitch = ({ obj, options, jobId }) => {
const { view = {}, table = {} } = options;
const extra = (
<CopyToClipboard text={stringify(obj)} onCopy={onCopy}>
Expand All @@ -36,6 +36,7 @@ const JsonSwitch = ({ obj, options }) => {
obj={obj}
// eslint-disable-next-line
{...table}
jobId={jobId}
/>
</Wrapper>
</Tabs.TabPane>
Expand All @@ -52,9 +53,11 @@ const JsonSwitch = ({ obj, options }) => {

JsonSwitch.propTypes = {
// eslint-disable-next-line
obj: PropTypes.object,
obj: PropTypes.shape({ view: PropTypes.object, table: PropTypes.object }),
// eslint-disable-next-line
options: PropTypes.object,
// eslint-disable-next-line
jobId: PropTypes.string.isRequired,
};
JsonSwitch.defaultProps = {
obj: {},
Expand Down
95 changes: 64 additions & 31 deletions src/components/common/Json/JsonTable/JsonTable.react.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Tag, Typography } from 'antd';
import { Tag, Typography, Button } from 'antd';
import { Descriptions } from 'components/common';
import PropTypes from 'prop-types';
import React from 'react';
import React, { useState, useCallback } from 'react';
import styled from 'styled-components';
import { prop } from 'styled-tools';
import DownloadLink from 'components/DownloadLink';
// TODO: re-write this whole component

const { Text } = Typography;
const EMPTY = `Empty`;

// Helpers

const isPureObject = obj =>
!Array.isArray(obj) && typeof obj === 'object' && obj !== null;
const getTotalColumns = ({ obj, vertical }) =>
Expand All @@ -22,67 +24,98 @@ const Margin = styled(Descriptions)`
`;

// Recursion Step
const RenderItemByValueType = ({ obj, vertical, isMargin = false, key }) =>
isPureObject(obj) ? (
<Margin
key={key}
column={getTotalColumns({ obj, vertical })}
vertical={vertical}
isMargin={isMargin}>
{
// eslint-disable-next-line
objToItem({ obj })
}
</Margin>
) : Array.isArray(obj) ? (
<>
{obj.map((value, i) =>
RenderItemByValueType({
obj: value,
vertical,
isMargin: i !== 0 || i === obj.length - 1,
key: i,
})
)}
</>
) : (
String(obj)
const RenderItemByValueType = ({
obj,
vertical,
isMargin = false,
key,
jobId,
}) => {
const [downloadHref, setDownloadHref] = useState(null);

const handleDownload = useCallback(
() => setDownloadHref(`/flowInput/${jobId}?download=true`),
[jobId, setDownloadHref]
);
if (isPureObject(obj)) {
if (key === 'flowInput' && obj.truncated) {
return (
<>
<Button onClick={handleDownload}>Download</Button>
<DownloadLink href={downloadHref} unset={setDownloadHref} />
</>
);
}
return (
<Margin
key={key}
column={getTotalColumns({ obj, vertical })}
vertical={vertical}
isMargin={isMargin}>
{
// eslint-disable-next-line
objToItem({ obj })
}
</Margin>
);
}
if (Array.isArray(obj)) {
return (
<>
{obj.map((value, i) =>
RenderItemByValueType({
obj: value,
vertical,
isMargin: i !== 0 || i === obj.length - 1,
key: i,
})
)}
</>
);
}
return String(obj);
};

RenderItemByValueType.propTypes = {
/* eslint-disable */
obj: PropTypes.object,
vertical: PropTypes.bool,
isMargin: PropTypes.bool,
key: PropTypes.oneOf([PropTypes.string, PropTypes.number]),
jobId: PropTypes.string,
/* eslint-enable */
};

RenderItemByValueType.defaultProps = {
jobId: null,
};

// Item
const objToItem = ({ obj, vertical }) =>
const objToItem = ({ obj, vertical, jobId }) =>
Object.entries(obj).map(([key, value]) => (
<Descriptions.Item key={key} label={<Text strong>{key}</Text>}>
{isPureObject(value) && isEmptyObject(value) ? (
<Tag>{EMPTY}</Tag>
) : (
RenderItemByValueType({ obj: value, vertical, key })
RenderItemByValueType({ obj: value, vertical, key, jobId })
)}
</Descriptions.Item>
));

// Entry
const JsonTable = ({ obj, vertical = false, ...props }) => (
const JsonTable = ({ obj, vertical = false, jobId, ...props }) => (
<Descriptions
column={getTotalColumns({ obj, vertical })}
vertical={vertical}
{...props}>
{objToItem({ obj, vertical })}
{objToItem({ obj, vertical, jobId })}
</Descriptions>
);
JsonTable.propTypes = {
/* eslint-disable */
obj: PropTypes.object,
vertical: PropTypes.bool,
jobId: PropTypes.string.isRequired,
/* eslint-enable */
};

Expand Down
25 changes: 25 additions & 0 deletions src/hooks/usePipeline.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { selectors } from 'reducers';
import { message } from 'antd';
import client from 'client';
import successMsg from 'config/schema/success-messages.schema';
import useActions from './useActions';
import { useFilter } from './useSearch';

Expand All @@ -22,10 +25,32 @@ const usePipeline = () => {
},
[updateStored]
);

const rerunRawPipeline = useCallback(async (pipeline, jobId) => {
let { flowInput } = pipeline;
try {
if (flowInput?.truncated) {
const flowInputRes = await client.get(`/flowInput/${jobId}`);
if (flowInputRes.data) {
flowInput = flowInputRes.data;
}
}

const res = await client.post('/exec/raw', {
...pipeline,
flowInput,
});
message.success(successMsg(res.data).PIPELINE_START);
} catch (error) {
message.error(error.message);
}
}, []);

return {
collection: filtered,
dataStats,
updateCron,
rerunRawPipeline,
};
};

Expand Down