Skip to content

Commit aa90ec7

Browse files
committed
Refactor IdentityProviderMetadataForm
1 parent 83da900 commit aa90ec7

4 files changed

Lines changed: 411 additions & 286 deletions

File tree

packages/ui/src/components/ConfigureSSO/steps/ConfigureStep/saml/SamlCustomConfigureSteps.tsx

Lines changed: 111 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { type JSX } from 'react';
22

33
import { Col, descriptors, Heading, localizationKeys, Text } from '@/customizables';
44
import { ClipboardInput } from '@/elements/ClipboardInput';
5+
import { useCardState } from '@/elements/contexts';
56
import { Form } from '@/elements/Form';
67
import { Checkmark, Clipboard } from '@/icons';
78
import { useFormControl } from '@/ui/utils/useFormControl';
@@ -12,6 +13,7 @@ import { useWizard, Wizard } from '../../../elements/Wizard';
1213
import { InnerStepCounter } from '../../../elements/Wizard/InnerStepCounter';
1314
import { AttributeMappingTable, type AttributeMappingTableConfig } from './shared/AttributeMappingTable';
1415
import { IdentityProviderMetadataForm } from './shared/IdentityProviderMetadataForm';
16+
import { useIdentityProviderMetadataForm } from './shared/useIdentityProviderMetadataForm';
1517

