Skip to content

Commit 066c11b

Browse files
Add better name validation and description on second modal page
1 parent 5fd8ca6 commit 066c11b

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

packages/maas/frontend/src/app/pages/api-keys/AllApiKeysPage.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import ApiKeysActions from './ApiKeysActions';
1111
const AllApiKeysPage: React.FC = () => {
1212
const [apiKeys, loaded, error, refresh] = useFetchApiKeys();
1313
const [isModalOpen, setIsModalOpen] = React.useState(false);
14+
const [modalKey, setModalKey] = React.useState(0);
1415

1516
return (
1617
<ApplicationsPage
@@ -23,6 +24,7 @@ const AllApiKeysPage: React.FC = () => {
2324
headerAction={<ApiKeysActions apiKeyCount={apiKeys.length} onRefresh={refresh} />}
2425
>
2526
<CreateApiKeyModal
27+
key={modalKey}
2628
isOpen={isModalOpen}
2729
onClose={() => {
2830
setIsModalOpen(false);
@@ -38,7 +40,10 @@ const AllApiKeysPage: React.FC = () => {
3840
<Button
3941
variant="primary"
4042
icon={<PlusIcon />}
41-
onClick={() => setIsModalOpen(true)}
43+
onClick={() => {
44+
setModalKey((prev) => prev + 1);
45+
setIsModalOpen(true);
46+
}}
4247
data-testid="create-api-key-button"
4348
>
4449
Create API key

packages/maas/frontend/src/app/pages/api-keys/CreateApiKeyModal.tsx

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ const dateToGoDuration = (selectedDate: Date): string => {
5757
};
5858

5959
const createApiKeySchema = z.object({
60-
name: z.string().min(1, 'Name is required'),
60+
name: z
61+
.string()
62+
.min(1, 'Name is required')
63+
.refine((val) => /^[a-zA-Z0-9_-]+$/.test(val), {
64+
message: 'Name can only contain letters, numbers, dashes, and underscores',
65+
}),
6166
description: z.string().optional(),
6267
expirationDate: z
6368
.date()
@@ -93,7 +98,10 @@ const CreateApiKeyModal: React.FC<CreateApiKeyModalProps> = ({ isOpen, onClose }
9398
const [error, setError] = React.useState<Error | undefined>();
9499
const [createdToken, setCreatedToken] = React.useState<string | undefined>();
95100

96-
const { markFieldTouched } = useZodFormValidation(formData, createApiKeySchema);
101+
const { getFieldValidation, getFieldValidationProps } = useZodFormValidation(
102+
formData,
103+
createApiKeySchema,
104+
);
97105

98106
const dateValidator = (date: Date) => {
99107
const dateAtMidnight = new Date(date);
@@ -204,6 +212,14 @@ const CreateApiKeyModal: React.FC<CreateApiKeyModalProps> = ({ isOpen, onClose }
204212
{formData.name}
205213
</DescriptionListDescription>
206214
</DescriptionListGroup>
215+
{formData.description && (
216+
<DescriptionListGroup>
217+
<DescriptionListTerm>Description</DescriptionListTerm>
218+
<DescriptionListDescription data-testid="api-key-display-description">
219+
{formData.description}
220+
</DescriptionListDescription>
221+
</DescriptionListGroup>
222+
)}
207223
{formData.expirationDate ? (
208224
<DescriptionListGroup>
209225
<DescriptionListTerm>Expiration</DescriptionListTerm>
@@ -248,14 +264,23 @@ const CreateApiKeyModal: React.FC<CreateApiKeyModalProps> = ({ isOpen, onClose }
248264
name="api-key-name"
249265
value={formData.name}
250266
onChange={(_event, value) => setFormData({ ...formData, name: value })}
251-
onBlur={() => markFieldTouched(['name'])}
267+
{...getFieldValidationProps(['name'])}
252268
data-testid="api-key-name-input"
253269
/>
254270
<FormHelperText>
255271
<HelperText>
256272
<HelperTextItem>A descriptive name for this API key</HelperTextItem>
257273
</HelperText>
258274
</FormHelperText>
275+
{getFieldValidation(['name']).length > 0 && (
276+
<FormHelperText>
277+
<HelperText>
278+
<HelperTextItem variant="error">
279+
{getFieldValidation(['name'])[0].message}
280+
</HelperTextItem>
281+
</HelperText>
282+
</FormHelperText>
283+
)}
259284
</FormGroup>
260285

261286
<FormGroup label="Description" fieldId="api-key-description">

0 commit comments

Comments
 (0)