mirror of https://github.com/certd/certd
perf: 任务支持拖动排序
parent
71ac8aae4a
commit
1e9b5638aa
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}"`;
|
||||
|
|
Loading…
Reference in New Issue