Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit 3f3f1c1

Browse files
committed
Merge remote-tracking branch 'origin/footer-lab'
2 parents d1429ff + 0808554 commit 3f3f1c1

File tree

17 files changed

+194
-159
lines changed

17 files changed

+194
-159
lines changed

src/__tests__/serviceBase.test.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/automations/Footer.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Row } from "@tanstack/react-table";
2+
import { RowDataType } from "cdm/FolderModel";
3+
4+
export default class Footer {
5+
constructor(public readonly rows: Row<RowDataType>[]) { }
6+
7+
public sum(key: string): string {
8+
const total = this.rows.reduce((acc, row) => acc + row.getValue<number>(key), 0);
9+
return `Total: ${total}`;
10+
}
11+
}

src/cdm/CellModel.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/cdm/FooterModel.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Header, Table } from "@tanstack/react-table";
2+
import { RowDataType, TableColumn } from "cdm/FolderModel";
3+
4+
export type TableFooterProps = {
5+
table: Table<RowDataType>;
6+
header: Header<RowDataType, TableColumn>;
7+
headerIndex: number;
8+
};

src/cdm/RowTypeModel.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { Link } from "obsidian-dataview";
22
import { RowSelectOption } from "cdm/ComponentsModel";
33
import NoteInfo from "services/NoteInfo";
4-
import { ConfigColumn } from "cdm/FolderModel";
4+
import { ConfigColumn, RowDataType } from "cdm/FolderModel";
5+
import { Row, Table } from "@tanstack/react-table";
56

6-
export type RowType = number | string | boolean | Date | Link | RowSelectOption[] | NoteInfo | ConfigColumn;
7+
export type RowType = number | string | boolean | Date | Link | RowSelectOption[] | NoteInfo | ConfigColumn;
8+
9+
export type TableRowProps = {
10+
row: Row<RowDataType>,
11+
table: Table<RowDataType>
12+
}

src/cdm/SettingsModel.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface LocalSettings {
5757
inline_new_position: string;
5858
date_format: string;
5959
datetime_format: string;
60+
enable_footer: boolean;
6061
}
6162

