1+ import { ReactNode , useMemo , useState } from 'react' ;
2+
3+ import { CollectionPermission , Method , ResourcePath } from '../../../../types/resources' ;
4+ import {
5+ getScopesFromPaths , getVersionsFromPaths , scopeOptions
6+ } from '../../../views/sidebar/resource-explorer/collection/collection.util' ;
7+ import { CollectionPermissionsContext } from './CollectionPermissionsContext' ;
8+ import { useAppSelector } from '../../../../store' ;
9+
10+ interface CollectionRequest {
11+ method : Method ;
12+ requestUrl : string ;
13+ }
14+
15+ function getRequestsFromPaths ( paths : ResourcePath [ ] , version : string , scope : string ) {
16+ const requests : CollectionRequest [ ] = [ ] ;
17+ paths . forEach ( path => {
18+ const { method, url } = path ;
19+ const pathScope = path . scope ?? scopeOptions [ 0 ] . key ;
20+ if ( version === path . version && scope === pathScope ) {
21+ requests . push ( {
22+ method : method as Method ,
23+ requestUrl : url
24+ } ) ;
25+ }
26+ } ) ;
27+ return requests ;
28+ }
29+
30+ async function getCollectionPermissions ( permissionsUrl : string , paths : ResourcePath [ ] ) :
31+ Promise < { [ key : string ] : CollectionPermission [ ] } > {
32+ const versions = getVersionsFromPaths ( paths ) ;
33+ const scopes = getScopesFromPaths ( paths ) ;
34+ const collectionPermissions : { [ key : string ] : CollectionPermission [ ] } = { } ;
35+
36+ for ( const version of versions ) {
37+ for ( const scope of scopes ) {
38+ const requestPaths = getRequestsFromPaths ( paths , version , scope ) ;
39+ if ( requestPaths . length === 0 ) {
40+ continue ;
41+ }
42+ const url = `${ permissionsUrl } ?version=${ version } &scopeType=${ scope } ` ;
43+ const response = await fetch ( url , {
44+ method : 'POST' ,
45+ headers : {
46+ 'Content-Type' : 'application/json'
47+ } ,
48+ body : JSON . stringify ( requestPaths )
49+ } ) ;
50+ const perms = await response . json ( ) ;
51+ collectionPermissions [ `${ version } -${ scope } ` ] = ( perms . results ) ? perms . results : [ ] ;
52+ }
53+ }
54+ return collectionPermissions ;
55+ }
56+
57+ const CollectionPermissionsProvider = ( { children } : { children : ReactNode } ) => {
58+ const { baseUrl } = useAppSelector ( ( state ) => state . devxApi ) ;
59+ const [ permissions , setPermissions ] = useState < { [ key : string ] : CollectionPermission [ ] } | undefined > ( undefined ) ;
60+ const [ isFetching , setIsFetching ] = useState ( false ) ;
61+ const [ code , setCode ] = useState ( '' ) ;
62+
63+ const getPermissions = async ( items : ResourcePath [ ] ) : Promise < void > => {
64+ const hashCode = window . btoa ( JSON . stringify ( [ ...items ] ) ) ;
65+ if ( hashCode !== code ) {
66+ try {
67+ setIsFetching ( true ) ;
68+ const perms = await getCollectionPermissions ( `${ baseUrl } /permissions` , items ) ;
69+ setPermissions ( perms ) ;
70+ setCode ( hashCode ) ;
71+ } catch ( error ) {
72+ setPermissions ( undefined ) ;
73+ } finally {
74+ setIsFetching ( false ) ;
75+ }
76+ }
77+ } ;
78+
79+ const contextValue = useMemo (
80+ ( ) => ( { getPermissions, permissions, isFetching } ) ,
81+ [ getPermissions , permissions , isFetching ]
82+ ) ;
83+
84+ return (
85+ < CollectionPermissionsContext . Provider value = { contextValue } >
86+ { children }
87+ </ CollectionPermissionsContext . Provider >
88+ ) ;
89+ } ;
90+
91+ export default CollectionPermissionsProvider ;
0 commit comments