mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-10 05:15:35 +08:00
feat: sortable column
This commit is contained in:
parent
be35f499ae
commit
4c4011a617
@ -21,6 +21,7 @@
|
|||||||
"@tabler/icons-solidjs": "^2.32.0",
|
"@tabler/icons-solidjs": "^2.32.0",
|
||||||
"@tanstack/solid-table": "^8.9.3",
|
"@tanstack/solid-table": "^8.9.3",
|
||||||
"@tanstack/solid-virtual": "3.0.0-beta.6",
|
"@tanstack/solid-virtual": "3.0.0-beta.6",
|
||||||
|
"@thisbeyond/solid-dnd": "^0.7.4",
|
||||||
"@types/byte-size": "^8.1.0",
|
"@types/byte-size": "^8.1.0",
|
||||||
"@types/node": "^20.5.7",
|
"@types/node": "^20.5.7",
|
||||||
"@types/uuid": "^9.0.3",
|
"@types/uuid": "^9.0.3",
|
||||||
|
@ -35,6 +35,9 @@ dependencies:
|
|||||||
'@tanstack/solid-virtual':
|
'@tanstack/solid-virtual':
|
||||||
specifier: 3.0.0-beta.6
|
specifier: 3.0.0-beta.6
|
||||||
version: 3.0.0-beta.6
|
version: 3.0.0-beta.6
|
||||||
|
'@thisbeyond/solid-dnd':
|
||||||
|
specifier: ^0.7.4
|
||||||
|
version: 0.7.4(solid-js@1.7.11)
|
||||||
'@types/byte-size':
|
'@types/byte-size':
|
||||||
specifier: ^8.1.0
|
specifier: ^8.1.0
|
||||||
version: 8.1.0
|
version: 8.1.0
|
||||||
@ -1296,6 +1299,17 @@ packages:
|
|||||||
engines: { node: '>=12' }
|
engines: { node: '>=12' }
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@thisbeyond/solid-dnd@0.7.4(solid-js@1.7.11):
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-jgV9EtR3gAtVsILG8p1OAGrhHIgnK4W04YxpyLgJRCDKEFYQWuDrMdUe8F5Kc6pcVXlC4IMXr4cB8fS2Ut3/Ow==,
|
||||||
|
}
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.5
|
||||||
|
dependencies:
|
||||||
|
solid-js: 1.7.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@tsconfig/node10@1.0.9:
|
/@tsconfig/node10@1.0.9:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
@ -1,41 +1,105 @@
|
|||||||
import { For } from 'solid-js'
|
import type {
|
||||||
|
DragEventHandler,
|
||||||
|
Draggable,
|
||||||
|
Droppable,
|
||||||
|
} from '@thisbeyond/solid-dnd'
|
||||||
|
import {
|
||||||
|
DragDropProvider,
|
||||||
|
DragDropSensors,
|
||||||
|
DragOverlay,
|
||||||
|
SortableProvider,
|
||||||
|
closestCenter,
|
||||||
|
createSortable,
|
||||||
|
useDragDropContext,
|
||||||
|
} from '@thisbeyond/solid-dnd'
|
||||||
|
import { For, createSignal } from 'solid-js'
|
||||||
import { AccessorKey } from '~/config/connection'
|
import { AccessorKey } from '~/config/connection'
|
||||||
|
|
||||||
type ColumnVisibility = Partial<Record<AccessorKey, boolean>>
|
type ColumnVisibility = Partial<Record<AccessorKey, boolean>>
|
||||||
|
type ColumnOrder = AccessorKey[]
|
||||||
|
|
||||||
export default (props: {
|
export default (props: {
|
||||||
data: ColumnVisibility
|
order: ColumnOrder
|
||||||
onChange: (value: ColumnVisibility) => void
|
visible: ColumnVisibility
|
||||||
|
onOrderChange: (value: ColumnOrder) => void
|
||||||
|
onVisibleChange: (value: ColumnVisibility) => void
|
||||||
}) => {
|
}) => {
|
||||||
const { onChange } = props
|
const [activeKey, setActiveKey] = createSignal<AccessorKey | null>(null)
|
||||||
|
const onDragStart = ({ draggable }: { draggable: Draggable }) =>
|
||||||
|
setActiveKey(draggable.id as AccessorKey)
|
||||||
|
const onDragEnd = ({
|
||||||
|
draggable,
|
||||||
|
droppable,
|
||||||
|
}: {
|
||||||
|
draggable: Draggable
|
||||||
|
droppable: Droppable
|
||||||
|
}) => {
|
||||||
|
if (draggable && droppable) {
|
||||||
|
const currentItems = props.order
|
||||||
|
const fromIndex = currentItems.indexOf(draggable.id as AccessorKey)
|
||||||
|
const toIndex = currentItems.indexOf(droppable.id as AccessorKey)
|
||||||
|
|
||||||
|
if (fromIndex !== toIndex) {
|
||||||
|
const updatedItems = currentItems.slice()
|
||||||
|
|
||||||
|
updatedItems.splice(toIndex, 0, ...updatedItems.splice(fromIndex, 1))
|
||||||
|
props.onOrderChange(updatedItems)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormRow = (p: { key: AccessorKey }) => {
|
||||||
|
const key = p.key
|
||||||
|
const sortable = createSortable(key)
|
||||||
|
const [state] = useDragDropContext()!
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
use:sortable
|
||||||
|
class="sortable"
|
||||||
|
classList={{
|
||||||
|
'opacity-25': sortable.isActiveDraggable,
|
||||||
|
'transition-transform': !!state.active.draggable,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="m-1 flex cursor-pointer justify-between p-1">
|
||||||
|
<span class="select-none">{key}</span>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="toggle"
|
||||||
|
checked={props.visible[key]}
|
||||||
|
onChange={(e) => {
|
||||||
|
props.onVisibleChange({
|
||||||
|
...props.visible,
|
||||||
|
[key]: e.target.checked,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<input type="checkbox" id="connection-modal" class="modal-toggle" />
|
<input type="checkbox" id="connection-modal" class="modal-toggle" />
|
||||||
<div class="modal">
|
<div class="modal">
|
||||||
<div class="modal-box w-80">
|
<div class="modal-box w-80">
|
||||||
<For
|
<DragDropProvider
|
||||||
each={Object.values(AccessorKey).filter(
|
onDragStart={onDragStart}
|
||||||
(i) => ![AccessorKey.Close, AccessorKey.ID].includes(i),
|
onDragEnd={onDragEnd as DragEventHandler}
|
||||||
)}
|
collisionDetector={closestCenter}
|
||||||
>
|
>
|
||||||
{(key) => (
|
<DragDropSensors />
|
||||||
<div class="m-1 flex justify-between p-1">
|
<div class="column self-stretch">
|
||||||
{key}
|
<SortableProvider ids={props.order}>
|
||||||
<input
|
<For each={props.order}>{(key) => <FormRow key={key} />}</For>
|
||||||
type="checkbox"
|
</SortableProvider>
|
||||||
class="toggle"
|
</div>
|
||||||
checked={props.data[key]}
|
<DragOverlay>
|
||||||
onChange={(e) => {
|
<div class="sortable">{activeKey()}</div>
|
||||||
onChange({
|
</DragOverlay>
|
||||||
...props.data,
|
</DragDropProvider>
|
||||||
[key]: e.target.checked,
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</div>
|
</div>
|
||||||
<label class="modal-backdrop" htmlFor="connection-modal">
|
<label class="modal-backdrop" htmlFor="connection-modal">
|
||||||
Close
|
Close
|
||||||
|
@ -30,9 +30,11 @@ type ConnectionWithSpeed = Connection & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ColumnVisibility = Partial<Record<AccessorKey, boolean>>
|
type ColumnVisibility = Partial<Record<AccessorKey, boolean>>
|
||||||
|
type ColumnOrder = AccessorKey[]
|
||||||
|
|
||||||
|
const initColumnOrder = Object.values(AccessorKey)
|
||||||
const initColumnVisibility = {
|
const initColumnVisibility = {
|
||||||
...Object.fromEntries(Object.values(AccessorKey).map((i) => [i, true])),
|
...Object.fromEntries(initColumnOrder.map((i) => [i, true])),
|
||||||
[AccessorKey.ID]: false,
|
[AccessorKey.ID]: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +46,13 @@ export default () => {
|
|||||||
storage: localStorage,
|
storage: localStorage,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
const [columnOrder, setColumnOrder] = makePersisted(
|
||||||
|
createSignal<ColumnOrder>(initColumnOrder),
|
||||||
|
{
|
||||||
|
name: 'columnOrder',
|
||||||
|
storage: localStorage,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const request = useRequest()
|
const request = useRequest()
|
||||||
const [search, setSearch] = createSignal('')
|
const [search, setSearch] = createSignal('')
|
||||||
@ -192,6 +201,9 @@ export default () => {
|
|||||||
|
|
||||||
const table = createSolidTable({
|
const table = createSolidTable({
|
||||||
state: {
|
state: {
|
||||||
|
get columnOrder() {
|
||||||
|
return columnOrder()
|
||||||
|
},
|
||||||
get sorting() {
|
get sorting() {
|
||||||
return sorting()
|
return sorting()
|
||||||
},
|
},
|
||||||
@ -229,8 +241,12 @@ export default () => {
|
|||||||
<IconSettings />
|
<IconSettings />
|
||||||
</label>
|
</label>
|
||||||
<ConnectionsModal
|
<ConnectionsModal
|
||||||
data={columnVisibility()}
|
order={columnOrder()}
|
||||||
onChange={(data: ColumnVisibility) =>
|
visible={columnVisibility()}
|
||||||
|
onOrderChange={(data: ColumnOrder) => {
|
||||||
|
setColumnOrder([...data])
|
||||||
|
}}
|
||||||
|
onVisibleChange={(data: ColumnVisibility) =>
|
||||||
setColumnVisibility({ ...data })
|
setColumnVisibility({ ...data })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user