6263
export interface FilterSettings {

src/components/DefaultFooter.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import Footer from "automations/Footer";
2+
import { DatabaseHeaderProps, TableColumn } from "cdm/FolderModel";
3+
import { InputType } from "helpers/Constants";
4+
import { c, getAlignmentClassname } from "helpers/StylesHelper";
5+
import React from "react";
6+
7+
export default function DefaultFooter(headerProps: DatabaseHeaderProps) {
8+
/** Properties of footer */
9+
const { header, table } = headerProps;
10+
const { tableState } = table.options.meta;
11+
const configInfo = tableState.configState((state) => state.info);
12+
/** Column values */
13+
const { input, config } = header.column.columnDef as TableColumn;
14+
let footerInfo: string;
15+
switch (input) {
16+
case InputType.NUMBER:
17+
footerInfo = new Footer(table.getRowModel().rows).sum(header.id);
18+
break;
19+
default:
20+
return null;
21+
// Do nothing
22+
}
23+
24+
return (
25+
<span
26+
key={`foot-th-cell-${header.id}`}
27+
className={c(
28+
getAlignmentClassname(config, configInfo.getLocalSettings())
29+
)}
30+
>
31+
{footerInfo}
32+
</span>
33+
);
34+
}

src/components/Table.tsx

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import {
2323
DatabaseLimits,
2424
MetadataColumns,
2525
ResizeConfiguration,
26-
StyleVariables,
2726
} from "helpers/Constants";
2827
import { LOGGER } from "services/Logger";
2928
import DefaultCell from "components/DefaultCell";
@@ -32,6 +31,8 @@ import { c } from "helpers/StylesHelper";
3231
import { HeaderNavBar } from "components/NavBar";
3332
import TableHeader from "components/TableHeader";
3433
import TableRow from "components/TableRow";
34+
import TableFooter from "components/TableFooter";
35+
import DefaultFooter from "components/DefaultFooter";
3536
import getInitialColumnSizing from "components/behavior/InitialColumnSizeRecord";
3637
import customSortingfns, {
3738
globalDatabaseFilterFn,
@@ -44,14 +45,15 @@ import {
4445
} from "components/obsidianArq/markdownLinks";
4546
import HeaderContextMenuWrapper from "components/contextMenu/HeaderContextMenuWrapper";
4647
import TableActions from "components/tableActions/TableActions";
47-
import PaginationTable from "./navbar/PaginationTable";
48+
import PaginationTable from "components/navbar/PaginationTable";
4849

4950
const defaultColumn: Partial<ColumnDef<RowDataType>> = {
5051
minSize: DatabaseLimits.MIN_COLUMN_HEIGHT,
5152
maxSize: DatabaseLimits.MAX_COLUMN_HEIGHT,
5253
cell: DefaultCell,
5354
header: DefaultHeader,
5455
enableResizing: true,
56+
footer: DefaultFooter,
5557
};
5658

5759
/**
@@ -229,10 +231,7 @@ export function Table(tableData: TableDataType) {
229231
width: table.getCenterTotalSize(),
230232
}}
231233
>
232-
<div
233-
key={`div-table-header-group-sticky`}
234-
className={c(`table-header-group ${"sticky-top"}`)}
235-
>
234+
<div key={`div-thead-sticky`} className={c(`thead sticky-top`)}>
236235
{/* INIT HEADERS */}
237236
{table
238237
.getHeaderGroups()
@@ -250,7 +249,7 @@ export function Table(tableData: TableDataType) {
250249
);
251250
return (
252251
<div
253-
key={`${headerGroup.id}-${headerGroupIndex}`}
252+
key={`header-group-${headerGroup.id}-${headerGroupIndex}`}
254253
className={`${c("tr header-group")}`}
255254
>
256255
{/** HEADER CONTEXT */}
@@ -282,7 +281,7 @@ export function Table(tableData: TableDataType) {
282281
/>
283282
)
284283
)}
285-
{/** ADD COLUMN HEADER*/}
284+
{/** ADD COLUMN HEADER */}
286285
<HeaderContextMenuWrapper header={addColumnHeader} />
287286
</div>
288287
);
@@ -291,13 +290,7 @@ export function Table(tableData: TableDataType) {
291290
{/* ENDS HEADERS */}
292291
</div>
293292
{/* INIT BODY */}
294-
295-
<div
296-
key={`div-tbody`}
297-
style={{
298-
display: "table-row-group",
299-
}}
300-
>
293+
<div key={`div-tbody`} className={c(`tbody`)}>
301294
{table.getRowModel().rows.map((row: Row<RowDataType>) => (
302295
<TableRow
303296
key={`table-cell-${row.index}`}
@@ -307,6 +300,40 @@ export function Table(tableData: TableDataType) {
307300
))}
308301
{/* ENDS BODY */}
309302
</div>
303+
{/* INIT FOOTER */}
304+
{configInfo.getLocalSettings().enable_footer && (
305+
<div key={`div-tfoot`} className={c(`tfoot`)}>
306+
{table
307+
.getFooterGroups()
308+
.map(
309+
(
310+
footerGroup: HeaderGroup<RowDataType>,
311+
footerGroupIndex: number
312+
) => {
313+
return (
314+
<div
315+
key={`footer-group-${footerGroup.id}-${footerGroupIndex}`}
316+
className={`${c("tr footer-group")}`}
317+
>
318+
{footerGroup.headers.map(
319+
(
320+
header: Header<RowDataType, TableColumn>,
321+
headerIndex: number
322+
) => (
323+
<TableFooter
324+
table={table}
325+
header={header}
326+
headerIndex={headerIndex + 1}
327+
/>
328+
)
329+
)}
330+
</div>
331+
);
332+
}
333+
)}
334+
{/* ENDS FOOTER */}
335+
</div>
336+
)}
310337
{/* ENDS TABLE */}
311338
</div>
312339
{/* ENDS SCROLL PANE */}

src/components/TableFooter.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { flexRender } from "@tanstack/react-table";
2+
import { TableFooterProps } from "cdm/FooterModel";
3+
import { c } from "helpers/StylesHelper";
4+
import React from "react";
5+
6+
export default function TableFooter(tableFooterProps: TableFooterProps) {
7+
const { table, header, headerIndex } = tableFooterProps;
8+
return (
9+
<div key={`foot-th-${headerIndex}`} className={c("th footer")}>
10+
{header.isPlaceholder
11+
? null
12+
: flexRender(header.column.columnDef.footer, header.getContext())}
13+
</div>
14+
);
15+
}

src/components/TableHeader.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { flexRender } from "@tanstack/react-table";
33
import { c } from "helpers/StylesHelper";
44
import { TableHeaderProps } from "cdm/HeaderModel";
55

6-
export default function TableHeader(headerProps: TableHeaderProps) {
7-
const { table, header, reorderColumn, headerIndex } = headerProps;
6+
export default function TableHeader(tableHeaderProps: TableHeaderProps) {
7+
const { table, header, reorderColumn, headerIndex } = tableHeaderProps;
88
const { view } = table.options.meta;
99
const { columnOrder } = table.options.state;
1010
const [isDragging, setIsDragging] = React.useState(false);

0 commit comments

Comments
 (0)