mirror of
https://github.com/acepanel/panel.git
synced 2026-02-07 07:03:12 +08:00
feat: 一堆调整
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
import { http } from '@/utils'
|
||||
|
||||
export default {
|
||||
// 面板信息
|
||||
panel: (): any => http.Get('/dashboard/panel'),
|
||||
// 首页应用
|
||||
homeApps: (): any => http.Get('/dashboard/home_apps'),
|
||||
// 实时信息
|
||||
current: (nets: string[], disks: string[]): any =>
|
||||
http.Post('/dashboard/current', { nets, disks }, { meta: { noAlert: true } }),
|
||||
// 系统信息
|
||||
systemInfo: (): any => http.Get('/dashboard/system_info'),
|
||||
// 统计信息
|
||||
countInfo: (): any => http.Get('/dashboard/count_info'),
|
||||
// 已安装的数据库和PHP
|
||||
installedDbAndPhp: (): any => http.Get('/dashboard/installed_db_and_php'),
|
||||
// 检查更新
|
||||
checkUpdate: (): any => http.Get('/dashboard/check_update'),
|
||||
// 更新日志
|
||||
updateInfo: (): any => http.Get('/dashboard/update_info'),
|
||||
// 更新面板
|
||||
update: (): any => http.Post('/dashboard/update'),
|
||||
// 重启面板
|
||||
restart: (): any => http.Post('/dashboard/restart')
|
||||
}
|
||||
25
web/src/api/panel/home/index.ts
Normal file
25
web/src/api/panel/home/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { http } from '@/utils'
|
||||
|
||||
export default {
|
||||
// 面板信息
|
||||
panel: (): any => http.Get('/home/panel'),
|
||||
// 首页应用
|
||||
apps: (): any => http.Get('/home/apps'),
|
||||
// 实时信息
|
||||
current: (nets: string[], disks: string[]): any =>
|
||||
http.Post('/home/current', { nets, disks }, { meta: { noAlert: true } }),
|
||||
// 系统信息
|
||||
systemInfo: (): any => http.Get('/home/system_info'),
|
||||
// 统计信息
|
||||
countInfo: (): any => http.Get('/home/count_info'),
|
||||
// 已安装的数据库和PHP
|
||||
installedDbAndPhp: (): any => http.Get('/home/installed_db_and_php'),
|
||||
// 检查更新
|
||||
checkUpdate: (): any => http.Get('/home/check_update'),
|
||||
// 更新日志
|
||||
updateInfo: (): any => http.Get('/home/update_info'),
|
||||
// 更新面板
|
||||
update: (): any => http.Post('/home/update'),
|
||||
// 重启面板
|
||||
restart: (): any => http.Post('/home/restart')
|
||||
}
|
||||
@@ -6,13 +6,13 @@ const themeStore = useThemeStore()
|
||||
const router = useRouter()
|
||||
const logo = computed(() => themeStore.logo || logoImg)
|
||||
|
||||
const toDashboard = () => {
|
||||
router.push({ name: 'dashboard' })
|
||||
const toHome = () => {
|
||||
router.push({ name: 'home' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-60 f-c-c cursor-pointer" @click="toDashboard">
|
||||
<div class="h-60 f-c-c cursor-pointer" @click="toHome">
|
||||
<n-image :src="logo" height="32" preview-disabled />
|
||||
<h2
|
||||
v-show="!themeStore.sider.collapsed"
|
||||
|
||||
@@ -8,16 +8,17 @@ export function translateTitle(key: string): string {
|
||||
Backup: $gettext('Backup'),
|
||||
Certificate: $gettext('Certificate'),
|
||||
Container: $gettext('Container'),
|
||||
Dashboard: $gettext('Dashboard'),
|
||||
Update: $gettext('Update'),
|
||||
Database: $gettext('Database'),
|
||||
Files: $gettext('Files'),
|
||||
Firewall: $gettext('Firewall'),
|
||||
Home: $gettext('Home'),
|
||||
Monitoring: $gettext('Monitoring'),
|
||||
Settings: $gettext('Settings'),
|
||||
Project: $gettext('Project'),
|
||||
Setting: $gettext('Setting'),
|
||||
Terminal: $gettext('Terminal'),
|
||||
Tasks: $gettext('Tasks'),
|
||||
Task: $gettext('Task'),
|
||||
Toolbox: $gettext('Toolbox'),
|
||||
Update: $gettext('Update'),
|
||||
Website: $gettext('Website'),
|
||||
'Website Edit': $gettext('Website Edit'),
|
||||
// 应用标题
|
||||
|
||||
@@ -12,7 +12,7 @@ import { gettext, setCurrent, setupNaiveDiscreteApi } from '@/utils'
|
||||
|
||||
import { install as VueMonacoEditorPlugin } from '@guolao/vue-monaco-editor'
|
||||
|
||||
import dashboard from '@/api/panel/dashboard'
|
||||
import dashboard from '@/api/panel/home'
|
||||
import CronNaivePlugin from '@vue-js-cron/naive-ui'
|
||||
|
||||
async function setupApp() {
|
||||
|
||||
@@ -3,20 +3,37 @@ defineOptions({
|
||||
name: 'app-index'
|
||||
})
|
||||
|
||||
import { NButton } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import app from '@/api/panel/app'
|
||||
import InstallView from '@/views/app/InstallView.vue'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
|
||||
const currentTab = ref('installed')
|
||||
|
||||
const handleUpdateCache = () => {
|
||||
useRequest(app.updateCache()).onSuccess(() => {
|
||||
window.$message.success($gettext('Cache updated successfully'))
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<common-page show-header show-footer>
|
||||
<template #tabbar>
|
||||
<n-tabs v-model:value="currentTab" animated>
|
||||
<n-tab name="installed" :tab="$gettext('Installed')" />
|
||||
<n-tab name="install" :tab="$gettext('Install')" />
|
||||
<n-tab name="environment" :tab="$gettext('Environment')" />
|
||||
<n-tab name="compose" :tab="$gettext('Compose Templates')" />
|
||||
</n-tabs>
|
||||
<div class="flex items-center justify-between">
|
||||
<n-tabs v-model:value="currentTab" animated class="flex-1">
|
||||
<n-tab name="installed" :tab="$gettext('Installed')" />
|
||||
<n-tab name="install" :tab="$gettext('Install')" />
|
||||
<n-tab name="environment" :tab="$gettext('Environment')" />
|
||||
<n-tab name="compose" :tab="$gettext('Compose Templates')" />
|
||||
</n-tabs>
|
||||
<n-button v-if="currentTab != 'installed'" type="primary" @click="handleUpdateCache">
|
||||
{{ $gettext('Update Cache') }}
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
<install-view v-if="currentTab === 'install'" />
|
||||
</common-page>
|
||||
|
||||
@@ -196,13 +196,6 @@ const handleManage = (slug: string) => {
|
||||
router.push({ name: 'apps-' + slug + '-index' })
|
||||
}
|
||||
|
||||
const handleUpdateCache = () => {
|
||||
useRequest(app.updateCache()).onSuccess(() => {
|
||||
refresh()
|
||||
window.$message.success($gettext('Cache updated successfully'))
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
refresh()
|
||||
})
|
||||
@@ -210,11 +203,6 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<n-flex vertical>
|
||||
<n-flex>
|
||||
<n-button type="primary" @click="handleUpdateCache">
|
||||
{{ $gettext('Update Cache') }}
|
||||
</n-button>
|
||||
</n-flex>
|
||||
<n-alert type="warning">{{
|
||||
$gettext(
|
||||
'Before updating apps, it is strongly recommended to backup/snapshot first, so you can roll back immediately if there are any issues!'
|
||||
|
||||
@@ -3,14 +3,14 @@ defineOptions({
|
||||
name: 'backup-index'
|
||||
})
|
||||
|
||||
import dashboard from '@/api/panel/dashboard'
|
||||
import home from '@/api/panel/home'
|
||||
import ListView from '@/views/backup/ListView.vue'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
const currentTab = ref('website')
|
||||
|
||||
const { data: installedDbAndPhp } = useRequest(dashboard.installedDbAndPhp, {
|
||||
const { data: installedDbAndPhp } = useRequest(home.installedDbAndPhp, {
|
||||
initialData: {
|
||||
db: [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
defineOptions({
|
||||
name: 'dashboard-index'
|
||||
name: 'home-index'
|
||||
})
|
||||
|
||||
import { LineChart } from 'echarts/charts'
|
||||
@@ -16,7 +16,7 @@ import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { NButton, NPopconfirm, useThemeVars } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import dashboard from '@/api/panel/dashboard'
|
||||
import home from '@/api/panel/home'
|
||||
import { router } from '@/router'
|
||||
import { useTabStore } from '@/store'
|
||||
import { formatDateTime, formatDuration, toTimestamp } from '@/utils/common'
|
||||
@@ -39,7 +39,7 @@ const themeVars = useThemeVars()
|
||||
const tabStore = useTabStore()
|
||||
const realtime = ref<Realtime | null>(null)
|
||||
|
||||
const { data: systemInfo } = useRequest(dashboard.systemInfo, {
|
||||
const { data: systemInfo } = useRequest(home.systemInfo, {
|
||||
initialData: {
|
||||
procs: 0,
|
||||
hostname: '',
|
||||
@@ -59,7 +59,7 @@ const { data: systemInfo } = useRequest(dashboard.systemInfo, {
|
||||
disks: []
|
||||
}
|
||||
})
|
||||
const { data: homeApps, loading: homeAppsLoading } = useRequest(dashboard.homeApps, {
|
||||
const { data: apps, loading: appLoading } = useRequest(home.apps, {
|
||||
initialData: {
|
||||
description: '',
|
||||
icon: '',
|
||||
@@ -68,7 +68,7 @@ const { data: homeApps, loading: homeAppsLoading } = useRequest(dashboard.homeAp
|
||||
version: ''
|
||||
}
|
||||
})
|
||||
const { data: countInfo } = useRequest(dashboard.countInfo, {
|
||||
const { data: countInfo } = useRequest(home.countInfo, {
|
||||
initialData: {
|
||||
website: 0,
|
||||
database: 0,
|
||||
@@ -235,7 +235,7 @@ let isFetching = false
|
||||
const fetchCurrent = () => {
|
||||
if (isFetching) return
|
||||
isFetching = true
|
||||
useRequest(dashboard.current(nets.value, disks.value))
|
||||
useRequest(home.current(nets.value, disks.value))
|
||||
.onSuccess(({ data }) => {
|
||||
data.percent = formatPercent(data.percent)
|
||||
data.mem.usedPercent = formatPercent(data.mem.usedPercent)
|
||||
@@ -323,7 +323,7 @@ const fetchCurrent = () => {
|
||||
const handleRestartPanel = () => {
|
||||
clearInterval(homeInterval)
|
||||
window.$message.loading($gettext('Panel restarting...'))
|
||||
useRequest(dashboard.restart()).onSuccess(() => {
|
||||
useRequest(home.restart()).onSuccess(() => {
|
||||
window.$message.success($gettext('Panel restarted successfully'))
|
||||
setTimeout(() => {
|
||||
tabStore.reloadTab(tabStore.active)
|
||||
@@ -332,9 +332,9 @@ const handleRestartPanel = () => {
|
||||
}
|
||||
|
||||
const handleUpdate = () => {
|
||||
useRequest(dashboard.checkUpdate()).onSuccess(({ data }) => {
|
||||
useRequest(home.checkUpdate()).onSuccess(({ data }) => {
|
||||
if (data.update) {
|
||||
router.push({ name: 'dashboard-update' })
|
||||
router.push({ name: 'home-update' })
|
||||
} else {
|
||||
window.$message.success($gettext('Current version is the latest'))
|
||||
}
|
||||
@@ -682,7 +682,7 @@ if (import.meta.hot) {
|
||||
<n-card :segmented="true" size="small" :title="$gettext('Quick Apps')" min-h-340>
|
||||
<n-scrollbar max-h-270>
|
||||
<n-grid
|
||||
v-if="!homeAppsLoading"
|
||||
v-if="!appLoading"
|
||||
x-gap="12"
|
||||
y-gap="12"
|
||||
cols="3 s:1 m:2 l:3"
|
||||
@@ -690,7 +690,7 @@ if (import.meta.hot) {
|
||||
responsive="screen"
|
||||
p-10
|
||||
>
|
||||
<n-gi v-for="item in homeApps" :key="item.name">
|
||||
<n-gi v-for="item in apps" :key="item.name">
|
||||
<n-card
|
||||
:segmented="true"
|
||||
size="small"
|
||||
@@ -717,10 +717,10 @@ if (import.meta.hot) {
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</n-scrollbar>
|
||||
<n-text v-if="!homeAppsLoading && !homeApps.length">
|
||||
<n-text v-if="!appLoading && !apps.length">
|
||||
{{ $gettext('You have not set any apps to display here!') }}
|
||||
</n-text>
|
||||
<n-skeleton v-if="homeAppsLoading" text :repeat="12" />
|
||||
<n-skeleton v-if="appLoading" text :repeat="12" />
|
||||
</n-card>
|
||||
<n-card :segmented="true" size="small" :title="$gettext('Environment Information')">
|
||||
<n-table v-if="systemInfo" :single-line="false">
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'dashboard-update'
|
||||
name: 'home-update'
|
||||
})
|
||||
|
||||
import { MdPreview } from 'md-editor-v3'
|
||||
@@ -9,12 +9,12 @@ import type { MessageReactive } from 'naive-ui'
|
||||
import { NButton } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import dashboard from '@/api/panel/dashboard'
|
||||
import home from '@/api/panel/home'
|
||||
import { router } from '@/router'
|
||||
import { formatDateTime } from '@/utils'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
const { data: versions } = useRequest(dashboard.updateInfo, {
|
||||
const { data: versions } = useRequest(home.updateInfo, {
|
||||
initialData: []
|
||||
})
|
||||
let messageReactive: MessageReactive | null = null
|
||||
@@ -29,13 +29,13 @@ const handleUpdate = () => {
|
||||
messageReactive = window.$message.loading($gettext('Panel updating...'), {
|
||||
duration: 0
|
||||
})
|
||||
useRequest(dashboard.update())
|
||||
useRequest(home.update())
|
||||
.onSuccess(() => {
|
||||
setTimeout(() => {
|
||||
setTimeout(() => {
|
||||
window.location.reload()
|
||||
}, 400)
|
||||
router.push({ name: 'dashboard-index' })
|
||||
router.push({ name: 'home-index' })
|
||||
}, 2500)
|
||||
window.$message.success($gettext('Panel updated successfully'))
|
||||
})
|
||||
@@ -3,27 +3,26 @@ import type { RouteType } from '~/types/router'
|
||||
const Layout = () => import('@/layout/IndexView.vue')
|
||||
|
||||
export default {
|
||||
name: 'dashboard',
|
||||
name: 'home',
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect: '/dashboard',
|
||||
meta: {
|
||||
order: 0
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: 'dashboard-index',
|
||||
path: 'dashboard',
|
||||
name: 'home-index',
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Dashboard',
|
||||
icon: 'mdi:gauge',
|
||||
title: 'Home',
|
||||
icon: 'mdi:house-outline',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'dashboard-update',
|
||||
name: 'home-update',
|
||||
path: 'update',
|
||||
component: () => import('./UpdateView.vue'),
|
||||
isHidden: true,
|
||||
@@ -15,8 +15,8 @@ export default {
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Projects',
|
||||
icon: 'mdi:folder-multiple',
|
||||
title: 'Project',
|
||||
icon: 'mdi:folder-multiple-outline',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Settings',
|
||||
title: 'Setting',
|
||||
icon: 'mdi:settings-outline',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import app from '@/api/panel/app'
|
||||
import cron from '@/api/panel/cron'
|
||||
import dashboard from '@/api/panel/dashboard'
|
||||
import dashboard from '@/api/panel/home'
|
||||
import website from '@/api/panel/website'
|
||||
import Editor from '@guolao/vue-monaco-editor'
|
||||
import { CronNaive } from '@vue-js-cron/naive-ui'
|
||||
|
||||
@@ -5,7 +5,6 @@ defineOptions({
|
||||
|
||||
import CreateModal from '@/views/task/CreateModal.vue'
|
||||
import CronView from '@/views/task/CronView.vue'
|
||||
import SystemView from '@/views/task/SystemView.vue'
|
||||
import TaskView from '@/views/task/TaskView.vue'
|
||||
import { NButton } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
@@ -21,7 +20,6 @@ const create = ref(false)
|
||||
<template #tabbar>
|
||||
<n-tabs v-model:value="current" animated>
|
||||
<n-tab name="cron" :tab="$gettext('Scheduled Tasks')" />
|
||||
<n-tab name="system" :tab="$gettext('System Processes')" />
|
||||
<n-tab name="task" :tab="$gettext('Panel Tasks')" />
|
||||
</n-tabs>
|
||||
</template>
|
||||
@@ -32,7 +30,6 @@ const create = ref(false)
|
||||
</n-button>
|
||||
</n-flex>
|
||||
<cron-view v-if="current === 'cron'" />
|
||||
<system-view v-if="current === 'system'" />
|
||||
<task-view v-if="current === 'task'" />
|
||||
</n-flex>
|
||||
</common-page>
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
path: '',
|
||||
component: () => import('./IndexView.vue'),
|
||||
meta: {
|
||||
title: 'Tasks',
|
||||
title: 'Task',
|
||||
icon: 'mdi:timetable',
|
||||
role: ['admin'],
|
||||
requireAuth: true
|
||||
|
||||
@@ -4,22 +4,25 @@ defineOptions({
|
||||
})
|
||||
|
||||
import BenchmarkView from '@/views/toolbox/BenchmarkView.vue'
|
||||
import ProcessView from '@/views/toolbox/ProcessView.vue'
|
||||
import SystemView from '@/views/toolbox/SystemView.vue'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
const current = ref('system')
|
||||
const current = ref('process')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<common-page show-header show-footer>
|
||||
<template #tabbar>
|
||||
<n-tabs v-model:value="current" animated>
|
||||
<n-tab name="process" :tab="$gettext('Process')" />
|
||||
<n-tab name="system" :tab="$gettext('System')" />
|
||||
<n-tab name="benchmark" :tab="$gettext('Benchmark')" />
|
||||
</n-tabs>
|
||||
</template>
|
||||
<n-flex vertical>
|
||||
<process-view v-if="current === 'process'" />
|
||||
<system-view v-if="current === 'system'" />
|
||||
<benchmark-view v-if="current === 'benchmark'" />
|
||||
</n-flex>
|
||||
|
||||
171
web/src/views/toolbox/ProcessView.vue
Normal file
171
web/src/views/toolbox/ProcessView.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<script setup lang="ts">
|
||||
import { NButton, NDataTable, NPopconfirm, NTag } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import process from '@/api/panel/process'
|
||||
import { formatBytes, formatDateTime, formatPercent } from '@/utils'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
|
||||
const columns: any = [
|
||||
{
|
||||
title: 'PID',
|
||||
key: 'pid',
|
||||
width: 120,
|
||||
ellipsis: { tooltip: true }
|
||||
},
|
||||
{
|
||||
title: $gettext('Name'),
|
||||
key: 'name',
|
||||
minWidth: 250,
|
||||
resizable: true,
|
||||
ellipsis: { tooltip: true }
|
||||
},
|
||||
{
|
||||
title: $gettext('Parent PID'),
|
||||
key: 'ppid',
|
||||
width: 120,
|
||||
ellipsis: { tooltip: true }
|
||||
},
|
||||
{
|
||||
title: $gettext('Threads'),
|
||||
key: 'num_threads',
|
||||
width: 100,
|
||||
ellipsis: { tooltip: true }
|
||||
},
|
||||
{
|
||||
title: $gettext('User'),
|
||||
key: 'username',
|
||||
minWidth: 100,
|
||||
ellipsis: { tooltip: true }
|
||||
},
|
||||
{
|
||||
title: $gettext('Status'),
|
||||
key: 'status',
|
||||
minWidth: 150,
|
||||
ellipsis: { tooltip: true },
|
||||
render(row: any) {
|
||||
switch (row.status) {
|
||||
case 'R':
|
||||
return h(NTag, { type: 'success' }, { default: () => $gettext('Running') })
|
||||
case 'S':
|
||||
return h(NTag, { type: 'warning' }, { default: () => $gettext('Sleeping') })
|
||||
case 'T':
|
||||
return h(NTag, { type: 'error' }, { default: () => $gettext('Stopped') })
|
||||
case 'I':
|
||||
return h(NTag, { type: 'primary' }, { default: () => $gettext('Idle') })
|
||||
case 'Z':
|
||||
return h(NTag, { type: 'error' }, { default: () => $gettext('Zombie') })
|
||||
case 'W':
|
||||
return h(NTag, { type: 'warning' }, { default: () => $gettext('Waiting') })
|
||||
case 'L':
|
||||
return h(NTag, { type: 'info' }, { default: () => $gettext('Locked') })
|
||||
default:
|
||||
return h(NTag, { type: 'default' }, { default: () => row.status })
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'CPU',
|
||||
key: 'cpu',
|
||||
minWidth: 100,
|
||||
ellipsis: { tooltip: true },
|
||||
render(row: any): string {
|
||||
return formatPercent(row.cpu) + '%'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: $gettext('Memory'),
|
||||
key: 'rss',
|
||||
minWidth: 100,
|
||||
ellipsis: { tooltip: true },
|
||||
render(row: any): string {
|
||||
return formatBytes(row.rss)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: $gettext('Start Time'),
|
||||
key: 'start_time',
|
||||
width: 160,
|
||||
ellipsis: { tooltip: true },
|
||||
render(row: any): string {
|
||||
return formatDateTime(row.start_time)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: $gettext('Actions'),
|
||||
key: 'actions',
|
||||
width: 150,
|
||||
hideInExcel: true,
|
||||
render(row: any) {
|
||||
return h(
|
||||
NPopconfirm,
|
||||
{
|
||||
onPositiveClick: () => {
|
||||
useRequest(process.kill(row.pid)).onSuccess(() => {
|
||||
refresh()
|
||||
window.$message.success(
|
||||
$gettext('Process %{ pid } has been terminated', { pid: row.pid })
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
return $gettext('Are you sure you want to terminate process %{ pid }?', {
|
||||
pid: row.pid
|
||||
})
|
||||
},
|
||||
trigger: () => {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
type: 'error'
|
||||
},
|
||||
{
|
||||
default: () => $gettext('Terminate')
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
(page, pageSize) => process.list(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
initialPageSize: 20,
|
||||
total: (res: any) => res.total,
|
||||
data: (res: any) => res.items
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-flex vertical>
|
||||
<n-data-table
|
||||
striped
|
||||
remote
|
||||
:scroll-x="1400"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:row-key="(row: any) => row.pid"
|
||||
v-model:page="page"
|
||||
v-model:pageSize="pageSize"
|
||||
:pagination="{
|
||||
page: page,
|
||||
pageCount: pageCount,
|
||||
pageSize: pageSize,
|
||||
itemCount: total,
|
||||
showQuickJumper: true,
|
||||
showSizePicker: true,
|
||||
pageSizes: [20, 50, 100, 200]
|
||||
}"
|
||||
/>
|
||||
</n-flex>
|
||||
</template>
|
||||
@@ -9,7 +9,7 @@ import { NButton } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import cert from '@/api/panel/cert'
|
||||
import dashboard from '@/api/panel/dashboard'
|
||||
import dashboard from '@/api/panel/home'
|
||||
import website from '@/api/panel/website'
|
||||
import ProxyBuilderModal from '@/views/website/ProxyBuilderModal.vue'
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { NButton, NCheckbox, NDataTable, NFlex, NInput, NPopconfirm, NSwitch, NTag } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import dashboard from '@/api/panel/dashboard'
|
||||
import dashboard from '@/api/panel/home'
|
||||
import website from '@/api/panel/website'
|
||||
import { useFileStore } from '@/store'
|
||||
import { generateRandomString, isNullOrUndef } from '@/utils'
|
||||
|
||||
Reference in New Issue
Block a user