1618
export const SamlCustomConfigureSteps = (): JSX.Element => {
1719
return (
@@ -250,29 +252,19 @@ const SamlCustomAssignUsersStep = (): JSX.Element => {
250252
);
251253
};
252254

253-
const SamlCustomIdentityProviderMetadataStep = (): JSX.Element => (
254-
<IdentityProviderMetadataForm
255-
modes={{
256-
title: localizationKeys('configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.title'),
257-
ariaLabel: localizationKeys('configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.ariaLabel'),
258-
metadataUrlLabel: localizationKeys(
259-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.metadataUrl',
260-
),
261-
manualLabel: localizationKeys('configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.manual'),
262-
}}
263-
metadataUrl={{
255+
const SamlCustomIdentityProviderMetadataStep = (): JSX.Element => {
256+
const card = useCardState();
257+
const { goNext, goPrev, isFirstStep } = useWizard();
258+
const { enterpriseConnection, updateEnterpriseConnection } = useConfigureSSO();
259+
260+
const controller = useIdentityProviderMetadataForm({
261+
metadataUrl: {
264262
label: localizationKeys('configureSSO.configureStep.samlCustom.identityProviderMetadataStep.metadataUrl.label'),
265263
placeholder: localizationKeys(
266264
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.metadataUrl.placeholder',
267265
),
268-
description: localizationKeys(
269-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.metadataUrl.description',
270-
),
271-
}}
272-
manual={{
273-
description: localizationKeys(
274-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.description',
275-
),
266+
},
267+
manual: {
276268
signOnUrl: {
277269
label: localizationKeys(
278270
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signOnUrl.label',
@@ -289,23 +281,103 @@ const SamlCustomIdentityProviderMetadataStep = (): JSX.Element => (
289281
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.issuer.placeholder',
290282
),
291283
},
292-
signingCertificate: {
293-
label: localizationKeys(
294-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.label',
295-
),
296-
uploadFile: localizationKeys(
297-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.uploadFile',
298-
),
299-
replaceFile: localizationKeys(
300-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.replaceFile',
301-
),
302-
removeFile: localizationKeys(
303-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.removeFile',
304-
),
305-
fileUploaded: localizationKeys(
306-
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.fileUploaded',
307-
),
308-
},
309-
}}
310-
/>
311-
);
284+
signingCertificateLabel: localizationKeys(
285+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.label',
286+
),
287+
},
288+
});
289+
290+
const canSubmit = !card.isLoading && controller.isValid;
291+
292+
const handleContinue = async (): Promise<void> => {
293+
if (!enterpriseConnection || !canSubmit) {
294+
return;
295+
}
296+
297+
card.setError(undefined);
298+
card.setLoading();
299+
300+
try {
301+
const saml = await controller.buildSamlPayload();
302+
await updateEnterpriseConnection(enterpriseConnection.id, { saml });
303+
void goNext();
304+
} catch (err) {
305+
controller.applySubmitError(err, card);
306+
} finally {
307+
card.setIdle();
308+
}
309+
};
310+
311+
return (
312+
<>
313+
<Step.Body>
314+
<Step.Section
315+
fill
316+
gap={5}
317+
>
318+
<Heading
319+
elementDescriptor={descriptors.configureSSOInstructionsHeading}
320+
as='h3'
321+
textVariant='subtitle'
322+
localizationKey={localizationKeys(
323+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.title',
324+
)}
325+
/>
326+
<IdentityProviderMetadataForm
327+
controller={controller}
328+
modes={{
329+
ariaLabel: localizationKeys(
330+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.ariaLabel',
331+
),
332+
metadataUrlLabel: localizationKeys(
333+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.metadataUrl',
334+
),
335+
manualLabel: localizationKeys(
336+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.modes.manual',
337+
),
338+
}}
339+
metadataUrl={{
340+
description: localizationKeys(
341+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.metadataUrl.description',
342+
),
343+
}}
344+
manual={{
345+
description: localizationKeys(
346+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.description',
347+
),
348+
signingCertificate: {
349+
label: localizationKeys(
350+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.label',
351+
),
352+
uploadFile: localizationKeys(
353+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.uploadFile',
354+
),
355+
replaceFile: localizationKeys(
356+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.replaceFile',
357+
),
358+
removeFile: localizationKeys(
359+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.removeFile',
360+
),
361+
fileUploaded: localizationKeys(
362+
'configureSSO.configureStep.samlCustom.identityProviderMetadataStep.manual.signingCertificate.fileUploaded',
363+
),
364+
},
365+
}}
366+
/>
367+
</Step.Section>
368+
</Step.Body>
369+
370+
<Step.Footer>
371+
<Step.Footer.Previous
372+
onClick={() => goPrev()}
373+
isDisabled={isFirstStep || card.isLoading}
374+
/>
375+
<Step.Footer.Continue
376+
onClick={handleContinue}
377+
isLoading={card.isLoading}
378+
isDisabled={!canSubmit}
379+
/>
380+
</Step.Footer>
381+
</>
382+
);
383+
};

packages/ui/src/components/ConfigureSSO/steps/ConfigureStep/saml/SamlOktaConfigureSteps.tsx

Lines changed: 111 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { type JSX } from 'react';
22

33
import { Col, descriptors, Heading, localizationKeys, Text } from '@/customizables';
44
import { ClipboardInput } from '@/elements/ClipboardInput';
5+
import { useCardState } from '@/elements/contexts';
56
import { Form } from '@/elements/Form';
67
import { Checkmark, Clipboard } from '@/icons';
78
import { useFormControl } from '@/ui/utils/useFormControl';
@@ -12,6 +13,7 @@ import { useWizard, Wizard } from '../../../elements/Wizard';
1213
import { InnerStepCounter } from '../../../elements/Wizard/InnerStepCounter';
1314
import { AttributeMappingTable, type AttributeMappingTableConfig } from './shared/AttributeMappingTable';
1415
import { IdentityProviderMetadataForm } from './shared/IdentityProviderMetadataForm';
16+
import { useIdentityProviderMetadataForm } from './shared/useIdentityProviderMetadataForm';
1517

1618
export const SamlOktaConfigureSteps = (): JSX.Element => {
1719
return (
@@ -448,29 +450,19 @@ const SamlOktaAssignUsersStep = (): JSX.Element => {
448450
);
449451
};
450452

451-
const SamlOktaIdentityProviderMetadataStep = (): JSX.Element => (
452-
<IdentityProviderMetadataForm
453-
modes={{
454-
title: localizationKeys('configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.title'),
455-
ariaLabel: localizationKeys('configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.ariaLabel'),
456-
metadataUrlLabel: localizationKeys(
457-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.metadataUrl',
458-
),
459-
manualLabel: localizationKeys('configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.manual'),
460-
}}
461-
metadataUrl={{
453+
const SamlOktaIdentityProviderMetadataStep = (): JSX.Element => {
454+
const card = useCardState();
455+
const { goNext, goPrev, isFirstStep } = useWizard();
456+
const { enterpriseConnection, updateEnterpriseConnection } = useConfigureSSO();
457+
458+
const controller = useIdentityProviderMetadataForm({
459+
metadataUrl: {
462460
label: localizationKeys('configureSSO.configureStep.samlOkta.identityProviderMetadataStep.metadataUrl.label'),
463461
placeholder: localizationKeys(
464462
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.metadataUrl.placeholder',
465463
),
466-
description: localizationKeys(
467-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.metadataUrl.description',
468-
),
469-
}}
470-
manual={{
471-
description: localizationKeys(
472-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.description',
473-
),
464+
},
465+
manual: {
474466
signOnUrl: {
475467
label: localizationKeys(
476468
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signOnUrl.label',
@@ -485,23 +477,103 @@ const SamlOktaIdentityProviderMetadataStep = (): JSX.Element => (
485477
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.issuer.placeholder',
486478
),
487479
},
488-
signingCertificate: {
489-
label: localizationKeys(
490-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.label',
491-
),
492-
uploadFile: localizationKeys(
493-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.uploadFile',
494-
),
495-
replaceFile: localizationKeys(
496-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.replaceFile',
497-
),
498-
removeFile: localizationKeys(
499-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.removeFile',
500-
),
501-
fileUploaded: localizationKeys(
502-
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.fileUploaded',
503-
),
504-
},
505-
}}
506-
/>
507-
);
480+
signingCertificateLabel: localizationKeys(
481+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.label',
482+
),
483+
},
484+
});
485+
486+
const canSubmit = !card.isLoading && controller.isValid;
487+
488+
const handleContinue = async (): Promise<void> => {
489+
if (!enterpriseConnection || !canSubmit) {
490+
return;
491+
}
492+
493+
card.setError(undefined);
494+
card.setLoading();
495+
496+
try {
497+
const saml = await controller.buildSamlPayload();
498+
await updateEnterpriseConnection(enterpriseConnection.id, { saml });
499+
void goNext();
500+
} catch (err) {
501+
controller.applySubmitError(err, card);
502+
} finally {
503+
card.setIdle();
504+
}
505+
};
506+
507+
return (
508+
<>
509+
<Step.Body>
510+
<Step.Section
511+
fill
512+
gap={5}
513+
>
514+
<Heading
515+
elementDescriptor={descriptors.configureSSOInstructionsHeading}
516+
as='h3'
517+
textVariant='subtitle'
518+
localizationKey={localizationKeys(
519+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.title',
520+
)}
521+
/>
522+
<IdentityProviderMetadataForm
523+
controller={controller}
524+
modes={{
525+
ariaLabel: localizationKeys(
526+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.ariaLabel',
527+
),
528+
metadataUrlLabel: localizationKeys(
529+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.metadataUrl',
530+
),
531+
manualLabel: localizationKeys(
532+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.modes.manual',
533+
),
534+
}}
535+
metadataUrl={{
536+
description: localizationKeys(
537+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.metadataUrl.description',
538+
),
539+
}}
540+
manual={{
541+
description: localizationKeys(
542+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.description',
543+
),
544+
signingCertificate: {
545+
label: localizationKeys(
546+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.label',
547+
),
548+
uploadFile: localizationKeys(
549+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.uploadFile',
550+
),
551+
replaceFile: localizationKeys(
552+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.replaceFile',
553+
),
554+
removeFile: localizationKeys(
555+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.removeFile',
556+
),
557+
fileUploaded: localizationKeys(
558+
'configureSSO.configureStep.samlOkta.identityProviderMetadataStep.manual.signingCertificate.fileUploaded',
559+
),
560+
},
561+
}}
562+
/>
563+
</Step.Section>
564+
</Step.Body>
565+
566+
<Step.Footer>
567+
<Step.Footer.Previous
568+
onClick={() => goPrev()}
569+
isDisabled={isFirstStep || card.isLoading}
570+
/>
571+
<Step.Footer.Continue
572+
onClick={handleContinue}
573+
isLoading={card.isLoading}
574+
isDisabled={!canSubmit}
575+
/>
576+
</Step.Footer>
577+
</>
578+
);
579+
};

0 commit comments

Comments
 (0)