@@ -10,20 +10,19 @@ import {
10
10
} from "components/MultiSelectCombobox/MultiSelectCombobox" ;
11
11
import { Spinner } from "components/Spinner/Spinner" ;
12
12
import { useFormik } from "formik" ;
13
- import { Plus , Trash } from "lucide-react" ;
13
+ import { Plus , Trash , TriangleAlert } from "lucide-react" ;
14
14
import { type FC , useId , useState } from "react" ;
15
15
import * as Yup from "yup" ;
16
16
import { ExportPolicyButton } from "./ExportPolicyButton" ;
17
17
import { IdpMappingTable } from "./IdpMappingTable" ;
18
18
import { IdpPillList } from "./IdpPillList" ;
19
-
20
- interface IdpRoleSyncFormProps {
21
- roleSyncSettings : RoleSyncSettings ;
22
- roleMappingCount : number ;
23
- organization : Organization ;
24
- roles : Role [ ] ;
25
- onSubmit : ( data : RoleSyncSettings ) => void ;
26
- }
19
+ import { Stack } from "components/Stack/Stack" ;
20
+ import {
21
+ Tooltip ,
22
+ TooltipContent ,
23
+ TooltipTrigger ,
24
+ TooltipProvider ,
25
+ } from "components/Tooltip/Tooltip" ;
27
26
28
27
const roleSyncValidationSchema = Yup . object ( {
29
28
field : Yup . string ( ) . trim ( ) ,
@@ -48,13 +47,23 @@ const roleSyncValidationSchema = Yup.object({
48
47
. default ( { } ) ,
49
48
} ) ;
50
49
51
- export const IdpRoleSyncForm = ( {
50
+ interface IdpRoleSyncFormProps {
51
+ roleSyncSettings : RoleSyncSettings ;
52
+ fieldValues : string [ ] | undefined ;
53
+ roleMappingCount : number ;
54
+ organization : Organization ;
55
+ roles : Role [ ] ;
56
+ onSubmit : ( data : RoleSyncSettings ) => void ;
57
+ }
58
+
59
+ export const IdpRoleSyncForm : FC < IdpRoleSyncFormProps > = ( {
52
60
roleSyncSettings,
61
+ fieldValues,
53
62
roleMappingCount,
54
63
organization,
55
64
roles,
56
65
onSubmit,
57
- } : IdpRoleSyncFormProps ) => {
66
+ } ) => {
58
67
const form = useFormik < RoleSyncSettings > ( {
59
68
initialValues : {
60
69
field : roleSyncSettings ?. field ?? "" ,
@@ -210,6 +219,7 @@ export const IdpRoleSyncForm = ({
210
219
< RoleRow
211
220
key = { idpRole }
212
221
idpRole = { idpRole }
222
+ exists = { fieldValues ?. includes ( idpRole ) }
213
223
coderRoles = { roles }
214
224
onDelete = { handleDelete }
215
225
/>
@@ -222,14 +232,43 @@ export const IdpRoleSyncForm = ({
222
232
223
233
interface RoleRowProps {
224
234
idpRole : string ;
235
+ exists : boolean | undefined ;
225
236
coderRoles : readonly string [ ] ;
226
237
onDelete : ( idpOrg : string ) => void ;
227
238
}
228
239
229
- const RoleRow : FC < RoleRowProps > = ( { idpRole, coderRoles, onDelete } ) => {
240
+ const RoleRow : FC < RoleRowProps > = ( {
241
+ idpRole,
242
+ exists = true ,
243
+ coderRoles,
244
+ onDelete,
245
+ } ) => {
230
246
return (
231
247
< TableRow data-testid = { `role-${ idpRole } ` } >
232
- < TableCell > { idpRole } </ TableCell >
248
+ < TableCell >
249
+ < Stack
250
+ direction = "row"
251
+ alignItems = "center"
252
+ spacing = { 1 }
253
+ className = "text-content-primary"
254
+ >
255
+ { idpRole }
256
+ { ! exists && (
257
+ < TooltipProvider >
258
+ < Tooltip >
259
+ < TooltipTrigger asChild >
260
+ < TriangleAlert className = "size-icon-sm cursor-pointer text-content-warning" />
261
+ </ TooltipTrigger >
262
+ < TooltipContent className = "p-2 text-xs text-content-secondary max-w-sm" >
263
+ This value has not be seen in the specified claim field
264
+ before. You might want to check your IdP configuration and
265
+ ensure that this value is not misspelled.
266
+ </ TooltipContent >
267
+ </ Tooltip >
268
+ </ TooltipProvider >
269
+ ) }
270
+ </ Stack >
271
+ </ TableCell >
233
272
< TableCell >
234
273
< IdpPillList roles = { coderRoles } />
235
274
</ TableCell >
0 commit comments