Skip to content

Commit 112e4e6

Browse files
Merge pull request #531 from CodeForAfrica/ft/entity-card-tooltip-fixes
refactor(PoliticalEntityList): Entity Card Tooltips
2 parents 850464a + 5119f21 commit 112e4e6

File tree

4 files changed

+46
-30
lines changed

4 files changed

+46
-30
lines changed

src/blocks/EntitySelection.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ export const EntitySelection: Block = {
7474
fr: "Titre du groupe",
7575
},
7676
},
77+
{
78+
name: "description",
79+
type: "textarea",
80+
required: true,
81+
localized: true,
82+
label: {
83+
en: "Group description",
84+
fr: "Description du groupe",
85+
},
86+
},
7787
colorPickerField({
7888
name: "color",
7989
label: {

src/components/PoliticalEntityList/PoliticalEntityList.client.tsx

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import {
1818
DesktopInfoStatusPopover,
1919
MobileInfoStatusPopover,
2020
} from "@/components/PromiseStatusInfo";
21-
import type { PromiseStatusListProps } from "@/components/PromiseStatusList";
2221

2322
export type PoliticalEntityListClientProps = {
2423
statusGroups: {
2524
id: string;
2625
title: string;
26+
description: string;
2727
color: string;
2828
statusIds: string[];
2929
}[];
@@ -47,19 +47,17 @@ export type PoliticalEntityListClientProps = {
4747
statusCounts: Record<string, number>;
4848
filterKey: string;
4949
}[];
50-
statusDefinitions: PromiseStatusListProps["statuses"];
5150
statusInfoTitle?: string;
5251
};
5352

5453
export const PoliticalEntityListClient = ({
5554
statusGroups,
5655
filterOptions,
5756
items,
58-
statusDefinitions,
5957
statusInfoTitle = "Promise status definitions",
6058
}: PoliticalEntityListClientProps) => {
6159
const [activeFilter, setActiveFilter] = useState(
62-
filterOptions[0]?.key ?? "all"
60+
filterOptions[0]?.key ?? "all",
6361
);
6462

6563
const visibleItems = useMemo(() => {
@@ -74,15 +72,27 @@ export const PoliticalEntityListClient = ({
7472
setActiveFilter(key);
7573
};
7674

77-
const hasStatusDefinitions = statusDefinitions.length > 0;
75+
const popoverStatuses = useMemo(
76+
() =>
77+
statusGroups.map((group) => ({
78+
id: group.id,
79+
label: group.title,
80+
description: group.description,
81+
color: group.color,
82+
})),
83+
[statusGroups],
84+
);
85+
86+
const hasStatusDefinitions = popoverStatuses.length > 0;
7887

7988
return (
8089
<Stack spacing={2.5}>
8190
<Stack
82-
direction={{ xs: "column", md: "row" }}
91+
direction="row"
8392
spacing={{ xs: 2, md: 3 }}
84-
alignItems={{ xs: "flex-start", md: "center" }}
93+
alignItems="center"
8594
justifyContent="space-between"
95+
sx={{ flexWrap: { xs: "wrap", md: "nowrap" } }}
8696
>
8797
<Stack
8898
direction="row"
@@ -121,20 +131,21 @@ export const PoliticalEntityListClient = ({
121131
spacing={1}
122132
alignItems="center"
123133
sx={{
124-
width: { xs: "100%", md: "auto" },
125-
justifyContent: { xs: "flex-start", md: "flex-end" },
134+
flexShrink: 0,
135+
justifyContent: "flex-end",
136+
marginLeft: "0 !important",
126137
}}
127138
>
128139
<Box sx={{ display: { xs: "none", md: "flex" } }}>
129140
<DesktopInfoStatusPopover
130141
title={statusInfoTitle}
131-
statuses={statusDefinitions}
142+
statuses={popoverStatuses}
132143
/>
133144
</Box>
134145
<Box sx={{ display: { xs: "flex", md: "none" } }}>
135146
<MobileInfoStatusPopover
136147
title={statusInfoTitle}
137-
statuses={statusDefinitions}
148+
statuses={popoverStatuses}
138149
/>
139150
</Box>
140151
</Stack>
@@ -157,7 +168,7 @@ export const PoliticalEntityListClient = ({
157168
const count = group.statusIds.reduce(
158169
(total, statusId) =>
159170
total + (item.statusCounts[statusId] ?? 0),
160-
0
171+
0,
161172
);
162173

163174
if (count === 0) {
@@ -173,13 +184,13 @@ export const PoliticalEntityListClient = ({
173184
})
174185
.filter(
175186
(
176-
value
187+
value,
177188
): value is {
178189
id: string;
179190
title: string;
180191
color: string;
181192
count: number;
182-
} => Boolean(value)
193+
} => Boolean(value),
183194
);
184195

185196
return (

src/components/PoliticalEntityList/index.tsx

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020

2121
type StatusGroupConfig = {
2222
title?: string | null;
23+
description?: string | null;
2324
color?: string | null;
2425
statuses?: (string | PromiseStatus)[];
2526
};
@@ -128,9 +129,9 @@ export const PoliticalEntityList = async ({
128129
return null;
129130
}
130131

131-
const titleText = group?.title?.trim() || statuses[0].label;
132-
const groupColorRaw =
133-
typeof group?.color === "string" ? group.color.trim() : "";
132+
const titleText = group.title;
133+
const descriptionText = group.description;
134+
const groupColorRaw = group.color;
134135
const resolvedColor =
135136
groupColorRaw ||
136137
statuses[0].colors?.textColor ||
@@ -140,6 +141,7 @@ export const PoliticalEntityList = async ({
140141
return {
141142
id: `group-${index}-${statuses[0].id}`,
142143
title: titleText,
144+
description: descriptionText,
143145
color: resolvedColor,
144146
statusIds,
145147
};
@@ -151,6 +153,7 @@ export const PoliticalEntityList = async ({
151153
statusGroups.push({
152154
id: `fallback-${status.id}-${index}`,
153155
title: status.label,
156+
description: status.description ?? "",
154157
color: status.colors?.textColor || status.colors?.color || "#000000",
155158
statusIds: [status.id],
156159
});
@@ -169,14 +172,14 @@ export const PoliticalEntityList = async ({
169172
return entityA.name.localeCompare(entityB.name, undefined, {
170173
sensitivity: "base",
171174
});
172-
}
175+
},
173176
);
174177

175178
const entitiesWithMedia = await Promise.all(
176179
sortedPoliticalEntities.map(async (entity) => ({
177180
entity,
178181
media: await resolveMedia(entity.image),
179-
}))
182+
})),
180183
);
181184

182185
const listItems: PoliticalEntityListClientProps["items"] =
@@ -217,7 +220,7 @@ export const PoliticalEntityList = async ({
217220
accumulator[label] = (accumulator[label] ?? 0) + 1;
218221
return accumulator;
219222
},
220-
{}
223+
{},
221224
);
222225

223226
const filterOptions: PoliticalEntityListClientProps["filterOptions"] = [
@@ -229,15 +232,6 @@ export const PoliticalEntityList = async ({
229232
})),
230233
];
231234

232-
const statusDefinitions: PoliticalEntityListClientProps["statusDefinitions"] =
233-
statusDocs.map((status) => ({
234-
id: status.id,
235-
label: status.label,
236-
description: status.description ?? "",
237-
color: status.colors?.color ?? null,
238-
textColor: status.colors?.textColor ?? null,
239-
}));
240-
241235
return (
242236
<Container component="section" sx={{ py: { xs: 5, md: 6 } }}>
243237
<Typography variant="h6" sx={{ fontWeight: 600, mb: 2 }}>
@@ -249,7 +243,6 @@ export const PoliticalEntityList = async ({
249243
statusGroups={statusGroups}
250244
filterOptions={filterOptions}
251245
items={listItems}
252-
statusDefinitions={statusDefinitions}
253246
/>
254247
</CardContent>
255248
</Card>

src/payload-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,7 @@ export interface EntitySelectionBlock {
18531853
statusGroups?:
18541854
| {
18551855
title: string;
1856+
description: string;
18561857
color: string;
18571858
statuses: (string | PromiseStatus)[];
18581859
id?: string | null;
@@ -2164,6 +2165,7 @@ export interface EntitySelectionBlockSelect<T extends boolean = true> {
21642165
| T
21652166
| {
21662167
title?: T;
2168+
description?: T;
21672169
color?: T;
21682170
statuses?: T;
21692171
id?: T;

0 commit comments

Comments
 (0)