Commit 622026d5 authored by Oleksii Savran's avatar Oleksii Savran

Added CropTraitCode table, fixed infinity loading for CropTraits

parent 79f74e30
......@@ -105,6 +105,10 @@
"originalValueFormat": "Original value format",
"originalValueTypeCode": "Original value Type Code"
},
"TranslatedCropTraitCode": {
"code": "Code",
"cropTrait": "Crop trait"
},
"Geography": {
"geography": "Geography",
"currentGeography": "Current Valid Geography",
......
......@@ -15,11 +15,11 @@ class CropTrait {
public ownedDate: Date;
public categoryCode: string;
public codedName: string;
public crop: Crop; //
public crop: Crop;
public dataTypeCode: string;
public id: number;
public isArchived: string;
public isCoded: string; //
public isCoded: string;
public isPeerReviewed: string;
public maxLength: number;
public note: string;
......
......@@ -94,6 +94,10 @@
"originalValueFormat": "Original value format",
"originalValueTypeCode": "Original value Type Code"
},
"TranslatedCropTraitCode": {
"code": "Code",
"cropTrait": "Crop trait"
},
"Geography": {
"geography": "Geography",
"currentGeography": "Current Valid Geography",
......
......@@ -7,6 +7,7 @@ import { IPageRequest } from '@gringlobal/client/model/page';
import CropTrait from '@gringlobal/client/model/gringlobal/CropTrait';
import CropTraitFilter from '@gringlobal/client/model/gringlobal/CropTraitFilter';
import TranslatedCropTrait from '@gringlobal/client/model/gringlobal/TranslatedCropTrait';
import FilteredPage from '@gringlobal/client/model/page/FilteredPage';
const URL_UPLOAD_FILE = UrlTemplate.parse('/api/v1/crop-trait/attach/{cropTraitId}');
const URL_GET_TRANSLATED = UrlTemplate.parse('/api/v1/crop-trait/{id}');
......@@ -201,7 +202,7 @@ class CropTraitService {
* @param page undefined
* @param xhrConfig additional xhr config
*/
public list = (data: CropTraitFilter, page?: IPageRequest, xhrConfig?: AxiosRequestConfig): Promise<TranslatedCropTrait> => {
public list = (data: CropTraitFilter, page?: IPageRequest, xhrConfig?: AxiosRequestConfig): Promise<FilteredPage<TranslatedCropTrait>> => {
const qs = QueryString.stringify({
p: page.page || undefined,
......@@ -218,7 +219,7 @@ class CropTraitService {
url: apiUrl,
method: 'POST',
...content,
}).then(({ data }) => data as TranslatedCropTrait);
}).then(({ data }) => data as FilteredPage<TranslatedCropTrait>);
}
}
......
......@@ -211,7 +211,8 @@
}
},
"traitsDetails": {
"title": "Crop trait details"
"title": "Crop trait details",
"codes": "Codes"
}
}
},
......
......@@ -64,7 +64,15 @@ export const getCropSpeciesAction = (id: string| number) => ({
export const getCropTraitsAction = (cropId: string| number, pageR: IPageRequest = { page: 0, size: 100 }) => ({
type: SAGA_RECEIVE_CROP_TRAITS,
payload: { cropId, pageR },
payload: { filter: { crop: [cropId] }, pageR },
});
export const loadMoreCropTraitsAction = (traits: FilteredPage<CropTrait>) => ({
type: SAGA_RECEIVE_CROP_TRAITS,
payload: {
filter: traits.filter || {},
pageR: Page.nextPage(traits),
},
});
export const uploadCropAttachment = (id: number, file: File) => ({
......@@ -129,12 +137,11 @@ export function* receiveCropTraitSaga(action) {
}
function* receiveCropTraitsSaga(action) {
const { cropId, pageR } = action.payload;
yield put({
type: 'API',
target: RECEIVE_CROP_TRAITS,
method: CropTraitService.list,
params: [{ crop: [cropId] }, pageR],
params: [action.payload.filter, action.payload.pageR],
onSuccess: (cropTraits: FilteredPage<CropTrait>) => {
dereferenceReferences3(cropTraits.content, {
coo: { id: [ 'ownedBy' ] },
......
......@@ -13,7 +13,8 @@
}
},
"traitsDetails": {
"title": "Crop trait details"
"title": "Crop trait details",
"codes": "Codes"
}
}
},
......
......@@ -3,7 +3,7 @@ import { bindActionCreators, compose } from 'redux';
import { connect } from 'react-redux';
import { WithTranslation, withTranslation } from 'react-i18next';
// Action
import { getCropDetailsAction, getCropSpeciesAction, uploadCropAttachment, getCropTraitsAction } from 'crop/action/public';
import { getCropDetailsAction, getCropSpeciesAction, uploadCropAttachment, getCropTraitsAction, loadMoreCropTraitsAction } from 'crop/action/public';
import navigateTo from '@gringlobal/client/action/navigation';
// Model
import ApiCall from '@gringlobal/client/model/common/ApiCall';
......@@ -41,12 +41,13 @@ interface ICropDetailsPage extends React.ClassAttributes<any>, WithTranslation {
getCropDetailsAction: (id) => void;
getCropSpeciesAction: (id) => void;
getCropTraitsAction: (id) => void;
loadMoreCropTraitsAction: (traits: FilteredPage<CropTrait>) => void;
id: string;
navigateTo: (path: string, query?: object) => void;
uploadCropAttachment: (id: number, file: File) => void;
}
export const CropTraitTablDefaultConfig = {
export const CropTraitTableDefaultConfig = {
defaultColumns: [
'id',
'codedName',
......@@ -79,7 +80,7 @@ export const CropTraitTablDefaultConfig = {
};
const TaxonomySpeciesTableConfig = new TableConfiguration(TaxonomySpeciesTableDefaultConfig);
const CropTraitTableConfig = new TableConfiguration(CropTraitTablDefaultConfig);
const CropTraitTableConfig = new TableConfiguration(CropTraitTableDefaultConfig);
class CropDetailsPage extends React.Component<ICropDetailsPage> {
......@@ -136,6 +137,11 @@ class CropDetailsPage extends React.Component<ICropDetailsPage> {
uploadCropAttachment(cropCall.data.id, files[0]);
};
public loadMoreCropTraits = (): void => {
const { traitsCall, loadMoreCropTraitsAction } = this.props;
loadMoreCropTraitsAction(traitsCall.data);
};
public render() {
const { cropCall, t, speciesCall, traitsCall } = this.props;
const { selectedTab } = this.state;
......@@ -155,7 +161,7 @@ class CropDetailsPage extends React.Component<ICropDetailsPage> {
onChange={ this.selectTab }
variant="scrollable"
scrollButtons="auto"
aria-label="Inventory tabs"
aria-label="Crop details tabs"
>
<Tab value="info" label={ t('crop.public.p.details.title') } />
<Tab value="attachments" label={ t('crop.public.p.details.attachments') } />
......@@ -229,6 +235,7 @@ class CropDetailsPage extends React.Component<ICropDetailsPage> {
data={ traitsCall && traitsCall.data && traitsCall.data.content }
tableConfig={ CropTraitTableConfig }
total={ traitsCall && traitsCall.data && traitsCall.data.content && traitsCall.data.totalElements }
loadMore={ this.loadMoreCropTraits }
/>
</SlotLayout>
<Authorize roles={ [ UserRole.ADMINISTRATOR ] }>
......@@ -272,6 +279,7 @@ const mapDispatchToProps = (dispatch) => bindActionCreators({
getCropSpeciesAction,
getCropTraitsAction,
uploadCropAttachment,
loadMoreCropTraitsAction,
navigateTo,
}, dispatch);
......
......@@ -20,6 +20,9 @@ import PrettyDate from '@gringlobal/client/ui/common/time/PrettyDate';
import { CodeValueDisplay } from 'common/CodeValue';
import PageTitle from '@gringlobal/client/ui/common/PageTitle';
import { YesNoToBoolean } from '@gringlobal/client/utilities';
import Table, { TextAlign } from '@gringlobal/client/ui/common/table/Table';
import { CooperatorOwnedTableConfiguration as TableConfiguration } from '@gringlobal/client/ui/common/table/TableConfiguration';
import { PageSection } from '@gringlobal/client/ui/common/layout/Section';
interface ICropTraitDetailsPage extends React.ClassAttributes<any>, WithTranslation {
......@@ -30,6 +33,21 @@ interface ICropTraitDetailsPage extends React.ClassAttributes<any>, WithTranslat
removeCropTraitAction: (id: number) => void;
}
const CropTraitsCodesTableDefaultConfig = {
defaultColumns: [
'id',
'code',
'title',
'description',
],
ignoredColumns: ['cropTrait'],
defaultColumnSettings: {
id: { readonly: true, align: TextAlign.right },
},
};
const CropTraitsCodesTableConfig = new TableConfiguration(CropTraitsCodesTableDefaultConfig);
class CropTraitDetailsPage extends React.Component<ICropTraitDetailsPage> {
protected static needs = [
......@@ -67,6 +85,9 @@ class CropTraitDetailsPage extends React.Component<ICropTraitDetailsPage> {
return null;
}
const { loading, data: cropTrait } = cropTraitCall;
const codesColumns = CropTraitsCodesTableConfig.getColumns(cropTraitCall && cropTraitCall.data && cropTraitCall.data.codes && cropTraitCall.data.codes.length ? cropTraitCall.data.codes[0] : null);
return (
<>
<PageTitle title={ t('crop.public.p.traitsDetails.title') }/>
......@@ -138,6 +159,19 @@ class CropTraitDetailsPage extends React.Component<ICropTraitDetailsPage> {
{ t('common:action.remove') }
</Button>
</CardActions>
{ YesNoToBoolean(cropTrait.isCoded) && cropTrait.codes && cropTrait.codes.length > 0 &&
<PageSection title={ t('crop.public.p.traitsDetails.codes') }>
<Table
noWrap
tableKey="crop-trait-code-list"
type={ 'TranslatedCropTraitCode' }
columns={ codesColumns }
data={ cropTrait.codes }
tableConfig={ CropTraitsCodesTableConfig }
total={ cropTrait.codes.length }
/>
</PageSection>
}
</Card>
</div>
) }
......
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