
1. Fix user columns 2. Update isInxxx name to inxxx 3. Fix inDetailPage intro in md Change-Id: I377215e853de0ddbadd255a9b82459ca4343b037
1146 lines
26 KiB
JavaScript
1146 lines
26 KiB
JavaScript
// Copyright 2021 99cloud
|
||
//
|
||
// 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.
|
||
|
||
import React from 'react';
|
||
import { parse } from 'qs';
|
||
import classnames from 'classnames';
|
||
import { toJS } from 'mobx';
|
||
import {
|
||
isEmpty,
|
||
isFunction,
|
||
get,
|
||
isString,
|
||
isEqual,
|
||
isArray,
|
||
has,
|
||
debounce,
|
||
} from 'lodash';
|
||
import { Menu, Icon, Dropdown, Button, Alert } from 'antd';
|
||
import BaseTable from 'components/Tables/Base';
|
||
import { isAdminPage } from 'utils/index';
|
||
import Notify from 'components/Notify';
|
||
import { checkTimeIn } from 'utils/time';
|
||
import checkItemPolicy from 'resources/policy';
|
||
import NotFound from 'components/Cards/NotFound';
|
||
import styles from './index.less';
|
||
|
||
const tabOtherHeight = 326;
|
||
const otherHeight = 272;
|
||
const hintHeight = 50;
|
||
const subTabHeight = 50;
|
||
|
||
export default class BaseList extends React.Component {
|
||
constructor(props, options = {}) {
|
||
super(props);
|
||
|
||
this.options = options;
|
||
|
||
this.state = {
|
||
filters: {},
|
||
timeFilter: {},
|
||
autoRefresh: true,
|
||
newHints: false,
|
||
tableHeight: this.getTableHeight(),
|
||
};
|
||
|
||
this.dataTimerTransition = null;
|
||
this.dataTimerAuto = null;
|
||
this.dataDurationTransition = 10; // fresh data interval when item in transition
|
||
this.dataDurationAuto = 30; // fresh data interval auto
|
||
this.autoRefreshTotalTime = 60 * 10; // seconds
|
||
this.autoRefreshCount = 0; // operation will reset the count, such as: action, select, pagination
|
||
this.autoRefreshCountMax = Math.floor(
|
||
this.autoRefreshTotalTime / this.dataDurationAuto
|
||
);
|
||
this.infoMessage = '';
|
||
this.successMessage = '';
|
||
this.errorMessage = '';
|
||
this.warnMessage = '';
|
||
this.inAction = false;
|
||
this.inSelect = false;
|
||
this.setTableHeight = this.setTableHeight.bind(this);
|
||
this.debounceSetTableHeight = this.debounceSetTableHeight.call(this);
|
||
this.init();
|
||
}
|
||
|
||
componentDidMount() {
|
||
this.unsubscribe = this.routing.history.subscribe((location) => {
|
||
if (
|
||
location.pathname === this.props.match.url &&
|
||
location.key === this.props.location.key
|
||
) {
|
||
const params = parse(location.search.slice(1));
|
||
// this.getDataWithPolicy(params);
|
||
const { limit, page } = this.store.list;
|
||
this.list.filters = {};
|
||
this.handleFetch({ ...params, limit, page }, true);
|
||
}
|
||
});
|
||
window.addEventListener('resize', this.debounceSetTableHeight);
|
||
}
|
||
|
||
componentDidUpdate(prevProps) {
|
||
if (this.inDetailPage) {
|
||
const { detail: oldDetail } = prevProps;
|
||
const { detail: newDetail } = this.props;
|
||
if (
|
||
!isEmpty(oldDetail) &&
|
||
!isEmpty(newDetail) &&
|
||
!isEqual(oldDetail, newDetail)
|
||
) {
|
||
this.handleRefresh(true);
|
||
}
|
||
}
|
||
}
|
||
|
||
componentWillUnmount() {
|
||
this.unsubscribe && this.unsubscribe();
|
||
this.disposer && this.disposer();
|
||
this.unMountActions && this.unMountActions();
|
||
this.stopRefreshTransition();
|
||
this.stopRefreshAuto();
|
||
if (this.clearListUnmount) {
|
||
this.store.clearData && this.store.clearData('listUnmount');
|
||
}
|
||
window.removeEventListener('resize', this.debounceSetTableHeight);
|
||
}
|
||
|
||
get policy() {
|
||
return '';
|
||
}
|
||
|
||
get name() {
|
||
return '';
|
||
}
|
||
|
||
get title() {
|
||
return `${this.name}s`;
|
||
}
|
||
|
||
get className() {
|
||
return '';
|
||
}
|
||
|
||
get inDetailPage() {
|
||
const { detail } = this.props;
|
||
return !!detail;
|
||
}
|
||
|
||
get shouldRefreshDetail() {
|
||
return true;
|
||
}
|
||
|
||
get location() {
|
||
return this.props.location;
|
||
}
|
||
|
||
get isAdminPage() {
|
||
const { pathname } = this.location;
|
||
return isAdminPage(pathname);
|
||
}
|
||
|
||
get hasAdminRole() {
|
||
return this.props.rootStore.hasAdminRole;
|
||
}
|
||
|
||
getUrl(path, adminStr) {
|
||
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
||
}
|
||
|
||
get prefix() {
|
||
return this.props.match.url;
|
||
}
|
||
|
||
get params() {
|
||
return this.props.match.params || {};
|
||
}
|
||
|
||
get routing() {
|
||
return this.props.rootStore.routing;
|
||
}
|
||
|
||
get list() {
|
||
return this.store.list;
|
||
}
|
||
|
||
get isLoading() {
|
||
return this.list.isLoading || this.store.isSubmitting;
|
||
}
|
||
|
||
get tips() {
|
||
return [];
|
||
}
|
||
|
||
get rowKey() {
|
||
return 'id';
|
||
}
|
||
|
||
get hasTab() {
|
||
return false;
|
||
}
|
||
|
||
get hasSubTab() {
|
||
return false;
|
||
}
|
||
|
||
get hideCustom() {
|
||
return false;
|
||
}
|
||
|
||
get hideSearch() {
|
||
return false;
|
||
}
|
||
|
||
get hideRefresh() {
|
||
return false;
|
||
}
|
||
|
||
get hideDownload() {
|
||
return false;
|
||
}
|
||
|
||
get checkEndpoint() {
|
||
return false;
|
||
}
|
||
|
||
get endpoint() {
|
||
return '';
|
||
}
|
||
|
||
get endpointError() {
|
||
return this.checkEndpoint && !this.endpoint;
|
||
}
|
||
|
||
get hintHeight() {
|
||
let height = 0;
|
||
if (this.infoMessage) {
|
||
height += hintHeight;
|
||
}
|
||
if (this.warnMessage) {
|
||
height += hintHeight;
|
||
}
|
||
if (this.errorMessage) {
|
||
height += hintHeight;
|
||
}
|
||
if (this.successMessage) {
|
||
height += hintHeight;
|
||
}
|
||
return height;
|
||
}
|
||
|
||
get tableTopHeight() {
|
||
if (this.hasSubTab) {
|
||
return tabOtherHeight + subTabHeight;
|
||
}
|
||
if (this.hasTab) {
|
||
return tabOtherHeight;
|
||
}
|
||
return otherHeight;
|
||
}
|
||
|
||
getTableHeight() {
|
||
const height = window.innerHeight;
|
||
const id = this.params && this.params.id;
|
||
if (id) {
|
||
return -1;
|
||
}
|
||
return height - this.tableTopHeight - this.hintHeight;
|
||
}
|
||
|
||
get tableWidth() {
|
||
return 800;
|
||
}
|
||
|
||
get isFilterByBackend() {
|
||
return false;
|
||
}
|
||
|
||
get isSortByBackend() {
|
||
return false;
|
||
}
|
||
|
||
get isCourier() {
|
||
// 如果是courier的并且是后端分页的,那么需要带数字的分页脚标,因为Courier自带分页且能跳页,而openstack的不支持跳页。
|
||
return false;
|
||
}
|
||
|
||
get enabledItemActions() {
|
||
return this.itemActions.filter((item) => !item.action);
|
||
}
|
||
|
||
get adminPageHasProjectFilter() {
|
||
return false;
|
||
}
|
||
|
||
get transitionStatusList() {
|
||
return [];
|
||
}
|
||
|
||
get fetchDataByAllProjects() {
|
||
return true;
|
||
}
|
||
|
||
get currentUser() {
|
||
const { user } = this.props.rootStore || {};
|
||
return user || {};
|
||
}
|
||
|
||
get currentProjectId() {
|
||
return this.props.rootStore.projectId;
|
||
}
|
||
|
||
get fetchDataByCurrentProject() {
|
||
// add project_id to fetch data;
|
||
return false;
|
||
}
|
||
|
||
get defaultSortKey() {
|
||
return '';
|
||
}
|
||
|
||
get defaultSortOrder() {
|
||
return 'descend';
|
||
}
|
||
|
||
get clearListUnmount() {
|
||
return false;
|
||
}
|
||
|
||
get itemInTransitionFunction() {
|
||
return (item) => {
|
||
const { status } = item;
|
||
return this.transitionStatusList.indexOf(status) >= 0;
|
||
};
|
||
}
|
||
|
||
get ableAutoFresh() {
|
||
return true;
|
||
}
|
||
|
||
get actionConfigs() {
|
||
return {
|
||
batchActions: [],
|
||
primaryActions: [],
|
||
rowActions: [],
|
||
};
|
||
}
|
||
|
||
get primaryActions() {
|
||
return this.actionConfigs.primaryActions;
|
||
}
|
||
|
||
get batchActions() {
|
||
return this.actionConfigs.batchActions;
|
||
}
|
||
|
||
get itemActions() {
|
||
return this.actionConfigs.rowActions;
|
||
}
|
||
|
||
get searchFilters() {
|
||
return [];
|
||
}
|
||
|
||
get expandable() {
|
||
return undefined;
|
||
}
|
||
|
||
get filterTimeKey() {
|
||
return undefined;
|
||
}
|
||
|
||
get projectFilterKey() {
|
||
return 'project_id';
|
||
}
|
||
|
||
get pageSizeOptions() {
|
||
return undefined;
|
||
}
|
||
|
||
get hideTotal() {
|
||
return false;
|
||
}
|
||
|
||
get primaryActionsExtra() {
|
||
return null;
|
||
}
|
||
|
||
get allProjectsKey() {
|
||
return 'all_projects';
|
||
}
|
||
|
||
setRefreshdataTimerTransition = () => {
|
||
this.stopRefreshAuto();
|
||
if (this.dataTimerTransition) {
|
||
return;
|
||
}
|
||
this.dataTimerTransition = setTimeout(() => {
|
||
this.handleRefresh();
|
||
this.dataTimerTransition = null;
|
||
}, this.dataDurationTransition * 1000);
|
||
};
|
||
|
||
setRefreshdataTimerAuto = () => {
|
||
this.stopRefreshTransition();
|
||
if (!this.ableAutoFresh) {
|
||
return;
|
||
}
|
||
const { autoRefresh } = this.state;
|
||
if (!autoRefresh || this.dataTimerAuto) {
|
||
return;
|
||
}
|
||
this.dataTimerAuto = setTimeout(() => {
|
||
this.autoRefreshCount += 1;
|
||
this.handleRefresh();
|
||
this.dataTimerAuto = null;
|
||
}, this.dataDurationAuto * 1000);
|
||
};
|
||
|
||
getEmptyProps() {
|
||
return {};
|
||
}
|
||
|
||
getEnabledTableProps() {
|
||
const props = this.getTableProps();
|
||
|
||
if (isEmpty(this.batchActions)) {
|
||
props.onSelectRowKeys = null;
|
||
}
|
||
|
||
return props;
|
||
}
|
||
|
||
getCheckboxProps(record) {
|
||
return {
|
||
disabled: false,
|
||
name: record.name,
|
||
};
|
||
}
|
||
|
||
onStopRefreshAuto = () => {
|
||
this.setState({
|
||
autoRefresh: false,
|
||
});
|
||
this.stopRefreshAuto();
|
||
};
|
||
|
||
onClickAction = () => {
|
||
this.inAction = true;
|
||
this.autoRefreshCount = 0;
|
||
};
|
||
|
||
onFinishAction = () => {
|
||
this.inAction = false;
|
||
this.handleSelectRowKeys([]);
|
||
this.handleRefresh(true);
|
||
};
|
||
|
||
onCancelAction = () => {
|
||
this.inAction = false;
|
||
this.getDataSource();
|
||
};
|
||
|
||
handleInputFocus = (value) => {
|
||
this.inAction = value;
|
||
if (!value) {
|
||
this.setRefreshdataTimerAuto();
|
||
}
|
||
};
|
||
|
||
getTableProps() {
|
||
return {
|
||
onRefresh: this.handleRefresh,
|
||
onFetch: this.handleFetch,
|
||
onFetchBySort: this.handleFetchBySort,
|
||
onSelectRowKeys: this.handleSelectRowKeys,
|
||
onFilterChange: this.handleFilterChange,
|
||
hideCustom: this.hideCustom,
|
||
hideSearch: this.hideSearch,
|
||
hideRefresh: this.hideRefresh,
|
||
hideAutoRefresh: !this.ableAutoFresh,
|
||
};
|
||
}
|
||
|
||
getData({ silent, ...params } = {}) {
|
||
silent && (this.list.silent = true);
|
||
const newParams = {
|
||
...this.props.match.params,
|
||
...params,
|
||
sortKey:
|
||
params.sortKey || (this.isSortByBackend && this.defaultSortKey) || '',
|
||
sortOrder:
|
||
params.sortOrder ||
|
||
(this.isSortByBackend && this.defaultSortOrder) ||
|
||
'',
|
||
};
|
||
if (!this.isAdminPage && this.fetchDataByCurrentProject) {
|
||
newParams.project_id = this.currentProjectId;
|
||
} else if (
|
||
this.isAdminPage &&
|
||
this.fetchDataByAllProjects &&
|
||
this.allProjectsKey
|
||
) {
|
||
newParams[this.allProjectsKey] = true;
|
||
}
|
||
if (this.isFilterByBackend) {
|
||
this.fetchListWithTry(() =>
|
||
this.fetchDataByPage(this.updateFetchParamsByPage(newParams))
|
||
);
|
||
} else {
|
||
this.fetchListWithTry(() =>
|
||
this.fetchData(this.updateFetchParams(newParams))
|
||
);
|
||
}
|
||
}
|
||
|
||
getDataWithPolicy(params) {
|
||
if (!this.currentUser || isEmpty(this.currentUser)) {
|
||
return;
|
||
}
|
||
if (this.endpointError) {
|
||
return;
|
||
}
|
||
if (!checkItemPolicy({ policy: this.policy, actionName: this.name })) {
|
||
const error = {
|
||
message: t("You don't have access to get {name}.", {
|
||
name: this.name.toLowerCase(),
|
||
}),
|
||
status: 401,
|
||
};
|
||
Notify.errorWithDetail(
|
||
error,
|
||
t('Unable to get {name}.', { name: this.name.toLowerCase() })
|
||
);
|
||
this.list.isLoading = false;
|
||
this.list.silent = false;
|
||
return;
|
||
}
|
||
this.getData(params);
|
||
}
|
||
|
||
setTableHeight() {
|
||
const currentTableHeight = this.getTableHeight();
|
||
const { tableHeight } = this.state;
|
||
if (currentTableHeight !== tableHeight) {
|
||
this.setState({
|
||
tableHeight: currentTableHeight,
|
||
});
|
||
}
|
||
}
|
||
|
||
fetchListWithTry = async (func) => {
|
||
try {
|
||
func && (await func());
|
||
} catch (e) {
|
||
// eslint-disable-next-line no-console
|
||
console.log('fetch list error', e);
|
||
const { message = '', data, status } = (e || {}).response || e || {};
|
||
if (status === 500) {
|
||
const sysErr = t('System is error, please try again later.');
|
||
const title = `${t('Get {name} error.', {
|
||
name: this.name.toLowerCase(),
|
||
})} ${sysErr}`;
|
||
Notify.errorWithDetail(null, title);
|
||
} else {
|
||
const error = {
|
||
message: data || message || e || '',
|
||
status,
|
||
};
|
||
Notify.errorWithDetail(
|
||
error,
|
||
t('Get {name} error.', { name: this.name.toLowerCase() })
|
||
);
|
||
}
|
||
this.list.isLoading = false;
|
||
this.list.silent = false;
|
||
}
|
||
};
|
||
|
||
updateFetchParamsByPage = (params) => params;
|
||
|
||
updateFetchParams = (params) => params;
|
||
|
||
fetchDataByPage = async (params) => {
|
||
await this.store.fetchListByPage(params);
|
||
this.list.silent = false;
|
||
};
|
||
|
||
fetchData = async (newParams) => {
|
||
await this.store.fetchList(newParams);
|
||
this.list.silent = false;
|
||
};
|
||
|
||
fetchDownloadData = async (params) => {
|
||
let result = [];
|
||
if (this.isFilterByBackend) {
|
||
result = await this.downloadStore.fetchListByPage(
|
||
this.updateFetchParamsByPage(params)
|
||
);
|
||
} else {
|
||
result = await this.downloadStore.fetchList(
|
||
this.updateFetchParams(params)
|
||
);
|
||
}
|
||
return result;
|
||
};
|
||
|
||
getDownloadData = async ({ ...params } = {}) => {
|
||
// only used for donwload all and pagination by backend
|
||
const { filters } = this.state;
|
||
const newParams = {
|
||
...this.props.match.params,
|
||
...params,
|
||
...filters,
|
||
sortKey:
|
||
params.sortKey || (this.isSortByBackend && this.defaultSortKey) || '',
|
||
sortOrder:
|
||
params.sortOrder ||
|
||
(this.isSortByBackend && this.defaultSortOrder) ||
|
||
'',
|
||
};
|
||
if (!this.isAdminPage && this.fetchDataByCurrentProject) {
|
||
newParams.project_id = this.currentProjectId;
|
||
} else if (
|
||
this.isAdminPage &&
|
||
this.fetchDataByAllProjects &&
|
||
this.allProjectsKey
|
||
) {
|
||
newParams[this.allProjectsKey] = true;
|
||
}
|
||
const result = await this.fetchDownloadData(newParams);
|
||
return result;
|
||
};
|
||
|
||
startRefreshAuto = () => {
|
||
this.autoRefreshCount = 0;
|
||
this.setState({
|
||
autoRefresh: true,
|
||
});
|
||
this.handleRefresh();
|
||
};
|
||
|
||
stopRefreshAuto = () => {
|
||
clearTimeout(this.dataTimerAuto);
|
||
this.dataTimerAuto = null;
|
||
};
|
||
|
||
stopRefreshTransition = () => {
|
||
clearTimeout(this.dataTimerTransition);
|
||
this.dataTimerTransition = null;
|
||
};
|
||
|
||
getFilteredValue = (dataIndex) => this.list.filters[dataIndex];
|
||
|
||
getColumns = () => [];
|
||
|
||
checkIsProjectFilter = (item) => item.name === this.projectFilterKey;
|
||
|
||
getSearchFilters = () => {
|
||
const filters = this.searchFilters;
|
||
if (!this.isAdminPage) {
|
||
return filters;
|
||
}
|
||
if (!this.adminPageHasProjectFilter) {
|
||
return filters;
|
||
}
|
||
const projectItem = filters.find((it) => this.checkIsProjectFilter(it));
|
||
if (projectItem) {
|
||
return filters;
|
||
}
|
||
return [
|
||
...filters,
|
||
{
|
||
label: t('Project ID'),
|
||
name: this.projectFilterKey,
|
||
},
|
||
];
|
||
};
|
||
|
||
filterDataByTime = (data) => {
|
||
if (!this.filterTimeKey) {
|
||
return true;
|
||
}
|
||
const { timeFilter: { value = 0, start, end } = {} } = this.state;
|
||
if (value === 0) {
|
||
return true;
|
||
}
|
||
const dataTime = get(data, this.filterTimeKey, 0);
|
||
if (value !== 1) {
|
||
return checkTimeIn(dataTime, new Date().getTime() - value, null);
|
||
}
|
||
return checkTimeIn(dataTime, start, end);
|
||
};
|
||
|
||
checkFilterInclude = (key) => {
|
||
const item = this.searchFilters.find((it) => it.name === key);
|
||
if (has(item, 'include')) {
|
||
return item.include;
|
||
}
|
||
if (has(item, 'options')) {
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
filterData = (data) => {
|
||
if (!this.filterDataByTime(data)) {
|
||
return false;
|
||
}
|
||
const { filters: filtersInState } = this.state;
|
||
if (Object.keys(filtersInState).length === 1 && filtersInState.keywords) {
|
||
const { keywords } = filtersInState;
|
||
const item = Object.values(data).find(
|
||
(value) =>
|
||
(isString(value) || isArray(value)) && value.indexOf(keywords) >= 0
|
||
);
|
||
return !!item;
|
||
}
|
||
const failed = Object.keys(filtersInState).find((key) => {
|
||
const value = get(data, key);
|
||
const filterValue = filtersInState[key];
|
||
const { filterFunc } = this.getSearchFilters().find(
|
||
(i) => i.name === key
|
||
);
|
||
if (filterFunc) {
|
||
return !filterFunc(value, filterValue);
|
||
}
|
||
|
||
const isInclude = this.checkFilterInclude(key);
|
||
if (isString(value) && isString(filterValue)) {
|
||
if (isInclude) {
|
||
return value.toLowerCase().indexOf(filterValue.toLowerCase()) < 0;
|
||
}
|
||
return value.toLowerCase() !== filterValue.toLowerCase();
|
||
}
|
||
return !isEqual(value, filterValue);
|
||
});
|
||
return !failed;
|
||
};
|
||
|
||
getDataSource = () => {
|
||
const { data, filters = {} } = this.list;
|
||
const { timeFilter = {} } = this.state;
|
||
const { id, tab, ...rest } = filters;
|
||
const newFilters = rest;
|
||
let datas = [];
|
||
if (this.isFilterByBackend) {
|
||
datas = toJS(data);
|
||
} else {
|
||
datas = (toJS(data) || []).filter((it) =>
|
||
this.filterData(it, toJS(newFilters), toJS(timeFilter))
|
||
);
|
||
this.updateList({ total: datas.length });
|
||
}
|
||
const hasTransData = datas.some((item) =>
|
||
this.itemInTransitionFunction(item)
|
||
);
|
||
if (hasTransData) {
|
||
this.setRefreshdataTimerTransition();
|
||
} else {
|
||
this.setRefreshdataTimerAuto();
|
||
}
|
||
this.updateHintsByDatas(datas);
|
||
return datas;
|
||
};
|
||
|
||
getFilters = () => {
|
||
const { filters } = this.list;
|
||
const params = parse(this.location.search.slice(1));
|
||
return {
|
||
...params,
|
||
...toJS(filters),
|
||
};
|
||
};
|
||
|
||
handleMoreMenuClick = (item) => (e, key) => {
|
||
const action = this.enabledItemActions.find(
|
||
(_action) => _action.key === key
|
||
);
|
||
if (action && action.onClick) {
|
||
action.onClick(item);
|
||
}
|
||
};
|
||
|
||
refreshDetailData = () => {
|
||
const { refreshDetail } = this.props;
|
||
refreshDetail && refreshDetail();
|
||
};
|
||
|
||
handleRefresh = (force) => {
|
||
const { inAction, inSelect } = this;
|
||
if (inAction || (inSelect && !force)) {
|
||
return;
|
||
}
|
||
if (!force && this.autoRefreshCount >= this.autoRefreshCountMax) {
|
||
return;
|
||
}
|
||
if (force) {
|
||
this.autoRefreshCount = 0;
|
||
}
|
||
const { page, limit, sortKey, sortOrder, filters } = this.list;
|
||
const params = {
|
||
page,
|
||
limit,
|
||
sortKey,
|
||
sortOrder,
|
||
...toJS(filters),
|
||
silent: !force,
|
||
};
|
||
this.handleFetch(params, true);
|
||
if (this.inDetailPage && force && this.shouldRefreshDetail) {
|
||
this.refreshDetailData();
|
||
}
|
||
};
|
||
|
||
updateList = (newObj) => {
|
||
if (!this.list) {
|
||
return;
|
||
}
|
||
if (this.list.update) {
|
||
this.list.update(newObj);
|
||
} else {
|
||
Object.keys(newObj).forEach((key) => {
|
||
this.list[key] = newObj[key];
|
||
});
|
||
}
|
||
};
|
||
|
||
handleFetch = (params, refresh) => {
|
||
if (refresh && !this.isFilterByBackend) {
|
||
this.getDataWithPolicy(params);
|
||
return;
|
||
}
|
||
// eslint-disable-next-line no-unused-vars
|
||
const { sortKey, limit, page, current, sortOrder, ...rest } = params;
|
||
if (page !== this.list.page || limit !== this.list.limit) {
|
||
this.autoRefreshCount = 0;
|
||
}
|
||
// const newParams = reverse === undefined ? rest : params;
|
||
if (this.isFilterByBackend) {
|
||
this.getDataWithPolicy({ ...params, ...(this.list.filters || {}) });
|
||
// this.routing.query(newParams, refresh);
|
||
} else {
|
||
this.updateList({
|
||
page,
|
||
limit,
|
||
sortKey,
|
||
sortOrder,
|
||
});
|
||
}
|
||
};
|
||
|
||
handleFetchBySort = (params) => {
|
||
if (!this.isSortByBackend) {
|
||
const { sortKey, limit, page, sortOrder } = params;
|
||
this.updateList({
|
||
page,
|
||
limit,
|
||
sortKey,
|
||
sortOrder,
|
||
});
|
||
return;
|
||
}
|
||
const newParams = {
|
||
...params,
|
||
page: 1,
|
||
};
|
||
this.handleFetch(newParams, true);
|
||
};
|
||
|
||
handleFilterChange = (filters, timeFilter) => {
|
||
const { page, limit, sortKey, sortOrder, ...rest } = filters;
|
||
if (this.isFilterByBackend) {
|
||
this.list.filters = filters;
|
||
// this.list.timeFilter = timeFilter;
|
||
this.setState(
|
||
{
|
||
timeFilter,
|
||
},
|
||
() => {
|
||
this.handleFetch(filters, true);
|
||
}
|
||
);
|
||
// this.routing.query(filters, true);
|
||
} else {
|
||
this.updateList({
|
||
page,
|
||
sortKey,
|
||
sortOrder,
|
||
filters: rest,
|
||
// timeFilter,
|
||
});
|
||
this.setState({
|
||
filters: rest,
|
||
timeFilter,
|
||
});
|
||
}
|
||
};
|
||
|
||
handleSelectRowKeys = (params) => {
|
||
this.store.setSelectRowKeys('list', params);
|
||
if (!params || params.length === 0) {
|
||
this.inSelect = false;
|
||
this.getDataSource();
|
||
} else {
|
||
this.inSelect = true;
|
||
this.autoRefreshCount = 0;
|
||
}
|
||
};
|
||
|
||
onCloseSuccessHint = () => {};
|
||
|
||
debounceSetTableHeight() {
|
||
return debounce(this.setTableHeight, 1000);
|
||
}
|
||
|
||
// eslint-disable-next-line no-unused-vars
|
||
updateHintsByOthers() {
|
||
if (this.updateHints) {
|
||
this.updateHints();
|
||
this.setState({
|
||
newHints: true,
|
||
});
|
||
}
|
||
}
|
||
|
||
// eslint-disable-next-line no-unused-vars
|
||
updateHintsByDatas(datas) {}
|
||
|
||
init() {
|
||
this.store = { list: {} };
|
||
this.downloadStore = {};
|
||
}
|
||
|
||
renderMore = (field, record) => {
|
||
if (isEmpty(this.enabledItemActions)) {
|
||
return null;
|
||
}
|
||
|
||
const content = this.renderMoreMenu(record);
|
||
|
||
if (content === null) {
|
||
return null;
|
||
}
|
||
|
||
return (
|
||
<Dropdown content={content} trigger="click" placement="bottomRight">
|
||
<Button icon="more" type="flat" />
|
||
</Dropdown>
|
||
);
|
||
};
|
||
|
||
renderMoreMenu = (record) => {
|
||
const items = this.enabledItemActions.map((action) => {
|
||
const show = isFunction(action.show)
|
||
? action.show(record)
|
||
: action.show || true;
|
||
if (!show) return null;
|
||
|
||
return (
|
||
<Menu.MenuItem key={action.key}>
|
||
<Icon name={action.icon} /> <span>{action.text}</span>
|
||
</Menu.MenuItem>
|
||
);
|
||
});
|
||
|
||
if (items.every((item) => item === null)) {
|
||
return null;
|
||
}
|
||
|
||
return <Menu onClick={this.handleMoreMenuClick(record)}>{items}</Menu>;
|
||
};
|
||
|
||
renderTable() {
|
||
try {
|
||
const {
|
||
keyword,
|
||
selectedRowKeys,
|
||
total,
|
||
page,
|
||
limit,
|
||
silent,
|
||
sortKey,
|
||
sortOrder,
|
||
timerFilter,
|
||
} = this.list;
|
||
const pagination = {
|
||
total,
|
||
current: Number(page),
|
||
pageSize: limit || 10,
|
||
// eslint-disable-next-line no-shadow
|
||
showTotal: (total) => t('Total {total} items', { total }),
|
||
showSizeChanger: true,
|
||
};
|
||
if (this.pageSizeOptions) {
|
||
pagination.pageSizeOptions = this.pageSizeOptions;
|
||
}
|
||
const { autoRefresh, tableHeight } = this.state;
|
||
|
||
return (
|
||
<BaseTable
|
||
resourceName={this.name}
|
||
data={this.getDataSource()}
|
||
// data={data}
|
||
columns={this.getColumns()}
|
||
filters={this.getFilters()}
|
||
timerFilter={timerFilter}
|
||
searchFilters={this.getSearchFilters()}
|
||
keyword={keyword}
|
||
pagination={pagination}
|
||
primaryActions={this.primaryActions}
|
||
batchActions={this.batchActions}
|
||
itemActions={this.itemActions}
|
||
getCheckboxProps={this.getCheckboxProps}
|
||
isLoading={this.isLoading}
|
||
silentLoading={silent}
|
||
rowKey={this.rowKey}
|
||
selectedRowKeys={toJS(selectedRowKeys)}
|
||
scrollY={tableHeight}
|
||
sortKey={sortKey}
|
||
sortOrder={sortOrder}
|
||
defaultSortKey={this.defaultSortKey}
|
||
defaultSortOrder={this.defaultSortOrder}
|
||
getDownloadData={this.getDownloadData}
|
||
containerProps={this.props}
|
||
expandable={this.expandable}
|
||
showTimeFilter={!!this.filterTimeKey}
|
||
filterTimeDefalutValue={this.filterTimeDefalutValue}
|
||
isPageByBack={this.isFilterByBackend}
|
||
isSortByBack={this.isSortByBackend}
|
||
isCourier={this.isCourier}
|
||
autoRefresh={autoRefresh}
|
||
startRefreshAuto={this.startRefreshAuto}
|
||
stopRefreshAuto={this.onStopRefreshAuto}
|
||
onClickAction={this.onClickAction}
|
||
onFinishAction={this.onFinishAction}
|
||
onCancelAction={this.onCancelAction}
|
||
dataDurationAuto={this.dataDurationAuto}
|
||
handleInputFocus={this.handleInputFocus}
|
||
hideTotal={this.hideTotal}
|
||
hideDownload={this.hideDownload}
|
||
primaryActionsExtra={this.primaryActionsExtra}
|
||
isAdminPage={this.isAdminPage}
|
||
{...this.getEnabledTableProps()}
|
||
/>
|
||
);
|
||
} catch (e) {
|
||
// eslint-disable-next-line no-console
|
||
console.log(e);
|
||
const link = this.getUrl('/base/overview');
|
||
return <NotFound title={this.name} link={link} codeError />;
|
||
}
|
||
}
|
||
|
||
renderInfoHint() {
|
||
if (!this.infoMessage) {
|
||
return null;
|
||
}
|
||
return (
|
||
<Alert
|
||
message={this.infoMessage}
|
||
type="info"
|
||
showIcon
|
||
className={styles.hint}
|
||
/>
|
||
);
|
||
}
|
||
|
||
renderSuccessHint() {
|
||
if (!this.successMessage) {
|
||
return null;
|
||
}
|
||
return (
|
||
<Alert
|
||
message={this.successMessage}
|
||
type="success"
|
||
showIcon
|
||
closable
|
||
className={styles.hint}
|
||
onClose={this.onCloseSuccessHint}
|
||
/>
|
||
);
|
||
}
|
||
|
||
renderWarnHint() {
|
||
if (!this.warnMessage) {
|
||
return null;
|
||
}
|
||
return (
|
||
<Alert
|
||
message={this.warnMessage}
|
||
type="warning"
|
||
showIcon
|
||
className={styles.hint}
|
||
/>
|
||
);
|
||
}
|
||
|
||
renderErrorHint() {
|
||
if (!this.errorMessage) {
|
||
return null;
|
||
}
|
||
return (
|
||
<Alert
|
||
message={this.errorMessage}
|
||
type="error"
|
||
showIcon
|
||
closable
|
||
className={styles.hint}
|
||
/>
|
||
);
|
||
}
|
||
|
||
renderHint() {
|
||
const { newHints } = this.state;
|
||
if (
|
||
!newHints &&
|
||
!this.infoMessage &&
|
||
!this.warnMessage &&
|
||
!this.successMessage &&
|
||
!this.errorMessage
|
||
) {
|
||
return null;
|
||
}
|
||
return (
|
||
<div className={classnames(styles.hints, 'list-hints')}>
|
||
{this.renderInfoHint()}
|
||
{this.renderSuccessHint()}
|
||
{this.renderWarnHint()}
|
||
{this.renderErrorHint()}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
renderHeader() {
|
||
return null;
|
||
}
|
||
|
||
render() {
|
||
if (this.endpointError) {
|
||
const link = this.getUrl('/base/overview');
|
||
return <NotFound title={this.name} link={link} endpointError />;
|
||
}
|
||
const table = this.renderTable();
|
||
return (
|
||
<div
|
||
className={classnames(styles.wrapper, 'list-container', this.className)}
|
||
>
|
||
{this.renderHeader()}
|
||
{this.renderHint()}
|
||
{table}
|
||
</div>
|
||
);
|
||
}
|
||
}
|