Skip to content

Commit

Permalink
435 basic list (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
rolfheij-sil authored Oct 18, 2023
2 parents e04d763 + 045da22 commit fcd26c6
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 0 deletions.
66 changes: 66 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@faker-js/faker": "^8.1.0",
"@mui/icons-material": "^5.14.7",
"@mui/material": "^5.14.7",
"@sillsdev/scripture": "^1.4.0",
"@tanstack/react-table": "^8.10.3",
"async-mutex": "^0.4.0",
"chalk": "^4.1.2",
"chokidar": "^3.5.3",
Expand Down
11 changes: 11 additions & 0 deletions src/renderer/components/basic-list/basic-list.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.basic-list-table {
overflow: auto;

.table-header {
text-align: left;
}
}

.basic-list-expand-button {
cursor: pointer;
}
167 changes: 167 additions & 0 deletions src/renderer/components/basic-list/basic-list.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { useState } from 'react';
import { SavedTabInfo, TabInfo } from '@shared/data/web-view.model';
import {
ExpandedState,
useReactTable,
getCoreRowModel,
getExpandedRowModel,
ColumnDef,
flexRender,
} from '@tanstack/react-table';
import { Canon } from '@sillsdev/scripture';
import { faker } from '@faker-js/faker';

import './basic-list.component.scss';

export const TAB_TYPE_BASIC_LIST = 'basic-list';

type CheckResult = {
book: string;
chapter?: number;
verse?: number;
issueDescription: string;
subRows?: CheckResult[];
};

const newCheckResult = (bookId: string): CheckResult => ({
book: Canon.bookIdToEnglishName(bookId),
chapter: faker.number.int(40),
verse: faker.number.int(40),
issueDescription: 'Basic check issue description',
});

const makeMockCheckResults = () => {
return Canon.allBookIds.map((bookId) => {
const numberOfIssues: number = faker.number.int({ min: 1, max: 10 });
const bookResults: CheckResult = {
book: Canon.bookIdToEnglishName(bookId),
issueDescription: `${numberOfIssues} issues`,
};
const subResults: CheckResult[] = [];
for (let i = 0; i < numberOfIssues; i++) {
subResults.push(newCheckResult(bookId));
}
bookResults.subRows = subResults;
return bookResults;
});
};

const columns: ColumnDef<CheckResult>[] = [
{
header: 'Scripture reference',
columns: [
{
accessorKey: 'book',
header: ({ table }) => (
<>
<button type="button" onClick={table.getToggleAllRowsExpandedHandler()}>
{table.getIsAllRowsExpanded() ? '⬇️' : '➡️'}
</button>{' '}
Book
</>
),
cell: ({ row, getValue }) => (
<div
style={{
paddingLeft: `${row.depth * 2}rem`,
}}
>
{row.getCanExpand() && (
<button
className="basic-list-expand-button"
type="button"
onClick={row.getToggleExpandedHandler()}
>
{row.getIsExpanded() ? '⬇️' : '➡️'}
</button>
)}{' '}
{getValue()}
</div>
),
},
{
accessorFn: (row) => row.chapter,
id: 'chapter',
cell: (info) => info.getValue(),
header: ({ table }) => <> {table.getIsSomeRowsExpanded() && <span>Chapter</span>} </>,
},
{
accessorFn: (row) => row.verse,
id: 'verse',
cell: (info) => info.getValue(),
header: ({ table }) => <> {table.getIsSomeRowsExpanded() && <span>Verse</span>} </>,
},
],
},
{
header: 'Issue',
columns: [
{
accessorKey: 'issueDescription',
header: () => 'Description',
footer: (props) => props.column.id,
},
],
},
];

export default function BasicList() {
const [expanded, setExpanded] = useState<ExpandedState>({});
const [data] = useState(() => makeMockCheckResults());
const table = useReactTable({
data,
columns,
state: {
expanded,
},
onExpandedChange: setExpanded,
getSubRows: (row) => row.subRows,
getCoreRowModel: getCoreRowModel(),
getExpandedRowModel: getExpandedRowModel(),
});

return (
<div className="basic-list-table">
<table>
<thead className="table-header">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<th key={header.id} colSpan={header.colSpan}>
{header.isPlaceholder ? null : (
<div>{flexRender(header.column.columnDef.header, header.getContext())}</div>
)}
</th>
);
})}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => {
return (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => {
return (
<td key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
</div>
);
}

export function loadBasicListTab(savedTabInfo: SavedTabInfo): TabInfo {
return {
...savedTabInfo,
tabTitle: 'Basic List',
content: <BasicList />,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ import {
TAB_TYPE_RUN_BASIC_CHECKS,
loadRunBasicChecksTab,
} from '@renderer/components/run-basic-checks-dialog/run-basic-checks-tab.component';
import {
TAB_TYPE_BASIC_LIST,
loadBasicListTab,
} from '@renderer/components/basic-list/basic-list.component';
import { hasDialogRequest, resolveDialogRequest } from '@renderer/services/dialog.service-host';
import { DialogData } from '@shared/models/dialog-options.model';
import DIALOGS from '@renderer/components/dialogs';
Expand Down Expand Up @@ -109,6 +113,7 @@ const tabLoaderMap = new Map<TabType, TabLoader>([
[TAB_TYPE_OPEN_MULTIPLE_PROJECTS_DIALOG, loadOpenMultipleProjectsTab],
[TAB_TYPE_EXTENSION_MANAGER, loadExtensionManagerTab],
[TAB_TYPE_RUN_BASIC_CHECKS, loadRunBasicChecksTab],
[TAB_TYPE_BASIC_LIST, loadBasicListTab],
...Object.entries(DIALOGS).map(
([dialogTabType, dialogDefinition]) =>
// The default implementation of `loadDialog` uses `this`, so bind it to the definition
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/testing/test-layout.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { TAB_TYPE_TEST } from '@renderer/testing/test-panel.component';
// import { TAB_TYPE_OPEN_MULTIPLE_PROJECTS_DIALOG } from '@renderer/components/project-dialogs/open-multiple-projects-tab.component';
// import { TAB_TYPE_EXTENSION_MANAGER } from '@renderer/components/extension-manager/extension-manager-tab.component';
import { TAB_TYPE_RUN_BASIC_CHECKS } from '@renderer/components/run-basic-checks-dialog/run-basic-checks-tab.component';
import { TAB_TYPE_BASIC_LIST } from '@renderer/components/basic-list/basic-list.component';

export const FIRST_TAB_ID = 'About';

Expand All @@ -31,6 +32,9 @@ const testLayout: LayoutBase = {
{
tabs: [{ id: 'Test Buttons', tabType: TAB_TYPE_BUTTONS }] as SavedTabInfo[],
},
{
tabs: [{ id: 'Basic List', tabType: TAB_TYPE_BASIC_LIST }] as SavedTabInfo[],
},
],
},
floatbox: {
Expand Down

0 comments on commit fcd26c6

Please sign in to comment.