Commit b515f433 authored by Zhou Fang's avatar Zhou Fang
Browse files

Moved states into Context to reduce API call times

parent 6cd8cc9e
...@@ -57,6 +57,21 @@ const App = () => { ...@@ -57,6 +57,21 @@ const App = () => {
const [msgContent, setMsgContent] = useState(''); const [msgContent, setMsgContent] = useState('');
const [isError, setIsError] = useState(false); const [isError, setIsError] = useState(false);
const [orgInfo, setOrgInfo] = useState(null); const [orgInfo, setOrgInfo] = useState(null);
const [allRelations, setAllRelations] = useState(null);
const [currentLinks, setCurrentLinks] = useState(null);
const [orgRepData, setOrgRepData] = useState(null);
const [resourcesData, setResourcesData] = useState(null);
const [committers, setCommitters] = useState(null);
const [contributors, setContributors] = useState(null);
const [cbiData, setCBIData] = useState(null);
const [chartCommits, setChartCommits] = useState(null);
const [chartCommitters, setChartCommitters] = useState(null);
const [interestedProjectsData, setInterestedProjectsData] = useState(null);
const [yourProjectsData, setYourProjectsData] = useState(null);
const [allYourProjectsData, setAllYourProjectsData] = useState(null);
const [yourWGData, setYourWGData] = useState(null);
const [allYourWGData, setAllYourWGData] = useState(null);
const [interestedWGData, setInterestedWGData] = useState(null);
const failedToExecute = (msg) => { const failedToExecute = (msg) => {
setShouldShowMsg(true); setShouldShowMsg(true);
...@@ -100,6 +115,36 @@ const App = () => { ...@@ -100,6 +115,36 @@ const App = () => {
setContactData, setContactData,
orgInfo, orgInfo,
setOrgInfo, setOrgInfo,
allRelations,
setAllRelations,
currentLinks,
setCurrentLinks,
orgRepData,
setOrgRepData,
resourcesData,
setResourcesData,
committers,
setCommitters,
contributors,
setContributors,
cbiData,
setCBIData,
chartCommits,
setChartCommits,
chartCommitters,
setChartCommitters,
interestedProjectsData,
setInterestedProjectsData,
yourProjectsData,
setYourProjectsData,
allYourProjectsData,
setAllYourProjectsData,
yourWGData,
setYourWGData,
allYourWGData,
setAllYourWGData,
interestedWGData,
setInterestedWGData,
}; };
useEffect(() => { useEffect(() => {
......
import React from 'react'; import React from 'react';
import { ContactBackend, OrgInfoBackend } from '../Interfaces/portal_interface'; import {
AllRelationsFrontend,
CBIData,
CommitterOrContributor,
ContactBackend,
CurrentLink,
OrgInfoBackend,
OrgRep,
ProjectsAndWGItem,
ResourcesData,
} from '../Interfaces/portal_interface';
interface PortalContextType { interface PortalContextType {
orgId: number; orgId: number;
...@@ -10,6 +20,36 @@ interface PortalContextType { ...@@ -10,6 +20,36 @@ interface PortalContextType {
setContactData: (data: Array<ContactBackend>) => void; setContactData: (data: Array<ContactBackend>) => void;
orgInfo: OrgInfoBackend | null; orgInfo: OrgInfoBackend | null;
setOrgInfo: (orgInfo: OrgInfoBackend) => void; setOrgInfo: (orgInfo: OrgInfoBackend) => void;
allRelations: AllRelationsFrontend | null;
setAllRelations: (relations: AllRelationsFrontend) => void;
currentLinks: Array<CurrentLink> | null;
setCurrentLinks: (links: Array<CurrentLink>) => void;
orgRepData: Array<OrgRep> | null;
setOrgRepData: (repData: Array<OrgRep>) => void;
resourcesData: Array<ResourcesData> | null;
setResourcesData: (resourcesData: Array<ResourcesData>) => void;
committers: Array<CommitterOrContributor> | null;
setCommitters: (committersData: Array<CommitterOrContributor>) => void;
contributors: Array<CommitterOrContributor> | null;
setContributors: (contributorsData: Array<CommitterOrContributor>) => void;
cbiData: CBIData | null;
setCBIData: (cbiData: CBIData) => void;
chartCommits: Array<number> | null;
setChartCommits: (commitsData: Array<number>) => void;
chartCommitters: Array<number> | null;
setChartCommitters: (committersData: Array<number>) => void;
interestedProjectsData: Array<ProjectsAndWGItem> | null;
setInterestedProjectsData: (interestedProjectsData: Array<ProjectsAndWGItem>) => void;
yourProjectsData: Array<ProjectsAndWGItem> | null;
setYourProjectsData: (yourProjectsData: Array<ProjectsAndWGItem>) => void;
allYourProjectsData: Array<ProjectsAndWGItem> | null;
setAllYourProjectsData: (allYourProjectsData: Array<ProjectsAndWGItem>) => void;
yourWGData: Array<ProjectsAndWGItem> | null;
setYourWGData: (yourWGData: Array<ProjectsAndWGItem>) => void;
allYourWGData: Array<ProjectsAndWGItem> | null;
setAllYourWGData: (allYourWGData: Array<ProjectsAndWGItem>) => void;
interestedWGData: Array<ProjectsAndWGItem> | null;
setInterestedWGData: (interestedWGData: Array<ProjectsAndWGItem>) => void;
} }
const PortalContext = React.createContext<PortalContextType>({ const PortalContext = React.createContext<PortalContextType>({
...@@ -21,6 +61,36 @@ const PortalContext = React.createContext<PortalContextType>({ ...@@ -21,6 +61,36 @@ const PortalContext = React.createContext<PortalContextType>({
setContactData: (data: Array<ContactBackend>) => {}, setContactData: (data: Array<ContactBackend>) => {},
orgInfo: null, orgInfo: null,
setOrgInfo: (orgInfo: OrgInfoBackend) => {}, setOrgInfo: (orgInfo: OrgInfoBackend) => {},
allRelations: null,
setAllRelations: (relations: AllRelationsFrontend) => {},
currentLinks: null,
setCurrentLinks: (links: Array<CurrentLink>) => {},
orgRepData: null,
setOrgRepData: (repData: Array<OrgRep>) => {},
resourcesData: null,
setResourcesData: (resourcesData: Array<ResourcesData>) => {},
committers: null,
setCommitters: (committersData: Array<CommitterOrContributor>) => {},
contributors: null,
setContributors: (contributorsData: Array<CommitterOrContributor>) => {},
cbiData: null,
setCBIData: (cbiData: CBIData) => {},
chartCommits: null,
setChartCommits: (commitsData: Array<number>) => {},
chartCommitters: null,
setChartCommitters: (committersData: Array<number>) => {},
interestedProjectsData: null,
setInterestedProjectsData: (interestedProjectsData: Array<ProjectsAndWGItem>) => {},
yourProjectsData: null,
setYourProjectsData: (yourProjectsData: Array<ProjectsAndWGItem>) => {},
allYourProjectsData: null,
setAllYourProjectsData: (allYourProjectsData: Array<ProjectsAndWGItem>) => {},
yourWGData: null,
setYourWGData: (yourWGData: Array<ProjectsAndWGItem>) => {},
allYourWGData: null,
setAllYourWGData: (allYourWGData: Array<ProjectsAndWGItem>) => {},
interestedWGData: null,
setInterestedWGData: (interestedWGData: Array<ProjectsAndWGItem>) => {},
}); });
export default PortalContext; export default PortalContext;
...@@ -63,3 +63,33 @@ export interface OrgInfoBackend { ...@@ -63,3 +63,33 @@ export interface OrgInfoBackend {
website: null | string; website: null | string;
wgpas: Array<WGPA>; wgpas: Array<WGPA>;
} }
export interface AllRelationsFrontend {
[key: string]: string;
}
export interface CurrentLink {
id: number;
title: string;
description: string;
url: string;
}
export interface ResourcesListItem {
name: string;
url: string;
}
export interface ResourcesData {
subtitle: string;
listItems: Array<ResourcesListItem>;
}
export interface CommitterOrContributor {
name: string;
url: string;
}
export interface CBIData {
inUse: number;
allocated: number;
}
...@@ -29,7 +29,12 @@ import EditIcon from '@material-ui/icons/Edit'; ...@@ -29,7 +29,12 @@ import EditIcon from '@material-ui/icons/Edit';
import PersonAddIcon from '@material-ui/icons/PersonAdd'; import PersonAddIcon from '@material-ui/icons/PersonAdd';
import Input from '../../UIComponents/Inputs/Input'; import Input from '../../UIComponents/Inputs/Input';
import ModalWindow from '../../UIComponents/Notifications/ModalWindow'; import ModalWindow from '../../UIComponents/Notifications/ModalWindow';
import { ContactBackend, OrganizationRoles, OrganizationRolesKeys } from '../../../Interfaces/portal_interface'; import {
AllRelationsFrontend,
ContactBackend,
OrganizationRoles,
OrganizationRolesKeys,
} from '../../../Interfaces/portal_interface';
import { fetchWrapper, fetchWrapperPagination, isProd } from '../../../Utils/formFunctionHelpers'; import { fetchWrapper, fetchWrapperPagination, isProd } from '../../../Utils/formFunctionHelpers';
import GlobalContext from '../../../Context/GlobalContext'; import GlobalContext from '../../../Context/GlobalContext';
import { checkPermission } from '../../../Utils/portalFunctionHelpers'; import { checkPermission } from '../../../Utils/portalFunctionHelpers';
...@@ -147,10 +152,6 @@ interface AllRelationsBackend { ...@@ -147,10 +152,6 @@ interface AllRelationsBackend {
sort_order: string; sort_order: string;
} }
interface AllRelationsFrontend {
[key: string]: string;
}
interface RoleDescription { interface RoleDescription {
[key: string]: string; [key: string]: string;
} }
...@@ -182,7 +183,8 @@ const customOperators = [ ...@@ -182,7 +183,8 @@ const customOperators = [
export default function ContactManagement() { export default function ContactManagement() {
const classes = useStyle(); const classes = useStyle();
const { currentUser, succeededToExecute, failedToExecute } = useContext(GlobalContext); const { currentUser, succeededToExecute, failedToExecute } = useContext(GlobalContext);
const { contactFilterRole, setContactFilterRole, orgId, contactData, setContactData } = useContext(PortalContext); const { contactFilterRole, setContactFilterRole, orgId, contactData, setContactData, allRelations, setAllRelations } =
useContext(PortalContext);
const columns: GridColDef[] = [ const columns: GridColDef[] = [
{ {
...@@ -278,7 +280,6 @@ export default function ContactManagement() { ...@@ -278,7 +280,6 @@ export default function ContactManagement() {
name: '', name: '',
}); });
const [checkedRoles, setCheckedRoles] = useState(INITIAL_CHECKED_ROLES); const [checkedRoles, setCheckedRoles] = useState(INITIAL_CHECKED_ROLES);
const [allRelations, setAllRelations] = useState<AllRelationsFrontend | null>(null);
const [roleDescription, setRoleDescription] = useState(''); const [roleDescription, setRoleDescription] = useState('');
const [anchorEle, setAnchorEle] = useState<HTMLElement | null>(null); const [anchorEle, setAnchorEle] = useState<HTMLElement | null>(null);
const openPopover = Boolean(anchorEle); const openPopover = Boolean(anchorEle);
...@@ -471,7 +472,7 @@ export default function ContactManagement() { ...@@ -471,7 +472,7 @@ export default function ContactManagement() {
if (allRelations === null) { if (allRelations === null) {
fetchWrapperPagination(api_prefix() + '/sys/relations?type=CO&page=', 1, saveAllRelations); fetchWrapperPagination(api_prefix() + '/sys/relations?type=CO&page=', 1, saveAllRelations);
} }
}, [allRelations]); }, [allRelations, setAllRelations]);
useEffect(() => { useEffect(() => {
if (contactData === null || allRelations === null) { if (contactData === null || allRelations === null) {
......
...@@ -4,47 +4,14 @@ import DashboardIntro from './DashboardIntro'; ...@@ -4,47 +4,14 @@ import DashboardIntro from './DashboardIntro';
import DashboardOverview from './DashboardOverview'; import DashboardOverview from './DashboardOverview';
import DashboardProjectsAndWG from './DashboardProjectsAndWG/DashboardProjectsAndWG'; import DashboardProjectsAndWG from './DashboardProjectsAndWG/DashboardProjectsAndWG';
import DashboardResources from './DashboardResources'; import DashboardResources from './DashboardResources';
import { useContext, useEffect, useState } from 'react'; import { useContext, useEffect } from 'react';
import { fetchWrapper } from '../../../Utils/formFunctionHelpers'; import { fetchWrapper } from '../../../Utils/formFunctionHelpers';
import { api_prefix, FETCH_METHOD, getCurrentMode, MODE_REACT_ONLY } from '../../../Constants/Constants'; import { api_prefix, FETCH_METHOD, getCurrentMode, MODE_REACT_ONLY } from '../../../Constants/Constants';
import { OrganizationRoles, OrgInfoBackend, OrgRep } from '../../../Interfaces/portal_interface'; import { OrgInfoBackend } from '../../../Interfaces/portal_interface';
import PortalContext from '../../../Context/PortalContext'; import PortalContext from '../../../Context/PortalContext';
export default function Dashboard() { export default function Dashboard() {
const { orgId, orgInfo, setOrgInfo } = useContext(PortalContext); const { orgId, orgInfo, setOrgInfo } = useContext(PortalContext);
const [orgRepData, setOrgRepData] = useState<Array<OrgRep> | null>(null);
useEffect(() => {
if (orgId === 0 || orgRepData !== null) {
return;
}
const urlForOrgInfo =
getCurrentMode() === MODE_REACT_ONLY
? '/membership_data/test_org_rep.json'
: `${api_prefix()}/organizations/${orgId}/representatives`;
const saveOrgRep = (data: any) => {
const repCR: Array<OrgRep> = [];
const repCRA: Array<OrgRep> = [];
const repMA: Array<OrgRep> = [];
const updateOrgRepData = (contact: any, relation: 'CR' | 'CRA' | 'MA', repArray: Array<OrgRep>) => {
contact.relations.includes(relation) &&
repArray.push({ name: `${contact.first_name} ${contact.last_name}`, type: OrganizationRoles[relation] });
};
data.forEach((item: any) => {
updateOrgRepData(item, 'CR', repCR);
updateOrgRepData(item, 'CRA', repCRA);
updateOrgRepData(item, 'MA', repMA);
});
setOrgRepData([...repCR, ...repCRA, ...repMA]);
};
fetchWrapper(urlForOrgInfo, FETCH_METHOD.GET, saveOrgRep);
}, [orgId, orgRepData]);
useEffect(() => { useEffect(() => {
if (orgId === 0 || orgInfo !== null) { if (orgId === 0 || orgInfo !== null) {
...@@ -64,7 +31,7 @@ export default function Dashboard() { ...@@ -64,7 +31,7 @@ export default function Dashboard() {
return ( return (
<> <>
<DashboardIntro orgRepData={orgRepData} /> <DashboardIntro />
<DashboardOverview /> <DashboardOverview />
<DashboardProjectsAndWG /> <DashboardProjectsAndWG />
<DashboardCommittersAndContributors /> <DashboardCommittersAndContributors />
......
...@@ -132,37 +132,27 @@ const useStyles = makeStyles((theme: Theme) => ...@@ -132,37 +132,27 @@ const useStyles = makeStyles((theme: Theme) =>
}) })
); );
interface CommitterOrContributor { const isReactOnlyMode = getCurrentMode() === MODE_REACT_ONLY;
name: string;
url: string;
}
interface CBIData {
inUse: number;
allocated: number;
}
export default function DashboardCommittersAndContributors() { export default function DashboardCommittersAndContributors() {
const classes = useStyles(); const classes = useStyles();
const history = useHistory(); const history = useHistory();
const [committers, setCommitters] = useState<Array<CommitterOrContributor>>([]);
const [contributors, setContributors] = useState<Array<CommitterOrContributor>>([]);
const [cbiData, setCBIData] = useState<CBIData>();
const [isFetchingCommitters, setIsFetchingCommitters] = useState(true); const [isFetchingCommitters, setIsFetchingCommitters] = useState(true);
const [isFetchingContributors, setIsFetchingContributors] = useState(true); const [isFetchingContributors, setIsFetchingContributors] = useState(true);
const [isFetchingCBI, setIsFetchingCBI] = useState(true); const [isFetchingCBI, setIsFetchingCBI] = useState(true);
const [anchorEle, setanchorEle] = useState<HTMLElement | null>(null); const [anchorEle, setAnchorEle] = useState<HTMLElement | null>(null);
const { orgId, setContactFilterRole } = useContext(PortalContext); const { orgId, setContactFilterRole, committers, setCommitters, contributors, setContributors, cbiData, setCBIData } =
useContext(PortalContext);
const { currentUser } = useContext(GlobalContext); const { currentUser } = useContext(GlobalContext);
const open = Boolean(anchorEle); const open = Boolean(anchorEle);
useEffect(() => { useEffect(() => {
if (!orgId) { if (!orgId || committers !== null) {
committers !== null && setIsFetchingCommitters(false);
return; return;
} }
const isReactOnlyMode = getCurrentMode() === MODE_REACT_ONLY;
// For committers // For committers
const urlForCommitters = isReactOnlyMode const urlForCommitters = isReactOnlyMode
...@@ -179,7 +169,14 @@ export default function DashboardCommittersAndContributors() { ...@@ -179,7 +169,14 @@ export default function DashboardCommittersAndContributors() {
setIsFetchingCommitters(false); setIsFetchingCommitters(false);
}; };
orgId !== 0 && fetchWrapper(urlForCommitters, FETCH_METHOD.GET, saveCommittersData); fetchWrapper(urlForCommitters, FETCH_METHOD.GET, saveCommittersData);
}, [orgId, committers, setCommitters]);
useEffect(() => {
if (!orgId || contributors !== null) {
contributors !== null && setIsFetchingContributors(false);
return;
}
// For contributors // For contributors
const urlForContributors = isReactOnlyMode const urlForContributors = isReactOnlyMode
...@@ -195,7 +192,14 @@ export default function DashboardCommittersAndContributors() { ...@@ -195,7 +192,14 @@ export default function DashboardCommittersAndContributors() {
setContributors(fiveRandomContributors); setContributors(fiveRandomContributors);
setIsFetchingContributors(false); setIsFetchingContributors(false);
}; };
orgId !== 0 && fetchWrapper(urlForContributors, FETCH_METHOD.GET, saveContributorsData); fetchWrapper(urlForContributors, FETCH_METHOD.GET, saveContributorsData);
}, [orgId, contributors, setContributors]);
useEffect(() => {
if (!orgId || cbiData !== null) {
cbiData !== null && setIsFetchingCBI(false);
return;
}
// For CBI data // For CBI data
const urlForCBIData = isReactOnlyMode const urlForCBIData = isReactOnlyMode
...@@ -213,8 +217,8 @@ export default function DashboardCommittersAndContributors() { ...@@ -213,8 +217,8 @@ export default function DashboardCommittersAndContributors() {
setCBIData({ inUse, allocated }); setCBIData({ inUse, allocated });
setIsFetchingCBI(false); setIsFetchingCBI(false);
}; };
orgId !== 0 && fetchWrapper(urlForCBIData, FETCH_METHOD.GET, saveCBIData); fetchWrapper(urlForCBIData, FETCH_METHOD.GET, saveCBIData);
}, [orgId]); }, [orgId, cbiData, setCBIData]);
const canViewCommiters = checkPermission(PERMISSIONS_BASED_ON_ROLES.viewCommitters, currentUser?.relation); const canViewCommiters = checkPermission(PERMISSIONS_BASED_ON_ROLES.viewCommitters, currentUser?.relation);
const canViewContributors = checkPermission(PERMISSIONS_BASED_ON_ROLES.viewContributors, currentUser?.relation); const canViewContributors = checkPermission(PERMISSIONS_BASED_ON_ROLES.viewContributors, currentUser?.relation);
...@@ -232,7 +236,7 @@ export default function DashboardCommittersAndContributors() { ...@@ -232,7 +236,7 @@ export default function DashboardCommittersAndContributors() {
subtitle="Your Committers" subtitle="Your Committers"
color={brightBlue} color={brightBlue}
icon={<PeopleAltIcon />} icon={<PeopleAltIcon />}
listItems={committers} listItems={committers || []}
urlText="View more" urlText="View more"
callBackFunc={() => { callBackFunc={() => {
setContactFilterRole('committer'); setContactFilterRole('committer');
...@@ -248,7 +252,7 @@ export default function DashboardCommittersAndContributors() { ...@@ -248,7 +252,7 @@ export default function DashboardCommittersAndContributors() {
subtitle="Your Contributors" subtitle="Your Contributors"
color={brightBlue} color={brightBlue}
icon={<PeopleAltIcon />} icon={<PeopleAltIcon />}
listItems={contributors} listItems={contributors || []}
urlText="View more" urlText="View more"
callBackFunc={() => { callBackFunc={() => {
setContactFilterRole('contributor'); setContactFilterRole('contributor');
...@@ -294,7 +298,7 @@ export default function DashboardCommittersAndContributors() { ...@@ -294,7 +298,7 @@ export default function DashboardCommittersAndContributors() {
</div> </div>
</> </>
)} )}
<div className={classes.helpButton} onClick={(ev) => setanchorEle(ev.currentTarget)}> <div className={classes.helpButton} onClick={(ev) => setAnchorEle(ev.currentTarget)}>
<HelpIcon className={classes.helpIcon} /> <HelpIcon className={classes.helpIcon} />
</div> </div>
<Popover <Popover
...@@ -303,7 +307,7 @@ export default function DashboardCommittersAndContributors() { ...@@ -303,7 +307,7 @@ export default function DashboardCommittersAndContributors() {
elevation={4} elevation={4}
open={open} open={open}
anchorEl={anchorEle} anchorEl={anchorEle}
onClose={() => setanchorEle(null)} onClose={() => setAnchorEle(null)}
anchorOrigin={{ anchorOrigin={{
vertical: -65, vertical: -65,
horizontal: 'center', horizontal: 'center',
......
<
...@@ -33,10 +33,8 @@ const useStyles = makeStyles(() => ...@@ -33,10 +33,8 @@ const useStyles = makeStyles(() =>
function DashboardCommittersAndContributorsChart() { function DashboardCommittersAndContributorsChart() {
const classes = useStyles(); const classes = useStyles();
const [chartCommits, setChartCommits] = useState<Array<number>>([]);
const [chartCommitters, setChartCommitters] = useState<Array<number>>([]);
const [chartMonths, setChartMonths] = useState<Array<string>>([]); const [chartMonths, setChartMonths] = useState<Array<string>>([]);
const { orgId } = useContext(PortalContext); const { orgId, chartCommits, setChartCommits, chartCommitters, setChartCommitters } = useContext(PortalContext);
const DATA_FOR_BAR_LINE_CHART = { const DATA_FOR_BAR_LINE_CHART = {
labels: chartMonths, labels: chartMonths,
...@@ -47,22 +45,22 @@ function DashboardCommittersAndContributorsChart() { ...@@ -47,22 +45,22 @@ function DashboardCommittersAndContributorsChart() {
borderColor: brightBlue, borderColor: brightBlue,
borderWidth: 2, borderWidth: 2,
fill: false, fill: false,
data: chartCommitters, data: chartCommitters || [],
}, },
{ {
type: 'bar', type: 'bar',
label: 'Commits', label: 'Commits',
backgroundColor: '#F0F2F8', backgroundColor: '#F0F2F8',
data: chartCommits, data: chartCommits || [],