mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 10:45:27 +00:00
testing out virtualized ,fixed some more bugs
This commit is contained in:
parent
5fd3d95a14
commit
29d2db0f8e
7 changed files with 138 additions and 42 deletions
34
frontend/package-lock.json
generated
34
frontend/package-lock.json
generated
|
|
@ -36,6 +36,7 @@
|
|||
"react-draggable": "^4.4.6",
|
||||
"react-pro-sidebar": "^1.1.0",
|
||||
"react-router-dom": "^7.3.0",
|
||||
"react-virtualized": "^9.22.6",
|
||||
"react-virtualized-auto-sizer": "^1.0.26",
|
||||
"react-window": "^1.8.11",
|
||||
"recharts": "^2.15.1",
|
||||
|
|
@ -3207,6 +3208,12 @@
|
|||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-number-format": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.3.tgz",
|
||||
|
|
@ -3390,6 +3397,24 @@
|
|||
"react-dom": ">=16.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-virtualized": {
|
||||
"version": "9.22.6",
|
||||
"resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.6.tgz",
|
||||
"integrity": "sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.7.2",
|
||||
"clsx": "^1.0.4",
|
||||
"dom-helpers": "^5.1.3",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-virtualized-auto-sizer": {
|
||||
"version": "1.0.26",
|
||||
"resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.26.tgz",
|
||||
|
|
@ -3400,6 +3425,15 @@
|
|||
"react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-virtualized/node_modules/clsx": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
|
||||
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/react-window": {
|
||||
"version": "1.8.11",
|
||||
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.11.tgz",
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
"react-draggable": "^4.4.6",
|
||||
"react-pro-sidebar": "^1.1.0",
|
||||
"react-router-dom": "^7.3.0",
|
||||
"react-virtualized": "^9.22.6",
|
||||
"react-virtualized-auto-sizer": "^1.0.26",
|
||||
"react-window": "^1.8.11",
|
||||
"recharts": "^2.15.1",
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ const ChannelsTable = ({}) => {
|
|||
header: () => <Flex justify="flex-end">#</Flex>,
|
||||
cell: ({ getValue }) => (
|
||||
<Flex justify="flex-end" style={{ width: '100%' }}>
|
||||
<Text size="xs">{getValue()}</Text>
|
||||
<Text size="sm">{getValue()}</Text>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
|
|
@ -545,7 +545,7 @@ const ChannelsTable = ({}) => {
|
|||
{
|
||||
id: 'channel_group',
|
||||
accessorFn: (row) =>
|
||||
row.channel_group_id && channelGroups
|
||||
channelGroups[row.channel_group_id]
|
||||
? channelGroups[row.channel_group_id].name
|
||||
: '',
|
||||
cell: ({ getValue }) => (
|
||||
|
|
@ -556,7 +556,7 @@ const ChannelsTable = ({}) => {
|
|||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
<Text size="xs">{getValue()}</Text>
|
||||
<Text size="sm">{getValue()}</Text>
|
||||
</Box>
|
||||
),
|
||||
},
|
||||
|
|
@ -596,7 +596,7 @@ const ChannelsTable = ({}) => {
|
|||
),
|
||||
},
|
||||
],
|
||||
[selectedProfileId, data, channelGroups]
|
||||
[selectedProfileId]
|
||||
);
|
||||
|
||||
const renderHeaderCell = (header) => {
|
||||
|
|
@ -685,7 +685,9 @@ const ChannelsTable = ({}) => {
|
|||
manualFiltering: true,
|
||||
enableRowSelection: true,
|
||||
onRowSelectionChange: onRowSelectionChange,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getExpandedRowHeight: (row) => {
|
||||
return 20 + 28 * row.original.streams.length;
|
||||
},
|
||||
expandedRowRenderer: ({ row }) => {
|
||||
return (
|
||||
<Box
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const CustomTable = ({ table }) => {
|
|||
className="divTable table-striped"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
|
|
@ -31,6 +32,7 @@ const CustomTable = ({ table }) => {
|
|||
expandedRowIds={table.expandedRowIds}
|
||||
expandedRowRenderer={table.expandedRowRenderer}
|
||||
renderBodyCell={table.renderBodyCell}
|
||||
getExpandedRowHeight={table.getExpandedRowHeight}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { Box, Flex } from '@mantine/core';
|
||||
import { flexRender } from '@tanstack/react-table';
|
||||
import { VariableSizeList as List } from 'react-window';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
|
||||
const CustomTableBody = ({
|
||||
getRowModel,
|
||||
expandedRowIds,
|
||||
expandedRowRenderer,
|
||||
renderBodyCell,
|
||||
getExpandedRowHeight,
|
||||
}) => {
|
||||
const renderExpandedRow = (row) => {
|
||||
if (expandedRowRenderer) {
|
||||
|
|
@ -17,46 +19,98 @@ const CustomTableBody = ({
|
|||
|
||||
const rows = getRowModel().rows;
|
||||
|
||||
return (
|
||||
<Box className="tbody">
|
||||
{rows.map((row, index) => (
|
||||
<Box>
|
||||
<Box
|
||||
key={`tr-${row.id}`}
|
||||
className={`tr ${index % 2 == 0 ? 'tr-even' : 'tr-odd'}`}
|
||||
style={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
...(row.getIsSelected() && {
|
||||
backgroundColor: '#163632',
|
||||
}),
|
||||
}}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => {
|
||||
const renderTableBodyContents = () => {
|
||||
const virtualized = false;
|
||||
|
||||
if (virtualized) {
|
||||
return (
|
||||
<Box className="tbody" style={{ flex: 1 }}>
|
||||
<AutoSizer disableWidth>
|
||||
{({ height }) => {
|
||||
const getItemSize = (index) => {
|
||||
const row = rows[index];
|
||||
const isExpanded = expandedRowIds.includes(row.original.id);
|
||||
console.log(isExpanded);
|
||||
|
||||
// Default row height
|
||||
let rowHeight = 28;
|
||||
|
||||
if (isExpanded && getExpandedRowHeight) {
|
||||
// If row is expanded, adjust the height to be larger (based on your logic)
|
||||
// You can get this height from your state, or calculate based on number of items in the expanded row
|
||||
rowHeight += getExpandedRowHeight(row); // This function would calculate the expanded row's height
|
||||
}
|
||||
|
||||
return rowHeight;
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
className="td"
|
||||
key={`td-${cell.id}`}
|
||||
style={{
|
||||
flex: cell.column.columnDef.size ? '0 0 auto' : '1 1 0',
|
||||
width: cell.column.columnDef.size
|
||||
? cell.column.getSize()
|
||||
: undefined,
|
||||
minWidth: 0,
|
||||
}}
|
||||
<List
|
||||
height={height}
|
||||
itemCount={rows.length}
|
||||
itemSize={getItemSize}
|
||||
width="100%"
|
||||
overscanCount={10}
|
||||
>
|
||||
<Flex align="center" style={{ height: '100%' }}>
|
||||
{renderBodyCell({ row, cell })}
|
||||
</Flex>
|
||||
</Box>
|
||||
{({ index, style }) => {
|
||||
const row = rows[index];
|
||||
return renderTableBodyRow(row, index, style);
|
||||
}}
|
||||
</List>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
{expandedRowIds.includes(row.original.id) && renderExpandedRow(row)}
|
||||
}}
|
||||
</AutoSizer>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box className="tbody" style={{ flex: 1 }}>
|
||||
{rows.map((row, index) => renderTableBodyRow(row, index))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const renderTableBodyRow = (row, index, style = {}) => {
|
||||
return (
|
||||
<Box style={style}>
|
||||
<Box
|
||||
key={`tr-${row.id}`}
|
||||
className={`tr ${index % 2 == 0 ? 'tr-even' : 'tr-odd'}`}
|
||||
style={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
...(row.getIsSelected() && {
|
||||
backgroundColor: '#163632',
|
||||
}),
|
||||
}}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => {
|
||||
return (
|
||||
<Box
|
||||
className="td"
|
||||
key={`td-${cell.id}`}
|
||||
style={{
|
||||
flex: cell.column.columnDef.size ? '0 0 auto' : '1 1 0',
|
||||
width: cell.column.columnDef.size
|
||||
? cell.column.getSize()
|
||||
: undefined,
|
||||
minWidth: 0,
|
||||
}}
|
||||
>
|
||||
<Flex align="center" style={{ height: '100%' }}>
|
||||
{renderBodyCell({ row, cell })}
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
{expandedRowIds.includes(row.original.id) && renderExpandedRow(row)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
return renderTableBodyContents();
|
||||
};
|
||||
|
||||
export default CustomTableBody;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ const useTable = ({
|
|||
bodyCellRenderFns = {},
|
||||
expandedRowRenderer = () => <></>,
|
||||
onRowSelectionChange = null,
|
||||
getExpandedRowHeight = null,
|
||||
...options
|
||||
}) => {
|
||||
const [selectedTableIds, setSelectedTableIds] = useState([]);
|
||||
|
|
@ -145,6 +146,7 @@ const useTable = ({
|
|||
headerCellRenderFns,
|
||||
bodyCellRenderFns,
|
||||
renderBodyCell,
|
||||
getExpandedRowHeight,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {
|
|||
import { isNotEmpty, useForm } from '@mantine/form';
|
||||
import UserAgentsTable from '../components/tables/UserAgentsTable';
|
||||
import StreamProfilesTable from '../components/tables/StreamProfilesTable';
|
||||
import { useLocalStorage } from '@mantine/hooks';
|
||||
|
||||
const SettingsPage = () => {
|
||||
const settings = useSettingsStore((s) => s.settings);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue