Merge remote-tracking branch 'baidu/master' into css

This commit is contained in:
liaoxuezhi 2020-12-08 23:03:37 +08:00
commit b38efd9905
14 changed files with 884 additions and 764 deletions

View File

@ -177,7 +177,12 @@ export function embed(
return window.history.back();
}
replace || (location.href = normalizeLink(to));
if (replace && window.history.replaceState) {
window.history.replaceState('', document.title, to);
return;
}
location.href = normalizeLink(to);
},
isCurrentUrl: (to: string) => {
const link = normalizeLink(to);

View File

@ -19,10 +19,13 @@
}
&-fixedLeft {
// 还是改成默认不显示footable 展示的时候配置 固定列还没修复
left: 0;
top: -99999px;
&.in {
box-shadow: $Table-fixedLeft-boxShadow;
top: auto;
}
& > .#{$ns}Table-table {
@ -38,10 +41,13 @@
}
&-fixedRight {
// 还是改成默认不显示footable 展示的时候配置 固定列还没修复
right: 0;
top: -99999px;
&.in {
box-shadow: $Table-fixedRight-boxShadow;
top: auto;
}
& > .#{$ns}Table-table {

View File

@ -165,7 +165,7 @@ function createScopedTools(
...values
};
const link = location.pathname + '?' + qsstringify(query);
env.updateLocation(link);
env.updateLocation(link, true);
}
});
},

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ export interface DiffControlSchema extends FormBaseControl {
}
function loadComponent(): Promise<any> {
return import('../../components/Editor');
return import('../../components/Editor').then(item => item.default);
}
export interface DiffEditorProps

View File

