mirror of https://github.com/certd/certd
perf: 任务支持拖动排序
parent
71ac8aae4a
commit
1e9b5638aa
|
@ -55,7 +55,7 @@
|
||||||
"vue-cropperjs": "^5.0.0",
|
"vue-cropperjs": "^5.0.0",
|
||||||
"vue-i18n": "^9.10.2",
|
"vue-i18n": "^9.10.2",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "^4.3.0",
|
||||||
"vuedraggable": "^2.24.3"
|
"vuedraggable": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/pipeline": "^1.24.1",
|
"@certd/pipeline": "^1.24.1",
|
||||||
|
|
|
@ -74,6 +74,9 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
.ml-5{
|
.ml-5{
|
||||||
margin-left:5px;
|
margin-left:5px;
|
||||||
}
|
}
|
||||||
|
.ml-10{
|
||||||
|
margin-left:10px;
|
||||||
|
}
|
||||||
.ml-20{
|
.ml-20{
|
||||||
margin-left:20px;
|
margin-left:20px;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +87,9 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
.mr-5{
|
.mr-5{
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
.mr-10{
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
.mr-20{
|
.mr-20{
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,25 +43,22 @@
|
||||||
<a-button type="primary" @click="stepAdd(currentTask)">添加步骤</a-button>
|
<a-button type="primary" @click="stepAdd(currentTask)">添加步骤</a-button>
|
||||||
</template>
|
</template>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
<a-list class="step-list" item-layout="horizontal" :data-source="currentTask.steps">
|
<v-draggable v-model="currentTask.steps" class="step-list" handle=".handle">
|
||||||
<template #renderItem="{ item, index }">
|
<template #item="{ element, index }">
|
||||||
<a-list-item>
|
<div class="step-row">
|
||||||
<template #actions>
|
<div class="text">
|
||||||
<a key="edit" @click="stepEdit(currentTask, item, index)">编辑</a>
|
|
||||||
<a key="edit" @click="stepCopy(currentTask, item, 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>
|
<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>
|
||||||
|
<fs-icon class="icon-button handle" title="拖动排序" icon="ion:move-outline"></fs-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-list-item-meta>
|
</v-draggable>
|
||||||
</a-list-item>
|
|
||||||
</template>
|
|
||||||
</a-list>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
@ -85,10 +82,10 @@ import { nanoid } from "nanoid";
|
||||||
import PiStepForm from "../step-form/index.vue";
|
import PiStepForm from "../step-form/index.vue";
|
||||||
import { Modal } from "ant-design-vue";
|
import { Modal } from "ant-design-vue";
|
||||||
import { CopyOutlined } from "@ant-design/icons-vue";
|
import { CopyOutlined } from "@ant-design/icons-vue";
|
||||||
|
import VDraggable from "vuedraggable";
|
||||||
export default {
|
export default {
|
||||||
name: "PiTaskForm",
|
name: "PiTaskForm",
|
||||||
components: { CopyOutlined, PiStepForm },
|
components: { CopyOutlined, PiStepForm, VDraggable },
|
||||||
props: {
|
props: {
|
||||||
editMode: {
|
editMode: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -268,5 +265,42 @@ export default {
|
||||||
.ant-list .ant-list-item .ant-list-item-meta .ant-list-item-meta-title {
|
.ant-list .ant-list-item .ant-list-item-meta .ant-list-item-meta-title {
|
||||||
margin: 0;
|
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>
|
</style>
|
||||||
|
|
|
@ -67,10 +67,9 @@
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<pi-editable v-model="stage.title" :disabled="!editMode"></pi-editable>
|
<pi-editable v-model="stage.title" :disabled="!editMode"></pi-editable>
|
||||||
</div>
|
</div>
|
||||||
<div class="tasks">
|
<v-draggable v-model="stage.tasks" item-key="id" class="tasks" handle=".handle">
|
||||||
|
<template #item="{ element: task, index: taskIndex }">
|
||||||
<div
|
<div
|
||||||
v-for="(task, taskIndex) of stage.tasks"
|
|
||||||
:key="task.id"
|
|
||||||
class="task-container"
|
class="task-container"
|
||||||
:class="{
|
:class="{
|
||||||
'first-task': taskIndex === 0
|
'first-task': taskIndex === 0
|
||||||
|
@ -82,7 +81,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="task">
|
<div class="task">
|
||||||
<a-button shape="round" @click="taskEdit(stage, index, task, taskIndex)">
|
<a-button shape="round" @click="taskEdit(stage, index, task, taskIndex)">
|
||||||
<a-popover title="步骤">
|
<a-popover title="步骤" :trigger="editMode ? 'none' : 'hover'">
|
||||||
<!-- :open="true"-->
|
<!-- :open="true"-->
|
||||||
<template #content>
|
<template #content>
|
||||||
<div v-for="(item, index) of task.steps" class="flex-o w-100">
|
<div v-for="(item, index) of task.steps" class="flex-o w-100">
|
||||||
|
@ -98,14 +97,23 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<span class="flex-o w-100">
|
<span class="flex-o w-100">
|
||||||
<span class="ellipsis flex-1" :class="{ 'mr-15': editMode }">{{ task.title }}</span>
|
<span class="ellipsis flex-1 task-title" :class="{ 'in-edit': editMode }">{{ task.title }}</span>
|
||||||
<pi-status-show :status="task.status?.result"></pi-status-show>
|
<pi-status-show :status="task.status?.result"></pi-status-show>
|
||||||
</span>
|
</span>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</a-button>
|
</a-button>
|
||||||
<fs-icon v-if="editMode" class="copy" title="复制" icon="ion:copy-outline" @click="taskCopy(stage, index, task)"></fs-icon>
|
<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 v-if="editMode" class="task-container is-add">
|
||||||
<div class="line">
|
<div class="line">
|
||||||
<div class="flow-line"></div>
|
<div class="flow-line"></div>
|
||||||
|
@ -119,7 +127,8 @@
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
</v-draggable>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="editMode" class="stage last-stage">
|
<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 PiNotificationForm from "./component/notification-form/index.vue";
|
||||||
import PiTaskView from "./component/task-view/index.vue";
|
import PiTaskView from "./component/task-view/index.vue";
|
||||||
import PiStatusShow from "./component/status-show.vue";
|
import PiStatusShow from "./component/status-show.vue";
|
||||||
|
import VDraggable from "vuedraggable";
|
||||||
import _ from "lodash-es";
|
import _ from "lodash-es";
|
||||||
import { message, Modal, notification } from "ant-design-vue";
|
import { message, Modal, notification } from "ant-design-vue";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
|
@ -245,7 +255,7 @@ import { FsIcon } from "@fast-crud/fast-crud";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "PipelineEdit",
|
name: "PipelineEdit",
|
||||||
// eslint-disable-next-line vue/no-unused-components
|
// 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: {
|
props: {
|
||||||
pipelineId: {
|
pipelineId: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
|
@ -785,14 +795,28 @@ export default defineComponent({
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
.copy {
|
.task-title {
|
||||||
|
&.in-edit {
|
||||||
|
margin-right: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 60px;
|
right: 60px;
|
||||||
top: 18px;
|
top: 18px;
|
||||||
|
//font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
z-index: 10;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #1890ff;
|
color: #1890ff;
|
||||||
}
|
}
|
||||||
|
&.copy {
|
||||||
|
right: 80px;
|
||||||
|
}
|
||||||
|
&.drag {
|
||||||
|
right: 60px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-btn {
|
.ant-btn {
|
||||||
|
|
|
@ -195,8 +195,8 @@ export class SshClient {
|
||||||
this.logger.info('请注意:windows下,文件目录分隔应该写成\\而不是/');
|
this.logger.info('请注意:windows下,文件目录分隔应该写成\\而不是/');
|
||||||
this.logger.info('--------------------------');
|
this.logger.info('--------------------------');
|
||||||
}
|
}
|
||||||
const spec = await conn.exec('echo %COMSPEC%');
|
const isCmd = await this.isCmd(conn);
|
||||||
if (spec.toString().trim() === '%COMSPEC%') {
|
if (!isCmd) {
|
||||||
mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`;
|
mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`;
|
||||||
} else {
|
} else {
|
||||||
mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`;
|
mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`;
|
||||||
|
|
Loading…
Reference in New Issue