mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-10 05:15:35 +08:00
feat(rule): implement virtual scroll on rules and rule providers, fixes #285
This commit is contained in:
parent
f8bf02e9c7
commit
7145cec62f
@ -32,7 +32,8 @@
|
||||
"@tabler/icons-solidjs": "^2.35.0",
|
||||
"@tanstack/match-sorter-utils": "^8.8.4",
|
||||
"@tanstack/solid-table": "^8.10.3",
|
||||
"@tanstack/solid-virtual": "3.0.0-beta.6",
|
||||
"@tanstack/solid-virtual": "3.0.0-beta.60",
|
||||
"@tanstack/virtual-core": "3.0.0-beta.60",
|
||||
"@thisbeyond/solid-dnd": "^0.7.4",
|
||||
"@types/byte-size": "^8.1.0",
|
||||
"@types/lodash": "^4.14.199",
|
||||
|
@ -60,8 +60,11 @@ dependencies:
|
||||
specifier: ^8.10.3
|
||||
version: 8.10.3(solid-js@1.7.12)
|
||||
'@tanstack/solid-virtual':
|
||||
specifier: 3.0.0-beta.6
|
||||
version: 3.0.0-beta.6
|
||||
specifier: 3.0.0-beta.60
|
||||
version: 3.0.0-beta.60(solid-js@1.7.12)
|
||||
'@tanstack/virtual-core':
|
||||
specifier: 3.0.0-beta.60
|
||||
version: 3.0.0-beta.60
|
||||
'@thisbeyond/solid-dnd':
|
||||
specifier: ^0.7.4
|
||||
version: 0.7.4(solid-js@1.7.12)
|
||||
@ -1968,10 +1971,6 @@ packages:
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/@reach/observe-rect@1.2.0:
|
||||
resolution: {integrity: sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==}
|
||||
dev: false
|
||||
|
||||
/@rollup/plugin-babel@5.3.1(@babel/core@7.22.20)(rollup@2.79.1):
|
||||
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
@ -2194,11 +2193,13 @@ packages:
|
||||
solid-js: 1.7.12
|
||||
dev: false
|
||||
|
||||
/@tanstack/solid-virtual@3.0.0-beta.6:
|
||||
resolution: {integrity: sha512-/HjeHZb4UZxxFSAkICUEWOozGwHQpKlvtnUoS5uSMSuLOz0XM5vFq6zR6ENwAczKWDtkh8ntddk+zXAhyXOlEw==}
|
||||
engines: {node: '>=12'}
|
||||
/@tanstack/solid-virtual@3.0.0-beta.60(solid-js@1.7.12):
|
||||
resolution: {integrity: sha512-SN007vDq1AeRq5w2rK0E47CeI8rv+oPZ5IjtOgLynt1MKNUsSsJ7d+igK2jUPQ24QrZf5NLrN4FRQRdxvakvIg==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.3.0
|
||||
dependencies:
|
||||
'@reach/observe-rect': 1.2.0
|
||||
'@tanstack/virtual-core': 3.0.0-beta.60
|
||||
solid-js: 1.7.12
|
||||
dev: false
|
||||
|
||||
/@tanstack/table-core@8.10.3:
|
||||
@ -2206,6 +2207,10 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/@tanstack/virtual-core@3.0.0-beta.60:
|
||||
resolution: {integrity: sha512-QlCdhsV1+JIf0c0U6ge6SQmpwsyAT0oQaOSZk50AtEeAyQl9tQrd6qCHAslxQpgphrfe945abvKG8uYvw3hIGA==}
|
||||
dev: false
|
||||
|
||||
/@thisbeyond/solid-dnd@0.7.4(solid-js@1.7.12):
|
||||
resolution: {integrity: sha512-jgV9EtR3gAtVsILG8p1OAGrhHIgnK4W04YxpyLgJRCDKEFYQWuDrMdUe8F5Kc6pcVXlC4IMXr4cB8fS2Ut3/Ow==}
|
||||
peerDependencies:
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { IconReload } from '@tabler/icons-solidjs'
|
||||
import { createVirtualizer } from '@tanstack/solid-virtual'
|
||||
import { For, Show, createSignal, onMount } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { Button } from '~/components'
|
||||
@ -56,6 +57,30 @@ export default () => {
|
||||
},
|
||||
]
|
||||
|
||||
let parentRef: HTMLDivElement | undefined
|
||||
|
||||
const ruleVirtualizer = createVirtualizer({
|
||||
get count() {
|
||||
return rules().length
|
||||
},
|
||||
getScrollElement: () => parentRef!,
|
||||
estimateSize: () => 74,
|
||||
overscan: 5,
|
||||
})
|
||||
|
||||
const ruleVirtualizerItems = ruleVirtualizer.getVirtualItems()
|
||||
|
||||
const ruleProviderVirtualizer = createVirtualizer({
|
||||
get count() {
|
||||
return ruleProviders().length
|
||||
},
|
||||
getScrollElement: () => parentRef!,
|
||||
estimateSize: () => 74,
|
||||
overscan: 5,
|
||||
})
|
||||
|
||||
const ruleProviderVirtualizerItems = ruleProviderVirtualizer.getVirtualItems()
|
||||
|
||||
return (
|
||||
<div class="flex h-full flex-col gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
@ -92,60 +117,91 @@ export default () => {
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<div ref={(ref) => (parentRef = ref)} class="flex-1 overflow-y-auto">
|
||||
<Show when={activeTab() === ActiveTab.rules}>
|
||||
<div class="grid gap-2">
|
||||
<For each={rules()}>
|
||||
{(rule) => (
|
||||
<div class="card card-bordered card-compact bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="break-all">{rule.payload}</span>
|
||||
<Show
|
||||
when={typeof rule.size === 'number' && rule.size !== -1}
|
||||
>
|
||||
<div class="badge badge-sm">{rule.size}</div>
|
||||
</Show>
|
||||
</div>
|
||||
<div class="text-xs text-slate-500">
|
||||
{rule.type} :: {rule.proxy}
|
||||
<div
|
||||
class="relative"
|
||||
style={{ height: `${ruleVirtualizer.getTotalSize()}px` }}
|
||||
>
|
||||
{ruleVirtualizerItems.map((virtualizerItem) => {
|
||||
const rule = rules()[virtualizerItem.index]
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={(el) =>
|
||||
onMount(() => ruleVirtualizer.measureElement(el))
|
||||
}
|
||||
data-index={virtualizerItem.index}
|
||||
class="absolute inset-x-0 top-0 pb-2 last:pb-0"
|
||||
style={{
|
||||
transform: `translateY(${virtualizerItem.start}px)`,
|
||||
}}
|
||||
>
|
||||
<div class="card card-bordered card-compact bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="break-all">{rule.payload}</span>
|
||||
|
||||
<Show when={rule.size !== -1}>
|
||||
<div class="badge badge-sm">{rule.size}</div>
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<div class="text-xs text-slate-500">
|
||||
{rule.type} :: {rule.proxy}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={activeTab() === ActiveTab.ruleProviders}>
|
||||
<div class="grid gap-2">
|
||||
<For each={ruleProviders()}>
|
||||
{(ruleProvider) => (
|
||||
<div class="card card-bordered card-compact bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2 pr-8">
|
||||
<span class="break-all">{ruleProvider.name}</span>
|
||||
<div class="badge badge-sm">{ruleProvider.ruleCount}</div>
|
||||
</div>
|
||||
<div class="relative">
|
||||
{ruleProviderVirtualizerItems.map((virtualizerItem) => {
|
||||
const ruleProvider = ruleProviders()[virtualizerItem.index]
|
||||
|
||||
<div class="text-xs text-slate-500">
|
||||
{ruleProvider.vehicleType} / {ruleProvider.behavior} /
|
||||
{t('updated')} {formatTimeFromNow(ruleProvider.updatedAt)}
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
ref={(el) =>
|
||||
onMount(() => ruleProviderVirtualizer.measureElement(el))
|
||||
}
|
||||
data-index={virtualizerItem.index}
|
||||
class="absolute inset-x-0 top-0 pb-2 last:pb-0"
|
||||
style={{
|
||||
transform: `translateY(${virtualizerItem.start}px)`,
|
||||
}}
|
||||
>
|
||||
<div class="card card-bordered card-compact bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2 pr-8">
|
||||
<span class="break-all">{ruleProvider.name}</span>
|
||||
<div class="badge badge-sm">{ruleProvider.ruleCount}</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
class="btn-circle btn-sm absolute right-2 top-2 mr-2 h-4"
|
||||
disabled={updatingMap()[ruleProvider.name]}
|
||||
onClick={(e) => onUpdateProviderClick(e, ruleProvider.name)}
|
||||
icon={
|
||||
<IconReload
|
||||
class={twMerge(
|
||||
updatingMap()[ruleProvider.name] &&
|
||||
'animate-spin text-success',
|
||||
)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<div class="text-xs text-slate-500">
|
||||
{ruleProvider.vehicleType} / {ruleProvider.behavior} /
|
||||
{t('updated')} {formatTimeFromNow(ruleProvider.updatedAt)}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
class="btn-circle btn-sm absolute right-2 top-2 mr-2 h-4"
|
||||
disabled={updatingMap()[ruleProvider.name]}
|
||||
onClick={(e) =>
|
||||
onUpdateProviderClick(e, ruleProvider.name)
|
||||
}
|
||||
icon={
|
||||
<IconReload
|
||||
class={twMerge(
|
||||
updatingMap()[ruleProvider.name] &&
|
||||
'animate-spin text-success',
|
||||
)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user