Skip to content

Commit e3d1113

Browse files
authored
chore: Portal UI improvements (#296)
* feat: Button icon & nav buttons * chore: Icons & navigation improvement * chore: UI improvements * feat: Badge size * chore: Fixed-width columns event table * chore: Dropdown badge variant
1 parent d66d7b9 commit e3d1113

File tree

11 files changed

+165
-41
lines changed

11 files changed

+165
-41
lines changed

internal/portal/src/common/Badge/Badge.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@
3434
color: var(--colors-foreground-danger);
3535
border-color: var(--colors-outline-danger);
3636
}
37+
38+
&__s {
39+
font-size: var(--font-size-xs);
40+
line-height: var(--line-height-xs);
41+
padding: 0 var(--spacing-1);
42+
}
3743
}

internal/portal/src/common/Badge/Badge.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@ interface BadgeProps {
66
danger?: boolean;
77
primary?: boolean;
88
text: string | number;
9+
size?: "s" | "m";
910
}
1011

1112
const Badge: FC<BadgeProps> = ({
1213
text,
14+
size = "m",
1315
success = false,
1416
danger = false,
1517
primary = false,
1618
}) => {
1719
const className = `badge${success ? " badge__success" : ""}${
1820
danger ? " badge__danger" : ""
19-
}${primary ? " badge__primary" : ""}`;
21+
}${primary ? " badge__primary" : ""}${size === "s" ? " badge__s" : ""}`;
2022

2123
return <span className={className}>{text}</span>;
2224
};

internal/portal/src/common/Button/Button.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
box-shadow: var(--colors-shadow-button);
1313
position: relative;
1414

15+
&.button__icon {
16+
line-height: 0;
17+
padding: var(--spacing-1--5) var(--spacing-1--5);
18+
}
19+
1520
> span {
1621
display: flex;
1722
align-items: center;

internal/portal/src/common/Button/Button.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ interface ButtonProps {
1313
primary?: boolean;
1414
danger?: boolean;
1515
minimal?: boolean;
16+
icon?: boolean;
17+
iconLabel?: string;
1618
}
1719

1820
const Button: FC<PropsWithChildren<ButtonProps>> = ({
@@ -26,12 +28,14 @@ const Button: FC<PropsWithChildren<ButtonProps>> = ({
2628
loading = false,
2729
danger = false,
2830
minimal = false,
31+
icon,
32+
iconLabel,
2933
}) => {
3034
className = `button${primary ? " button__primary" : ""}${
3135
disabled || loading ? " button__disabled" : ""
3236
} ${loading ? " button__loading" : ""} ${danger ? " button__danger" : ""} ${
3337
minimal ? " button__minimal" : ""
34-
} ${className || ""}`;
38+
} ${icon ? " button__icon" : ""}${className || ""}`;
3539

