Skip to content

Commit

Permalink
feat: activity tab
Browse files Browse the repository at this point in the history
  • Loading branch information
Innei committed Aug 10, 2023
1 parent 8e0c3ad commit 42f2bcb
Show file tree
Hide file tree
Showing 7 changed files with 393 additions and 247 deletions.
20 changes: 17 additions & 3 deletions src/components/icons/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import CheckCircleOutlined from '@vicons/antd/CheckCircleOutlined'
import QuestionCircleOutlined from '@vicons/antd/es/QuestionCircleOutlined'
import Lock from '@vicons/antd/LockFilled'
import Snippet from '@vicons/antd/SnippetsFilled'
import QuestionCircleOutlined from '@vicons/antd/es/QuestionCircleOutlined'
import Pen from '@vicons/fa/Pen'
import SlackHash from '@vicons/fa/SlackHash'
import Book from '@vicons/fa/es/Book'
import Bookmark from '@vicons/fa/es/Bookmark'
import ChartLine from '@vicons/fa/es/ChartLine'
Expand All @@ -24,6 +22,8 @@ import TelegramPlane from '@vicons/fa/es/TelegramPlane'
import ThumbsUp from '@vicons/fa/es/ThumbsUp'
import UndoAlt from '@vicons/fa/es/UndoAlt'
import UserFriends from '@vicons/fa/es/UserFriends'
import Pen from '@vicons/fa/Pen'
import SlackHash from '@vicons/fa/SlackHash'
import Add12Filled from '@vicons/fluent/es/Add12Filled'
import Delete16Regular from '@vicons/fluent/es/Delete16Regular'
import EmojiAdd24Regular from '@vicons/fluent/es/EmojiAdd24Regular'
Expand Down Expand Up @@ -483,3 +483,17 @@ export function MagnifyingGlass() {
</svg>
)
}

export const MidHammer = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M2 19.63L13.43 8.2l-.71-.7l1.42-1.43L12 3.89c1.2-1.19 3.09-1.19 4.27 0l3.6 3.61l-1.42 1.41h2.84l.71.71l-3.55 3.59l-.71-.71V9.62l-1.47 1.42l-.71-.71L4.13 21.76L2 19.63Z"
></path>
</svg>
)
4 changes: 3 additions & 1 deletion src/router/name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export enum RouteName {
System = 'setting-system',
Security = 'setting-security',
Reset = 'reset',
Other = 'other',
Backup = 'backup',
Markdown = 'markdown',
Subscribe = 'subscribe',
Expand All @@ -43,4 +42,7 @@ export enum RouteName {

AssetTemplate = 'asset-template',
Pty = 'pty',

Maintain = 'maintain',
Other = 'other',
}
42 changes: 27 additions & 15 deletions src/router/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
FunctionIcon,
LogIcon,
MarkdownIcon,
MidHammer,
PencilAltIcon,
PencilIcon,
PuzzlePieceIcon,
Expand All @@ -34,6 +35,7 @@ import $RouterView from 'layouts/router-view'
import { SidebarLayout } from 'layouts/sidebar'
import { DashBoardView } from 'views/dashboard'
import type { RouteRecordRaw } from 'vue-router'

import SetupLayout from '../layouts/setup-view.vue'
import LoginView from '../views/login/index.vue'
import { RouteName } from './name'
Expand Down Expand Up @@ -303,13 +305,11 @@ export const routeForMenu: Array<RouteRecordRaw> = [
},
component: () => import('../views/setting'),
},

