Commit 3bec0de1 authored by Maksym Tishchenko's avatar Maksym Tishchenko
Browse files

Bug: Missing pagination

parent 1463879f
......@@ -6,7 +6,8 @@ import { AxiosInstance, AxiosRequestConfig } from 'axios';
import CodeValueInfo from '@gringlobal-ce/client/model/gringlobal/CodeValueInfo';
import SysLang from '@gringlobal-ce/client/model/gringlobal/SysLang';
import AppSetting from '@gringlobal-ce/client/model/gringlobal/AppSetting';
import { Page } from '@gringlobal-ce/client/model/page';
import { IPageRequest, Page } from '@gringlobal-ce/client/model/page';
import * as QueryString from "query-string";
const URL_CODE_VALUES_LIST = '/api/v1/app/codes';
// const URL_APP_RESOURCES_LIST = UrlTemplate.parse('/api/v1/app/resources/{appName}/{lang}');
......@@ -154,11 +155,18 @@ class ApplicationService {
/**
* appSettingsList at /api/v1/app/settings
*
* @param page = paged query
* @param xhrConfig additional xhr config
*/
public appSettingsList = (xhrConfig?: AxiosRequestConfig): Promise<Page<AppSetting>> => {
const apiUrl = URL_APP_SETTINGS_LIST;
public appSettingsList = (page: IPageRequest = {}, xhrConfig?: AxiosRequestConfig): Promise<Page<AppSetting>> => {
const qs = QueryString.stringify({
p: page.page || undefined,
l: page.size || 100,
d: page.direction ? page.direction : undefined,
s: page.properties && page.properties.length && page.properties || undefined,
}, {});
const apiUrl = URL_APP_SETTINGS_LIST + (qs ? `?${qs}` : '');
// console.log(`Fetching from ${apiUrl}`);
const content = { /* No content in request body */ };
......
......@@ -79,9 +79,15 @@ class InventoryViabilityRuleService {
* @param id undefined
* @param xhrConfig additional xhr config
*/
public listSpecies = (id: number, xhrConfig?: AxiosRequestConfig): Promise<Page<InventoryViabilityRuleMap>> => {
public listSpecies = (id: number, page: IPageRequest = {}, xhrConfig?: AxiosRequestConfig): Promise<Page<InventoryViabilityRuleMap>> => {
const apiUrl = URL_LIST_SPECIES.expand({ id });
const qs = QueryString.stringify({
p: page.page || undefined,
l: page.size || undefined,
d: page.direction ? page.direction : undefined,
s: page.properties || undefined,
}, {});
const apiUrl = URL_LIST_SPECIES.expand({ id }) + (qs ? `?${qs}` : '');
// console.log(`Fetching from ${apiUrl}`);
const content = { /* No content in request body */ };
......
......@@ -224,9 +224,16 @@ class InventoryViabilityService {
* @param data Request body
* @param xhrConfig additional xhr config
*/
public listScheduledInventories = (data: InventoryFilter, xhrConfig?: AxiosRequestConfig): Promise<InventoryActionFilteredPage> => {
public listScheduledInventories = (data: InventoryFilter, page: IPageRequest = {}, xhrConfig?: AxiosRequestConfig): Promise<InventoryActionFilteredPage> => {
const apiUrl = URL_LIST_SCHEDULED_INVENTORIES;
const qs = QueryString.stringify({
f: typeof data === 'string' ? data : undefined,
p: page.page || undefined,
l: page.size || undefined,
d: page.direction ? page.direction : undefined,
s: page.properties || undefined,
}, {});
const apiUrl = URL_LIST_SCHEDULED_INVENTORIES + (qs ? `?${qs}` : '');
// console.log(`Fetching from ${apiUrl}`);
const content = { data };
......
......@@ -6,6 +6,7 @@ import {
import { ApplicationService } from '@gringlobal-ce/client/service';
import { ApiCall } from '@gringlobal-ce/client/model/common';
import AppSetting from '@gringlobal-ce/client/model/gringlobal/AppSetting';
import { IPageRequest, Page } from "@gringlobal-ce/client/model/page";
export const appSetting = [
......@@ -48,13 +49,23 @@ function * listAppSettingSaga(action) {
type: 'API',
target: RECEIVE_APP_SETTING_LIST,
method: ApplicationService.appSettingsList,
params: [],
params: [ action.payload.pageR ],
});
}
export const getAppSettingList = () => ({
export const listAppSettings = (pageR: IPageRequest = { page: 0, size: 100 }) => ({
type: SAGA_LIST_APP_SETTINGS,
payload: {
pageR,
},
});
export const loadMoreAppSettings = (settings: Page<AppSetting>) => ({
type: SAGA_LIST_APP_SETTINGS,
payload: { },
payload: {
pageR: Page.nextPage(settings),
},
});
function* receiveAppSettingSaga(action) {
......
......@@ -5,7 +5,7 @@ import { ApiCall } from '@gringlobal-ce/client/model/common';
import AppSetting from '@gringlobal-ce/client/model/gringlobal/AppSetting';
import { RECEIVE_APP_SETTING_ITEM, RECEIVE_APP_SETTING_LIST, REMOVE_APP_SETTING } from '@gringlobal-ce/ui-express/src/_core/constants/appSetting';
import { Page } from '@gringlobal-ce/client/model/page';
import { FilteredPage, Page } from '@gringlobal-ce/client/model/page';
const INITIAL_STATE: {
appSettingCall: ApiCall<AppSetting>,
......@@ -19,9 +19,16 @@ export default (state = INITIAL_STATE, action: { type?: string, payload?: any }
switch (action.type) {
case RECEIVE_APP_SETTING_LIST: {
const { apiCall } = action.payload;
const { apiCall: { loading, error, timestamp, data } } = action.payload;
return update(state, {
appSettingListCall: { $set: apiCall },
appSettingListCall: {
$set: {
loading,
error,
timestamp,
data: FilteredPage.merge(state.appSettingListCall && state.appSettingListCall.data, data),
},
},
});
}
case RECEIVE_APP_SETTING_ITEM: {
......
......@@ -4,7 +4,12 @@ import { compose } from 'redux';
import { WithTranslation, withTranslation } from 'react-i18next';
// Action
import { getAppSettingList, receiveAppSettingSuccessAction, removeAppSettingsAction } from '_core/action/appSetting';
import {
loadMoreAppSettings,
listAppSettings,
receiveAppSettingSuccessAction,
removeAppSettingsAction
} from '_core/action/appSetting';
// Model
import AppSetting from '@gringlobal-ce/client/model/gringlobal/AppSetting'
// Ui
......@@ -20,6 +25,7 @@ import { showSnackbar } from '@gringlobal-ce/client/action/snackbar';
import CancelOutlinedIcon from '@material-ui/icons/CancelOutlined';
import EditIcon from '@material-ui/icons/Edit';
import FABMenu from '@gringlobal-ce/client/ui/common/button/FABMenu';
import withBrowsePageBase, { WithBrowsePage } from "ui/common/withBrowsePageBase";
export const AppSettingsTableConfig = new TableConfiguration({
defaultColumns: [
......@@ -38,7 +44,7 @@ export const AppSettingsTableConfig = new TableConfiguration({
},
});
class BrowsePage extends React.Component<PropsFromRedux & WithTranslation, any> {
class BrowsePage extends React.Component<PropsFromRedux & WithTranslation & WithBrowsePage, any> {
public constructor(props) {
super(props);
}
......@@ -50,13 +56,9 @@ class BrowsePage extends React.Component<PropsFromRedux & WithTranslation, any>
error: null,
};
public componentDidMount() {
this.props.getAppSettingList();
}
private rowsToggled = (selectedRows: number[]) => {
const { appSettingListCall } = this.props;
const selectedIds = selectedRows.map((rowIndex) => appSettingListCall.data.content[rowIndex].id)
const { data } = this.props;
const selectedIds = selectedRows.map((rowIndex) => data.content[rowIndex].id)
this.setState({ selected: selectedIds });
}
......@@ -109,7 +111,7 @@ class BrowsePage extends React.Component<PropsFromRedux & WithTranslation, any>
};
public render() {
const { t, appSettingListCall } = this.props;
const { t, data, loadMore } = this.props;
const { appSettingDialogIsOpen, error, selected, createNew } = this.state;
const actions = [
......@@ -135,9 +137,10 @@ class BrowsePage extends React.Component<PropsFromRedux & WithTranslation, any>
type="AppSetting"
onRowsToggled={ this.rowsToggled }
columns={ AppSettingsTableConfig.defaultColumns }
data={ appSettingListCall?.data?.content }
data={ data?.content }
tableConfig={ AppSettingsTableConfig }
total={ appSettingListCall?.data?.totalElements }
total={ data?.totalElements }
loadMore={ loadMore }
/>
{ selected.length === 0 &&
<AddNewButton action={ this.openAppSettingDialog }/>
......@@ -153,7 +156,7 @@ class BrowsePage extends React.Component<PropsFromRedux & WithTranslation, any>
? t('appsetting.admin.p.browse.label.edit')
: t('appsetting.admin.p.browse.label.add')
}
initialValues={ ! createNew ? appSettingListCall?.data?.content?.find((setting) => +setting.id === +selected[0]) : {} }
initialValues={ ! createNew ? data?.content?.find((setting) => +setting.id === +selected[0]) : {} }
size="sm"
/>
{ selected.length > 0 &&
......@@ -170,11 +173,12 @@ class BrowsePage extends React.Component<PropsFromRedux & WithTranslation, any>
const mapStateToProps = (state) => ({
appSettingListCall: state.appSetting.appSettingListCall,
loadableData: state.appSetting.appSettingListCall,
});
const mapDispatch ={
getAppSettingList,
listAction: listAppSettings,
loadMoreData: loadMoreAppSettings,
receiveAppSettingSuccessAction,
removeAppSettingsAction,
showSnackbar,
......@@ -185,4 +189,4 @@ type PropsFromRedux = ReturnType<typeof mapStateToProps> & typeof mapDispatch;
export default compose(
connect(mapStateToProps, mapDispatch),
withTranslation(),
)(BrowsePage);
)(withBrowsePageBase(BrowsePage));
......@@ -9,6 +9,7 @@ import { printLabels } from "@gringlobal-ce/client/utilities";
import { showSnackbar } from "@gringlobal-ce/client/action/snackbar";
import { ApplicationService } from "@gringlobal-ce/client/service";
import { closeDialog } from "@gringlobal-ce/client/action/dialog";
import { loadAllPages } from "@gringlobal-ce/client/utilities";
interface IPrintLabelProps extends React.ClassAttributes<any>, WithTranslation, WithWidth {
labelsGenerator: (...args: any[]) => Generator | { [key: string]: any }[];
......@@ -40,8 +41,8 @@ class PrintLabelDialog extends React.Component<IPrintLabelProps, any> {
private checkMultiple = () => {
const { templateName, showSnackbar, t } = this.props;
ApplicationService.appSettingsList().then((settings) => {
const labelTemplates = settings.content.filter((setting) => setting.categoryTag === 'LABEL' && setting.name.startsWith(templateName))
loadAllPages(ApplicationService, ApplicationService.appSettingsList).then((settings) => {
const labelTemplates = settings.filter((setting) => setting.categoryTag === 'LABEL' && setting.name.startsWith(templateName))
if (labelTemplates.length > 0) {
this.setState({ templates: labelTemplates })
return;
......
......@@ -14,6 +14,7 @@ import { bindActionCreators } from "redux";
import { showSnackbar } from "@gringlobal-ce/client/action/snackbar";
import AppSetting from "@gringlobal-ce/client/model/gringlobal/AppSetting";
import { CodeValueDisplay } from './CodeValue';
import { loadAllPages } from "@gringlobal-ce/client/utilities";
const PrintLabelForm = ({ t, onSubmit, initialValues, templateName, templates, showSnackbar, error }:
{ showSnackbar: (msg) => void, onSubmit: (values) => void, templates?: AppSetting[], templateName?: string } & FormProps & WithTranslation) => {
......@@ -23,8 +24,8 @@ const PrintLabelForm = ({ t, onSubmit, initialValues, templateName, templates, s
React.useEffect(() => {
if (!settings && !templates && templateName) {
ApplicationService.appSettingsList().then((settings) => {
const labelTemplates = settings.content.filter((setting) => setting.categoryTag === 'LABEL' && setting.name.startsWith(templateName))
loadAllPages(ApplicationService, ApplicationService.appSettingsList).then((settings) => {
const labelTemplates = settings.filter((setting) => setting.categoryTag === 'LABEL' && setting.name.startsWith(templateName))
if (labelTemplates.length === 0) {
setInternalError(t('public.c.printLabel.noTemplateFound', { templateName }))
}
......
......@@ -30,6 +30,7 @@ import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import Number from '@gringlobal-ce/client/ui/common/Number';
import { CodeValueDisplay } from 'common/CodeValue';
import { WithBrowsePage } from 'ui/common/withBrowsePageBase';
import { loadAllPages } from "@gringlobal-ce/client/utilities";
export const CropTableDefaultConfig = {
defaultColumns: [
......@@ -158,8 +159,8 @@ const BrowsePage = ({ id, t, showSnackbar }: PropsFromRedux & WithSnackbar & Wit
React.useEffect(() => {
if (id) {
console.log(`Loading traits for crop=${id}`);
CropTraitService.list({ crop: [ +id ] }, { size: 500 }).then((page) => {
const sortedTraits = page.content.sort((a, b) => a?.title && b?.title ? a.title.localeCompare(b.title) : a?.codedName?.localeCompare(b?.codedName));
loadAllPages(CropTraitService, CropTraitService.list, { crop: [ +id ] }).then((traits) => {
const sortedTraits = traits.sort((a, b) => a?.title && b?.title ? a.title.localeCompare(b.title) : a?.codedName?.localeCompare(b?.codedName));
setCropTraits(sortedTraits);
}).catch((err) => {
console.log('Could not fetch trait list', err);
......@@ -267,6 +268,14 @@ const BrowsePage = ({ id, t, showSnackbar }: PropsFromRedux & WithSnackbar & Wit
setSelectedTraits(traits);
}
const loadMoreCrops = (): void => {
CropService.listCrops({}, Page.nextPage(crops)).then((newPage) => {
setCrops(Page.merge(crops, newPage));
}).catch((err) => {
console.log('Could not fetch crop list', err);
});
};
const toggleMethod = (ev) => {
const methodId: number = +ev.target.getAttribute('x-method-id') || +ev.target.parentElement.getAttribute('x-method-id');
if (! methodId) {
......@@ -306,6 +315,7 @@ const BrowsePage = ({ id, t, showSnackbar }: PropsFromRedux & WithSnackbar & Wit
data={ crops?.content }
tableConfig={ CropTableConfig }
total={ crops?.totalElements }
loadMore={ loadMoreCrops }
/>
</>
:
......
......@@ -203,16 +203,16 @@ class OrderRequestDetailsPage extends React.Component<PropsFromRedux & WithTrans
}
if ((id && +id !== requestCall?.data?.id) || currentTab === RequestTabs.ACTIONS && currentTab !== prevProps.currentTab) {
RequestService.listActionsByOrderRequest(id).then((data) => {
this.setState({ actionList: data.content })
loadAllPages(RequestService, RequestService.listActionsByOrderRequest, id).then((data) => {
this.setState({ actionList: data })
}).catch((e) => {
showSnackbar(e.data && e.data.error || e.toString());
});
}
if ((id && +id !== requestCall?.data?.id) || currentTab === RequestTabs.ITEM_ACTIONS && currentTab !== prevProps.currentTab) {
RequestService.listItemActionsByOrderRequest(id).then((data) => {
this.setState({ itemActionList: data.content })
loadAllPages(RequestService, RequestService.listItemActionsByOrderRequest, id).then((data) => {
this.setState({ itemActionList: data })
}).catch((e) => {
showSnackbar(e.data && e.data.error || e.toString());
});
......
......@@ -266,16 +266,25 @@ function* removeViabilityRulesSaga(action) {
// Viability Rule Map
export const listViabilitySpeciesAction = (id: number) => ({
export const listViabilitySpeciesAction = (id: number, pageR: IPageRequest = { page: 0, size: 100 }) => ({
type: SAGA_LIST_VIABILITY_SPECIES,
payload: { id },
payload: { id, pageR },
})
export const loadMoreViabilitySpecies = (id: number, species: Page<InventoryViabilityRuleMap>) => ({
type: SAGA_LIST_VIABILITY_SPECIES,
payload: {
id,
pageR: Page.nextPage(species),
},
});
function * listViabilitySpeciesSaga(action) {
yield put({
type: 'API',
target: RECEIVE_VIABILITY_SPECIES_LIST,
method: InventoryViabilityRuleService.listSpecies,
params: [ action.payload.id ],
params: [ action.payload.id, action.payload.pageR ],
});
}
......
......@@ -22,6 +22,7 @@ import ViabilityForm from 'viability/ui/c/ViabilityForm';
import { InventoryService, InventoryViabilityService } from '@gringlobal-ce/client/service';
import InventoryAction from '@gringlobal-ce/client/src/model/gringlobal/InventoryAction';
import Number from '@gringlobal-ce/client/ui/common/Number';
import { loadAllPages } from "@gringlobal-ce/client/utilities";
interface IBeginTestingPageState {
inventory: Inventory,
......@@ -47,8 +48,8 @@ class BeginTestingPage extends React.Component<PropsFromRedux & WithTranslation
private onBarcodeScan = (inventory) => {
const { navigateTo } = this.props;
InventoryViabilityService.list({ inventory: { id: [ inventory.id ] } })
.then(({ content: viabilityList }) => {
loadAllPages(InventoryViabilityService, InventoryViabilityService.list,{ inventory: { id: [ inventory.id ] } })
.then((viabilityList) => {
const foundNotViable = viabilityList.filter((viability) => viability.percentViable === null);
if (foundNotViable && foundNotViable.length === 1) {
navigateTo(`/viability/result/${foundNotViable[0].id}`)
......
......@@ -23,6 +23,7 @@ import { showSnackbar } from '@gringlobal-ce/client/action/snackbar';
import OrderDialog from 'viability/ui/c/OrderDialog';
import ListAltOutlinedIcon from '@material-ui/icons/ListAltOutlined';
import FABMenu from '@gringlobal-ce/client/ui/common/button/FABMenu';
import { Page } from "@gringlobal-ce/client/model/page";
export const InventoryViabilityOrderTableDefaultConfig = {
defaultColumns: [
......@@ -114,11 +115,24 @@ class OrderBrowsePage extends React.Component<PropsFromRedux & WithTranslation>
private loadData = () => {
InventoryViabilityService.listScheduledInventories(this.state.filter)
.then((scheduledActions) => {
const scheduledInventories = scheduledActions.content.map(action => { return { ...action.inventory, notBeforeDate: action.notBeforeDate, notBeforeDateCode: action.notBeforeDateCode } });
const scheduledInventories = scheduledActions.content.map((action) => { return { ...action.inventory, notBeforeDate: action.notBeforeDate, notBeforeDateCode: action.notBeforeDateCode } });
this.setState({ scheduledActions, scheduledInventories })
})
}).catch((e) => {
this.setState({ error: e.data && e.data.error || e.toString() });
});
}
private loadMore = (): void => {
const { scheduledActions, filter } = this.state;
InventoryViabilityService.listScheduledInventories(filter, Page.nextPage(scheduledActions)).then((newPage) => {
const merged = Page.merge(scheduledActions, newPage)
const scheduledInventories = merged.content.map((action) => { return { ...action.inventory, notBeforeDate: action.notBeforeDate, notBeforeDateCode: action.notBeforeDateCode } });
this.setState({ scheduledActions: merged, scheduledInventories });
}).catch((e) => {
this.setState({ error: e.data && e.data.error || e.toString() });
});
};
private handleSubmit = (data) => {
const { showSnackbar, t } = this.props
this.resetError();
......@@ -185,6 +199,7 @@ class OrderBrowsePage extends React.Component<PropsFromRedux & WithTranslation>
total={ scheduledActions.content && scheduledActions.totalElements }
onRowsToggled={ this.rowsToggled }
sort={ scheduledActions.sort }
loadMore={ this.loadMore }
/>
{ selected.length > 0 &&
<FABMenu
......
......@@ -3,7 +3,15 @@ import { connect } from 'react-redux';
import { compose } from 'redux';
import { WithTranslation, withTranslation } from 'react-i18next';
// Action
import { getViabilityRuleAction, listViabilitySpeciesAction, receiveViabilityRuleMapSuccessAction, receiveViabilityRuleSuccessAction, removeViabilityRuleAction, removeViabilityRuleMapsAction } from 'viability/action/public';
import {
getViabilityRuleAction,
listViabilitySpeciesAction,
loadMoreViabilitySpecies,
receiveViabilityRuleMapSuccessAction,
receiveViabilityRuleSuccessAction,
removeViabilityRuleAction,
removeViabilityRuleMapsAction
} from 'viability/action/public';
import { showSnackbar } from '@gringlobal-ce/client/action/snackbar';
import Loading from '@gringlobal-ce/client/ui/common/Loading';
......@@ -28,6 +36,7 @@ import { CodeValueDisplay } from 'common/CodeValue';
import CancelOutlinedIcon from '@material-ui/icons/CancelOutlined';
import FABMenu from '@gringlobal-ce/client/ui/common/button/FABMenu';
import TaxonomySpeciesSelector from 'taxonomy/ui/c/TaxonomySpeciesSelector';
import { Page } from "@gringlobal-ce/client/model/page";
const TaxonomySpeciesTableConfig = new TableConfiguration(TaxonomySpeciesTableDefaultConfig);
......@@ -133,6 +142,11 @@ class RuleDetailsPage extends React.Component<PropsFromRedux & WithTranslation &
});
};
private loadMoreViabilitySpecies = (): void => {
const { viabilityRuleMapListCall, id, loadMoreViabilitySpecies } = this.props;
loadMoreViabilitySpecies(id, Page.nextPage(viabilityRuleMapListCall.data));
};
private resetError = () => {
return this.setState({ error: null });
}
......@@ -260,7 +274,8 @@ class RuleDetailsPage extends React.Component<PropsFromRedux & WithTranslation &
onRowsToggled={ this.rowsToggled }
data={ this.species }
tableConfig={ TaxonomySpeciesTableConfig }
total={ this.species?.length }
total={ viabilityRuleMapListCall.data.totalElements }
loadMore={ this.loadMoreViabilitySpecies }
/>
</>
}
......@@ -293,6 +308,7 @@ const mapDispatch = {
removeViabilityRuleAction,
removeViabilityRuleMapsAction,
listViabilitySpeciesAction,
loadMoreViabilitySpecies,
receiveViabilityRuleMapSuccessAction,
receiveViabilityRuleSuccessAction,
showSnackbar,
......
Supports Markdown
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