Commit 12ec1698 authored by Matija Obreza's avatar Matija Obreza

Merge branch 'genesys-server-425-ui-part' into 'master'

Versioned Datasets: update - UI part

See merge request genesys-pgr/genesys-ui!264
parents 6ece18c7 c1059c70
......@@ -1078,7 +1078,10 @@
},
"c": {
"card": {
"evaluationPeriod": "Evaluation period"
"evaluationPeriod": "Evaluation period",
"version": "Version",
"newVersionLink": "See current version of the subset",
"currentVersion": "Current version"
},
"datasetDisplay": {
"accessionsEvaluated": "Accessions evaluated",
......
......@@ -31,6 +31,7 @@ export { createDataset };
// Wrapped API Calls
const apiMyDatasets = createApiCaller(DatasetService.myDatasets, DASHBOARD_APPEND_DATASET_PAGE);
const apiListAccessions = createApiCaller(DatasetService.listAccessions, DASHBOARD_APPEND_ACCESSIONS_PAGE);
const apiCreateNewVersion = createApiCaller(DatasetService.createNewVersion, RECEIVE_DATASET);
export const apiGetDataset = createApiCaller(DatasetService.getDataset, RECEIVE_DATASET);
export const apiRejectDataset = createApiCaller(DatasetService.rejectDataset, RECEIVE_DATASET);
......@@ -71,6 +72,10 @@ export const loadDataset = (uuid: string) => (dispatch) => {
return dispatch(apiGetDataset(uuid));
};
export const createNewVersion = (uuid) => (dispatch) => {
return dispatch(apiCreateNewVersion(uuid))
.then((newVersion) => dispatch(navigateTo(`/dashboard/datasets/${newVersion.uuid}/edit`)));
};
function publishDataset(datasetUuid: string) {
return (dispatch, getState) => {
......
......@@ -62,6 +62,7 @@ function datasetsDashboard(state = INITIAL_STATE, action: { type?: string, paylo
return update(state, {
dataset: { $set: apiCall },
paged: apiCall.loading ? { $set: state.paged } : { $set: null },
accessionRefs: { $set: mustRemoveAccessions ? null : state.accessionRefs },
});
}
}
......
......@@ -35,7 +35,7 @@ function datasetsPublic(state = INITIAL_STATE, action: { type?: string, payload?
const {apiCall} = action.payload;
const receivedIndex = state.paged && state.paged.data ? _.findIndex(state.paged.data.content, (item) => item.uuid === apiCall.uuid) : -1;
const mustRemoveAccessions = state.dataset && state.dataset.data && (apiCall.uuid !== state.dataset.data.uuid);
const mustRemoveAccessions = state.dataset && state.dataset.data && apiCall.data && (apiCall.uuid !== state.dataset.data.uuid);
if (receivedIndex !== -1) {
return update(state, {
......@@ -50,6 +50,7 @@ function datasetsPublic(state = INITIAL_STATE, action: { type?: string, payload?
} else {
return update(state, {
dataset: { $set: apiCall },
accessionRefs: { $set: mustRemoveAccessions ? null : state.accessionRefs },
});
}
}
......
......@@ -147,7 +147,10 @@
},
"c": {
"card": {
"evaluationPeriod": "Evaluation period"
"evaluationPeriod": "Evaluation period",
"version": "Version",
"newVersionLink": "See current version of the subset",
"currentVersion": "Current version"
},
"datasetDisplay": {
"accessionsEvaluated": "Accessions evaluated",
......
......@@ -61,6 +61,14 @@ class DatasetDetail extends React.Component<IDatasetDetailProps, any> {
}
}
public componentWillReceiveProps(nextProps) {
const { loading, dataset, uuid, loadDataset, loadMoreAccessions } = nextProps;
if (!loading && uuid && (! dataset || uuid !== dataset.uuid)) {
loadDataset(uuid);
loadMoreAccessions(uuid);
}
}
private loadMoreAccessions = (paged: Page<AccessionRef>) => {
const { loadMoreAccessions, dataset } = this.props;
loadMoreAccessions(dataset.uuid, paged);
......
......@@ -40,6 +40,7 @@ import PagedLoader from 'ui/common/PagedLoader';
import AccessionRefCard from 'accessions/ui/c/AccessionRefCard';
import Number from 'ui/common/Number';
import DownloadDialog from 'ui/common/download-dialog';
import {DatasetLink} from 'ui/genesys/Links';
const styles = (theme) => ({
root: {
......@@ -129,6 +130,9 @@ const styles = (theme) => ({
marginRight: '0',
},
},
hasNewVersion: {
backgroundColor: '#ffe2e2 !important',
},
});
interface IDetailInfoProps extends React.ClassAttributes<any> {
......@@ -264,7 +268,7 @@ class DetailInfo extends React.Component<IDetailInfoProps, any> {
<Grid container spacing={ 0 }>
<Grid item xs={ 12 } className="p-10" id="dataset-top">
<Card className={ classes.card } square>
<CardHeader className={ classes.cardHeader }
<CardHeader className={ dataset.currentVersion && classes.hasNewVersion }
title={ t('datasets.public.p.display.title') }
subheader={ <small>{ dataset.versionTag }</small> }/>
<CardContent className={ classes.cardContent }>
......@@ -291,6 +295,13 @@ class DetailInfo extends React.Component<IDetailInfoProps, any> {
<PropertiesItem title={ t('datasets.public.c.datasetDisplay.properties.evaluationEnd') }>
<McpdDate value={ dataset.endDate }/>
</PropertiesItem>
{ dataset.currentVersion &&
<PropertiesItem classes={ {propertiesRow: classes.hasNewVersion} } title={ t('datasets.public.c.card.version') }>
<span>
<DatasetLink uuid={ dataset.currentVersion }>{ t('datasets.public.c.card.newVersionLink') }</DatasetLink>
</span>
</PropertiesItem>
}
</Properties>
</CardContent>
{ publishDataset && (dataset._permissions.write || dataset._permissions.delete) && (
......
......@@ -3,12 +3,27 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import BaseMyDataPage from 'ui/catalog/dashboard/MyDataPage';
import { approveDataset, deleteDataset, loadMoreDatasets, unpublishDataset, publishDataset } from 'datasets/actions/dashboard';
import { approveDataset, deleteDataset, loadMoreDatasets, unpublishDataset, publishDataset, createNewVersion } from 'datasets/actions/dashboard';
import Dataset from 'model/catalog/Dataset';
import { DatasetLink } from 'ui/catalog/Links';
import { DatasetLink } from 'ui/genesys/Links';
import { PublishState } from 'model/common.model';
import ActionButton from 'ui/common/buttons/ActionButton';
const renderDataLink = ({ row, children }) => (<DatasetLink to={ row } edit={ row.state === PublishState.DRAFT && row._permissions.write }>{ children }</DatasetLink>);
const renderDataLink = ({ row, children, needCurrent, t }) => (
<span>
{ needCurrent ? <DatasetLink uuid={ row.currentVersion }>{ t('datasets.public.c.card.currentVersion') }</DatasetLink>
: <DatasetLink to={ row } edit={ row.state === PublishState.DRAFT && row._permissions.write }>{ children }</DatasetLink>
}
</span>
);
const renderActions = ({ row, handleCreateNewVersion, t }) => (
<div>
{ row.state === PublishState.PUBLISHED &&
<ActionButton variant="text" title={ t('common:action.createNewVersion') } action={ () => handleCreateNewVersion(row.uuid) }/>
}
</div>
);
class DashboardPage extends BaseMyDataPage<Dataset> {}
......@@ -18,6 +33,7 @@ const mapStateToProps = (state, ownProps) => ({
dataClassName: Dataset.clazz,
filterCode: ownProps.match.params.filterCode,
renderDataLink,
renderActions,
});
const mapDispatchToProps = (dispatch) => bindActionCreators({
......@@ -26,6 +42,7 @@ const mapDispatchToProps = (dispatch) => bindActionCreators({
publishOne: publishDataset,
approveOne: approveDataset,
unpublishOne: unpublishDataset,
createNewVersion: (uuid) => dispatch(createNewVersion(uuid)),
}, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage);
......@@ -23,6 +23,7 @@ class Dataset implements IUserPermissions {
public createdDate: Date;
public creators: DatasetCreator[];
public crops: string[];
public currentVersion: string;
public description: string;
public descriptorCount: number;
public descriptors: Descriptor[];
......
......@@ -42,6 +42,7 @@ const URL_DELETE_LOCATION = UrlTemplate.parse(`/api/v1/dataset/{uuid}/location/d
const URL_LIST_LOCATION = UrlTemplate.parse(`/api/v1/dataset/{uuid}/location/list`);
const URL_UPDATE_LOCATION = UrlTemplate.parse(`/api/v1/dataset/{uuid}/location/update`);
const URL_LOAD_LOCATION_BY_UUID = UrlTemplate.parse(`/api/v1/dataset/{uuid}/location/{locationUuid}`);
const URL_CREATE_NEW_VERSION = `/api/v1/dataset/create-new-version`;
/*
* Defined in Swagger as 'dataset'
......@@ -137,6 +138,28 @@ class DatasetService {
}).then(({ data }) => data as Dataset);
}
/**
* createNewVersion at /api/v1/dataset/create-new-version
*
* @param uuid uuid
*/
public static createNewVersion(uuid: string, xhrConfig?): Promise<Dataset> {
const qs = QueryString.stringify({
uuid: uuid || undefined,
}, {});
const apiUrl = URL_CREATE_NEW_VERSION + (qs ? `?${qs}` : '');
// console.log(`Fetching from ${apiUrl}`);
const content = { /* No content in request body */ };
return axiosBackend.request({
...xhrConfig,
url: apiUrl,
method: 'POST',
...content,
}).then(({ data }) => data as Dataset);
}
/**
* reviewDataset at /api/v1/dataset/for-review
*
......
......@@ -33,6 +33,8 @@ interface IDataPublishedContainerProps extends React.ClassAttributes<any> {
listMyData: any;
dataClassName: string;
renderDataLink: any;
renderActions: any;
createNewVersion: (uuid: string) => void;
addToEditList: (item: any) => void;
removeFromEditList: (item: any) => void;
onPageChange: () => void;
......@@ -117,7 +119,7 @@ class BaseMyDataPage<T> extends React.Component<T & IDataPublishedContainerProps
}
public render() {
const { tab, filterComponent, basePath, addToEditList, removeFromEditList, isEditMode, setEditMode, editList, paged, dataClassName, renderDataLink, title } = this.props;
const { tab, filterComponent, basePath, addToEditList, removeFromEditList, isEditMode, setEditMode, editList, paged, dataClassName, renderDataLink, renderActions, createNewVersion, title } = this.props;
const actionHandlers = this.getActionHandlers();
const Filters = filterComponent ? filterComponent : DashboardFilters;
......@@ -132,6 +134,8 @@ class BaseMyDataPage<T> extends React.Component<T & IDataPublishedContainerProps
onFilter={ this.onFilter }
dataClassName={ dataClassName }
renderDataLink={ renderDataLink }
renderActions={ renderActions }
createNewVersion={ createNewVersion }
paged={ paged }
onSortChange={ this.onSortChange }
setEditState={ setEditMode }
......
......@@ -35,6 +35,11 @@ const styles = () => ({
},
/*tslint:enable*/
},
cardActions: {
width: '100%',
display: 'flex',
flexDirection: 'row-reverse' as 'row-reverse',
},
});
class DashboardCard extends React.Component<any> {
......@@ -61,7 +66,7 @@ class DashboardCard extends React.Component<any> {
}
public render() {
const { item, tab, index, isEditMode, DataLink, dataClassName, t, classes } = this.props;
const { item, tab, index, isEditMode, DataLink, dataClassName, createNewVersion, Actions, t, classes } = this.props;
const { inEditList } = this.state;
return (
......@@ -93,6 +98,11 @@ class DashboardCard extends React.Component<any> {
{ ` ${t('descriptors.common.modelName', {count: item.descriptorCount})} ` }
</span>
}
{ item.currentVersion &&
<span className="float-right">
<DataLink row={ item } needCurrent t={ t }/>
</span>
}
</div>
<DashboardCardDates item={ item }/>
</div>
......@@ -108,7 +118,10 @@ class DashboardCard extends React.Component<any> {
onChange={ this.onCheckboxChange }
style={ !isEditMode ? { opacity: 0 } : {} }
/>
{ item._permissions.manage && <Permissions clazz={ dataClassName } id={ item.id }/> }
<div className={ classes.cardActions }>
{ item._permissions.manage && <Permissions clazz={ dataClassName } id={ item.id }/> }
{ Actions && <Actions row={ item } handleCreateNewVersion={ createNewVersion } t={ t } /> }
</div>
</CardActions>
</Card>
);
......
......@@ -32,6 +32,8 @@ interface IMyDataCardsProps extends React.Props<any> {
onFilter: (filter) => void;
dataClassName: string;
renderDataLink: any;
renderActions: any;
createNewVersion: (uuid: string) => void;
pagination: any;
promiseListData: any;
deleteAllAction: any;
......@@ -74,6 +76,8 @@ class MyDataCards extends React.Component<IMyDataCardsProps> {
removeFromEditAction={ this.props.removeFromEditList }
dataClassName={ this.props.dataClassName }
DataLink={ this.props.renderDataLink }
Actions={ this.props.renderActions }
createNewVersion={ this.props.createNewVersion }
/>
)
......
......@@ -3,6 +3,7 @@ import { Link } from 'react-router-dom';
import Markdown from 'ui/common/markdown';
import Subset from 'model/subset/Subset';
import Dataset from 'model/catalog/Dataset';
import Accession from 'model/accession/Accession';
import FaoInstitute from 'model/genesys/FaoInstitute';
import MaterialRequest from 'model/request/MaterialRequest';
......@@ -137,16 +138,20 @@ const RegionLink = ({ region, children }: { region: GeoRegion, children?: any })
);
};
const DatasetLink = ({ to: dataset, edit = false, children = null }
: { to: any, edit?: boolean, children?: any }) => {
const DatasetLink = ({ to: dataset, uuid = null, edit = false, children = null }
: { to?: Dataset, uuid?: string, edit?: boolean, children?: any }) => {
if (dataset) {
return (
<Link to={ `/datasets/${dataset.uuid}` }>
<Link to={ `${edit ? '/dashboard' : ''}/datasets/${dataset.uuid}${edit ? '/edit' : '' }` }>
{ children || <Markdown basic source={ dataset.title } /> }
</Link>
);
} else {
return null;
return uuid && children ? (
<Link to={ `${edit ? '/dashboard' : ''}/datasets/${uuid}${edit ? '/edit' : ''}` }>
{ children }
</Link>
) : null;
}
};
......
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