@ -7,7 +7,7 @@ import {
} from './Options';
import cx from 'classnames';
import Button from '../../components/Button';
import {SchemaNode, Schema, Action} from '../../types';
import {SchemaNode, Schema, Action, PlainObject} from '../../types';
import find from 'lodash/find';
import {
anyChanged,
@ -67,7 +67,7 @@ export interface PickerControlSchema extends FormOptionsControl {
export interface PickerProps extends OptionsControlProps {
modalMode: 'dialog' | 'drawer';
pickerSchema: object;
pickerSchema: PlainObject;
labelField: string;
}
@ -169,7 +169,9 @@ export default class PickerControl extends React.PureComponent<
buildSchema(props: PickerProps) {
return {
checkOnItemClick: true,
...props.pickerSchema,
labelTpl: props.pickerSchema?.labelTpl ?? props.labelTpl,
type: 'crud',
pickerMode: true,
syncLocation: false,
@ -177,7 +179,6 @@ export default class PickerControl extends React.PureComponent<
keepItemSelectionOnPageChange: true,
valueField: props.valueField,
labelField: props.labelField,
checkOnItemClick: true,
// 不支持批量操作,会乱套
bulkActions: props.multiple
@ -361,6 +362,7 @@ export default class PickerControl extends React.PureComponent<
labelTpl,
disabled
} = this.props;
return (
<div className={`${ns}Picker-values`}>
{selectedOptions.map((item, index) => (

View File

@ -29,8 +29,8 @@ function loadRichText(
): () => Promise<any> {
return () =>
type === 'tinymce'
? import('../../components/Tinymce')
: import('../../components/RichText');
? import('../../components/Tinymce').then(item => item.default)
: import('../../components/RichText').then(item => item.default);
}
export default class RichTextControl extends React.Component<

View File

@ -227,7 +227,7 @@ export class HeadCellFilterDropDown extends React.Component<
? filterOptions.map((option: any, index) => (
<li
key={index}
className={cx('DropDown-divider', {
className={cx({
'is-selected': option.selected
})}
onClick={this.handleClick.bind(this, option.value)}
@ -236,7 +236,7 @@ export class HeadCellFilterDropDown extends React.Component<
</li>
))
: filterOptions.map((option: any, index) => (
<li key={index} className={cx('DropDown-divider')}>
<li key={index}>
<Checkbox
classPrefix={ns}
onChange={this.handleCheck.bind(this, option.value)}
@ -248,7 +248,6 @@ export class HeadCellFilterDropDown extends React.Component<
))}
<li
key="DropDown-menu-reset"
className={cx('DropDown-divider')}
onClick={this.handleReset.bind(this)}
>
{__('重置')}

View File

@ -0,0 +1,199 @@
import React from 'react';
import {ClassNamesFn} from '../../theme';
import {IColumn, IRow} from '../../store/table';
import {SchemaNode, Action} from '../../types';
import {TableRow} from './TableRow';
import {filter} from '../../utils/tpl';
import {observer} from 'mobx-react';
import {trace, reaction} from 'mobx';
import {flattenTree} from '../../utils/helper';
export interface TableBodyProps {
className?: string;
rowsProps?: any;
tableClassName?: string;
classnames: ClassNamesFn;
columns: Array<IColumn>;
rows: Array<IRow>;
placeholder?: string;
render: (region: string, node: SchemaNode, props?: any) => JSX.Element;
renderCell: (
region: string,
column: IColumn,
item: IRow,
props: any
) => React.ReactNode;
onCheck: (item: IRow) => void;
onQuickChange?: (
item: IRow,
values: object,
saveImmediately?: boolean | any,
savePristine?: boolean
) => void;
footable?: boolean;
ignoreFootableContent?: boolean;
footableColumns: Array<IColumn>;
checkOnItemClick?: boolean;
buildItemProps?: (item: IRow, index: number) => any;
onAction?: (e: React.UIEvent<any>, action: Action, ctx: object) => void;
rowClassNameExpr?: string;
rowClassName?: string;
}
export class TableBody extends React.Component<TableBodyProps> {
reaction?: () => void;
constructor(props: TableBodyProps) {
super(props);
const rows = props.rows;
this.reaction = reaction(
() =>
`${flattenTree(rows)
.map(item => `${item.id}`)
.join(',')}${rows
.filter(item => item.checked)
.map(item => item.id)
.join(',')}`,
() => this.forceUpdate(),
{
onError: () => this.reaction!()
}
);
}
shouldComponentUpdate(nextProps: TableBodyProps) {
const props = this.props;
if (
props.columns !== nextProps.columns ||
props.buildItemProps !== nextProps.buildItemProps
) {
return true;
}
return false;
}
componentwillUnmount() {
this.reaction?.();
}
renderRows(
rows: Array<any>,
columns = this.props.columns,
rowProps: any = {}
): any {
const {
rowClassName,
rowClassNameExpr,
onAction,
buildItemProps,
checkOnItemClick,
classnames: cx,
render,
renderCell,
onCheck,
onQuickChange,
footable,
ignoreFootableContent,
footableColumns
} = this.props;
return rows.map((item: IRow, rowIndex: number) => {
const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null;
const doms = [
<TableRow
{...itemProps}
classnames={cx}
checkOnItemClick={checkOnItemClick}
key={item.id}
itemIndex={rowIndex}
item={item}
itemClassName={cx(
rowClassNameExpr
? filter(rowClassNameExpr, item.data)
: rowClassName,
{
'is-last': item.depth > 1 && rowIndex === rows.length - 1
}
)}
columns={columns}
renderCell={renderCell}
render={render}
onAction={onAction}
onCheck={onCheck}
// todo 先注释 quickEditEnabled={item.depth === 1}
onQuickChange={onQuickChange}
{...rowProps}
/>
];
if (footable && footableColumns.length) {
if (item.depth === 1) {
doms.push(
<TableRow
{...itemProps}
classnames={cx}
checkOnItemClick={checkOnItemClick}
key={`foot-${item.id}`}
itemIndex={rowIndex}
item={item}
itemClassName={cx(
rowClassNameExpr
? filter(rowClassNameExpr, item.data)
: rowClassName
)}
columns={footableColumns}
renderCell={renderCell}
render={render}
onAction={onAction}
onCheck={onCheck}
footableMode
footableColSpan={columns.length}
onQuickChange={onQuickChange}
ignoreFootableContent={ignoreFootableContent}
{...rowProps}
/>
);
}
} else if (item.children.length) {
// 嵌套表格
doms.push(
...this.renderRows(item.children, columns, {
...rowProps,
parent: item
})
);
}
return doms;
});
}
render() {
const {
placeholder,
classnames: cx,
className,
render,
rows,
columns,
rowsProps
} = this.props;
return (
<tbody className={className}>
{rows.length ? (
this.renderRows(rows, columns, rowsProps)
) : (
<tr className={cx('Table-placeholder')}>
<td colSpan={columns.length}>
{render('placeholder', placeholder || '暂无数据')}
</td>
</tr>
)}
</tbody>
);
}
}

View File

@ -7,6 +7,7 @@ import {filter} from '../../utils/tpl';
import {observer} from 'mobx-react';
import {trace, reaction} from 'mobx';
import {flattenTree} from '../../utils/helper';
import {TableBody} from './TableBody';
export interface TableContentProps {
className?: string;
@ -52,22 +53,6 @@ export class TableContent extends React.Component<TableContentProps> {
reaction?: () => void;
constructor(props: TableContentProps) {
super(props);
const rows = props.rows;
this.reaction = reaction(
() =>
`${flattenTree(rows)
.map(item => `${item.id}`)
.join(',')}${rows
.filter(item => item.checked)
.map(item => item.id)
.join(',')}`,
() => this.forceUpdate(),
{
onError: () => this.reaction!()
}
);
}
shouldComponentUpdate(nextProps: TableContentProps) {
@ -83,100 +68,6 @@ export class TableContent extends React.Component<TableContentProps> {
return false;
}
componentwillUnmount() {
this.reaction?.();
}
renderRows(
rows: Array<any>,
columns = this.props.columns,
rowProps: any = {}
): any {
const {
rowClassName,
rowClassNameExpr,
onAction,
buildItemProps,
checkOnItemClick,
classnames: cx,
render,
renderCell,
onCheck,
onQuickChange,
footable,
footableColumns
} = this.props;
return rows.map((item: IRow, rowIndex: number) => {
const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null;
const doms = [
<TableRow
{...itemProps}
classnames={cx}
checkOnItemClick={checkOnItemClick}
key={item.id}
itemIndex={rowIndex}
item={item}
itemClassName={cx(
rowClassNameExpr
? filter(rowClassNameExpr, item.data)
: rowClassName,
{
'is-last': item.depth > 1 && rowIndex === rows.length - 1
}
)}
columns={columns}
renderCell={renderCell}
render={render}
onAction={onAction}
onCheck={onCheck}
// todo 先注释 quickEditEnabled={item.depth === 1}
onQuickChange={onQuickChange}
{...rowProps}
/>
];
if (footable && footableColumns.length) {
if (item.depth === 1) {
doms.push(
<TableRow
{...itemProps}
classnames={cx}
checkOnItemClick={checkOnItemClick}
key={`foot-${item.id}`}
itemIndex={rowIndex}
item={item}
itemClassName={cx(
rowClassNameExpr
? filter(rowClassNameExpr, item.data)
: rowClassName
)}
columns={footableColumns}
renderCell={renderCell}
render={render}
onAction={onAction}
onCheck={onCheck}
footableMode
footableColSpan={columns.length}
onQuickChange={onQuickChange}
{...rowProps}
/>
);
}
} else if (item.children.length) {
// 嵌套表格
doms.push(
...this.renderRows(item.children, columns, {
...rowProps,
parent: item
})
);
}
return doms;
});
}
render() {
const {
placeholder,
@ -189,7 +80,17 @@ export class TableContent extends React.Component<TableContentProps> {
onScroll,
tableRef,
rows,
renderHeadCell
renderHeadCell,
renderCell,
onCheck,
rowClassName,
onQuickChange,
footable,
footableColumns,
checkOnItemClick,
buildItemProps,
onAction,
rowClassNameExpr
} = this.props;
const tableClassName = cx('Table-table', this.props.tableClassName);
@ -225,17 +126,23 @@ export class TableContent extends React.Component<TableContentProps> {
)}
</tr>
</thead>
<tbody>
{rows.length ? (
this.renderRows(rows, columns)
) : (
<tr className={cx('Table-placeholder')}>
<td colSpan={columns.length}>
{render('placeholder', placeholder || '暂无数据')}
</td>
</tr>
)}
</tbody>
<TableBody
classnames={cx}
placeholder={placeholder}
render={render}
renderCell={renderCell}
onCheck={onCheck}
onQuickChange={onQuickChange}
footable={footable}
footableColumns={footableColumns}
checkOnItemClick={checkOnItemClick}
buildItemProps={buildItemProps}
onAction={onAction}
rowClassNameExpr={rowClassNameExpr}
rowClassName={rowClassName}
rows={rows}
columns={columns}
></TableBody>
</table>
</div>
);

View File

@ -21,6 +21,7 @@ interface TableRowProps extends Pick<RendererProps, 'render'> {
itemIndex: number;
regionPrefix?: string;
checkOnItemClick?: boolean;
ignoreFootableContent?: boolean;
[propName: string]: any;
}
@ -103,6 +104,7 @@ export class TableRow extends React.Component<TableRowProps> {
renderCell,
children,
footableMode,
ignoreFootableContent,
footableColSpan,
regionPrefix,
checkOnItemClick,
@ -137,33 +139,40 @@ export class TableRow extends React.Component<TableRowProps> {
<td className={cx(`Table-foot`)} colSpan={footableColSpan}>
<table className={cx(`Table-footTable`)}>
<tbody>
{columns.map(column => (
<tr key={column.index}>
{column.label !== false ? (
<th>
{render(
`${regionPrefix}${itemIndex}/${column.index}/tpl`,
column.label
)}
</th>
) : null}
{ignoreFootableContent
? columns.map(column => (
<tr key={column.index}>
{column.label !== false ? <th></th> : null}
<td></td>
</tr>
))
: columns.map(column => (
<tr key={column.index}>
{column.label !== false ? (
<th>
{render(
`${regionPrefix}${itemIndex}/${column.index}/tpl`,
column.label
)}
</th>
) : null}
{renderCell(
`${regionPrefix}${itemIndex}/${column.index}`,
column,
item,
{
...rest,
width: null,
rowIndex: itemIndex,
colIndex: column.rawIndex,
key: column.index,
onAction: this.handleAction,
onQuickChange: this.handleQuickChange
}
)}
</tr>
))}
{renderCell(
`${regionPrefix}${itemIndex}/${column.index}`,
column,
item,
{
...rest,
width: null,
rowIndex: itemIndex,
colIndex: column.rawIndex,
key: column.index,
onAction: this.handleAction,
onQuickChange: this.handleQuickChange
}
)}
</tr>
))}
</tbody>
</table>
</td>

View File

@ -40,6 +40,7 @@ import {SchemaQuickEdit} from '../QuickEdit';
import {SchemaCopyable} from '../Copyable';
import {SchemaRemark} from '../Remark';
import {toDataURL, getImageDimensions} from '../../utils/image';
import {TableBody} from './TableBody';
/**
*
@ -789,8 +790,9 @@ export default class Table extends React.Component<TableProps, object> {
const dom = findDOMNode(this) as HTMLElement;
forEach(
// 折叠 footTable 不需要改变
dom.querySelectorAll(
`.${ns}Table-fixedTop table, .${ns}Table-fixedLeft table, .${ns}Table-fixedRight table`
`.${ns}Table-fixedTop table, .${ns}Table-fixedLeft>table, .${ns}Table-fixedRight>table`
),
(table: HTMLTableElement) => {
let totalWidth = 0;
@ -1572,7 +1574,17 @@ export default class Table extends React.Component<TableProps, object> {
headerOnly: boolean = false,
tableClassName: string = ''
) {
const {placeholder, store, classnames: cx, render, data} = this.props;
const {
placeholder,
store,
classnames: cx,
render,
data,
checkOnItemClick,
buildItemProps,
rowClassNameExpr,
rowClassName
} = this.props;
const hideHeader = store.filteredColumns.every(column => !column.label);
return (
@ -1612,25 +1624,37 @@ export default class Table extends React.Component<TableProps, object> {
</thead>
{headerOnly ? null : (
<tbody>
{rows.length ? (
this.renderRows(rows, columns, {
regionPrefix: 'fixed/',
renderCell: (
region: string,
column: IColumn,
item: IRow,
props: any
) => this.renderCell(region, column, item, props, true)
})
) : (
<tr className={cx('Table-placeholder')}>
<td colSpan={columns.length}>
{render('placeholder', placeholder, {data})}
</td>
</tr>
<TableBody
tableClassName={cx(
store.combineNum > 0 ? 'Table-table--withCombine' : '',
tableClassName
)}
</tbody>
classnames={cx}
placeholder={placeholder}
render={render}
renderCell={this.renderCell}
onCheck={this.handleCheck}
onQuickChange={store.dragging ? undefined : this.handleQuickChange}
footable={store.footable}
ignoreFootableContent
footableColumns={store.footableColumns}
checkOnItemClick={checkOnItemClick}
buildItemProps={buildItemProps}
onAction={this.handleAction}
rowClassNameExpr={rowClassNameExpr}
rowClassName={rowClassName}
columns={columns}
rows={rows}
rowsProps={{
regionPrefix: 'fixed/',
renderCell: (
region: string,
column: IColumn,
item: IRow,
props: any
) => this.renderCell(region, column, item, props, true)
}}
/>
)}
</table>
);
@ -2085,93 +2109,6 @@ export default class Table extends React.Component<TableProps, object> {
: footerNode || toolbarNode || null;
}
renderRows(
rows: Array<any>,
columns = this.props.store.filteredColumns,
rowProps: any = {}
): any {
const {
store,
rowClassName,
rowClassNameExpr,
onAction,
buildItemProps,
checkOnItemClick,
classPrefix: ns,
classnames: cx,
render
} = this.props;
return rows.map((item: IRow, rowIndex: number) => {
const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null;
const doms = [
<TableRow
{...itemProps}
classPrefix={ns}
classnames={cx}
checkOnItemClick={checkOnItemClick}
key={item.id}
itemIndex={rowIndex}
item={item}
itemClassName={cx(
rowClassNameExpr
? filter(rowClassNameExpr, item.data)
: rowClassName,
{
'is-last': item.depth > 1 && rowIndex === rows.length - 1,
'is-expanded': item.expanded,
'is-expandable': item.expandable
}
)}
columns={columns}
renderCell={this.renderCell}
render={render}
onAction={onAction}
onCheck={this.handleCheck}
// todo 先注释 quickEditEnabled={item.depth === 1}
onQuickChange={store.dragging ? null : this.handleQuickChange}
{...rowProps}
/>
];
if (store.footable && store.footableColumns.length) {
if (item.depth === 1) {
doms.push(
<TableRow
{...itemProps}
classPrefix={ns}
classnames={cx}
checkOnItemClick={checkOnItemClick}
key={`foot-${item.id}`}
itemIndex={rowIndex}
item={item}
itemClassName={cx(
rowClassNameExpr
? filter(rowClassNameExpr, item.data)
: rowClassName
)}
columns={store.footableColumns}
renderCell={this.renderCell}
render={render}
onAction={onAction}
onCheck={this.handleCheck}
footableMode
footableColSpan={store.filteredColumns.length}
onQuickChange={store.dragging ? null : this.handleQuickChange}
{...rowProps}
/>
);
}
} else if (Array.isArray(item.data.children)) {
// 嵌套表格
doms.push(...this.renderRows(item.children, columns, rowProps));
}
return doms;
});
}
renderItemActions() {
const {itemActions, render, store, classnames: cx} = this.props;
const finalActions = Array.isArray(itemActions)

View File

@ -117,10 +117,27 @@ export const Row = types
return data;
},
get expanded(): boolean {
get collapsed(): boolean {
const table = getParent(self, self.depth * 2) as ITableStore;
if (table.dragging) {
return true;
}
return !table.dragging && table.isExpanded(self as IRow);
let from: IRow = self as any;
while (from && (from as any) !== table) {
if (!table.isExpanded(from)) {
return true;
}
from = getParent(from, 2);
}
return false;
},
get expanded(): boolean {
return !this.collapsed;
},
get moved() {

View File

@ -164,20 +164,20 @@ function str2function(
function responseAdaptor(ret: fetcherResult) {
const data = ret.data;
let hasStatusField = true;
if (!data) {
throw new Error('Response is empty!');
} else if (!data.hasOwnProperty('status')) {
// 兼容不返回 status 字段的情况
data.status = 0;
hasStatusField = false;
}
const payload: Payload = {
ok: data.status == 0,
status: data.status,
ok: hasStatusField === false || data.status == 0,
status: hasStatusField === false ? 0 : data.status,
msg: data.msg,
msgTimeout: data.msgTimeout,
data: !data.data && !data.hasOwnProperty('status') ? data : data.data // 兼容直接返回数据的情况
data: !data.data && !hasStatusField ? data : data.data // 兼容直接返回数据的情况
};
if (payload.status == 422) {