Commit d7352bfb authored by Oleksii Savran's avatar Oleksii Savran Committed by Matija Obreza

Dashboard: List partners of user

- removed unused components
Signed-off-by: Matija Obreza's avatarMatija Obreza <matija.obreza@croptrust.org>
parent 101f3e9e
......@@ -334,6 +334,8 @@
"title": "My Dashboard",
"subtitle": "Manage data published on Genesys",
"whatDoYouWant": "What do you want to do?",
"manageMyProfile": "Manage my profile",
"selected": "Selected",
"record": "Record",
"record_plural": "Records"
}
......@@ -2095,6 +2097,14 @@
"viewOnWebsite": "View on FAO WIEWS website"
}
}
},
"dashboard": {
"p": {
"browse": {
"subtitle": "You are a member of Genesys data providers",
"empty": "You are not a member of a Genesys data provider"
}
}
}
},
"repository": {
......
......@@ -3,13 +3,16 @@ import { push } from 'connected-react-router';
// Actions
import { loadPartner } from 'partners/actions/editor';
import { loadPartnerNames } from 'actions/decoder';
import {createApiCaller} from 'actions/ApiCall';
import { createApiCaller, createPureApiCaller } from 'actions/ApiCall';
// Constants
import { DASHBOARD_CREATE_PARTNER, DASHBOARD_RECEIVE_MY_PARTNERLIST } from 'partners/constants';
// Model
import PartnerFilter from 'model/genesys/PartnerFilter';
import FilteredPage from 'model/FilteredPage';
import Page from 'model/Page';
import Partner from 'model/genesys/Partner';
// Service
import PartnerService from 'service/catalog/PartnerService';
......@@ -20,6 +23,7 @@ import { log } from 'utilities/debug';
// Wrapped API calls
const apiListPartners = createApiCaller(PartnerService.myPartners, DASHBOARD_RECEIVE_MY_PARTNERLIST);
export const listPartnerInstitutesCall = createPureApiCaller(PartnerService.listInstitutes);
// List user's partners
export const loadMyPartners = () => (dispatch, getState) => {
......@@ -41,3 +45,13 @@ export const editPartner = (uuid: string) => (dispatch, getState) => {
dispatch(loadPartner(uuid));
dispatch(push(`/admin/partners/${uuid}/edit`));
};
export const updateRoute = (paged: FilteredPage<Partner>) => (dispatch) => {
// stub for BrowsePageTemplate
return null;
};
export const loadMorePartners = (paged?: FilteredPage<Partner>) => (dispatch) => {
return dispatch(apiListPartners(new PartnerFilter(), Page.nextPage(paged)))
.then((paged) => dispatch(updateRoute(paged)));
};
......@@ -2,7 +2,7 @@
import { loadPartnerNames } from 'actions/decoder';
import { addFilterCode, filterCodeToUrl} from 'actions/filterCode';
import navigateTo from 'actions/navigation';
import {createApiCaller} from 'actions/ApiCall';
import { createApiCaller } from 'actions/ApiCall';
// Constants
import {
......
import update from 'immutability-helper';
import { IReducerAction } from 'model/common.model';
import Partner from 'model/genesys/Partner';
import FilteredPage from 'model/FilteredPage';
import {
DASHBOARD_REMOVE_PARTNER_INSTITUTES,
......@@ -15,7 +16,7 @@ import Page from 'model/Page';
const INITIAL_STATE: {
myPartners: ApiCall<Partner[]>,
myPartners: ApiCall<FilteredPage<Partner>>,
currentPartner: ApiCall<Partner>,
partnerInstitutes: ApiCall<Page<FaoInstitute>>,
} = {
......@@ -64,10 +65,17 @@ export default (state = INITIAL_STATE, action: IReducerAction = { type: '' }) =>
// set myPartners
case DASHBOARD_RECEIVE_MY_PARTNERLIST: {
const {apiCall} = action.payload;
const {apiCall: {loading, error, timestamp, data}} = action.payload;
// log('My partners', action.payload);
return update(state, {
myPartners: { $set: apiCall },
myPartners: {
$set: {
loading,
error,
timestamp,
data: FilteredPage.merge(state.myPartners && state.myPartners.data, data),
},
},
});
}
default:
......
......@@ -65,5 +65,13 @@
"viewOnWebsite": "View on FAO WIEWS website"
}
}
},
"dashboard": {
"p": {
"browse": {
"subtitle": "You are a member of Genesys data providers",
"empty": "You are not a member of a Genesys data provider"
}
}
}
}
......@@ -334,6 +334,8 @@
"title": "My Dashboard",
"subtitle": "Manage data published on Genesys",
"whatDoYouWant": "What do you want to do?",
"manageMyProfile": "Manage my profile",
"selected": "Selected",
"record": "Record",
"record_plural": "Records"
}
......
import * as React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { parse } from 'query-string';
import { withTranslation } from 'react-i18next';
import { WithStyles, withStyles } from '@material-ui/core/styles';
import { filterCodeToUrl } from 'actions/filterCode';
import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton';
import Loading from 'ui/common/Loading';
import PageTitle from 'ui/common/PageTitle';
import PageLayout, { PageContents } from 'ui/layout/PageLayout';
import { ScrollToTopOnMount } from 'ui/common/page/scrollers';
import ContentHeader from 'ui/common/heading/ContentHeader';
import ErrorMessage from 'ui/common/error/ErrorMessage';
import SectionHeader from 'ui/common/heading/SectionHeader';
import { BaseMyDataPage } from './MyDataPage';
import { loadMyPartners, listPartnerInstitutesCall } from 'partners/actions/dashboard';
import Partner from 'model/genesys/Partner';
import ApiCall from 'model/ApiCall';
import FilteredPage from 'model/FilteredPage';
import Page from 'model/Page';
import FaoInstitute from 'model/genesys/FaoInstitute';
import Grid from '@material-ui/core/Grid';
import Card from 'ui/common/Card';
import { Link } from 'react-router-dom';
const styles = (theme) => ({
/* eslint-disable*/
link: {
display: 'block',
fontSize: '1.5rem',
width: '100%',
height: '100%',
lineHeight: '3rem',
'&:hover': {
textDecoration: 'underline',
},
},
card: {
height: '3rem',
textAlign: 'center' as 'center',
'& a': {
color: 'black',
}
}
/* eslint-enable */
});
interface IAdminDashProps extends React.ClassAttributes<any> {
createDataset: any;
createPartner: any;
createDescriptor: any;
createDescriptorList: any;
title: string;
history: any;
interface IDashProps extends React.ClassAttributes<any>, WithStyles {
t: any;
partnersApi: ApiCall<FilteredPage<Partner>>;
listPartnerInstitutesCall: (uuid: string) => Promise<Page<FaoInstitute>>;
loadMyPartners: () => void;
}
class AdministrationDashboard extends BaseMyDataPage<IAdminDashProps> {
public constructor(props) {
super(props);
class DashboardPage extends React.Component<IDashProps> {
public state = {
selectedPartner: undefined,
institutes: undefined,
}
public constructor(props) {
super(props);
}
public componentDidUpdate(prevProps) {
const { partnersApi } = this.props;
if (partnersApi == null) {
// Initial load
// console.log('Initial load');
this.selectPartner(undefined);
this.props.loadMyPartners();
} else if (this.state.selectedPartner === undefined && partnersApi.data) {
if (partnersApi.data && partnersApi.data.content.length > 0) {
// console.log('Selected 1st');
this.selectPartner(partnersApi.data.content[0]);
} else {
// console.log('Null partner');
this.selectPartner(null);
}
}
}
private selectPartner(partner: Partner) {
if (partner && this.state.selectedPartner && this.state.selectedPartner.uuid === partner.uuid) {
return;
}
console.log(`Selecting partner`, partner);
if (partner && partner.uuid) {
this.props.listPartnerInstitutesCall(partner.uuid).then((institutes) => {
this.setState({ ...this.state, institutes: institutes.content });
});
}
this.setState({ selectedPartner: partner, institutes: undefined });
}
public render() {
const { t } = this.props;
return (
<div>
<PageTitle title={ t('dashboard.p.dashboard.whatDoYouWant') }/>
<ContentHeaderWithButton title={ t('dashboard.p.dashboard.whatDoYouWant') }/>
public render() {
const { partnersApi, t, classes } = this.props;
const { selectedPartner, institutes } = this.state;
const { data: partners, loading, error} = partnersApi || { data: undefined, loading: true, error: undefined };
return (
<PageLayout>
<ScrollToTopOnMount/>
<PageTitle title={ t('dashboard.p.dashboard.whatDoYouWant') }/>
<ContentHeader title={ t('dashboard.p.dashboard.whatDoYouWant') }/>
<PageContents className="pt-1rem container-spacing-horizontal">
<Grid container spacing={ 3 } className="p-20">
<Grid item xs={ 12 } sm={ 6 } md={ 3 }>
<Card className={ classes.card } square>
<Link className={ classes.link } to="/dashboard/profile">
{ t('dashboard.p.dashboard.manageMyProfile') }
</Link>
</Card>
</Grid>
<Grid item xs={ 12 } sm={ 6 } md={ 3 }>
<Card className={ classes.card } square>
<Link className={ classes.link } to="/dashboard/profile/password">
{ t('user.dashboard.menu.changePassword') }
</Link>
</Card>
</Grid>
<Grid item xs={ 12 } sm={ 6 } md={ 3 }>
<Card className={ classes.card } square>
<Link className={ classes.link } to="/dashboard/datasets">
{ t('datasets.dashboard.menu.datasets') }
</Link>
</Card>
</Grid>
<Grid item xs={ 12 } sm={ 6 } md={ 3 }>
<Card className={ classes.card } square>
<Link className={ classes.link } to="/dashboard/subsets">
{ t('subsets.dashboard.menu.subsets') }
</Link>
</Card>
</Grid>
</Grid>
{ partners && partners.content.length > 0 ? (
<>
<SectionHeader
className="mt-1rem"
title={ t('partners.common.modelName_plural') }
subTitle={ t('partners.dashboard.p.browse.subtitle') }
/>
{ partners.content.map((partner) => (
<div key={ partner.uuid }>
{ selectedPartner && selectedPartner.uuid === partner.uuid && (
<strong>{ t('dashboard.p.dashboard.selected') } </strong>
) }
<span onClick={ () => this.selectPartner(partner) }>{ partner.name }</span>
{ institutes && selectedPartner && selectedPartner.uuid === partner.uuid && institutes.map((institute) => (
<div key={ institute.code }>{ institute.code }</div>
) ) }
</div>
);
}
) ) }
</>
) : error ? (
<ErrorMessage error={ error }/>
) : loading ? (
<Loading />
) : (
<></>
) }
</PageContents>
</PageLayout>
);
}
}
const mapStateToProps = (state, ownProps) => ({
title: ownProps.route.extraProps.title, // route-configured
tab: ownProps.match.params.tab || 'datasets', // current tab, or ownProps.location.pathname
pageCurrent: +parse(ownProps.location.search).p || 0, // current page
pageSize: +parse(ownProps.location.search).l || 20, // page size
pageSort: parse(ownProps.location.search).s || 'lastModifiedDate', // page sort
pageDir: parse(ownProps.location.search).d || 'DESC', // page sort direction
filterCode: parse(ownProps.location.search).filter, // filter code
filter: state.filterCode.filters && parse(ownProps.location.search).filter && state.filterCode.filters[parse(ownProps.location.search).filter as string] || null,
tab: ownProps.match.params.tab || 'index', // current tab, or ownProps.location.pathname
partnersApi: state.partner.dashboard.myPartners,
});
const mapDispatchToProps = (dispatch) => bindActionCreators({
filterCodeToUrl,
loadMyPartners,
listPartnerInstitutesCall,
}, dispatch);
export default withTranslation()(connect(mapStateToProps, mapDispatchToProps)(AdministrationDashboard));
export default withTranslation()(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(DashboardPage)));
import * as React from 'react';
import {withStyles} from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
const styles = (theme) => ({
buttonStyle: theme.buttons.dashboardBigButton,
title: {
fontSize: '20px',
},
subTitle: {
display: 'inline-block',
width: '100%',
fontSize: '16px',
},
});
interface IDashboardButtonProps extends React.ClassAttributes<any> {
classes: any;
title: string;
subTitle: string;
onClickFunction: () => void;
}
class DashboardButton extends React.Component<IDashboardButtonProps, any> {
public constructor(props: any) {
super(props);
}
public render() {
const {classes, title, subTitle} = this.props;
return (
<div className="pt-10 pr-10 pb-10 pl-10">
<Button onClick={ this.props.onClickFunction } className={ classes.buttonStyle }>
<span className={ `font-bold ${ classes.title }` }>{ title }</span>
{
!subTitle ? null : <span className={ classes.subTitle }>{ subTitle }</span>
}
</Button>
</div>
);
}
}
export default (withStyles as any)(styles)(DashboardButton);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment