Skip to content

Commit 4bc8aaf

Browse files
committed
feat: replace data table with mantine data table
not feature complete
1 parent d59e946 commit 4bc8aaf

14 files changed

+207
-292
lines changed

postcss.config.cjs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
module.exports = {
2-
plugins: {
3-
"postcss-preset-mantine": {},
4-
"postcss-simple-vars": {
5-
variables: {
6-
"mantine-breakpoint-xs": "36em",
7-
"mantine-breakpoint-sm": "48em",
8-
"mantine-breakpoint-md": "62em",
9-
"mantine-breakpoint-lg": "75em",
10-
"mantine-breakpoint-xl": "88em",
11-
},
2+
plugins: {
3+
"postcss-preset-mantine": {},
4+
"postcss-simple-vars": {
5+
variables: {
6+
"mantine-breakpoint-xs": "36em",
7+
"mantine-breakpoint-sm": "48em",
8+
"mantine-breakpoint-md": "62em",
9+
"mantine-breakpoint-lg": "75em",
10+
"mantine-breakpoint-xl": "88em",
11+
},
12+
},
1213
},
13-
},
1414
};

src/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import "@mantine/core/styles.css";
22
import "@mantine/charts/styles.css";
33
import "@mantine/notifications/styles.css";
44
import "@mantine/spotlight/styles.css";
5+
import 'mantine-datatable/styles.css';
56
import "./style/index.css";
67

7-
import { AppShell, Center, MantineProvider, Stack } from "@mantine/core";
8-
98
import classes from "./App.module.css";
9+
import { cssVariablesResolver, presetTheme } from "./style/StyleProvider";
1010

11+
import { AppShell, Center, MantineProvider, Stack } from "@mantine/core";
1112
import { useDisclosure, useLocalStorage } from "@mantine/hooks";
1213
import { Notifications } from "@mantine/notifications";
1314
import { useEffect } from "react";
@@ -19,7 +20,6 @@ import Header from "./app/shell/Header/Header";
1920
import Sidebar from "./app/shell/Sidebar/Sidebar";
2021
import i18n from "./i18n";
2122
import { useSetting } from "./logic/settings/hooks/useSetting";
22-
import { cssVariablesResolver, presetTheme } from "./style/StyleProvider";
2323

2424
function useRestoreLanguage() {
2525
const [language] = useSetting("language");
Lines changed: 9 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,13 @@
1-
.tableScrollContainer {
2-
min-width: 300px;
3-
width: 100%;
4-
max-width: 100%;
5-
}
6-
.tableWrapper {
7-
width: 100%;
8-
height: 100%;
9-
overflow-x: "scroll";
10-
overflow-y: "scroll";
11-
}
12-
13-
.table {
14-
white-space: nowrap;
15-
font-size: 2rem !important;
16-
&:focus {
17-
outline: none;
18-
}
19-
}
20-
21-
.tr {
22-
border-radius: var(--mantine-radius-lg);
23-
user-select: none;
24-
}
25-
26-
.bodyTr {
27-
cursor: pointer;
1+
.row {
2+
border-radius: var(--mantine-radius-md);
3+
overflow: hidden;
4+
font-weight: 500;
5+
transition: none;
286
}
297

30-
.td {
31-
font-size: var(--mantine-font-size-xs) !important;
32-
font-weight: 500;
33-
border-top: none !important;
34-
overflow: hidden;
35-
max-width: 15rem;
36-
white-space: nowrap;
37-
&:first-of-type {
38-
border-top-left-radius: var(--mantine-radius-md);
39-
border-bottom-left-radius: var(--mantine-radius-md);
40-
}
41-
&:last-of-type {
42-
border-top-right-radius: var(--mantine-radius-md);
43-
border-bottom-right-radius: var(--mantine-radius-md);
44-
}
8+
.row td {
9+
background: none;
10+
transition: none;
4511
}
4612

4713
.selected {
@@ -50,54 +16,5 @@
5016
var(--mantine-primary-color-8)
5117
) !important;
5218
color: var(--mantine-color-white);
53-
}
54-
55-
.th {
56-
border-bottom: none !important;
57-
border-radius: 0 !important;
58-
font-size: var(--mantine-font-size-xs) !important;
59-
font-weight: 500; /*???*/
60-
line-height: 1rem;
61-
position: sticky;
62-
top: 0px;
63-
background-color: light-dark(
64-
var(--mantine-color-white),
65-
var(--mantine-color-dark-7)
66-
);
67-
color: light-dark(
68-
var(--mantine-color-black),
69-
var(--mantine-color-white)
70-
) !important;
71-
cursor: pointer;
72-
@mixin hover {
73-
background-color: light-dark(
74-
var(--mantine-color-gray-1),
75-
var(--mantine-color-dark-6)
76-
);
77-
}
78-
}
79-
80-
.thInnerWrapper {
81-
display: inline-flex;
82-
align-items: center;
83-
line-height: 1rem;
84-
height: 1rem;
85-
gap: 0.25rem;
86-
87-
& svg {
88-
opacity: 0;
89-
color: light-dark(
90-
var(--mantine-color-gray-6),
91-
var(--mantine-color-dark-2)
92-
);
93-
transition: transform 0.2s ease, opacity 0.1s ease;
94-
}
95-
}
96-
97-
.thInnerWrapper.thInnerWrapperActive svg {
98-
opacity: 1;
99-
}
100-
101-
.thInnerWrapper.thInnerWrapperActiveDesc svg {
102-
transform: rotate(180deg);
19+
transition: none;
10320
}

src/app/NoteTable/NoteTable.tsx

Lines changed: 82 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,103 @@
1-
import { NoteType } from "@/logic/note/note";
1+
import { Note, NoteType } from "@/logic/note/note";
22
import { NoteSortFunction, NoteSorts } from "@/logic/note/sort";
3-
import { Table } from "@mantine/core";
4-
import { useEventListener } from "@mantine/hooks";
5-
import { IconCards } from "@tabler/icons-react";
6-
import { t } from "i18next";
7-
import { useEffect } from "react";
8-
import EmptyNotice from "../../components/EmptyNotice";
9-
import { Note } from "../../logic/note/note";
3+
import clsx from "clsx";
4+
import { DataTable, DataTableSortStatus } from "mantine-datatable";
5+
import { useEffect, useState } from "react";
106
import classes from "./NoteTable.module.css";
11-
import NoteTableHeadItem from "./NoteTableHeadItem";
12-
import { NoteTableItem } from "./NoteTableItem";
7+
import { useMediaQuery } from "@mantine/hooks";
138

149
interface CardTableProps {
1510
noteSet: Note<NoteType>[];
16-
selectedIndex: number;
17-
setSelectedIndex: (index: number) => void;
18-
selectedNote: Note<NoteType> | undefined;
19-
setSelectedNote: (card: Note<NoteType>) => void;
2011
sort: [NoteSortFunction, boolean];
2112
setSort: (sort: [NoteSortFunction, boolean]) => void;
13+
openedNote: Note<NoteType> | undefined;
14+
setOpenedNote: (note: Note<NoteType> | undefined) => void;
15+
openModal: () => void;
2216
}
2317

2418
function NoteTable({
2519
noteSet,
26-
selectedIndex,
27-
setSelectedIndex,
28-
selectedNote,
29-
setSelectedNote,
30-
sort,
20+
openedNote,
21+
setOpenedNote,
3122
setSort,
23+
openModal,
3224
}: CardTableProps) {
33-
const ref = useEventListener("keydown", (event) => {
34-
if (event.key === "ArrowDown") {
35-
setSelectedIndex(
36-
selectedIndex !== undefined
37-
? Math.min(selectedIndex + 1, noteSet.length - 1)
38-
: 0
39-
);
40-
} else if (event.key === "ArrowUp") {
41-
setSelectedIndex(
42-
selectedIndex !== undefined
43-
? Math.max(selectedIndex - 1, 0)
44-
: noteSet.length - 1
45-
);
46-
}
25+
const [selectedNotes, setSelectedNotes] = useState<Note<NoteType>[]>([]);
26+
27+
const [sortStatus, setSortStatus] = useState<DataTableSortStatus<Note<NoteType>>>({
28+
columnAccessor: 'sortField',
29+
sortKey: 'bySortField',
30+
direction: 'asc',
4731
});
4832

49-
//Set the selected index to 0 if there is no selected index (i.e. on page load)
5033
useEffect(() => {
51-
if (selectedIndex === -1) {
52-
setSelectedIndex(0);
53-
}
54-
}, [selectedIndex]);
34+
setSort([NoteSorts[sortStatus.sortKey as keyof typeof NoteSorts], sortStatus.direction === 'asc']);
35+
}, [sortStatus]);
36+
37+
38+
const isTouch = useMediaQuery('(pointer: coarse)');
39+
const isMobile = useMediaQuery('(max-width: 50em)');
5540

5641
return (
57-
<Table.ScrollContainer
58-
minWidth="500px"
59-
type="native"
60-
className={classes.tableScrollContainer}
61-
>
62-
<Table
63-
className={classes.table}
64-
highlightOnHover
65-
withRowBorders={false}
66-
withColumnBorders={false}
67-
striped
68-
stickyHeader
69-
ref={ref}
70-
tabIndex={0}
71-
>
72-
<Table.Thead>
73-
<Table.Tr className={classes.tr}>
74-
<NoteTableHeadItem
75-
name={"Name"}
76-
sortFunction={NoteSorts.bySortField}
77-
sort={sort}
78-
setSort={setSort}
79-
/>
80-
<NoteTableHeadItem
81-
name={"Type"}
82-
sortFunction={NoteSorts.byType}
83-
sort={sort}
84-
setSort={setSort}
85-
/>
86-
<NoteTableHeadItem
87-
name={"Deck"}
88-
sortFunction={NoteSorts.byDeckName}
89-
sort={sort}
90-
setSort={setSort}
91-
/>
92-
<NoteTableHeadItem
93-
name={"Creation Date"}
94-
sortFunction={NoteSorts.byCreationDate}
95-
sort={sort}
96-
setSort={setSort}
97-
/>
98-
</Table.Tr>
99-
</Table.Thead>
100-
<Table.Tbody>
101-
{noteSet.map((note, index) => (
102-
<NoteTableItem
103-
note={note}
104-
key={note.id}
105-
index={index}
106-
selectedIndex={selectedIndex}
107-
setSelectedIndex={setSelectedIndex}
108-
selectedNote={selectedNote}
109-
setSelectedNote={setSelectedNote}
110-
/>
111-
))}
112-
</Table.Tbody>
113-
</Table>
114-
{noteSet.length === 0 && (
115-
<EmptyNotice
116-
icon={IconCards}
117-
description={t("manage-cards.table.no-cards-found")}
118-
hideTitle
119-
p="xl"
120-
/>
121-
)}
122-
</Table.ScrollContainer>
42+
<DataTable
43+
className={classes.table}
44+
records={noteSet}
45+
columns={[
46+
{
47+
accessor: "sortField",
48+
title: "Name",
49+
ellipsis: true,
50+
width: 200,
51+
resizable: true,
52+
filtering: true,
53+
sortable: true,
54+
sortKey: "bySortField",
55+
},
56+
{
57+
accessor: "creationDate",
58+
title: "Creation Date",
59+
render: (note) => note.creationDate.toLocaleDateString(),
60+
resizable: true,
61+
sortable: true,
62+
sortKey: "byCreationDate",
63+
},
64+
{
65+
accessor: "content.type",
66+
title: "Note Type",
67+
resizable: true,
68+
sortable: true,
69+
sortKey: "byType",
70+
},
71+
]}
72+
withTableBorder={false}
73+
withRowBorders={false}
74+
highlightOnHover
75+
borderRadius="md"
76+
striped="odd"
77+
height="100%"
78+
textSelectionDisabled={isTouch}
79+
selectionCheckboxProps={{ size: isMobile ? "sm" : "xs" }}
80+
selectedRecords={selectedNotes}
81+
onSelectedRecordsChange={setSelectedNotes}
82+
sortStatus={sortStatus}
83+
onSortStatusChange={setSortStatus}
84+
rowClassName={(record) =>
85+
clsx({
86+
[classes.selected]: record.id === openedNote?.id,
87+
[classes.row]: true,
88+
})
89+
}
90+
onRowClick={(row) => {
91+
setOpenedNote(row.record);
92+
if(isMobile) {
93+
openModal();
94+
}
95+
}}
96+
onRowDoubleClick={(row) => {
97+
setOpenedNote(row.record);
98+
openModal();
99+
}}
100+
/>
123101
);
124102
}
125103

src/app/NoteTable/NoteTableItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { NoteType } from "@/logic/note/note";
44
import { Table } from "@mantine/core";
55
import cx from "clsx";
66
import { useEffect } from "react";
7-
import { NoteTypeLabels } from "../../logic/card/card";
8-
import { Note } from "../../logic/note/note";
7+
import { NoteTypeLabels } from "@/logic/card/card";
8+
import { Note } from "@/logic/note/note";
99
import classes from "./NoteTable.module.css";
1010

1111
export function NoteTableItem({

0 commit comments

Comments
 (0)