|
@@ -15,11 +15,11 @@
|
|
|
<span class="detail-task-name-text">{{ task.name }}</span>
|
|
<span class="detail-task-name-text">{{ task.name }}</span>
|
|
|
<div class="detail-task-actions">
|
|
<div class="detail-task-actions">
|
|
|
<a-switch :checked="task.enabled" size="small" class="schedule-switch" @change="handleToggle" />
|
|
<a-switch :checked="task.enabled" size="small" class="schedule-switch" @change="handleToggle" />
|
|
|
- <a-popover v-model:open="moreVisible" trigger="click" placement="bottomRight" overlayClassName="schedule-more-popover">
|
|
|
|
|
- <div class="detail-more-btn"></div>
|
|
|
|
|
- <template #content>
|
|
|
|
|
|
|
+ <div class="more-btn-wrapper" ref="morePopupRef">
|
|
|
|
|
+ <div class="detail-more-btn" @click="toggleMorePopup"></div>
|
|
|
|
|
+ <div v-if="showMorePopup" class="more-popup" @click.stop>
|
|
|
<div class="more-menu">
|
|
<div class="more-menu">
|
|
|
- <div class="more-menu-item" @click="handleAction('run')">
|
|
|
|
|
|
|
+ <div class="more-menu-item" :class="{ disabled: !task.enabled }" @click="handleAction('run')">
|
|
|
<div class="more-menu-icon run-icon"></div>
|
|
<div class="more-menu-icon run-icon"></div>
|
|
|
<span>立即执行</span>
|
|
<span>立即执行</span>
|
|
|
</div>
|
|
</div>
|
|
@@ -32,8 +32,8 @@
|
|
|
<span>删除</span>
|
|
<span>删除</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- </template>
|
|
|
|
|
- </a-popover>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="detail-task-prompt">{{ task.prompt }}</div>
|
|
<div class="detail-task-prompt">{{ task.prompt }}</div>
|
|
@@ -87,8 +87,9 @@
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import { ref, reactive, watch } from 'vue';
|
|
import { ref, reactive, watch } from 'vue';
|
|
|
|
|
+ import { onClickOutside } from '@vueuse/core';
|
|
|
import { message, Modal } from 'ant-design-vue';
|
|
import { message, Modal } from 'ant-design-vue';
|
|
|
- import { getScheduleRuns, pauseSchedule, resumeSchedule, deleteSchedule, runScheduleNow } from '../../api';
|
|
|
|
|
|
|
+ import { getScheduleRuns, pauseSchedule, resumeSchedule, deleteSchedule } from '../../api';
|
|
|
import CreateScheduleModal from './CreateScheduleModal.vue';
|
|
import CreateScheduleModal from './CreateScheduleModal.vue';
|
|
|
|
|
|
|
|
interface ScheduleTask {
|
|
interface ScheduleTask {
|
|
@@ -108,12 +109,21 @@
|
|
|
(e: 'close'): void;
|
|
(e: 'close'): void;
|
|
|
(e: 'deleted'): void;
|
|
(e: 'deleted'): void;
|
|
|
(e: 'updated'): void;
|
|
(e: 'updated'): void;
|
|
|
|
|
+ (e: 'open-session', sessionId: string, prompt: string): void;
|
|
|
}>();
|
|
}>();
|
|
|
|
|
|
|
|
- const moreVisible = ref(false);
|
|
|
|
|
|
|
+ const morePopupRef = ref<HTMLElement>();
|
|
|
|
|
+ const showMorePopup = ref(false);
|
|
|
const showEditModal = ref(false);
|
|
const showEditModal = ref(false);
|
|
|
const editData = ref<ScheduleTask | null>(null);
|
|
const editData = ref<ScheduleTask | null>(null);
|
|
|
- const runningIds = reactive(new Set<number>());
|
|
|
|
|
|
|
+
|
|
|
|
|
+ const toggleMorePopup = () => {
|
|
|
|
|
+ showMorePopup.value = !showMorePopup.value;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ onClickOutside(morePopupRef, () => {
|
|
|
|
|
+ showMorePopup.value = false;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
watch(showEditModal, (val) => {
|
|
watch(showEditModal, (val) => {
|
|
|
if (!val) editData.value = null;
|
|
if (!val) editData.value = null;
|
|
@@ -136,15 +146,11 @@
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleRunNow = async () => {
|
|
const handleRunNow = async () => {
|
|
|
- if (!props.task) return;
|
|
|
|
|
- runningIds.add(props.task.id);
|
|
|
|
|
- try {
|
|
|
|
|
- await runScheduleNow(props.task.id);
|
|
|
|
|
- message.success(`任务「${props.task.name}」已开始执行`);
|
|
|
|
|
- } catch {
|
|
|
|
|
- message.error('执行失败');
|
|
|
|
|
- } finally {
|
|
|
|
|
- runningIds.delete(props.task.id);
|
|
|
|
|
|
|
+ if (!props.task || !props.task.enabled) return;
|
|
|
|
|
+ if (props.task.feedback_session_id) {
|
|
|
|
|
+ emit('open-session', props.task.feedback_session_id, props.task.prompt);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ message.warning('该任务暂无关联会话');
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -177,7 +183,7 @@
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleAction = (action: 'run' | 'edit' | 'delete') => {
|
|
const handleAction = (action: 'run' | 'edit' | 'delete') => {
|
|
|
- moreVisible.value = false;
|
|
|
|
|
|
|
+ showMorePopup.value = false;
|
|
|
if (action === 'run') handleRunNow();
|
|
if (action === 'run') handleRunNow();
|
|
|
else if (action === 'edit') handleEdit();
|
|
else if (action === 'edit') handleEdit();
|
|
|
else if (action === 'delete') handleDelete();
|
|
else if (action === 'delete') handleDelete();
|
|
@@ -385,8 +391,8 @@
|
|
|
|
|
|
|
|
.detail-task-meta {
|
|
.detail-task-meta {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
|
|
- gap: 20px;
|
|
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 6px;
|
|
|
font-size: 13px;
|
|
font-size: 13px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -405,6 +411,18 @@
|
|
|
font-size: 13px;
|
|
font-size: 13px;
|
|
|
color: #8b949e;
|
|
color: #8b949e;
|
|
|
line-height: 1.6;
|
|
line-height: 1.6;
|
|
|
|
|
+ max-height: 120px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ word-break: break-all;
|
|
|
|
|
+
|
|
|
|
|
+ &::-webkit-scrollbar {
|
|
|
|
|
+ width: 4px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
|
|
+ background: rgba(63, 80, 106, 0.4);
|
|
|
|
|
+ border-radius: 2px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 执行历史 */
|
|
/* 执行历史 */
|
|
@@ -529,26 +547,24 @@
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|
|
|
|
|
|
|
|
-<style lang="less">
|
|
|
|
|
- .schedule-more-popover {
|
|
|
|
|
- .zxm-popover-inner {
|
|
|
|
|
- background: linear-gradient(135deg, #0a1628 0%, #0d2137 50%, #0a1e35 100%);
|
|
|
|
|
- border: 1px solid rgba(63, 80, 106, 0.4);
|
|
|
|
|
- border-radius: 8px;
|
|
|
|
|
- padding: 4px;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+<style scoped lang="less">
|
|
|
|
|
+ .more-btn-wrapper {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- .zxm-popover-arrow::before {
|
|
|
|
|
- background: #0d2137;
|
|
|
|
|
- border-color: rgba(63, 80, 106, 0.4);
|
|
|
|
|
- }
|
|
|
|
|
- .zxm-popover-inner-content {
|
|
|
|
|
- padding: 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .more-popup {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 100%;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ margin-top: 4px;
|
|
|
|
|
+ background: linear-gradient(135deg, #0a1628 0%, #0d2137 50%, #0a1e35 100%);
|
|
|
|
|
+ border: 1px solid rgba(63, 80, 106, 0.4);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ padding: 4px;
|
|
|
|
|
+ z-index: 100;
|
|
|
|
|
+ min-width: 120px;
|
|
|
}
|
|
}
|
|
|
-</style>
|
|
|
|
|
|
|
|
|
|
-<style scoped lang="less">
|
|
|
|
|
.more-menu {
|
|
.more-menu {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
@@ -577,6 +593,12 @@
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ &.disabled {
|
|
|
|
|
+ opacity: 0.4;
|
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.more-menu-icon {
|
|
.more-menu-icon {
|
|
|
width: 16px;
|
|
width: 16px;
|
|
|
height: 16px;
|
|
height: 16px;
|