metacubexd/src/components/ConnectionsSettingsModal.tsx

167 lines
4.5 KiB
TypeScript
Raw Normal View History

import { useI18n } from '@solid-primitives/i18n'
2023-09-01 00:12:33 +08:00
import type {
DragEventHandler,
Draggable,
Droppable,
} from '@thisbeyond/solid-dnd'
import {
DragDropProvider,
DragDropSensors,
DragOverlay,
SortableProvider,
closestCenter,
createSortable,
useDragDropContext,
} from '@thisbeyond/solid-dnd'
2023-09-03 03:36:12 +08:00
import { Component, For, Show, createSignal } from 'solid-js'
2023-09-15 23:43:55 +08:00
import { Button, ConfigTitle } from '~/components'
2023-09-03 03:36:12 +08:00
import {
CONNECTIONS_TABLE_ACCESSOR_KEY,
CONNECTIONS_TABLE_INITIAL_COLUMN_ORDER,
CONNECTIONS_TABLE_INITIAL_COLUMN_VISIBILITY,
2023-09-15 23:43:55 +08:00
MODAL,
TAILWINDCSS_SIZE,
2023-09-03 03:36:12 +08:00
} from '~/constants'
2023-09-15 23:43:55 +08:00
import { connectionsTableSize, setConnectionsTableSize } from '~/signals'
2023-08-31 22:49:34 +08:00
2023-09-03 03:36:12 +08:00
type ColumnVisibility = Partial<Record<CONNECTIONS_TABLE_ACCESSOR_KEY, boolean>>
type ColumnOrder = CONNECTIONS_TABLE_ACCESSOR_KEY[]
2023-08-31 22:49:34 +08:00
2023-09-15 23:43:55 +08:00
export const ConnectionsSettingsModal = (props: {
2023-09-01 00:12:33 +08:00
order: ColumnOrder
visible: ColumnVisibility
onOrderChange: (value: ColumnOrder) => void
onVisibleChange: (value: ColumnVisibility) => void
2023-08-31 22:49:34 +08:00
}) => {
const [t] = useI18n()
2023-09-03 03:36:12 +08:00
const [activeKey, setActiveKey] =
createSignal<CONNECTIONS_TABLE_ACCESSOR_KEY | null>(null)
2023-09-01 00:12:33 +08:00
const onDragStart = ({ draggable }: { draggable: Draggable }) =>
2023-09-03 03:36:12 +08:00
setActiveKey(draggable.id as CONNECTIONS_TABLE_ACCESSOR_KEY)
2023-09-01 00:12:33 +08:00
const onDragEnd = ({
draggable,
droppable,
}: {
draggable: Draggable
droppable: Droppable
}) => {
if (draggable && droppable) {
const currentItems = props.order
2023-09-03 03:36:12 +08:00
const fromIndex = currentItems.indexOf(
draggable.id as CONNECTIONS_TABLE_ACCESSOR_KEY,
)
const toIndex = currentItems.indexOf(
droppable.id as CONNECTIONS_TABLE_ACCESSOR_KEY,
)
2023-09-01 00:12:33 +08:00
if (fromIndex !== toIndex) {
const updatedItems = currentItems.slice()
updatedItems.splice(toIndex, 0, ...updatedItems.splice(fromIndex, 1))
props.onOrderChange(updatedItems)
}
}
}
2023-09-03 03:36:12 +08:00
const FormRow: Component<{
key: CONNECTIONS_TABLE_ACCESSOR_KEY
}> = ({ key }) => {
2023-09-01 00:12:33 +08:00
const sortable = createSortable(key)
const [state] = useDragDropContext()!
return (
<div
use:sortable
class="sortable"
classList={{
'opacity-25': sortable.isActiveDraggable,
'transition-transform': !!state.active.draggable,
}}
>
2023-09-15 23:43:55 +08:00
<div class="flex cursor-grab justify-between py-2">
2023-09-02 13:50:24 +08:00
<span class="select-none">{t(key)}</span>
2023-09-15 23:43:55 +08:00
2023-09-01 00:12:33 +08:00
<input
type="checkbox"
class="toggle"
checked={props.visible[key]}
onChange={(e) => {
props.onVisibleChange({
...props.visible,
[key]: e.target.checked,
})
}}
/>
</div>
</div>
)
}
2023-08-31 22:49:34 +08:00
return (
<dialog
2023-09-15 23:43:55 +08:00
id={MODAL.CONNECTIONS_SETTINGS}
class="modal modal-bottom sm:modal-middle"
>
2023-09-15 23:43:55 +08:00
<div
class="modal-box flex flex-col gap-4"
onContextMenu={(e) => e.preventDefault()}
>
<div>
<ConfigTitle withDivider>{t('tableSize')}</ConfigTitle>
<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>
<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
class="btn-neutral btn-sm ml-auto mt-4 block"
onClick={() => {
props.onOrderChange(CONNECTIONS_TABLE_INITIAL_COLUMN_ORDER)
props.onVisibleChange(CONNECTIONS_TABLE_INITIAL_COLUMN_VISIBILITY)
}}
>
{t('reset')}
</Button>
</div>
2023-08-31 22:49:34 +08:00
</div>
<form method="dialog" class="modal-backdrop">
<button />
</form>
</dialog>
2023-08-31 22:49:34 +08:00
)
}