Commit b645f18f authored by zhangwenshuai's avatar zhangwenshuai

update apolloTable locale

parent 728c2b95
...@@ -191,7 +191,6 @@ const Cell = (props: CellProps) => { ...@@ -191,7 +191,6 @@ const Cell = (props: CellProps) => {
)} )}
</div> </div>
); );
console.log('contentMenu', contentMenu);
return contentMenu ? ( return contentMenu ? (
<Popover <Popover
......
...@@ -5,6 +5,15 @@ ...@@ -5,6 +5,15 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
border: 1px solid @borderColor; border: 1px solid @borderColor;
&.scroll {
height: 100%;
.loading{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
}
.leftSideContainer { .leftSideContainer {
box-shadow: 6px 0 6px -4px rgba(0, 0, 0, 0.15); box-shadow: 6px 0 6px -4px rgba(0, 0, 0, 0.15);
position: absolute; position: absolute;
...@@ -88,3 +97,6 @@ ...@@ -88,3 +97,6 @@
right: 0; right: 0;
pointer-events: none; pointer-events: none;
} }
.defaultEmpty{
padding-top: 100px;
}
import React, { Component } from 'react'; import React, { Component } from 'react';
import classNames from 'classnames';
import memoizeOne from 'memoize-one'; import memoizeOne from 'memoize-one';
import { Empty, Spin } from 'antd'; import { Empty, Spin } from 'antd';
import { ScrollSync, Grid, AutoSizer } from 'react-virtualized'; import { ScrollSync, Grid, AutoSizer } from 'react-virtualized';
...@@ -9,6 +10,7 @@ import { TableProps, TableState, ColumnProps, RowProps } from './interface'; ...@@ -9,6 +10,7 @@ import { TableProps, TableState, ColumnProps, RowProps } from './interface';
import Column from './Column'; import Column from './Column';
import Cell from './Cell'; import Cell from './Cell';
import { getMergeClassName, getMergeStyle } from '../utils/utils'; import { getMergeClassName, getMergeStyle } from '../utils/utils';
import { Consumer } from './context';
const borderStyle = '1px solid #ececec'; const borderStyle = '1px solid #ececec';
...@@ -175,10 +177,11 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -175,10 +177,11 @@ export default class AirTable extends Component<TableProps, TableState> {
return colWidth; return colWidth;
}; };
onResize = ({ width }: { width: number }) => { onResize = ({ width, height }: { width: number; height: number }) => {
this.setState( this.setState(
{ {
tableWidth: width, tableWidth: width,
tableHeight: height,
}, },
() => { () => {
this.grid1 && this.grid1.recomputeGridSize(); this.grid1 && this.grid1.recomputeGridSize();
...@@ -194,7 +197,7 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -194,7 +197,7 @@ export default class AirTable extends Component<TableProps, TableState> {
// 下拉加载 // 下拉加载
onScroll = ({ clientHeight, scrollHeight, scrollTop }: any) => { onScroll = ({ clientHeight, scrollHeight, scrollTop }: any) => {
const height = clientHeight + scrollTop || 0; const height = clientHeight + scrollTop || 0;
const { onScroll, distanceToLoad = 100 } = this.props; const { onScroll, distanceToLoad = 0 } = this.props;
if (scrollTop > 0 && height >= scrollHeight - distanceToLoad && typeof onScroll === 'function') { if (scrollTop > 0 && height >= scrollHeight - distanceToLoad && typeof onScroll === 'function') {
onScroll(); onScroll();
} }
...@@ -338,15 +341,17 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -338,15 +341,17 @@ export default class AirTable extends Component<TableProps, TableState> {
}; };
render() { render() {
const { loading, noDataPlaceholder } = this.props; const { loading, noDataPlaceholder, loadComp } = this.props;
const { columns, dataSource, tableWidth = 0 } = this.state; const { columns, dataSource, tableWidth = 0, tableHeight = 0 } = this.state;
const { overscanColumnCount, overscanRowCount, rowHeight, columnWidth, headerHeight } = this.config; const { overscanColumnCount, overscanRowCount, rowHeight, headerHeight } = this.config;
const scrollbarWidth = scrollbarSize() || 0; const scrollbarWidth = scrollbarSize() || 0;
const showColumns = this.memoizeColumns(columns); const showColumns = this.memoizeColumns(columns);
const leftColumns = this.memoizeLeftColumns(columns); const leftColumns = this.memoizeLeftColumns(columns);
const rightColumns = this.memoizeRightColumns(columns); const rightColumns = this.memoizeRightColumns(columns);
// 有隐藏列时,修正数据与列头不匹配问题 // 有隐藏列时,修正数据与列头不匹配问题
const showData = this.memoizeData(showColumns, dataSource); const showData = this.memoizeData(showColumns, dataSource);
const leftData = this.memoizeData(leftColumns, dataSource);
const rightData = this.memoizeData(rightColumns, dataSource);
// 左侧固定列数量 // 左侧固定列数量
const leftCount = leftColumns.length; const leftCount = leftColumns.length;
const rightCount = rightColumns.length; const rightCount = rightColumns.length;
...@@ -354,242 +359,263 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -354,242 +359,263 @@ export default class AirTable extends Component<TableProps, TableState> {
const rowCount = showData.length; const rowCount = showData.length;
const leftWidth = this.memoizeLeftWidth(leftColumns, showColumns); const leftWidth = this.memoizeLeftWidth(leftColumns, showColumns);
const rightWidth = this.memoizeLeftWidth(rightColumns, showColumns); const rightWidth = this.memoizeLeftWidth(rightColumns, showColumns);
let totalHeight: number = rowCount * rowHeight; // let totalHeight: number = rowCount * rowHeight;
let totalHeight: number = tableHeight - headerHeight;
const { totalWidth } = this.memoizeTotalWidth(showColumns); const { totalWidth } = this.memoizeTotalWidth(showColumns);
if (rowCount > 0 && totalWidth > tableWidth) { // if (rowCount > 0 && totalWidth > tableWidth) {
totalHeight = rowCount * rowHeight + scrollbarWidth; // // totalHeight = rowCount * rowHeight + scrollbarWidth;
// totalHeight = tableHeight + scrollbarWidth;
// }
let realWidth = tableWidth;
if (rowCount > 0 && rowCount * rowHeight > totalHeight) {
realWidth = tableWidth + scrollbarWidth;
} }
console.log('rightColumns', rightColumns);
return ( return (
<ScrollSync> <Consumer>
{({ onScroll, scrollLeft, scrollTop }: any) => { {({ locale }) => (
return ( <ScrollSync>
<div className={styles.tableContainer} style={{ height: totalHeight + headerHeight }}> {({ onScroll, scrollLeft, scrollTop }: any) => {
{totalWidth > tableWidth && leftCount > 0 && ( return (
<div <div
className={styles.leftSideContainer} className={
style={{ this.props.onScroll
width: `${leftWidth}px`, ? classNames(styles.tableContainer, styles.scroll)
height: `${totalHeight - scrollbarWidth + headerHeight}px`, : styles.tableContainer
}}
>
{
// 左侧表头
<div
className={styles.leftSideHeaderContainer}
style={{
left: 0,
}}
>
<Grid
ref={(dom: any) => {
this.grid1 = dom;
}}
className={styles.headerGrid}
columnWidth={this.getColumnWidth.bind(this, showColumns)}
columnCount={leftCount}
width={leftWidth}
rowHeight={headerHeight}
rowCount={1}
height={headerHeight}
cellRenderer={this.renderHeaderCell.bind(this, {
showColumns: leftColumns,
})}
/>
</div>
} }
{ >
// 左侧固定列 {totalWidth > tableWidth && leftCount > 0 && (
<div <div
className={styles.leftSideGridContainer} className={styles.leftSideContainer}
style={{ style={{
left: 0, width: `${leftWidth}px`,
top: headerHeight, height: `${totalHeight - scrollbarWidth + headerHeight}px`,
}} }}
> >
<Grid {
ref={(dom: any) => { // 左侧表头
this.grid2 = dom; <div
}} className={styles.leftSideHeaderContainer}
className={styles.sideGrid} style={{
overscanRowCount={overscanRowCount} left: 0,
cellRenderer={this.renderBodyRow.bind(this, { }}
showColumns: leftColumns, >
showData, <Grid
})} ref={(dom: any) => {
columnWidth={this.getColumnWidth.bind(this, showColumns)} this.grid1 = dom;
columnCount={leftCount}
width={leftWidth}
rowHeight={rowHeight}
rowCount={rowCount}
height={totalHeight - scrollbarWidth}
scrollTop={scrollTop}
/>
</div>
}
</div>
)}
<div className={styles.centerContainer}>
<AutoSizer disableHeight onResize={this.onResize}>
{({ width }: any) => {
return (
<div>
{
// 中部表头
<div
style={{
backgroundColor: 'rgba(246, 246, 246, 1)',
height: headerHeight,
width,
}} }}
> className={styles.headerGrid}
<Grid columnWidth={this.getColumnWidth.bind(this, showColumns)}
ref={(dom: any) => { columnCount={leftCount}
this.grid3 = dom; width={leftWidth}
}} rowHeight={headerHeight}
className={styles.headerGrid} rowCount={1}
overscanColumnCount={overscanColumnCount} height={headerHeight}
columnWidth={this.getColumnWidth.bind(this, showColumns)} cellRenderer={this.renderHeaderCell.bind(this, {
columnCount={columnCount} showColumns: leftColumns,
width={width} })}
rowHeight={headerHeight} />
rowCount={1} </div>
height={headerHeight} }
scrollLeft={scrollLeft} {
cellRenderer={this.renderHeaderCell.bind(this, { // 左侧固定列
showColumns, <div
})} className={styles.leftSideGridContainer}
/> style={{
</div> left: 0,
} top: headerHeight,
{ }}
// 中部内容 >
<div <Grid
style={{ ref={(dom: any) => {
height: totalHeight, this.grid2 = dom;
minHeight:
!dataSource || dataSource.length === 0
? '300px'
: 'auto',
width,
}} }}
> className={styles.sideGrid}
{rowCount > 0 ? ( overscanRowCount={overscanRowCount}
<Grid cellRenderer={this.renderBodyRow.bind(this, {
ref={(dom: any) => { showColumns: leftColumns,
this.grid4 = dom; showData: leftData,
}} })}
className={styles.centerGrid} columnWidth={this.getColumnWidth.bind(this, showColumns)}
overscanColumnCount={overscanColumnCount} columnCount={leftCount}
overscanRowCount={overscanRowCount} width={leftWidth}
columnWidth={this.getColumnWidth.bind( rowHeight={rowHeight}
this, rowCount={rowCount}
showColumns, height={totalHeight - scrollbarWidth}
)} scrollTop={scrollTop}
columnCount={columnCount} />
width={width} </div>
rowHeight={rowHeight} }
rowCount={rowCount} </div>
onScroll={(...arg: Array<Object>) => { )}
onScroll(...arg); <div className={styles.centerContainer}>
this.onScroll(arg[0]); <AutoSizer onResize={this.onResize}>
{({ width, height }: any) => {
return (
<div>
{
// 中部表头
<div
style={{
backgroundColor: 'rgba(246, 246, 246, 1)',
height: headerHeight,
width,
}} }}
height={totalHeight} >
cellRenderer={this.renderBodyRow.bind(this, { <Grid
showColumns, ref={(dom: any) => {
showData, this.grid3 = dom;
})} }}
/> className={styles.headerGrid}
) : ( overscanColumnCount={overscanColumnCount}
columnCount > 0 && columnWidth={this.getColumnWidth.bind(
!loading && ( this,
<Empty showColumns,
imageStyle={{ marginTop: '100px' }} )}
description={ columnCount={columnCount}
noDataPlaceholder || 'It’s empty here.' width={width}
} rowHeight={headerHeight}
rowCount={1}
height={headerHeight}
scrollLeft={scrollLeft}
cellRenderer={this.renderHeaderCell.bind(this, {
showColumns,
})}
/> />
) </div>
)} }
{
// 中部内容
<div
style={{
height: totalHeight,
// height: height - headerHeight,
// minHeight:
// !dataSource || dataSource.length === 0
// ? '300px'
// : 'auto',
width: tableWidth,
}}
>
{rowCount > 0 ? (
<Grid
ref={(dom: any) => {
this.grid4 = dom;
}}
className={styles.centerGrid}
overscanColumnCount={overscanColumnCount}
overscanRowCount={overscanRowCount}
columnWidth={this.getColumnWidth.bind(
this,
showColumns,
)}
columnCount={columnCount}
width={realWidth}
rowHeight={rowHeight}
rowCount={rowCount}
onScroll={(...arg: Array<Object>) => {
onScroll(...arg);
this.onScroll(arg[0]);
}}
height={totalHeight}
cellRenderer={this.renderBodyRow.bind(this, {
showColumns,
showData,
})}
/>
) : (
columnCount > 0 &&
!loading && (
<Empty
className={styles.defaultEmpty}
description={
noDataPlaceholder || locale.empty
}
/>
)
)}
</div>
}
</div> </div>
} );
</div>
);
}}
</AutoSizer>
</div>
{totalWidth > tableWidth && rightCount > 0 && (
<div
className={styles.rightSideContainer}
style={{
width: `${rightWidth}px`,
height: `${totalHeight - scrollbarWidth + headerHeight}px`,
}}
>
{
// 右侧表头
<div
className={styles.rightSideHeaderContainer}
style={{
right: 0,
}} }}
> </AutoSizer>
<Grid </div>
ref={(dom: any) => { {totalWidth > tableWidth && rightCount > 0 && (
this.grid5 = dom;
}}
className={styles.headerGrid}
columnWidth={this.getColumnWidth.bind(this, showColumns)}
columnCount={rightCount}
width={rightWidth}
rowHeight={headerHeight}
rowCount={1}
height={headerHeight}
cellRenderer={this.renderHeaderCell.bind(this, {
showColumns: rightColumns,
position: 'right',
})}
/>
</div>
}
{
// 右侧固定列
<div <div
className={styles.rightSideGridContainer} className={styles.rightSideContainer}
style={{ style={{
position: 'absolute', width: `${rightWidth}px`,
right: 0, height: `${totalHeight - scrollbarWidth + headerHeight}px`,
top: headerHeight,
}} }}
> >
<Grid {
ref={(dom: any) => { // 右侧表头
this.grid6 = dom; <div
}} className={styles.rightSideHeaderContainer}
className={styles.sideGrid} style={{
overscanRowCount={overscanRowCount} right: 0,
cellRenderer={this.renderBodyRow.bind(this, { }}
showColumns: rightColumns, >
showData, <Grid
position: 'right', ref={(dom: any) => {
})} this.grid5 = dom;
columnWidth={this.getColumnWidth.bind(this, showColumns)} }}
columnCount={rightCount} className={styles.headerGrid}
width={rightWidth} columnWidth={this.getColumnWidth.bind(this, showColumns)}
rowHeight={rowHeight} columnCount={rightCount}
rowCount={rowCount} width={rightWidth}
height={totalHeight - scrollbarWidth} rowHeight={headerHeight}
scrollTop={scrollTop} rowCount={1}
/> height={headerHeight}
cellRenderer={this.renderHeaderCell.bind(this, {
showColumns: rightColumns,
position: 'right',
})}
/>
</div>
}
{
// 右侧固定列
<div
className={styles.rightSideGridContainer}
style={{
position: 'absolute',
right: 0,
top: headerHeight,
}}
>
<Grid
ref={(dom: any) => {
this.grid6 = dom;
}}
className={styles.sideGrid}
overscanRowCount={overscanRowCount}
cellRenderer={this.renderBodyRow.bind(this, {
showColumns: rightColumns,
showData: rightData,
position: 'right',
})}
columnWidth={this.getColumnWidth.bind(this, showColumns)}
columnCount={rightCount}
width={rightWidth}
rowHeight={rowHeight}
rowCount={rowCount}
height={totalHeight - scrollbarWidth}
scrollTop={scrollTop}
/>
</div>
}
</div> </div>
} )}
<div className={styles.fillHandleWrapper} />
<div className={styles.loading}>{loading && (loadComp ? loadComp : <Spin />)}</div>
</div> </div>
)} );
<div className={styles.fillHandleWrapper} /> }}
<div className={styles.loading}>{/*<Spin spinning={loading} />*/}</div> </ScrollSync>
</div> )}
); </Consumer>
}}
</ScrollSync>
); );
} }
} }
import React from 'react';
const { Consumer, Provider } = React.createContext({});
export { Consumer, Provider };
...@@ -5,6 +5,7 @@ import styles from './styles.less'; ...@@ -5,6 +5,7 @@ import styles from './styles.less';
import { config } from '../base/config'; import { config } from '../base/config';
import { transferAttr } from '../base/_utils/transferAttr'; import { transferAttr } from '../base/_utils/transferAttr';
import { ColumnProps } from '../interface'; import { ColumnProps } from '../interface';
import { Consumer } from '../context';
const formatTags = (columns: ColumnProps[], tags: any[]) => { const formatTags = (columns: ColumnProps[], tags: any[]) => {
if (!columns || columns.length === 0 || !tags || !Array.isArray(tags)) { if (!columns || columns.length === 0 || !tags || !Array.isArray(tags)) {
...@@ -29,9 +30,10 @@ const formatTags = (columns: ColumnProps[], tags: any[]) => { ...@@ -29,9 +30,10 @@ const formatTags = (columns: ColumnProps[], tags: any[]) => {
return item.text; return item.text;
}) })
.join(','); .join(',');
const op = operator.find((item: any) => { const op =
return item.id === tag.operationCode; operator.find((item: any) => {
}) || {}; return item.id === tag.operationCode;
}) || {};
textTags.push(`${colConfig.columnChsName} ${op.name} ${value}`); textTags.push(`${colConfig.columnChsName} ${op.name} ${value}`);
}); });
return textTags; return textTags;
...@@ -59,8 +61,8 @@ class FormFilterButton extends Component<Props, State> { ...@@ -59,8 +61,8 @@ class FormFilterButton extends Component<Props, State> {
static getDerivedStateFromProps(nextProps: Props, prevState: State) { static getDerivedStateFromProps(nextProps: Props, prevState: State) {
if ( if (
JSON.stringify(nextProps.value) !== JSON.stringify(prevState.value) JSON.stringify(nextProps.value) !== JSON.stringify(prevState.value) ||
|| JSON.stringify(nextProps.columns) !== JSON.stringify(prevState.columns) JSON.stringify(nextProps.columns) !== JSON.stringify(prevState.columns)
) { ) {
return { return {
value: _.cloneDeep(nextProps.value), value: _.cloneDeep(nextProps.value),
...@@ -105,36 +107,42 @@ class FormFilterButton extends Component<Props, State> { ...@@ -105,36 +107,42 @@ class FormFilterButton extends Component<Props, State> {
const { tags } = this.state; const { tags } = this.state;
const { onSaveFilter } = this.props; const { onSaveFilter } = this.props;
return ( return (
<div className={styles.container}> <Consumer>
<div className={styles.title}>Selected conditions:</div> {({ locale }) => {
<div className={styles.footer}> return (
<div className={styles.chooseItem}> <div className={styles.container}>
{tags.map((item: any, i: number) => { <div className={styles.title}>{locale.selectedConditions}</div>
return ( <div className={styles.footer}>
<Tag <div className={styles.chooseItem}>
key={i} {tags.map((item: any, i: number) => {
color="#f1f4f7" return (
visible={true} <Tag
closable key={i}
onClose={this.removeTag.bind(this, i)} color="#f1f4f7"
> visible={true}
<span className={styles.tag}>{item}</span> closable
</Tag> onClose={this.removeTag.bind(this, i)}
); >
})} <span className={styles.tag}>{item}</span>
</div> </Tag>
<div className={styles.buttonGroup}> );
{onSaveFilter && ( })}
<div onClick={this.save} className={styles.saveBtn}> </div>
Save as a shortcut <div className={styles.buttonGroup}>
{onSaveFilter && (
<div onClick={this.save} className={styles.saveBtn}>
{locale.saveShortcut}
</div>
)}
<div onClick={this.reset} className={styles.resetBtn}>
{locale.clearFilter}
</div>
</div>
</div> </div>
)}
<div onClick={this.reset} className={styles.resetBtn}>
Clear filters
</div> </div>
</div> );
</div> }}
</div> </Consumer>
); );
} }
} }
......
...@@ -9,6 +9,7 @@ import s from '../hide/index.less'; ...@@ -9,6 +9,7 @@ import s from '../hide/index.less';
import styles from './index.less'; import styles from './index.less';
import filterIcon from '../../assets/filter.png'; import filterIcon from '../../assets/filter.png';
import closeIcon from '../../assets/close.png'; import closeIcon from '../../assets/close.png';
import { Consumer } from '../context';
const TransType = ['2', '3', '4', '13', '14', '15']; const TransType = ['2', '3', '4', '13', '14', '15'];
interface Props { interface Props {
...@@ -190,7 +191,7 @@ export default class Filter extends Component<Props, State> { ...@@ -190,7 +191,7 @@ export default class Filter extends Component<Props, State> {
} }
}; };
renderContent = () => { renderContent = (locale) => {
const { filterConfig } = this.state; const { filterConfig } = this.state;
const { columns } = this.props; const { columns } = this.props;
const filterColumnConfig = this.getFilterColumns(columns); const filterColumnConfig = this.getFilterColumns(columns);
...@@ -229,7 +230,7 @@ export default class Filter extends Component<Props, State> { ...@@ -229,7 +230,7 @@ export default class Filter extends Component<Props, State> {
value={item.colName || undefined} value={item.colName || undefined}
onChange={this.changeFilterKey.bind(this, i)} onChange={this.changeFilterKey.bind(this, i)}
style={{ width: '100%' }} style={{ width: '100%' }}
placeholder="please select" placeholder={locale.select}
> >
{filterColumnConfig.map((option) => { {filterColumnConfig.map((option) => {
return ( return (
...@@ -243,7 +244,7 @@ export default class Filter extends Component<Props, State> { ...@@ -243,7 +244,7 @@ export default class Filter extends Component<Props, State> {
<div className={styles.optionMid}> <div className={styles.optionMid}>
<Select <Select
value={item.operationCode || undefined} value={item.operationCode || undefined}
placeholder="please select" placeholder={locale.select}
onChange={this.changeFilterOperate.bind(this, i)} onChange={this.changeFilterOperate.bind(this, i)}
style={{ width: '100%' }} style={{ width: '100%' }}
> >
...@@ -279,7 +280,7 @@ export default class Filter extends Component<Props, State> { ...@@ -279,7 +280,7 @@ export default class Filter extends Component<Props, State> {
})} })}
<div className={styles.optionItem}> <div className={styles.optionItem}>
<div role="presentation" className={styles.add} onClick={this.addFilterLine}> <div role="presentation" className={styles.add} onClick={this.addFilterLine}>
Add {locale.filterAdd}
</div> </div>
</div> </div>
<div className={styles.btns}> <div className={styles.btns}>
...@@ -288,14 +289,14 @@ export default class Filter extends Component<Props, State> { ...@@ -288,14 +289,14 @@ export default class Filter extends Component<Props, State> {
className={classNames(styles.btn, styles.search)} className={classNames(styles.btn, styles.search)}
onClick={this.saveFilterList} onClick={this.saveFilterList}
> >
Search {locale.filterSearch}
</div> </div>
<div <div
role="presentation" role="presentation"
className={classNames(styles.btn, styles.reset)} className={classNames(styles.btn, styles.reset)}
onClick={this.resetFilterItem} onClick={this.resetFilterItem}
> >
Reset {locale.filterReset}
</div> </div>
</div> </div>
</div> </div>
...@@ -313,20 +314,27 @@ export default class Filter extends Component<Props, State> { ...@@ -313,20 +314,27 @@ export default class Filter extends Component<Props, State> {
bg = 'rgba(247,181,0,0.1)'; bg = 'rgba(247,181,0,0.1)';
} }
return ( return (
<Popover <Consumer>
overlayClassName={s.popover} {({ locale }) => {
placement="bottomLeft" const txt = locale.filter === '筛选' ? `${len}条筛选` : `Filtered by ${len} fields`;
title="Filter" return (
content={this.renderContent()} <Popover
visible={visible} overlayClassName={s.popover}
onVisibleChange={this.toggleOption} placement="bottomLeft"
trigger="click" title={locale.filter}
> content={this.renderContent(locale)}
<div className={s.operateContainer} style={{ background: bg }}> visible={visible}
<img alt="" className={s.operateIcon} src={filterIcon} /> onVisibleChange={this.toggleOption}
<span className={s.operateName}>{len > 0 ? `Filtered by ${len} fields` : 'Filter'}</span> trigger="click"
</div> >
</Popover> <div className={s.operateContainer} style={{ background: bg }}>
<img alt="" className={s.operateIcon} src={filterIcon} />
<span className={s.operateName}>{len > 0 ? txt : locale.filter}</span>
</div>
</Popover>
);
}}
</Consumer>
); );
} }
} }
...@@ -3,6 +3,7 @@ import { Switch, Popover } from 'antd'; ...@@ -3,6 +3,7 @@ import { Switch, Popover } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import s from './index.less'; import s from './index.less';
import hideIcon from '../../assets/hide.png'; import hideIcon from '../../assets/hide.png';
import { Consumer } from '../context';
interface Props { interface Props {
columns: any; columns: any;
...@@ -72,7 +73,7 @@ export default class Hide extends Component<Props, State> { ...@@ -72,7 +73,7 @@ export default class Hide extends Component<Props, State> {
} }
}; };
renderContent = () => { renderContent = (locale) => {
const { columnConfig } = this.state; const { columnConfig } = this.state;
return ( return (
<div className={s.optionsModal}> <div className={s.optionsModal}>
...@@ -95,10 +96,10 @@ export default class Hide extends Component<Props, State> { ...@@ -95,10 +96,10 @@ export default class Hide extends Component<Props, State> {
</div> </div>
<div className={s.btns}> <div className={s.btns}>
<div className={s.btn} role="presentation" onClick={this.changeHide.bind(this, 'all', 0)}> <div className={s.btn} role="presentation" onClick={this.changeHide.bind(this, 'all', 0)}>
Hide all {locale.hideHideAll}
</div> </div>
<div className={s.btn} role="presentation" onClick={this.changeHide.bind(this, 'all', 1)}> <div className={s.btn} role="presentation" onClick={this.changeHide.bind(this, 'all', 1)}>
Show all {locale.hideShowAll}
</div> </div>
</div> </div>
</div> </div>
...@@ -115,20 +116,29 @@ export default class Hide extends Component<Props, State> { ...@@ -115,20 +116,29 @@ export default class Hide extends Component<Props, State> {
bg = 'rgba(66,202,196,0.1)'; bg = 'rgba(66,202,196,0.1)';
} }
return ( return (
<Popover <Consumer>
overlayClassName={s.popover} {({ locale }) => {
placement="bottomLeft" const txt = locale.hide === '隐藏' ? `${len}条隐藏` : `${len} fields hidden`;
title="Hide" return (
content={this.renderContent()} <Popover
visible={visible} overlayClassName={s.popover}
onVisibleChange={this.toggleOption} placement="bottomLeft"
trigger="click" title={locale.hide}
> content={this.renderContent(locale)}
<div className={s.operateContainer} style={{ background: bg }}> visible={visible}
<img alt="" className={s.operateIcon} src={hideIcon} /> onVisibleChange={this.toggleOption}
<span className={s.operateName}>{len > 0 ? `${len} fields hidden` : 'Hide fields'}</span> trigger="click"
</div> >
</Popover> <div className={s.operateContainer} style={{ background: bg }}>
<img alt="" className={s.operateIcon} src={hideIcon} />
<span className={s.operateName}>
{len > 0 ? txt : locale.hide}
</span>
</div>
</Popover>
);
}}
</Consumer>
); );
} }
} }
...@@ -4,13 +4,21 @@ ...@@ -4,13 +4,21 @@
//height: 100%; //height: 100%;
width: 100%; width: 100%;
position: relative; position: relative;
.operateContainer { &.scroll {
display: flex;
flex-direction: column;
height: calc(100vh - 92px);
}
.operateContainer {
} }
.tableContainer { .tableContainer {
position: relative; position: relative;
box-shadow: @boxShadow; box-shadow: @boxShadow;
//min-height: 600px; //min-height: 600px;
&.scroll {
flex: 1;
}
.tableC { .tableC {
padding: 0 16px; padding: 0 16px;
......
import React from 'react'; import React from 'react';
import { Pagination } from 'antd'; import { Pagination } from 'antd';
import classNames from 'classnames';
import styles from './index.less'; import styles from './index.less';
import { CommonProps, CommonState } from './interface'; import { CommonProps, CommonState } from './interface';
import Table from './Table'; import Table from './Table';
import OperateConfig from './operate'; import OperateConfig from './operate';
import TableOperateConfig from './tableOperate'; import TableOperateConfig from './tableOperate';
import { defaultLocale } from '../locale';
import { Provider } from './context';
class AirTable extends React.Component<CommonProps, CommonState> { class AirTable extends React.Component<CommonProps, CommonState> {
static getDerivedStateFromProps(nextProps: CommonProps, prevState: CommonState) { static getDerivedStateFromProps(nextProps: CommonProps, prevState: CommonState) {
...@@ -38,6 +41,19 @@ class AirTable extends React.Component<CommonProps, CommonState> { ...@@ -38,6 +41,19 @@ class AirTable extends React.Component<CommonProps, CommonState> {
} }
}; };
getContext = () => {
const { locale } = this.props;
if (locale) {
if (locale.context) {
if (locale.lang && defaultLocale[locale.lang]) {
return { ...defaultLocale[locale.lang], ...locale.context };
}
return locale.context;
}
}
return defaultLocale.cn;
};
render() { render() {
const { columns, dataSource } = this.state; const { columns, dataSource } = this.state;
const { const {
...@@ -61,44 +77,50 @@ class AirTable extends React.Component<CommonProps, CommonState> { ...@@ -61,44 +77,50 @@ class AirTable extends React.Component<CommonProps, CommonState> {
columnWidth, columnWidth,
headerHeight, headerHeight,
contentMenu, contentMenu,
onScroll,
} = this.props; } = this.props;
const sortConfig = operateConfig const sortConfig =
&& operateConfig.menusGroup operateConfig &&
&& operateConfig.menusGroup.find((item: any) => { operateConfig.menusGroup &&
operateConfig.menusGroup.find((item: any) => {
return item.type === 'sort'; return item.type === 'sort';
}); });
return ( return (
<div className={styles.container}> <Provider value={{ locale: this.getContext() }}>
{operateConfig && <OperateConfig columns={columns} operateConfig={operateConfig} />} <div className={onScroll ? classNames(styles.container, styles.scroll) : styles.container}>
<div className={styles.tableContainer}> {operateConfig && <OperateConfig columns={columns} operateConfig={operateConfig} />}
{tableOperateConfig && <TableOperateConfig operateConfig={tableOperateConfig} />} <div
<Table className={onScroll ? classNames(styles.tableContainer, styles.scroll) : styles.tableContainer}
columns={columns} >
dataSource={dataSource} {tableOperateConfig && <TableOperateConfig operateConfig={tableOperateConfig} />}
onScroll={this.onScroll} <Table
rowStyle={rowStyle} columns={columns}
rowClassName={rowClassName} dataSource={dataSource}
distanceToLoad={distanceToLoad} onScroll={this.onScroll}
emitChangeCell={emitChangeCell} rowStyle={rowStyle}
bordered={bordered} rowClassName={rowClassName}
width={width} distanceToLoad={distanceToLoad}
height={height} emitChangeCell={emitChangeCell}
sortConfig={sortConfig} bordered={bordered}
paginationConfig={paginationConfig} width={width}
showIndex={showIndex} height={height}
emptyPlaceholder={emptyPlaceholder} sortConfig={sortConfig}
cellEditable={cellEditable} paginationConfig={paginationConfig}
rowHeight={rowHeight} showIndex={showIndex}
headerHeight={headerHeight} emptyPlaceholder={emptyPlaceholder}
columnWidth={columnWidth} cellEditable={cellEditable}
loading={loading} rowHeight={rowHeight}
rowSelection={rowSelection} headerHeight={headerHeight}
noDataPlaceholder={noDataPlaceholder} columnWidth={columnWidth}
contentMenu={contentMenu} loading={loading}
/> rowSelection={rowSelection}
noDataPlaceholder={noDataPlaceholder}
contentMenu={contentMenu}
/>
</div>
{paginationConfig && <Pagination {...paginationConfig} />}
</div> </div>
{paginationConfig && <Pagination {...paginationConfig} />} </Provider>
</div>
); );
} }
} }
......
...@@ -70,7 +70,8 @@ export interface TableProps extends LoadConfigProps { ...@@ -70,7 +70,8 @@ export interface TableProps extends LoadConfigProps {
loading?: boolean; loading?: boolean;
rowSelection?: any; rowSelection?: any;
noDataPlaceholder?: any; noDataPlaceholder?: any;
contentMenu?:any; contentMenu?: any;
loadComp?: any;
} }
export interface TableState { export interface TableState {
columns: ColumnProps[]; columns: ColumnProps[];
...@@ -82,6 +83,7 @@ export interface CommonProps extends TableProps { ...@@ -82,6 +83,7 @@ export interface CommonProps extends TableProps {
operateConfig?: OperateConfigProps; operateConfig?: OperateConfigProps;
tableOperateConfig?: OperateConfigProps; tableOperateConfig?: OperateConfigProps;
paginationConfig?: any; paginationConfig?: any;
locale?: any;
} }
export interface CommonState extends TableState {} export interface CommonState extends TableState {}
...@@ -112,7 +114,7 @@ export interface CellProps { ...@@ -112,7 +114,7 @@ export interface CellProps {
emptyPlaceholder?: string; emptyPlaceholder?: string;
cellEditable?: boolean; cellEditable?: boolean;
rowSelection?: any; rowSelection?: any;
contentMenu?:any; contentMenu?: any;
} }
export interface EditCellProps { export interface EditCellProps {
......
...@@ -7,6 +7,7 @@ import styles from './index.less'; ...@@ -7,6 +7,7 @@ import styles from './index.less';
import sortIcon from '../../assets/sort.png'; import sortIcon from '../../assets/sort.png';
import closeIcon from '../../assets/close.png'; import closeIcon from '../../assets/close.png';
import { ColumnProps } from '../interface'; import { ColumnProps } from '../interface';
import { Consumer } from '../context';
interface Props { interface Props {
columns: any; columns: any;
...@@ -169,7 +170,7 @@ export default class Sort extends Component<Props, State> { ...@@ -169,7 +170,7 @@ export default class Sort extends Component<Props, State> {
}); });
}; };
renderContent = () => { renderContent = (locale) => {
const { sortConfig, temp } = this.state; const { sortConfig, temp } = this.state;
const filterConfig = this.getFilterConfig(); const filterConfig = this.getFilterConfig();
return ( return (
...@@ -182,7 +183,7 @@ export default class Sort extends Component<Props, State> { ...@@ -182,7 +183,7 @@ export default class Sort extends Component<Props, State> {
value={item.colName} value={item.colName}
onChange={this.changeSortKey.bind(this, i)} onChange={this.changeSortKey.bind(this, i)}
style={{ width: '100%' }} style={{ width: '100%' }}
placeholder="please select" placeholder={locale.select}
> >
{filterConfig.map((option) => { {filterConfig.map((option) => {
return ( return (
...@@ -207,7 +208,7 @@ export default class Sort extends Component<Props, State> { ...@@ -207,7 +208,7 @@ export default class Sort extends Component<Props, State> {
} }
onClick={this.changeSortType.bind(this, i, 'ASC')} onClick={this.changeSortType.bind(this, i, 'ASC')}
> >
ASC {locale.sortASC}
</Button> </Button>
<Button <Button
className={ className={
...@@ -217,7 +218,7 @@ export default class Sort extends Component<Props, State> { ...@@ -217,7 +218,7 @@ export default class Sort extends Component<Props, State> {
} }
onClick={this.changeSortType.bind(this, i, 'DESC')} onClick={this.changeSortType.bind(this, i, 'DESC')}
> >
DESC {locale.sortDESC}
</Button> </Button>
</Button.Group> </Button.Group>
</div> </div>
...@@ -236,7 +237,7 @@ export default class Sort extends Component<Props, State> { ...@@ -236,7 +237,7 @@ export default class Sort extends Component<Props, State> {
<div className={styles.optionLeft}> <div className={styles.optionLeft}>
<Select <Select
value={temp.colName} value={temp.colName}
placeholder="please select" placeholder={locale.select}
onChange={this.changeColName} onChange={this.changeColName}
style={{ width: '100%' }} style={{ width: '100%' }}
> >
...@@ -263,7 +264,7 @@ export default class Sort extends Component<Props, State> { ...@@ -263,7 +264,7 @@ export default class Sort extends Component<Props, State> {
} }
onClick={this.changeNewSortType.bind(this, 'ASC')} onClick={this.changeNewSortType.bind(this, 'ASC')}
> >
ASC {locale.sortASC}
</Button> </Button>
<Button <Button
className={ className={
...@@ -273,7 +274,7 @@ export default class Sort extends Component<Props, State> { ...@@ -273,7 +274,7 @@ export default class Sort extends Component<Props, State> {
} }
onClick={this.changeNewSortType.bind(this, 'DESC')} onClick={this.changeNewSortType.bind(this, 'DESC')}
> >
DESC {locale.sortDESC}
</Button> </Button>
</Button.Group> </Button.Group>
</div> </div>
...@@ -285,7 +286,7 @@ export default class Sort extends Component<Props, State> { ...@@ -285,7 +286,7 @@ export default class Sort extends Component<Props, State> {
className={classNames(styles.btn, styles.reset)} className={classNames(styles.btn, styles.reset)}
onClick={this.resetSortItem} onClick={this.resetSortItem}
> >
Reset {locale.sortReset}
</div> </div>
</div> </div>
</div> </div>
...@@ -303,20 +304,27 @@ export default class Sort extends Component<Props, State> { ...@@ -303,20 +304,27 @@ export default class Sort extends Component<Props, State> {
bg = 'rgba(92,153,255,0.2)'; bg = 'rgba(92,153,255,0.2)';
} }
return ( return (
<Popover <Consumer>
overlayClassName={s.popover} {({ locale }) => {
placement="bottomLeft" const txt = locale.sort === '排序' ? `${len}条排序` : `Sorted by ${len} fields`;
title="Sort" return (
content={this.renderContent()} <Popover
visible={visible} overlayClassName={s.popover}
onVisibleChange={this.toggleOption} placement="bottomLeft"
trigger="click" title={locale.sort}
> content={this.renderContent(locale)}
<div className={s.operateContainer} style={{ background: bg }}> visible={visible}
<img alt="" className={s.operateIcon} src={sortIcon} /> onVisibleChange={this.toggleOption}
<span className={s.operateName}>{len > 0 ? `Sorted by ${len} fields` : 'Sort'}</span> trigger="click"
</div> >
</Popover> <div className={s.operateContainer} style={{ background: bg }}>
<img alt="" className={s.operateIcon} src={sortIcon} />
<span className={s.operateName}>{len > 0 ? txt : locale.sort}</span>
</div>
</Popover>
);
}}
</Consumer>
); );
} }
} }
export const defaultLocale: any = {
cn: {
empty: '暂无数据',
filter: '筛选',
filterAdd: '添加',
filterSearch: '查询',
filterReset: '重置',
selectedConditions: '已选条件:',
saveShortcut: '新建快捷筛选',
clearFilter: '重置',
sort: '排序',
sortReset: '重置',
sortASC: '正序',
sortDESC: '倒序',
group: '分组',
hide: '隐藏',
hideShowAll: '显示所有',
hideHideAll: '全部隐藏',
select: '请选择',
text: '请输入',
},
en: {
empty: 'It’s empty here.',
filter: 'Filter',
filterAdd: 'Add',
filterSearch: 'Search',
filterReset: 'Reset',
selectedConditions: 'Selected conditions:',
saveShortcut: 'Save as a shortcut',
clearFilter: 'Clear filters',
sort: 'Sort',
sortReset: 'Reset',
sortASC: 'ASC',
sortDESC: 'DESC',
group: 'Group',
hide: 'Hide',
hideShowAll: 'Show all',
hideHideAll: 'Hide all',
select: 'please select',
text: 'please input',
},
};
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