{
path: '/other',
path: '/extra-features',
name: RouteName.Other,
meta: {
title: '其他',
icon: <EllipsisHIcon />,
},
meta: { title: '附加功能', icon: <EllipsisHIcon /> },
component: $RouterView,
children: [
{
Expand All @@ -330,15 +330,6 @@ export const routeForMenu: Array<RouteRecordRaw> = [
},
component: () => import('../views/assets/template'),
},
{
path: 'backup',
name: RouteName.Backup,
meta: {
title: '备份',
icon: <UndoAltIcon />,
},
component: () => import('../views/other/backup'),
},
{
path: 'markdown',
name: RouteName.Markdown,
Expand All @@ -358,6 +349,18 @@ export const routeForMenu: Array<RouteRecordRaw> = [
},
component: () => import('../views/other/subscribe'),
},
],
},
{
name: RouteName.Maintain,
path: '/maintain',
component: $RouterView,
redirect: '/maintain/log',
meta: {
title: '维护',
icon: <MidHammer />,
},
children: [
{
path: 'cron',
name: RouteName.Cron,
Expand All @@ -367,6 +370,16 @@ export const routeForMenu: Array<RouteRecordRaw> = [
},
component: () => import('../views/other/cron'),
},
{
path: 'backup',
name: RouteName.Backup,
meta: {
title: '备份',
icon: <UndoAltIcon />,
},
component: () => import('../views/other/backup'),
},

{
path: 'log',
name: RouteName.Log,
Expand Down Expand Up @@ -397,7 +410,6 @@ export const routes: RouteRecordRaw[] = [
redirect: '/dashboard',
children: [...routeForMenu],
},

{
path: '/',
component: SetupLayout,
Expand Down
192 changes: 192 additions & 0 deletions src/views/analyze/components/analyze-data-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { IpInfoPopover } from 'components/ip-info'
import { Table } from 'components/table'
import { useDataTableFetch } from 'hooks/use-table'
import { useLayout } from 'layouts/content'
import { NButton, NEllipsis } from 'naive-ui'
import { parseDate, RESTManager } from 'utils'
import { defineComponent, onBeforeMount, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import type { UA } from 'models/analyze'
import type { Pager } from 'models/base'
import type { TableColumns } from 'naive-ui/lib/data-table/src/interface'

import { HeaderActionButton } from '~/components/button/rounded-button'
import { RefreshOutlineIcon, TrashIcon } from '~/components/icons'
import { DeleteConfirmButton } from '~/components/special-button/delete-confirm'
import { router } from '~/router'

export const AnalyzeDataTable = defineComponent({
setup() {
const route = useRoute()
const { setHeaderButtons } = useLayout()
onMounted(() => {
setHeaderButtons(
<>
<HeaderActionButton
icon={<RefreshOutlineIcon />}
variant="success"
name="刷新数据"
onClick={() => {
if (+route.query.page! === 1) {
fetchData()
} else {
router.replace({
path: route.path,
query: { ...route.query, page: 1 },
})
}
}}
></HeaderActionButton>
<DeleteConfirmButton
onDelete={async () => {
await RESTManager.api.analyze.delete()

if (parseInt(route.query.page as string) === 1) {
fetchData()
} else {
router.replace({
path: route.path,
query: {
page: 1,
},
})
}
}}
customSuccessMessage="已清空"
message="你确定要清空数据表?"
customButtonTip="清空表"
customIcon={<TrashIcon />}
/>
</>,
)

onBeforeUnmount(() => {
setHeaderButtons(null)
})
})
const {
data,
pager,
fetchDataFn: fetchData,
} = useDataTableFetch(
(data, pager) =>
async (page = route.query.page || 1, size = 30) => {
const response = (await RESTManager.api.analyze.get({
params: {
page,
size,
},
})) as {
data: UA.Root[]
pagination: Pager
}

data.value = response.data
pager.value = response.pagination
},
)

onBeforeMount(() => {
fetchData()
})

return () => (
<Table
data={data}
onFetchData={fetchData}
pager={pager}
columns={
[
{
title: '时间',
key: 'timestamp',
width: 150,
render({ timestamp }) {
return parseDate(timestamp, 'M-d HH:mm:ss')
},
},
{
title: 'IP',
key: 'ip',
width: 100,
render({ ip }) {
if (!ip) {
return null
}
return (
<IpInfoPopover
ip={ip}
triggerEl={
<NButton text size="tiny" type="primary">
{ip}
</NButton>
}
></IpInfoPopover>
)
},
},

{
title: '请求路径',
key: 'path',
render({ path }) {
return (
<NEllipsis class="max-w-[150px] truncate">
{path ?? ''}
</NEllipsis>
)
},
},

{
key: 'ua',
title: '浏览器',
render({ ua }) {
return (
<NEllipsis class="max-w-[200px] truncate">
{ua.browser
? Object.values(ua.browser).filter(Boolean).join(' ')
: 'N/A'}
</NEllipsis>
)
},
},

{
key: 'ua',
title: 'OS',
render({ ua }) {
return (
<NEllipsis class="max-w-[150px] truncate">
{ua.os
? Object.values(ua.os).filter(Boolean).join(' ')
: 'N/A'}
</NEllipsis>
)
},
},

{
key: 'ua',
title: 'User Agent',
render({ ua }) {
return (
<NEllipsis lineClamp={2}>
{{
default() {
return ua.ua ?? ''
},
tooltip() {
return <div class="max-w-[500px]">{ua.ua ?? ''}</div>
},
}}
</NEllipsis>
)
},
},
] as TableColumns<UA.Root>
}
></Table>
)
},
})
Loading

0 comments on commit 42f2bcb

Please sign in to comment.