Skip to content

Commit bc47e54

Browse files
authored
Merge pull request #3440 from IntersectMBO/feat/3247-improve-metadata-validation-approach-for-faster-content-loading
feat(#3247, #3307): add skeleton on cards while validating
2 parents ccfacff + a8b1562 commit bc47e54

38 files changed

+1026
-658
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ changes.
1414

1515
- Add Proposal discussion context that manages username [Issue 3341](https://github.com/IntersectMBO/govtool/issues/3341)
1616
- Add epochParams and ada holder balance to Proposal Discussion Pillar [Issue 2243](https://github.com/IntersectMBO/govtool/issues/2243)
17+
- Add skeleton element to the drep and governance action cards on validation [Issue 3247](https://github.com/IntersectMBO/govtool/issues/3247)
18+
- Add mock for the authors field in governance metadata [Issue 3307](https://github.com/IntersectMBO/govtool/issues/3307)
1719

1820
- Add uncontrolled image input to improve performance of large base64 encoded image strings
1921

govtool/frontend/src/components/molecules/DataMissingHeader.tsx

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Avatar, Box, SxProps } from "@mui/material";
1+
import { Avatar, Box, Skeleton, SxProps } from "@mui/material";
22

33
import { Typography } from "@atoms";
44
import { MetadataValidationStatus } from "@models";
@@ -11,10 +11,11 @@ import { Share } from "./Share";
1111
import { useScreenDimension } from "@/hooks";
1212

1313
type DataMissingHeaderProps = {
14-
isDataMissing: MetadataValidationStatus | null;
14+
isDataMissing?: MetadataValidationStatus;
1515
title?: string;
1616
titleStyle?: SxProps;
1717
isDRep?: boolean;
18+
isValidating?: boolean;
1819
image?: string | null;
1920
shareLink?: string;
2021
};
@@ -23,6 +24,7 @@ export const DataMissingHeader = ({
2324
title,
2425
isDataMissing,
2526
titleStyle,
27+
isValidating,
2628
isDRep,
2729
image,
2830
shareLink,
@@ -53,39 +55,49 @@ export const DataMissingHeader = ({
5355
display: "flex",
5456
}}
5557
>
56-
{isDRep && (
57-
<Avatar
58-
alt="drep-image"
59-
src={
60-
(base64Image.isValidBase64Image
61-
? `${base64Image.base64Prefix}${image}`
62-
: image) || ICONS.defaultDRepIcon
63-
}
64-
sx={{ width: 80, height: 80 }}
65-
data-testid="drep-image"
58+
{isDRep &&
59+
(isValidating ? (
60+
<Skeleton width={80} height={80} variant="circular" />
61+
) : (
62+
<Avatar
63+
alt="drep-image"
64+
src={
65+
(base64Image.isValidBase64Image
66+
? `${base64Image.base64Prefix}${image}`
67+
: image) ?? ICONS.defaultDRepIcon
68+
}
69+
sx={{ width: 80, height: 80 }}
70+
data-testid="drep-image"
71+
/>
72+
))}
73+
{isValidating ? (
74+
<Skeleton
75+
width="120px"
76+
height="32px"
77+
sx={{ ...(isDRep && { ml: 4 }) }}
78+
variant="rounded"
6679
/>
80+
) : (
81+
<Typography
82+
sx={{
83+
...(isDRep && { ml: { md: 3 } }),
84+
...(isDRep && { mt: { xxs: 2, md: 0 } }),
85+
textOverflow: "ellipsis",
86+
fontWeight: 600,
87+
...(isDataMissing && { color: "errorRed" }),
88+
...titleStyle,
89+
}}
90+
variant="title2"
91+
component="h1"
92+
>
93+
{(isDataMissing &&
94+
getMetadataDataMissingStatusTranslation(isDataMissing)) ||
95+
title}
96+
</Typography>
6797
)}
68-
<Typography
69-
sx={{
70-
...(isDRep && { ml: { md: 3 } }),
71-
...(isDRep && { mt: { xxs: 2, md: 0 } }),
72-
textOverflow: "ellipsis",
73-
fontWeight: 600,
74-
...(isDataMissing && { color: "errorRed" }),
75-
...titleStyle,
76-
}}
77-
variant="title2"
78-
component="h1"
79-
>
80-
{(isDataMissing &&
81-
getMetadataDataMissingStatusTranslation(
82-
isDataMissing as MetadataValidationStatus,
83-
)) ||
84-
title}
85-
</Typography>
8698
</Box>
8799
{screenWidth >= 1020 && (
88-
<Share link={shareLink || window.location.href} />
100+
<Share link={shareLink ?? window.location.href} />
89101
)}
90102
</Box>
91103
);

govtool/frontend/src/components/molecules/DataMissingInfoBox.tsx

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Box, Link, SxProps } from "@mui/material";
1+
import { Box, Link, Skeleton, SxProps } from "@mui/material";
22

33
import { Typography } from "@atoms";
44
import { useTranslation } from "@hooks";
@@ -9,12 +9,14 @@ import { LINKS } from "@/consts/links";
99
export const DataMissingInfoBox = ({
1010
isDataMissing,
1111
isInProgress,
12+
isValidating,
1213
isSubmitted,
1314
isDrep = false,
1415
sx,
1516
}: {
16-
isDataMissing: MetadataValidationStatus | null;
17+
isDataMissing?: MetadataValidationStatus;
1718
isInProgress?: boolean;
19+
isValidating?: boolean;
1820
isSubmitted?: boolean;
1921
isDrep?: boolean;
2022
sx?: SxProps;
@@ -63,36 +65,58 @@ export const DataMissingInfoBox = ({
6365
...sx,
6466
}}
6567
>
66-
<Typography
67-
sx={{
68-
fontSize: "18px",
69-
fontWeight: 500,
70-
color: "errorRed",
71-
mb: 0.5,
72-
}}
73-
>
74-
{gaMetadataErrorMessage}
75-
</Typography>
76-
<Typography
77-
sx={{
78-
fontWeight: 400,
79-
color: "errorRed",
80-
mb: 0.5,
81-
}}
82-
>
83-
{gaMetadataErrorDescription}
84-
</Typography>
85-
<Link
86-
onClick={() => openInNewTab(LINKS.DREP_ERROR_CONDITIONS)}
87-
sx={{
88-
fontFamily: "Poppins",
89-
fontSize: "16px",
90-
lineHeight: "24px",
91-
cursor: "pointer",
92-
}}
93-
>
94-
{t("learnMore")}
95-
</Link>
68+
{isValidating ? (
69+
<Skeleton
70+
sx={{ mb: 0.5 }}
71+
width="128px"
72+
height="48px"
73+
variant="rounded"
74+
/>
75+
) : (
76+
<Typography
77+
sx={{
78+
fontSize: "18px",
79+
fontWeight: 500,
80+
color: "errorRed",
81+
mb: 0.5,
82+
}}
83+
>
84+
{gaMetadataErrorMessage}
85+
</Typography>
86+
)}
87+
{isValidating ? (
88+
<Skeleton
89+
sx={{ mb: 0.5 }}
90+
width="100%"
91+
height="96px"
92+
variant="rounded"
93+
/>
94+
) : (
95+
<Typography
96+
sx={{
97+
fontWeight: 400,
98+
color: "errorRed",
99+
mb: 0.5,
100+
}}
101+
>
102+
{gaMetadataErrorDescription}
103+
</Typography>
104+
)}
105+
{isValidating ? (
106+
<Skeleton width="128px" height="24px" variant="text" />
107+
) : (
108+
<Link
109+
onClick={() => openInNewTab(LINKS.DREP_ERROR_CONDITIONS)}
110+
sx={{
111+
fontFamily: "Poppins",
112+
fontSize: "16px",
113+
lineHeight: "24px",
114+
cursor: "pointer",
115+
}}
116+
>
117+
{t("learnMore")}
118+
</Link>
119+
)}
96120
</Box>
97121
) : null;
98122
};

govtool/frontend/src/components/molecules/GovernanceActionCard.tsx

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { FC } from "react";
2-
import { Box } from "@mui/material";
2+
import { Box, Skeleton } from "@mui/material";
33

44
import { Button } from "@atoms";
55
import {
@@ -8,7 +8,6 @@ import {
88
GovernanceActionCardStatePill,
99
GovernanceActionsDatesBox,
1010
} from "@molecules";
11-
1211
import { useScreenDimension, useTranslation } from "@hooks";
1312
import {
1413
encodeCIP129Identifier,
@@ -23,33 +22,32 @@ type ActionTypeProps = Omit<
2322
| "yesVotes"
2423
| "noVotes"
2524
| "abstainVotes"
26-
| "metadataHash"
27-
| "url"
2825
| "id"
2926
| "details"
3027
| "rationale"
3128
| "motivation"
3229
> & {
3330
onClick?: () => void;
3431
inProgress?: boolean;
32+
isValidating?: boolean;
33+
metadataStatus?: MetadataValidationStatus;
3534
};
3635

37-
export const GovernanceActionCard: FC<ActionTypeProps> = ({ ...props }) => {
38-
const {
39-
abstract,
40-
type,
41-
inProgress = false,
42-
expiryDate,
43-
expiryEpochNo,
44-
onClick,
45-
createdDate,
46-
createdEpochNo,
47-
txHash,
48-
index,
49-
metadataStatus,
50-
metadataValid,
51-
title,
52-
} = props;
36+
export const GovernanceActionCard: FC<ActionTypeProps> = ({
37+
abstract,
38+
type,
39+
inProgress = false,
40+
expiryDate,
41+
expiryEpochNo,
42+
onClick,
43+
createdDate,
44+
createdEpochNo,
45+
txHash,
46+
index,
47+
title,
48+
isValidating,
49+
metadataStatus,
50+
}) => {
5351
const { isMobile, screenWidth } = useScreenDimension();
5452
const { t } = useTranslation();
5553

@@ -71,10 +69,10 @@ export const GovernanceActionCard: FC<ActionTypeProps> = ({ ...props }) => {
7169
justifyContent: "space-between",
7270
boxShadow: "0px 4px 15px 0px #DDE3F5",
7371
borderRadius: "20px",
74-
backgroundColor: !metadataValid
72+
backgroundColor: metadataStatus
7573
? "rgba(251, 235, 235, 0.50)"
7674
: "rgba(255, 255, 255, 0.3)",
77-
...(!metadataValid && {
75+
...(!!metadataStatus && {
7876
border: "1px solid #F6D5D5",
7977
}),
8078
...(inProgress && {
@@ -92,15 +90,17 @@ export const GovernanceActionCard: FC<ActionTypeProps> = ({ ...props }) => {
9290
<GovernanceActionCardHeader
9391
title={title}
9492
isDataMissing={metadataStatus}
93+
isValidating={isValidating}
9594
/>
96-
{!metadataStatus && (
95+
{!!metadataStatus && (
9796
<GovernanceActionCardElement
9897
label={t("govActions.abstract")}
9998
text={abstract}
10099
textVariant="twoLines"
101100
dataTestId="governance-action-abstract"
102101
isSliderCard
103102
isMarkdown
103+
isValidating={isValidating}
104104
/>
105105
)}
106106
<GovernanceActionCardElement
@@ -109,20 +109,23 @@ export const GovernanceActionCard: FC<ActionTypeProps> = ({ ...props }) => {
109109
textVariant="pill"
110110
dataTestId={`${getProposalTypeNoEmptySpaces(type)}-type`}
111111
isSliderCard
112+
isValidating={isValidating}
112113
/>
113114
<GovernanceActionsDatesBox
114115
createdDate={createdDate}
115116
expiryDate={expiryDate}
116117
expiryEpochNo={expiryEpochNo}
117118
createdEpochNo={createdEpochNo}
118119
isSliderCard
120+
isValidating={isValidating}
119121
/>
120122
<GovernanceActionCardElement
121123
label={t("govActions.cip129GovernanceActionId")}
122124
text={cip129GovernanceActionId}
123125
dataTestId={`${cip129GovernanceActionId}-id`}
124126
isCopyButton
125127
isSliderCard
128+
isValidating={isValidating}
126129
/>
127130
<GovernanceActionCardElement
128131
label={t("govActions.governanceActionId")}
@@ -131,6 +134,7 @@ export const GovernanceActionCard: FC<ActionTypeProps> = ({ ...props }) => {
131134
isCopyButton
132135
isSliderCard
133136
isSemiTransparent
137+
isValidating={isValidating}
134138
/>
135139
</Box>
136140
<Box
@@ -142,21 +146,25 @@ export const GovernanceActionCard: FC<ActionTypeProps> = ({ ...props }) => {
142146
bgcolor: "white",
143147
}}
144148
>
145-
<Button
146-
onClick={onClick}
147-
variant={inProgress ? "outlined" : "contained"}
148-
size="large"
149-
sx={{
150-
width: "100%",
151-
}}
152-
data-testid={`govaction-${govActionId}-view-detail`}
153-
>
154-
{t(
155-
inProgress
156-
? "govActions.viewDetails"
157-
: "govActions.viewDetailsAndVote",
158-
)}
159-
</Button>
149+
{isValidating ? (
150+
<Skeleton width="100%" height="40px" sx={{ borderRadius: "20px" }} />
151+
) : (
152+
<Button
153+
onClick={onClick}
154+
variant={inProgress ? "outlined" : "contained"}
155+
size="large"
156+
sx={{
157+
width: "100%",
158+
}}
159+
data-testid={`govaction-${govActionId}-view-detail`}
160+
>
161+
{t(
162+
inProgress
163+
? "govActions.viewDetails"
164+
: "govActions.viewDetailsAndVote",
165+
)}
166+
</Button>
167+
)}
160168
</Box>
161169
</Box>
162170
);

0 commit comments

Comments
 (0)