diff --git a/src/store/fenceConnection/index.ts b/src/store/fenceConnection/index.ts index e6cee74d1..95caf7b49 100644 --- a/src/store/fenceConnection/index.ts +++ b/src/store/fenceConnection/index.ts @@ -1,6 +1,8 @@ -import { FENCE_NAMES } from 'common/fenceTypes'; import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; + +import { FENCE_NAMES } from 'common/fenceTypes'; + import { fenceConnectionSelector } from './selector'; import { checkFenceAuthStatus, checkFencesAuthStatus } from './thunks'; diff --git a/src/store/fenceConnection/thunks.ts b/src/store/fenceConnection/thunks.ts index 76d0e3df1..086abccde 100644 --- a/src/store/fenceConnection/thunks.ts +++ b/src/store/fenceConnection/thunks.ts @@ -38,14 +38,7 @@ const checkFenceAuthStatus = createAsyncThunk< error, data: { auth: data!, - acls: [ - 'phs001138.c1', - 'phs001138.c2', - 'phs001138.c999', - 'phs002330.c1', - 'phs002330.c2', - 'phs002330.c999', - ], + acls: fenceAcls, }, reject: thunkAPI.rejectWithValue, }); @@ -71,50 +64,47 @@ const connectToFence = createAsyncThunk< { state: RootState; } ->( - 'fence/connection', - async (fence, thunkAPI) => { - const { fenceConnection } = thunkAPI.getState(); - let fenceInfo = fenceConnection.fencesInfo[fence]; +>('fence/connection', async (fence, thunkAPI) => { + const { fenceConnection } = thunkAPI.getState(); + let fenceInfo = fenceConnection.fencesInfo[fence]; - if (!fenceInfo) { - const { data } = await FenceApi.fetchInfo(fence); - fenceInfo = data; - } + if (!fenceInfo) { + const { data } = await FenceApi.fetchInfo(fence); + fenceInfo = data; + } + + const authWindow = window.open(fenceInfo?.authorize_uri)!; - const authWindow = window.open(fenceInfo?.authorize_uri)!; + return new Promise((resolve, reject) => { + const interval = setInterval(async () => { + if (authWindow.closed) { + let fenceAcls: string[] = []; + const { data } = await FenceApi.isAuthenticated(fence); - return new Promise((resolve, reject) => { - const interval = setInterval(async () => { - if (authWindow.closed) { - let fenceAcls: string[] = []; - const { data } = await FenceApi.isAuthenticated(fence); + if (data?.authenticated) { + clearInterval(interval); if (data?.authenticated) { - clearInterval(interval); - - if (data?.authenticated) { - const { data: aclData } = await FenceApi.fetchAcls(fence); - fenceAcls = aclData?.acl || []; - } - - resolve({ - info: fenceInfo!, - acls: fenceAcls, - }); - } else { - clearInterval(interval); - reject('failed authenticating'); + const { data: aclData } = await FenceApi.fetchAcls(fence); + fenceAcls = aclData?.acl || []; } + + resolve({ + info: fenceInfo!, + acls: fenceAcls, + }); + } else { + clearInterval(interval); + reject('failed authenticating'); } - }, 1000); - setTimeout(() => { - clearInterval(interval); - reject('nothing'); - }, TEN_MINUTES_IN_MS); - }); - }, -); + } + }, 1000); + setTimeout(() => { + clearInterval(interval); + reject('nothing'); + }, TEN_MINUTES_IN_MS); + }); +}); const disconnectFromFence = createAsyncThunk( 'fence/disconnection', diff --git a/src/store/fenceStudies/index.ts b/src/store/fenceStudies/index.ts index 367d7377c..0fbd1be96 100644 --- a/src/store/fenceStudies/index.ts +++ b/src/store/fenceStudies/index.ts @@ -10,19 +10,18 @@ import { computeAllFencesAuthStudies } from './thunks'; export type { initialState as fenceStudiesInitialState } from './types'; export { default, FenceStudiesState } from './slice'; -export const useFenceStudies = () => { +export const useFenceStudies = (fence: FENCE_NAMES) => { const state = useSelector(fenceStudiesSelector); - const { connectionStatus, fencesConnectError, loadingFences } = useFenceConnection( - FENCE_NAMES.gen3, - ); + + const { connectionStatus, fencesConnectError, loadingFences } = useFenceConnection(fence); const isConnected = (status: FENCE_CONNECTION_STATUSES) => status === FENCE_CONNECTION_STATUSES.connected; return { ...state, fenceStudiesAcls: computeAllFencesAuthStudies(state.studies), - isConnected: isConnected(connectionStatus.gen3), - connectionLoading: loadingFences.includes(FENCE_NAMES.gen3), - hasErrors: fencesConnectError.includes(FENCE_NAMES.gen3) || !isEmpty(state.fencesError), + isConnected: isConnected(connectionStatus[fence]), + connectionLoading: loadingFences.includes(fence), + hasErrors: fencesConnectError.includes(fence) || !isEmpty(state.fencesError), }; }; diff --git a/src/store/fenceStudies/thunks.ts b/src/store/fenceStudies/thunks.ts index 6c3c8e2b8..1bb965a7d 100644 --- a/src/store/fenceStudies/thunks.ts +++ b/src/store/fenceStudies/thunks.ts @@ -205,7 +205,7 @@ const getAuthStudyIdsAndCounts = async ( content: [ { op: TermOperators.in, - content: { field: 'access_control', value: [FileAccessType.REGISTERED] }, + content: { field: 'controlled_access', value: [FileAccessType.REGISTERED] }, }, ], }, @@ -246,7 +246,15 @@ export const computeAllFencesAuthStudies = (fenceStudies: TFenceStudies) => { if (isEmpty(fenceStudies)) { return []; } - return flatMap(Object.values(fenceStudies), (studies) => studies.authorizedStudies); + + return Object.values(fenceStudies) + .map((x) => x.authorizedStudies) + .flat() + .reduce((xs: TFenceStudy[], x: TFenceStudy) => { + // remove duplicates + const sId = x.id; + return xs.some((s) => s.id === sId) ? xs : [...xs, { ...x }]; + }, []); }; const replaceDashByUnderscore = (value: string) => value.replaceAll('-', ''); diff --git a/src/views/Dashboard/components/DashboardCards/AuthorizedStudies/index.tsx b/src/views/Dashboard/components/DashboardCards/AuthorizedStudies/index.tsx index 908a8a890..84583752f 100644 --- a/src/views/Dashboard/components/DashboardCards/AuthorizedStudies/index.tsx +++ b/src/views/Dashboard/components/DashboardCards/AuthorizedStudies/index.tsx @@ -11,6 +11,7 @@ import CardErrorPlaceholder from 'views/Dashboard/components/CardErrorPlaceHolde import CardHeader from 'views/Dashboard/components/CardHeader'; import { DashboardCardProps } from 'views/Dashboard/components/DashboardCards'; +import { FENCE_NAMES } from 'common/fenceTypes'; import PopoverContentLink from 'components/uiKit/PopoverContentLink'; import { fenceConnectionActions } from 'store/fenceConnection/slice'; import { useFenceStudies } from 'store/fenceStudies'; @@ -23,16 +24,34 @@ import styles from './index.module.scss'; const AuthorizedStudies = ({ id, className = '' }: DashboardCardProps) => { const dispatch = useDispatch(); - const { loadingStudiesForFences, fenceStudiesAcls, isConnected, hasErrors, connectionLoading } = - useFenceStudies(); + const { + loadingStudiesForFences, + fenceStudiesAcls, + isConnected: isGen3Connected, + hasErrors: hasGen3Errors, + connectionLoading: connectionGen3Loading, + } = useFenceStudies(FENCE_NAMES.gen3); + + const { + //Shared: loadingStudiesForFences, + //Shared: fenceStudiesAcls, + isConnected: isDcfConnected, + hasErrors: hasDcfErrors, + connectionLoading: connectionDcfLoading, + } = useFenceStudies(FENCE_NAMES.dcf); + const fenceStudiesLoading = loadingStudiesForFences.length > 0; + const isOneFenceAtLeastConnected = isGen3Connected || isDcfConnected; + const hasAtLeastOneFenceWithErrors = hasGen3Errors || hasDcfErrors; + const connectionLoadingForAtLeastOneFence = connectionGen3Loading || connectionDcfLoading; + useEffect(() => { - if (isConnected) { + if (isOneFenceAtLeastConnected) { dispatch(fetchAllFenceStudies()); } // eslint-disable-next-line - }, [isConnected]); + }, [isOneFenceAtLeastConnected]); return ( { { } content={
- {isConnected && !hasErrors && !fenceStudiesLoading && ( + {isOneFenceAtLeastConnected && !hasAtLeastOneFenceWithErrors && !fenceStudiesLoading && ( @@ -81,7 +100,7 @@ const AuthorizedStudies = ({ id, className = '' }: DashboardCardProps) => { dispatch(fenceConnectionActions.setConnectionModalParams({ open: true })) } className={styles.disconnectBtn} - loading={connectionLoading} + loading={connectionLoadingForAtLeastOneFence} > {intl.get('screen.dashboard.cards.authorizedStudies.manageConnections')} @@ -93,11 +112,11 @@ const AuthorizedStudies = ({ id, className = '' }: DashboardCardProps) => { className={styles.authorizedStudiesList} bordered itemLayout="vertical" - loading={fenceStudiesLoading || connectionLoading} + loading={fenceStudiesLoading || connectionLoadingForAtLeastOneFence} locale={{ - emptyText: hasErrors ? ( + emptyText: hasAtLeastOneFenceWithErrors ? ( - ) : isConnected ? ( + ) : isOneFenceAtLeastConnected ? ( { /> ), }} - dataSource={isConnected && !hasErrors ? fenceStudiesAcls : []} + dataSource={ + isOneFenceAtLeastConnected && !hasAtLeastOneFenceWithErrors ? fenceStudiesAcls : [] + } renderItem={(item) => } >