perf: 任务支持拖动排序

pull/189/head
xiaojunnuo 2024-09-05 01:39:46 +08:00
parent 71ac8aae4a
commit 1e9b5638aa
5 changed files with 139 additions and 75 deletions

View File

@ -55,7 +55,7 @@
"vue-cropperjs": "^5.0.0",
"vue-i18n": "^9.10.2",
"vue-router": "^4.3.0",
"vuedraggable": "^2.24.3"
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@certd/pipeline": "^1.24.1",

View File

@ -74,6 +74,9 @@ h1, h2, h3, h4, h5, h6 {
.ml-5{
margin-left:5px;
}
.ml-10{
margin-left:10px;
}
.ml-20{
margin-left:20px;
}
@ -84,6 +87,9 @@ h1, h2, h3, h4, h5, h6 {
.mr-5{
margin-right: 5px;
}
.mr-10{
margin-right: 10px;
}
.mr-20{
margin-right: 20px;
}

View File

@ -43,25 +43,22 @@
<a-button type="primary" @click="stepAdd(currentTask)"></a-button>
</template>
</a-descriptions>
<a-list class="step-list" item-layout="horizontal" :data-source="currentTask.steps">
<template #renderItem="{ item, index }">
<a-list-item>
<template #actions>
<a key="edit" @click="stepEdit(currentTask, item, index)">编辑</a>
<a key="edit" @click="stepCopy(currentTask, item, index)">复制</a>
<v-draggable v-model="currentTask.steps" class="step-list" handle=".handle">
<template #item="{ element, index }">
<div class="step-row">
<div class="text">
<fs-icon icon="ion:flash"></fs-icon>
<h4 class="title">{{ element.title }}</h4>
</div>
<div class="action">
<a key="edit" @click="stepEdit(currentTask, element, index)">编辑</a>
<a key="edit" @click="stepCopy(currentTask, element, index)">复制</a>
<a key="remove" @click="stepDelete(currentTask, index)">删除</a>
</template>
<a-list-item-meta>
<template #title>
{{ item.title }}
</template>
<template #avatar>
<fs-icon icon="ion:flash"></fs-icon>
</template>
</a-list-item-meta>
</a-list-item>
<fs-icon class="icon-button handle" title="拖动排序" icon="ion:move-outline"></fs-icon>
</div>
</div>
</template>
</a-list>
</v-draggable>
</a-form-item>
</div>
</a-form>
@ -85,10 +82,10 @@ import { nanoid } from "nanoid";
import PiStepForm from "../step-form/index.vue";
import { Modal } from "ant-design-vue";
import { CopyOutlined } from "@ant-design/icons-vue";
import VDraggable from "vuedraggable";
export default {
name: "PiTaskForm",
components: { CopyOutlined, PiStepForm },
components: { CopyOutlined, PiStepForm, VDraggable },
props: {
editMode: {
type: Boolean,
@ -268,5 +265,42 @@ export default {
.ant-list .ant-list-item .ant-list-item-meta .ant-list-item-meta-title {
margin: 0;
}
.ant-list .ant-list-item .ant-list-item-action {
display: flex;
> li {
display: flex;
align-items: center;
}
}
.step-list {
padding: 10px;
.icon-button {
font-size: 18px;
color: #1677ff;
cursor: pointer;
}
.step-row {
padding: 10px;
display: flex;
align-items: center;
justify-content: space-between;
.text {
display: flex;
> * {
margin: 0px;
margin-right: 15px;
}
}
.action {
display: flex;
align-items: center;
> * {
margin-right: 15px;
font-size: 14px;
}
}
}
}
}
</style>

View File

@ -67,59 +67,68 @@
<div class="title">
<pi-editable v-model="stage.title" :disabled="!editMode"></pi-editable>
</div>
<div class="tasks">
<div
v-for="(task, taskIndex) of stage.tasks"
:key="task.id"
class="task-container"
:class="{
'first-task': taskIndex === 0
}"
>
<div class="line">
<div class="flow-line"></div>
<fs-icon v-if="editMode" class="add-stage-btn" title="添加新阶段" icon="ion:add-circle" @click="stageAdd(index)"></fs-icon>
</div>
<div class="task">
<a-button shape="round" @click="taskEdit(stage, index, task, taskIndex)">
<a-popover title="步骤">
<!-- :open="true"-->
<template #content>
<div v-for="(item, index) of task.steps" class="flex-o w-100">
<span class="ellipsis flex-1">{{ index + 1 }}. {{ item.title }} </span>
<pi-status-show v-if="!editMode" :status="item.status?.result"></pi-status-show>
<fs-icon
v-if="!editMode"
class="pointer color-blue ml-2"
title="重新运行此步骤"
icon="SyncOutlined"
@click="run(item.id)"
></fs-icon>
</div>
</template>
<span class="flex-o w-100">
<span class="ellipsis flex-1" :class="{ 'mr-15': editMode }">{{ task.title }}</span>
<pi-status-show :status="task.status?.result"></pi-status-show>
</span>
</a-popover>
</a-button>
<fs-icon v-if="editMode" class="copy" title="复制" icon="ion:copy-outline" @click="taskCopy(stage, index, task)"></fs-icon>
</div>
</div>
<div v-if="editMode" class="task-container is-add">
<div class="line">
<div class="flow-line"></div>
</div>
<div class="task">
<a-tooltip>
<a-button type="dashed" shape="round" @click="taskAdd(stage, index)">
<fs-icon class="font-20" icon="ion:add-circle-outline"></fs-icon>
并行任务
<v-draggable v-model="stage.tasks" item-key="id" class="tasks" handle=".handle">
<template #item="{ element: task, index: taskIndex }">
<div
class="task-container"
:class="{
'first-task': taskIndex === 0
}"
>
<div class="line">
<div class="flow-line"></div>
<fs-icon v-if="editMode" class="add-stage-btn" title="添加新阶段" icon="ion:add-circle" @click="stageAdd(index)"></fs-icon>
</div>
<div class="task">
<a-button shape="round" @click="taskEdit(stage, index, task, taskIndex)">
<a-popover title="步骤" :trigger="editMode ? 'none' : 'hover'">
<!-- :open="true"-->
<template #content>
<div v-for="(item, index) of task.steps" class="flex-o w-100">
<span class="ellipsis flex-1">{{ index + 1 }}. {{ item.title }} </span>
<pi-status-show v-if="!editMode" :status="item.status?.result"></pi-status-show>
<fs-icon
v-if="!editMode"
class="pointer color-blue ml-2"
title="重新运行此步骤"
icon="SyncOutlined"
@click="run(item.id)"
></fs-icon>
</div>
</template>
<span class="flex-o w-100">
<span class="ellipsis flex-1 task-title" :class="{ 'in-edit': editMode }">{{ task.title }}</span>
<pi-status-show :status="task.status?.result"></pi-status-show>
</span>
</a-popover>
</a-button>
</a-tooltip>
<fs-icon
v-if="editMode"
class="action copy"
title="复制"
icon="ion:copy-outline"
@click="taskCopy(stage, index, task)"
></fs-icon>
<fs-icon v-if="editMode" class="handle action drag" title="拖动排序" icon="ion:move-outline"></fs-icon>
</div>
</div>
</div>
</div>
</template>
<template #footer>
<div v-if="editMode" class="task-container is-add">
<div class="line">
<div class="flow-line"></div>
</div>
<div class="task">
<a-tooltip>
<a-button type="dashed" shape="round" @click="taskAdd(stage, index)">
<fs-icon class="font-20" icon="ion:add-circle-outline"></fs-icon>
并行任务
</a-button>
</a-tooltip>
</div>
</div>
</template>
</v-draggable>
</div>
<div v-if="editMode" class="stage last-stage">
@ -235,6 +244,7 @@ import PiTriggerForm from "./component/trigger-form/index.vue";
import PiNotificationForm from "./component/notification-form/index.vue";
import PiTaskView from "./component/task-view/index.vue";
import PiStatusShow from "./component/status-show.vue";
import VDraggable from "vuedraggable";
import _ from "lodash-es";
import { message, Modal, notification } from "ant-design-vue";
import { nanoid } from "nanoid";
@ -245,7 +255,7 @@ import { FsIcon } from "@fast-crud/fast-crud";
export default defineComponent({
name: "PipelineEdit",
// eslint-disable-next-line vue/no-unused-components
components: { FsIcon, PiHistoryTimelineItem, PiTaskForm, PiTriggerForm, PiTaskView, PiStatusShow, PiNotificationForm },
components: { FsIcon, PiHistoryTimelineItem, PiTaskForm, PiTriggerForm, PiTaskView, PiStatusShow, PiNotificationForm, VDraggable },
props: {
pipelineId: {
type: [Number, String],
@ -785,14 +795,28 @@ export default defineComponent({
height: 100%;
z-index: 2;
.copy {
.task-title {
&.in-edit {
margin-right: 28px;
}
}
.action {
position: absolute;
right: 60px;
top: 18px;
//font-size: 18px;
cursor: pointer;
z-index: 10;
&:hover {
color: #1890ff;
}
&.copy {
right: 80px;
}
&.drag {
right: 60px;
}
}
.ant-btn {

View File

@ -195,8 +195,8 @@ export class SshClient {
this.logger.info('请注意windows下文件目录分隔应该写成\\而不是/');
this.logger.info('--------------------------');
}
const spec = await conn.exec('echo %COMSPEC%');
if (spec.toString().trim() === '%COMSPEC%') {
const isCmd = await this.isCmd(conn);
if (!isCmd) {
mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`;
} else {
mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`;