Skip to content

Commit

Permalink
Update time column in inputs table to show date in age or UTC format (#…
Browse files Browse the repository at this point in the history
…74)

Co-authored-by: nevendiulgerov <[email protected]>
  • Loading branch information
nevendyulgerov authored Nov 29, 2023
1 parent 99b06a6 commit 43cf277
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 55 deletions.
24 changes: 4 additions & 20 deletions apps/web/src/app/applications/[address]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
Pagination,
Select,
Stack,
Table,
Text,
Title,
} from "@mantine/core";
Expand All @@ -16,12 +15,12 @@ import { pathOr } from "ramda";
import { FC, useEffect, useState } from "react";
import { TbInbox } from "react-icons/tb";
import Address from "../../../components/address";
import InputRow from "../../../components/inputRow";
import { InputOrderByInput, useInputsQuery } from "../../../graphql";
import {
limitBounds,
usePaginationParams,
} from "../../../hooks/usePaginationParams";
import InputsTable from "../../../components/inputsTable";

export type ApplicationPageProps = {
params: { address: string };
Expand All @@ -42,6 +41,7 @@ const ApplicationPage: FC<ApplicationPageProps> = ({ params }) => {
const [activePage, setActivePage] = useState(
page > totalPages ? totalPages : page,
);
const inputs = data?.inputsConnection.edges.map((edge) => edge.node) ?? [];
const { scrollIntoView, targetRef } = useScrollIntoView<HTMLDivElement>({
duration: 700,
offset: 150,
Expand Down Expand Up @@ -82,24 +82,8 @@ const ApplicationPage: FC<ApplicationPageProps> = ({ params }) => {
updateParams(pageN, limit);
}}
/>
<Table>
<Table.Thead>
<Table.Tr>
<Table.Th>From</Table.Th>
<Table.Th></Table.Th>
<Table.Th>To</Table.Th>
<Table.Th>Method</Table.Th>
<Table.Th>Index</Table.Th>
<Table.Th>Age</Table.Th>
<Table.Th>Data</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{data?.inputsConnection.edges.map(({ node: input }) => (
<InputRow key={input.id} input={input} />
))}
</Table.Tbody>
</Table>

<InputsTable inputs={inputs} />

<Group justify="space-between" align="center">
<Group>
Expand Down
31 changes: 5 additions & 26 deletions apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,16 @@ import {
Pagination,
Select,
Stack,
Table,
Text,
Title,
} from "@mantine/core";
import { FC, useEffect, useState } from "react";
import { TbInbox } from "react-icons/tb";

import { useScrollIntoView } from "@mantine/hooks";
import { pathOr } from "ramda";
import InputRow from "../components/inputRow";
import {
InputOrderByInput,
useInputsQuery,
useStatsQuery,
} from "../graphql/index";
import { InputOrderByInput, useInputsQuery, useStatsQuery } from "../graphql";
import { limitBounds, usePaginationParams } from "../hooks/usePaginationParams";
import InputsTable from "../components/inputsTable";

const Explorer: FC = (props) => {
const [{ limit, page }, updateParams] = usePaginationParams();
Expand All @@ -40,6 +34,7 @@ const Explorer: FC = (props) => {
const [activePage, setActivePage] = useState(
page > totalPages ? totalPages : page,
);
const inputs = data?.inputsConnection.edges.map((edge) => edge.node) ?? [];

const { scrollIntoView, targetRef } = useScrollIntoView<HTMLDivElement>({
duration: 700,
Expand Down Expand Up @@ -82,24 +77,8 @@ const Explorer: FC = (props) => {
updateParams(pageN, limit);
}}
/>
<Table>
<Table.Thead>
<Table.Tr>
<Table.Th>From</Table.Th>
<Table.Th></Table.Th>
<Table.Th>To</Table.Th>
<Table.Th>Method</Table.Th>
<Table.Th>Index</Table.Th>
<Table.Th>Age</Table.Th>
<Table.Th>Data</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{data?.inputsConnection.edges.map(({ node: input }) => (
<InputRow key={input.id} input={input} />
))}
</Table.Tbody>
</Table>

<InputsTable inputs={inputs} />

<Group justify="space-between" align="center">
<Group>
Expand Down
24 changes: 15 additions & 9 deletions apps/web/src/components/inputRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import { InputItemFragment } from "../graphql";
import Address from "./address";
import InputDetailsView from "./inputDetailsView";

export type InputCardProps = {
export type InputRowProps = {
input: InputItemFragment;
timeType: string;
};

export type MethodResolver = (
Expand All @@ -32,14 +33,8 @@ const methodResolver: MethodResolver = (input) => {
return undefined;
};

const InputRow: FC<InputCardProps> = ({ input }) => {
const InputRow: FC<InputRowProps> = ({ input, timeType }) => {
const [opened, { toggle }] = useDisclosure(false);
const age = prettyMilliseconds(Date.now() - input.timestamp * 1000, {
unitCount: 2,
secondsDecimalDigits: 0,
verbose: true,
});

const from = input.msgSender as AddressType;
const to = input.application.id as AddressType;

Expand Down Expand Up @@ -98,7 +93,18 @@ const InputRow: FC<InputCardProps> = ({ input }) => {
<Text>{input.index}</Text>
</Table.Td>
<Table.Td>
<Text>{age} ago</Text>
<Text>
{timeType === "age"
? `${prettyMilliseconds(
Date.now() - input.timestamp * 1000,
{
unitCount: 2,
secondsDecimalDigits: 0,
verbose: true,
},
)} ago`
: new Date(input.timestamp * 1000).toISOString()}
</Text>
</Table.Td>
<Table.Td>
<ActionIcon variant="default" onClick={toggle}>
Expand Down
52 changes: 52 additions & 0 deletions apps/web/src/components/inputsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"use client";
import { Button, Table } from "@mantine/core";
import { FC, useCallback, useState } from "react";
import InputRow from "../components/inputRow";
import type { InputItemFragment } from "../graphql";

export interface InputsTableProps {
inputs: InputItemFragment[];
}

const InputsTable: FC<InputsTableProps> = ({ inputs }) => {
const [timeType, setTimeType] = useState("age");

const onChangeTimeColumnType = useCallback(() => {
setTimeType((timeType) => (timeType === "age" ? "timestamp" : "age"));
}, []);

return (
<Table>
<Table.Thead>
<Table.Tr>
<Table.Th>From</Table.Th>
<Table.Th></Table.Th>
<Table.Th>To</Table.Th>
<Table.Th>Method</Table.Th>
<Table.Th>Index</Table.Th>
<Table.Th>
<Button
variant="transparent"
px={0}
onClick={onChangeTimeColumnType}
>
{timeType === "age" ? "Age" : "Timestamp (UTC)"}
</Button>
</Table.Th>
<Table.Th>Data</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{inputs.map((input) => (
<InputRow
key={input.id}
input={input}
timeType={timeType}
/>
))}
</Table.Tbody>
</Table>
);
};

export default InputsTable;
59 changes: 59 additions & 0 deletions apps/web/test/components/inputRow.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { describe, it } from "vitest";
import type { FC } from "react";
import { render, screen } from "@testing-library/react";
import InputRow, { InputRowProps } from "../../src/components/inputRow";
import { withMantineTheme } from "../utils/WithMantineTheme";
import { Table } from "@mantine/core";
import prettyMilliseconds from "pretty-ms";

const TableComponent: FC<InputRowProps> = (props) => (
<Table>
<Table.Tbody>
<InputRow {...props} />
</Table.Tbody>
</Table>
);

const Component = withMantineTheme(TableComponent);

const defaultProps: InputRowProps = {
input: {
id: "0xdb84080e7d2b4654a7e384de851a6cf7281643de-1",
application: {
id: "0xdb84080e7d2b4654a7e384de851a6cf7281643de",
},
index: 1,
payload: "0x68656c6c6f2032",
msgSender: "0x8a12cf75000cd2e73ab16469826838d5f137f444",
timestamp: 1700593992,
transactionHash:
"0x4ad73b8f46dc16bc27d75b3f8f584e8785a8cb6fdf97a6c2a5a5dcfbda3e75c0",
erc20Deposit: null,
},
timeType: "age",
};

describe("InputRow component", () => {
it("should display correct age", () => {
render(<Component {...defaultProps} />);

const age = `${prettyMilliseconds(
Date.now() - defaultProps.input.timestamp * 1000,
{
unitCount: 2,
secondsDecimalDigits: 0,
verbose: true,
},
)} ago`;
expect(screen.getByText(age)).toBeInTheDocument();
});

it("should display correct timestamp in UTC format", () => {
render(<Component input={defaultProps.input} timeType="timestamp" />);

const timestamp = new Date(
defaultProps.input.timestamp * 1000,
).toISOString();
expect(screen.getByText(timestamp)).toBeInTheDocument();
});
});
42 changes: 42 additions & 0 deletions apps/web/test/components/inputsTable.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { describe, it } from "vitest";
import { fireEvent, render, screen } from "@testing-library/react";
import InputsTable, {
InputsTableProps,
} from "../../src/components/inputsTable";
import { withMantineTheme } from "../utils/WithMantineTheme";

const Component = withMantineTheme(InputsTable);

const defaultProps: InputsTableProps = {
inputs: [
{
id: "0xdb84080e7d2b4654a7e384de851a6cf7281643de-1",
application: {
id: "0xdb84080e7d2b4654a7e384de851a6cf7281643de",
},
index: 1,
payload: "0x68656c6c6f2032",
msgSender: "0x8a12cf75000cd2e73ab16469826838d5f137f444",
timestamp: 1700593992,
transactionHash:
"0x4ad73b8f46dc16bc27d75b3f8f584e8785a8cb6fdf97a6c2a5a5dcfbda3e75c0",
erc20Deposit: null,
},
],
};

describe("InputsTable component", () => {
it("should display time column with age label", () => {
render(<Component {...defaultProps} />);
expect(screen.getByText("Age")).toBeInTheDocument();
});

it("should display time column with timestamp label", () => {
render(<Component {...defaultProps} />);

const timeTypeButton = screen.getByText("Age");
fireEvent.click(timeTypeButton);

expect(screen.getByText("Timestamp (UTC)")).toBeInTheDocument();
});
});

2 comments on commit 43cf277

@vercel
Copy link

@vercel vercel bot commented on 43cf277 Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 43cf277 Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

rollups-explorer-workshop – ./apps/workshop

rollups-explorer-workshop-cartesi.vercel.app
rollups-explorer-workshop-git-main-cartesi.vercel.app
rollups-explorer-workshop.vercel.app

Please sign in to comment.