Skip to content

Commit 02bebb7

Browse files
carderneTrigger.dev RepoOps
authored andcommitted
feat(webapp): guide users from root keys to individual API keys
- Add a compact API key migration callout only while the environment's root key is visible. - Put migration instructions in a dedicated modal: create an individual key, update applications, then hide the root key with a clear 24-hour expiry warning. Return users to these steps after key creation. - Keep root key regeneration directly available, with an inline recommendation linking to the migration flow. - Align callout buttons with their copy and make the root-key confirmation text consistent. Mono-RevId: da4ab2309bb2447a8b47945ddd490094f4a1a926
1 parent 01b2bad commit 02bebb7

4 files changed

Lines changed: 958 additions & 783 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: improvement
4+
---
5+
6+
Guide switching from shared root keys to individually managed API keys, while keeping root key regeneration directly available.

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type ModalProps = {
2020
hasVercelIntegration: boolean;
2121
isDevelopment: boolean;
2222
isRootApiKeyHidden?: boolean;
23+
onSwitchToApiKeys: () => void;
2324
};
2425

2526
type ModalContentProps = ModalProps & {
@@ -33,9 +34,11 @@ export function RegenerateApiKeyModal({
3334
hasVercelIntegration,
3435
isDevelopment,
3536
isRootApiKeyHidden = false,
37+
onSwitchToApiKeys,
3638
}: ModalProps) {
3739
const randomWord = generateTwoRandomWords();
3840
const [open, setOpen] = useState(false);
41+
3942
return (
4043
<Dialog open={open} onOpenChange={setOpen}>
4144
<DialogTrigger asChild>
@@ -51,6 +54,7 @@ export function RegenerateApiKeyModal({
5154
hasVercelIntegration={hasVercelIntegration}
5255
isDevelopment={isDevelopment}
5356
isRootApiKeyHidden={isRootApiKeyHidden}
57+
onSwitchToApiKeys={onSwitchToApiKeys}
5458
randomWord={randomWord}
5559
closeModal={() => setOpen(false)}
5660
/>
@@ -66,6 +70,7 @@ const RegenerateApiKeyModalContent = ({
6670
hasVercelIntegration,
6771
isDevelopment,
6872
isRootApiKeyHidden,
73+
onSwitchToApiKeys,
6974
closeModal,
7075
}: ModalContentProps) => {
7176
const [confirmationText, setConfirmationText] = useState("");
@@ -79,6 +84,24 @@ const RegenerateApiKeyModalContent = ({
7984

8085
return (
8186
<div className="flex flex-col items-center gap-y-4 pt-4">
87+
{!isRootApiKeyHidden ? (
88+
<Callout variant="info">
89+
<div className="flex flex-col items-start gap-2">
90+
<Paragraph variant="small">
91+
For routine key management, use individually managed API keys instead.
92+
</Paragraph>
93+
<Button
94+
variant="secondary/small"
95+
onClick={() => {
96+
closeModal();
97+
onSwitchToApiKeys();
98+
}}
99+
>
100+
Switch to API keys…
101+
</Button>
102+
</div>
103+
</Callout>
104+
) : null}
82105
<Callout variant="warning">
83106
{`A new API key will be issued for the ${title} environment. Choose what happens to the previous key.`}
84107
</Callout>

0 commit comments

Comments
 (0)