Table updates
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Button, Group, Text } from '@mantine/core';
|
||||
import { Button, Group, ScrollArea, Text } from '@mantine/core';
|
||||
import {
|
||||
type ColumnFiltersState,
|
||||
flexRender,
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
useReactTable,
|
||||
} from '@tanstack/react-table';
|
||||
import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
|
||||
import { scrollAreaClasses } from 'styles';
|
||||
import { Filter } from './components';
|
||||
|
||||
export function DataTable({
|
||||
@@ -62,144 +63,168 @@ export function DataTable({
|
||||
}
|
||||
}, [filtersEnabled]);
|
||||
return (
|
||||
<table
|
||||
style={{
|
||||
borderSpacing: '2px 0px',
|
||||
backgroundColor: 'var(--mantine-color-accent-0)',
|
||||
<ScrollArea
|
||||
className={scrollAreaClasses.default}
|
||||
classNames={scrollAreaClasses}
|
||||
styles={{
|
||||
scrollbar: {
|
||||
paddingTop: '2.5rem',
|
||||
paddingBottom: '2rem',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<thead
|
||||
<table
|
||||
style={{
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
zIndex: 1,
|
||||
backgroundColor: 'var(--mantine-color-primary-0)',
|
||||
width: '100%',
|
||||
borderSpacing: '2px 0px',
|
||||
backgroundColor: 'var(--mantine-color-accent-0)',
|
||||
}}
|
||||
>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<th
|
||||
key={header.id}
|
||||
style={{
|
||||
width: header.getSize(),
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
{header.isPlaceholder ? null : (
|
||||
<>
|
||||
<Button
|
||||
{...{
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
borderRadius: '0px',
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
px: 0,
|
||||
onClick: () => {
|
||||
if (header.column.getCanSort()) {
|
||||
if (sorting[0].id === header.id) {
|
||||
setSorting([
|
||||
{
|
||||
id: header.id,
|
||||
desc: !sorting[0].desc,
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
setSorting([
|
||||
{
|
||||
id: header.id,
|
||||
desc: false,
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Group align='center' justify='center'>
|
||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
||||
{{
|
||||
asc: ' 🔼',
|
||||
desc: ' 🔽',
|
||||
}[header.column.getIsSorted() as string] ?? null}
|
||||
</Group>
|
||||
</Button>
|
||||
{filtersEnabled ? (
|
||||
<Filter
|
||||
column={header.column}
|
||||
options={[...new Set(data.map((item: any) => item[header.id]))]}
|
||||
resultCount={table.getFilteredRowModel().rows.length}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody>
|
||||
{table.getRowModel().rows.map((row, index) => (
|
||||
<tr
|
||||
key={row.id}
|
||||
style={{
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
backgroundColor:
|
||||
index % 2 === 0
|
||||
? 'color-mix(in srgb, var(--mantine-color-background-0), var(--mantine-color-primary-0) 10%)'
|
||||
: 'color-mix(in srgb, var(--mantine-color-background-0), var(--mantine-color-primary-0) 30%)',
|
||||
}}
|
||||
onClick={() => {
|
||||
row.toggleExpanded();
|
||||
}}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<td
|
||||
key={cell.id}
|
||||
style={{
|
||||
width: cell.column.getSize(),
|
||||
}}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{table.getFooterGroups().map((footerGroup) => (
|
||||
<tr key={footerGroup.id}>
|
||||
{footerGroup.headers.map((header) => (
|
||||
<th key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(header.column.columnDef.footer, header.getContext())}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
<tr
|
||||
<thead
|
||||
style={{
|
||||
width: '100%',
|
||||
backgroundColor: 'var(--mantine-color-primary-0)',
|
||||
position: 'sticky',
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
zIndex: 1,
|
||||
backgroundColor: 'var(--mantine-color-primary-0)',
|
||||
}}
|
||||
>
|
||||
<td colSpan={5}>
|
||||
<Text
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<th
|
||||
key={header.id}
|
||||
style={{
|
||||
width: header.getSize(),
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
{header.isPlaceholder ? null : (
|
||||
<>
|
||||
<Button
|
||||
{...{
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
borderRadius: '0px',
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
px: 0,
|
||||
onClick: () => {
|
||||
if (header.column.getCanSort()) {
|
||||
if (sorting[0].id === header.id) {
|
||||
setSorting([
|
||||
{
|
||||
id: header.id,
|
||||
desc: !sorting[0].desc,
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
setSorting([
|
||||
{
|
||||
id: header.id,
|
||||
desc: false,
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Group align='center' justify='center'>
|
||||
{flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
{{
|
||||
asc: (
|
||||
<Group gap={0}>
|
||||
<Text c={'var(--mantine-color-accent-0)'}>🠗</Text>
|
||||
<Text>🠕</Text>
|
||||
</Group>
|
||||
),
|
||||
desc: (
|
||||
<Group gap={0}>
|
||||
<Text>🠗</Text>
|
||||
<Text c={'var(--mantine-color-accent-0)'}>🠕</Text>
|
||||
</Group>
|
||||
),
|
||||
}[header.column.getIsSorted() as string] ?? null}
|
||||
</Group>
|
||||
</Button>
|
||||
{filtersEnabled ? (
|
||||
<Filter
|
||||
column={header.column}
|
||||
options={[...new Set(data.map((item: any) => item[header.id]))]}
|
||||
resultCount={table.getFilteredRowModel().rows.length}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody>
|
||||
{table.getRowModel().rows.map((row, index) => (
|
||||
<tr
|
||||
key={row.id}
|
||||
style={{
|
||||
color: 'var(--mantine-color-background-0)',
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
backgroundColor:
|
||||
index % 2 === 0
|
||||
? 'color-mix(in srgb, var(--mantine-color-background-0), var(--mantine-color-primary-0) 10%)'
|
||||
: 'color-mix(in srgb, var(--mantine-color-background-0), var(--mantine-color-primary-0) 30%)',
|
||||
}}
|
||||
onClick={() => {
|
||||
row.toggleExpanded();
|
||||
}}
|
||||
>
|
||||
Total Entries: {table.getRowCount()}
|
||||
</Text>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<td
|
||||
key={cell.id}
|
||||
style={{
|
||||
width: cell.column.getSize(),
|
||||
}}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{table.getFooterGroups().map((footerGroup) => (
|
||||
<tr key={footerGroup.id}>
|
||||
{footerGroup.headers.map((header) => (
|
||||
<th key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(header.column.columnDef.footer, header.getContext())}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
<tr
|
||||
style={{
|
||||
backgroundColor: 'var(--mantine-color-primary-0)',
|
||||
position: 'sticky',
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<td colSpan={5}>
|
||||
<Text
|
||||
style={{
|
||||
color: 'var(--mantine-color-background-0)',
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
Total Entries: {table.getCoreRowModel().rows.length}
|
||||
</Text>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</ScrollArea>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { DatePickerInput } from '@mantine/dates';
|
||||
import type { Column, RowData } from '@tanstack/react-table';
|
||||
import { DebouncedInput } from 'components';
|
||||
import { selectClasses } from 'styles';
|
||||
import { datePickerInputClasses, selectClasses } from 'styles';
|
||||
|
||||
declare module '@tanstack/react-table' {
|
||||
//allows us to define custom properties for our columns
|
||||
@@ -57,16 +57,7 @@ export function Filter({
|
||||
<DatePickerInput
|
||||
type='range'
|
||||
clearable
|
||||
style={{
|
||||
width: '100%',
|
||||
}}
|
||||
styles={{
|
||||
input: {
|
||||
borderRadius: 0,
|
||||
border: 'none',
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
},
|
||||
}}
|
||||
classNames={datePickerInputClasses}
|
||||
value={columnFilterValue as [Date, Date]}
|
||||
onChange={(value) => column.setFilterValue(value)}
|
||||
/>
|
||||
@@ -99,6 +90,12 @@ export function Filter({
|
||||
options: selectClasses.menuSelectOptions,
|
||||
option: selectClasses.menuSelectOption,
|
||||
}}
|
||||
styles={{
|
||||
input: {
|
||||
border: 'none',
|
||||
borderRadius: 0,
|
||||
},
|
||||
}}
|
||||
data={options
|
||||
.map((option: ComboboxItem) => {
|
||||
return { value: option, label: option };
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ActionIcon, TextInput } from '@mantine/core';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FiX } from 'react-icons/fi';
|
||||
import { textInputClasses } from 'styles';
|
||||
|
||||
export function DebouncedInput({
|
||||
value: initialValue,
|
||||
@@ -34,11 +35,20 @@ export function DebouncedInput({
|
||||
p={0}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
classNames={textInputClasses}
|
||||
styles={{
|
||||
input: {
|
||||
borderRadius: 0,
|
||||
border: 'none',
|
||||
borderStyle: 'none',
|
||||
color: 'var(--mantine-color-primary-0)',
|
||||
'&::placeholder': {
|
||||
color: 'red !important',
|
||||
},
|
||||
},
|
||||
wrapper: {
|
||||
'&::placeholder': {
|
||||
color: 'red !important',
|
||||
},
|
||||
},
|
||||
}}
|
||||
rightSection={
|
||||
|
||||
55
src/styles/DatePickerInput.module.css
Normal file
55
src/styles/DatePickerInput.module.css
Normal file
@@ -0,0 +1,55 @@
|
||||
.input {
|
||||
border-radius: 0 !important;
|
||||
border: none !important;
|
||||
color: var(--mantine-color-primary-0) !important;
|
||||
}
|
||||
.levelsGroup {
|
||||
background-color: var(--mantine-color-background-0) !important;
|
||||
}
|
||||
.day {
|
||||
color: var(--mantine-color-primary-0) !important;
|
||||
&:hover {
|
||||
color: var(--mantine-color-background-0) !important;
|
||||
background-color: var(--mantine-color-primary-0) !important;
|
||||
}
|
||||
&[data-weekend="true"] {
|
||||
color: var(--mantine-color-accent-0) !important;
|
||||
}
|
||||
}
|
||||
.monthsListControl {
|
||||
color: var(--mantine-color-primary-0) !important;
|
||||
&:hover {
|
||||
color: var(--mantine-color-background-0) !important;
|
||||
background-color: var(--mantine-color-primary-0) !important;
|
||||
}
|
||||
&[data-weekend="true"] {
|
||||
color: var(--mantine-color-accent-0) !important;
|
||||
}
|
||||
}
|
||||
.yearsListControl {
|
||||
color: var(--mantine-color-primary-0) !important;
|
||||
&:hover {
|
||||
color: var(--mantine-color-background-0) !important;
|
||||
background-color: var(--mantine-color-primary-0) !important;
|
||||
}
|
||||
&[data-weekend="true"] {
|
||||
color: var(--mantine-color-accent-0) !important;
|
||||
}
|
||||
}
|
||||
.weekday {
|
||||
color: var(--mantine-color-border-0) !important;
|
||||
}
|
||||
.calendarHeaderControl {
|
||||
color: var(--mantine-color-primary-0) !important;
|
||||
&:hover {
|
||||
color: var(--mantine-color-background-0) !important;
|
||||
background-color: var(--mantine-color-primary-0) !important;
|
||||
}
|
||||
}
|
||||
.calendarHeaderLevel {
|
||||
color: var(--mantine-color-primary-0) !important;
|
||||
&:hover {
|
||||
color: var(--mantine-color-background-0) !important;
|
||||
background-color: var(--mantine-color-primary-0) !important;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import boxClasses from './Box.module.css';
|
||||
import buttonClasses from './Button.module.css';
|
||||
import cardClasses from './Card.module.css';
|
||||
import colorSwatchClasses from './ColorSwatch.module.css';
|
||||
import datePickerInputClasses from './DatePickerInput.module.css';
|
||||
import menuClasses from './Menu.module.css';
|
||||
import modalClasses from './Modal.module.css';
|
||||
import multiSelectClasses from './MultiSelect.module.css';
|
||||
@@ -23,6 +24,7 @@ export {
|
||||
buttonClasses,
|
||||
cardClasses,
|
||||
colorSwatchClasses,
|
||||
datePickerInputClasses,
|
||||
menuClasses,
|
||||
modalClasses,
|
||||
multiSelectClasses,
|
||||
|
||||
Reference in New Issue
Block a user