Webhooks for the AT Protocol airglow.run
atproto atprotocol automation webhook
12
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: copy secret to clipboard

Hugo dfcc6517 368337cb

+35 -1
+10
app/islands/SecretsManager.css.ts
··· 101 101 fontWeight: fontWeight.medium, 102 102 fontFamily: "monospace", 103 103 color: vars.color.text, 104 + cursor: "pointer", 105 + borderRadius: radii.sm, 106 + paddingBlock: space[1], 107 + paddingInline: space[2], 108 + marginInlineStart: `calc(-1 * ${space[2]})`, 109 + transition: "background-color 0.15s, color 0.15s", 110 + ":hover": { 111 + backgroundColor: vars.color.accentSubtle, 112 + color: vars.color.accent, 113 + }, 104 114 }); 105 115 106 116 export const secretMeta = style({
+25 -1
app/islands/SecretsManager.tsx
··· 25 25 const [error, setError] = useState(""); 26 26 const [success, setSuccess] = useState(""); 27 27 const [deleting, setDeleting] = useState<string | null>(null); 28 + const [hovered, setHovered] = useState<string | null>(null); 29 + const [copied, setCopied] = useState<string | null>(null); 28 30 29 31 const handleSubmit = useCallback( 30 32 async (e: Event) => { ··· 67 69 }, 68 70 [name, value, secrets], 69 71 ); 72 + 73 + const handleCopy = useCallback((secretName: string) => { 74 + const template = `{{secret:${secretName}}}`; 75 + navigator.clipboard.writeText(template).then( 76 + () => { 77 + setCopied(secretName); 78 + setTimeout(() => setCopied(null), 1500); 79 + }, 80 + () => setError("Failed to copy to clipboard"), 81 + ); 82 + }, []); 70 83 71 84 const handleDelete = useCallback(async (secretName: string) => { 72 85 setError(""); ··· 143 156 {secrets.map((secret) => ( 144 157 <div key={secret.name} class={s.secretRow}> 145 158 <div class={s.secretInfo}> 146 - <span class={s.secretName}>{secret.name}</span> 159 + <span 160 + class={s.secretName} 161 + onMouseEnter={() => setHovered(secret.name)} 162 + onMouseLeave={() => setHovered(null)} 163 + onClick={() => handleCopy(secret.name)} 164 + > 165 + {copied === secret.name 166 + ? "Copied!" 167 + : hovered === secret.name 168 + ? `{{secret:${secret.name}}}` 169 + : secret.name} 170 + </span> 147 171 <span class={s.secretMeta}>Updated {formatDate(secret.updatedAt)}</span> 148 172 </div> 149 173 <button