diff --git a/dinky-web/src/components/FlinkDag/component/DagNode.tsx b/dinky-web/src/components/FlinkDag/component/DagDataNode.tsx
similarity index 74%
rename from dinky-web/src/components/FlinkDag/component/DagNode.tsx
rename to dinky-web/src/components/FlinkDag/component/DagDataNode.tsx
index f645535edb..542191c360 100644
--- a/dinky-web/src/components/FlinkDag/component/DagNode.tsx
+++ b/dinky-web/src/components/FlinkDag/component/DagDataNode.tsx
@@ -18,25 +18,30 @@
*/
import StatusTag from '@/components/JobTags/StatusTag';
-import { Jobs } from '@/types/DevOps/data';
import { Card, Col, Row, Tag, Typography } from 'antd';
-const { Text } = Typography;
+const { Text, Paragraph } = Typography;
-const DagNode = (props: any) => {
+const DagDataNode = (props: any) => {
const { node } = props;
- const vertices: Jobs.JobVertices = node?.getData();
+ const data: any = node?.getData();
return (
{vertices.parallelism}}
+ title={data.name}
+ extra={{data.parallelism}}
>
+
+
+ {data.description}
+
+
+
BackPressure:
@@ -51,7 +56,7 @@ const DagNode = (props: any) => {
Status:
-
+
Idle:50%
@@ -60,4 +65,4 @@ const DagNode = (props: any) => {
);
};
-export default DagNode;
+export default DagDataNode;
diff --git a/dinky-web/src/components/FlinkDag/component/DagPlanNode.tsx b/dinky-web/src/components/FlinkDag/component/DagPlanNode.tsx
new file mode 100644
index 0000000000..cb7cdf2a2a
--- /dev/null
+++ b/dinky-web/src/components/FlinkDag/component/DagPlanNode.tsx
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Card, Typography } from 'antd';
+
+const { Text, Paragraph } = Typography;
+
+const DagPlanNode = (props: any) => {
+ const { node } = props;
+ const data: any = node?.getData();
+
+ return (
+ {data.parallelism}}
+ >
+
+
+ {data.description}
+
+
+
+ );
+};
+export default DagPlanNode;
diff --git a/dinky-web/src/components/FlinkDag/functions.tsx b/dinky-web/src/components/FlinkDag/functions.tsx
index 69c5ee345e..c88cdfab77 100644
--- a/dinky-web/src/components/FlinkDag/functions.tsx
+++ b/dinky-web/src/components/FlinkDag/functions.tsx
@@ -17,94 +17,69 @@
*
*/
+import { JOB_STATUS } from '@/pages/DevOps/constants';
import { Jobs } from '@/types/DevOps/data';
import { Graph, Path } from '@antv/x6';
-export const buildEdge = (job: Jobs.Job) => {
+export const buildDag = (job: Jobs.JobPlan) => {
const edges: any = [];
+ const nodes: any = [];
- for (let node of job.plan.nodes) {
- if (node.inputs) {
- const sources = node.inputs;
- for (let i = 0; i < sources.length; i++) {
- const plan_node = sources[i];
- edges.push({
- attrs: {
- line: {
- strokeDasharray: '5',
- stroke: '#3471F9',
- style: {
- animation: 'running-line 30s infinite linear'
- }
- },
- label: {
- text: plan_node.ship_strategy
- }
- },
- label: plan_node.ship_strategy,
- id: `${plan_node.id}-${i}`,
- shape: 'data-processing-curve',
- zIndex: -1,
- source: {
- cell: `${plan_node.id}`,
- port: `${plan_node.id}-out`
- },
- target: {
- cell: `${node.id}`,
- port: `${node.id}-in`
- },
- data: node
- });
- }
- }
- }
- return edges;
-};
+ if (!job) return { nodes: nodes, edges: edges };
-export const buildNode = (job: Jobs.Job) => {
- const nodes: any = {};
-
- for (let vertice of job.vertices) {
- nodes[vertice.id] = {
- id: vertice.id,
+ job.nodes.forEach((node) => {
+ nodes.push({
+ id: node.id,
shape: 'data-processing-dag-node',
ports: [
{
- id: `${vertice.id}-in`,
+ id: `${node.id}-in`,
group: 'in'
},
{
- id: `${vertice.id}-out`,
+ id: `${node.id}-out`,
group: 'out'
}
],
- data: vertice
- };
- }
- return nodes;
-};
+ data: node
+ });
+
+ node.inputs?.forEach((plan_node) => {
+ edges.push({
+ label: plan_node.ship_strategy,
+ id: `${node.id}-${plan_node.num}`,
+ shape: 'data-processing-curve',
+ zIndex: -1,
+ source: {
+ cell: `${plan_node.id}`,
+ port: `${plan_node.id}-out`
+ },
+ target: {
+ cell: `${node.id}`,
+ port: `${node.id}-in`
+ },
+ data: node
+ });
+ });
+ });
-export const buildData = (job: Jobs.Job) => {
- const nodes = Object.values(buildNode(job));
- return { nodes: nodes, edges: buildEdge(job) };
+ return { nodes: nodes, edges: edges };
};
-export const updateEdge = (job: Jobs.Job, graph?: Graph) => {
- if (graph) {
- const nodes = buildNode(job);
+export const updateDag = (job: Jobs.JobVertices[], graph?: Graph) => {
+ if (!job || !graph) return;
- graph.getCells().forEach((node) => {
- const data = node.getData();
- if (nodes[data.id]) {
- console.log(nodes[data.id]);
- node.setData(nodes[data.id].data);
+ if (job && graph) {
+ job.forEach((vertice) => {
+ const node = graph.getCellById(vertice.id);
+ if (node) {
+ node.setData({ ...node.getData(), ...vertice });
}
});
graph.getEdges().forEach((edge) => {
- const node = edge.getSourceNode()?.getData();
-
- if (node.status == 'RUNNING') {
+ const nodeData = edge.getSourceNode()?.getData();
+ if (nodeData.status == JOB_STATUS.RUNNING) {
edge.attr({ line: { stroke: '#3471F9' } });
edge.attr('line/strokeDasharray', 5);
edge.attr('line/strokeWidth', 2);
@@ -113,11 +88,11 @@ export const updateEdge = (job: Jobs.Job, graph?: Graph) => {
edge.attr('line/strokeDasharray', 0);
edge.attr('line/style/animation', '');
edge.attr('line/strokeWidth', 1);
- if (node.status == 'FINISHED') {
+ if (nodeData.status == JOB_STATUS.FINISHED) {
edge.attr('line/stroke', '#52c41a');
- } else if (node.status == 'CANCELED') {
+ } else if (nodeData.status == JOB_STATUS.CANCELED) {
edge.attr('line/stroke', '#ffe7ba');
- } else if (node.status == 'FAILED') {
+ } else if (nodeData.status == JOB_STATUS.FAILED) {
edge.attr('line/stroke', '#ff4d4f');
} else {
edge.attr('line/stroke', '#bfbfbf');
diff --git a/dinky-web/src/components/FlinkDag/index.tsx b/dinky-web/src/components/FlinkDag/index.tsx
index 1b10892e61..4eff6e5899 100644
--- a/dinky-web/src/components/FlinkDag/index.tsx
+++ b/dinky-web/src/components/FlinkDag/index.tsx
@@ -17,9 +17,10 @@
*
*/
-import DagNode from '@/components/FlinkDag/component/DagNode';
+import DagDataNode from '@/components/FlinkDag/component/DagDataNode';
+import DagPlanNode from '@/components/FlinkDag/component/DagPlanNode';
import { edgeConfig, graphConfig, layoutConfig, portConfig } from '@/components/FlinkDag/config';
-import { buildData, regConnect, updateEdge } from '@/components/FlinkDag/functions';
+import { buildDag, regConnect, updateDag } from '@/components/FlinkDag/functions';
import { Jobs } from '@/types/DevOps/data';
import { DagreLayout } from '@antv/layout';
import { Edge, Graph } from '@antv/x6';
@@ -27,9 +28,16 @@ import { register } from '@antv/x6-react-shape';
import { useEffect, useRef, useState } from 'react';
import './index.css';
-const FlinkDag = (props: { jobDetail: Jobs.JobInfoDetail }) => {
+export type DagProps = {
+ job: Jobs.Job;
+ onlyPlan?: boolean;
+};
+
+const FlinkDag = (props: DagProps) => {
const container = useRef(null);
- const job = props.jobDetail.jobDataDto.job;
+
+ const { job, onlyPlan = false } = props;
+
const [graph, setGraph] = useState();
const [curentJob, setCurentJob] = useState();
@@ -38,7 +46,7 @@ const FlinkDag = (props: { jobDetail: Jobs.JobInfoDetail }) => {
shape: 'data-processing-dag-node',
width: 212,
height: 48,
- component: DagNode,
+ component: onlyPlan ? DagPlanNode : DagDataNode,
ports: portConfig
});
@@ -67,11 +75,12 @@ const FlinkDag = (props: { jobDetail: Jobs.JobInfoDetail }) => {
};
graph.zoomToFit(zoomOptions);
graph.centerContent();
+ updateDag(job.vertices, graph);
return graph;
};
useEffect(() => {
- const flinkData = buildData(job);
+ const flinkData = buildDag(job.plan);
// Clean up old data
if (graph) {
graph.clearCells();
@@ -80,7 +89,7 @@ const FlinkDag = (props: { jobDetail: Jobs.JobInfoDetail }) => {
}, [curentJob]);
useEffect(() => {
- updateEdge(job, graph);
+ updateDag(job.vertices, graph);
if (curentJob != job.jid) {
setCurentJob(job.jid);
}
diff --git a/dinky-web/src/components/JobTags/JobLifeCycleTag.tsx b/dinky-web/src/components/JobTags/JobLifeCycleTag.tsx
new file mode 100644
index 0000000000..d558327863
--- /dev/null
+++ b/dinky-web/src/components/JobTags/JobLifeCycleTag.tsx
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { StatusTagProps } from '@/components/JobTags/data';
+import { JOB_LIFE_CYCLE } from '@/pages/DevOps/constants';
+import { l } from '@/utils/intl';
+import {
+ CameraOutlined,
+ CarryOutOutlined,
+ CloseCircleOutlined,
+ EditOutlined
+} from '@ant-design/icons';
+import { Tag } from 'antd';
+
+/**
+ * Renders a tag for the job life cycle based on the provided step.
+ *
+ * @returns {JSX.Element} - The tag representing the job life cycle.
+ * @param props
+ */
+const JobLifeCycleTag = (props: StatusTagProps) => {
+ const { status, animation = true, bordered = true } = props;
+
+ const buildParam = () => {
+ switch (status) {
+ case JOB_LIFE_CYCLE.DEVELOP:
+ return {
+ icon: ,
+ color: 'default',
+ text: l('global.table.lifecycle.dev')
+ };
+ case JOB_LIFE_CYCLE.RELEASE:
+ return {
+ icon: ,
+ color: 'green',
+ text: l('global.table.lifecycle.publish')
+ };
+
+ case JOB_LIFE_CYCLE.ONLINE:
+ return {
+ icon: ,
+ color: 'blue',
+ text: l('global.table.lifecycle.online')
+ };
+ default:
+ return {
+ icon: ,
+ color: 'default',
+ text: status
+ };
+ }
+ };
+
+ const param = buildParam();
+ return (
+
+ {param.text}
+
+ );
+};
+
+export default JobLifeCycleTag;
diff --git a/dinky-web/src/components/JobTags/StatusTag.tsx b/dinky-web/src/components/JobTags/StatusTag.tsx
index 326819571b..14d8e450b6 100644
--- a/dinky-web/src/components/JobTags/StatusTag.tsx
+++ b/dinky-web/src/components/JobTags/StatusTag.tsx
@@ -16,6 +16,7 @@
*
*/
+import { StatusTagProps } from '@/components/JobTags/data';
import { JOB_STATUS } from '@/pages/DevOps/constants';
import {
CheckCircleOutlined,
@@ -27,12 +28,12 @@ import {
} from '@ant-design/icons';
import { Tag } from 'antd';
-export interface StatusTagProps {
- status: string;
- animation?: boolean;
- bordered?: boolean;
-}
-
+/**
+ * Renders a tag for the job status based on the provided status.
+ *
+ * @returns {JSX.Element} - The tag representing the job status.
+ * @param props
+ */
const StatusTag = (props: StatusTagProps) => {
const { status, animation = true, bordered = true } = props;
@@ -84,8 +85,8 @@ const StatusTag = (props: StatusTagProps) => {
default:
return {
icon: ,
- color: 'error',
- text: 'FAILED'
+ color: 'default',
+ text: 'UNKNOWN Status'
};
}
};
diff --git a/dinky-web/src/components/JobTags/data.d.ts b/dinky-web/src/components/JobTags/data.d.ts
new file mode 100644
index 0000000000..ff0c38f5d2
--- /dev/null
+++ b/dinky-web/src/components/JobTags/data.d.ts
@@ -0,0 +1,5 @@
+export interface StatusTagProps {
+ status?: any;
+ animation?: boolean;
+ bordered?: boolean;
+}
diff --git a/dinky-web/src/pages/DataStudio/HeaderContainer/FlinkGraph/function.tsx b/dinky-web/src/pages/DataStudio/HeaderContainer/FlinkGraph/function.tsx
deleted file mode 100644
index 75167c8180..0000000000
--- a/dinky-web/src/pages/DataStudio/HeaderContainer/FlinkGraph/function.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-const escape2Html = (str: string) => {
- let arrEntities: Record = {
- lt: '<',
- gt: '>',
- nbsp: ' ',
- amp: '&',
- quot: '"'
- };
- return str.replace(/&(lt|gt|nbsp|amp|quot);/gi, function (all, t) {
- return arrEntities[t];
- });
-};
-const getRangeText = (str: string) => {
- str = escape2Html(str);
- // @ts-ignore
- const canvas = getRangeText.canvas || (getRangeText.canvas = document.createElement('canvas'));
- const context = canvas.getContext('2d');
- context.font = '10px sans-serif';
- let result = '';
- let count = 1;
- for (let i = 0, len = str.length; i < len; i++) {
- result += str[i];
- let width = context.measureText(result).width;
- if (width >= 110 * count) {
- result += '\r\n';
- count++;
- }
- }
- return result;
-};
-
-export const buildGraphData = (data: any) => {
- const edges = [];
- for (const i in data.nodes) {
- data.nodes[i].id = data.nodes[i].id.toString();
- data.nodes[i].value = {
- title: data.nodes[i].pact,
- items: [
- {
- text: getRangeText(data.nodes[i].description)
- },
- {
- text: '\r\nParallelism: ',
- value: '\r\n ' + data.nodes[i].parallelism
- }
- ]
- };
- if (data.nodes[i].inputs) {
- for (let j in data.nodes[i].inputs) {
- edges.push({
- source: data.nodes[i].inputs[j].id.toString(),
- target: data.nodes[i].id.toString(),
- value: data.nodes[i].inputs[j].ship_strategy
- });
- }
- }
- }
- data.edges = edges;
- return data;
-};
diff --git a/dinky-web/src/pages/DataStudio/HeaderContainer/FlinkGraph/index.tsx b/dinky-web/src/pages/DataStudio/HeaderContainer/FlinkGraph/index.tsx
index 67653fcd4c..e00e221d71 100644
--- a/dinky-web/src/pages/DataStudio/HeaderContainer/FlinkGraph/index.tsx
+++ b/dinky-web/src/pages/DataStudio/HeaderContainer/FlinkGraph/index.tsx
@@ -1,85 +1,27 @@
-import { FlowAnalysisGraph } from '@ant-design/charts';
-import { FlowAnalysisGraphConfig } from '@ant-design/graphs/es/components/flow-analysis-graph';
+import FlinkDag from '@/components/FlinkDag';
+import { Jobs } from '@/types/DevOps/data';
import { Empty } from 'antd';
import { StateType } from 'rmc-input-number';
import { connect } from 'umi';
-const FlinkGraph = (props: any) => {
+const FlinkGraph = (props: { data: Jobs.JobPlan }) => {
const { data } = props;
- const config: FlowAnalysisGraphConfig = {
- data,
- height: 350,
- nodeCfg: {
- size: [160, 65],
- items: {
- autoEllipsis: false,
- padding: [10],
- containerStyle: {
- fill: '#fff',
- width: '100px'
- },
- style: (cfg, group, type) => {
- const styles = {
- value: {
- fill: '#000'
- },
- text: {
- fill: '#222',
- width: '100px'
- }
- };
- return styles[type];
- }
- },
- nodeStateStyles: {
- hover: {
- stroke: '#1890ff',
- lineWidth: 2
- }
- },
- style: {
- fill: '#40a9ff',
- stroke: '#1890ff'
- }
- },
- edgeCfg: {
- type: 'polyline',
- label: {
- style: {
- fill: '#666',
- fontSize: 12,
- fillOpacity: 1
- }
- },
- endArrow: {
- fill: '#333'
- },
- edgeStateStyles: {
- hover: {
- stroke: '#1890ff',
- lineWidth: 2
- }
- }
- },
- markerCfg: (cfg) => {
- const { edges } = data;
- return {
- position: 'right',
- show: edges.find((item) => item.source === cfg.id),
- collapsed: !edges.find((item) => item.source === cfg.id)
- };
- },
- behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node']
- /*layout: {
- rankdir: 'TB',
- ranksepFunc: () => 20,
- },*/
- };
+ const job = {
+ plan: data
+ } as Jobs.Job;
return (
- <>{data ? : }>
+ <>
+ {data ? (
+
+
+
+ ) : (
+
+ )}
+ >
);
};
-export default connect(({ Studio }: { Studio: StateType }) => ({}))(FlinkGraph);
+export default connect(({}: { Studio: StateType }) => ({}))(FlinkGraph);
diff --git a/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx b/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx
index 2e6466c226..c439f89aa8 100644
--- a/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx
+++ b/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx
@@ -20,7 +20,6 @@ import { FlexCenterDiv } from '@/components/StyledComponents';
import { getCurrentData, getCurrentTab, mapDispatchToProps } from '@/pages/DataStudio/function';
import Explain from '@/pages/DataStudio/HeaderContainer/Explain';
import FlinkGraph from '@/pages/DataStudio/HeaderContainer/FlinkGraph';
-import { buildGraphData } from '@/pages/DataStudio/HeaderContainer/FlinkGraph/function';
import {
buildBreadcrumbItems,
projectCommonShow
@@ -245,7 +244,7 @@ const HeaderContainer = (props: any) => {
title: l('pages.datastudio.editor.explan.tip'),
width: '100%',
icon: null,
- content: ,
+ content: ,
cancelButtonProps: { style: { display: 'none' } }
});
}
diff --git a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/JobOverview.tsx b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/JobOverview.tsx
index dc4dc4d0f8..886af7f529 100644
--- a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/JobOverview.tsx
+++ b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/JobOverview.tsx
@@ -35,7 +35,7 @@ const JobConfigTab = (props: JobProps) => {
height: '40vh'
}}
>
-
+
diff --git a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/FlinkTable.tsx b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/FlinkTable.tsx
index 1cb97587a7..564d7f1c26 100644
--- a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/FlinkTable.tsx
+++ b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/FlinkTable.tsx
@@ -1,4 +1,4 @@
-import { TagJobStatus } from '@/pages/DevOps/function';
+import StatusTag from '@/components/JobTags/StatusTag';
import { JobProps } from '@/pages/DevOps/JobDetail/data';
import { parseByteStr, parseMilliSecondStr, parseNumStr } from '@/utils/function';
import { l } from '@/utils/intl';
@@ -42,7 +42,7 @@ const FlinkTable = (props: JobProps): JSX.Element => {
dataIndex: 'status',
sorter: true,
render: (dom, entity) => {
- return <>{TagJobStatus(entity.status)}>;
+ return ;
}
},
{
diff --git a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx
index d4a808ae4f..3e1f4f6ff9 100644
--- a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx
+++ b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx
@@ -1,4 +1,4 @@
-import { TagJobStatus } from '@/pages/DevOps/function';
+import StatusTag from '@/components/JobTags/StatusTag';
import { JobProps } from '@/pages/DevOps/JobDetail/data';
import { parseSecondStr } from '@/utils/function';
import { l } from '@/utils/intl';
@@ -58,7 +58,7 @@ const JobDesc = (props: JobProps) => {
- {TagJobStatus(jobDetail?.instance?.status)}
+
diff --git a/dinky-web/src/pages/DevOps/JobDetail/index.tsx b/dinky-web/src/pages/DevOps/JobDetail/index.tsx
index cb8b455bf1..a1177ef009 100644
--- a/dinky-web/src/pages/DevOps/JobDetail/index.tsx
+++ b/dinky-web/src/pages/DevOps/JobDetail/index.tsx
@@ -17,8 +17,7 @@
*
*/
-import Lineage from '@/components/FlinkDag';
-import { TagJobLifeCycle } from '@/pages/DevOps/function';
+import JobLifeCycleTag from '@/components/JobTags/JobLifeCycleTag';
import CheckPoints from '@/pages/DevOps/JobDetail/CheckPointsTab';
import JobLogsTab from '@/pages/DevOps/JobDetail/JobLogs/JobLogsTab';
import JobMetrics from '@/pages/DevOps/JobDetail/JobMetrics';
@@ -72,14 +71,14 @@ const JobDetail = (props: any) => {
[OperatorEnum.JOB_VERSION]: ,
[OperatorEnum.JOB_CHECKPOINTS]: ,
[OperatorEnum.JOB_METRICS]: ,
- [OperatorEnum.JOB_LINEAGE]: ,
+ // [OperatorEnum.JOB_LINEAGE]: ,
[OperatorEnum.JOB_ALERT]: ,
[OperatorEnum.JOB_GRAPH]:
};
useRequest(
{
- url: API_CONSTANTS.GET_JOB_DETAIL,
+ url: API_CONSTANTS.REFESH_JOB_DETAIL,
params: { id: id }
},
{
@@ -127,7 +126,7 @@ const JobDetail = (props: any) => {
return (
}
ghost={false}
extra={}
onBack={() => window.history.back()}
diff --git a/dinky-web/src/pages/DevOps/JobList/components/JobHistoryList.tsx b/dinky-web/src/pages/DevOps/JobList/components/JobHistoryList.tsx
index 9119db45c2..86607e0d37 100644
--- a/dinky-web/src/pages/DevOps/JobList/components/JobHistoryList.tsx
+++ b/dinky-web/src/pages/DevOps/JobList/components/JobHistoryList.tsx
@@ -1,4 +1,4 @@
-import { TagJobStatus } from '@/pages/DevOps/function';
+import StatusTag from '@/components/JobTags/StatusTag';
import { queryList } from '@/services/api';
import { API_CONSTANTS } from '@/services/endpoints';
import { Jobs } from '@/types/DevOps/data';
@@ -36,7 +36,7 @@ const JobHistoryList = (props: HistoryProps) => {
{
title: l('global.table.status'),
dataIndex: 'status',
- render: (_: any, row: { status: string | undefined }) => TagJobStatus(row.status)
+ render: (_: any, row: { status: string | undefined }) =>
},
{
title: l('global.table.useTime'),
diff --git a/dinky-web/src/pages/DevOps/JobList/index.tsx b/dinky-web/src/pages/DevOps/JobList/index.tsx
index f2fa9349ca..0800d8be2f 100644
--- a/dinky-web/src/pages/DevOps/JobList/index.tsx
+++ b/dinky-web/src/pages/DevOps/JobList/index.tsx
@@ -1,9 +1,6 @@
-import {
- JOB_STATUS_FILTER,
- LIFECYCLE_FILTER,
- TagJobLifeCycle,
- TagJobStatus
-} from '@/pages/DevOps/function';
+import JobLifeCycleTag from '@/components/JobTags/JobLifeCycleTag';
+import StatusTag from '@/components/JobTags/StatusTag';
+import { JOB_STATUS_FILTER, LIFECYCLE_FILTER } from '@/pages/DevOps/function';
import JobHistoryList from '@/pages/DevOps/JobList/components/JobHistoryList';
import { queryList } from '@/services/api';
import { PROTABLE_OPTIONS_PUBLIC } from '@/services/constants';
@@ -36,7 +33,7 @@ const JobList = () => {
hideInSearch: true,
filterMultiple: false,
dataIndex: 'step',
- render: (_: any, row: { step: number }) => TagJobLifeCycle(row.step)
+ render: (_: any, row: { step: number }) =>
},
{
title: l('global.table.runmode'),
@@ -64,7 +61,7 @@ const JobList = () => {
filterMultiple: false,
hideInSearch: true,
dataIndex: 'status',
- render: (_: any, row: Jobs.JobInstance) => TagJobStatus(row.status)
+ render: (_: any, row: Jobs.JobInstance) =>
},
Table.EXPAND_COLUMN,
{
diff --git a/dinky-web/src/pages/DevOps/function.tsx b/dinky-web/src/pages/DevOps/function.tsx
index dd1b281c3e..86de579110 100644
--- a/dinky-web/src/pages/DevOps/function.tsx
+++ b/dinky-web/src/pages/DevOps/function.tsx
@@ -17,108 +17,6 @@
import { JOB_LIFE_CYCLE, JOB_STATUS } from '@/pages/DevOps/constants';
import { l } from '@/utils/intl';
-import {
- CameraOutlined,
- CarryOutOutlined,
- CheckCircleOutlined,
- ClockCircleOutlined,
- CloseCircleOutlined,
- EditOutlined,
- MinusCircleOutlined,
- QuestionCircleOutlined,
- SyncOutlined
-} from '@ant-design/icons';
-import { Tag } from 'antd';
-
-/**
- * Renders a tag for the job life cycle based on the provided step.
- *
- * @param {number} step - The step in the job life cycle.
- * @returns {JSX.Element} - The tag representing the job life cycle.
- */
-export const TagJobLifeCycle = (step?: number) => {
- switch (step) {
- case JOB_LIFE_CYCLE.DEVELOP:
- return (
- } color='default'>
- {l('global.table.lifecycle.dev')}
-
- );
- case JOB_LIFE_CYCLE.RELEASE:
- return (
- } color='green'>
- {l('global.table.lifecycle.publish')}
-
- );
- case JOB_LIFE_CYCLE.ONLINE:
- return (
- } color='blue'>
- {l('global.table.lifecycle.online')}
-
- );
- default:
- return step;
- }
-};
-
-/**
- * Renders a tag for the job status based on the provided status.
- *
- * @param {string|undefined} status - The status of the job.
- * @returns {JSX.Element} - The tag representing the job status.
- */
-export const TagJobStatus = (status: string | undefined) => {
- switch (status) {
- case JOB_STATUS.RUNNING:
- return (
- } color='green'>
- RUNNING
-
- );
- case JOB_STATUS.FINISHED:
- return (
- } color='blue'>
- FINISHED
-
- );
- case JOB_STATUS.CANCELED:
- return (
- } color='orange'>
- CANCELED
-
- );
- case JOB_STATUS.INITIALIZING:
- return (
- } color='default'>
- INITIALIZING
-
- );
- case JOB_STATUS.RESTARTING:
- return (
- } color='default'>
- RESTARTING
-
- );
- case JOB_STATUS.CREATED:
- return (
- } color='default'>
- CREATED
-
- );
- case JOB_STATUS.UNKNOWN:
- return (
- } color='default'>
- UNKNOWN
-
- );
- default:
- return (
- } color='error'>
- FAILED
-
- );
- }
-};
/**
* Generates an array of options for the life cycle filter.
diff --git a/dinky-web/src/pages/Metrics/Job/index.tsx b/dinky-web/src/pages/Metrics/Job/index.tsx
index 44515cd770..3856c437ee 100644
--- a/dinky-web/src/pages/Metrics/Job/index.tsx
+++ b/dinky-web/src/pages/Metrics/Job/index.tsx
@@ -84,7 +84,7 @@ const Job = () => {
* @returns {Promise}
*/
const getFlinkTaskDetail = async (id: number) => {
- return await getData(API_CONSTANTS.GET_JOB_DETAIL, { id: id });
+ return await getData(API_CONSTANTS.REFESH_JOB_DETAIL, { id: id });
};
/**
diff --git a/dinky-web/src/services/endpoints.tsx b/dinky-web/src/services/endpoints.tsx
index 89d5ec9731..3c6d1d56e1 100644
--- a/dinky-web/src/services/endpoints.tsx
+++ b/dinky-web/src/services/endpoints.tsx
@@ -216,6 +216,7 @@ export enum API_CONSTANTS {
GET_JOB_LIST = '/api/jobInstance',
GET_JOB_BY_ID = '/api/jobInstance/getOneById',
GET_JOB_DETAIL = '/api/jobInstance/getJobInfoDetail',
+ REFESH_JOB_DETAIL = '/api/jobInstance/refreshJobInfoDetail',
GET_JOB_VERSION = '/api/task/version',
GET_JOBMANAGER_LOG = 'api/jobInstance/getJobManagerLog',
GET_JOBMANAGER_STDOUT = 'api/jobInstance/getJobManagerStdOut',
diff --git a/dinky-web/src/types/DevOps/data.d.ts b/dinky-web/src/types/DevOps/data.d.ts
index e4fc47f162..8fe76ce874 100644
--- a/dinky-web/src/types/DevOps/data.d.ts
+++ b/dinky-web/src/types/DevOps/data.d.ts
@@ -93,6 +93,30 @@ declare namespace Jobs {
metrics: VetricsMetrics;
};
+ export type JobNodeInput = {
+ num: number;
+ id: string;
+ ship_strategy: string;
+ exchange: string;
+ };
+
+ export type JobNode = {
+ id: string;
+ parallelism: number;
+ operator: string;
+ operator_strategy: string;
+ description: string;
+ inputs: JobNodeInput[];
+ optimizer_properties: any;
+ };
+
+ export type JobPlan = {
+ jid: string;
+ name: string;
+ type: string;
+ nodes: JobNode[];
+ };
+
export type Job = {
jid: string;
name: string;
@@ -106,8 +130,9 @@ declare namespace Jobs {
timestamps: any;
vertices: JobVertices[];
'status-counts': any;
- plan: any;
+ plan: JobPlan;
};
+
export type JobDataDtoItem = {
id: number;
job: Job;