mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 05:19:19 +08:00
feat(task): Add Global Task List (#7569)
This commit is contained in:
parent
008c369a9b
commit
e56c0c7fba
8 changed files with 141 additions and 53 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="initLog && isLoading">
|
<div v-loading="initLog && isLoading">
|
||||||
<div v-if="defaultButton">
|
<div v-if="defaultButton">
|
||||||
<el-checkbox border v-model="tailLog" class="float-left" @change="changeTail(false)">
|
<el-checkbox border v-model="tailLog" class="float-left" @change="changeTail(false)" v-if="showTail">
|
||||||
{{ $t('commons.button.watch') }}
|
{{ $t('commons.button.watch') }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
<el-button class="ml-2.5" @click="onDownload" icon="Download" :disabled="logs.length === 0">
|
<el-button class="ml-2.5" @click="onDownload" icon="Download" :disabled="logs.length === 0">
|
||||||
|
|
@ -63,6 +63,10 @@ const props = defineProps({
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 500,
|
default: 500,
|
||||||
},
|
},
|
||||||
|
showTail: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const stopSignals = [
|
const stopSignals = [
|
||||||
'docker-compose up failed!',
|
'docker-compose up failed!',
|
||||||
|
|
@ -294,7 +298,6 @@ onMounted(async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
console.log('onUnmounted');
|
|
||||||
onCloseLog();
|
onCloseLog();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ const getType = (status: string) => {
|
||||||
case 'exceptional':
|
case 'exceptional':
|
||||||
case 'disable':
|
case 'disable':
|
||||||
case 'unhealthy':
|
case 'unhealthy':
|
||||||
|
case 'failed':
|
||||||
return 'danger';
|
return 'danger';
|
||||||
case 'paused':
|
case 'paused':
|
||||||
case 'exited':
|
case 'exited':
|
||||||
|
|
|
||||||
101
frontend/src/components/task-list/index.vue
Normal file
101
frontend/src/components/task-list/index.vue
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
<template>
|
||||||
|
<DrawerPro v-model="open" size="large" :header="$t('logs.task')" @close="handleClose">
|
||||||
|
<template #content>
|
||||||
|
<LayoutContent v-loading="loading" :title="$t('logs.task')">
|
||||||
|
<template #rightToolBar>
|
||||||
|
<el-select v-model="req.status" @change="search()" clearable class="p-w-200 mr-2.5">
|
||||||
|
<template #prefix>{{ $t('commons.table.status') }}</template>
|
||||||
|
<el-option :label="$t('commons.table.all')" value=""></el-option>
|
||||||
|
<el-option :label="$t('commons.status.success')" value="Success"></el-option>
|
||||||
|
<el-option :label="$t('commons.status.failed')" value="Failed"></el-option>
|
||||||
|
<el-option :label="$t('logs.taskRunning')" value="Executing"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<TableRefresh @search="search()" />
|
||||||
|
<TableSetting title="task-log-refresh" @search="search()" />
|
||||||
|
</template>
|
||||||
|
<template #main>
|
||||||
|
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search" :heightDiff="370">
|
||||||
|
<el-table-column :label="$t('logs.taskName')" prop="name" />
|
||||||
|
<el-table-column :label="$t('commons.table.type')" prop="type" />
|
||||||
|
<el-table-column :label="$t('commons.table.status')" prop="status">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<Status :status="row.status" :msg="row.errorMsg" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('website.log')" prop="log">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button @click="openTaskLog(row)" link type="primary">
|
||||||
|
{{ $t('website.check') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="createdAt"
|
||||||
|
:label="$t('commons.table.date')"
|
||||||
|
:formatter="dateFormat"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
</ComplexTable>
|
||||||
|
</template>
|
||||||
|
</LayoutContent>
|
||||||
|
<TaskLog ref="taskLogRef" width="70%" />
|
||||||
|
</template>
|
||||||
|
</DrawerPro>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormat } from '@/utils/util';
|
||||||
|
import { searchTasks } from '@/api/modules/log';
|
||||||
|
import { reactive, ref } from '@vue/runtime-core';
|
||||||
|
import { Log } from '@/api/interface/log';
|
||||||
|
import TaskLog from '@/components/task-log/index.vue';
|
||||||
|
|
||||||
|
const open = ref(false);
|
||||||
|
const handleClose = () => {
|
||||||
|
open.value = false;
|
||||||
|
};
|
||||||
|
const loading = ref();
|
||||||
|
const data = ref();
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
cacheSizeKey: 'task-list-page-size',
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
const taskLogRef = ref();
|
||||||
|
const req = reactive({
|
||||||
|
type: '',
|
||||||
|
status: 'Executing',
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const search = async () => {
|
||||||
|
req.page = paginationConfig.currentPage;
|
||||||
|
req.pageSize = paginationConfig.pageSize;
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const res = await searchTasks(req);
|
||||||
|
loading.value = false;
|
||||||
|
data.value = res.data.items;
|
||||||
|
paginationConfig.total = res.data.total;
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const openTaskLog = (row: Log.Task) => {
|
||||||
|
taskLogRef.value.openWithTaskID(row.id, !(row.status == 'Executing'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const acceptParams = () => {
|
||||||
|
search();
|
||||||
|
open.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
:width="width"
|
:width="width"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<LogFile :config="config"></LogFile>
|
<LogFile :config="config" :showTail="showTail"></LogFile>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -37,12 +37,16 @@ const config = reactive({
|
||||||
taskOperate: '',
|
taskOperate: '',
|
||||||
resourceID: 0,
|
resourceID: 0,
|
||||||
taskType: '',
|
taskType: '',
|
||||||
tail: true,
|
tail: false,
|
||||||
});
|
});
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
|
const showTail = ref(true);
|
||||||
|
|
||||||
const openWithTaskID = (id: string) => {
|
const openWithTaskID = (id: string, tail: boolean) => {
|
||||||
config.taskID = id;
|
config.taskID = id;
|
||||||
|
if (!tail) {
|
||||||
|
config.tail = false;
|
||||||
|
}
|
||||||
open.value = true;
|
open.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<el-tag type="danger" size="small" effect="light" class="mr-2">{{ taskCount }}</el-tag>
|
<el-tag type="danger" size="small" effect="light" class="mr-2" @click="openTask">{{ taskCount }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<el-menu
|
<el-menu
|
||||||
|
|
@ -132,7 +132,7 @@ const listeningWindow = () => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
listeningWindow();
|
listeningWindow();
|
||||||
const emit = defineEmits(['menuClick']);
|
const emit = defineEmits(['menuClick', 'openTask']);
|
||||||
const handleMenuClick = (path) => {
|
const handleMenuClick = (path) => {
|
||||||
emit('menuClick', path);
|
emit('menuClick', path);
|
||||||
};
|
};
|
||||||
|
|
@ -252,6 +252,10 @@ const checkTask = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openTask = () => {
|
||||||
|
emit('openTask');
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
menuStore.setMenuList(menuList);
|
menuStore.setMenuList(menuList);
|
||||||
search();
|
search();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div :class="classObj" class="app-wrapper" v-loading="loading" :element-loading-text="loadingText" fullscreen>
|
<div :class="classObj" class="app-wrapper" v-loading="loading" :element-loading-text="loadingText" fullscreen>
|
||||||
<div v-if="classObj.mobile && classObj.openSidebar" class="drawer-bg" @click="handleClickOutside" />
|
<div v-if="classObj.mobile && classObj.openSidebar" class="drawer-bg" @click="handleClickOutside" />
|
||||||
<div class="app-sidebar" v-if="!globalStore.isFullScreen">
|
<div class="app-sidebar" v-if="!globalStore.isFullScreen">
|
||||||
<Sidebar @menu-click="handleMenuClick" :menu-router="!classObj.openMenuTabs" />
|
<Sidebar @menu-click="handleMenuClick" :menu-router="!classObj.openMenuTabs" @open-task="openTask" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
<Tabs v-if="classObj.openMenuTabs" />
|
<Tabs v-if="classObj.openMenuTabs" />
|
||||||
<app-main :keep-alive="classObj.openMenuTabs ? tabsStore.cachedTabs : null" class="app-main" />
|
<app-main :keep-alive="classObj.openMenuTabs ? tabsStore.cachedTabs : null" class="app-main" />
|
||||||
<Footer class="app-footer" v-if="!globalStore.isFullScreen" />
|
<Footer class="app-footer" v-if="!globalStore.isFullScreen" />
|
||||||
|
<TaskList ref="taskListRef" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -25,8 +26,14 @@ import { useRoute, useRouter } from 'vue-router';
|
||||||
import { loadMasterProductProFromDB, loadProductProFromDB } from '@/utils/xpack';
|
import { loadMasterProductProFromDB, loadProductProFromDB } from '@/utils/xpack';
|
||||||
import { useTheme } from '@/global/use-theme';
|
import { useTheme } from '@/global/use-theme';
|
||||||
const { switchTheme } = useTheme();
|
const { switchTheme } = useTheme();
|
||||||
|
import TaskList from '@/components/task-list/index.vue';
|
||||||
|
|
||||||
useResize();
|
useResize();
|
||||||
|
|
||||||
|
const taskListRef = ref();
|
||||||
|
const openTask = () => {
|
||||||
|
taskListRef.value.acceptParams();
|
||||||
|
};
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const menuStore = MenuStore();
|
const menuStore = MenuStore();
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="showButton">
|
<div v-if="showButton">
|
||||||
<RouterButton :buttons="buttons">
|
<RouterButton :buttons="buttons"></RouterButton>
|
||||||
<template #route-button>
|
|
||||||
<el-badge is-dot :hidden="!canUpdate" class="pr-5">
|
|
||||||
<el-button @click="sync" type="primary" plain :disabled="syncing">
|
|
||||||
{{ $t('app.syncAppList') }}
|
|
||||||
</el-button>
|
|
||||||
</el-badge>
|
|
||||||
</template>
|
|
||||||
</RouterButton>
|
|
||||||
</div>
|
</div>
|
||||||
<LayoutContent>
|
<LayoutContent>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
|
|
@ -20,13 +12,9 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { SearchAppInstalled, SyncApp } from '@/api/modules/app';
|
import { SearchAppInstalled } from '@/api/modules/app';
|
||||||
import bus from './bus';
|
import bus from './bus';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
|
||||||
import { newUUID } from '@/utils/util';
|
|
||||||
let showButton = ref(false);
|
let showButton = ref(false);
|
||||||
const syncing = ref(false);
|
|
||||||
const canUpdate = ref(false);
|
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
|
|
@ -48,26 +36,6 @@ const buttons = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const sync = () => {
|
|
||||||
syncing.value = true;
|
|
||||||
const taskID = newUUID();
|
|
||||||
const syncReq = {
|
|
||||||
taskID: taskID,
|
|
||||||
};
|
|
||||||
SyncApp(syncReq)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.message != '') {
|
|
||||||
MsgSuccess(res.message);
|
|
||||||
} else {
|
|
||||||
MsgSuccess(i18n.global.t('app.syncStart'));
|
|
||||||
}
|
|
||||||
canUpdate.value = false;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
syncing.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
SearchAppInstalled({ update: true, page: 1, pageSize: 100 })
|
SearchAppInstalled({ update: true, page: 1, pageSize: 100 })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ import TaskLog from '@/components/task-log/index.vue';
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const data = ref();
|
const data = ref();
|
||||||
const paginationConfig = reactive({
|
const paginationConfig = reactive({
|
||||||
cacheSizeKey: 'login-log-page-size',
|
cacheSizeKey: 'task-page-size',
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
|
|
@ -73,19 +73,19 @@ const search = async () => {
|
||||||
req.page = paginationConfig.currentPage;
|
req.page = paginationConfig.currentPage;
|
||||||
req.pageSize = paginationConfig.pageSize;
|
req.pageSize = paginationConfig.pageSize;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await searchTasks(req)
|
try {
|
||||||
.then((res) => {
|
const res = await searchTasks(req);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
data.value = res.data.items;
|
data.value = res.data.items;
|
||||||
paginationConfig.total = res.data.total;
|
paginationConfig.total = res.data.total;
|
||||||
})
|
} catch (error) {
|
||||||
.catch(() => {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const openTaskLog = (row: Log.Task) => {
|
const openTaskLog = (row: Log.Task) => {
|
||||||
taskLogRef.value.openWithTaskID(row.id);
|
taskLogRef.value.openWithTaskID(row.id, !(row.status == 'Executing'));
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue