3
3
* SPDX-License-Identifier: Apache-2.0
4
4
*/
5
5
6
- import React , { useCallback , useMemo , useRef } from 'react' ;
6
+ import React , { useCallback , useMemo } from 'react' ;
7
7
import {
8
8
EuiDescribedFormGroup ,
9
9
EuiFlexGroup ,
@@ -25,57 +25,61 @@ export type WorkspacePermissionSetting = (
25
25
type : 'user' | 'group' ;
26
26
userId ?: string ;
27
27
group ?: string ;
28
- modes : Array <
29
- | WorkspacePermissionMode . LibraryRead
30
- | WorkspacePermissionMode . LibraryWrite
31
- | WorkspacePermissionMode . Management
32
- > ;
28
+ modes : WorkspacePermissionMode [ ] ;
33
29
} ;
34
30
31
+ enum PermissionModeId {
32
+ Read = 'read' ,
33
+ ReadAndWrite = 'read+write' ,
34
+ Admin = 'admin' ,
35
+ }
36
+
35
37
const permissionModeOptions = [
36
38
{
37
- id : WorkspacePermissionMode . LibraryRead ,
38
- label : 'View ' ,
39
+ id : PermissionModeId . Read ,
40
+ label : 'Read ' ,
39
41
iconType : 'eye' ,
40
42
} ,
41
43
{
42
- id : WorkspacePermissionMode . LibraryWrite ,
43
- label : 'Edit ' ,
44
+ id : PermissionModeId . ReadAndWrite ,
45
+ label : 'Read + Write ' ,
44
46
iconType : 'pencil' ,
45
47
} ,
46
48
{
47
- id : WorkspacePermissionMode . Management ,
49
+ id : PermissionModeId . Admin ,
48
50
label : 'Management' ,
49
51
iconType : 'visTimelion' ,
50
52
} ,
51
53
] ;
52
54
55
+ const optionIdToWorkspacePermissionModesMap : {
56
+ [ key : string ] : WorkspacePermissionMode [ ] ;
57
+ } = {
58
+ [ PermissionModeId . Read ] : [ WorkspacePermissionMode . LibraryRead , WorkspacePermissionMode . Read ] ,
59
+ [ PermissionModeId . ReadAndWrite ] : [
60
+ WorkspacePermissionMode . LibraryWrite ,
61
+ WorkspacePermissionMode . Read ,
62
+ ] ,
63
+ [ PermissionModeId . Admin ] : [ WorkspacePermissionMode . LibraryWrite , WorkspacePermissionMode . Write ] ,
64
+ } ;
65
+
53
66
const permissionTypeOptions = [
54
67
{ value : 'user' as const , inputDisplay : 'User' } ,
55
68
{ value : 'group' as const , inputDisplay : 'Group' } ,
56
69
] ;
57
70
58
- const isWorkspacePermissionMode = (
59
- test : string
60
- ) : test is
61
- | WorkspacePermissionMode . LibraryRead
62
- | WorkspacePermissionMode . LibraryWrite
63
- | WorkspacePermissionMode . Management =>
64
- test === WorkspacePermissionMode . LibraryRead ||
65
- test === WorkspacePermissionMode . LibraryWrite ||
66
- test === WorkspacePermissionMode . Management ;
71
+ const generateWorkspacePermissionItemKey = (
72
+ item : Partial < WorkspacePermissionSetting > ,
73
+ index ?: number
74
+ ) => [ item . type , item . userId , item . group , ...( item . modes ?? [ ] ) , index ] . filter ( Boolean ) . join ( '-' ) ;
67
75
68
76
interface WorkspacePermissionSettingInputProps {
69
77
index : number ;
70
78
deletable : boolean ;
71
79
type ?: 'user' | 'group' ;
72
80
userId ?: string ;
73
81
group ?: string ;
74
- modes ?: Array <
75
- | WorkspacePermissionMode . LibraryRead
76
- | WorkspacePermissionMode . LibraryWrite
77
- | WorkspacePermissionMode . Management
78
- > ;
82
+ modes ?: WorkspacePermissionMode [ ] ;
79
83
onTypeChange : ( type : 'user' | 'group' , index : number ) => void ;
80
84
onGroupOrUserIdChange : (
81
85
groupOrUserId :
@@ -85,11 +89,7 @@ interface WorkspacePermissionSettingInputProps {
85
89
index : number
86
90
) => void ;
87
91
onPermissionModesChange : (
88
- WorkspacePermissionMode : Array <
89
- | WorkspacePermissionMode . LibraryRead
90
- | WorkspacePermissionMode . LibraryWrite
91
- | WorkspacePermissionMode . Management
92
- > ,
92
+ WorkspacePermissionMode : WorkspacePermissionMode [ ] ,
93
93
index : number
94
94
) => void ;
95
95
onDelete : ( index : number ) => void ;
@@ -111,16 +111,16 @@ const WorkspacePermissionSettingInput = ({
111
111
( ) => ( group || userId ? [ { label : ( group || userId ) as string } ] : [ ] ) ,
112
112
[ group , userId ]
113
113
) ;
114
- const permissionModesIdToSelectMap = useMemo (
115
- ( ) => ( {
116
- [ WorkspacePermissionMode . LibraryRead ] : ! ! modes ?. includes ( WorkspacePermissionMode . LibraryRead ) ,
117
- [ WorkspacePermissionMode . LibraryWrite ] : ! ! modes ?. includes (
118
- WorkspacePermissionMode . LibraryWrite
119
- ) ,
120
- [ WorkspacePermissionMode . Management ] : ! ! modes ?. includes ( WorkspacePermissionMode . Management ) ,
121
- } ) ,
122
- [ modes ]
123
- ) ;
114
+ const permissionModesSelectedId = useMemo ( ( ) => {
115
+ if ( ! modes ) {
116
+ return undefined ;
117
+ }
118
+ for ( const key in optionIdToWorkspacePermissionModesMap ) {
119
+ if ( optionIdToWorkspacePermissionModesMap [ key ] . every ( ( mode ) => modes ?. includes ( mode ) ) ) {
120
+ return key ;
121
+ }
122
+ }
123
+ } , [ modes ] ) ;
124
124
125
125
const handleTypeChange = useCallback (
126
126
( newType : 'user' | 'group' ) => {
@@ -154,16 +154,13 @@ const WorkspacePermissionSettingInput = ({
154
154
[ index , type , onGroupOrUserIdChange ]
155
155
) ;
156
156
157
- const handlePermissionStateChange = useCallback (
157
+ const handlePermissionModeOptionChange = useCallback (
158
158
( id : string ) => {
159
- if ( isWorkspacePermissionMode ( id ) ) {
160
- onPermissionModesChange (
161
- modes ?. includes ( id ) ? modes . filter ( ( value ) => value !== id ) : [ ...( modes ?? [ ] ) , id ] ,
162
- index
163
- ) ;
159
+ if ( optionIdToWorkspacePermissionModesMap [ id ] ) {
160
+ onPermissionModesChange ( [ ...optionIdToWorkspacePermissionModesMap [ id ] ] , index ) ;
164
161
}
165
162
} ,
166
- [ index , modes , onPermissionModesChange ]
163
+ [ index , onPermissionModesChange ]
167
164
) ;
168
165
169
166
const handleDelete = useCallback ( ( ) => {
@@ -195,11 +192,11 @@ const WorkspacePermissionSettingInput = ({
195
192
< EuiFlexItem grow = { false } >
196
193
< EuiButtonGroup
197
194
legend = "Permission Modes"
198
- type = "multi "
195
+ type = "single "
199
196
options = { permissionModeOptions }
200
- onChange = { handlePermissionStateChange }
201
197
isIconOnly
202
- idToSelectedMap = { permissionModesIdToSelectMap }
198
+ idSelected = { permissionModesSelectedId }
199
+ onChange = { handlePermissionModeOptionChange }
203
200
/>
204
201
</ EuiFlexItem >
205
202
< EuiFlexItem grow = { false } >
@@ -227,63 +224,99 @@ export const WorkspacePermissionSettingPanel = ({
227
224
onChange,
228
225
firstRowDeletable,
229
226
} : WorkspacePermissionSettingPanelProps ) => {
230
- const valueRef = useRef ( value ) ;
231
- valueRef . current = value ;
227
+ const transformedValue = useMemo ( ( ) => {
228
+ if ( ! value ) {
229
+ return [ ] ;
230
+ }
231
+ const result : Array < Partial < WorkspacePermissionSetting > > = [ ] ;
232
+ /**
233
+ * One workspace permission setting may includes multi setting options,
234
+ * for loop the workspace permission setting array to separate it to multi rows.
235
+ **/
236
+ for ( let i = 0 ; i < value . length ; i ++ ) {
237
+ const valueItem = value [ i ] ;
238
+ // Incomplete workspace permission setting don't need to separate to multi rows
239
+ if (
240
+ ! valueItem . modes ||
241
+ ! valueItem . type ||
242
+ ( valueItem . type === 'user' && ! valueItem . userId ) ||
243
+ ( valueItem . type === 'group' && ! valueItem . group )
244
+ ) {
245
+ result . push ( valueItem ) ;
246
+ continue ;
247
+ }
248
+ /**
249
+ * For loop the option id to workspace permission modes map,
250
+ * if one settings includes all permission modes in a specific option,
251
+ * add these permission modes to the result array.
252
+ */
253
+ for ( const key in optionIdToWorkspacePermissionModesMap ) {
254
+ if ( ! Object . prototype . hasOwnProperty . call ( optionIdToWorkspacePermissionModesMap , key ) ) {
255
+ continue ;
256
+ }
257
+ const modesForCertainPermissionId = optionIdToWorkspacePermissionModesMap [ key ] ;
258
+ if ( modesForCertainPermissionId . every ( ( mode ) => valueItem . modes ?. includes ( mode ) ) ) {
259
+ result . push ( { ...valueItem , modes : modesForCertainPermissionId } ) ;
260
+ }
261
+ }
262
+ }
263
+ return result ;
264
+ } , [ value ] ) ;
232
265
233
266
const handleAddNewOne = useCallback ( ( ) => {
234
- onChange ?.( [ ...( valueRef . current ?? [ ] ) , { } ] ) ;
235
- } , [ onChange ] ) ;
267
+ onChange ?.( [ ...( transformedValue ?? [ ] ) , { } ] ) ;
268
+ } , [ onChange , transformedValue ] ) ;
236
269
237
270
const handleDelete = useCallback (
238
271
( index : number ) => {
239
- onChange ?.( ( valueRef . current ?? [ ] ) . filter ( ( _item , itemIndex ) => itemIndex !== index ) ) ;
272
+ onChange ?.( ( transformedValue ?? [ ] ) . filter ( ( _item , itemIndex ) => itemIndex !== index ) ) ;
240
273
} ,
241
- [ onChange ]
274
+ [ onChange , transformedValue ]
242
275
) ;
243
276
244
277
const handlePermissionModesChange = useCallback <
245
278
WorkspacePermissionSettingInputProps [ 'onPermissionModesChange' ]
246
279
> (
247
280
( modes , index ) => {
248
281
onChange ?.(
249
- ( valueRef . current ?? [ ] ) . map ( ( item , itemIndex ) =>
282
+ ( transformedValue ?? [ ] ) . map ( ( item , itemIndex ) =>
250
283
index === itemIndex ? { ...item , modes } : item
251
284
)
252
285
) ;
253
286
} ,
254
- [ onChange ]
287
+ [ onChange , transformedValue ]
255
288
) ;
256
289
257
290
const handleTypeChange = useCallback < WorkspacePermissionSettingInputProps [ 'onTypeChange' ] > (
258
291
( type , index ) => {
259
292
onChange ?.(
260
- ( valueRef . current ?? [ ] ) . map ( ( item , itemIndex ) =>
293
+ ( transformedValue ?? [ ] ) . map ( ( item , itemIndex ) =>
261
294
index === itemIndex ? { ...item , type } : item
262
295
)
263
296
) ;
264
297
} ,
265
- [ onChange ]
298
+ [ onChange , transformedValue ]
266
299
) ;
267
300
268
301
const handleGroupOrUserIdChange = useCallback <
269
302
WorkspacePermissionSettingInputProps [ 'onGroupOrUserIdChange' ]
270
303
> (
271
304
( userOrGroupIdWithType , index ) => {
272
305
onChange ?.(
273
- ( valueRef . current ?? [ ] ) . map ( ( item , itemIndex ) =>
306
+ ( transformedValue ?? [ ] ) . map ( ( item , itemIndex ) =>
274
307
index === itemIndex
275
308
? { ...userOrGroupIdWithType , ...( item . modes ? { modes : item . modes } : { } ) }
276
309
: item
277
310
)
278
311
) ;
279
312
} ,
280
- [ onChange ]
313
+ [ onChange , transformedValue ]
281
314
) ;
282
315
283
316
return (
284
317
< EuiDescribedFormGroup title = { < h3 > Users, User Groups & Groups </ h3 > } >
285
- { value ?. map ( ( item , index ) => (
286
- < React . Fragment key = { index } >
318
+ { transformedValue ?. map ( ( item , index ) => (
319
+ < React . Fragment key = { generateWorkspacePermissionItemKey ( item , index ) } >
287
320
< EuiFormRow isInvalid = { ! ! errors ?. [ index ] } error = { errors ?. [ index ] } >
288
321
< WorkspacePermissionSettingInput
289
322
{ ...item }
0 commit comments