From 146be445f970c5e61a28f69f562165cb013edfb6 Mon Sep 17 00:00:00 2001
From: poomthiti
Date: Fri, 13 Jan 2023 00:35:05 +0700
Subject: [PATCH 1/6] feat: proposal table ui and wireup
---
src/lib/data/queries.ts | 40 +++
src/lib/gql/gql.ts | 10 +
src/lib/gql/graphql.ts | 311 ++++++++++++++++++
src/lib/model/contract.ts | 5 +
.../tables/migration/MigrationHeader.tsx | 26 +-
.../tables/migration/MigrationRow.tsx | 40 +--
.../RelatedProposalsHeader.tsx | 22 ++
.../related-proposals/RelatedProposalsRow.tsx | 106 ++++++
.../tables/related-proposals/StatusChip.tsx | 43 +++
.../tables/related-proposals/index.tsx | 91 +++++
src/lib/pages/contract-details/index.tsx | 24 +-
src/lib/services/contractService.ts | 63 ++++
src/lib/types/contract.ts | 29 ++
13 files changed, 760 insertions(+), 50 deletions(-)
create mode 100644 src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsHeader.tsx
create mode 100644 src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx
create mode 100644 src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx
create mode 100644 src/lib/pages/contract-details/components/tables/related-proposals/index.tsx
diff --git a/src/lib/data/queries.ts b/src/lib/data/queries.ts
index 35b730f2f..403cdd79a 100644
--- a/src/lib/data/queries.ts
+++ b/src/lib/data/queries.ts
@@ -158,6 +158,46 @@ export const getMigrationHistoriesCountByContractAddress = graphql(`
}
`);
+export const getRelatedProposalsByContractAddress = graphql(`
+ query getRelatedProposalsByContractAddress(
+ $contractAddress: String!
+ $offset: Int!
+ $pageSize: Int!
+ ) {
+ contract_proposals(
+ where: { contract: { address: { _eq: $contractAddress } } }
+ order_by: { proposal_id: desc }
+ offset: $offset
+ limit: $pageSize
+ ) {
+ proposal {
+ title
+ status
+ voting_end_time
+ deposit_end_time
+ type
+ account {
+ address
+ }
+ }
+ proposal_id
+ resolved_height
+ }
+ }
+`);
+
+export const getRelatedProposalsCountByContractAddress = graphql(`
+ query getRelatedProposalsCountByContractAddress($contractAddress: String!) {
+ contract_proposals_aggregate(
+ where: { contract: { address: { _eq: $contractAddress } } }
+ ) {
+ aggregate {
+ count
+ }
+ }
+ }
+`);
+
export const getContractListByCodeId = graphql(`
query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {
contracts(
diff --git a/src/lib/gql/gql.ts b/src/lib/gql/gql.ts
index 6e6456554..4c9f4de31 100644
--- a/src/lib/gql/gql.ts
+++ b/src/lib/gql/gql.ts
@@ -21,6 +21,10 @@ const documents = {
types.GetMigrationHistoriesByContractAddressDocument,
"\n query getMigrationHistoriesCountByContractAddress($contractAddress: String!) {\n contract_histories_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n":
types.GetMigrationHistoriesCountByContractAddressDocument,
+ "\n query getRelatedProposalsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_proposals(\n where: { contract: { address: { _eq: $contractAddress } } }\n order_by: { proposal_id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n proposal {\n title\n status\n voting_end_time\n deposit_end_time\n type\n account {\n address\n }\n }\n proposal_id\n resolved_height\n }\n }\n":
+ types.GetRelatedProposalsByContractAddressDocument,
+ "\n query getRelatedProposalsCountByContractAddress($contractAddress: String!) {\n contract_proposals_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n":
+ types.GetRelatedProposalsCountByContractAddressDocument,
"\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n":
types.GetContractListByCodeIdDocument,
"\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n":
@@ -56,6 +60,12 @@ export function graphql(
export function graphql(
source: "\n query getMigrationHistoriesCountByContractAddress($contractAddress: String!) {\n contract_histories_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n"
): typeof documents["\n query getMigrationHistoriesCountByContractAddress($contractAddress: String!) {\n contract_histories_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n"];
+export function graphql(
+ source: "\n query getRelatedProposalsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_proposals(\n where: { contract: { address: { _eq: $contractAddress } } }\n order_by: { proposal_id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n proposal {\n title\n status\n voting_end_time\n deposit_end_time\n type\n account {\n address\n }\n }\n proposal_id\n resolved_height\n }\n }\n"
+): typeof documents["\n query getRelatedProposalsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_proposals(\n where: { contract: { address: { _eq: $contractAddress } } }\n order_by: { proposal_id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n proposal {\n title\n status\n voting_end_time\n deposit_end_time\n type\n account {\n address\n }\n }\n proposal_id\n resolved_height\n }\n }\n"];
+export function graphql(
+ source: "\n query getRelatedProposalsCountByContractAddress($contractAddress: String!) {\n contract_proposals_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n"
+): typeof documents["\n query getRelatedProposalsCountByContractAddress($contractAddress: String!) {\n contract_proposals_aggregate(\n where: { contract: { address: { _eq: $contractAddress } } }\n ) {\n aggregate {\n count\n }\n }\n }\n"];
export function graphql(
source: "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"
): typeof documents["\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"];
diff --git a/src/lib/gql/graphql.ts b/src/lib/gql/graphql.ts
index 31442f753..90548cc9c 100644
--- a/src/lib/gql/graphql.ts
+++ b/src/lib/gql/graphql.ts
@@ -6392,6 +6392,45 @@ export type GetMigrationHistoriesCountByContractAddressQuery = {
};
};
+export type GetRelatedProposalsByContractAddressQueryVariables = Exact<{
+ contractAddress: Scalars["String"];
+ offset: Scalars["Int"];
+ pageSize: Scalars["Int"];
+}>;
+
+export type GetRelatedProposalsByContractAddressQuery = {
+ __typename?: "query_root";
+ contract_proposals: Array<{
+ __typename?: "contract_proposals";
+ proposal_id: number;
+ resolved_height?: number | null;
+ proposal: {
+ __typename?: "proposals";
+ title: string;
+ status: any;
+ voting_end_time: any;
+ deposit_end_time: any;
+ type: string;
+ account?: { __typename?: "accounts"; address: string } | null;
+ };
+ }>;
+};
+
+export type GetRelatedProposalsCountByContractAddressQueryVariables = Exact<{
+ contractAddress: Scalars["String"];
+}>;
+
+export type GetRelatedProposalsCountByContractAddressQuery = {
+ __typename?: "query_root";
+ contract_proposals_aggregate: {
+ __typename?: "contract_proposals_aggregate";
+ aggregate?: {
+ __typename?: "contract_proposals_aggregate_fields";
+ count: number;
+ } | null;
+ };
+};
+
export type GetContractListByCodeIdQueryVariables = Exact<{
codeId: Scalars["Int"];
offset: Scalars["Int"];
@@ -7625,6 +7664,278 @@ export const GetMigrationHistoriesCountByContractAddressDocument = {
GetMigrationHistoriesCountByContractAddressQuery,
GetMigrationHistoriesCountByContractAddressQueryVariables
>;
+export const GetRelatedProposalsByContractAddressDocument = {
+ kind: "Document",
+ definitions: [
+ {
+ kind: "OperationDefinition",
+ operation: "query",
+ name: { kind: "Name", value: "getRelatedProposalsByContractAddress" },
+ variableDefinitions: [
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "contractAddress" },
+ },
+ type: {
+ kind: "NonNullType",
+ type: {
+ kind: "NamedType",
+ name: { kind: "Name", value: "String" },
+ },
+ },
+ },
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "offset" },
+ },
+ type: {
+ kind: "NonNullType",
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } },
+ },
+ },
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "pageSize" },
+ },
+ type: {
+ kind: "NonNullType",
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } },
+ },
+ },
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "contract_proposals" },
+ arguments: [
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "where" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "contract" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "address" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_eq" },
+ value: {
+ kind: "Variable",
+ name: {
+ kind: "Name",
+ value: "contractAddress",
+ },
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "order_by" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "proposal_id" },
+ value: { kind: "EnumValue", value: "desc" },
+ },
+ ],
+ },
+ },
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "offset" },
+ value: {
+ kind: "Variable",
+ name: { kind: "Name", value: "offset" },
+ },
+ },
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "limit" },
+ value: {
+ kind: "Variable",
+ name: { kind: "Name", value: "pageSize" },
+ },
+ },
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "proposal" },
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ { kind: "Field", name: { kind: "Name", value: "title" } },
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "status" },
+ },
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "voting_end_time" },
+ },
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "deposit_end_time" },
+ },
+ { kind: "Field", name: { kind: "Name", value: "type" } },
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "account" },
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "address" },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ { kind: "Field", name: { kind: "Name", value: "proposal_id" } },
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "resolved_height" },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ ],
+} as unknown as DocumentNode<
+ GetRelatedProposalsByContractAddressQuery,
+ GetRelatedProposalsByContractAddressQueryVariables
+>;
+export const GetRelatedProposalsCountByContractAddressDocument = {
+ kind: "Document",
+ definitions: [
+ {
+ kind: "OperationDefinition",
+ operation: "query",
+ name: {
+ kind: "Name",
+ value: "getRelatedProposalsCountByContractAddress",
+ },
+ variableDefinitions: [
+ {
+ kind: "VariableDefinition",
+ variable: {
+ kind: "Variable",
+ name: { kind: "Name", value: "contractAddress" },
+ },
+ type: {
+ kind: "NonNullType",
+ type: {
+ kind: "NamedType",
+ name: { kind: "Name", value: "String" },
+ },
+ },
+ },
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "contract_proposals_aggregate" },
+ arguments: [
+ {
+ kind: "Argument",
+ name: { kind: "Name", value: "where" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "contract" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "address" },
+ value: {
+ kind: "ObjectValue",
+ fields: [
+ {
+ kind: "ObjectField",
+ name: { kind: "Name", value: "_eq" },
+ value: {
+ kind: "Variable",
+ name: {
+ kind: "Name",
+ value: "contractAddress",
+ },
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ ],
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ {
+ kind: "Field",
+ name: { kind: "Name", value: "aggregate" },
+ selectionSet: {
+ kind: "SelectionSet",
+ selections: [
+ { kind: "Field", name: { kind: "Name", value: "count" } },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ ],
+} as unknown as DocumentNode<
+ GetRelatedProposalsCountByContractAddressQuery,
+ GetRelatedProposalsCountByContractAddressQueryVariables
+>;
export const GetContractListByCodeIdDocument = {
kind: "Document",
definitions: [
diff --git a/src/lib/model/contract.ts b/src/lib/model/contract.ts
index 079384041..c3c6ec165 100644
--- a/src/lib/model/contract.ts
+++ b/src/lib/model/contract.ts
@@ -16,6 +16,7 @@ import {
useInstantiateDetailByContractQuery,
useInstantiatedListByUserQuery,
useMigrationHistoriesCountByContractAddress,
+ useRelatedProposalsCountByContractAddress,
} from "lib/services/contractService";
import type { CodeLocalInfo } from "lib/stores/code";
import type { ContractInfo, ContractListInfo } from "lib/stores/contract";
@@ -145,12 +146,16 @@ export const useContractDetailsTableCounts = (
useExecuteTxsCountByContractAddress(contractAddress);
const { data: migrationCount = 0, refetch: refetchMigration } =
useMigrationHistoriesCountByContractAddress(contractAddress);
+ const { data: relatedProposalsCount = 0, refetch: refetchRelatedProposals } =
+ useRelatedProposalsCountByContractAddress(contractAddress);
return {
tableCounts: {
executeCount,
migrationCount,
+ relatedProposalsCount,
},
refetchExecute,
refetchMigration,
+ refetchRelatedProposals,
};
};
diff --git a/src/lib/pages/contract-details/components/tables/migration/MigrationHeader.tsx b/src/lib/pages/contract-details/components/tables/migration/MigrationHeader.tsx
index 0a43aa201..a4baf3cb3 100644
--- a/src/lib/pages/contract-details/components/tables/migration/MigrationHeader.tsx
+++ b/src/lib/pages/contract-details/components/tables/migration/MigrationHeader.tsx
@@ -1,17 +1,7 @@
import type { GridProps } from "@chakra-ui/react";
-import { chakra, Grid, GridItem } from "@chakra-ui/react";
+import { Grid } from "@chakra-ui/react";
-const StyledGridItem = chakra(GridItem, {
- baseStyle: {
- color: "text.main",
- fontSize: "12px",
- fontWeight: 700,
- py: 6,
- px: 4,
- borderY: "1px solid",
- borderColor: "divider.main",
- },
-});
+import { TableHeader } from "lib/components/table";
export const MigrationHeader = ({
templateColumns,
@@ -20,12 +10,12 @@ export const MigrationHeader = ({
}) => {
return (
- Code ID
- Code Description
- Sender
- Block Height
- Timestamp
- Remark
+ Code ID
+ Code Description
+ Sender
+ Block Height
+ Timestamp
+ Remark
);
};
diff --git a/src/lib/pages/contract-details/components/tables/migration/MigrationRow.tsx b/src/lib/pages/contract-details/components/tables/migration/MigrationRow.tsx
index 17815c910..adec92999 100644
--- a/src/lib/pages/contract-details/components/tables/migration/MigrationRow.tsx
+++ b/src/lib/pages/contract-details/components/tables/migration/MigrationRow.tsx
@@ -1,25 +1,13 @@
import type { GridProps } from "@chakra-ui/react";
-import { chakra, Flex, Grid, GridItem, Text } from "@chakra-ui/react";
+import { Flex, Grid, Text } from "@chakra-ui/react";
import { ExplorerLink } from "lib/components/ExplorerLink";
+import { TableRow } from "lib/components/table";
import { useGetAddressType } from "lib/hooks";
import type { ContractMigrationHistory } from "lib/types";
import { RemarkOperation } from "lib/types";
import { dateFromNow, formatUTC } from "lib/utils";
-const StyledGridItem = chakra(GridItem, {
- baseStyle: {
- color: "text.main",
- fontSize: "14px",
- fontWeight: 400,
- p: 4,
- display: "flex",
- alignItems: "center",
- borderBottom: "1px solid",
- borderColor: "divider.main",
- },
-});
-
interface MigrationRowProps {
templateColumns: GridProps["templateColumns"];
history: ContractMigrationHistory;
@@ -64,34 +52,34 @@ export const MigrationRow = ({
const getAddressType = useGetAddressType();
return (
-
+
-
-
+
+
{history.codeDescription || (
No Description
)}
-
-
+
+
-
-
+
+
-
-
+
+
{formatUTC(history.timestamp)}
({dateFromNow(history.timestamp)})
-
-
+
+
-
+
);
};
diff --git a/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsHeader.tsx b/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsHeader.tsx
new file mode 100644
index 000000000..ef1524aef
--- /dev/null
+++ b/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsHeader.tsx
@@ -0,0 +1,22 @@
+import type { GridProps } from "@chakra-ui/react";
+import { Grid } from "@chakra-ui/react";
+
+import { TableHeader } from "lib/components/table";
+
+export const RelatedProposalsHeader = ({
+ templateColumns,
+}: {
+ templateColumns: GridProps["templateColumns"];
+}) => {
+ return (
+
+ Proposal ID
+ Proposal Title
+ Status
+ Vote Finish on
+ Resolve Block Height
+ Type
+ Proposer
+
+ );
+};
diff --git a/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx b/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx
new file mode 100644
index 000000000..60620abd8
--- /dev/null
+++ b/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx
@@ -0,0 +1,106 @@
+import type { GridProps } from "@chakra-ui/react";
+import { Flex, Grid, Text } from "@chakra-ui/react";
+
+import { ExplorerLink } from "lib/components/ExplorerLink";
+import { TableRow } from "lib/components/table";
+import { useGetAddressType } from "lib/hooks";
+import type { ContractRelatedProposals } from "lib/types";
+import { ProposalStatus } from "lib/types";
+import { dateFromNow, formatUTC } from "lib/utils";
+
+import { StatusChip } from "./StatusChip";
+
+interface RelatedProposalsRowProps {
+ proposal: ContractRelatedProposals;
+ templateColumns: GridProps["templateColumns"];
+}
+
+const VotingEndTimeRender = ({
+ votingEndTime,
+ depositEndTime,
+ status,
+}: {
+ votingEndTime: ContractRelatedProposals["votingEndTime"];
+ depositEndTime: ContractRelatedProposals["depositEndTime"];
+ status: ContractRelatedProposals["status"];
+}) => {
+ const isDepositPeriod = status === ProposalStatus.DEPOSIT_PERIOD;
+ return (
+ p:first-of-type": {
+ color: isDepositPeriod ? "text.dark" : "text.main",
+ mb: "2px",
+ },
+ "& > p:last-of-type": {
+ color: "text.dark",
+ fontSize: "12px",
+ },
+ }}
+ >
+ {isDepositPeriod ? "Voting not started" : formatUTC(votingEndTime)}
+
+ (
+ {isDepositPeriod
+ ? `Deposit Period ends in ${dateFromNow(depositEndTime)}`
+ : dateFromNow(votingEndTime)}
+ )
+
+
+ );
+};
+
+export const RelatedProposalsRow = ({
+ proposal,
+ templateColumns,
+}: RelatedProposalsRowProps) => {
+ const getAddressType = useGetAddressType();
+ return (
+
+
+
+
+ {proposal.title}
+
+
+
+
+
+
+
+ {proposal.resolvedHeight ? (
+
+ ) : (
+ Pending
+ )}
+
+
+ {proposal.type}
+
+
+ {proposal.proposer ? (
+
+ ) : (
+ "N/A"
+ )}
+
+
+ );
+};
diff --git a/src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx b/src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx
new file mode 100644
index 000000000..728e9d2c9
--- /dev/null
+++ b/src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx
@@ -0,0 +1,43 @@
+import { chakra, Tag } from "@chakra-ui/react";
+import type { CSSProperties } from "react";
+
+import type { ContractRelatedProposals } from "lib/types";
+import { ProposalStatus } from "lib/types";
+
+const StyledTag = chakra(Tag, {
+ baseStyle: {
+ borderRadius: "16px",
+ fontSize: "12px",
+ fontWeight: 400,
+ color: "text.main",
+ height: "24px",
+ w: "fit-content",
+ },
+});
+
+const getBgColor = (
+ status: ContractRelatedProposals["status"]
+): CSSProperties["backgroundColor"] => {
+ switch (status) {
+ case ProposalStatus.DEPOSIT_PERIOD:
+ return "#BA863A";
+ case ProposalStatus.FAILED:
+ case ProposalStatus.REJECTED:
+ return "#F2605B";
+ case ProposalStatus.PASSED:
+ return "#A1E58F";
+ case ProposalStatus.VOTING_PERIOD:
+ return "#0288D1";
+ case ProposalStatus.INACTIVE:
+ default:
+ return "rgba(173, 173, 173, 0.6)";
+ }
+};
+
+export const StatusChip = ({
+ status,
+}: {
+ status: ContractRelatedProposals["status"];
+}) => {
+ return {status};
+};
diff --git a/src/lib/pages/contract-details/components/tables/related-proposals/index.tsx b/src/lib/pages/contract-details/components/tables/related-proposals/index.tsx
new file mode 100644
index 000000000..afdea3f04
--- /dev/null
+++ b/src/lib/pages/contract-details/components/tables/related-proposals/index.tsx
@@ -0,0 +1,91 @@
+import { Flex } from "@chakra-ui/react";
+import type { ChangeEvent } from "react";
+
+import { NoTransactions } from "../NoTransactions";
+import { Pagination } from "lib/components/pagination";
+import { usePaginator } from "lib/components/pagination/usePaginator";
+import { useRelatedProposalsByContractAddress } from "lib/services/contractService";
+import type { ContractAddr } from "lib/types";
+
+import { RelatedProposalsHeader } from "./RelatedProposalsHeader";
+import { RelatedProposalsRow } from "./RelatedProposalsRow";
+
+interface RelatedProposalsTableProps {
+ contractAddress: ContractAddr;
+ scrollComponentId: string;
+ totalData: number;
+ refetchCount: () => void;
+}
+
+export const RelatedProposalsTable = ({
+ contractAddress,
+ scrollComponentId,
+ totalData,
+ refetchCount,
+}: RelatedProposalsTableProps) => {
+ const {
+ pagesQuantity,
+ currentPage,
+ setCurrentPage,
+ pageSize,
+ setPageSize,
+ offset,
+ } = usePaginator({
+ total: totalData,
+ initialState: {
+ pageSize: 10,
+ currentPage: 1,
+ isDisabled: false,
+ },
+ });
+
+ const { data: relatedProposals } = useRelatedProposalsByContractAddress(
+ contractAddress,
+ offset,
+ pageSize
+ );
+
+ const onPageChange = (nextPage: number) => {
+ refetchCount();
+ setCurrentPage(nextPage);
+ };
+
+ const onPageSizeChange = (e: ChangeEvent) => {
+ const size = Number(e.target.value);
+ refetchCount();
+ setPageSize(size);
+ setCurrentPage(1);
+ };
+
+ const templateColumns =
+ "100px minmax(300px, 1fr) 150px 330px 180px 140px 160px";
+
+ if (!relatedProposals?.length)
+ return (
+
+ );
+
+ return (
+
+
+ {relatedProposals.map((proposal) => (
+
+ ))}
+ {relatedProposals.length > 10 && (
+
+ )}
+
+ );
+};
diff --git a/src/lib/pages/contract-details/index.tsx b/src/lib/pages/contract-details/index.tsx
index ae82195ab..70be2db90 100644
--- a/src/lib/pages/contract-details/index.tsx
+++ b/src/lib/pages/contract-details/index.tsx
@@ -30,6 +30,7 @@ import { InstantiateInfo } from "./components/InstantiateInfo";
import { JsonInfo } from "./components/JsonInfo";
import { ExecuteTable } from "./components/tables/execute/Execute";
import { MigrationTable } from "./components/tables/migration";
+import { RelatedProposalsTable } from "./components/tables/related-proposals";
import { TokenSection } from "./components/TokenSection";
interface ContractDetailsBodyProps {
@@ -60,9 +61,15 @@ const InvalidContract = () => (
const ContractDetailsBody = ({ contractAddress }: ContractDetailsBodyProps) => {
const contractData = useContractData(contractAddress);
const tableHeaderId = "contractDetailTableHeader";
- const { tableCounts, refetchExecute, refetchMigration } =
- useContractDetailsTableCounts(contractAddress);
+ const {
+ tableCounts,
+ refetchExecute,
+ refetchMigration,
+ refetchRelatedProposals,
+ } = useContractDetailsTableCounts(contractAddress);
+
if (!contractData) return ;
+
return (
<>
@@ -104,7 +111,9 @@ const ContractDetailsBody = ({ contractAddress }: ContractDetailsBodyProps) => {
All
Executes
Migration
- Related Proposals
+
+ Related Proposals
+
{/* TODOs: Wireup with real table data, Make table component, and render each table with different data under each TabPanel */}
@@ -130,9 +139,12 @@ const ContractDetailsBody = ({ contractAddress }: ContractDetailsBodyProps) => {
/>
-
- Related Proposals Table
-
+
diff --git a/src/lib/services/contractService.ts b/src/lib/services/contractService.ts
index 100e0d02c..f6bfa30d3 100644
--- a/src/lib/services/contractService.ts
+++ b/src/lib/services/contractService.ts
@@ -11,15 +11,20 @@ import {
getExecuteTxsByContractAddress,
getMigrationHistoriesCountByContractAddress,
getMigrationHistoriesByContractAddress,
+ getRelatedProposalsCountByContractAddress,
+ getRelatedProposalsByContractAddress,
} from "lib/data/queries";
import type { ContractInfo } from "lib/stores/contract";
import type {
ContractAddr,
ContractMigrationHistory,
+ ContractRelatedProposals,
ExecuteTransaction,
HumanAddr,
MigrationRemark,
Option,
+ ProposalStatus,
+ ProposalType,
} from "lib/types";
import { parseDate, parseDateDefault, parseTxHash } from "lib/utils";
@@ -224,3 +229,61 @@ export const useMigrationHistoriesCountByContractAddress = (
enabled: !!contractAddress,
});
};
+
+export const useRelatedProposalsByContractAddress = (
+ contractAddress: ContractAddr,
+ offset: number,
+ pageSize: number
+): UseQueryResult