Skip to content

Commit

Permalink
feat(dashboard): SKFP-874 refact authorized studies widget
Browse files Browse the repository at this point in the history
  • Loading branch information
lflangis committed Dec 19, 2023
1 parent a9628cf commit 80d471f
Show file tree
Hide file tree
Showing 23 changed files with 538 additions and 357 deletions.
6 changes: 6 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export default {
'web.jsx',
'jsx',
'node',
'module.scss',
'module.css',
'module.sass',
'scss',
'css',
'sass',
],
watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
resetMocks: true,
Expand Down
24 changes: 14 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"@babel/core": "^7.16.0",
"@dnd-kit/core": "^4.0.3",
"@dnd-kit/sortable": "^5.1.0",
"@ferlab/ui": "^7.16.0",
"@ferlab/ui": "^7.18.0",
"@loadable/component": "^5.15.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
"@react-keycloak/core": "^3.2.0",
Expand Down Expand Up @@ -100,7 +100,6 @@
"graphql": "^16.2.0",
"html-react-parser": "^1.4.4",
"html-webpack-plugin": "^5.5.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^27.4.3",
"jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",
Expand Down Expand Up @@ -175,6 +174,7 @@
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-sort-destructure-keys": "^1.5.0",
"eslint-plugin-sort-keys-fix": "^1.1.2",
"identity-obj-proxy": "^3.0.0",
"less": "^4.1.3",
"less2sass": "^1.0.3",
"nodemon": "^2.0.20",
Expand Down
9 changes: 5 additions & 4 deletions src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,26 +552,27 @@ const en = {
error: {
title: 'Connection error',
subtitle:
'We are currently unable to connect to this service. Please refresh the page and try again. If the problem persists, please',
'We are currently unable to connect to this service. Please refresh the page and try again. If the problem persists, please ',
contactSupport: 'contact support',
},
datarelease: {
title: 'Data release {version}',
},
authorizedStudies: {
title: 'Authorized Studies {count, plural, =0 {} other {(#)}}',
connectedNotice: 'You have access to the following Kids First controlled data.',
connectedNotice: 'You have access to the following Kids First controlled data. ',
disconnectedNotice:
'To access controlled study files, connect to our data repository partners using your NIH credentials.',
disconnect: 'Disconnect',
manageConnections: 'Manage your connections',
noAvailableStudies: 'No available studies',
authorization: 'Authorization',
authorization: 'Authorization : ',
of: 'of',
files: 'Files',
dataGroups: 'Data use groups: {groups}',
dataGroups: 'Data use groups: ',
modal: {
title: 'Manage Connections',
error: 'We were unable to establish a connection. Please try again later.',
description:
'Access select NCI and Kids First controlled access data by connecting your account using your NIH login credentials. Please remember that it is your responsibility to follow any data use limitations with controlled access data.',
},
Expand Down
3 changes: 2 additions & 1 deletion src/locales/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import intlEn from './en';
import { LANG } from 'common/constants';

import intlEn from './en';

const locales = {
[LANG.EN]: intlEn,
};
Expand Down
33 changes: 16 additions & 17 deletions src/provider/ContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
import intl from "react-intl-universal";
import { Provider as ReduxProvider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import KeycloakProvider from "provider/KeycloakProvider";
import getStoreConfig from "store";
import { LANG } from "common/constants";
import locales from "locales";
import intl from 'react-intl-universal';
import { Provider as ReduxProvider } from 'react-redux';
import locales from 'locales';
import KeycloakProvider from 'provider/KeycloakProvider';
import { PersistGate } from 'redux-persist/integration/react';

import { LANG } from 'common/constants';
import getStoreConfig from 'store';

const { store, persistor } = getStoreConfig();
persistor.subscribe(function () {
intl.init({
currentLocale: store.getState().global.lang || LANG.EN,
locales,
warningHandler: () => ""
warningHandler: () => '',
});
});

const ContextProvider = ({ children }: any) => {
return (
<KeycloakProvider>
<ReduxProvider store={store}>
<PersistGate persistor={persistor}>{children}</PersistGate>
</ReduxProvider>
</KeycloakProvider>
);
};
const ContextProvider = ({ children }: any) => (
<KeycloakProvider>
<ReduxProvider store={store}>
<PersistGate persistor={persistor}>{children}</PersistGate>
</ReduxProvider>
</KeycloakProvider>
);

export default ContextProvider;
24 changes: 22 additions & 2 deletions src/services/api/fence/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import { FENCE_NAMES } from 'common/fenceTypes';
import EnvironmentVariables from 'helpers/EnvVariables';
import { ARRANGER_API } from 'provider/ApolloProvider';

import { FENCE_NAMES } from 'common/fenceTypes';
import { IAuthorizedStudiesFetchParams } from 'store/fences/types';

import { sendRequest } from '..';
import { IFenceAclsPayload, IFenceAuthPayload, IFenceInfo } from './models';

import {
IAuthorizedStudiesPayload,
IFenceAclsPayload,
IFenceAuthPayload,
IFenceInfo,
} from './models';

export const FENCE_API_URL = EnvironmentVariables.configFor('FENCE_API_URL');

//https://kf-api-arranger-next-qa.kf-strides.org/authorized-studies

const fetchAuthorizedStudies = (params: IAuthorizedStudiesFetchParams) =>
sendRequest<IAuthorizedStudiesPayload>({
method: 'POST',
url: `${ARRANGER_API}/authorized-studies`,
data: params,
});

const isAuthenticated = (fence: FENCE_NAMES) =>
sendRequest<IFenceAuthPayload>({
url: `${FENCE_API_URL}/${fence}/authenticated`,
Expand Down Expand Up @@ -39,6 +58,7 @@ const disconnect = (fence: FENCE_NAMES) =>
});

export const FenceApi = {
fetchAuthorizedStudies,
isAuthenticated,
fetchInfo,
exchangeCode,
Expand Down
9 changes: 9 additions & 0 deletions src/services/api/fence/models.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { IAuthorizedStudy } from '@ferlab/ui/core/components/AuthorizedStudies';

export interface IFenceAuthPayload {
authenticated: boolean;
expiration?: number;
}

export interface IAuthorizedStudiesPayload {
[key: string]: {
data: IAuthorizedStudy[];
error: boolean;
};
}

export interface IFenceAclsPayload {
acl: string[];
}
Expand Down
6 changes: 4 additions & 2 deletions src/store/fenceConnection/slice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { initialState, TModalConnectionParams } from 'store/fenceConnection/types';

import { FENCE_CONNECTION_STATUSES, FENCE_NAMES } from 'common/fenceTypes';
import { initialState, TModalConnectionParams } from 'store/fenceConnection/types';

import { checkFenceAuthStatus, connectToFence, disconnectFromFence } from './thunks';

export const FenceConnectionState: initialState = {
Expand Down Expand Up @@ -95,7 +97,7 @@ const fenceConnectionSlice = createSlice({
state.loadingFences = addLoadingFences(state, action.meta.arg);
});
builder.addCase(checkFenceAuthStatus.fulfilled, (state, action) => {
const isAuthenticated = action.payload && action.payload.auth.authenticated;
const isAuthenticated = action.payload && action.payload.auth?.authenticated;
state.loadingFences = removeLoadingFences(state, action.meta.arg);

if (isAuthenticated) {
Expand Down
30 changes: 30 additions & 0 deletions src/store/fences/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { FENCE_NAMES } from 'common/fenceTypes';

import { fencesAuthorizedStudiesSelector, fencesSelector } from './selector';
import { fetchFenceAuthentificationStatus } from './thunks';

export type { initialState as fencesInitialState } from './types';
export { default, FencesState } from './slice';

export const useFenceAuthentification = (fence: FENCE_NAMES) => {
const dispatch = useDispatch();
const state = useSelector(fencesSelector);

useEffect(() => {
dispatch(fetchFenceAuthentificationStatus(fence));
}, []);

return {
...state[fence],
};
};

export const useFencesAuthorizedStudies = () => {
const state = useSelector(fencesAuthorizedStudiesSelector);
return {
...state,
};
};
8 changes: 8 additions & 0 deletions src/store/fences/selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { RootState } from 'store/types';

import { initialState } from './types';

export type FencesProps = initialState;

export const fencesSelector = (state: RootState) => state.fences;
export const fencesAuthorizedStudiesSelector = (state: RootState) => state.fences.authorizedStudies;
Loading

0 comments on commit 80d471f

Please sign in to comment.