3640
if (to) {
3741
return (
@@ -53,6 +57,9 @@ const Button: FC<PropsWithChildren<ButtonProps>> = ({
5357
type={type}
5458
>
5559
<span>{children}</span>
60+
{icon && iconLabel && (
61+
<span className="visually-hidden">{iconLabel}</span>
62+
)}
5663
{loading && (
5764
<div className="button__loading-container">
5865
<Loading />

internal/portal/src/common/Dropdown/Dropdown.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ interface DropdownProps {
99
trigger: React.ReactNode;
1010
disabled?: boolean;
1111
badge_count?: number;
12+
badge_variant?: "primary" | "success" | "danger";
1213
}
1314

1415
const Dropdown: FC<PropsWithChildren<DropdownProps>> = ({
1516
trigger_icon,
1617
trigger,
1718
children,
1819
badge_count,
20+
badge_variant,
1921
disabled = false,
2022
}) => {
2123
return (
@@ -26,7 +28,12 @@ const Dropdown: FC<PropsWithChildren<DropdownProps>> = ({
2628
{trigger_icon}
2729
{trigger}
2830
{badge_count && badge_count > 0 ? (
29-
<Badge text={String(badge_count)} />
31+
<Badge
32+
text={String(badge_count)}
33+
primary={badge_variant === "primary"}
34+
success={badge_variant === "success"}
35+
danger={badge_variant === "danger"}
36+
/>
3037
) : null}
3138
</Button>
3239
</div>

internal/portal/src/common/Icons.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,39 @@ export const Loading = () => (
309309
></circle>
310310
</svg>
311311
);
312+
313+
export const ArrowUpwardIcon = () => (
314+
<svg
315+
width="16"
316+
height="16"
317+
viewBox="0 0 16 16"
318+
fill="none"
319+
xmlns="http://www.w3.org/2000/svg"
320+
>
321+
<path d="M7.40026 5.50001L4.46339 8.43688C4.34353 8.55675 4.20304 8.61668 4.04193 8.61668C3.88082 8.61668 3.73649 8.55557 3.60896 8.43335C3.49205 8.31112 3.43359 8.16946 3.43359 8.00835C3.43359 7.84723 3.49372 7.70663 3.61396 7.58653L7.58206 3.62341C7.64218 3.56337 7.70732 3.51946 7.77746 3.49168C7.8476 3.4639 7.92276 3.45001 8.00293 3.45001C8.08308 3.45001 8.15823 3.4639 8.22838 3.49168C8.29852 3.51946 8.36137 3.56112 8.41693 3.61668L12.3836 7.58335C12.5058 7.70557 12.5669 7.84446 12.5669 8.00001C12.5669 8.15557 12.5085 8.29446 12.3916 8.41668C12.264 8.5389 12.1188 8.60001 11.9558 8.60001C11.7929 8.60001 11.6521 8.5389 11.5336 8.41668L8.60026 5.50001V12.2004C8.60026 12.3703 8.5431 12.5127 8.42878 12.6276C8.31444 12.7426 8.17278 12.8 8.00378 12.8C7.83477 12.8 7.69193 12.7426 7.57526 12.6276C7.45859 12.5127 7.40026 12.3703 7.40026 12.2004V5.50001Z" />
322+
</svg>
323+
);
324+
325+
export const ArrowForwardIcon = () => (
326+
<svg
327+
width="16"
328+
height="16"
329+
viewBox="0 0 16 16"
330+
fill="none"
331+
xmlns="http://www.w3.org/2000/svg"
332+
>
333+
<path d="M10.4992 8.59989H3.79889C3.629 8.59989 3.48655 8.54273 3.37155 8.42839C3.25666 8.31406 3.19922 8.17239 3.19922 8.00339C3.19922 7.83439 3.25666 7.69156 3.37155 7.57489C3.48655 7.45823 3.629 7.39989 3.79889 7.39989H10.4992L7.56239 4.46306C7.4425 4.34317 7.38255 4.20267 7.38255 4.04156C7.38255 3.88045 7.44366 3.73612 7.56589 3.60856C7.68811 3.49167 7.82977 3.43323 7.99089 3.43323C8.152 3.43323 8.29261 3.49334 8.41272 3.61356L12.3759 7.58173C12.4359 7.64184 12.4798 7.70695 12.5076 7.77706C12.5353 7.84717 12.5492 7.92234 12.5492 8.00256C12.5492 8.08267 12.5353 8.15784 12.5076 8.22806C12.4798 8.29817 12.4381 8.36101 12.3826 8.41656L8.41589 12.3832C8.29366 12.5055 8.15477 12.5638 7.99922 12.5582C7.84366 12.5527 7.70477 12.4914 7.58255 12.3746C7.46033 12.247 7.39922 12.1017 7.39922 11.9387C7.39922 11.7758 7.46033 11.6351 7.58255 11.5166L10.4992 8.59989Z" />
334+
</svg>
335+
);
336+
337+
export const ArrowBackIcon = () => (
338+
<svg
339+
width="16"
340+
height="16"
341+
viewBox="0 0 16 16"
342+
fill="none"
343+
xmlns="http://www.w3.org/2000/svg"
344+
>
345+
<path d="M5.49922 8.59989L8.43605 11.5367C8.55594 11.6566 8.61589 11.7971 8.61589 11.9582C8.61589 12.1193 8.55477 12.2637 8.43255 12.3912C8.31033 12.5081 8.16866 12.5666 8.00755 12.5666C7.84644 12.5666 7.70583 12.5064 7.58572 12.3862L3.62255 8.41806C3.56255 8.35795 3.51866 8.29284 3.49089 8.22273C3.46311 8.15262 3.44922 8.07745 3.44922 7.99723C3.44922 7.91712 3.46311 7.84195 3.49089 7.77173C3.51866 7.70162 3.56033 7.63878 3.61589 7.58323L7.58255 3.61656C7.70477 3.49434 7.84739 3.43323 8.01039 3.43323C8.17327 3.43323 8.314 3.49434 8.43255 3.61656C8.55477 3.73512 8.61589 3.87584 8.61589 4.03873C8.61589 4.20173 8.55566 4.34345 8.43522 4.46389L5.49922 7.39989H12.1996C12.3694 7.39989 12.5119 7.45706 12.6269 7.57139C12.7418 7.68573 12.7992 7.82739 12.7992 7.99639C12.7992 8.16539 12.7418 8.30823 12.6269 8.42489C12.5119 8.54156 12.3694 8.59989 12.1996 8.59989H5.49922Z" />
346+
</svg>
347+
);

internal/portal/src/global.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,3 +560,15 @@ textarea {
560560
box-shadow: var(--colors-shadow-input-danger);
561561
}
562562
}
563+
564+
.visually-hidden {
565+
position: absolute;
566+
width: 1px;
567+
height: 1px;
568+
padding: 0;
569+
margin: -1px;
570+
overflow: hidden;
571+
clip: rect(0, 0, 0, 0);
572+
white-space: nowrap;
573+
border: 0;
574+
}

internal/portal/src/scenes/Destination/Destination.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
.tab {
5252
padding: var(--spacing-2) var(--spacing-3);
5353
padding-bottom: var(--spacing-3);
54+
font-size: var(--font-size-m);
5455
font-weight: 500;
5556
color: var(--colors-foreground-neutral-3);
5657
text-decoration: none;

internal/portal/src/scenes/Destination/Events/EventDetails.tsx

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { Route, Routes, useLocation, useParams } from "react-router-dom";
22
import Button from "../../../common/Button/Button";
3-
import { CloseIcon, NextIcon, PreviousIcon } from "../../../common/Icons";
3+
import {
4+
ArrowForwardIcon,
5+
CloseIcon,
6+
ArrowBackIcon,
7+
} from "../../../common/Icons";
48
import useSWR from "swr";
59
import { Event, Delivery } from "../../../typings/Event";
610
import Badge from "../../../common/Badge/Badge";
@@ -74,7 +78,12 @@ const EventData = ({
7478
danger={event.status === "failed"}
7579
/>
7680

77-
<Button minimal onClick={() => navigateEvent("/")}>
81+
<Button
82+
icon
83+
iconLabel="Close"
84+
minimal
85+
onClick={() => navigateEvent("/")}
86+
>
7887
<CloseIcon />
7988
</Button>
8089
</div>
@@ -83,7 +92,7 @@ const EventData = ({
8392
<div className="drawer__body">
8493
<div className="event-data">
8594
<div className="event-data__overview">
86-
<h3 className="title-m">Overview</h3>
95+
<h3 className="subtitle-m">Overview</h3>
8796
<dl className="body-m description-list">
8897
<div>
8998
<dt>ID</dt>
@@ -127,7 +136,9 @@ const EventData = ({
127136

128137
<div className="event-data__metadata">
129138
<h3 className="subtitle-m">Metadata</h3>
130-
<pre className="mono-s">{JSON.stringify(event.metadata, null, 2)}</pre>
139+
<pre className="mono-s">
140+
{JSON.stringify(event.metadata, null, 2)}
141+
</pre>
131142
</div>
132143
</div>
133144
</div>
@@ -163,7 +174,12 @@ const EventAttempts = ({
163174
</div>
164175

165176
<div>
166-
<Button minimal onClick={() => navigateEvent("/")}>
177+
<Button
178+
icon
179+
iconLabel="Close"
180+
minimal
181+
onClick={() => navigateEvent("/")}
182+
>
167183
<CloseIcon />
168184
</Button>
169185
</div>
@@ -217,8 +233,9 @@ const EventAttempts = ({
217233
success={delivery.status === "success"}
218234
danger={delivery.status === "failed"}
219235
/>
220-
{/* TODO: use RightArrowIcon */}
221-
<NextIcon />
236+
<span className="icon-container">
237+
<ArrowForwardIcon />
238+
</span>
222239
</span>
223240
</span>
224241
</li>
@@ -251,7 +268,7 @@ const EventAttemptDetails = ({
251268
minimal
252269
onClick={() => navigateEvent(`/${event.id}/attempts`)}
253270
>
254-
<PreviousIcon />
271+
<ArrowBackIcon />
255272
Attempts {deliveryIndex}
256273
</Button>
257274
</div>
@@ -263,7 +280,12 @@ const EventAttemptDetails = ({
263280
danger={delivery.status === "failed"}
264281
/>
265282

266-
<Button minimal onClick={() => navigateEvent("/")}>
283+
<Button
284+
icon
285+
iconLabel="Close"
286+
minimal
287+
onClick={() => navigateEvent("/")}
288+
>
267289
<CloseIcon />
268290
</Button>
269291
</div>
@@ -272,7 +294,7 @@ const EventAttemptDetails = ({
272294
<div className="drawer__body">
273295
<div className="event-attempt-details">
274296
<div className="event-attempt-details__overview">
275-
<h3 className="title-m">Overview</h3>
297+
<h3 className="subtitle-m">Overview</h3>
276298

277299
<dl className="body-m description-list">
278300
<div>
@@ -325,7 +347,9 @@ const EventAttemptDetails = ({
325347

326348
<div className="event-attempt-details__result">
327349
<h3 className="subtitle-m">Response</h3>
328-
<pre className="mono-s">{JSON.stringify(delivery.response_data, null, 2)}</pre>
350+
<pre className="mono-s">
351+
{JSON.stringify(delivery.response_data, null, 2)}
352+
</pre>
329353
</div>
330354
</div>
331355
</div>

internal/portal/src/scenes/Destination/Events/Events.scss

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
&-filters {
1919
display: flex;
2020
align-items: center;
21-
gap: var(--spacing-2);
21+
gap: var(--spacing-3);
22+
}
23+
24+
&-title .badge {
25+
color: currentColor;
2226
}
2327
}
2428

@@ -35,16 +39,26 @@
3539
.table {
3640
height: 100%;
3741

38-
[data-active="true"] {
39-
box-shadow: inset 0 0 0 2px var(--colors-outline-primary-focus);
40-
background-color: var(--colors-background-container-primary);
42+
&__body-cell > * {
43+
padding: var(--spacing-3) var(--spacing-4);
4144
}
4245

4346
&__footer {
4447
display: flex;
4548
align-items: center;
4649
justify-content: space-between;
4750
gap: var(--spacing-2);
51+
52+
nav {
53+
display: flex;
54+
align-items: center;
55+
gap: var(--spacing-2);
56+
}
57+
}
58+
59+
[data-active="true"] {
60+
box-shadow: inset 0 0 0 2px var(--colors-outline-primary-focus);
61+
background-color: var(--colors-background-container-primary);
4862
}
4963
}
5064

@@ -78,11 +92,15 @@
7892
align-items: center;
7993
gap: var(--spacing-2);
8094

81-
button.button__minimal.active {
82-
background-color: var(--colors-background-neutral-2);
95+
button.button__minimal {
96+
padding: var(--spacing-1) var(--spacing-2);
8397

84-
> span {
85-
color: var(--colors-foreground-neutral);
98+
&.active {
99+
background-color: var(--colors-background-neutral-2);
100+
101+
> span {
102+
color: var(--colors-foreground-neutral);
103+
}
86104
}
87105
}
88106
}
@@ -162,7 +180,7 @@
162180
margin: 0;
163181

164182
&-item {
165-
padding: var(--spacing-3) var(--spacing-6);
183+
padding: var(--spacing-2) var(--spacing-6);
166184
border-bottom: 1px solid var(--colors-outline-neutral);
167185
position: relative;
168186

@@ -207,6 +225,20 @@
207225
display: flex;
208226
align-items: center;
209227
gap: var(--spacing-2);
228+
229+
.icon-container {
230+
width: 28px;
231+
height: 28px;
232+
display: flex;
233+
align-items: center;
234+
justify-content: center;
235+
236+
svg {
237+
fill: var(--colors-foreground-neutral-2);
238+
width: 16px;
239+
height: 16px;
240+
}
241+
}
210242
}
211243

212244
svg {
@@ -267,18 +299,6 @@
267299
}
268300
}
269301

270-
.visually-hidden {
271-
position: absolute;
272-
width: 1px;
273-
height: 1px;
274-
padding: 0;
275-
margin: -1px;
276-
overflow: hidden;
277-
clip: rect(0, 0, 0, 0);
278-
white-space: nowrap;
279-
border: 0;
280-
}
281-
282302
dl.description-list {
283303
margin-top: 0;
284304
margin-bottom: 0;

0 commit comments

Comments
 (0)