Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Create basic table component #3

Merged
merged 25 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-07-01T02:04:44.570Z\n"
"PO-Revision-Date: 2024-07-01T02:04:44.570Z\n"
"POT-Creation-Date: 2024-07-10T13:58:01.688Z\n"
"PO-Revision-Date: 2024-07-10T13:58:01.688Z\n"

msgid "Low"
msgstr ""
Expand All @@ -32,10 +32,14 @@ msgstr ""
msgid "Within a province with more than one district affected"
msgstr ""

msgid "More than one province affected with high threat of spread locally and internationally"
msgid ""
"More than one province affected with high threat of spread locally and "
"internationally"
msgstr ""

msgid "Available within the district with support from provincial and national level"
msgid ""
"Available within the district with support from provincial and national "
"level"
msgstr ""

msgid "Available within the province with minimal support from national level"
Expand Down
2 changes: 1 addition & 1 deletion i18n/es.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: i18next-conv\n"
"POT-Creation-Date: 2024-07-01T02:04:44.570Z\n"
"POT-Creation-Date: 2024-07-10T13:58:01.688Z\n"
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down
97 changes: 97 additions & 0 deletions src/webapp/components/table/BasicTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from "react";
import { Table, TableBody, TableCell, TableHead, TableRow } from "@material-ui/core";
import styled from "styled-components";
import { Maybe } from "../../../utils/ts-utils";
import i18n from "../../../utils/i18n";
import { Option } from "../utils/option";
import { Cell } from "./Cell";

const noop = () => {};

interface BaseColumn {
value: string;
label: string;
}
interface TextColumn extends BaseColumn {
type: "text";
underline?: boolean;
bold?: boolean;
}
interface LinkColumn extends BaseColumn {
type: "link";
}
interface SelectorColumn extends BaseColumn {
type: "selector";
options: Option[];
}

export type TableColumn = TextColumn | LinkColumn | SelectorColumn;
interface BasicTableProps {
columns: TableColumn[];
rows: {
[key: TableColumn["value"]]: string;
}[];
onChange?: (cell: Maybe<string>, rowIndex: number, column: TableColumn["value"]) => void;
showRowIndex?: boolean;
}

export const BasicTable: React.FC<BasicTableProps> = React.memo(
({ columns, rows, onChange = noop, showRowIndex = false }) => {
return (
<StyledTable stickyHeader>
<TableHead>
delemaf marked this conversation as resolved.
Show resolved Hide resolved
<TableRow>
{showRowIndex && <TableCell />}
{columns.map(({ value, label }) => (
<TableCell key={value}>{i18n.t(label)}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{showRowIndex && <IndexTableCell>{rowIndex + 1}</IndexTableCell>}
{columns.map(column => (
<Cell
key={`${rowIndex}-${column.value}`}
value={row[column.value] || ""}
rowIndex={rowIndex}
column={column}
onChange={onChange}
/>
))}
</TableRow>
))}
</TableBody>
</StyledTable>
);
}
);

const StyledTable = styled(Table)`
border-collapse: collapse;
& .MuiTableHead-root {
color: ${props => props.theme.palette.common.grey1};
font-weight: 600;
height: 2.25rem;
& .MuiTableCell-root {
white-space: nowrap;
background-color: ${props => props.theme.palette.common.greyLight};
}
}
& .MuiTableBody-root {
color: ${props => props.theme.palette.common.grey};
}
& .MuiTableCell-root {
font-size: 0.75rem;
padding-block: 0.375rem;
border: 1px solid ${props => props.theme.palette.common.grey4};
height: 1.875rem;
}
`;

const IndexTableCell = styled(TableCell)`
min-width: 2.25rem;
padding-inline: 0.375rem;
text-align: center;
`;
67 changes: 67 additions & 0 deletions src/webapp/components/table/Cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useCallback } from "react";
import { TableCell, Link } from "@material-ui/core";
import styled from "styled-components";
import { Selector } from "../selector/Selector";
import { TableColumn } from "./BasicTable";

const noop = () => {};

type CellProps = {
value: string;
rowIndex: number;
column: TableColumn;
onChange?: (value: string, rowIndex: number, column: TableColumn["value"]) => void;
};

export const Cell: React.FC<CellProps> = React.memo(
({ value, rowIndex, column, onChange = noop }) => {
const [selectorValue, setSelectorValue] = React.useState<string>(value);
const handleChange = useCallback(
(value: string) => {
setSelectorValue(value);
onChange(value, rowIndex, column.value);
},
[onChange, rowIndex, column.value]
);

switch (column.type) {
case "link":
return (
<StyledTableCell>
<StyledLink onClick={() => onChange(value, rowIndex, column.value)}>
{value}
</StyledLink>
</StyledTableCell>
);
case "selector":
return (
<StyledTableCell>
<Selector
id={`selector-${rowIndex}-${column.value}`}
options={column.options}
selected={selectorValue}
onChange={handleChange}
/>
</StyledTableCell>
);
case "text":
default:
return (
<StyledTableCell $underline={column.underline} $bold={column.bold}>
{value}
</StyledTableCell>
);
}
}
);

const StyledTableCell = styled(TableCell)<{ $underline?: boolean; $bold?: boolean }>`
text-decoration: ${props => (props.$underline ? "underline" : "initial")};
font-weight: ${props => (props.$bold ? 700 : 400)};
`;

const StyledLink = styled(Link)`
color: ${props => props.theme.palette.common.blue600};
text-decoration: underline;
cursor: pointer;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import React from "react";
import i18n from "../../../utils/i18n";
import { Layout } from "../../components/layout/Layout";

// TODO: Add every section here, first it's just an example

export const IncidentActionPlanPage: React.FC = React.memo(() => {
return (
<Layout
Expand Down
Loading