/** * ============LICENSE_START======================================================================== * ONAP : ccsdk feature sdnr wt odlux * ================================================================================================= * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. * ================================================================================================= * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. * ============LICENSE_END========================================================================== */ import { Action, IActionHandler } from '../../flux/action'; import { Dispatch } from '../../flux/store'; import { AddErrorInfoAction } from '../../actions/errorActions'; import { IApplicationStoreState } from '../../store/applicationStore'; import { DataCallback } from "."; export interface IExternalTableState { order: 'asc' | 'desc'; orderBy: string | null; selected: any[] | null; rows: TData[]; total: number; page: number; rowsPerPage: number; loading: boolean; showFilter: boolean; filter: { [property: string]: string }; preFilter: { [property: string]: string }; } /** Create an actionHandler and actions for external table states. */ export function createExternal(callback: DataCallback, selectState: (appState: IApplicationStoreState) => IExternalTableState) { //#region Actions abstract class TableAction extends Action { } class RequestSortAction extends TableAction { constructor(public orderBy: string) { super(); } } class SetSelectedAction extends TableAction { constructor(public selected: TData[] | null) { super(); } } class SetPageAction extends TableAction { constructor(public page: number) { super(); } } class SetRowsPerPageAction extends TableAction { constructor(public rowsPerPage: number) { super(); } } class SetPreFilterChangedAction extends TableAction { constructor(public preFilter: { [key: string]: string }) { super(); } } class SetFilterChangedAction extends TableAction { constructor(public filter: { [key: string]: string }) { super(); } } class SetShowFilterAction extends TableAction { constructor(public show: boolean) { super(); } } class RefreshAction extends TableAction { constructor() { super(); } } class SetResultAction extends TableAction { constructor(public result: { page: number, total: number, rows: TData[] }) { super(); } } // #endregion //#region Action Handler const externalTableStateInit: IExternalTableState = { order: 'asc', orderBy: null, selected: null, rows: [], total: 0, page: 0, rowsPerPage: 10, loading: false, showFilter: false, filter: {}, preFilter: {} }; const externalTableStateActionHandler: IActionHandler> = (state = externalTableStateInit, action) => { if (!(action instanceof TableAction)) return state; if (action instanceof RefreshAction) { state = { ...state, loading: true } } else if (action instanceof SetResultAction) { state = { ...state, loading: false, rows: action.result.rows, total: action.result.total, page: action.result.page, } } else if (action instanceof RequestSortAction) { state = { ...state, loading: true, orderBy: state.orderBy === action.orderBy && state.order === 'desc' ? null : action.orderBy, order: state.orderBy === action.orderBy && state.order === 'asc' ? 'desc' : 'asc', } } else if (action instanceof SetShowFilterAction) { state = { ...state, loading: true, showFilter: action.show } } else if (action instanceof SetPreFilterChangedAction) { state = { ...state, loading: true, preFilter: action.preFilter } } else if (action instanceof SetFilterChangedAction) { state = { ...state, loading: true, filter: action.filter } } else if (action instanceof SetPageAction) { state = { ...state, loading: true, page: action.page } } else if (action instanceof SetRowsPerPageAction) { state = { ...state, loading: true, rowsPerPage: action.rowsPerPage } } return state; } //const createTableAction(tableAction) //#endregion const reloadAction = (dispatch: Dispatch, getAppState: () => IApplicationStoreState) => { dispatch(new RefreshAction()); const ownState = selectState(getAppState()); const filter = { ...ownState.preFilter, ...(ownState.showFilter && ownState.filter || {}) }; Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result => { if (ownState.page > 0 && ownState.rowsPerPage * ownState.page > result.total) { //if result is smaller than the currently shown page, new search and repaginate let newPage = Math.floor(result.total / ownState.rowsPerPage); Promise.resolve(callback(newPage, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result1 => { dispatch(new SetResultAction(result1)); }); } else { dispatch(new SetResultAction(result)); } }).catch(error => new AddErrorInfoAction(error)); }; const reloadActionAsync = async (dispatch: Dispatch, getAppState: () => IApplicationStoreState) => { dispatch(new RefreshAction()); const ownState = selectState(getAppState()); const filter = { ...ownState.preFilter, ...(ownState.showFilter && ownState.filter || {}) }; try { const result = await Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)); if (ownState.page > 0 && ownState.rowsPerPage * ownState.page > result.total) { //if result is smaller than the currently shown page, new search and repaginate let newPage = Math.floor(result.total / ownState.rowsPerPage); const repaginationResult = await Promise.resolve(callback(newPage, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)); dispatch(new SetResultAction(repaginationResult)); } else { dispatch(new SetResultAction(result)); } } catch (error) { new AddErrorInfoAction(error); } }; const createPreActions = (dispatch: Dispatch, skipRefresh: boolean = false) => { return { onPreFilterChanged: (preFilter: { [key: string]: string }) => { dispatch(new SetPreFilterChangedAction(preFilter)); (!skipRefresh) && dispatch(reloadAction); } }; } const createActions = (dispatch: Dispatch, skipRefresh: boolean = false) => { return { onRefresh: () => { dispatch(reloadAction); }, onHandleRequestSort: (orderBy: string) => { dispatch((dispatch: Dispatch) => { dispatch(new RequestSortAction(orderBy)); (!skipRefresh) && dispatch(reloadAction); }); }, onToggleFilter: () => { dispatch((dispatch: Dispatch, getAppState: () => IApplicationStoreState) => { const { showFilter } = selectState(getAppState()); dispatch(new SetShowFilterAction(!showFilter)); (!skipRefresh) && dispatch(reloadAction); }); }, onFilterChanged: (property: string, filterTerm: string) => { dispatch((dispatch: Dispatch, getAppState: () => IApplicationStoreState) => { let { filter } = selectState(getAppState()); filter = { ...filter, [property]: filterTerm }; dispatch(new SetFilterChangedAction(filter)); (!skipRefresh) && dispatch(reloadAction); }); }, onHandleChangePage: (page: number) => { dispatch((dispatch: Dispatch) => { dispatch(new SetPageAction(page)); (!skipRefresh) && dispatch(reloadAction); }); }, onHandleChangeRowsPerPage: (rowsPerPage: number | null) => { dispatch((dispatch: Dispatch) => { dispatch(new SetRowsPerPageAction(rowsPerPage || 10)); (!skipRefresh) && dispatch(reloadAction); }); } // selected: }; }; const createProperties = (state: IApplicationStoreState) => { return { ...selectState(state) } } return { reloadAction: reloadAction, createActions: createActions, createProperties: createProperties, createPreActions: createPreActions, actionHandler: externalTableStateActionHandler, reloadActionAsync: reloadActionAsync, } }