1
1
import type { Interpolation , Theme } from "@emotion/react" ;
2
2
import LaunchOutlined from "@mui/icons-material/LaunchOutlined" ;
3
3
import Button from "@mui/material/Button" ;
4
+ import Link from "@mui/material/Link" ;
4
5
import Skeleton from "@mui/material/Skeleton" ;
5
6
import Table from "@mui/material/Table" ;
6
7
import TableBody from "@mui/material/TableBody" ;
@@ -17,6 +18,13 @@ import type {
17
18
import { ErrorAlert } from "components/Alert/ErrorAlert" ;
18
19
import { ChooseOne , Cond } from "components/Conditionals/ChooseOne" ;
19
20
import { EmptyState } from "components/EmptyState/EmptyState" ;
21
+ import {
22
+ HelpTooltip ,
23
+ HelpTooltipContent ,
24
+ HelpTooltipText ,
25
+ HelpTooltipTitle ,
26
+ HelpTooltipTrigger ,
27
+ } from "components/HelpTooltip/HelpTooltip" ;
20
28
import { Loader } from "components/Loader/Loader" ;
21
29
import { Stack } from "components/Stack/Stack" ;
22
30
import { StatusIndicator } from "components/StatusIndicator/StatusIndicator" ;
@@ -60,6 +68,9 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({
60
68
const groupMappingCount = groupSyncSettings ?. mapping
61
69
? Object . entries ( groupSyncSettings . mapping ) . length
62
70
: 0 ;
71
+ const legacyGroupMappingCount = groupSyncSettings ?. legacy_group_name_mapping
72
+ ? Object . entries ( groupSyncSettings . legacy_group_name_mapping ) . length
73
+ : 0 ;
63
74
const roleMappingCount = roleSyncSettings ?. mapping
64
75
? Object . entries ( roleSyncSettings . mapping ) . length
65
76
: 0 ;
@@ -88,22 +99,22 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({
88
99
{ tab === "groups" ? (
89
100
< >
90
101
< div css = { styles . fields } >
91
- < Stack direction = { "row" } alignItems = { "center" } spacing = { 6 } >
102
+ < Stack direction = "row" alignItems = "center" spacing = { 6 } >
92
103
< IdpField
93
- name = { "Sync Field" }
104
+ name = "Sync Field"
94
105
fieldText = { groupSyncSettings ?. field }
95
106
showDisabled
96
107
/>
97
108
< IdpField
98
- name = { "Regex Filter" }
109
+ name = "Regex Filter"
99
110
fieldText = {
100
111
typeof groupSyncSettings ?. regex_filter === "string"
101
112
? groupSyncSettings . regex_filter
102
113
: "none"
103
114
}
104
115
/>
105
116
< IdpField
106
- name = { "Auto Create" }
117
+ name = "Auto Create"
107
118
fieldText = {
108
119
groupSyncSettings ?. field
109
120
? String ( groupSyncSettings ?. auto_create_missing_groups )
@@ -126,10 +137,7 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({
126
137
/>
127
138
</ Stack >
128
139
< Stack spacing = { 6 } >
129
- < IdpMappingTable
130
- type = "Group"
131
- isEmpty = { Boolean ( groupMappingCount === 0 ) }
132
- >
140
+ < IdpMappingTable type = "Group" isEmpty = { groupMappingCount === 0 } >
133
141
{ groupSyncSettings ?. mapping &&
134
142
Object . entries ( groupSyncSettings . mapping )
135
143
. sort ( )
@@ -141,13 +149,32 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({
141
149
/>
142
150
) ) }
143
151
</ IdpMappingTable >
152
+ { groupSyncSettings ?. legacy_group_name_mapping && (
153
+ < section >
154
+ < LegacyGroupSyncHeader />
155
+ < IdpMappingTable
156
+ type = "Group"
157
+ isEmpty = { legacyGroupMappingCount === 0 }
158
+ >
159
+ { Object . entries ( groupSyncSettings . legacy_group_name_mapping )
160
+ . sort ( )
161
+ . map ( ( [ idpGroup , groupId ] ) => (
162
+ < GroupRow
163
+ key = { idpGroup }
164
+ idpGroup = { idpGroup }
165
+ coderGroup = { getGroupNames ( [ groupId ] ) }
166
+ />
167
+ ) ) }
168
+ </ IdpMappingTable >
169
+ </ section >
170
+ ) }
144
171
</ Stack >
145
172
</ >
146
173
) : (
147
174
< >
148
175
< div css = { styles . fields } >
149
176
< IdpField
150
- name = { "Sync Field" }
177
+ name = "Sync Field"
151
178
fieldText = { roleSyncSettings ?. field }
152
179
showDisabled
153
180
/>
@@ -165,10 +192,7 @@ export const IdpSyncPageView: FC<IdpSyncPageViewProps> = ({
165
192
type = "roles"
166
193
/>
167
194
</ Stack >
168
- < IdpMappingTable
169
- type = "Role"
170
- isEmpty = { Boolean ( roleMappingCount === 0 ) }
171
- >
195
+ < IdpMappingTable type = "Role" isEmpty = { roleMappingCount === 0 } >
172
196
{ roleSyncSettings ?. mapping &&
173
197
Object . entries ( roleSyncSettings . mapping )
174
198
. sort ( )
@@ -268,7 +292,7 @@ const IdpMappingTable: FC<IdpMappingTableProps> = ({
268
292
< Table >
269
293
< TableHead >
270
294
< TableRow >
271
- < TableCell width = "45%" > Idp { type } </ TableCell >
295
+ < TableCell width = "45%" > IdP { type } </ TableCell >
272
296
< TableCell width = "55%" > Coder { type } </ TableCell >
273
297
</ TableRow >
274
298
</ TableHead >
@@ -359,12 +383,43 @@ const TableLoader = () => {
359
383
) ;
360
384
} ;
361
385
386
+ const LegacyGroupSyncHeader : FC = ( ) => {
387
+ return (
388
+ < h4
389
+ css = { {
390
+ fontSize : 20 ,
391
+ fontWeight : 500 ,
392
+ } }
393
+ >
394
+ < Stack direction = "row" alignItems = "end" spacing = { 1 } >
395
+ < span > Legacy Group Sync Settings</ span >
396
+ < HelpTooltip >
397
+ < HelpTooltipTrigger />
398
+ < HelpTooltipContent >
399
+ < HelpTooltipTitle > Legacy Group Sync Settings</ HelpTooltipTitle >
400
+ < HelpTooltipText >
401
+ These settings were configured using environment variables, and
402
+ only apply to the default organization. It is now recommended to
403
+ configure IdP sync via the CLI, which enables sync to be
404
+ configured for any organization, and for those settings to be
405
+ persisted without manually setting environment variables.{ " " }
406
+ < Link href = { docs ( "/admin/auth#group-sync-enterprise" ) } >
407
+ Learn more…
408
+ </ Link >
409
+ </ HelpTooltipText >
410
+ </ HelpTooltipContent >
411
+ </ HelpTooltip >
412
+ </ Stack >
413
+ </ h4 >
414
+ ) ;
415
+ } ;
416
+
362
417
const styles = {
363
- fieldText : ( theme ) => ( {
418
+ fieldText : {
364
419
fontFamily : MONOSPACE_FONT_FAMILY ,
365
420
whiteSpace : "nowrap" ,
366
421
paddingBottom : ".02rem" ,
367
- } ) ,
422
+ } ,
368
423
fieldLabel : ( theme ) => ( {
369
424
color : theme . palette . text . secondary ,
370
425
} ) ,
0 commit comments