alternating row colors are restored, row hover restored, fixed drag and drop functionality in streams table

This commit is contained in:
dekzter 2025-04-23 13:02:01 -04:00
parent bdc36bf5a0
commit 03f6c77391
6 changed files with 28 additions and 102 deletions

View file

@ -23,6 +23,7 @@ import {
MouseSensor,
TouchSensor,
closestCenter,
useDraggable,
useSensor,
useSensors,
} from '@dnd-kit/core';
@ -36,19 +37,22 @@ import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { shallow } from 'zustand/shallow';
// Cell Component
const RowDragHandleCell = ({ rowId }) => {
const { attributes, listeners } = useSortable({
const { attributes, listeners, setNodeRef } = useDraggable({
id: rowId,
});
return (
// Alternatively, you could set these attributes on the rows themselves
<Center>
<ActionIcon
{...attributes}
ref={setNodeRef}
{...listeners}
{...attributes}
variant="transparent"
size="xs"
style={{
cursor: 'grab', // this is enough
}}
>
<GripHorizontal color="white" />
</ActionIcon>
@ -57,7 +61,7 @@ const RowDragHandleCell = ({ rowId }) => {
};
// Row Component
const DraggableRow = ({ row }) => {
const DraggableRow = ({ row, index }) => {
const { transform, transition, setNodeRef, isDragging } = useSortable({
id: row.original.id,
});
@ -73,7 +77,7 @@ const DraggableRow = ({ row }) => {
<Box
ref={setNodeRef}
key={row.id}
className="tr"
className={`tr ${index % 2 == 0 ? 'tr-even' : 'tr-odd'}`}
style={{
...style,
display: 'flex',
@ -186,9 +190,6 @@ const ChannelStreams = ({ channel, isExpanded }) => {
enableRowSelection: true,
getRowId: (row) => row.id,
getCoreRowModel: getCoreRowModel(),
// getFilteredRowModel: getFilteredRowModel(),
// getSortedRowModel: getSortedRowModel(),
// getPaginationRowModel: getPaginationRowModel(),
});
function handleDragEnd(event) {

View file

@ -31,8 +31,6 @@ import {
ArrowUpNarrowWide,
ArrowUpDown,
ArrowDownWideNarrow,
ChevronDown,
ChevronRight,
} from 'lucide-react';
import ghostImage from '../../images/ghost.svg';
import {
@ -54,7 +52,6 @@ import {
MultiSelect,
Pagination,
NativeSelect,
Checkbox,
UnstyledButton,
CopyButton,
} from '@mantine/core';
@ -254,7 +251,6 @@ const ChannelRowActions = React.memo(
const ChannelsTable = ({}) => {
const data = useChannelsTableStore((s) => s.channels);
const rowCount = useChannelsTableStore((s) => s.count);
const pageCount = useChannelsTableStore((s) => s.pageCount);
const setSelectedTableIds = useChannelsTableStore(
(s) => s.setSelectedChannelIds
@ -710,7 +706,9 @@ const ChannelsTable = ({}) => {
},
{
accessorFn: (row) =>
row.channel_group_id ? channelGroups[row.channel_group_id].name : '',
row.channel_group_id && channelGroups
? channelGroups[row.channel_group_id].name
: '',
id: 'channel_group',
cell: ({ getValue }) => (
<Box
@ -894,84 +892,6 @@ const ChannelsTable = ({}) => {
},
});
const onRowExpansion = (row) => {
let isExpanded = false;
setExpandedRowIds((prev) => {
isExpanded = prev === row.original.id ? null : row.original.id;
return isExpanded;
});
setRowSelection({ [row.index]: true });
setSelectedChannelIds([row.original.id]);
setSelectedTableIds([row.original.id]);
};
// const renderBodyCell = (cell) => {
// switch (cell.column.id) {
// case 'select':
// return ChannelRowSelectCell({ row: cell.row });
// case 'expand':
// return ChannelExpandCell({ row: cell.row });
// default:
// return flexRender(cell.column.columnDef.cell, cell.getContext());
// }
// };
const ChannelExpandCell = useCallback(
({ row }) => {
const isExpanded = expandedRowIds === row.original.id;
return (
<Center
style={{ width: '100%', cursor: 'pointer' }}
onClick={() => {
onRowExpansion(row);
}}
>
{isExpanded ? <ChevronDown size={16} /> : <ChevronRight size={16} />}
</Center>
);
},
[expandedRowIds]
);
// const ChannelRowSelectCell = useCallback(
// ({ row }) => {
// return (
// <Center style={{ width: '100%' }}>
// <Checkbox
// size="xs"
// checked={row.getIsSelected()}
// onChange={row.getToggleSelectedHandler()}
// />
// </Center>
// );
// },
// [rows]
// );
// const ChannelRowSelectHeader = useCallback(
// ({ selectedChannelIds }) => {
// return (
// <Center style={{ width: '100%' }}>
// <Checkbox
// size="xs"
// checked={
// rowCount == 0 ? false : selectedChannelIds.length == rowCount
// }
// indeterminate={
// selectedChannelIds.length > 0 &&
// selectedChannelIds.length !== rowCount
// }
// onChange={onSelectAllChange}
// />
// </Center>
// );
// },
// [rows]
// );
return (
<Box>
{/* Header Row: outside the Paper */}
@ -1123,6 +1043,7 @@ const ChannelsTable = ({}) => {
<Group gap={5} style={{ paddingLeft: 10 }}>
<Select
size="xs"
allowDeselect={false}
value={selectedProfileId}
onChange={setSelectedProfileId}
data={Object.values(profiles).map((profile) => ({

View file

@ -17,11 +17,11 @@ const CustomTableBody = ({
return (
<Box className="tbody">
{getRowModel().rows.map((row) => (
{getRowModel().rows.map((row, index) => (
<Box>
<Box
key={row.id}
className="tr"
key={`tr-${row.id}`}
className={`tr ${index % 2 == 0 ? 'tr-even' : 'tr-odd'}`}
style={{
display: 'flex',
width: '100%',
@ -34,7 +34,7 @@ const CustomTableBody = ({
return (
<Box
className="td"
key={cell.id}
key={`td-${cell.id}`}
style={{
flex: cell.column.columnDef.size ? '0 0 auto' : '1 1 0',
width: cell.column.columnDef.size

View file

@ -18,6 +18,10 @@
display: flex;
}
.table-striped .tbody .tr:hover {
background-color: rgb(68,68,68);
}
.tr {
/* width: fit-content;
width: 100%; */
@ -79,12 +83,12 @@
}
}
.table-striped .tbody .tr:nth-child(odd),
/* .table-striped .tbody .tr:nth-child(odd), */
.table-striped .tbody .tr-odd {
background-color: #18181b;
}
.table-striped .tbody .tr:nth-child(even),
/* .table-striped .tbody .tr:nth-child(even), */
.table-striped .tbody .tr-even {
background-color: #27272A;
}

View file

@ -293,6 +293,7 @@ const useChannelsStore = create((set, get) => ({
const updates = {
profiles: {
...state.profiles,
[profileId]: updatedProfile,
},
};

View file

@ -5,11 +5,11 @@ import API from '../api';
const useChannelsTableStore = create((set, get) => ({
channels: [],
count: 0,
pageCount: 0,
sorting: [{ id: 'channel_number', desc: false }],
pagination: {
pageIndex: 0,
pageCount: 50,
pageSize: 50,
},
selectedChannelIds: [],
@ -17,8 +17,7 @@ const useChannelsTableStore = create((set, get) => ({
set((state) => {
return {
channels: results,
count: count,
pageCount: Math.ceil(count / params.page_size),
pageCount: Math.ceil(count / params.get('page_size')),
};
});
},