Commit d2d5f406 authored by Maksym Tishchenko's avatar Maksym Tishchenko
Browse files

AccessionSource Cooperators

parent 685cf69c
......@@ -564,6 +564,9 @@
"associatedSpecies_hint": "associated_species -- Associated Species"
},
"AccessionSourceMap": {
"sourceTypeCode": "Source Type",
"sourceId": "Accession Source ID",
"cooperatorId": "Source Cooperator ID",
"accessionSourceMap": "Accession Source Map",
"accessionSource": "Accession Source",
"cooperator": "Cooperator"
......
......@@ -4,6 +4,7 @@ import AccessionIpr from '@gringlobal-ce/client/model/gringlobal/AccessionIpr';
import AccessionPedigree from '@gringlobal-ce/client/model/gringlobal/AccessionPedigree';
import AccessionQuarantine from '@gringlobal-ce/client/model/gringlobal/AccessionQuarantine';
import AccessionSource from '@gringlobal-ce/client/model/gringlobal/AccessionSource';
import AccessionSourceMap from '@gringlobal-ce/client/model/gringlobal/AccessionSourceMap';
import Citation from '@gringlobal-ce/client/model/gringlobal/Citation';
import AccessionInvAttach from '@gringlobal-ce/client/model/gringlobal/AccessionInvAttach';
import Accession from './Accession';
......@@ -15,6 +16,7 @@ import Accession from './Accession';
*/
class AccessionDetails extends Accession {
public sources: AccessionSource[];
public sourceCooperators: AccessionSourceMap[];
public actions: AccessionAction[];
public ipr: AccessionIpr[];
public pedigree: AccessionPedigree[];
......@@ -23,6 +25,15 @@ class AccessionDetails extends Accession {
public names: AccessionInvName[];
public attachments: AccessionInvAttach[];
public static DEREFERENCES = {
// sit: { id: [ 'site', 'backupLocation1Site', 'backupLocation2Site' ] },
// spe: { id: [ 'taxonomySpecies' ] },
// gen: { id: [ 'taxonomySpecies.taxonomyGenus' ] },
...Accession.DEREFERENCES,
src: { id: [ 'sources[]', 'sourceCooperators[].accessionSource' ] },
coo: { id: [ 'names[].nameSourceCooperator', 'sourceCooperators[].cooperator', 'actions[].cooperator', 'ipr[].cooperator', 'quarantine[].custodialCooperator', 'attachments[].attachCooperator' ] },
geo: { id: [ 'sources[].geography', 'sourceCooperators[].accessionSource.geography' ] }
}
}
export default AccessionDetails;
import AccessionSource from '@gringlobal-ce/client/model/gringlobal/AccessionSource';
import Cooperator from '@gringlobal-ce/client/model/gringlobal/Cooperator';
import AclSid from '@gringlobal-ce/client/model/acl/AclSid';
/**
* AccessionSourceMap
*
* GRIN-Global CE API
*/
class AccessionSourceMap {
public createdBy: number;
public createdDate: Date;
public modifiedBy: number;
public modifiedDate: Date;
public ownedBy: AclSid;
public ownedDate: Date;
public accessionSource: AccessionSource;
public cooperator: Cooperator;
public id: number;
}
export default AccessionSourceMap;
......@@ -551,6 +551,9 @@
"associatedSpecies_hint": "associated_species -- Associated Species"
},
"AccessionSourceMap": {
"sourceTypeCode": "Source Type",
"sourceId": "Accession Source ID",
"cooperatorId": "Source Cooperator ID",
"accessionSourceMap": "Accession Source Map",
"accessionSource": "Accession Source",
"cooperator": "Cooperator"
......
......@@ -3,7 +3,7 @@ import * as UrlTemplate from 'url-template';
import * as QueryString from 'query-string';
import { AxiosInstance, AxiosRequestConfig } from 'axios';
import { Accession, AccessionFilter, AccessionFilteredPage, AccessionAction, AccessionActionFilter, AccessionActionFilteredPage } from '@gringlobal-ce/client/model/gringlobal';
import { Accession, AccessionFilter, AccessionFilteredPage, AccessionAction, AccessionActionFilter, AccessionActionFilteredPage, Cooperator } from '@gringlobal-ce/client/model/gringlobal';
import { FilteredPage, IPageRequest, Page, SortDirection } from '@gringlobal-ce/client/model/page';
import { dereferenceReferences3, stripObjectsToId } from '@gringlobal-ce/client/utilities';
import AccessionSource from '@gringlobal-ce/client/model/gringlobal/AccessionSource';
......@@ -16,6 +16,7 @@ import AccessionQuarantine from '@gringlobal-ce/client/model/gringlobal/Accessio
import Citation from '@gringlobal-ce/client/model/gringlobal/Citation';
import AccessionInvGroup from '@gringlobal-ce/client/model/gringlobal/AccessionInvGroup';
import AccessionActionRequest from '@gringlobal-ce/client/model/gringlobal/AccessionActionRequest';
import AccessionSourceMap from '@gringlobal-ce/client/model/gringlobal/AccessionSourceMap';
const URL_GET_DETAILS = UrlTemplate.parse('/api/v1/a/details/{id}');
const URL_ACCESSION_AUDIT_LOGS = UrlTemplate.parse('/api/v1/a/auditlog/{id}');
......@@ -57,6 +58,10 @@ const URL_UPDATE_ACCESSION_SOURCE = '/api/v1/a/source';
const URL_CREATE_ACCESSION_SOURCE = '/api/v1/a/source';
const URL_GET_ACCESSION_SOURCE = UrlTemplate.parse('/api/v1/a/source/{id}');
const URL_REMOVE_ACCESSION_SOURCE = UrlTemplate.parse('/api/v1/a/source/{id}');
const URL_UPDATE_SOURCE_COOPERATOR = `/api/v1/a/source/cooperator-map`;
const URL_CREATE_SOURCE_COOPERATOR = `/api/v1/a/source/cooperator-map`;
const URL_GET_SOURCE_COOPERATOR = UrlTemplate.parse(`/api/v1/a/source/cooperator-map/{id}`);
const URL_REMOVE_SOURCE_COOPERATOR = UrlTemplate.parse(`/api/v1/a/source/cooperator-map/{id}`);
const URL_UPDATE_CITATION = '/api/v1/a/citation';
const URL_CREATE_CITATION = '/api/v1/a/citation';
const URL_GET_CITATION = UrlTemplate.parse('/api/v1/a/citation/{id}');
......@@ -92,7 +97,17 @@ class AccessionService {
method: 'GET',
...content,
}).then(({ data }) => {
dereferenceReferences3([ data ], Accession.DEREFERENCES);
dereferenceReferences3([ data ], AccessionDetails.DEREFERENCES);
const sourceCooperators: Cooperator & { cooperatorId: number, source: AccessionSource }[]
= data?.sourceCooperators?.map(sourceCoop => ({
cooperatorId: sourceCoop.cooperator.id,
...sourceCoop.cooperator,
id: sourceCoop.id, // preserve original id
accessionSource: sourceCoop.accessionSource
}));
if (sourceCooperators) {
data.sourceCooperators = sourceCooperators;
}
return data as AccessionDetails
});
}
......@@ -927,6 +942,86 @@ class AccessionService {
}).then(({ data }) => data as AccessionSource);
}
/**
* updateSourceMap at /api/v1/a/source/cooperator-map
*
* @param data Request body
* @param xhrConfig additional xhr config
*/
public updateSourceMap = (data: AccessionSourceMap, xhrConfig?: AxiosRequestConfig): Promise<AccessionSourceMap> => {
const apiUrl = URL_UPDATE_SOURCE_COOPERATOR;
// console.log(`Fetching from ${apiUrl}`);
const content = { data: stripObjectsToId(data) };
return this._axios.request({
...xhrConfig,
url: apiUrl,
method: 'PUT',
...content,
}).then(({ data }) => data as AccessionSourceMap);
}
/**
* createSourceMap at /api/v1/a/source/cooperator-map
*
* @param data Request body
* @param xhrConfig additional xhr config
*/
public createSourceMap = (data: AccessionSourceMap, xhrConfig?: AxiosRequestConfig): Promise<AccessionSourceMap> => {
const apiUrl = URL_CREATE_SOURCE_COOPERATOR;
// console.log(`Fetching from ${apiUrl}`);
const content = { data };
return this._axios.request({
...xhrConfig,
url: apiUrl,
method: 'POST',
...content,
}).then(({ data }) => data as AccessionSourceMap);
}
/**
* getSourceMap at /api/v1/a/source/cooperator-map/{id}
*
* @param id undefined
* @param xhrConfig additional xhr config
*/
public getSourceMap = (id: number, xhrConfig?: AxiosRequestConfig): Promise<AccessionSourceMap> => {
const apiUrl = URL_GET_SOURCE_COOPERATOR.expand({ id });
// console.log(`Fetching from ${apiUrl}`);
const content = { /* No content in request body */ };
return this._axios.request({
...xhrConfig,
url: apiUrl,
method: 'GET',
...content,
}).then(({ data }) => data as AccessionSourceMap);
}
/**
* removeSourceMap at /api/v1/a/source/cooperator-map/{id}
*
* @param id undefined
* @param xhrConfig additional xhr config
*/
public removeSourceMap = (id: number, xhrConfig?: AxiosRequestConfig): Promise<AccessionSourceMap> => {
const apiUrl = URL_REMOVE_SOURCE_COOPERATOR.expand({ id });
// console.log(`Fetching from ${apiUrl}`);
const content = { /* No content in request body */ };
return this._axios.request({
...xhrConfig,
url: apiUrl,
method: 'DELETE',
...content,
}).then(({ data }) => data as AccessionSourceMap);
}
/**
* updateCitation at /api/v1/a/citation
*
......
......@@ -38,7 +38,7 @@ interface IAutocompleteProps {
label: string;
mapOptions: (data: any) => any[];
getOptionLabel: (option: any) => string;
searchProperty?: string;
renderOption?: (option: any, state?: any) => React.ReactNode;
helperText?: string; // static hint
......@@ -48,6 +48,7 @@ interface IAutocompleteProps {
noOptionsText?: string;
placeholder?: string;
required?: boolean;
withDetails?: (details: any) => React.ReactNode;
}
interface IAutocompleteState {
......@@ -161,7 +162,7 @@ class Autocomplete extends React.Component<IAutocompleteProps & WithStyles & Wit
};
public render() {
const { label, classes, helperText, renderOption, getOptionLabel, noOptionsText, placeholder, t, required, meta } = this.props;
const { label, classes, helperText, renderOption, getOptionLabel, noOptionsText, placeholder, t, required, meta, withDetails } = this.props;
const { error, touched, dirty } = meta;
const { loading, open, options, inputValue } = this.state;
......@@ -187,28 +188,31 @@ class Autocomplete extends React.Component<IAutocompleteProps & WithStyles & Wit
filterOptions={ NOFILTER } // disable default filtering
inputValue={ inputValue }
renderInput={ (params) => (
<TextField
{ ...params }
label={ label }
variant="filled"
placeholder={ placeholder || t('common:autocomplete.helperText') }
helperText={ (touched && error ? t(error) : this.getHelperText()) || helperText }
error={ touched && error && true }
InputLabelProps={ {
'aria-label': meta.dirty ? t('common:label.fieldModified', { what: label }) : null,
required
} }
InputProps={ {
...params.InputProps,
className: dirty ? classes.dirtyField : '',
endAdornment: (
<React.Fragment>
{ loading ? <CircularProgress color="inherit" size={ 20 } className={ classes.loading } /> : null }
{ options.length > 0 && params.InputProps.endAdornment }
</React.Fragment>
),
} }
/>
<>
<TextField
{ ...params }
label={ label }
variant="filled"
placeholder={ placeholder || t('common:autocomplete.helperText') }
helperText={ (touched && error ? t(error) : this.getHelperText()) || helperText }
error={ touched && error && true }
InputLabelProps={ {
'aria-label': meta.dirty ? t('common:label.fieldModified', { what: label }) : null,
required
} }
InputProps={ {
...params.InputProps,
className: dirty ? classes.dirtyField : '',
endAdornment: (
<React.Fragment>
{ loading ? <CircularProgress color="inherit" size={ 20 } className={ classes.loading } /> : null }
{ options.length > 0 && params.InputProps.endAdornment }
</React.Fragment>
),
} }
/>
{ withDetails && options.length === 1 && withDetails(options[0]) }
</>
) }
/>
);
......
......@@ -182,7 +182,7 @@ export function dereferenceReferences3(content: any[], referenceMaps: { [key: st
})
});
const sortedPaths = paths.sort(); // sorted paths should ensure we access deeper properties late
// console.log('Caches', refs, paths, sortedPaths, keyOfPath, cacheForPath);
console.log('Caches', refs, paths, sortedPaths, keyOfPath, cacheForPath);
// First scan: fill caches with objects
sortedPaths.forEach((path) => {
......@@ -194,10 +194,10 @@ export function dereferenceReferences3(content: any[], referenceMaps: { [key: st
if (typeof v === 'object') {
if (selfRef) {
refs._self[`${v[keyOfPath._self]}`] = v;
// console.log(`Cached ${path} by prop ${keyOfPath[path]}`, v[keyOfPath[path]], v, cacheForPath[path]);
console.log(`Cached ${path} by prop ${keyOfPath[path]}`, v[keyOfPath[path]], v, cacheForPath[path]);
} else {
cacheForPath[path][`${v[keyOfPath[path]]}`] = v;
// console.log(`Cached ${path} by prop ${keyOfPath[path]}`, v[keyOfPath[path]], v, cacheForPath[path]);
console.log(`Cached ${path} by prop ${keyOfPath[path]}`, v[keyOfPath[path]], v, cacheForPath[path]);
}
}
}
......@@ -215,10 +215,10 @@ export function dereferenceReferences3(content: any[], referenceMaps: { [key: st
const cv = cacheForPath[path][`${v}`];
if (selfRef) {
content[index] = cv || v;
// console.log(`Set self from ${keyOfPath[path]}=${v}`, cv);
console.log(`Set self from ${keyOfPath[path]}=${v}`, cv);
} else {
propertySet(entry, path, cv || v);
// console.log(`Set ${path} from ${keyOfPath[path]}=${v}`, cv);
console.log(`Set ${path} from ${keyOfPath[path]}=${v}`, cv);
}
}
}
......
......@@ -214,6 +214,7 @@
"citations": "Accession citations",
"pedigree": "Accession pedigree",
"sources": "Accession source history",
"sourceCooperators": "Accession source cooperators",
"ipr": "Intellectual Property Rights/Restrictions",
"names": "Accession names",
"delete": "Do you really want to delete {{name}} accession?",
......@@ -267,6 +268,10 @@
"edit": "Edit accession source",
"add": "Add accession source"
},
"AccessionSourceMapDialog": {
"edit": "Edit accession source cooperator",
"add": "Add accession source cooperator"
},
"AccessionPedigreeDialog": {
"edit": "Edit accession pedigree",
"add": "Add accession pedigree"
......@@ -280,7 +285,8 @@
"add": "Add accession citation"
},
"error": {
"noInventories": "Accession doesn't have any inventories"
"noInventories": "Accession doesn't have any inventories",
"noAccessionSource": "No accession source selected, please select one"
},
"AccessionInventorySelector": {
"selectAccessions": "Select from one accession",
......
......@@ -29,6 +29,10 @@ import {
SAGA_RECEIVE_ACCESSION_SOURCE_SUCCESS,
REMOVE_ACCESSION_SOURCE,
SAGA_REMOVE_ACCESSION_SOURCE,
SAGA_REMOVE_ACCESSION_SOURCE_MAP,
SAGA_RECEIVE_ACCESSION_SOURCE_MAP_SUCCESS,
RECEIVE_ACCESSION_SOURCE_MAP,
REMOVE_ACCESSION_SOURCE_MAP,
RECEIVE_ACCESSION_PEDIGREE,
SAGA_RECEIVE_ACCESSION_PEDIGREE_SUCCESS,
REMOVE_ACCESSION_PEDIGREE,
......@@ -39,8 +43,14 @@ import {
SAGA_REMOVE_CITATION,
RECEIVE_ACCESSION_QUARANTINE,
SAGA_RECEIVE_ACCESSION_QUARANTINE_SUCCESS,
REMOVE_ACCESSION_QUARANTINE, SAGA_REMOVE_ACCESSION_QUARANTINE,
REMOVE_ACCESSION_ATTACHMENT, SAGA_REMOVE_ACCESSION_ATTACHMENT, SAGA_REMOVE_ACCESSION_ATTACHMENTS, SAGA_RECEIVE_ACCESSION_ATTACHMENT_SUCCESS, UPDATE_ACCESSION_ATTACHMENT, RECEIVE_ACCESSIONS_MCPD_LIST,
REMOVE_ACCESSION_QUARANTINE,
SAGA_REMOVE_ACCESSION_QUARANTINE,
REMOVE_ACCESSION_ATTACHMENT,
SAGA_REMOVE_ACCESSION_ATTACHMENT,
SAGA_REMOVE_ACCESSION_ATTACHMENTS,
SAGA_RECEIVE_ACCESSION_ATTACHMENT_SUCCESS,
UPDATE_ACCESSION_ATTACHMENT,
RECEIVE_ACCESSIONS_MCPD_LIST,
} from 'accession/constants';
// Actions
import { uploadFilesSaga } from 'inventory/action/public';
......@@ -63,6 +73,7 @@ import AccessionQuarantine from '@gringlobal-ce/client/model/gringlobal/Accessio
import { dereferenceReferences3 as dereferenceReferences } from '@gringlobal-ce/client/utilities';
import { AccessionFilteredPage, InventoryFilteredPage, AccessionActionFilteredPage } from '@gringlobal-ce/client/model/gringlobal';
import AccessionInvAttach from '@gringlobal-ce/client/model/gringlobal/AccessionInvAttach';
import AccessionSourceMap from '@gringlobal-ce/client/model/gringlobal/AccessionSourceMap';
export const accessionPublicSagas = [
takeEvery(SAGA_LIST_ACCESSIONS, listAccessionsSaga),
......@@ -79,6 +90,8 @@ export const accessionPublicSagas = [
takeEvery(SAGA_RECEIVE_ACCESSION_IPR_SUCCESS, receiveAccessionIprSaga),
takeEvery(SAGA_REMOVE_ACCESSION_SOURCE, removeAccessionSourceSaga),
takeEvery(SAGA_RECEIVE_ACCESSION_SOURCE_SUCCESS, receiveAccessionSourceSaga),
takeEvery(SAGA_REMOVE_ACCESSION_SOURCE_MAP, removeAccessionSourceMapSaga),
takeEvery(SAGA_RECEIVE_ACCESSION_SOURCE_MAP_SUCCESS, receiveAccessionSourceMapSaga),
takeEvery(SAGA_REMOVE_ACCESSION_PEDIGREE, removeAccessionPedigreeSaga),
takeEvery(SAGA_RECEIVE_ACCESSION_PEDIGREE_SUCCESS, receiveAccessionPedigreeSaga),
takeEvery(SAGA_REMOVE_CITATION, removeCitationSaga),
......@@ -338,7 +351,7 @@ export const removeAccessionInvNameAction = (id: number) => ({
payload: { id },
});
// Accession Ipr
// AccessionIpr
function* receiveAccessionIprSaga(action) {
yield put({
......@@ -369,7 +382,7 @@ export const removeAccessionIprAction = (id: number) => ({
payload: { id },
});
// Accession Source
// AccessionSource
function* receiveAccessionSourceSaga(action) {
yield put({
......@@ -400,7 +413,38 @@ export const removeAccessionSourceAction = (id: number) => ({
payload: { id },
});
// Accession Pedigree
// AccessionSourceMap
function* receiveAccessionSourceMapSaga(action) {
yield put({
type: RECEIVE_ACCESSION_SOURCE_MAP,
payload: { apiCall: ApiCall.success(action.payload.accessionSourceMap) },
});
}
export const receiveAccessionSourceMapSuccessAction = (accessionSourceMap: AccessionSourceMap) => ({
type: SAGA_RECEIVE_ACCESSION_SOURCE_MAP_SUCCESS,
payload: { accessionSourceMap },
});
function* removeAccessionSourceMapSaga(action) {
yield put({
type: 'API',
target: REMOVE_ACCESSION_SOURCE_MAP,
method: AccessionService.removeSourceMap,
params: [ action.payload.id ],
onSuccess: (accessionSourceMap: AccessionSourceMap) => {
return accessionSourceMap;
},
});
}
export const removeAccessionSourceMapAction = (id: number) => ({
type: SAGA_REMOVE_ACCESSION_SOURCE_MAP,
payload: { id },
});
// AccessionPedigree
function* receiveAccessionPedigreeSaga(action) {
yield put({
......@@ -462,7 +506,7 @@ export const removeCitationAction = (id: number) => ({
payload: { id },
});
// Accession Quarantine
// AccessionQuarantine
function* receiveAccessionQuarantineSaga(action) {
yield put({
......
......@@ -45,6 +45,13 @@ export const RECEIVE_ACCESSION_SOURCE = 'success/accession/public/RECEIVE_ACCESS
export const SAGA_REMOVE_ACCESSION_SOURCE = 'saga/accession/public/REMOVE_ACCESSION_SOURCE';
export const REMOVE_ACCESSION_SOURCE = 'success/accession/public/REMOVE_ACCESSION_SOURCE';
// AccessionSourceMap
export const SAGA_RECEIVE_ACCESSION_SOURCE_MAP_SUCCESS = 'saga/accession/public/RECEIVE_SOURCE_MAP_SUCCESS';
export const RECEIVE_ACCESSION_SOURCE_MAP = 'success/accession/public/RECEIVE_ACCESSION_SOURCE_MAP';
export const SAGA_REMOVE_ACCESSION_SOURCE_MAP = 'saga/accession/public/REMOVE_ACCESSION_SOURCE_MAP';
export const REMOVE_ACCESSION_SOURCE_MAP = 'success/accession/public/REMOVE_ACCESSION_SOURCE_MAP';
// AccessionPedigree
export const SAGA_RECEIVE_ACCESSION_PEDIGREE_SUCCESS = 'saga/accession/public/RECEIVE_PEDIGREE_SUCCESS';
export const RECEIVE_ACCESSION_PEDIGREE = 'success/accession/public/RECEIVE_ACCESSION_PEDIGREE';
......
......@@ -23,6 +23,8 @@ import {
RECEIVE_ACCESSION_QUARANTINE,
REMOVE_ACCESSION_ATTACHMENT,
UPDATE_ACCESSION_ATTACHMENT,
RECEIVE_ACCESSION_SOURCE_MAP,
REMOVE_ACCESSION_SOURCE_MAP,
} from 'accession/constants';
// Model
import AccessionDetails from '@gringlobal-ce/client/model/gringlobal/AccessionDetails';
......@@ -192,6 +194,40 @@ const publicReducer = (state = initialState, action) => {
accession: { $set: null },
});
}
case RECEIVE_ACCESSION_SOURCE_MAP: {
const { apiCall } = action.payload;
if (apiCall.data && state.accession) {
const { data: accession } = state.accession;
const accessionSourceMap = apiCall.data;
const updatedIndex = accession && accession.sourceCooperators && accession.sourceCooperators.findIndex((sourceMap) => +sourceMap.id === +accessionSourceMap.id);
if (updatedIndex !== undefined && updatedIndex !== -1) {
return update(state, {
accession: {
data: {
sourceCooperators: {
[updatedIndex]: { $set: accessionSourceMap },
},
},
},
});
} else {
return update(state, {
accession: {
data: {
sourceCooperators: {
$set: [ ...accession.sourceCooperators, accessionSourceMap ],
},
},
},
});
}
}
return update(state, {
accession: { $set: null },
});
}
case RECEIVE_ACCESSION_PEDIGREE: {
const { apiCall } = action.payload;
if (apiCall.data && state.accession) {
......@@ -490,6 +526,27 @@ const publicReducer = (state = initialState, action) => {
}
return state;
}
case REMOVE_ACCESSION_SOURCE_MAP: {
const { apiCall: { data } } = action.payload;
if (data) {
if (state.accession && state.accession.data && state.accession.data.sourceCooperators) {
const updatedSourceCooperators = state.accession.data.sourceCooperators.filter((sourceMap) => sourceMap.id !== data.id);
return update(state, {
accession: {
data: {
sourceCooperators: {
$set: updatedSourceCooperators,
},
},
},
});
}
return update(state, {
accession: { $set: null },
});
}
return state;
}
case REMOVE_ACCESSION_PEDIGREE: {
const { apiCall: { data } } = action.payload;
if (data) {
......
......@@ -36,6 +36,7 @@
"citations": "Accession citations",
"pedigree": "Accession pedigree",
"sources": "Accession source history",
"sourceCooperators": "Accession source cooperators",
"ipr": "Intellectual Property Rights/Restrictions",
"names": "Accession names",
"delete": "Do you really want to delete {{name}} accession?",
......@@ -89,6 +90,10 @@
"edit": "Edit accession source",
"add": "Add accession source"
},
"AccessionSourceMapDialog": {
"edit": "Edit accession source cooperator",
"add": "Add accession source cooperator"
},
"AccessionPedigreeDialog": {
"edit": "Edit accession pedigree",
"add": "Add accession pedigree"
......@@ -102,7 +107,8 @@
"add": "Add accession citation"
},
"error": {
"noInventories": "Accession doesn't have any inventories"
"noInventories": "Accession doesn't have any inventories",
"noAccessionSource": "No accession source selected, please select one"
},
"AccessionInventorySelector": {
"selectAccessions": "Select from one accession",
......
......@@ -218,7 +218,6 @@ class BrowsePage extends React.Component<IBrowsePageProps> {
resetError={ this.resetError }
accessions={ selected }
tableConfig={ AccessionTableConfig }
initialValues={ { isWebVisible: 'N' } }