Skip to content

Commit 6a312fe

Browse files
atrakhConvex, Inc.
authored andcommitted
dashboard: split prod and preview deploy key lists into separate sections (#42260)
Also removes the callout that displayed when viewing the keys - it was unnecessary GitOrigin-RevId: c55540c6f99048c56413cbca05a6170aab4863a1
1 parent 5694a50 commit 6a312fe

File tree

4 files changed

+111
-129
lines changed

4 files changed

+111
-129
lines changed

npm-packages/dashboard/src/components/AccessTokenListItem.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { EyeOpenIcon, EyeNoneIcon, Cross2Icon } from "@radix-ui/react-icons";
22
import { AccessTokenListKind, useDeleteAccessToken } from "api/accessTokens";
33
import { Button } from "@ui/Button";
44
import { TimestampDistance } from "@common/elements/TimestampDistance";
5-
import { Callout } from "@ui/Callout";
65
import { ConfirmationDialog } from "@ui/ConfirmationDialog";
76
import { CopyTextButton } from "@common/elements/CopyTextButton";
87
import { TeamAccessTokenResponse } from "generatedApi";
@@ -17,15 +16,13 @@ export function AccessTokenListItem({
1716
kind,
1817
shouldShow,
1918
showMemberName = true,
20-
showCallout = true,
2119
}: {
2220
token: TeamAccessTokenResponse;
2321
identifier: string;
2422
tokenPrefix?: string;
2523
kind: AccessTokenListKind;
2624
shouldShow: boolean;
2725
showMemberName?: boolean;
28-
showCallout?: boolean;
2926
}) {
3027
const team = useCurrentTeam();
3128
const members = useTeamMembers(team?.id);
@@ -98,14 +95,7 @@ export function AccessTokenListItem({
9895
</div>
9996
<div className="mb-2 flex items-center gap-1">
10097
{showToken && (
101-
<div className="flex flex-col gap-1">
102-
{showCallout && (
103-
<Callout variant="instructions" className="mb-2 max-w-[30rem]">
104-
This key enables reading and writing data to your deployment
105-
without needing to log in, so it should not be shared or
106-
committed to git.
107-
</Callout>
108-
)}
98+
<div className="mt-1 flex flex-col gap-1">
10999
<CopyTextButton
110100
text={
111101
tokenPrefix

npm-packages/dashboard/src/components/deploymentSettings/DeploymentAccessTokenList.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export function DeploymentAccessTokenList({
1919
buttonProps,
2020
header,
2121
description,
22+
headingLevel = "h4",
2223
}: {
2324
identifier: string;
2425
tokenPrefix: string;
@@ -31,12 +32,14 @@ export function DeploymentAccessTokenList({
3132
>;
3233
header: string;
3334
description: React.ReactNode;
35+
headingLevel?: "h3" | "h4";
3436
}) {
3537
const [latestToken, setLatestToken] = useState<string | null>(null);
38+
const HeadingTag = (headingLevel ?? "h4") as keyof JSX.IntrinsicElements;
3639
return (
3740
<>
3841
<div className="mb-2 flex w-full items-center justify-between">
39-
<h4>{header}</h4>
42+
<HeadingTag>{header}</HeadingTag>
4043
<GenerateDeployKeyWithNameButton
4144
{...buttonProps}
4245
onCreateAccessToken={setLatestToken}
@@ -64,7 +67,6 @@ export function DeploymentAccessTokenList({
6467
latestToken.endsWith(token.serializedAccessToken)
6568
}
6669
showMemberName
67-
showCallout
6870
/>
6971
))
7072
) : (

npm-packages/dashboard/src/components/teamSettings/TeamAccessTokens.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ export function TeamAccessTokens({
9494
identifier={team.id.toString()}
9595
shouldShow={false}
9696
showMemberName={false}
97-
showCallout={false}
9897
/>
9998
))
10099
) : (

npm-packages/dashboard/src/pages/t/[team]/[project]/settings.tsx

Lines changed: 106 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ const SECTION_IDS = {
5959
projectRoles: "project-roles",
6060
projectUsage: "project-usage",
6161
customDomains: "custom-domains",
62-
deployKeys: "deploy-keys",
62+
productionDeployKeys: "production-deploy-keys",
63+
previewDeployKeys: "preview-deploy-keys",
6364
authorizedApps: "applications",
6465
envVars: "env-vars",
6566
lostAccess: "lost-access",
@@ -72,7 +73,8 @@ const sections = [
7273
{ id: SECTION_IDS.projectRoles, label: "Project Admins" },
7374
{ id: SECTION_IDS.projectUsage, label: "Project Usage" },
7475
{ id: SECTION_IDS.customDomains, label: "Custom Domains" },
75-
{ id: SECTION_IDS.deployKeys, label: "Deploy Keys" },
76+
{ id: SECTION_IDS.productionDeployKeys, label: "Production Deploy Keys" },
77+
{ id: SECTION_IDS.previewDeployKeys, label: "Preview Deploy Keys" },
7678
{
7779
id: SECTION_IDS.authorizedApps,
7880
label: "Authorized Applications",
@@ -377,13 +379,18 @@ function ProjectSettings() {
377379
</div>
378380
)}
379381
{project && (
380-
<div id={SECTION_IDS.deployKeys}>
381-
<GenerateDeployKey
382+
<div id={SECTION_IDS.productionDeployKeys}>
383+
<ProductionDeployKeys
382384
project={project}
383385
hasAdminPermissions={hasAdminPermissions}
384386
/>
385387
</div>
386388
)}
389+
{project && (
390+
<div id={SECTION_IDS.previewDeployKeys}>
391+
<PreviewDeployKeys project={project} />
392+
</div>
393+
)}
387394
{project && (
388395
<div id={SECTION_IDS.authorizedApps}>
389396
<AuthorizedApplications
@@ -482,27 +489,6 @@ function DeleteProject() {
482489
);
483490
}
484491

485-
function GenerateDeployKey({
486-
project,
487-
hasAdminPermissions,
488-
}: {
489-
project: ProjectDetails;
490-
hasAdminPermissions: boolean;
491-
}) {
492-
return (
493-
<Sheet className="flex flex-col gap-4">
494-
<h3>Deploy Keys</h3>
495-
<div className="flex flex-col gap-4 divide-y">
496-
<ProductionDeployKeys
497-
project={project}
498-
hasAdminPermissions={hasAdminPermissions}
499-
/>
500-
<PreviewDeployKeys project={project} />
501-
</div>
502-
</Sheet>
503-
);
504-
}
505-
506492
function ProductionDeployKeys({
507493
project,
508494
hasAdminPermissions,
@@ -529,7 +515,7 @@ function ProductionDeployKeys({
529515

530516
const deployKeyDescription = (
531517
<p className="mb-2 text-sm text-content-primary">
532-
This is the key for your{" "}
518+
These keys are for your{" "}
533519
<Link passHref href={prodHref} className="text-content-link">
534520
<DeploymentType deploymentType="prod" /> deployment
535521
</Link>
@@ -557,40 +543,43 @@ function ProductionDeployKeys({
557543
);
558544

559545
return (
560-
<div className="flex flex-col gap-2">
561-
{team && prodDeployment ? (
562-
<DeploymentAccessTokenList
563-
header="Production"
564-
description={deployKeyDescription}
565-
disabledReason={disabledReason}
566-
buttonProps={{
567-
deploymentType: "prod",
568-
getAdminKey: async (name: string) =>
569-
getAccessTokenBasedDeployKey(
570-
prodDeployment,
571-
project,
572-
team,
573-
`prod:${prodDeployment.name}`,
574-
accessToken,
575-
createAccessTokenMutation,
576-
name,
577-
),
578-
disabledReason,
579-
}}
580-
identifier={prodDeployment.name}
581-
tokenPrefix={`prod:${prodDeployment.name}`}
582-
accessTokens={accessTokens}
583-
kind="deployment"
584-
/>
585-
) : (
586-
<div className="mb-4">
587-
<h4 className="mb-2">Production</h4>
588-
<p className="text-sm text-content-primary">
589-
This project does not have a Production deployment yet.
590-
</p>
591-
</div>
592-
)}
593-
</div>
546+
<Sheet className="flex flex-col gap-4">
547+
<div className="flex flex-col gap-2">
548+
{team && prodDeployment ? (
549+
<DeploymentAccessTokenList
550+
header="Production Deploy Keys"
551+
headingLevel="h3"
552+
description={deployKeyDescription}
553+
disabledReason={disabledReason}
554+
buttonProps={{
555+
deploymentType: "prod",
556+
getAdminKey: async (name: string) =>
557+
getAccessTokenBasedDeployKey(
558+
prodDeployment,
559+
project,
560+
team,
561+
`prod:${prodDeployment.name}`,
562+
accessToken,
563+
createAccessTokenMutation,
564+
name,
565+
),
566+
disabledReason,
567+
}}
568+
identifier={prodDeployment.name}
569+
tokenPrefix={`prod:${prodDeployment.name}`}
570+
accessTokens={accessTokens}
571+
kind="deployment"
572+
/>
573+
) : (
574+
<>
575+
<h3>Production Deploy Keys</h3>
576+
<p className="text-sm text-content-primary">
577+
This project does not have a Production deployment yet.
578+
</p>
579+
</>
580+
)}
581+
</div>
582+
</Sheet>
594583
);
595584
}
596585

@@ -632,62 +621,64 @@ function PreviewDeployKeys({ project }: { project: ProjectDetails }) {
632621
</p>
633622
);
634623

635-
if (!arePreviewDeploymentsAvailable) {
636-
return (
637-
<div className="pt-4">
638-
<Callout>
639-
<p>
640-
<Link
641-
passHref
642-
href="https://docs.convex.dev/production/hosting/preview-deployments"
643-
className="underline"
644-
target="_blank"
645-
>
646-
Preview deployments
647-
</Link>
648-
{" are only available on the Pro plan. "}
649-
<Link
650-
href={`/${selectedTeamSlug}/settings/billing`}
651-
className="underline"
652-
>
653-
Upgrade to get access.
654-
</Link>
655-
</p>
656-
</Callout>
657-
<LocalDevCallout
658-
tipText="Tip: Run this to enable preview deployments locally:"
659-
command={`cargo run --bin big-brain-tool -- --dev grant-entitlement --team-entitlement project_max_preview_deployments --team-id ${team?.id} --reason "local" 200 --for-real`}
660-
/>
661-
</div>
662-
);
663-
}
664-
665624
return (
666-
<div className="flex flex-col gap-2 pt-4">
667-
{team && accessToken && createProjectAccessTokenMutation && (
668-
<DeploymentAccessTokenList
669-
identifier={project.id.toString()}
670-
tokenPrefix={`preview:${selectedTeamSlug}:${project.slug}`}
671-
accessTokens={projectAccessTokens}
672-
kind="project"
673-
disabledReason={null}
674-
buttonProps={{
675-
deploymentType: "preview",
676-
disabledReason: null,
677-
getAdminKey: async (name: string) =>
678-
getAccessTokenBasedDeployKeyForPreview(
679-
project,
680-
team,
681-
`preview:${selectedTeamSlug}:${project.slug}`,
682-
accessToken,
683-
createProjectAccessTokenMutation,
684-
name,
685-
),
686-
}}
687-
header="Preview"
688-
description={deployKeyDescription}
689-
/>
625+
<Sheet className="flex flex-col gap-4">
626+
{!arePreviewDeploymentsAvailable ? (
627+
<>
628+
<h3>Preview Deploy Keys</h3>
629+
<Callout>
630+
<p>
631+
<Link
632+
passHref
633+
href="https://docs.convex.dev/production/hosting/preview-deployments"
634+
className="underline"
635+
target="_blank"
636+
>
637+
Preview deployments
638+
</Link>
639+
{" are only available on the Pro plan. "}
640+
<Link
641+
href={`/${selectedTeamSlug}/settings/billing`}
642+
className="underline"
643+
>
644+
Upgrade to get access.
645+
</Link>
646+
</p>
647+
</Callout>
648+
<LocalDevCallout
649+
tipText="Tip: Run this to enable preview deployments locally:"
650+
command={`cargo run --bin big-brain-tool -- --dev grant-entitlement --team-entitlement project_max_preview_deployments --team-id ${team?.id} --reason "local" 200 --for-real`}
651+
/>
652+
</>
653+
) : (
654+
<div className="flex flex-col gap-2">
655+
{team && accessToken && createProjectAccessTokenMutation && (
656+
<DeploymentAccessTokenList
657+
identifier={project.id.toString()}
658+
tokenPrefix={`preview:${selectedTeamSlug}:${project.slug}`}
659+
accessTokens={projectAccessTokens}
660+
kind="project"
661+
disabledReason={null}
662+
buttonProps={{
663+
deploymentType: "preview",
664+
disabledReason: null,
665+
getAdminKey: async (name: string) =>
666+
getAccessTokenBasedDeployKeyForPreview(
667+
project,
668+
team,
669+
`preview:${selectedTeamSlug}:${project.slug}`,
670+
accessToken,
671+
createProjectAccessTokenMutation,
672+
name,
673+
),
674+
}}
675+
header="Preview Deploy Keys"
676+
headingLevel="h3"
677+
description={deployKeyDescription}
678+
/>
679+
)}
680+
</div>
690681
)}
691-
</div>
682+
</Sheet>
692683
);
693684
}

0 commit comments

Comments
 (0)