diff --git a/desktop/assets/MadeWithSlint-logo-whitebg.png b/desktop/assets/MadeWithSlint-logo-whitebg.png deleted file mode 100644 index f7f39c1..0000000 Binary files a/desktop/assets/MadeWithSlint-logo-whitebg.png and /dev/null differ diff --git a/server-ui/package-lock.json b/server-ui/package-lock.json index 18a1693..51005f2 100644 --- a/server-ui/package-lock.json +++ b/server-ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "orbien-server-ui", - "version": "2.1.0-SNAPSHOT", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orbien-server-ui", - "version": "2.1.0-SNAPSHOT", + "version": "3.0.0", "dependencies": { "vue": "^3.5.22", "vue-i18n": "^11.4.8", diff --git a/server-ui/package.json b/server-ui/package.json index 14d4e54..b60c5a3 100644 --- a/server-ui/package.json +++ b/server-ui/package.json @@ -1,7 +1,7 @@ { "name": "orbien-server-ui", "private": true, - "version": "2.1.0-SNAPSHOT", + "version": "3.0.0", "type": "module", "scripts": { "dev": "vite", diff --git a/server-ui/src/api/client.ts b/server-ui/src/api/client.ts index bccda09..0599697 100644 --- a/server-ui/src/api/client.ts +++ b/server-ui/src/api/client.ts @@ -2,8 +2,8 @@ import type { Page, SystemInfo, ClientInfo, - ProxyInfo, - ProxyTrafficResp, + TunnelInfo, + TunnelTrafficResp, ApiResponse, } from '@/types/api' import {ApiError} from './errors' @@ -31,34 +31,34 @@ export function fetchClients(page = 1, pageSize = 200) { return api>(`/api/v1/clients?page=${page}&pageSize=${pageSize}`) } -export function fetchClient(runId: string) { - return api(`/api/v1/clients/${encodeURIComponent(runId)}`) +export function fetchClient(sessionId: string) { + return api(`/api/v1/clients/${encodeURIComponent(sessionId)}`) } -export function kickClient(runId: string) { - return api(`/api/v1/clients/${encodeURIComponent(runId)}/kick`, { +export function kickClient(sessionId: string) { + return api(`/api/v1/clients/${encodeURIComponent(sessionId)}/kick`, { method: 'POST', }) } -export type ProxyListParams = { +export type TunnelListParams = { page?: number pageSize?: number - clientId?: string + sessionId?: string q?: string } -export function fetchProxies(pageOrParams: number | ProxyListParams = 1, pageSize = 200) { - const params: ProxyListParams = +export function fetchTunnels(pageOrParams: number | TunnelListParams = 1, pageSize = 200) { + const params: TunnelListParams = typeof pageOrParams === 'number' ? {page: pageOrParams, pageSize} : pageOrParams const qs = new URLSearchParams() qs.set('page', String(params.page ?? 1)) qs.set('pageSize', String(params.pageSize ?? 200)) - if (params.clientId) qs.set('clientId', params.clientId) + if (params.sessionId) qs.set('sessionId', params.sessionId) if (params.q) qs.set('q', params.q) - return api>(`/api/v1/proxies?${qs.toString()}`) + return api>(`/api/v1/tunnels?${qs.toString()}`) } export type TrafficRange = '7d' | '24h' @@ -67,12 +67,12 @@ function trafficQuery(range: TrafficRange = '7d') { return range === '24h' ? '?range=24h' : '?range=7d' } -export function fetchProxyTraffic(name: string, range: TrafficRange = '7d') { - return api( - `/api/v1/proxies/${encodeURIComponent(name)}/traffic${trafficQuery(range)}`, +export function fetchTunnelTraffic(name: string, range: TrafficRange = '7d') { + return api( + `/api/v1/tunnels/${encodeURIComponent(name)}/traffic${trafficQuery(range)}`, ) } export function fetchSystemTraffic(range: TrafficRange = '7d') { - return api(`/api/v1/system/traffic${trafficQuery(range)}`) + return api(`/api/v1/system/traffic${trafficQuery(range)}`) } diff --git a/server-ui/src/api/index.ts b/server-ui/src/api/index.ts index 5c7cfa0..cea0fcc 100644 --- a/server-ui/src/api/index.ts +++ b/server-ui/src/api/index.ts @@ -4,8 +4,8 @@ export { fetchClients, fetchClient, kickClient, - fetchProxies, - fetchProxyTraffic, + fetchTunnels, + fetchTunnelTraffic, fetchSystemTraffic, } from './client' -export type {ProxyListParams, TrafficRange} from './client' +export type {TunnelListParams, TrafficRange} from './client' diff --git a/server-ui/src/assets/icon/arrow-down.svg b/server-ui/src/assets/icon/arrow-down.svg new file mode 100644 index 0000000..46d7cdc --- /dev/null +++ b/server-ui/src/assets/icon/arrow-down.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/arrow-left.svg b/server-ui/src/assets/icon/arrow-left.svg new file mode 100644 index 0000000..37945df --- /dev/null +++ b/server-ui/src/assets/icon/arrow-left.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/arrow-right.svg b/server-ui/src/assets/icon/arrow-right.svg new file mode 100644 index 0000000..652ddfb --- /dev/null +++ b/server-ui/src/assets/icon/arrow-right.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/arrow-up.svg b/server-ui/src/assets/icon/arrow-up.svg new file mode 100644 index 0000000..e5e02ad --- /dev/null +++ b/server-ui/src/assets/icon/arrow-up.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/server-ui/src/assets/icon/computer.svg b/server-ui/src/assets/icon/computer.svg new file mode 100644 index 0000000..e26ddee --- /dev/null +++ b/server-ui/src/assets/icon/computer.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/download.svg b/server-ui/src/assets/icon/download.svg new file mode 100644 index 0000000..e220ff2 --- /dev/null +++ b/server-ui/src/assets/icon/download.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/kick.svg b/server-ui/src/assets/icon/kick.svg new file mode 100644 index 0000000..7c277a2 --- /dev/null +++ b/server-ui/src/assets/icon/kick.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/link.svg b/server-ui/src/assets/icon/link.svg new file mode 100644 index 0000000..7333c8c --- /dev/null +++ b/server-ui/src/assets/icon/link.svg @@ -0,0 +1,10 @@ + + + + diff --git a/server-ui/src/assets/icon/moon.svg b/server-ui/src/assets/icon/moon.svg new file mode 100644 index 0000000..ba37e58 --- /dev/null +++ b/server-ui/src/assets/icon/moon.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/search.svg b/server-ui/src/assets/icon/search.svg new file mode 100644 index 0000000..dd30c8d --- /dev/null +++ b/server-ui/src/assets/icon/search.svg @@ -0,0 +1,10 @@ + + + + diff --git a/server-ui/src/assets/icon/share.svg b/server-ui/src/assets/icon/share.svg new file mode 100644 index 0000000..28eb068 --- /dev/null +++ b/server-ui/src/assets/icon/share.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/signal.svg b/server-ui/src/assets/icon/signal.svg new file mode 100644 index 0000000..270db29 --- /dev/null +++ b/server-ui/src/assets/icon/signal.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/sun.svg b/server-ui/src/assets/icon/sun.svg new file mode 100644 index 0000000..fa8d400 --- /dev/null +++ b/server-ui/src/assets/icon/sun.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/upload.svg b/server-ui/src/assets/icon/upload.svg new file mode 100644 index 0000000..8781e50 --- /dev/null +++ b/server-ui/src/assets/icon/upload.svg @@ -0,0 +1,6 @@ + + + diff --git a/server-ui/src/assets/icon/user.svg b/server-ui/src/assets/icon/user.svg new file mode 100644 index 0000000..e8a894f --- /dev/null +++ b/server-ui/src/assets/icon/user.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/server-ui/src/assets/icon/users.svg b/server-ui/src/assets/icon/users.svg new file mode 100644 index 0000000..8a0ba4b --- /dev/null +++ b/server-ui/src/assets/icon/users.svg @@ -0,0 +1,10 @@ + + + + diff --git a/server-ui/src/assets/styles/main.css b/server-ui/src/assets/styles/main.css index 56283ab..83350f5 100644 --- a/server-ui/src/assets/styles/main.css +++ b/server-ui/src/assets/styles/main.css @@ -23,7 +23,6 @@ html[data-theme='dark'] { --focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent); --status-ok: #52c41a; --status-ok-soft: rgba(82, 196, 26, 0.14); - --table-head-bg: rgba(255, 255, 255, 0.04); --scrollbar: #434343; --header-height: 56px; --sidebar-width: 200px; @@ -55,7 +54,6 @@ html[data-theme='light'] { --focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent); --status-ok: #52c41a; --status-ok-soft: rgba(82, 196, 26, 0.1); - --table-head-bg: #fafafa; --scrollbar: #d9d9d9; } @@ -82,11 +80,8 @@ body { .top, .sidebar, .card, -table, -.ghost, .theme-toggle, .icon-btn, -.pill, .err, .side-link, .sidebar-collapse { @@ -147,6 +142,9 @@ table, align-items: center; gap: 0.65rem; min-width: 0; + text-decoration: none; + color: inherit; + cursor: pointer; } .logo-img { @@ -186,7 +184,6 @@ html[data-theme='dark'] .brand-orb { flex-shrink: 0; } -.ghost, .theme-toggle, .icon-btn { background: var(--panel); @@ -217,14 +214,12 @@ html[data-theme='dark'] .brand-orb { stroke-linejoin: round; } -.ghost:hover:not(:disabled), .theme-toggle:hover, .icon-btn:hover { border-color: var(--line-strong); background: var(--panel-hover); } -.ghost:focus-visible, .theme-toggle:focus-visible, .icon-btn:focus-visible, .side-link:focus-visible, @@ -234,11 +229,6 @@ html[data-theme='dark'] .brand-orb { box-shadow: var(--focus-ring); } -.ghost:disabled { - opacity: 0.5; - cursor: not-allowed; -} - .theme-toggle { display: inline-grid; place-items: center; @@ -251,11 +241,8 @@ html[data-theme='dark'] .brand-orb { .theme-toggle svg { width: 1.1rem; height: 1.1rem; - fill: none; - stroke: currentColor; - stroke-width: 1.8; - stroke-linecap: round; - stroke-linejoin: round; + fill: currentColor; + stroke: none; } .locale-switch { @@ -355,11 +342,8 @@ html[data-theme='dark'] .brand-orb { .side-icon svg { width: 1.2rem; height: 1.2rem; - fill: none; - stroke: currentColor; - stroke-width: 1.7; - stroke-linecap: round; - stroke-linejoin: round; + fill: currentColor; + stroke: none; } .side-label { @@ -395,14 +379,26 @@ html[data-theme='dark'] .brand-orb { } .sidebar-collapse svg { - width: 1.1rem; - height: 1.1rem; + width: 1.05rem; + height: 1.05rem; flex-shrink: 0; - fill: none; - stroke: currentColor; - stroke-width: 1.8; - stroke-linecap: round; - stroke-linejoin: round; + fill: currentColor; + stroke: none; +} + +.collapse-icon { + width: 1.05rem; + height: 1.05rem; + display: inline-grid; + place-items: center; + line-height: 0; + color: inherit; +} + +.collapse-icon svg { + width: 100%; + height: 100%; + display: block; } .sidebar-backdrop { @@ -454,10 +450,6 @@ html[data-theme='dark'] .brand-orb { border-color: var(--line-strong); } -.card.wide { - grid-column: 1 / -1; -} - .k { color: var(--muted); font-size: 0.85rem; @@ -477,78 +469,6 @@ html[data-theme='dark'] .brand-orb { color: var(--text-secondary); } -table { - width: 100%; - border-collapse: collapse; - background: var(--panel); - border: 1px solid var(--line); - border-radius: 12px; - overflow: hidden; - box-shadow: var(--shadow); -} - -thead { - background: var(--table-head-bg); -} - -th, -td { - text-align: left; - padding: 0.7rem 0.85rem; - border-bottom: 1px solid var(--line); - color: var(--text); -} - -th { - color: var(--muted); - font-weight: 500; - font-size: 0.85rem; -} - -tbody tr:hover td { - background: var(--panel-hover); -} - -tbody tr:last-child td { - border-bottom: none; -} - -.empty { - color: var(--muted); - text-align: center; -} - -.pill { - display: inline-block; - background: var(--accent-soft); - color: var(--accent-text); - border: 1px solid transparent; - padding: 0.15rem 0.55rem; - border-radius: 999px; - font-size: 0.8rem; - font-weight: 600; -} - -.status { - display: inline-flex; - align-items: center; - gap: 0.35rem; - color: var(--status-ok); - background: var(--status-ok-soft); - padding: 0.15rem 0.55rem; - border-radius: 999px; - font-size: 0.8rem; - font-weight: 600; -} - -.status::before { - content: ''; - width: 0.45rem; - height: 0.45rem; - border-radius: 50%; - background: currentColor; -} - .err { color: var(--danger); background: var(--danger-bg); diff --git a/server-ui/src/components/AppIcon.vue b/server-ui/src/components/AppIcon.vue index a44b7e1..5afe4a4 100644 --- a/server-ui/src/components/AppIcon.vue +++ b/server-ui/src/components/AppIcon.vue @@ -1,112 +1,50 @@ diff --git a/server-ui/src/components/DonutChart.vue b/server-ui/src/components/DonutChart.vue index b2d1fe0..86acbd7 100644 --- a/server-ui/src/components/DonutChart.vue +++ b/server-ui/src/components/DonutChart.vue @@ -66,7 +66,7 @@ function donutArc(x: number, y: number, radius: number, start: number, end: numb class="donut-svg" :viewBox="`0 0 ${size} ${size}`" role="img" - :aria-label="t('monitor.proxyTypes')" + :aria-label="t('monitor.tunnelTypes')" > -export type IconTone = 'blue' | 'green' | 'purple' | 'violet' | 'orange' | 'slate' | 'teal' +export type IconTone = 'blue' | 'green' | 'violet' | 'orange' @@ -61,10 +57,4 @@ withDefaults( .stat-icon { margin-top: 0.05rem; } - -.stat-hint { - margin-top: 0.45rem; - color: var(--muted); - font-size: 0.78rem; -} diff --git a/server-ui/src/components/ThemeToggle.vue b/server-ui/src/components/ThemeToggle.vue index b3634b9..ee4e35d 100644 --- a/server-ui/src/components/ThemeToggle.vue +++ b/server-ui/src/components/ThemeToggle.vue @@ -1,5 +1,7 @@ @@ -12,14 +14,24 @@ const {isDark, label, toggle} = useTheme() :title="label" @click="toggle" > - - +