bill 1 jaar geleden
bovenliggende
commit
36766c959f

+ 10 - 9
src/lib/board/4dmap.d.ts

@@ -423,7 +423,10 @@ type ContainerProps<T extends string = string, R extends Attrib = Attrib, S exte
     data: DATA;
 }>, "attrib">;
 type ContainerEvent = EntityEvent & {
-    active: Entity;
+    active: {
+        active: boolean;
+        entity: Entity;
+    };
     dataChange: void;
     dataChangeBefore: void;
     viewChange: {
@@ -494,6 +497,7 @@ type EntityEvent = {
     mounted: void;
     destroyed: void;
     statusChange: Partial<ShapeStylesStatus> | null;
+    updateAttrib: void;
     shapeStatusChange: {
         type?: "click" | "mouse";
         current: ShapeStylesStatusKey;
@@ -1023,7 +1027,9 @@ type PoiData = {
 type PoiAttrib = Attrib & PoiData;
 declare class Poi<T extends PoiAttrib = PoiAttrib> extends Entity<T, ShapeType> {
     static namespace: string;
+    showLabel: boolean;
     constructor(props: EntityProps<T>);
+    setShowLabel(showLabel: any): void;
     actShape: CustomizeShape<PoiData, ShapeType, {
         getSize: () => number[];
     }>;
@@ -1210,19 +1216,14 @@ type ScaleAttrib = {
 };
 declare class Scale extends Entity<ScaleAttrib, Group> {
     private mat;
-    pixelScale: {
-        value: number;
-        unit: string;
-    };
+    pixelScale: number;
     allowable: number;
     private fontSize;
     private padding;
     get height(): number;
     constructor(props: EntityProps<ScaleAttrib>);
-    getScaleUnit: (pixelScale: number[]) => {
-        value: number;
-        unit: string;
-    };
+    getScaleUnit: (pixelScale: number[]) => number;
+    getScaleText: (value: number) => string;
     initShape(): Group;
     setColor(color: string): void;
     diffRedraw(): void;

File diff suppressed because it is too large
+ 833 - 834
src/lib/board/4dmap.js


File diff suppressed because it is too large
+ 6 - 6
src/lib/board/4dmap.umd.cjs


+ 6 - 0
src/router.ts

@@ -21,6 +21,12 @@ const routes: RouteRecordRaw[] = [
     component: () => import("@/view/login.vue"),
   },
   {
+    path: "/tree2",
+    name: "query-tree-2",
+    meta: { title: "登录" },
+    component: () => import("@/view/step-tree-v2/example/example.vue"),
+  },
+  {
     path: "/tree",
     name: "query-tree",
     meta: { title: "登录" },

+ 1 - 1
src/view/map/coord.vue

@@ -211,7 +211,7 @@ const treeNode = computed(() =>
     disable: !validScene(scene),
     raw: scene,
     children: scene.scenePos.map((pos) => ({
-      label: pos.uuid,
+      label: pos.index || pos.uuid,
       run: scene.calcStatus !== SceneStatus.SUCCESS,
       disable: noValidPoint(pos),
       id: pos.id,

+ 4 - 2
src/view/map/layout.vue

@@ -27,7 +27,9 @@
         <div class="board" :ref="setBoardContainer"></div>
         <div class="map-top-out-pano">
           <template v-if="!isCoordPage">
-            <el-button @click="capture" v-if="loaded"> 提取位置图 </el-button>
+            <el-button @click="capture" v-if="loaded && !queryMode">
+              提取位置图
+            </el-button>
             <el-button @click="showPoints = !showPoints">
               <el-checkbox :modelValue="showPoints" label="点位" size="large" />
             </el-button>
@@ -164,7 +166,7 @@ const capture = async () => {
   await new Promise((resolve) => setTimeout(resolve, 300));
   try {
     const dataURL = await board.toDataURL(2);
-    await saveAs(dataURL, "map.png");
+    await saveAs(dataURL, `${relics.value.name}-位置图.jpg`);
   } finally {
     captureing.value = false;
   }

+ 2 - 5
src/view/map/polygons.vue

@@ -78,6 +78,7 @@ import { getWholeLinePolygonPoints } from "drawing-board";
 import { board, boardDataChange, mapManage, queryMode } from "./install";
 import { confirm } from "@/helper/message";
 import picpenIcon from "@/assets/pic_pen.svg";
+import { relics } from "@/store/relics";
 import { ElMessage } from "element-plus";
 
 const boardStatus = board.polygon.status;
@@ -178,11 +179,7 @@ const handleDownload = async (item: any) => {
     desc: p.title || p.id,
   }));
   console.log(dists, polygonPoints);
-  await downloadPointsXLSL1(
-    points,
-    dists,
-    `${item.name ? item.name : "本体边界" + item.id}`
-  );
+  await downloadPointsXLSL1(points, dists, `${relics!.value.name}-绘制矢量数据.xls`);
 };
 </script>
 

+ 175 - 0
src/view/step-tree-v2/StepTree.vue

@@ -0,0 +1,175 @@
+<template>
+  <div class="tree-layout">
+    <div class="seize back" v-if="ctx" :style="seizeStyle">
+      <div
+        class="tree-group-back"
+        v-for="box in ctx.groupBoxs"
+        :style="{
+          top: box.bound.y + 'px',
+          width: ctx.size.w + ctx.offset.x + 'px',
+          height: box.bound.h + 'px',
+        }"
+      />
+    </div>
+    <svg
+      :viewBox="`${ctx.offset.x} ${ctx.offset.y} ${ctx.size.w} ${ctx.size.h}`"
+      v-if="ctx"
+      :style="{ width: ctx.size.w + 'px', height: ctx.size.h + 'px' }"
+      xmlns="http://www.w3.org/2000/svg"
+    >
+      <template v-for="box in ctx.boxs">
+        <polyline
+          v-for="line in box.lines"
+          :points="line.join(',')"
+          fill="none"
+          :stroke="lineColor"
+          :stroke-width="1"
+        />
+      </template>
+      <template v-for="gbox in ctx.groupBoxs">
+        <polyline
+          :points="gbox.line.join(',')"
+          fill="none"
+          stroke-dasharray="3 3"
+          :stroke="lineColor"
+          :stroke-width="1"
+        />
+      </template>
+    </svg>
+
+    <div class="seize steps" :style="seizeStyle">
+      <div
+        class="tree-item-layout"
+        v-for="(step, i) in steps"
+        :ref="(dom: HTMLDivElement) => setDom(dom, i)"
+        :style="{
+          ...getStepStyle(step),
+          padding: margin.map((p) => p + 'px').join(' '),
+        }"
+      >
+        <div class="tree-item-inner">
+          <slot name="step" :data="step.raw" />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { DataStepTree, flatSteps, getStepsTreeCtx, NStep } from "./helper-v2";
+import { computed, reactive, onUpdated, ref, watch, onMounted } from "vue";
+import { DataStep } from "./type";
+
+const props = withDefaults(
+  defineProps<{
+    margin?: number[];
+    data: DataStep[];
+    group: DataStep[];
+    lineColor?: string;
+  }>(),
+  {
+    margin: () => [10, 10],
+  }
+);
+
+const steps = computed(() => flatSteps(props.data));
+const stepNodes = reactive([]) as HTMLDivElement[];
+
+const getStepStyle = (step: NStep<DataStepTree<DataStep>>) => {
+  if (!ctx.value) return {};
+  const box = ctx.value.boxs.find((box) => box.step === step);
+  return {
+    left: box.offset.x + "px",
+    top: box.offset.y + "px",
+  };
+};
+
+const setDom = (dom: HTMLDivElement, ndx: number) => {
+  if (loaded.value) {
+    stepNodes[ndx] = dom;
+  }
+};
+
+const loaded = ref(false);
+watch(
+  () => props,
+  () => {
+    stepNodes.length = 0;
+    loaded.value = false;
+  },
+  { flush: "pre", deep: true }
+);
+
+onUpdated(() => (loaded.value = true));
+onMounted(() => (loaded.value = true));
+
+const ctx = computed(() => {
+  if (stepNodes.length !== steps.value.length || !loaded.value) return;
+  const ctx = getStepsTreeCtx(
+    steps.value,
+    props.margin,
+    (step) => {
+      const ndx = steps.value.findIndex(({ raw }) => raw === step);
+      const node = stepNodes[ndx];
+      return { w: node.offsetWidth, h: node.offsetHeight };
+    },
+    props.group
+  );
+  console.log(ctx.roots);
+  return ctx;
+});
+
+// 跟svg坐标系保持一致
+const seizeStyle = computed(() => {
+  if (!ctx.value) return {};
+  return {
+    left: -ctx.value.offset.x + "px",
+    top: -ctx.value.offset.y + "px",
+  };
+});
+</script>
+
+<style lang="scss" scoped>
+.tree-layout {
+  display: inline-block;
+  position: relative;
+  overflow: hidden;
+
+  .seize {
+    left: 0;
+    top: 0;
+    width: 9000px;
+    height: 9000px;
+    position: absolute;
+    pointer-events: none;
+
+    &.steps {
+      z-index: 2;
+    }
+
+    &.back {
+      z-index: 1;
+    }
+  }
+
+  svg {
+    position: relative;
+    z-index: 1;
+  }
+}
+
+.tree-group-back {
+  position: absolute;
+  background-color: #f2f2f2;
+  left: 0;
+}
+
+.tree-item-layout {
+  position: absolute;
+  box-sizing: border-box;
+
+  .tree-item-inner {
+    pointer-events: all;
+  }
+}
+</style>

+ 689 - 0
src/view/step-tree-v2/example/data/1.json

@@ -0,0 +1,689 @@
+{
+	"end_time": "2024_07_11_08:48:22",
+	"start_time": "20240711081512",
+	"status": "partsuccess",
+	"steps": [{
+		"displayName": "Stop AP7 And MA7",
+		"name": "step1",
+		"status": "success",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop AP7",
+			"hosts": [{
+				"host": "qlaasap7",
+				"status": "success"
+			}],
+			"name": "step1_1",
+			"serviceType": "AASAP_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MA7",
+			"hosts": [{
+				"host": "qlaasma7",
+				"status": "success"
+			}],
+			"name": "step1_2",
+			"serviceType": "AASMA_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step2",
+		"name": "step2",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "AP7 & MA7 application have closed, next step deploy application",
+			"name": "step2_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Deploy AP7 MA7 PW7 SC7 HT7 And MH7",
+		"name": "step3",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy AP7",
+			"hosts": [{
+				"host": "qlaasap7",
+				"status": "success"
+			}],
+			"name": "step3_1",
+			"serviceType": "AASAP_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MA7",
+			"hosts": [{
+				"host": "qlaasma7",
+				"status": "success"
+			}],
+			"name": "step3_2",
+			"serviceType": "AASMA_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy PW7",
+			"hosts": [{
+				"host": "qlaaspw7",
+				"status": "success"
+			}],
+			"name": "step3_3",
+			"serviceType": "AASPW_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy SC7",
+			"hosts": [{
+				"host": "qlaassc7",
+				"status": "success"
+			}],
+			"name": "step3_4",
+			"serviceType": "AASSC_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy HT7",
+			"hosts": [{
+				"host": "qlaasht7",
+				"status": "success"
+			}],
+			"name": "step3_5",
+			"serviceType": "AASHT_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MH7",
+			"hosts": [{
+				"host": "qlaasmh7",
+				"status": "success"
+			}],
+			"name": "step3_6",
+			"serviceType": "AASMH_part7",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step4",
+		"name": "step4",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Waiting for verify internal environment",
+			"name": "step4_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "stop BM1 BM2 application",
+		"name": "step5",
+		"status": "success",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop BM1",
+			"hosts": [{
+				"host": "qlaasbm1",
+				"status": "success"
+			}],
+			"name": "step5_1",
+			"serviceType": "AASBM_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop BM2",
+			"hosts": [{
+				"host": "qlaasbm2",
+				"status": "success"
+			}],
+			"name": "step5_2",
+			"serviceType": "AASBM_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Deploy BM1 And BM2 application",
+		"name": "step6",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy BM1",
+			"hosts": [{
+				"host": "qlaasbm1",
+				"status": "success"
+			}],
+			"name": "step6_1",
+			"serviceType": "AASBM_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy BM2",
+			"hosts": [{
+				"host": "qlaasbm2",
+				"status": "success"
+			}],
+			"name": "step6_2",
+			"serviceType": "AASBM_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step7",
+		"name": "step7",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Waiting for verify BM1 And BM2 application",
+			"name": "step7_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Stop HT1 And MH1 F5",
+		"name": "step8",
+		"status": "success",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop HT1",
+			"hosts": [{
+				"host": "qlaasht3",
+				"status": "success"
+			}],
+			"name": "step8_1",
+			"serviceType": "AASHT_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MH1",
+			"hosts": [{
+				"host": "qlaasmh1",
+				"status": "success"
+			}],
+			"name": "step8_2",
+			"serviceType": "AASMH_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step9",
+		"name": "step9",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Finish HT1 & MH1 closeF5, next step stop AP1 MA1 PW1 And SC1 application",
+			"name": "step9_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "stop AP1 MA1 PW1 And SC1 application",
+		"name": "step10",
+		"status": "success",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop AP1",
+			"hosts": [{
+				"host": "qlaasap1",
+				"status": "success"
+			}],
+			"name": "step10_1",
+			"serviceType": "AASAP_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MA1",
+			"hosts": [{
+				"host": "qlaasma1",
+				"status": "success"
+			}],
+			"name": "step10_2",
+			"serviceType": "AASMA_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop PW1",
+			"hosts": [{
+				"host": "qlaaspw1",
+				"status": "success"
+			}],
+			"name": "step10_3",
+			"serviceType": "AASPW_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop SC1",
+			"hosts": [{
+				"host": "qlaassc1",
+				"status": "success"
+			}],
+			"name": "step10_4",
+			"serviceType": "AASSC_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step11",
+		"name": "step11",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "all application have closed, next step Deploy all application",
+			"name": "step11_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Deploy AP1 MA1 PW1 And SC1",
+		"name": "step12",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy AP1",
+			"hosts": [{
+				"host": "qlaasap1",
+				"status": "success"
+			}],
+			"name": "step12_1",
+			"serviceType": "AASAP_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MA1",
+			"hosts": [{
+				"host": "qlaasma1",
+				"status": "success"
+			}],
+			"name": "step12_2",
+			"serviceType": "AASMA_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy PW1",
+			"hosts": [{
+				"host": "qlaaspw1",
+				"status": "success"
+			}],
+			"name": "step12_3",
+			"serviceType": "AASPW_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy SC1",
+			"hosts": [{
+				"host": "qlaassc1",
+				"status": "success"
+			}],
+			"name": "step12_4",
+			"serviceType": "AASSC_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Deploy HT1 And MH1",
+		"name": "step13",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy HT1",
+			"hosts": [{
+				"host": "qlaasht3",
+				"status": "success"
+			}],
+			"name": "step13_1",
+			"serviceType": "AASHT_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MH1",
+			"hosts": [{
+				"host": "qlaasmh1",
+				"status": "success"
+			}],
+			"name": "step13_2",
+			"serviceType": "AASMH_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step14",
+		"name": "step14",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Waiting for external services",
+			"name": "step14_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "StartF5 HT1 And MH1",
+		"name": "step15",
+		"status": "success",
+		"steps": [{
+			"action": "start",
+			"displayName": "StartF5 HT1",
+			"hosts": [{
+				"host": "qlaasht3",
+				"status": "success"
+			}],
+			"name": "step15_1",
+			"serviceType": "AASHT_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "start",
+			"displayName": "StartF5 MH1",
+			"hosts": [{
+				"host": "qlaasmh1",
+				"status": "success"
+			}],
+			"name": "step15_2",
+			"serviceType": "AASMH_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Stop HT2 And MH2 closeF5, stop ap2 ma2 pw2 and sc2 application",
+		"name": "step16",
+		"status": "success",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop HT2",
+			"hosts": [{
+				"host": "qlaasht4",
+				"status": "success"
+			}],
+			"name": "step16_1",
+			"serviceType": "AASHT_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MH2",
+			"hosts": [{
+				"host": "qlaasmh2",
+				"status": "success"
+			}],
+			"name": "step16_2",
+			"serviceType": "AASMH_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop AP2",
+			"hosts": [{
+				"host": "qlaasap2",
+				"status": "success"
+			}],
+			"name": "step16_3",
+			"serviceType": "AASAP_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MA2",
+			"hosts": [{
+				"host": "qlaasma2",
+				"status": "success"
+			}],
+			"name": "step16_4",
+			"serviceType": "AASMA_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop PW2",
+			"hosts": [{
+				"host": "qlaaspw2",
+				"status": "success"
+			}],
+			"name": "step16_5",
+			"serviceType": "AASPW_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop SC2",
+			"hosts": [{
+				"host": "qlaassc2",
+				"status": "success"
+			}],
+			"name": "step16_6",
+			"serviceType": "AASSC_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step17",
+		"name": "step17",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Finish HT2 & MH2 closeF5, stop ap2 ma2 pw2 and sc2 application,next step Deploy AP2 MA2 PW2 And SC2",
+			"name": "step17_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Deploy AP2 MA2 PW2 And SC2",
+		"name": "step18",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy AP2",
+			"hosts": [{
+				"host": "qlaasap2",
+				"status": "success"
+			}],
+			"name": "step18_1",
+			"serviceType": "AASAP_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MA2",
+			"hosts": [{
+				"host": "qlaasma2",
+				"status": "success"
+			}],
+			"name": "step18_2",
+			"serviceType": "AASMA_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy PW2",
+			"hosts": [{
+				"host": "qlaaspw2",
+				"status": "success"
+			}],
+			"name": "step18_3",
+			"serviceType": "AASPW_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy SC2",
+			"hosts": [{
+				"host": "qlaassc2",
+				"status": "success"
+			}],
+			"name": "step18_4",
+			"serviceType": "AASSC_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Deploy HT2 And MH2",
+		"name": "step19",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy HT2",
+			"hosts": [{
+				"host": "qlaasht4",
+				"status": "success"
+			}],
+			"name": "step19_1",
+			"serviceType": "AASHT_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MH2",
+			"hosts": [{
+				"host": "qlaasmh2",
+				"status": "success"
+			}],
+			"name": "step19_2",
+			"serviceType": "AASMH_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "StartF5 HT2 And MH2",
+		"name": "step20",
+		"status": "success",
+		"steps": [{
+			"action": "start",
+			"displayName": "StartF5 HT2",
+			"hosts": [{
+				"host": "qlaasht4",
+				"status": "success"
+			}],
+			"name": "step20_1",
+			"serviceType": "AASHT_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "start",
+			"displayName": "StartF5 MH2",
+			"hosts": [{
+				"host": "qlaasmh2",
+				"status": "success"
+			}],
+			"name": "step20_2",
+			"serviceType": "AASMH_part2",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	}],
+	"subStepsParallel": false,
+	"yamlversion": "v1.0"
+}

+ 161 - 0
src/view/step-tree-v2/example/data/2.json

@@ -0,0 +1,161 @@
+{
+	"end_time": "2024_07_09_10:47:34",
+	"start_time": "20240709104623",
+	"status": "success",
+	"steps": [{
+		"displayName": "Stop All Services",
+		"name": "step1",
+		"status": "success",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop app1_part1 Services",
+			"hosts": [{
+				"host": "quadpax1",
+				"status": "success"
+			}],
+			"name": "step1_1",
+			"serviceType": "app1_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"displayName": "Stop app2 Services",
+			"name": "step1_2",
+			"status": "success",
+			"steps": [{
+				"action": "stop",
+				"displayName": "Stop app2_part1 Services",
+				"hosts": [{
+					"host": "quadpax2",
+					"status": "success"
+				}],
+				"name": "step1_2_1",
+				"serviceType": "app2_part1",
+				"serviceTypeParallel": true,
+				"status": "success",
+				"type": "execution"
+			},
+			{
+				"displayName": "Stop app2_part2 Services",
+				"name": "step1_2_2",
+				"status": "success",
+				"steps": [{
+					"action": "stop",
+					"displayName": "Stop app2_part2 Services",
+					"hosts": [{
+						"host": "quadpax3",
+						"status": "success"
+					},
+					{
+						"host": "qladpax3",
+						"status": "success"
+					}],
+					"name": "step1_2_2_1",
+					"serviceType": "app2_part2",
+					"serviceTypeParallel": true,
+					"status": "success",
+					"type": "execution"
+				},
+				{
+					"action": "stop",
+					"displayName": "Stop app2_part3 Services",
+					"hosts": [{
+						"host": "quadpax4",
+						"status": "success"
+					},
+					{
+						"host": "qladpax4",
+						"status": "success"
+					}],
+					"name": "step1_2_2_2",
+					"serviceType": "app2_part3",
+					"serviceTypeParallel": true,
+					"status": "success",
+					"type": "execution"
+				}],
+				"subStepsParallel": true
+			}],
+			"subStepsParallel": true
+		}],
+		"subStepsParallel": false
+	},
+	{
+		"displayName": "step2",
+		"name": "step2",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Waiting",
+			"name": "step2_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "deploy All Services",
+		"name": "step3",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "deploy app1_part1 Services",
+			"hosts": [{
+				"host": "quadpax1",
+				"status": "success"
+			}],
+			"name": "step3_1",
+			"serviceType": "app1_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "deploy app2_part1 Services",
+			"hosts": [{
+				"host": "quadpax2",
+				"status": "success"
+			}],
+			"name": "step3_2",
+			"serviceType": "app2_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "start All Services",
+		"name": "step4",
+		"status": "success",
+		"steps": [{
+			"action": "start",
+			"displayName": "start app1_part1 Services",
+			"hosts": [{
+				"host": "quadpax1",
+				"status": "success"
+			}],
+			"name": "step4_1",
+			"serviceType": "app1_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		},
+		{
+			"action": "start",
+			"displayName": "start app2_part1 Services",
+			"hosts": [{
+				"host": "quadpax2",
+				"status": "success"
+			}],
+			"name": "step4_2",
+			"serviceType": "app2_part1",
+			"serviceTypeParallel": true,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": false
+	}],
+	"subStepsParallel": false,
+	"yamlversion": "v1.0"
+}

+ 689 - 0
src/view/step-tree-v2/example/data/3.json

@@ -0,0 +1,689 @@
+{
+	"end_time": "",
+	"start_time": "20240611181515",
+	"status": "waiting",
+	"steps": [{
+		"displayName": "Stop AP7 And MA7",
+		"name": "step1",
+		"status": "error",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop AP7",
+			"hosts": [{
+				"host": "qlaasap7",
+				"status": "error"
+			}],
+			"name": "step1_1",
+			"serviceType": "AASAP_part7",
+			"serviceTypeParallel": true,
+			"status": "error",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MA7",
+			"hosts": [{
+				"host": "qlaasma7",
+				"status": "error"
+			}],
+			"name": "step1_2",
+			"serviceType": "AASMA_part7",
+			"serviceTypeParallel": true,
+			"status": "error",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step2",
+		"name": "step2",
+		"status": "waiting",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "AP7 & MA7 application have closed, next step deploy application",
+			"name": "step2_1",
+			"status": "waiting",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Deploy AP7 MA7 PW7 SC7 HT7 And MH7",
+		"name": "step3",
+		"status": "waiting",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy AP7",
+			"hosts": [{
+				"host": "qlaasap7",
+				"status": "waiting"
+			}],
+			"name": "step3_1",
+			"serviceType": "AASAP_part7",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MA7",
+			"hosts": [{
+				"host": "qlaasma7",
+				"status": "waiting"
+			}],
+			"name": "step3_2",
+			"serviceType": "AASMA_part7",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy PW7",
+			"hosts": [{
+				"host": "qlaaspw7",
+				"status": "waiting"
+			}],
+			"name": "step3_3",
+			"serviceType": "AASPW_part7",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy SC7",
+			"hosts": [{
+				"host": "qlaassc7",
+				"status": "waiting"
+			}],
+			"name": "step3_4",
+			"serviceType": "AASSC_part7",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy HT7",
+			"hosts": [{
+				"host": "qlaasht7",
+				"status": "waiting"
+			}],
+			"name": "step3_5",
+			"serviceType": "AASHT_part7",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MH7",
+			"hosts": [{
+				"host": "qlaasmh7",
+				"status": "waiting"
+			}],
+			"name": "step3_6",
+			"serviceType": "AASMH_part7",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step4",
+		"name": "step4",
+		"status": "waiting",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Waiting for verify internal environment",
+			"name": "step4_1",
+			"status": "waiting",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "stop BM1 BM2 application",
+		"name": "step5",
+		"status": "waiting",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop BM1",
+			"hosts": [{
+				"host": "qlaasbm1",
+				"status": "waiting"
+			}],
+			"name": "step5_1",
+			"serviceType": "AASBM_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop BM2",
+			"hosts": [{
+				"host": "qlaasbm2",
+				"status": "waiting"
+			}],
+			"name": "step5_2",
+			"serviceType": "AASBM_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Deploy BM1 And BM2 application",
+		"name": "step6",
+		"status": "waiting",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy BM1",
+			"hosts": [{
+				"host": "qlaasbm1",
+				"status": "waiting"
+			}],
+			"name": "step6_1",
+			"serviceType": "AASBM_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy BM2",
+			"hosts": [{
+				"host": "qlaasbm2",
+				"status": "waiting"
+			}],
+			"name": "step6_2",
+			"serviceType": "AASBM_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step7",
+		"name": "step7",
+		"status": "waiting",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Waiting for verify BM1 And BM2 application",
+			"name": "step7_1",
+			"status": "waiting",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Stop HT1 And MH1 F5",
+		"name": "step8",
+		"status": "waiting",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop HT1",
+			"hosts": [{
+				"host": "qlaasht3",
+				"status": "waiting"
+			}],
+			"name": "step8_1",
+			"serviceType": "AASHT_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MH1",
+			"hosts": [{
+				"host": "qlaasmh1",
+				"status": "waiting"
+			}],
+			"name": "step8_2",
+			"serviceType": "AASMH_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step9",
+		"name": "step9",
+		"status": "waiting",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Finish HT1 & MH1 closeF5, next step stop AP1 MA1 PW1 And SC1 application",
+			"name": "step9_1",
+			"status": "waiting",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "stop AP1 MA1 PW1 And SC1 application",
+		"name": "step10",
+		"status": "waiting",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop AP1",
+			"hosts": [{
+				"host": "qlaasap1",
+				"status": "waiting"
+			}],
+			"name": "step10_1",
+			"serviceType": "AASAP_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MA1",
+			"hosts": [{
+				"host": "qlaasma1",
+				"status": "waiting"
+			}],
+			"name": "step10_2",
+			"serviceType": "AASMA_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop PW1",
+			"hosts": [{
+				"host": "qlaaspw1",
+				"status": "waiting"
+			}],
+			"name": "step10_3",
+			"serviceType": "AASPW_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop SC1",
+			"hosts": [{
+				"host": "qlaassc1",
+				"status": "waiting"
+			}],
+			"name": "step10_4",
+			"serviceType": "AASSC_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step11",
+		"name": "step11",
+		"status": "waiting",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "all application have closed, next step Deploy all application",
+			"name": "step11_1",
+			"status": "waiting",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Deploy AP1 MA1 PW1 And SC1",
+		"name": "step12",
+		"status": "waiting",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy AP1",
+			"hosts": [{
+				"host": "qlaasap1",
+				"status": "waiting"
+			}],
+			"name": "step12_1",
+			"serviceType": "AASAP_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MA1",
+			"hosts": [{
+				"host": "qlaasma1",
+				"status": "waiting"
+			}],
+			"name": "step12_2",
+			"serviceType": "AASMA_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy PW1",
+			"hosts": [{
+				"host": "qlaaspw1",
+				"status": "waiting"
+			}],
+			"name": "step12_3",
+			"serviceType": "AASPW_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy SC1",
+			"hosts": [{
+				"host": "qlaassc1",
+				"status": "waiting"
+			}],
+			"name": "step12_4",
+			"serviceType": "AASSC_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Deploy HT1 And MH1",
+		"name": "step13",
+		"status": "waiting",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy HT1",
+			"hosts": [{
+				"host": "qlaasht3",
+				"status": "waiting"
+			}],
+			"name": "step13_1",
+			"serviceType": "AASHT_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MH1",
+			"hosts": [{
+				"host": "qlaasmh1",
+				"status": "waiting"
+			}],
+			"name": "step13_2",
+			"serviceType": "AASMH_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step14",
+		"name": "step14",
+		"status": "waiting",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Waiting for external services",
+			"name": "step14_1",
+			"status": "waiting",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "StartF5 HT1 And MH1",
+		"name": "step15",
+		"status": "waiting",
+		"steps": [{
+			"action": "start",
+			"displayName": "StartF5 HT1",
+			"hosts": [{
+				"host": "qlaasht3",
+				"status": "waiting"
+			}],
+			"name": "step15_1",
+			"serviceType": "AASHT_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "start",
+			"displayName": "StartF5 MH1",
+			"hosts": [{
+				"host": "qlaasmh1",
+				"status": "waiting"
+			}],
+			"name": "step15_2",
+			"serviceType": "AASMH_part1",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Stop HT2 And MH2 closeF5, stop ap2 ma2 pw2 and sc2 application",
+		"name": "step16",
+		"status": "waiting",
+		"steps": [{
+			"action": "stop",
+			"displayName": "Stop HT2",
+			"hosts": [{
+				"host": "qlaasht4",
+				"status": "waiting"
+			}],
+			"name": "step16_1",
+			"serviceType": "AASHT_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MH2",
+			"hosts": [{
+				"host": "qlaasmh2",
+				"status": "waiting"
+			}],
+			"name": "step16_2",
+			"serviceType": "AASMH_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop AP2",
+			"hosts": [{
+				"host": "qlaasap2",
+				"status": "waiting"
+			}],
+			"name": "step16_3",
+			"serviceType": "AASAP_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop MA2",
+			"hosts": [{
+				"host": "qlaasma2",
+				"status": "waiting"
+			}],
+			"name": "step16_4",
+			"serviceType": "AASMA_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop PW2",
+			"hosts": [{
+				"host": "qlaaspw2",
+				"status": "waiting"
+			}],
+			"name": "step16_5",
+			"serviceType": "AASPW_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "stop",
+			"displayName": "Stop SC2",
+			"hosts": [{
+				"host": "qlaassc2",
+				"status": "waiting"
+			}],
+			"name": "step16_6",
+			"serviceType": "AASSC_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "step17",
+		"name": "step17",
+		"status": "waiting",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "Finish HT2 & MH2 closeF5, stop ap2 ma2 pw2 and sc2 application,next step Deploy AP2 MA2 PW2 And SC2",
+			"name": "step17_1",
+			"status": "waiting",
+			"type": "execution"
+		}]
+	},
+	{
+		"displayName": "Deploy AP2 MA2 PW2 And SC2",
+		"name": "step18",
+		"status": "waiting",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy AP2",
+			"hosts": [{
+				"host": "qlaasap2",
+				"status": "waiting"
+			}],
+			"name": "step18_1",
+			"serviceType": "AASAP_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MA2",
+			"hosts": [{
+				"host": "qlaasma2",
+				"status": "waiting"
+			}],
+			"name": "step18_2",
+			"serviceType": "AASMA_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy PW2",
+			"hosts": [{
+				"host": "qlaaspw2",
+				"status": "waiting"
+			}],
+			"name": "step18_3",
+			"serviceType": "AASPW_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy SC2",
+			"hosts": [{
+				"host": "qlaassc2",
+				"status": "waiting"
+			}],
+			"name": "step18_4",
+			"serviceType": "AASSC_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "Deploy HT2 And MH2",
+		"name": "step19",
+		"status": "waiting",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "Deploy HT2",
+			"hosts": [{
+				"host": "qlaasht4",
+				"status": "waiting"
+			}],
+			"name": "step19_1",
+			"serviceType": "AASHT_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "deploy",
+			"displayName": "Deploy MH2",
+			"hosts": [{
+				"host": "qlaasmh2",
+				"status": "waiting"
+			}],
+			"name": "step19_2",
+			"serviceType": "AASMH_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	},
+	{
+		"displayName": "StartF5 HT2 And MH2",
+		"name": "step20",
+		"status": "waiting",
+		"steps": [{
+			"action": "start",
+			"displayName": "StartF5 HT2",
+			"hosts": [{
+				"host": "qlaasht4",
+				"status": "waiting"
+			}],
+			"name": "step20_1",
+			"serviceType": "AASHT_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		},
+		{
+			"action": "start",
+			"displayName": "StartF5 MH2",
+			"hosts": [{
+				"host": "qlaasmh2",
+				"status": "waiting"
+			}],
+			"name": "step20_2",
+			"serviceType": "AASMH_part2",
+			"serviceTypeParallel": true,
+			"status": "waiting",
+			"type": "execution"
+		}],
+		"subStepsParallel": true
+	}],
+	"subStepsParallel": false,
+	"yamlversion": "v1.0"
+}

+ 65 - 0
src/view/step-tree-v2/example/data/4.json

@@ -0,0 +1,65 @@
+{
+	"end_time": "2024_06_28_17:05:39",
+	"start_time": "20240628170507",
+	"status": "success",
+	"steps": [{
+		"displayName": "deploy MGSHZ ",
+		"name": "step1",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "deploy MGSHZ Services",
+			"hosts": [{
+				"host": "qlmgshz1",
+				"status": "success"
+			},
+			{
+				"host": "qlmgshz2",
+				"status": "success"
+			}],
+			"name": "step1_1",
+			"serviceType": "MGSHZ",
+			"serviceTypeParallel": false,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": false
+	},
+	{
+		"displayName": "deploy MGSAZ",
+		"name": "step2",
+		"status": "success",
+		"steps": [{
+			"action": "deploy",
+			"displayName": "deploy MGSAZ Services",
+			"hosts": [{
+				"host": "qlmgsaz1",
+				"status": "success"
+			},
+			{
+				"host": "qlmgsaz2",
+				"status": "success"
+			}],
+			"name": "step2_1",
+			"serviceType": "MGSAZ",
+			"serviceTypeParallel": false,
+			"status": "success",
+			"type": "execution"
+		}],
+		"subStepsParallel": false
+	},
+	{
+		"displayName": "step3",
+		"name": "step3",
+		"status": "success",
+		"steps": [{
+			"action": "humanWaiting",
+			"displayName": "waiting for delpoy DB",
+			"name": "step3_1",
+			"status": "success",
+			"type": "execution"
+		}]
+	}],
+	"subStepsParallel": false,
+	"yamlversion": "v1.0"
+}

+ 811 - 0
src/view/step-tree-v2/example/data/5.json

@@ -0,0 +1,811 @@
+{
+  "end_time": "",
+  "start_time": "20240601085011",
+  "status": "waiting",
+  "steps": [
+    {
+      "displayName": "Stop AP7 And MA7",
+      "name": "step1",
+      "status": "success",
+      "steps": [
+        {
+          "action": "stop",
+          "displayName": "Stop AP7",
+          "hosts": [
+            {
+              "host": "qlaasap7",
+              "status": "success"
+            }
+          ],
+          "name": "step1_1",
+          "serviceType": "AASAP_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop MA7",
+          "hosts": [
+            {
+              "host": "qlaasma7",
+              "status": "success"
+            }
+          ],
+          "name": "step1_2",
+          "serviceType": "AASMA_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "step2",
+      "name": "step2",
+      "status": "success",
+      "steps": [
+        {
+          "action": "humanWaiting",
+          "displayName": "AP7 & MA7 application have closed, next step deploy application",
+          "name": "step2_1",
+          "status": "success",
+          "type": "execution"
+        }
+      ]
+    },
+    {
+      "displayName": "Deploy AP7 MA7 PW7 SC7 HT7 And MH7",
+      "name": "step3",
+      "status": "success",
+      "steps": [
+        {
+          "action": "deploy",
+          "displayName": "Deploy AP7",
+          "hosts": [
+            {
+              "host": "qlaasap7",
+              "status": "success"
+            }
+          ],
+          "name": "step3_1",
+          "serviceType": "AASAP_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy MA7",
+          "hosts": [
+            {
+              "host": "qlaasma7",
+              "status": "success"
+            }
+          ],
+          "name": "step3_2",
+          "serviceType": "AASMA_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy PW7",
+          "hosts": [
+            {
+              "host": "qlaaspw7",
+              "status": "success"
+            }
+          ],
+          "name": "step3_3",
+          "serviceType": "AASPW_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy SC7",
+          "hosts": [
+            {
+              "host": "qlaassc7",
+              "status": "success"
+            }
+          ],
+          "name": "step3_4",
+          "serviceType": "AASSC_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy HT7",
+          "hosts": [
+            {
+              "host": "qlaasht7",
+              "status": "success"
+            }
+          ],
+          "name": "step3_5",
+          "serviceType": "AASHT_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy MH7",
+          "hosts": [
+            {
+              "host": "qlaasmh7",
+              "status": "success"
+            }
+          ],
+          "name": "step3_6",
+          "serviceType": "AASMH_part7",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "step4",
+      "name": "step4",
+      "status": "success",
+      "steps": [
+        {
+          "action": "humanWaiting",
+          "displayName": "Waiting for verify internal environment",
+          "name": "step4_1",
+          "status": "success",
+          "type": "execution"
+        }
+      ]
+    },
+    {
+      "displayName": "stop BM1 BM2 application",
+      "name": "step5",
+      "status": "success",
+      "steps": [
+        {
+          "action": "stop",
+          "displayName": "Stop BM1",
+          "hosts": [
+            {
+              "host": "qlaasbm1",
+              "status": "success"
+            }
+          ],
+          "name": "step5_1",
+          "serviceType": "AASBM_part1",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop BM2",
+          "hosts": [
+            {
+              "host": "qlaasbm2",
+              "status": "success"
+            }
+          ],
+          "name": "step5_2",
+          "serviceType": "AASBM_part2",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "Deploy BM1 And BM2 application",
+      "name": "step6",
+      "status": "success",
+      "steps": [
+        {
+          "action": "deploy",
+          "displayName": "Deploy BM1",
+          "hosts": [
+            {
+              "host": "qlaasbm1",
+              "status": "success"
+            }
+          ],
+          "name": "step6_1",
+          "serviceType": "AASBM_part1",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy BM2",
+          "hosts": [
+            {
+              "host": "qlaasbm2",
+              "status": "success"
+            }
+          ],
+          "name": "step6_2",
+          "serviceType": "AASBM_part2",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "step7",
+      "name": "step7",
+      "status": "success",
+      "steps": [
+        {
+          "action": "humanWaiting",
+          "displayName": "Waiting for verify BM1 And BM2 application",
+          "name": "step7_1",
+          "status": "success",
+          "type": "execution"
+        }
+      ]
+    },
+    {
+      "displayName": "Stop HT1 And MH1 F5",
+      "name": "step8",
+      "status": "success",
+      "steps": [
+        {
+          "action": "stop",
+          "displayName": "Stop HT1",
+          "hosts": [
+            {
+              "host": "qlaasht3",
+              "status": "success"
+            }
+          ],
+          "name": "step8_1",
+          "serviceType": "AASHT_part1",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop MH1",
+          "hosts": [
+            {
+              "host": "qlaasmh1",
+              "status": "success"
+            }
+          ],
+          "name": "step8_2",
+          "serviceType": "AASMH_part1",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "step9",
+      "name": "step9",
+      "status": "running",
+      "steps": [
+        {
+          "action": "humanWaiting",
+          "displayName": "Finish HT1 & MH1 closeF5, next step stop AP1 MA1 PW1 And SC1 application",
+          "name": "step9_1",
+          "status": "running",
+          "type": "execution"
+        }
+      ]
+    },
+    {
+      "displayName": "stop AP1 MA1 PW1 And SC1 application",
+      "name": "step10",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "stop",
+          "displayName": "Stop AP1",
+          "hosts": [
+            {
+              "host": "qlaasap1",
+              "status": "error"
+            }
+          ],
+          "name": "step10_1",
+          "serviceType": "AASAP_part1",
+          "serviceTypeParallel": true,
+          "status": "error",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop MA1",
+          "hosts": [
+            {
+              "host": "qlaasma1",
+              "status": "success"
+            }
+          ],
+          "name": "step10_2",
+          "serviceType": "AASMA_part1",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop PW1",
+          "hosts": [
+            {
+              "host": "qlaaspw1",
+              "status": "success"
+            }
+          ],
+          "name": "step10_3",
+          "serviceType": "AASPW_part1",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop SC1",
+          "hosts": [
+            {
+              "host": "qlaassc1",
+              "status": "success"
+            }
+          ],
+          "name": "step10_4",
+          "serviceType": "AASSC_part1",
+          "serviceTypeParallel": true,
+          "status": "success",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "step11",
+      "name": "step11",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "humanWaiting",
+          "displayName": "all application have closed, next step Deploy all application",
+          "name": "step11_1",
+          "status": "waiting",
+          "type": "execution"
+        }
+      ]
+    },
+    {
+      "displayName": "Deploy AP1 MA1 PW1 And SC1",
+      "name": "step12",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "deploy",
+          "displayName": "Deploy AP1",
+          "hosts": [
+            {
+              "host": "qlaasap1",
+              "status": "waiting"
+            }
+          ],
+          "name": "step12_1",
+          "serviceType": "AASAP_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy MA1",
+          "hosts": [
+            {
+              "host": "qlaasma1",
+              "status": "waiting"
+            }
+          ],
+          "name": "step12_2",
+          "serviceType": "AASMA_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy PW1",
+          "hosts": [
+            {
+              "host": "qlaaspw1",
+              "status": "waiting"
+            }
+          ],
+          "name": "step12_3",
+          "serviceType": "AASPW_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy SC1",
+          "hosts": [
+            {
+              "host": "qlaassc1",
+              "status": "waiting"
+            }
+          ],
+          "name": "step12_4",
+          "serviceType": "AASSC_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "Deploy HT1 And MH1",
+      "name": "step13",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "deploy",
+          "displayName": "Deploy HT1",
+          "hosts": [
+            {
+              "host": "qlaasht3",
+              "status": "waiting"
+            }
+          ],
+          "name": "step13_1",
+          "serviceType": "AASHT_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy MH1",
+          "hosts": [
+            {
+              "host": "qlaasmh1",
+              "status": "waiting"
+            }
+          ],
+          "name": "step13_2",
+          "serviceType": "AASMH_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "step14",
+      "name": "step14",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "humanWaiting",
+          "displayName": "Waiting for external services",
+          "name": "step14_1",
+          "status": "waiting",
+          "type": "execution"
+        }
+      ]
+    },
+    {
+      "displayName": "StartF5 HT1 And MH1",
+      "name": "step15",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "start",
+          "displayName": "StartF5 HT1",
+          "hosts": [
+            {
+              "host": "qlaasht3",
+              "status": "waiting"
+            }
+          ],
+          "name": "step15_1",
+          "serviceType": "AASHT_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "start",
+          "displayName": "StartF5 MH1",
+          "hosts": [
+            {
+              "host": "qlaasmh1",
+              "status": "waiting"
+            }
+          ],
+          "name": "step15_2",
+          "serviceType": "AASMH_part1",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "Stop HT2 And MH2 closeF5, stop ap2 ma2 pw2 and sc2 application",
+      "name": "step16",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "stop",
+          "displayName": "Stop HT2",
+          "hosts": [
+            {
+              "host": "qlaasht4",
+              "status": "waiting"
+            }
+          ],
+          "name": "step16_1",
+          "serviceType": "AASHT_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop MH2",
+          "hosts": [
+            {
+              "host": "qlaasmh2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step16_2",
+          "serviceType": "AASMH_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop AP2",
+          "hosts": [
+            {
+              "host": "qlaasap2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step16_3",
+          "serviceType": "AASAP_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop MA2",
+          "hosts": [
+            {
+              "host": "qlaasma2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step16_4",
+          "serviceType": "AASMA_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop PW2",
+          "hosts": [
+            {
+              "host": "qlaaspw2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step16_5",
+          "serviceType": "AASPW_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "stop",
+          "displayName": "Stop SC2",
+          "hosts": [
+            {
+              "host": "qlaassc2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step16_6",
+          "serviceType": "AASSC_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "step17",
+      "name": "step17",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "humanWaiting",
+          "displayName": "Finish HT2 & MH2 closeF5, stop ap2 ma2 pw2 and sc2 application,next step Deploy AP2 MA2 PW2 And SC2",
+          "name": "step17_1",
+          "status": "waiting",
+          "type": "execution"
+        }
+      ]
+    },
+    {
+      "displayName": "Deploy AP2 MA2 PW2 And SC2",
+      "name": "step18",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "deploy",
+          "displayName": "Deploy AP2",
+          "hosts": [
+            {
+              "host": "qlaasap2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step18_1",
+          "serviceType": "AASAP_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy MA2",
+          "hosts": [
+            {
+              "host": "qlaasma2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step18_2",
+          "serviceType": "AASMA_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy PW2",
+          "hosts": [
+            {
+              "host": "qlaaspw2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step18_3",
+          "serviceType": "AASPW_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy SC2",
+          "hosts": [
+            {
+              "host": "qlaassc2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step18_4",
+          "serviceType": "AASSC_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "Deploy HT2 And MH2",
+      "name": "step19",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "deploy",
+          "displayName": "Deploy HT2",
+          "hosts": [
+            {
+              "host": "qlaasht4",
+              "status": "waiting"
+            }
+          ],
+          "name": "step19_1",
+          "serviceType": "AASHT_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "deploy",
+          "displayName": "Deploy MH2",
+          "hosts": [
+            {
+              "host": "qlaasmh2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step19_2",
+          "serviceType": "AASMH_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    },
+    {
+      "displayName": "StartF5 HT2 And MH2",
+      "name": "step20",
+      "status": "waiting",
+      "steps": [
+        {
+          "action": "start",
+          "displayName": "StartF5 HT2",
+          "hosts": [
+            {
+              "host": "qlaasht4",
+              "status": "waiting"
+            }
+          ],
+          "name": "step20_1",
+          "serviceType": "AASHT_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        },
+        {
+          "action": "start",
+          "displayName": "StartF5 MH2",
+          "hosts": [
+            {
+              "host": "qlaasmh2",
+              "status": "waiting"
+            }
+          ],
+          "name": "step20_2",
+          "serviceType": "AASMH_part2",
+          "serviceTypeParallel": true,
+          "status": "waiting",
+          "type": "execution"
+        }
+      ],
+      "subStepsParallel": true
+    }
+  ],
+  "subStepsParallel": false,
+  "yamlversion": "v1.0"
+}

+ 191 - 0
src/view/step-tree-v2/example/data/6.json

@@ -0,0 +1,191 @@
+{
+    "end_time": "2024_07_12_09:08:54",
+    "start_time": "20240712090823",
+    "status": "success",
+    "steps": [
+        {
+            "displayName": "Stop All Services",
+            "name": "step1",
+            "status": "success",
+            "steps": [
+                {
+                    "action": "stop",
+                    "displayName": "Stop app1_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax1",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step1_1",
+                    "serviceType": "app1_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                },
+                {
+                    "displayName": "Stop app2 Services",
+                    "name": "step1_2",
+                    "status": "success",
+                    "steps": [
+                        {
+                            "action": "stop",
+                            "displayName": "Stop app2_part1 Services",
+                            "hosts": [
+                                {
+                                    "host": "quadpax2",
+                                    "status": "success"
+                                }
+                            ],
+                            "name": "step1_2_1",
+                            "serviceType": "app2_part1",
+                            "serviceTypeParallel": true,
+                            "status": "success",
+                            "type": "execution"
+                        },
+                        {
+                            "displayName": "Stop app2_part2 Services",
+                            "name": "step1_2_2",
+                            "status": "success",
+                            "steps": [
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app2_part2 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax3",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "qladpax3",
+                                            "status": "success"
+                                        }
+                                    ],
+                                    "name": "step1_2_2_1",
+                                    "serviceType": "app2_part2",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                },
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app2_part3 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax4",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "qladpax4",
+                                            "status": "success"
+                                        }
+                                    ],
+                                    "name": "step1_2_2_2",
+                                    "serviceType": "app2_part3",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                }
+                            ],
+                            "subStepsParallel": true
+                        }
+                    ],
+                    "subStepsParallel": false
+                }
+            ],
+            "subStepsParallel": false
+        },
+        {
+            "displayName": "step2",
+            "name": "step2",
+            "status": "success",
+            "steps": [
+                {
+                    "action": "humanWaiting",
+                    "displayName": "Waiting",
+                    "name": "step2_1",
+                    "status": "success",
+                    "type": "execution"
+                }
+            ]
+        },
+        {
+            "displayName": "deploy All Services",
+            "name": "step3",
+            "status": "success",
+            "steps": [
+                {
+                    "action": "deploy",
+                    "displayName": "deploy app1_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax1",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step3_1",
+                    "serviceType": "app1_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                },
+                {
+                    "action": "deploy",
+                    "displayName": "deploy app2_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax2",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step3_2",
+                    "serviceType": "app2_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                }
+            ],
+            "subStepsParallel": true
+        },
+        {
+            "displayName": "start All Services",
+            "name": "step4",
+            "status": "success",
+            "steps": [
+                {
+                    "action": "start",
+                    "displayName": "start app1_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax1",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step4_1",
+                    "serviceType": "app1_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                },
+                {
+                    "action": "start",
+                    "displayName": "start app2_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax2",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step4_2",
+                    "serviceType": "app2_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                }
+            ],
+            "subStepsParallel": false
+        }
+    ],
+    "subStepsParallel": false,
+    "yamlversion": "v1.0"
+}

File diff suppressed because it is too large
+ 1 - 0
src/view/step-tree-v2/example/data/7.json


File diff suppressed because it is too large
+ 1 - 0
src/view/step-tree-v2/example/data/8.json


+ 381 - 0
src/view/step-tree-v2/example/data/9.json

@@ -0,0 +1,381 @@
+{
+    "end_time": "2024_07_12_09:08:54",
+    "start_time": "20240712090823",
+    "status": "success",
+    "steps": [
+        {
+            "displayName": "Stop All Services",
+            "name": "step1",
+            "status": "success",
+            "steps": [
+                {
+                    "displayName": "Stop app1 Services",
+                    "name": "step1_1",
+                    "status": "success",
+                    "steps": [
+                        {
+                            "displayName": "Stop app1_part1 Services",
+                            "name": "step1_1_1",
+                            "status": "success",
+                            "steps": [
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app1_part2 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax3",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax4",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax5",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax6",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax7",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax8",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax9",
+                                            "status": "success"
+                                        }
+                                    ],
+                                    "name": "step1_1_1_1",
+                                    "serviceType": "app1_part2",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                },
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app1_part3 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax4",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "qladpax4",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax5",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax6",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax7",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax8",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax9",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax10",
+                                            "status": "success"
+                                        }
+                                    ],
+                                    "name": "step1_1_1_2",
+                                    "serviceType": "app1_part3",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                }
+                            ],
+                            "subStepsParallel": true
+                        },
+                        {
+                            "displayName": "Stop app1_part2 Services",
+                            "name": "step1_1_2",
+                            "status": "success",
+                            "steps": [
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app1_part2 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax3",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "qladpax3",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax5",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax6",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax7",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax8",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax9",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax10",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax11",
+                                            "status": "success"
+                                        }
+                                        
+                                    ],
+                                    "name": "step1_1_2_1",
+                                    "serviceType": "app1_part2",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                },
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app1_part3 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax4",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "qladpax4",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax5",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax6",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax7",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax8",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax9",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax10",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax11",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "quadpax12",
+                                            "status": "success"
+                                        }
+                                    ],
+                                    "name": "step1_1_2_2",
+                                    "serviceType": "app1_part3",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                }
+                            ],
+                            "subStepsParallel": false
+                        }
+                    ],
+                    "subStepsParallel": true
+                },
+                {
+                    "displayName": "Stop app2 Services",
+                    "name": "step1_2",
+                    "status": "success",
+                    "steps": [
+                        {
+                            "action": "stop",
+                            "displayName": "Stop app2_part1 Services",
+                            "hosts": [
+                                {
+                                    "host": "quadpax2",
+                                    "status": "success"
+                                }
+                            ],
+                            "name": "step1_2_1",
+                            "serviceType": "app2_part1",
+                            "serviceTypeParallel": true,
+                            "status": "success",
+                            "type": "execution"
+                        },
+                        {
+                            "displayName": "Stop app2_part2 Services",
+                            "name": "step1_2_2",
+                            "status": "success",
+                            "steps": [
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app2_part2 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax3",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "qladpax3",
+                                            "status": "success"
+                                        }
+                                    ],
+                                    "name": "step1_2_2_1",
+                                    "serviceType": "app2_part2",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                },
+                                {
+                                    "action": "stop",
+                                    "displayName": "Stop app2_part3 Services",
+                                    "hosts": [
+                                        {
+                                            "host": "quadpax4",
+                                            "status": "success"
+                                        },
+                                        {
+                                            "host": "qladpax4",
+                                            "status": "success"
+                                        }
+                                    ],
+                                    "name": "step1_2_2_2",
+                                    "serviceType": "app2_part3",
+                                    "serviceTypeParallel": true,
+                                    "status": "success",
+                                    "type": "execution"
+                                }
+                            ],
+                            "subStepsParallel": true
+                        }
+                    ],
+                    "subStepsParallel": false
+                }
+            ],
+            "subStepsParallel": false
+        },
+        {
+            "displayName": "step2",
+            "name": "step2",
+            "status": "success",
+            "steps": [
+                {
+                    "action": "humanWaiting",
+                    "displayName": "Waiting",
+                    "name": "step2_1",
+                    "status": "success",
+                    "type": "execution"
+                }
+            ]
+        },
+        {
+            "displayName": "deploy All Services",
+            "name": "step3",
+            "status": "success",
+            "steps": [
+                {
+                    "action": "deploy",
+                    "displayName": "deploy app1_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax1",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step3_1",
+                    "serviceType": "app1_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                },
+                {
+                    "action": "deploy",
+                    "displayName": "deploy app2_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax2",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step3_2",
+                    "serviceType": "app2_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                }
+            ],
+            "subStepsParallel": true
+        },
+        {
+            "displayName": "start All Services",
+            "name": "step4",
+            "status": "success",
+            "steps": [
+                {
+                    "action": "start",
+                    "displayName": "start app1_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax1",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step4_1",
+                    "serviceType": "app1_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                },
+                {
+                    "action": "start",
+                    "displayName": "start app2_part1 Services",
+                    "hosts": [
+                        {
+                            "host": "quadpax2",
+                            "status": "success"
+                        }
+                    ],
+                    "name": "step4_2",
+                    "serviceType": "app2_part1",
+                    "serviceTypeParallel": true,
+                    "status": "success",
+                    "type": "execution"
+                }
+            ],
+            "subStepsParallel": false
+        }
+    ],
+    "subStepsParallel": false,
+    "yamlversion": "v1.0"
+}

+ 113 - 0
src/view/step-tree-v2/example/example.vue

@@ -0,0 +1,113 @@
+<template>
+  <div class="status-box flex">
+    <!-- <span class="defualt">运行中</span> -->
+    <span class="waiting">等待中</span>
+    <span class="running">运行中</span>
+    <span class="succ">成功</span>
+    <span class="bf-suc">部分成功</span>
+    <span class="error">失败</span>
+    <select v-model="activeNdx">
+      <option :value="n" v-for="(_, n) in items">测试数据{{ n }}</option>
+    </select>
+  </div>
+  <div class="tree-cont-wrap" ref="treeWrapRef">
+    <StepTree
+      :data="items[activeNdx].steps"
+      :margin="[25, 25]"
+      lineColor="#89beb2"
+      :group="items[activeNdx].steps"
+    >
+      <template #step="{ data }">
+        <Step
+          :item="data"
+          @click="stepClickHandler(data)"
+          @clickHost="stepHostClickHandler"
+        />
+      </template>
+    </StepTree>
+  </div>
+</template>
+
+<script setup>
+import StepTree from "../StepTree.vue";
+import Step from "./step.vue";
+import data1 from "./data/1.json";
+import data2 from "./data/2.json";
+import data3 from "./data/3.json";
+import data4 from "./data/4.json";
+import data5 from "./data/5.json";
+import data6 from "./data/6.json";
+import data7 from "./data/7.json";
+import data8 from "./data/8.json";
+import data9 from "./data/9.json";
+import { ref, nextTick, toRefs, watchEffect } from "vue";
+import { useRouter } from "vue-router";
+
+const treeWrapRef = ref();
+const $router = useRouter();
+const items = [data1, data2, data3, data4, data5, data6, data7, data8, data9];
+const activeNdx = ref("8");
+
+const stepClickHandler = (step) => {
+  if (step.type === "startEnd") return;
+  let url = $router.resolve({
+    path: "/stepLogs",
+    params: {
+      key: 1,
+    },
+  }).href;
+  window.open(url, "_blank");
+};
+const stepHostClickHandler = (host) => {
+  console.log(host);
+};
+nextTick(() => {
+  treeWrapRef.value.scrollLeft =
+    (treeWrapRef.value.scrollWidth - treeWrapRef.value.clientWidth) / 2;
+});
+</script>
+
+<style scoped>
+.tree-cont-wrap {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  text-align: center;
+}
+
+.flex {
+  display: flex;
+}
+.status-box {
+  width: 400px;
+}
+.status-box span {
+  display: inline-block;
+  width: 120px;
+  height: 30px;
+  line-height: 30px;
+  color: #333;
+  text-align: center;
+  margin: 0 5px;
+}
+/* 运行中 */
+.running {
+  background: #ecf752;
+}
+/* 错误 */
+.error {
+  background: #ff4238;
+}
+/* 成功 */
+.succ {
+  background: #30d567;
+}
+/* 等待中 */
+.waiting {
+  background: #89beb2;
+}
+/* 部分成功 */
+.bf-suc {
+  background: #c6f9ae;
+}
+</style>

BIN
src/view/step-tree-v2/example/image/c.png


BIN
src/view/step-tree-v2/example/image/g.png


BIN
src/view/step-tree-v2/example/image/p.png


BIN
src/view/step-tree-v2/example/image/x.png


+ 108 - 0
src/view/step-tree-v2/example/step.vue

@@ -0,0 +1,108 @@
+<template>
+  <div
+    class="step-layout"
+    @click="emit('click')"
+    :style="{ '--statusColor': currentColor }"
+  >
+    <div class="step-header">
+      <span class="type">{{ item.name }}</span>
+      <span class="title">{{ item.displayName }}</span>
+      <span class="icons">
+        <img src="./image/g.png" v-if="props.item.status === 'success'" />
+        <img src="./image/x.png" v-else-if="props.item.status === 'error'" />
+
+        <template v-if="'serviceTypeParallel' in item">
+          <img src="./image/p.png" v-if="item.serviceTypeParallel" />
+          <img src="./image/c.png" v-else />
+        </template>
+      </span>
+    </div>
+
+    <div class="step-hosts" v-if="item.hosts?.length">
+      <span v-for="host in item.hosts" @click.stop="$emit('clickHost', host)">
+        {{ host.host }}
+      </span>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { DataStep } from "../type";
+import { computed } from "vue";
+
+const props = defineProps<{ item: DataStep }>();
+const emit = defineEmits<{
+  (e: "click"): void;
+  (e: "clickHost", host: DataStep["hosts"][number]): void;
+}>();
+
+const defaultColor = "#d4f8c3";
+const colorMap = {
+  success: "#30d567",
+  error: "#ff4238",
+  running: "#ecf752",
+  waiting: "#89beb2",
+};
+const currentColor = computed(() =>
+  props.item.status in colorMap ? colorMap[props.item.status] : defaultColor
+);
+</script>
+
+<style scoped lang="scss">
+.step-layout {
+  border-radius: 8px;
+  color: rgb(51, 51, 51);
+  font-family: "微软雅黑";
+  background-color: var(--pColor);
+  max-width: 400px;
+  min-width: 100px;
+  text-align: center;
+  overflow: hidden;
+  cursor: pointer;
+}
+
+.step-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 14px;
+  padding: 8px 10px;
+  background: #8ebeb2;
+
+  .type {
+    font-weight: bold;
+  }
+
+  .title {
+    margin: 0 20px;
+  }
+
+  .icons {
+    img {
+      width: 20px;
+      height: 20px;
+      :not(:last-child) {
+        margin-right: 5px;
+      }
+    }
+  }
+}
+
+.step-hosts {
+  padding: 5px;
+  display: flex;
+  justify-content: center;
+  background: #fff;
+  font-size: 12px;
+  flex-wrap: wrap;
+
+  span {
+    padding: 6px 10px;
+    border: 2px solid var(--statusColor);
+    color: var(--statusColor);
+    border-radius: 6px;
+    cursor: pointer;
+    margin: 5px;
+  }
+}
+</style>

+ 221 - 0
src/view/step-tree-v2/helper-v2.ts

@@ -0,0 +1,221 @@
+import { getStepLine, Step, traversalSteps } from "./tree-helper";
+import {
+  getStepsTreeCtx as getStepsTreeCtxRaw,
+  StepsCtx as StepsCtxRaw,
+} from "./tree-helper";
+
+type DataStep = {
+  serviceTypeParallel?: boolean | "True" | "Flase";
+  subStepsParallel?: boolean | "True" | "Flase";
+};
+export type DataStepTree<T extends DataStep = DataStep> = T & {
+  steps: DataStepTree<T>[];
+};
+
+export type NStep<T extends DataStepTree> = Step<T>;
+
+const _flatSteps = <T extends DataStep>(
+  steps: DataStepTree<T>[],
+  nsteps: NStep<DataStepTree<T>>[] = [],
+  parents: NStep<DataStepTree<T>>[] = [],
+  parallel = false
+) => {
+  const lonelySteps: NStep<DataStepTree<T>>[] = [];
+  let tempParents = parents;
+
+  for (const step of steps) {
+    const stepParallel = parallel;
+    if (!stepParallel && lonelySteps.length) {
+      tempParents = [...lonelySteps];
+      lonelySteps.length = 0;
+    }
+    const nstep = {
+      raw: step,
+      children: [],
+      parents: tempParents,
+    } as NStep<DataStepTree<T>>;
+    nsteps.push(nstep);
+    tempParents.forEach((parent) => parent.children.push(nstep));
+
+    if (step.steps && step.steps.length) {
+      step.serviceTypeParallel;
+      lonelySteps.push(
+        ..._flatSteps(
+          step.steps,
+          nsteps,
+          [nstep],
+          step.subStepsParallel === "True" ||
+            step.serviceTypeParallel === "True" ||
+            !!step.subStepsParallel ||
+            !!step.serviceTypeParallel
+        )
+      );
+    } else {
+      lonelySteps.push(nstep);
+    }
+  }
+
+  return lonelySteps;
+};
+
+export const flatSteps = <T extends DataStep>(steps: DataStepTree<T>[]) => {
+  const nsteps: NStep<DataStepTree<T>>[] = [];
+  _flatSteps(steps, nsteps);
+  return nsteps;
+};
+
+// 获取step所有子级
+const getStepFlatSteps = <T extends DataStep>(step: DataStepTree<T>) => {
+  if (!step.steps || step.steps.length === 0) return [];
+
+  const children: DataStepTree<T>[] = [];
+  for (const child of step.steps) {
+    children.push(child);
+    children.push(...getStepFlatSteps(child));
+  }
+
+  return children;
+};
+
+// 获取steps组成的bound
+const getStepsBound = <T>(nsteps: NStep<DataStepTree<T>>[]) => {
+  const bounds = nsteps.map((nstep) => {
+    return { ...nstep.box.offset, ...nstep.box.size };
+  });
+
+  let maxX = -Number.MAX_VALUE,
+    maxY = -Number.MAX_VALUE,
+    minX = Number.MAX_VALUE,
+    minY = Number.MAX_VALUE;
+  for (const bound of bounds) {
+    minX = Math.min(bound.x, minX);
+    minY = Math.min(bound.y, minY);
+    maxX = Math.max(bound.x + bound.w, maxX);
+    maxY = Math.max(bound.y + bound.h, maxY);
+  }
+  return {
+    x: minX,
+    y: minY,
+    w: maxX - minX,
+    h: maxY - minY,
+  };
+};
+
+export type StepsCtx<T> = StepsCtxRaw<T> & {
+  groupBoxs: {
+    step: Step<T>;
+    bound: { w: number; h: number; x: number; y: number };
+    line: number[][];
+  }[];
+};
+
+const setGroupBack = <T>(
+  steps: NStep<DataStepTree<T>>[],
+  ctx: StepsCtx<DataStepTree<T>>,
+  groups: NStep<DataStepTree<T>>[]
+) => {
+  const maxWidth = Math.max(...groups.map(({ box }) => box.size.w));
+  for (const groupStep of groups) {
+    const children = getStepFlatSteps(groupStep.raw);
+    const childSteps = children.map((raw) =>
+      steps.find((step) => raw === step.raw)
+    );
+    ctx.groupBoxs.push({
+      step: groupStep,
+      line: [],
+      bound: getStepsBound(childSteps),
+    });
+    groupStep.box.offset.x = -maxWidth + (maxWidth - groupStep.box.size.w) / 2;
+  }
+  ctx.offset.x = -maxWidth;
+  ctx.size.w += maxWidth;
+};
+
+const setGroupOffset = <T>(
+  steps: NStep<DataStepTree<T>>[],
+  ctx: StepsCtx<DataStepTree<T>>,
+  groupSteps: NStep<DataStepTree<T>>[],
+  margin: number
+) => {
+  // margin = 0;
+  const offsetYs: number[] = [];
+  const offsetLYs: number[] = [];
+  for (let i = 0; i < groupSteps.length; i++) {
+    const groupStep = groupSteps[i];
+    if (i > 0) {
+      offsetYs[i] = -groupStep.box.size.h + offsetYs[i - 1] + margin;
+      offsetLYs[i] = offsetLYs[i - 1] - groupStep.box.size.h + margin;
+    } else {
+      offsetYs[i] = -groupStep.box.size.h + margin;
+      offsetLYs[i] = -groupStep.box.size.h + margin;
+    }
+
+    groupStep.box.offset.y += margin;
+  }
+  let offsetNdx = offsetYs.length - 1;
+  let offsetLNdx = offsetYs.length - 1;
+
+  traversalSteps({
+    steps,
+    ctx,
+    oper: ({ currents }) => {
+      const isBorder = currents.some((current) => groupSteps.includes(current));
+      if (isBorder) {
+        offsetNdx -= 1;
+      }
+
+      for (const current of currents) {
+        if (offsetNdx === -1) {
+          current.box.lines = [];
+          break;
+        }
+        current.box.offset.y += offsetYs[offsetNdx];
+        for (const points of current.box.lines) {
+          for (const point of points) {
+            point[1] = point[1] + offsetLYs[offsetLNdx];
+          }
+        }
+      }
+      if (isBorder) {
+        offsetLNdx -= 1;
+      }
+    },
+    reverse: true,
+  });
+
+  ctx.size.h += offsetYs[offsetYs.length - 1];
+};
+
+export const setGroupLine = <T>(
+  ctx: StepsCtx<DataStepTree<T>>,
+  groupSteps: NStep<DataStepTree<T>>[],
+  margin: number[]
+) => {
+  for (let i = 0; i < groupSteps.length - 1; i++) {
+    ctx.groupBoxs[i].line = getStepLine(
+      ctx,
+      groupSteps[i],
+      groupSteps[i + 1],
+      margin
+    );
+  }
+};
+
+export const getStepsTreeCtx = <T extends DataStep>(
+  steps: NStep<DataStepTree<T>>[],
+  margin: number[],
+  getStepSize: (step: T) => { w: number; h: number },
+  groups: DataStepTree<T>[]
+) => {
+  const ctx = getStepsTreeCtxRaw(steps, margin, getStepSize) as StepsCtx<
+    DataStepTree<T>
+  >;
+  const groupSteps = groups.map((group) =>
+    steps.find((step) => group === step.raw)
+  );
+  setGroupOffset(steps, ctx, groupSteps, margin[0]);
+  ctx.groupBoxs = [];
+  setGroupBack(steps, ctx, groupSteps);
+  setGroupLine(ctx, groupSteps, margin);
+  return ctx;
+};

+ 332 - 0
src/view/step-tree-v2/tree-helper.ts

@@ -0,0 +1,332 @@
+export type Step<T> = {
+  raw: T;
+  parents: Step<T>[];
+  children: Step<T>[];
+  box: StepCtx<T>;
+};
+export type Steps<T> = Step<T>[];
+
+export type StepCtx<T> = {
+  level: number;
+  step: Step<T>;
+  // 自身大小
+  size: { w: number; h: number };
+  // 如果是多对一则存储多宽度
+  parallelWidth?: number;
+  // 树宽高
+  treeSize?: { w: number; h: number };
+  // 相对于兄弟
+  offset: { x: number; y: number };
+  treeOffset: { x: number; y: number };
+  lines: number[][][];
+};
+
+export type StepsCtx<T> = {
+  levelHeight: number[];
+  boxs: StepCtx<T>[];
+  roots: Step<T>[];
+  offset: { x: number; y: number };
+  size: { w: number; h: number };
+};
+
+type traversalStepsProps<T> = {
+  steps: Steps<T>;
+  ctx: StepsCtx<T>;
+  oper: (data: {
+    currents: Step<T>[];
+    prev: Step<T> | null;
+    next: Step<T> | null;
+    levelSteps: Step<T>[];
+  }) => void;
+  cs?: Step<T>[];
+  checkeds?: Steps<T>;
+  level?: number;
+  reverse?: boolean;
+};
+
+const setStepsLevel = <T>(
+  steps: Steps<T>,
+  ctx: StepsCtx<T>,
+  level = 0,
+  cs: Step<T>[] = ctx.roots
+) => {
+  if (cs && cs.length === 0) return;
+  const cSteps = cs;
+
+  for (let i = 0; i < cSteps.length; i++) {
+    const current = cSteps[i];
+    if ("level" in current.box) {
+      current.box.level = Math.max(level, current.box.level);
+    } else {
+      (current.box as any).level = level;
+    }
+    ctx.levelHeight[level] = 0;
+    setStepsLevel(steps, ctx, level + 1, current.children);
+  }
+};
+
+export const traversalSteps = <T>({
+  steps,
+  ctx,
+  oper,
+  cs = ctx.roots,
+  level = 0,
+  reverse = false,
+  checkeds = [],
+}: traversalStepsProps<T>) => {
+  if (cs.length === 0) return;
+  const cSteps = cs;
+
+  for (let i = 0; i < cSteps.length; i++) {
+    const current = cSteps[i];
+    if (checkeds.includes(current)) continue;
+    const children = current.children.filter(
+      (child) => child.box.level === level + 1
+    );
+
+    // 查看是否是多对一的情况,如果是这current为所有多的step
+    let currents = [current];
+    if (children.length === 1 && children[0].parents.length > 1) {
+      const steps = children[0].parents;
+      currents = steps.filter((step) => step.box.level === level);
+    }
+    checkeds.push(...currents);
+
+    const props = {
+      currents: currents,
+      prev: cSteps[i - 1] || null,
+      next: cSteps[i + 1] || null,
+      level: level,
+      levelSteps: cSteps,
+    };
+
+    reverse || oper(props);
+    traversalSteps({
+      steps,
+      ctx,
+      oper,
+      cs: current.children,
+      level: level + 1,
+      reverse,
+      checkeds,
+    });
+    reverse && oper(props);
+  }
+};
+
+const setStepsBound = <T>(
+  steps: Steps<T>,
+  ctx: StepsCtx<T>,
+  getStepSize: (step: T) => { w: number; h: number }
+) => {
+  // 注入levelHeights, box size offset
+  traversalSteps({
+    steps,
+    ctx,
+    oper: ({ currents }) => {
+      currents.forEach((current) => {
+        const size = getStepSize(current.raw);
+        current.box.size = size;
+        ctx.levelHeight[current.box.level] = Math.max(
+          size.h,
+          ctx.levelHeight[current.box.level] || 0
+        );
+      });
+    },
+  });
+};
+
+const setStepsTreeSize = <T>(steps: Steps<T>, ctx: StepsCtx<T>) => {
+  // 从低到顶分别计算树大小
+  traversalSteps({
+    steps,
+    ctx,
+    oper: ({ currents }) => {
+      let levelHeight = 0;
+      const level = currents[0].box.level;
+      for (let i = 0; i <= level; i++) {
+        levelHeight += ctx.levelHeight[i];
+      }
+      const current = currents[0];
+      const treeSize = { w: 0, h: 0 };
+      for (const child of current.children) {
+        if (child.box.treeSize) {
+          treeSize.w += child.box.treeSize.w;
+          treeSize.h = Math.max(child.box.treeSize.w, treeSize.w);
+        }
+      }
+      treeSize.h += levelHeight;
+
+      if (currents.length === 1) {
+        // 一对一  一对多情况
+        treeSize.w = Math.max(current.box.size.w, treeSize.w);
+        current.box.treeSize = treeSize;
+      } else {
+        // 多对一情况
+        let parallelWidth = 0;
+        for (const parallel of currents) {
+          parallelWidth += parallel.box.size.w;
+        }
+        treeSize.w = Math.max(parallelWidth, treeSize.w);
+        currents[0].box.parallelWidth = parallelWidth;
+        currents[0].box.treeSize = treeSize;
+      }
+    },
+    reverse: true,
+  });
+};
+
+const setStepsOffset = <T>(steps: Steps<T>, ctx: StepsCtx<T>) => {
+  // 从顶到底分别计算树偏移量以及step偏移
+  traversalSteps({
+    steps,
+    ctx,
+    oper: ({ currents, prev }) => {
+      const box = currents[0].box;
+      let levelHeight = 0;
+      const level = currents[0].box.level;
+      for (let i = 0; i < level; i++) {
+        levelHeight += ctx.levelHeight[i];
+      }
+
+      const treeOffset = { x: 0, y: levelHeight };
+
+      if (prev) {
+        // 上一个是普通树
+        if (prev.box.treeOffset) {
+          treeOffset.x += prev.box.treeOffset.x + prev.box.treeSize.w;
+        } else {
+          // 上一个是多对一树,需要找到box属性值
+          let prevTreeBox: StepCtx<T>;
+          for (const prevParent of prev.parents) {
+            for (let prevLevel of prevParent.children) {
+              if (prevLevel.box.treeOffset) {
+                prevTreeBox = prevLevel.box;
+                break;
+              }
+            }
+            if (prevTreeBox) break;
+          }
+          treeOffset.x += prevTreeBox.treeOffset.x + prevTreeBox.parallelWidth;
+        }
+      } else if (currents[0].parents.length) {
+        // 如果是第一个,则需要计算子级,相对父级做偏移
+        const parents = currents[0].parents;
+        const levels = new Set(parents.flatMap((parent) => parent.children));
+        let levelWidth = 0;
+        for (const levelStep of levels) {
+          if ("parallelWidth" in levelStep.box) {
+            levelWidth += levelStep.box.parallelWidth;
+          } else if (levelStep.box.treeSize) {
+            levelWidth += levelStep.box.treeSize.w || 0;
+          }
+        }
+
+        let parentWidth = 0;
+        for (const parent of parents) {
+          parentWidth +=
+            "parallelWidth" in parent.box
+              ? parent.box.parallelWidth
+              : "treeSize" in parent.box
+              ? parent.box.treeSize.w
+              : 0;
+        }
+
+        treeOffset.x +=
+          parents[0].box.treeOffset.x + (parentWidth - levelWidth) / 2;
+      }
+
+      box.treeOffset = { ...treeOffset };
+      if ("parallelWidth" in box) {
+        let lOffset = 0;
+        for (const current of currents) {
+          current.box.offset = {
+            x: treeOffset.x + lOffset,
+            y: treeOffset.y + (ctx.levelHeight[level] - current.box.size.h) / 2,
+          };
+          lOffset += current.box.size.w;
+        }
+      } else {
+        treeOffset.x += (box.treeSize.w - box.size.w) / 2;
+        treeOffset.y += (ctx.levelHeight[level] - box.size.h) / 2;
+
+        box.offset = treeOffset;
+      }
+    },
+  });
+};
+
+const setStepsLines = <T>(
+  steps: Steps<T>,
+  ctx: StepsCtx<T>,
+  margin: number[]
+) => {
+  traversalSteps({
+    steps,
+    ctx,
+    oper: ({ currents }) => {
+      for (const current of currents) {
+        current.box.lines = current.children.map((child) =>
+          getStepLine(ctx, current, child, margin)
+        );
+      }
+    },
+  });
+};
+
+export const getStepLine = <T>(
+  ctx: StepsCtx<T>,
+  topStep: Step<T>,
+  bottomStep: Step<T>,
+  margin: number[] = [0, 0]
+) => {
+  const top = topStep.box;
+  const bottom = bottomStep.box;
+  const bottomHeight = ctx.levelHeight[bottom.level];
+  const start = [
+    top.offset.x + top.size.w / 2,
+    top.offset.y + top.size.h - margin[0],
+  ];
+
+  const diffHeight = (bottomHeight - bottom.size.h) / 2;
+
+  const c1 = [top.offset.x + top.size.w / 2, bottom.offset.y - diffHeight];
+  const c2 = [
+    bottom.offset.x + bottom.size.w / 2,
+    bottom.offset.y - diffHeight,
+  ];
+  const end = [
+    bottom.offset.x + bottom.size.w / 2,
+    bottom.offset.y + margin[0],
+  ];
+  return [start, c1, c2, end];
+};
+
+export const getStepsTreeCtx = <T>(
+  steps: Steps<T>,
+  margin: number[],
+  getStepSize: (step: T) => { w: number; h: number }
+) => {
+  const roots = steps.filter((step) => step.parents.length === 0);
+  const ctx: StepsCtx<T> = {
+    size: { w: 0, h: 0 },
+    offset: { x: 0, y: 0 },
+    levelHeight: [],
+    boxs: steps.map((step) => {
+      const box = { step } as any;
+      step.box = box;
+      step.box.lines = [];
+      return box;
+    }),
+    roots: roots,
+  };
+  setStepsLevel(steps, ctx);
+  setStepsBound(steps, ctx, getStepSize);
+  setStepsTreeSize(steps, ctx);
+  setStepsOffset(steps, ctx);
+  setStepsLines(steps, ctx, margin);
+
+  ctx.size.w = roots.reduce((t, root) => t + root.box.treeSize.w, 0);
+  ctx.size.h = ctx.levelHeight.reduce((t, h) => t + h, 0);
+  return ctx;
+};

+ 11 - 0
src/view/step-tree-v2/type.ts

@@ -0,0 +1,11 @@
+export type DataStep = {
+  action?: string;
+  displayName: string;
+  hosts?: { host: string; status: string }[];
+  name: string;
+  serviceType?: string;
+  serviceTypeParallel?: boolean;
+  status?: string;
+  type?: string;
+  steps: DataStep[];
+};

+ 95 - 720
src/view/step-tree/example/data.ts

@@ -1,46 +1,100 @@
 export default [
   {
-    end_time: "",
-    start_time: "20240601085011",
-    status: "waiting",
+    end_time: "2024_07_09_10:47:34",
+    start_time: "20240709104623",
+    status: "success",
     steps: [
       {
-        displayName: "Stop AP7 And MA7",
+        displayName: "Stop All Services",
         name: "step1",
         status: "success",
         steps: [
           {
             action: "stop",
-            displayName: "Stop AP7",
+            displayName: "Stop app1_part1 Services",
             hosts: [
               {
-                host: "qlaasap7",
+                host: "quadpax1",
                 status: "success",
               },
             ],
             name: "step1_1",
-            serviceType: "AASAP_part7",
+            serviceType: "app1_part1",
             serviceTypeParallel: true,
             status: "success",
             type: "execution",
           },
           {
-            action: "stop",
-            displayName: "Stop MA7",
-            hosts: [
-              {
-                host: "qlaasma7",
-                status: "success",
-              },
-            ],
+            displayName: "Stop app2 Services",
             name: "step1_2",
-            serviceType: "AASMA_part7",
-            serviceTypeParallel: true,
             status: "success",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
+            steps: [
+              {
+                action: "stop",
+                displayName: "Stop app2_part1 Services",
+                hosts: [
+                  {
+                    host: "quadpax2",
+                    status: "success",
+                  },
+                ],
+                name: "step1_2_1",
+                serviceType: "app2_part1",
+                serviceTypeParallel: true,
+                status: "success",
+                type: "execution",
+              },
+              {
+                displayName: "Stop app2_part2 Services",
+                name: "step1_2_2",
+                status: "success",
+                steps: [
+                  {
+                    action: "stop",
+                    displayName: "Stop app2_part2 Services",
+                    hosts: [
+                      {
+                        host: "quadpax3",
+                        status: "success",
+                      },
+                      {
+                        host: "qladpax3",
+                        status: "success",
+                      },
+                    ],
+                    name: "step1_2_2_1",
+                    serviceType: "app2_part2",
+                    serviceTypeParallel: true,
+                    status: "success",
+                    type: "execution",
+                  },
+                  {
+                    action: "stop",
+                    displayName: "Stop app2_part3 Services",
+                    hosts: [
+                      {
+                        host: "quadpax4",
+                        status: "success",
+                      },
+                      {
+                        host: "qladpax4",
+                        status: "success",
+                      },
+                    ],
+                    name: "step1_2_2_2",
+                    serviceType: "app2_part3",
+                    serviceTypeParallel: true,
+                    status: "success",
+                    type: "execution",
+                  },
+                ],
+                subStepsParallel: true,
+              },
+            ],
+            subStepsParallel: true,
+          },
+        ],
+        subStepsParallel: false,
       },
       {
         displayName: "step2",
@@ -49,8 +103,7 @@ export default [
         steps: [
           {
             action: "humanWaiting",
-            displayName:
-              "AP7 & MA7 application have closed, next step deploy application",
+            displayName: "Waiting",
             name: "step2_1",
             status: "success",
             type: "execution",
@@ -58,96 +111,36 @@ export default [
         ],
       },
       {
-        displayName: "Deploy AP7 MA7 PW7 SC7 HT7 And MH7",
+        displayName: "deploy All Services",
         name: "step3",
         status: "success",
         steps: [
           {
             action: "deploy",
-            displayName: "Deploy AP7",
+            displayName: "deploy app1_part1 Services",
             hosts: [
               {
-                host: "qlaasap7",
+                host: "quadpax1",
                 status: "success",
               },
             ],
             name: "step3_1",
-            serviceType: "AASAP_part7",
+            serviceType: "app1_part1",
             serviceTypeParallel: true,
             status: "success",
             type: "execution",
           },
           {
             action: "deploy",
-            displayName: "Deploy MA7",
+            displayName: "deploy app2_part1 Services",
             hosts: [
               {
-                host: "qlaasma7",
+                host: "quadpax2",
                 status: "success",
               },
             ],
             name: "step3_2",
-            serviceType: "AASMA_part7",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy PW7",
-            hosts: [
-              {
-                host: "qlaaspw7",
-                status: "success",
-              },
-            ],
-            name: "step3_3",
-            serviceType: "AASPW_part7",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy SC7",
-            hosts: [
-              {
-                host: "qlaassc7",
-                status: "success",
-              },
-            ],
-            name: "step3_4",
-            serviceType: "AASSC_part7",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy HT7",
-            hosts: [
-              {
-                host: "qlaasht7",
-                status: "success",
-              },
-            ],
-            name: "step3_5",
-            serviceType: "AASHT_part7",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy MH7",
-            hosts: [
-              {
-                host: "qlaasmh7",
-                status: "success",
-              },
-            ],
-            name: "step3_6",
-            serviceType: "AASMH_part7",
+            serviceType: "app2_part1",
             serviceTypeParallel: true,
             status: "success",
             type: "execution",
@@ -156,660 +149,42 @@ export default [
         subStepsParallel: true,
       },
       {
-        displayName: "step4",
+        displayName: "start All Services",
         name: "step4",
         status: "success",
         steps: [
           {
-            action: "humanWaiting",
-            displayName: "Waiting for verify internal environment",
-            name: "step4_1",
-            status: "success",
-            type: "execution",
-          },
-        ],
-      },
-      {
-        displayName: "stop BM1 BM2 application",
-        name: "step5",
-        status: "success",
-        steps: [
-          {
-            action: "stop",
-            displayName: "Stop BM1",
-            hosts: [
-              {
-                host: "qlaasbm1",
-                status: "success",
-              },
-            ],
-            name: "step5_1",
-            serviceType: "AASBM_part1",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop BM2",
-            hosts: [
-              {
-                host: "qlaasbm2",
-                status: "success",
-              },
-            ],
-            name: "step5_2",
-            serviceType: "AASBM_part2",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "Deploy BM1 And BM2 application",
-        name: "step6",
-        status: "success",
-        steps: [
-          {
-            action: "deploy",
-            displayName: "Deploy BM1",
-            hosts: [
-              {
-                host: "qlaasbm1",
-                status: "success",
-              },
-            ],
-            name: "step6_1",
-            serviceType: "AASBM_part1",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy BM2",
-            hosts: [
-              {
-                host: "qlaasbm2",
-                status: "success",
-              },
-            ],
-            name: "step6_2",
-            serviceType: "AASBM_part2",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "step7",
-        name: "step7",
-        status: "success",
-        steps: [
-          {
-            action: "humanWaiting",
-            displayName: "Waiting for verify BM1 And BM2 application",
-            name: "step7_1",
-            status: "success",
-            type: "execution",
-          },
-        ],
-      },
-      {
-        displayName: "Stop HT1 And MH1 F5",
-        name: "step8",
-        status: "success",
-        steps: [
-          {
-            action: "stop",
-            displayName: "Stop HT1",
-            hosts: [
-              {
-                host: "qlaasht3",
-                status: "success",
-              },
-            ],
-            name: "step8_1",
-            serviceType: "AASHT_part1",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop MH1",
-            hosts: [
-              {
-                host: "qlaasmh1",
-                status: "success",
-              },
-            ],
-            name: "step8_2",
-            serviceType: "AASMH_part1",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "step9",
-        name: "step9",
-        status: "running",
-        steps: [
-          {
-            action: "humanWaiting",
-            displayName:
-              "Finish HT1 & MH1 closeF5, next step stop AP1 MA1 PW1 And SC1 application",
-            name: "step9_1",
-            status: "running",
-            type: "execution",
-          },
-        ],
-      },
-      {
-        displayName: "stop AP1 MA1 PW1 And SC1 application",
-        name: "step10",
-        status: "waiting",
-        steps: [
-          {
-            action: "stop",
-            displayName: "Stop AP1",
-            hosts: [
-              {
-                host: "qlaasap1",
-                status: "error",
-              },
-            ],
-            name: "step10_1",
-            serviceType: "AASAP_part1",
-            serviceTypeParallel: true,
-            status: "error",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop MA1",
-            hosts: [
-              {
-                host: "qlaasma1",
-                status: "success",
-              },
-            ],
-            name: "step10_2",
-            serviceType: "AASMA_part1",
-            serviceTypeParallel: true,
-            status: "success",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop PW1",
+            action: "start",
+            displayName: "start app1_part1 Services",
             hosts: [
               {
-                host: "qlaaspw1",
+                host: "quadpax1",
                 status: "success",
               },
             ],
-            name: "step10_3",
-            serviceType: "AASPW_part1",
+            name: "step4_1",
+            serviceType: "app1_part1",
             serviceTypeParallel: true,
             status: "success",
             type: "execution",
           },
           {
-            action: "stop",
-            displayName: "Stop SC1",
+            action: "start",
+            displayName: "start app2_part1 Services",
             hosts: [
               {
-                host: "qlaassc1",
+                host: "quadpax2",
                 status: "success",
               },
             ],
-            name: "step10_4",
-            serviceType: "AASSC_part1",
+            name: "step4_2",
+            serviceType: "app2_part1",
             serviceTypeParallel: true,
             status: "success",
             type: "execution",
           },
         ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "step11",
-        name: "step11",
-        status: "waiting",
-        steps: [
-          {
-            action: "humanWaiting",
-            displayName:
-              "all application have closed, next step Deploy all application",
-            name: "step11_1",
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-      },
-      {
-        displayName: "Deploy AP1 MA1 PW1 And SC1",
-        name: "step12",
-        status: "waiting",
-        steps: [
-          {
-            action: "deploy",
-            displayName: "Deploy AP1",
-            hosts: [
-              {
-                host: "qlaasap1",
-                status: "waiting",
-              },
-            ],
-            name: "step12_1",
-            serviceType: "AASAP_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy MA1",
-            hosts: [
-              {
-                host: "qlaasma1",
-                status: "waiting",
-              },
-            ],
-            name: "step12_2",
-            serviceType: "AASMA_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy PW1",
-            hosts: [
-              {
-                host: "qlaaspw1",
-                status: "waiting",
-              },
-            ],
-            name: "step12_3",
-            serviceType: "AASPW_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy SC1",
-            hosts: [
-              {
-                host: "qlaassc1",
-                status: "waiting",
-              },
-            ],
-            name: "step12_4",
-            serviceType: "AASSC_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "Deploy HT1 And MH1",
-        name: "step13",
-        status: "waiting",
-        steps: [
-          {
-            action: "deploy",
-            displayName: "Deploy HT1",
-            hosts: [
-              {
-                host: "qlaasht3",
-                status: "waiting",
-              },
-            ],
-            name: "step13_1",
-            serviceType: "AASHT_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy MH1",
-            hosts: [
-              {
-                host: "qlaasmh1",
-                status: "waiting",
-              },
-            ],
-            name: "step13_2",
-            serviceType: "AASMH_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "step14",
-        name: "step14",
-        status: "waiting",
-        steps: [
-          {
-            action: "humanWaiting",
-            displayName: "Waiting for external services",
-            name: "step14_1",
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-      },
-      {
-        displayName: "StartF5 HT1 And MH1",
-        name: "step15",
-        status: "waiting",
-        steps: [
-          {
-            action: "start",
-            displayName: "StartF5 HT1",
-            hosts: [
-              {
-                host: "qlaasht3",
-                status: "waiting",
-              },
-            ],
-            name: "step15_1",
-            serviceType: "AASHT_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "start",
-            displayName: "StartF5 MH1",
-            hosts: [
-              {
-                host: "qlaasmh1",
-                status: "waiting",
-              },
-            ],
-            name: "step15_2",
-            serviceType: "AASMH_part1",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName:
-          "Stop HT2 And MH2 closeF5, stop ap2 ma2 pw2 and sc2 application",
-        name: "step16",
-        status: "waiting",
-        steps: [
-          {
-            action: "stop",
-            displayName: "Stop HT2",
-            hosts: [
-              {
-                host: "qlaasht4",
-                status: "waiting",
-              },
-            ],
-            name: "step16_1",
-            serviceType: "AASHT_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop MH2",
-            hosts: [
-              {
-                host: "qlaasmh2",
-                status: "waiting",
-              },
-            ],
-            name: "step16_2",
-            serviceType: "AASMH_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop AP2",
-            hosts: [
-              {
-                host: "qlaasap2",
-                status: "waiting",
-              },
-            ],
-            name: "step16_3",
-            serviceType: "AASAP_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop MA2",
-            hosts: [
-              {
-                host: "qlaasma2",
-                status: "waiting",
-              },
-            ],
-            name: "step16_4",
-            serviceType: "AASMA_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop PW2",
-            hosts: [
-              {
-                host: "qlaaspw2",
-                status: "waiting",
-              },
-            ],
-            name: "step16_5",
-            serviceType: "AASPW_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "stop",
-            displayName: "Stop SC2",
-            hosts: [
-              {
-                host: "qlaassc2",
-                status: "waiting",
-              },
-            ],
-            name: "step16_6",
-            serviceType: "AASSC_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "step17",
-        name: "step17",
-        status: "waiting",
-        steps: [
-          {
-            action: "humanWaiting",
-            displayName:
-              "Finish HT2 & MH2 closeF5, stop ap2 ma2 pw2 and sc2 application,next step Deploy AP2 MA2 PW2 And SC2",
-            name: "step17_1",
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-      },
-      {
-        displayName: "Deploy AP2 MA2 PW2 And SC2",
-        name: "step18",
-        status: "waiting",
-        steps: [
-          {
-            action: "deploy",
-            displayName: "Deploy AP2",
-            hosts: [
-              {
-                host: "qlaasap2",
-                status: "waiting",
-              },
-            ],
-            name: "step18_1",
-            serviceType: "AASAP_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy MA2",
-            hosts: [
-              {
-                host: "qlaasma2",
-                status: "waiting",
-              },
-            ],
-            name: "step18_2",
-            serviceType: "AASMA_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy PW2",
-            hosts: [
-              {
-                host: "qlaaspw2",
-                status: "waiting",
-              },
-            ],
-            name: "step18_3",
-            serviceType: "AASPW_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy SC2",
-            hosts: [
-              {
-                host: "qlaassc2",
-                status: "waiting",
-              },
-            ],
-            name: "step18_4",
-            serviceType: "AASSC_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "Deploy HT2 And MH2",
-        name: "step19",
-        status: "waiting",
-        steps: [
-          {
-            action: "deploy",
-            displayName: "Deploy HT2",
-            hosts: [
-              {
-                host: "qlaasht4",
-                status: "waiting",
-              },
-            ],
-            name: "step19_1",
-            serviceType: "AASHT_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "deploy",
-            displayName: "Deploy MH2",
-            hosts: [
-              {
-                host: "qlaasmh2",
-                status: "waiting",
-              },
-            ],
-            name: "step19_2",
-            serviceType: "AASMH_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
-      },
-      {
-        displayName: "StartF5 HT2 And MH2",
-        name: "step20",
-        status: "waiting",
-        steps: [
-          {
-            action: "start",
-            displayName: "StartF5 HT2",
-            hosts: [
-              {
-                host: "qlaasht4",
-                status: "waiting",
-              },
-            ],
-            name: "step20_1",
-            serviceType: "AASHT_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-          {
-            action: "start",
-            displayName: "StartF5 MH2",
-            hosts: [
-              {
-                host: "qlaasmh2",
-                status: "waiting",
-              },
-            ],
-            name: "step20_2",
-            serviceType: "AASMH_part2",
-            serviceTypeParallel: true,
-            status: "waiting",
-            type: "execution",
-          },
-        ],
-        subStepsParallel: true,
+        subStepsParallel: false,
       },
     ],
     subStepsParallel: false,