mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-12-26 07:24:10 +08:00
feat: settings per-page
This commit is contained in:
parent
c607a31070
commit
d77626058a
14
src/components/ConfigTitle.tsx
Normal file
14
src/components/ConfigTitle.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { children, ParentComponent } from 'solid-js'
|
||||
|
||||
export const ConfigTitle: ParentComponent<{ withDivider?: boolean }> = (
|
||||
props,
|
||||
) => (
|
||||
<div
|
||||
class="pb-4 text-lg font-semibold"
|
||||
classList={{
|
||||
divider: props.withDivider,
|
||||
}}
|
||||
>
|
||||
{children(() => props.children)()}
|
||||
</div>
|
||||
)
|
@ -14,17 +14,20 @@ import {
|
||||
useDragDropContext,
|
||||
} from '@thisbeyond/solid-dnd'
|
||||
import { Component, For, Show, createSignal } from 'solid-js'
|
||||
import { Button } from '~/components'
|
||||
import { Button, ConfigTitle } from '~/components'
|
||||
import {
|
||||
CONNECTIONS_TABLE_ACCESSOR_KEY,
|
||||
CONNECTIONS_TABLE_INITIAL_COLUMN_ORDER,
|
||||
CONNECTIONS_TABLE_INITIAL_COLUMN_VISIBILITY,
|
||||
MODAL,
|
||||
TAILWINDCSS_SIZE,
|
||||
} from '~/constants'
|
||||
import { connectionsTableSize, setConnectionsTableSize } from '~/signals'
|
||||
|
||||
type ColumnVisibility = Partial<Record<CONNECTIONS_TABLE_ACCESSOR_KEY, boolean>>
|
||||
type ColumnOrder = CONNECTIONS_TABLE_ACCESSOR_KEY[]
|
||||
|
||||
export const ConnectionsTableOrderingModal = (props: {
|
||||
export const ConnectionsSettingsModal = (props: {
|
||||
order: ColumnOrder
|
||||
visible: ColumnVisibility
|
||||
onOrderChange: (value: ColumnOrder) => void
|
||||
@ -76,8 +79,9 @@ export const ConnectionsTableOrderingModal = (props: {
|
||||
'transition-transform': !!state.active.draggable,
|
||||
}}
|
||||
>
|
||||
<div class="my-1 flex cursor-grab justify-between p-1">
|
||||
<div class="flex cursor-grab justify-between py-2">
|
||||
<span class="select-none">{t(key)}</span>
|
||||
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle"
|
||||
@ -96,27 +100,50 @@ export const ConnectionsTableOrderingModal = (props: {
|
||||
|
||||
return (
|
||||
<dialog
|
||||
id="connections-table-ordering-modal"
|
||||
id={MODAL.CONNECTIONS_SETTINGS}
|
||||
class="modal modal-bottom sm:modal-middle"
|
||||
>
|
||||
<div class="modal-box" onContextMenu={(e) => e.preventDefault()}>
|
||||
<DragDropProvider
|
||||
onDragStart={onDragStart}
|
||||
onDragEnd={onDragEnd as DragEventHandler}
|
||||
collisionDetector={closestCenter}
|
||||
>
|
||||
<DragDropSensors />
|
||||
<div
|
||||
class="modal-box flex flex-col gap-4"
|
||||
onContextMenu={(e) => e.preventDefault()}
|
||||
>
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('tableSize')}</ConfigTitle>
|
||||
|
||||
<SortableProvider ids={props.order}>
|
||||
<For each={props.order}>{(key) => <FormRow key={key} />}</For>
|
||||
</SortableProvider>
|
||||
<select
|
||||
class="select select-bordered w-full"
|
||||
value={connectionsTableSize()}
|
||||
onChange={(e) =>
|
||||
setConnectionsTableSize(e.target.value as TAILWINDCSS_SIZE)
|
||||
}
|
||||
>
|
||||
<For each={Object.values(TAILWINDCSS_SIZE)}>
|
||||
{(value) => <option value={value}>{t(value)}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<DragOverlay>
|
||||
<Show when={activeKey()}>
|
||||
<div>{t(activeKey()!)}</div>
|
||||
</Show>
|
||||
</DragOverlay>
|
||||
</DragDropProvider>
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('sort')}</ConfigTitle>
|
||||
|
||||
<DragDropProvider
|
||||
onDragStart={onDragStart}
|
||||
onDragEnd={onDragEnd as DragEventHandler}
|
||||
collisionDetector={closestCenter}
|
||||
>
|
||||
<DragDropSensors />
|
||||
|
||||
<SortableProvider ids={props.order}>
|
||||
<For each={props.order}>{(key) => <FormRow key={key} />}</For>
|
||||
</SortableProvider>
|
||||
|
||||
<DragOverlay>
|
||||
<Show when={activeKey()}>
|
||||
<div>{t(activeKey()!)}</div>
|
||||
</Show>
|
||||
</DragOverlay>
|
||||
</DragDropProvider>
|
||||
</div>
|
||||
|
||||
<div class="modal-action">
|
||||
<Button
|
@ -1,4 +1,5 @@
|
||||
import { Component, Show } from 'solid-js'
|
||||
import { MODAL } from '~/constants'
|
||||
import { allConnections } from '~/signals'
|
||||
|
||||
export const ConnectionsTableDetailsModal: Component<{
|
||||
@ -6,7 +7,7 @@ export const ConnectionsTableDetailsModal: Component<{
|
||||
}> = (props) => {
|
||||
return (
|
||||
<dialog
|
||||
id="connections-table-details-modal"
|
||||
id={MODAL.CONNECTIONS_TABLE_DETAILS}
|
||||
class="modal modal-bottom sm:modal-middle"
|
||||
>
|
||||
<div class="modal-box">
|
||||
|
81
src/components/LogsSettingsModal.tsx
Normal file
81
src/components/LogsSettingsModal.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import { useI18n } from '@solid-primitives/i18n'
|
||||
import { For } from 'solid-js'
|
||||
import { ConfigTitle } from '~/components'
|
||||
import {
|
||||
LOG_LEVEL,
|
||||
LOGS_TABLE_MAX_ROWS_LIST,
|
||||
MODAL,
|
||||
TAILWINDCSS_SIZE,
|
||||
} from '~/constants'
|
||||
import {
|
||||
logMaxRows,
|
||||
logsTableSize,
|
||||
setLogLevel,
|
||||
setLogMaxRows,
|
||||
setLogsTableSize,
|
||||
} from '~/signals'
|
||||
|
||||
export const LogsSettingsModal = () => {
|
||||
const [t] = useI18n()
|
||||
|
||||
return (
|
||||
<dialog id={MODAL.LOGS_SETTINGS} class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box flex flex-col gap-4">
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('tableSize')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full"
|
||||
value={logsTableSize()}
|
||||
onChange={(e) =>
|
||||
setLogsTableSize(e.target.value as TAILWINDCSS_SIZE)
|
||||
}
|
||||
>
|
||||
<For each={Object.values(TAILWINDCSS_SIZE)}>
|
||||
{(value) => <option value={value}>{t(value)}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('logLevel')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full"
|
||||
onChange={(e) => setLogLevel(e.target.value as LOG_LEVEL)}
|
||||
>
|
||||
<For
|
||||
each={[
|
||||
LOG_LEVEL.Info,
|
||||
LOG_LEVEL.Error,
|
||||
LOG_LEVEL.Warning,
|
||||
LOG_LEVEL.Debug,
|
||||
LOG_LEVEL.Silent,
|
||||
]}
|
||||
>
|
||||
{(level) => <option value={level}>{t(level)}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('logMaxRows')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full"
|
||||
value={logMaxRows()}
|
||||
onChange={(e) => setLogMaxRows(parseInt(e.target.value))}
|
||||
>
|
||||
<For each={LOGS_TABLE_MAX_ROWS_LIST}>
|
||||
{(rows) => <option value={rows}>{rows}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button />
|
||||
</form>
|
||||
</dialog>
|
||||
)
|
||||
}
|
107
src/components/ProxiesSettingsModal.tsx
Normal file
107
src/components/ProxiesSettingsModal.tsx
Normal file
@ -0,0 +1,107 @@
|
||||
import { useI18n } from '@solid-primitives/i18n'
|
||||
import { For } from 'solid-js'
|
||||
import { ConfigTitle } from '~/components'
|
||||
import { MODAL, PROXIES_ORDERING_TYPE, PROXIES_PREVIEW_TYPE } from '~/constants'
|
||||
import {
|
||||
autoCloseConns,
|
||||
latencyTestTimeoutDuration,
|
||||
proxiesOrderingType,
|
||||
proxiesPreviewType,
|
||||
setAutoCloseConns,
|
||||
setLatencyTestTimeoutDuration,
|
||||
setProxiesOrderingType,
|
||||
setProxiesPreviewType,
|
||||
setUrlForLatencyTest,
|
||||
urlForLatencyTest,
|
||||
} from '~/signals'
|
||||
|
||||
export const ProxiesSettingsModal = () => {
|
||||
const [t] = useI18n()
|
||||
|
||||
return (
|
||||
<dialog
|
||||
id={MODAL.PROXIES_SETTINGS}
|
||||
class="modal modal-bottom sm:modal-middle"
|
||||
>
|
||||
<div class="modal-box flex flex-col gap-4">
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('autoCloseConns')}</ConfigTitle>
|
||||
|
||||
<div class="flex w-full justify-center">
|
||||
<input
|
||||
class="toggle"
|
||||
type="checkbox"
|
||||
checked={autoCloseConns()}
|
||||
onChange={(e) => setAutoCloseConns(e.target.checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<ConfigTitle withDivider>{t('urlForLatencyTest')}</ConfigTitle>
|
||||
|
||||
<input
|
||||
class="input input-bordered w-full"
|
||||
value={urlForLatencyTest()}
|
||||
onChange={(e) => setUrlForLatencyTest(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle withDivider>
|
||||
{t('latencyTestTimeoutDuration')} ({t('ms')})
|
||||
</ConfigTitle>
|
||||
|
||||
<input
|
||||
type="number"
|
||||
class="input input-bordered w-full"
|
||||
value={latencyTestTimeoutDuration()}
|
||||
onChange={(e) =>
|
||||
setLatencyTestTimeoutDuration(Number(e.target.value))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('proxiesSorting')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full"
|
||||
value={proxiesOrderingType()}
|
||||
onChange={(e) =>
|
||||
setProxiesOrderingType(e.target.value as PROXIES_ORDERING_TYPE)
|
||||
}
|
||||
>
|
||||
<For each={Object.values(PROXIES_ORDERING_TYPE)}>
|
||||
{(value) => (
|
||||
<option class="flex items-center gap-2" value={value}>
|
||||
{t(value)}
|
||||
</option>
|
||||
)}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle withDivider>{t('proxiesPreviewType')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full"
|
||||
value={proxiesPreviewType()}
|
||||
onChange={(e) =>
|
||||
setProxiesPreviewType(e.target.value as PROXIES_PREVIEW_TYPE)
|
||||
}
|
||||
>
|
||||
<For each={Object.values(PROXIES_PREVIEW_TYPE)}>
|
||||
{(value) => <option value={value}>{t(value)}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button />
|
||||
</form>
|
||||
</dialog>
|
||||
)
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
export * from './Button'
|
||||
export * from './Collapse'
|
||||
export * from './ConfigTitle'
|
||||
export * from './ConnectionsSettingsModal'
|
||||
export * from './ConnectionsTableDetailsModal'
|
||||
export * from './ConnectionsTableOrderingModal'
|
||||
export * from './ForTwoColumns'
|
||||
export * from './Header'
|
||||
export * from './Latency'
|
||||
export * from './LogoText'
|
||||
export * from './LogsSettingsModal'
|
||||
export * from './ProxiesSettingsModal'
|
||||
export * from './ProxyCardGroups'
|
||||
export * from './ProxyNodeCard'
|
||||
export * from './ProxyNodePreview'
|
||||
|
@ -163,3 +163,11 @@ export enum LOG_LEVEL {
|
||||
}
|
||||
|
||||
export const LOGS_TABLE_MAX_ROWS_LIST = [200, 300, 500, 800, 1000]
|
||||
|
||||
export enum MODAL {
|
||||
PROXIES_SETTINGS = 'proxies-settings',
|
||||
RULES_SETTINGS = 'rules-settings',
|
||||
CONNECTIONS_SETTINGS = 'connections-settings',
|
||||
CONNECTIONS_TABLE_DETAILS = 'connections-table-details',
|
||||
LOGS_SETTINGS = 'logs-settings',
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ export default {
|
||||
orderName_desc: 'By name alphabetically (Z-A)',
|
||||
ms: 'ms',
|
||||
updated: 'Updated',
|
||||
renderProxiesInSamePage: 'Render proxies and proxy provider in same page',
|
||||
tableSize: 'Table size',
|
||||
logLevel: 'Log Level',
|
||||
info: 'info',
|
||||
@ -67,7 +66,7 @@ export default {
|
||||
debug: 'debug',
|
||||
warning: 'warning',
|
||||
error: 'error',
|
||||
logMaxRows: 'Log Maxinum Reserved Rows',
|
||||
logMaxRows: 'Log Maximum Reserved Rows',
|
||||
xs: 'Extra small size',
|
||||
sm: 'Small size',
|
||||
md: 'Normal size',
|
||||
@ -86,4 +85,5 @@ export default {
|
||||
direct: 'Direct',
|
||||
active: 'Active',
|
||||
closed: 'Closed',
|
||||
sort: 'Sort',
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ export default {
|
||||
orderName_desc: '按名称字母排序 (Z-A)',
|
||||
ms: '毫秒',
|
||||
updated: '更新于',
|
||||
renderProxiesInSamePage: '将代理和代理提供者显示在同一页',
|
||||
tableSize: '表格大小',
|
||||
logLevel: '日志等级',
|
||||
info: '信息',
|
||||
@ -86,4 +85,5 @@ export default {
|
||||
direct: '直连',
|
||||
active: '活动',
|
||||
closed: '已关闭',
|
||||
sort: '排序',
|
||||
}
|
||||
|
@ -2,14 +2,7 @@ import { createForm } from '@felte/solid'
|
||||
import { validator } from '@felte/validator-zod'
|
||||
import { useI18n } from '@solid-primitives/i18n'
|
||||
import { useNavigate } from '@solidjs/router'
|
||||
import {
|
||||
For,
|
||||
ParentComponent,
|
||||
Show,
|
||||
children,
|
||||
createSignal,
|
||||
onMount,
|
||||
} from 'solid-js'
|
||||
import { For, Show, createSignal, onMount } from 'solid-js'
|
||||
import { z } from 'zod'
|
||||
import {
|
||||
fetchBackendConfigAPI,
|
||||
@ -22,47 +15,21 @@ import {
|
||||
upgradeBackendAPI,
|
||||
upgradingBackend,
|
||||
} from '~/apis'
|
||||
import { Button } from '~/components'
|
||||
import { Button, ConfigTitle } from '~/components'
|
||||
import { LANG, MODE_OPTIONS, ROUTES, themes } from '~/constants'
|
||||
import {
|
||||
LANG,
|
||||
LOGS_TABLE_MAX_ROWS_LIST,
|
||||
LOG_LEVEL,
|
||||
MODE_OPTIONS,
|
||||
PROXIES_ORDERING_TYPE,
|
||||
PROXIES_PREVIEW_TYPE,
|
||||
ROUTES,
|
||||
TAILWINDCSS_SIZE,
|
||||
themes,
|
||||
} from '~/constants'
|
||||
import {
|
||||
autoCloseConns,
|
||||
autoSwitchTheme,
|
||||
backendConfig,
|
||||
favDayTheme,
|
||||
favNightTheme,
|
||||
latencyTestTimeoutDuration,
|
||||
logLevel,
|
||||
logMaxRows,
|
||||
proxiesOrderingType,
|
||||
proxiesPreviewType,
|
||||
renderInTwoColumns,
|
||||
setAutoCloseConns,
|
||||
setAutoSwitchTheme,
|
||||
setBackendConfig,
|
||||
setFavDayTheme,
|
||||
setFavNightTheme,
|
||||
setLatencyTestTimeoutDuration,
|
||||
setLogLevel,
|
||||
setLogMaxRows,
|
||||
setProxiesOrderingType,
|
||||
setProxiesPreviewType,
|
||||
setRenderInTwoColumns,
|
||||
setSelectedEndpoint,
|
||||
setTableSize,
|
||||
setTwemoji,
|
||||
setUrlForLatencyTest,
|
||||
tableSize,
|
||||
urlForLatencyTest,
|
||||
useRequest,
|
||||
useTwemoji,
|
||||
} from '~/signals'
|
||||
@ -73,12 +40,6 @@ const dnsQueryFormSchema = z.object({
|
||||
type: z.string(),
|
||||
})
|
||||
|
||||
const ConfigTitle: ParentComponent = (props) => (
|
||||
<div class="pb-4 text-lg font-semibold">
|
||||
{children(() => props.children)()}
|
||||
</div>
|
||||
)
|
||||
|
||||
const DNSQueryForm = () => {
|
||||
const [t] = useI18n()
|
||||
const request = useRequest()
|
||||
@ -147,7 +108,7 @@ const ConfigForm = () => {
|
||||
|
||||
const portsList = [
|
||||
{
|
||||
label: 'Http Port',
|
||||
label: 'HTTP Port',
|
||||
key: 'port',
|
||||
},
|
||||
{
|
||||
@ -159,7 +120,7 @@ const ConfigForm = () => {
|
||||
key: 'redir-port',
|
||||
},
|
||||
{
|
||||
label: 'Tproxy Port',
|
||||
label: 'TProxy Port',
|
||||
key: 'tproxy-port',
|
||||
},
|
||||
{
|
||||
@ -226,42 +187,6 @@ const ConfigForm = () => {
|
||||
{t('restartCore')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<ConfigTitle>{t('urlForLatencyTest')}</ConfigTitle>
|
||||
|
||||
<input
|
||||
class="input input-bordered max-w-md"
|
||||
value={urlForLatencyTest()}
|
||||
onChange={(e) => setUrlForLatencyTest(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle>
|
||||
{t('latencyTestTimeoutDuration')} ({t('ms')})
|
||||
</ConfigTitle>
|
||||
|
||||
<input
|
||||
type="number"
|
||||
class="input input-bordered w-full max-w-md"
|
||||
value={latencyTestTimeoutDuration()}
|
||||
onChange={(e) =>
|
||||
setLatencyTestTimeoutDuration(Number(e.target.value))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle>{t('autoCloseConns')}</ConfigTitle>
|
||||
|
||||
<input
|
||||
class="toggle"
|
||||
type="checkbox"
|
||||
checked={autoCloseConns()}
|
||||
onChange={(e) => setAutoCloseConns(e.target.checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -355,97 +280,6 @@ const ConfigForXd = () => {
|
||||
)}
|
||||
</For>
|
||||
|
||||
<div>
|
||||
<ConfigTitle>{t('proxiesPreviewType')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
value={proxiesPreviewType()}
|
||||
onChange={(e) =>
|
||||
setProxiesPreviewType(e.target.value as PROXIES_PREVIEW_TYPE)
|
||||
}
|
||||
>
|
||||
<For each={Object.values(PROXIES_PREVIEW_TYPE)}>
|
||||
{(value) => <option value={value}>{t(value)}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle>{t('proxiesSorting')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
value={proxiesOrderingType()}
|
||||
onChange={(e) =>
|
||||
setProxiesOrderingType(e.target.value as PROXIES_ORDERING_TYPE)
|
||||
}
|
||||
>
|
||||
<For each={Object.values(PROXIES_ORDERING_TYPE)}>
|
||||
{(value) => (
|
||||
<option class="flex items-center gap-2" value={value}>
|
||||
{t(value)}
|
||||
</option>
|
||||
)}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle>{t('tableSize')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
value={tableSize()}
|
||||
onChange={(e) => setTableSize(e.target.value as TAILWINDCSS_SIZE)}
|
||||
>
|
||||
<For each={Object.values(TAILWINDCSS_SIZE)}>
|
||||
{(value) => <option value={value}>{t(value)}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle>{t('logLevel')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
onChange={(e) => {
|
||||
setLogLevel(e.target.value as LOG_LEVEL)
|
||||
}}
|
||||
>
|
||||
<For
|
||||
each={[
|
||||
LOG_LEVEL.Info,
|
||||
LOG_LEVEL.Error,
|
||||
LOG_LEVEL.Warning,
|
||||
LOG_LEVEL.Debug,
|
||||
LOG_LEVEL.Silent,
|
||||
]}
|
||||
>
|
||||
{(level) => (
|
||||
<option selected={logLevel() === level} value={level}>
|
||||
{t(level)}
|
||||
</option>
|
||||
)}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ConfigTitle>{t('logMaxRows')}</ConfigTitle>
|
||||
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
value={logMaxRows()}
|
||||
onChange={(e) => setLogMaxRows(parseInt(e.target.value))}
|
||||
>
|
||||
<For each={LOGS_TABLE_MAX_ROWS_LIST}>
|
||||
{(rows) => <option value={rows}>{rows}</option>}
|
||||
</For>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Button
|
||||
onClick={() => {
|
||||
|
@ -33,16 +33,21 @@ import { twMerge } from 'tailwind-merge'
|
||||
import { closeAllConnectionsAPI, closeSingleConnectionAPI } from '~/apis'
|
||||
import {
|
||||
Button,
|
||||
ConnectionsSettingsModal,
|
||||
ConnectionsTableDetailsModal,
|
||||
ConnectionsTableOrderingModal,
|
||||
} from '~/components'
|
||||
import {
|
||||
CONNECTIONS_TABLE_ACCESSOR_KEY,
|
||||
CONNECTIONS_TABLE_INITIAL_COLUMN_ORDER,
|
||||
CONNECTIONS_TABLE_INITIAL_COLUMN_VISIBILITY,
|
||||
MODAL,
|
||||
} from '~/constants'
|
||||
import { formatTimeFromNow } from '~/helpers'
|
||||
import { tableSize, tableSizeClassName, useConnections } from '~/signals'
|
||||
import {
|
||||
connectionsTableSize,
|
||||
tableSizeClassName,
|
||||
useConnections,
|
||||
} from '~/signals'
|
||||
import type { Connection } from '~/types'
|
||||
|
||||
type ColumnVisibility = Partial<Record<CONNECTIONS_TABLE_ACCESSOR_KEY, boolean>>
|
||||
@ -107,7 +112,7 @@ export default () => {
|
||||
setSelectedConnectionID(row.original.id)
|
||||
|
||||
const modal = document.querySelector(
|
||||
'#connections-table-details-modal',
|
||||
`#${MODAL.CONNECTIONS_TABLE_DETAILS}`,
|
||||
) as HTMLDialogElement | null
|
||||
|
||||
modal?.showModal()
|
||||
@ -357,7 +362,7 @@ export default () => {
|
||||
class="btn join-item btn-sm sm:btn-md"
|
||||
onClick={() => {
|
||||
const modal = document.querySelector(
|
||||
'#connections-table-ordering-modal',
|
||||
`#${MODAL.CONNECTIONS_SETTINGS}`,
|
||||
) as HTMLDialogElement | null
|
||||
|
||||
modal?.showModal()
|
||||
@ -371,7 +376,7 @@ export default () => {
|
||||
<div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300">
|
||||
<table
|
||||
class={twMerge(
|
||||
tableSizeClassName(tableSize()),
|
||||
tableSizeClassName(connectionsTableSize()),
|
||||
'table table-zebra relative rounded-none',
|
||||
)}
|
||||
>
|
||||
@ -488,7 +493,7 @@ export default () => {
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<ConnectionsTableOrderingModal
|
||||
<ConnectionsSettingsModal
|
||||
order={columnOrder()}
|
||||
visible={columnVisibility()}
|
||||
onOrderChange={(data: ColumnOrder) => setColumnOrder(data)}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { useI18n } from '@solid-primitives/i18n'
|
||||
import { IconSettings } from '@tabler/icons-solidjs'
|
||||
import {
|
||||
ColumnDef,
|
||||
createSolidTable,
|
||||
@ -7,8 +8,9 @@ import {
|
||||
} from '@tanstack/solid-table'
|
||||
import { For, Index, createEffect, createSignal } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { LOG_LEVEL } from '~/constants'
|
||||
import { tableSize, tableSizeClassName, useWsRequest } from '~/signals'
|
||||
import { Button, LogsSettingsModal } from '~/components'
|
||||
import { LOG_LEVEL, MODAL } from '~/constants'
|
||||
import { logsTableSize, tableSizeClassName, useWsRequest } from '~/signals'
|
||||
import { logLevel, logMaxRows } from '~/signals/config'
|
||||
import { Log } from '~/types'
|
||||
|
||||
@ -85,17 +87,32 @@ export default () => {
|
||||
|
||||
return (
|
||||
<div class="flex h-full flex-col gap-4 p-1">
|
||||
<input
|
||||
type="search"
|
||||
class="input input-primary input-sm flex-shrink-0 sm:input-md"
|
||||
placeholder={t('search')}
|
||||
onInput={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
<div class="join w-full">
|
||||
<input
|
||||
type="search"
|
||||
class="input join-item input-primary input-sm flex-1 flex-shrink-0 sm:input-md"
|
||||
placeholder={t('search')}
|
||||
onInput={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
|
||||
<Button
|
||||
class="join-item btn-sm sm:btn-md"
|
||||
onClick={() => {
|
||||
const modal = document.querySelector(
|
||||
`#${MODAL.LOGS_SETTINGS}`,
|
||||
) as HTMLDialogElement | null
|
||||
|
||||
modal?.showModal()
|
||||
}}
|
||||
>
|
||||
<IconSettings />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300">
|
||||
<table
|
||||
class={twMerge(
|
||||
tableSizeClassName(tableSize()),
|
||||
tableSizeClassName(logsTableSize()),
|
||||
'table relative rounded-none',
|
||||
)}
|
||||
>
|
||||
@ -150,6 +167,8 @@ export default () => {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<LogsSettingsModal />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,15 +1,21 @@
|
||||
import { useI18n } from '@solid-primitives/i18n'
|
||||
import { IconBrandSpeedtest, IconReload } from '@tabler/icons-solidjs'
|
||||
import {
|
||||
IconBrandSpeedtest,
|
||||
IconReload,
|
||||
IconSettings,
|
||||
} from '@tabler/icons-solidjs'
|
||||
import { For, Show, createSignal } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import {
|
||||
Button,
|
||||
Collapse,
|
||||
ForTwoColumns,
|
||||
ProxiesSettingsModal,
|
||||
ProxyCardGroups,
|
||||
ProxyNodePreview,
|
||||
SubscriptionInfo,
|
||||
} from '~/components'
|
||||
import { MODAL } from '~/constants'
|
||||
import {
|
||||
formatTimeFromNow,
|
||||
sortProxiesByOrderingType,
|
||||
@ -123,6 +129,21 @@ export default () => {
|
||||
/>
|
||||
</Button>
|
||||
</Show>
|
||||
|
||||
<div class="ml-auto">
|
||||
<Button
|
||||
class="btn-circle btn-sm sm:btn-md"
|
||||
onClick={() => {
|
||||
const modal = document.querySelector(
|
||||
`#${MODAL.PROXIES_SETTINGS}`,
|
||||
) as HTMLDialogElement | null
|
||||
|
||||
modal?.showModal()
|
||||
}}
|
||||
>
|
||||
<IconSettings />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
@ -274,6 +295,8 @@ export default () => {
|
||||
/>
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<ProxiesSettingsModal />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -48,9 +48,13 @@ export const [renderInTwoColumns, setRenderInTwoColumns] = makePersisted(
|
||||
createSignal(true),
|
||||
{ name: 'renderInTwoColumn', storage: localStorage },
|
||||
)
|
||||
export const [tableSize, setTableSize] = makePersisted(
|
||||
export const [connectionsTableSize, setConnectionsTableSize] = makePersisted(
|
||||
createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS),
|
||||
{ name: 'tableSize', storage: localStorage },
|
||||
{ name: 'connectionsTableSize', storage: localStorage },
|
||||
)
|
||||
export const [logsTableSize, setLogsTableSize] = makePersisted(
|
||||
createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS),
|
||||
{ name: 'logsTableSize', storage: localStorage },
|
||||
)
|
||||
|
||||
export const [logLevel, setLogLevel] = makePersisted(
|
||||
|
Loading…
x
Reference in New Issue
Block a user