Skip to content

Commit 1b3a2f2

Browse files
samejrmatt-aitken
andauthored
Full width tables (#1474)
* Updated styling * Updated the main Table component styles to the new design * Run page table layout style updates * Updated row styling and new scrolling behaviour * Fixed bulk action bar no appearing * Improved table component styles * Pagination arrows now chevrons * Added link to Runs docs page * Small popover tweak * Moved the extra Test button out of Tables and into the RunsTable * WIP refactoring the sticky table cell * Support for the existing way we have menus in the sticky table cells * Created a specific Docs style button * Improved dialog trigger button styles * Improved docs button styles * Updated Docs buttons to the new style in the tooltips * Adding a Test button on hover * Removed the page padding and made table scroll * Fixed table scrolling * cleaned up imports * WIP adding a test button that links to the test page * added a docs button to the header * Much nicer display bar for showing how many schedules you have (and it works with the updated table) * Fixed the button types in the schedules info panel * Fixed button icon colour * Removed the pagination as it’s not being used * Delete modal button position updated * Fixed padding on recent payloads panel * Fixed button icon colours * Better style for active table row * Table scrolling now behaves properly * environment buttons now have a hover state * Bigger Run test bar to match the Run page * Small layout fixes to the schedule side panel * Test page now has link to docs * fixed text alignment with table headers * API keys page now has full width tables * Fix typo and modal layout * Table uses new sticky button type * Tidy imports * Env var table now full width * Form buttons have a border top * Updated button styles * Updated blank state message style to be consistent * Removed unnecessary form button border * Alerts page tables now full width * Allowing the Detail cell to be styled * Updated the page structure to be the same as the scheduled page – with better progress indicator * Concurrency limits page now full width * Fixed function name label extending too far * Improved the button sizes on the replay modal * Added a minimal style to the info panels * Make sure you can always see the info and unlock staging info when the table scrolls * Info panel style updated to match the others * Removed the duplicate header * Usage page tables now full width * Personal access token page using full width tables * Small CSS fixes * Deployments page table now full width * Deploy page scrolls properly and pagination stays on screen if table is scrollable * TableCellMenu using the correct popover * Added missing button variant * Button group is now named so it doesn’t cause conflicts * Added docs link to the Run page * Typo * Added a link to the test page if you have no runs * Make the table sticky cell buttons more obvious * Env var page now using the new popover menu * Improved the menu items * Copy tweak * Made the icons bright on hover * Updated the cancel run dialog * Improved the API keys sticky menu behaviour * Alerts table menu using the new popover * Correct sized buttons in the Env Var page table menu * Fixed weird Dialog text styling * Schedules page blank state using correct docs button style * Copy tweak * Menu buttons styled correctly * Added close buttons to the deploy dialogs * Made the Dialog footer match the Form footer style * Fixed feedback form buttons * Fixed cancel run dialog * Test page uses the taskIdentifier in the path * Test task button working * Added Spline component for 404 logo to remove spline logo * Removed todo comment * Added a docs button to the PAT page --------- Co-authored-by: Matt Aitken <matt@mattaitken.com>
1 parent 653d974 commit 1b3a2f2

File tree

41 files changed

+1389
-806
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1389
-806
lines changed

apps/webapp/app/components/ErrorDisplay.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { friendlyErrorDisplay } from "~/utils/httpErrors";
55
import { LinkButton } from "./primitives/Buttons";
66
import { Header1 } from "./primitives/Headers";
77
import { Paragraph } from "./primitives/Paragraph";
8+
import Spline from "@splinetool/react-spline";
89

910
type ErrorDisplayOptions = {
1011
button?: {
@@ -55,18 +56,13 @@ export function ErrorDisplay({ title, message, button }: DisplayOptionsProps) {
5556
{button ? button.title : "Go to homepage"}
5657
</LinkButton>
5758
</div>
58-
<div className="pointer-events-none absolute bottom-4 right-4 z-10 h-[70px] w-[200px] bg-[rgb(24,26,30)]" />
5959
<motion.div
6060
className="pointer-events-none absolute inset-0 overflow-hidden"
6161
initial={{ opacity: 0 }}
6262
animate={{ opacity: 1 }}
6363
transition={{ delay: 0.5, duration: 2, ease: "easeOut" }}
6464
>
65-
<iframe
66-
src="https://my.spline.design/untitled-a6f70b5ebc46bdb2dcc0f21d5397e8ac/"
67-
className="pointer-events-none absolute inset-0 h-full w-full object-cover"
68-
style={{ border: "none" }}
69-
/>
65+
<Spline scene="https://prod.spline.design/wRly8TZN-e0Twb8W/scene.splinecode" />
7066
</motion.div>
7167
</div>
7268
);

apps/webapp/app/components/Feedback.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { Paragraph } from "./primitives/Paragraph";
1818
import { Select, SelectItem } from "./primitives/Select";
1919
import { TextArea } from "./primitives/TextArea";
2020
import { TextLink } from "./primitives/TextLink";
21+
import { DialogClose } from "@radix-ui/react-dialog";
2122

2223
type FeedbackProps = {
2324
button: ReactNode;
@@ -120,16 +121,18 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
120121
<FormError id={message.errorId}>{message.error}</FormError>
121122
</InputGroup>
122123
<FormError>{form.error}</FormError>
123-
<div className="flex w-full justify-end">
124-
<FormButtons
125-
className="m-0 w-max"
126-
confirmButton={
127-
<Button type="submit" variant="tertiary/medium">
128-
Send message
129-
</Button>
130-
}
131-
/>
132-
</div>
124+
<FormButtons
125+
confirmButton={
126+
<Button type="submit" variant="primary/medium">
127+
Send message
128+
</Button>
129+
}
130+
cancelButton={
131+
<DialogClose asChild>
132+
<Button variant="tertiary/medium">Cancel</Button>
133+
</DialogClose>
134+
}
135+
/>
133136
</Fieldset>
134137
</Form>
135138
</div>

apps/webapp/app/components/ListPagination.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function NextButton({ cursor }: { cursor?: string }) {
2626
<LinkButton
2727
to={path ?? "#"}
2828
variant={"minimal/small"}
29-
TrailingIcon="arrow-right"
29+
TrailingIcon="chevron-right"
3030
trailingIconClassName="text-text-dimmed"
3131
className={cn(
3232
"flex items-center",
@@ -47,7 +47,7 @@ function PreviousButton({ cursor }: { cursor?: string }) {
4747
<LinkButton
4848
to={path ?? "#"}
4949
variant={"minimal/small"}
50-
LeadingIcon="arrow-left"
50+
LeadingIcon="chevron-left"
5151
leadingIconClassName="text-text-dimmed"
5252
className={cn(
5353
"flex items-center",

apps/webapp/app/components/environments/RegenerateApiKeyModal.tsx

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
import { ArrowPathIcon, ArrowRightIcon } from "@heroicons/react/20/solid";
2-
import { ExclamationTriangleIcon } from "@heroicons/react/24/solid";
1+
import { ArrowPathIcon } from "@heroicons/react/20/solid";
32
import { useFetcher } from "@remix-run/react";
43
import { useState } from "react";
54
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from "~/components/primitives/Dialog";
65
import { generateTwoRandomWords } from "~/utils/randomWords";
76
import { Button } from "../primitives/Buttons";
8-
import { Header1 } from "../primitives/Headers";
9-
import { Input } from "../primitives/Input";
10-
import { Paragraph } from "../primitives/Paragraph";
11-
import { Spinner } from "../primitives/Spinner";
127
import { Callout } from "../primitives/Callout";
138
import { Fieldset } from "../primitives/Fieldset";
14-
import { InputGroup } from "../primitives/InputGroup";
159
import { FormButtons } from "../primitives/FormButtons";
10+
import { Input } from "../primitives/Input";
11+
import { InputGroup } from "../primitives/InputGroup";
12+
import { Paragraph } from "../primitives/Paragraph";
13+
import { Spinner } from "../primitives/Spinner";
1614

1715
type ModalProps = {
1816
id: string;
@@ -31,15 +29,17 @@ export function RegenerateApiKeyModal({ id, title }: ModalProps) {
3129
<Dialog open={open} onOpenChange={setOpen}>
3230
<DialogTrigger asChild>
3331
<Button
34-
variant="minimal/small"
35-
leadingIconClassName="text-text-dimmed"
32+
variant="small-menu-item"
33+
fullWidth
34+
textAlignLeft
35+
leadingIconClassName="text-success"
3636
LeadingIcon={ArrowPathIcon}
3737
>
38-
Regenerate
38+
Regenerate
3939
</Button>
4040
</DialogTrigger>
4141
<DialogContent>
42-
<DialogHeader>{`Regenerate ${title} Environment Key`}</DialogHeader>
42+
<DialogHeader>{`Regenerate ${title.toUpperCase()} environment key`}</DialogHeader>
4343
<RegenerateApiKeyModalContent
4444
id={id}
4545
title={title}
@@ -62,18 +62,18 @@ const RegenerateApiKeyModalContent = ({ id, randomWord, title, closeModal }: Mod
6262
}
6363

6464
return (
65-
<div className="flex flex-col items-center gap-y-5 py-4">
65+
<div className="flex flex-col items-center gap-y-4 pt-4">
6666
<Callout variant="warning">
67-
{`Regenerating the keys for this environment will temporarily break any live Jobs in the
68-
${title} Environmentuntil the new API keys are set in the relevant environment variables.`}
67+
{`Regenerating the keys for this environment will temporarily break any live tasks in the
68+
${title} environment until the new API keys are set in the relevant environment variables.`}
6969
</Callout>
7070
<fetcher.Form
7171
method="post"
7272
action={`/resources/environments/${id}/regenerate-api-key`}
7373
className="mt-2 w-full"
7474
>
7575
<Fieldset className="w-full">
76-
<InputGroup>
76+
<InputGroup className="max-w-full">
7777
<Paragraph variant="small/bright">Enter this text below to confirm:</Paragraph>
7878
<Paragraph
7979
variant="small"
@@ -93,14 +93,14 @@ const RegenerateApiKeyModalContent = ({ id, randomWord, title, closeModal }: Mod
9393
confirmButton={
9494
<Button
9595
type="submit"
96-
variant={"primary/small"}
96+
variant={"primary/medium"}
9797
LeadingIcon={isSubmitting ? Spinner : undefined}
9898
disabled={confirmationText !== randomWord}
9999
>
100100
Regenerate
101101
</Button>
102102
}
103-
cancelButton={<Button variant={"tertiary/small"}>Cancel</Button>}
103+
cancelButton={<Button variant={"tertiary/medium"}>Cancel</Button>}
104104
/>
105105
</Fieldset>
106106
</fetcher.Form>

apps/webapp/app/components/primitives/Buttons.tsx

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,40 +41,53 @@ type Size = keyof typeof sizes;
4141
const theme = {
4242
primary: {
4343
textColor:
44-
"text-charcoal-900 group-hover:text-charcoal-900 transition group-disabled:text-charcoal-900",
44+
"text-charcoal-900 group-hover/button:text-charcoal-900 transition group-disabled/button:text-charcoal-900",
4545
button:
46-
"bg-primary group-hover:bg-apple-200 group-disabled:opacity-50 group-disabled:bg-primary group-disabled:pointer-events-none",
46+
"bg-primary group-hover/button:bg-apple-200 group-disabled/button:opacity-50 group-disabled/button:bg-primary group-disabled/button:pointer-events-none",
4747
shortcut:
48-
"border-black/40 text-charcoal-900 group-hover:border-black/60 group-hover:text-charcoal-900",
48+
"border-black/40 text-charcoal-900 group-hover/button:border-black/60 group-hover/button:text-charcoal-900",
49+
icon: "text-charcoal-900",
4950
},
5051
secondary: {
51-
textColor: "text-text-bright transition group-disabled:text-text-dimmed/80",
52+
textColor: "text-text-bright transition group-disabled/button:text-text-dimmed/80",
5253
button:
53-
"bg-secondary group-hover:bg-charcoal-600 group-hover:border-charcoal-650 border border-charcoal-600 group-disabled:bg-secondary group-disabled:opacity-60 group-disabled:pointer-events-none",
54+
"bg-secondary group-hover/button:bg-charcoal-600 group-hover/button:border-charcoal-650 border border-charcoal-600 group-disabled/button:bg-secondary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
5455
shortcut:
55-
"border-text-dimmed/40 text-text-dimmed group-hover:text-text-bright group-hover:border-text-dimmed",
56+
"border-text-dimmed/40 text-text-dimmed group-hover/button:text-text-bright group-hover/button:border-text-dimmed",
57+
icon: "text-text-bright",
5658
},
5759
tertiary: {
58-
textColor: "text-text-bright transition group-disabled:text-text-dimmed/80",
60+
textColor: "text-text-bright transition group-disabled/button:text-text-dimmed/80",
5961
button:
60-
"bg-tertiary group-hover:bg-charcoal-600 group-disabled:bg-tertiary group-disabled:opacity-60 group-disabled:pointer-events-none",
62+
"bg-tertiary group-hover/button:bg-charcoal-600 group-disabled/button:bg-tertiary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
6163
shortcut:
62-
"border-text-dimmed/40 text-text-dimmed group-hover:text-text-bright group-hover:border-text-dimmed",
64+
"border-text-dimmed/40 text-text-dimmed group-hover/button:text-text-bright group-hover/button:border-text-dimmed",
65+
icon: "text-text-bright",
6366
},
6467
minimal: {
6568
textColor:
66-
"text-text-dimmed group-hover:text-text-bright transition group-disabled:text-text-dimmed/80",
69+
"text-text-dimmed group-hover/button:text-text-bright transition group-disabled/button:text-text-dimmed/80",
6770
button:
68-
"bg-transparent group-hover:bg-tertiary disabled:opacity-50 group-disabled:bg-transparent group-disabled:pointer-events-none",
71+
"bg-transparent group-hover/button:bg-tertiary disabled:opacity-50 group-disabled/button:bg-transparent group-disabled/button:pointer-events-none",
6972
shortcut:
70-
"border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60",
73+
"border-dimmed/40 text-text-dimmed group-hover/button:text-text-bright/80 group-hover/button:border-dimmed/60",
74+
icon: "text-text-dimmed",
7175
},
7276
danger: {
7377
textColor:
74-
"text-text-bright group-hover:text-white transition group-disabled:text-text-bright/80",
78+
"text-text-bright group-hover/button:text-white transition group-disabled/button:text-text-bright/80",
7579
button:
76-
"bg-error group-hover:bg-rose-500 disabled:opacity-50 group-disabled:bg-error group-disabled:pointer-events-none",
77-
shortcut: "border-text-bright text-text-bright group-hover:border-bright/60",
80+
"bg-error group-hover/button:bg-rose-500 disabled:opacity-50 group-disabled/button:bg-error group-disabled/button:pointer-events-none",
81+
shortcut: "border-text-bright text-text-bright group-hover/button:border-bright/60",
82+
icon: "text-text-bright",
83+
},
84+
docs: {
85+
textColor: "text-blue-200/70 transition group-disabled/button:text-text-dimmed/80",
86+
button:
87+
"bg-charcoal-700 border border-charcoal-600/50 shadow group-hover/button:bg-charcoal-650 group-disabled/button:bg-tertiary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
88+
shortcut:
89+
"border-text-dimmed/40 text-text-dimmed group-hover/button:text-text-bright group-hover/button:border-text-dimmed",
90+
icon: "text-blue-500",
7891
},
7992
};
8093

@@ -84,7 +97,7 @@ function createVariant(sizeName: Size, themeName: Theme) {
8497
return {
8598
textColor: theme[themeName].textColor,
8699
button: cn(sizes[sizeName].button, theme[themeName].button),
87-
icon: sizes[sizeName].icon,
100+
icon: cn(sizes[sizeName].icon, theme[themeName].icon),
88101
iconSpacing: sizes[sizeName].iconSpacing,
89102
shortcutVariant: sizes[sizeName].shortcutVariant,
90103
shortcut: cn(sizes[sizeName].shortcut, theme[themeName].shortcut),
@@ -112,9 +125,14 @@ const variant = {
112125
"danger/medium": createVariant("medium", "danger"),
113126
"danger/large": createVariant("large", "danger"),
114127
"danger/extra-large": createVariant("extra-large", "danger"),
128+
"docs/small": createVariant("small", "docs"),
129+
"docs/medium": createVariant("medium", "docs"),
130+
"docs/large": createVariant("large", "docs"),
131+
"docs/extra-large": createVariant("extra-large", "docs"),
115132
"menu-item": {
116133
textColor: "text-text-bright px-1",
117-
button: "h-9 px-[0.475rem] text-sm rounded-sm bg-transparent group-hover:bg-charcoal-750",
134+
button:
135+
"h-9 px-[0.475rem] text-sm rounded-sm bg-transparent group-hover/button:bg-charcoal-750",
118136
icon: "h-5",
119137
iconSpacing: "gap-x-0.5",
120138
shortcutVariant: undefined,
@@ -123,7 +141,7 @@ const variant = {
123141
"small-menu-item": {
124142
textColor: "text-text-bright",
125143
button:
126-
"h-[1.8rem] px-[0.4rem] text-2sm rounded-sm text-text-dimmed bg-transparent group-hover:bg-charcoal-750",
144+
"h-[1.8rem] px-[0.4rem] text-2sm rounded-sm text-text-dimmed bg-transparent group-hover/button:bg-charcoal-750",
127145
icon: "h-4",
128146
iconSpacing: "gap-x-1.5",
129147
shortcutVariant: undefined,
@@ -132,7 +150,7 @@ const variant = {
132150
"small-menu-sub-item": {
133151
textColor: "text-text-dimmed",
134152
button:
135-
"h-[1.8rem] px-[0.5rem] ml-5 text-2sm rounded-sm text-text-dimmed bg-transparent group-hover:bg-charcoal-750 focus-custom",
153+
"h-[1.8rem] px-[0.5rem] ml-5 text-2sm rounded-sm text-text-dimmed bg-transparent group-hover/button:bg-charcoal-750 focus-custom",
136154
icon: undefined,
137155
iconSpacing: undefined,
138156
shortcutVariant: undefined,
@@ -141,7 +159,7 @@ const variant = {
141159
};
142160

143161
const allVariants = {
144-
$all: "font-normal text-center font-sans justify-center items-center shrink-0 transition duration-150 rounded-[3px] select-none group-focus:outline-none group-disabled:opacity-75 group-disabled:pointer-events-none focus-custom",
162+
$all: "font-normal text-center font-sans justify-center items-center shrink-0 transition duration-150 rounded-[3px] select-none group-focus/button:outline-none group-disabled/button:opacity-75 group-disabled/button:pointer-events-none focus-custom",
145163
variant: variant,
146164
};
147165

@@ -192,13 +210,18 @@ export function ButtonContent(props: ButtonContentPropsType) {
192210
(typeof LeadingIcon === "string" ? (
193211
<NamedIcon
194212
name={LeadingIcon}
195-
className={cn(iconClassName, leadingIconClassName, "shrink-0 justify-start")}
213+
className={cn(
214+
iconClassName,
215+
leadingIconClassName,
216+
"shrink-0 justify-start",
217+
variation.icon
218+
)}
196219
/>
197220
) : (
198221
<LeadingIcon
199222
className={cn(
200223
iconClassName,
201-
textColorClassName,
224+
variation.icon,
202225
leadingIconClassName,
203226
"shrink-0 justify-start"
204227
)}
@@ -218,13 +241,18 @@ export function ButtonContent(props: ButtonContentPropsType) {
218241
(typeof TrailingIcon === "string" ? (
219242
<NamedIcon
220243
name={TrailingIcon}
221-
className={cn(iconClassName, trailingIconClassName, "shrink-0 justify-end")}
244+
className={cn(
245+
iconClassName,
246+
trailingIconClassName,
247+
"shrink-0 justify-end",
248+
variation.icon
249+
)}
222250
/>
223251
) : (
224252
<TrailingIcon
225253
className={cn(
226254
iconClassName,
227-
textColorClassName,
255+
variation.icon,
228256
trailingIconClassName,
229257
"shrink-0 justify-end"
230258
)}
@@ -267,7 +295,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonPropsType>(
267295

268296
return (
269297
<button
270-
className={cn("group outline-none focus-custom", props.fullWidth ? "w-full" : "")}
298+
className={cn("group/button outline-none focus-custom", props.fullWidth ? "w-full" : "")}
271299
type={type}
272300
disabled={disabled}
273301
onClick={onClick}
@@ -313,7 +341,7 @@ export const LinkButton = ({
313341
return (
314342
<div
315343
className={cn(
316-
"group pointer-events-none cursor-default opacity-40 outline-none",
344+
"group/button pointer-events-none cursor-default opacity-40 outline-none",
317345
props.fullWidth ? "w-full" : ""
318346
)}
319347
>
@@ -327,7 +355,7 @@ export const LinkButton = ({
327355
<ExtLink
328356
href={to.toString()}
329357
ref={innerRef}
330-
className={cn("group focus-custom", props.fullWidth ? "w-full" : "")}
358+
className={cn("group/button focus-custom", props.fullWidth ? "w-full" : "")}
331359
onClick={onClick}
332360
onMouseDown={onMouseDown}
333361
onMouseEnter={onMouseEnter}
@@ -342,7 +370,7 @@ export const LinkButton = ({
342370
<Link
343371
to={to}
344372
ref={innerRef}
345-
className={cn("group focus-custom", props.fullWidth ? "w-full" : "")}
373+
className={cn("group/button focus-custom", props.fullWidth ? "w-full" : "")}
346374
onClick={onClick}
347375
onMouseDown={onMouseDown}
348376
onMouseEnter={onMouseEnter}
@@ -363,7 +391,7 @@ export const NavLinkButton = ({ to, className, target, ...props }: NavLinkPropsT
363391
return (
364392
<NavLink
365393
to={to}
366-
className={cn("group outline-none", props.fullWidth ? "w-full" : "")}
394+
className={cn("group/button outline-none", props.fullWidth ? "w-full" : "")}
367395
target={target}
368396
>
369397
{({ isActive, isPending }) => (

0 commit comments

Comments
 (0)