Skip to content

Commit

Permalink
feat: basic styling for config viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
johnflank committed Mar 18, 2022
1 parent 36d1dc8 commit d1c9d27
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 47 deletions.
11 changes: 7 additions & 4 deletions src/pages/config/columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ export function TagsCell({ row, column }) {
<div className="flex">
{tags?.length > 0 ? (
tags.map((tag) => (
<div className="border rounded-md" key={tag}>
<div
className="bg-gray-200 px-1 py-0.5 mr-1 rounded-md text-gray-600 font-semibold text-xs"
key={tag}
>
{tag}
</div>
))
) : (
<span>no tags</span>
<span className="text-gray-400">none</span>
)}
</div>
);
Expand All @@ -20,8 +23,8 @@ export function TagsCell({ row, column }) {
export function DateCell({ row, column }) {
const dateString = row?.values[column.id];
return (
<div className="">
{dateString ? dayjs(dateString).format("MMM DD HH:mm") : "None"}
<div className="text-xs">
{dateString ? dayjs(dateString).format("h:mm A, DD-MM-YYYY") : "None"}
</div>
);
}
10 changes: 6 additions & 4 deletions src/pages/config/config-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ import { useNavigate, useParams } from "react-router-dom";
import { SearchLayout } from "../../components/Layout";
import jsonString from "../../data/sampleConfig.json";

const mockName = "package.json"; // TODO: get actual name from API call

export function ConfigDetailsPage() {
const { id } = useParams();
const navigate = useNavigate();

return (
<SearchLayout title={`Config Details for ${id}`}>
<SearchLayout title={`Config Details for ${mockName}`}>
<div className="flex flex-col items-start">
<button
className="border rounded-md px-4 py-2"
className="border rounded-md px-3 py-1 text-sm"
type="button"
onClick={() => navigate("/config")}
>
Back to list
Back
</button>
<textarea
readOnly
className="w-full text-sm mt-2"
className="w-full text-xs mt-2 rounded-md border-gray-300"
contentEditable={false}
style={{ minHeight: "700px", fontFamily: "monospace" }}
value={JSON.stringify(jsonString, undefined, 4)}
Expand Down
121 changes: 82 additions & 39 deletions src/pages/config/config-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@ import { DateCell, TagsCell } from "./columns";
const sampleRow = {
type: "Type",
name: "package.json",
tags: ["tag1", "tag2", "tag3"],
tags: null,
id: 12345,
created_at: `${new Date()}`,
updated_at: `${new Date()}`
};

const tableStyles = {
outerDivClass: "border border-b-0 border-gray-300",
tableClass: "min-w-full border-separate",
theadClass: "bg-white z-10",
theadRowClass: "z-10",
theadHeaderClass:
"px-5 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider border-b border-gray-300",
tbodyClass: "rounded-md",
tbodyRowClass: "border cursor-pointer text-sm",
tbodyDataClass: "whitespace-nowrap border-gray-300 border-b p-2"
};

export function ConfigListPage() {
const data = React.useMemo(() => [...Array(10).fill(sampleRow)], []);
const navigate = useNavigate();
Expand All @@ -22,30 +34,36 @@ export function ConfigListPage() {
() => [
{
Header: "Type",
accessor: "type"
accessor: "type",
cellClass: `px-5 py-2`
},
{
Header: "Name",
accessor: "name"
accessor: "name",
cellClass: `px-5 py-2`
},
{
Header: "Tags",
accessor: "tags",
Cell: TagsCell
Cell: TagsCell,
cellClass: `px-5 py-2`
},
{
Header: "ID",
accessor: "id"
accessor: "id",
cellClass: `px-5 py-2`
},
{
Header: "Created",
accessor: "created_at",
Cell: DateCell
Cell: DateCell,
cellClass: `px-5 py-2`
},
{
Header: "Last Updated",
accessor: "updated_at",
Cell: DateCell
Cell: DateCell,
cellClass: `px-5 py-2`
}
],
[]
Expand All @@ -59,56 +77,81 @@ export function ConfigListPage() {
};

return (
<SearchLayout title="Config Viewer">
<SearchLayout title="Config List">
<ConfigListTable
columns={columns}
data={data}
handleRowClick={handleRowClick}
tableStyle={{ borderSpacing: "0" }}
/>
</SearchLayout>
);
}

const ConfigListTable = ({ columns, data, handleRowClick }) => {
const ConfigListTable = ({
columns,
data,
handleRowClick,
tableStyle,
...rest
}) => {
const tableInstance = useTable({ columns, data });

const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
tableInstance;

return (
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr
key={headerGroup.getHeaderGroupProps().key}
{...headerGroup.getHeaderGroupProps()}
>
{headerGroup.headers.map((column) => (
<th key={column.Header} {...column.getHeaderProps()}>
{column.render("Header")}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<div className={tableStyles.outerDivClass} {...rest}>
<table
className={tableStyles.tableClass}
style={tableStyle}
{...getTableProps()}
>
<thead className={tableStyles.theadClass}>
{headerGroups.map((headerGroup) => (
<tr
key={row.id}
{...row.getRowProps()}
onClick={handleRowClick ? () => handleRowClick(row) : () => {}}
key={headerGroup.getHeaderGroupProps().key}
className={tableStyles.theadRowClass}
{...headerGroup.getHeaderGroupProps()}
>
{row.cells.map((cell) => (
<td key={cell.column.Header} {...cell.getCellProps()}>
{cell.render("Cell")}
</td>
{headerGroup.headers.map((column) => (
<th
key={column.Header}
className={tableStyles.theadHeaderClass}
{...column.getHeaderProps()}
>
{column.render("Header")}
</th>
))}
</tr>
);
})}
</tbody>
</table>
))}
</thead>
<tbody className={tableStyles.tbodyClass} {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<tr
key={row.id}
className={tableStyles.tbodyRowClass}
{...row.getRowProps()}
onClick={handleRowClick ? () => handleRowClick(row) : () => {}}
>
{row.cells.map((cell) => (
<td
key={cell.column.Header}
className={`${tableStyles.tbodyDataClass} ${
cell.column.cellClass || ""
}`}
{...cell.getCellProps()}
>
{cell.render("Cell")}
</td>
))}
</tr>
);
})}
</tbody>
</table>
</div>
);
};

0 comments on commit d1c9d27

Please sign in to comment.