mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-04 04:59:17 +08:00
Merge remote-tracking branch 'amis/master'
This commit is contained in:
commit
faf79f1073
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true,
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib"
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import Layout from '../../src/components/Layout';
|
|||||||
import AsideNav from '../../src/components/AsideNav';
|
import AsideNav from '../../src/components/AsideNav';
|
||||||
import {AlertComponent, ToastComponent} from '../../src/components/index';
|
import {AlertComponent, ToastComponent} from '../../src/components/index';
|
||||||
import {mapTree} from '../../src/utils/helper';
|
import {mapTree} from '../../src/utils/helper';
|
||||||
|
import '../../src/locale/en';
|
||||||
import {
|
import {
|
||||||
Router,
|
Router,
|
||||||
Route,
|
Route,
|
||||||
@ -560,6 +561,18 @@ const themes = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const locales = [
|
||||||
|
{
|
||||||
|
label: '默认',
|
||||||
|
value: 'zh-cn'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: 'English',
|
||||||
|
value: 'en'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
@withRouter
|
@withRouter
|
||||||
export class App extends React.PureComponent {
|
export class App extends React.PureComponent {
|
||||||
state = {
|
state = {
|
||||||
@ -568,7 +581,8 @@ export class App extends React.PureComponent {
|
|||||||
headerVisible: true,
|
headerVisible: true,
|
||||||
themeIndex: 0,
|
themeIndex: 0,
|
||||||
themes: themes,
|
themes: themes,
|
||||||
theme: themes[localStorage.getItem('themeIndex') || 0]
|
theme: themes[localStorage.getItem('themeIndex') || 0],
|
||||||
|
locale: localStorage.getItem('locale') || ''
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -767,10 +781,27 @@ export class App extends React.PureComponent {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="hidden-xs p-t-sm pull-right m-l-sm">
|
||||||
|
语言:
|
||||||
|
{
|
||||||
|
<Select
|
||||||
|
clearable={false}
|
||||||
|
theme={this.state.theme.value}
|
||||||
|
value={this.state.locale || 'zh-cn'}
|
||||||
|
options={locales}
|
||||||
|
onChange={locale => {
|
||||||
|
this.setState({locale: locale.value});
|
||||||
|
localStorage.setItem('locale', locale.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="hidden-xs p-t-sm pull-right">
|
<div className="hidden-xs p-t-sm pull-right">
|
||||||
主题:
|
主题:
|
||||||
{
|
{
|
||||||
<Select
|
<Select
|
||||||
|
clearable={false}
|
||||||
theme={this.state.theme.value}
|
theme={this.state.theme.value}
|
||||||
value={this.state.theme}
|
value={this.state.theme}
|
||||||
options={this.state.themes}
|
options={this.state.themes}
|
||||||
@ -802,14 +833,15 @@ export class App extends React.PureComponent {
|
|||||||
folded={this.state.asideFolded}
|
folded={this.state.asideFolded}
|
||||||
aside={this.renderAside()}
|
aside={this.renderAside()}
|
||||||
>
|
>
|
||||||
<ToastComponent theme={theme.value} />
|
<ToastComponent theme={theme.value} locale={this.state.locale} />
|
||||||
<AlertComponent theme={theme.value} />
|
<AlertComponent theme={theme.value} locale={this.state.locale} />
|
||||||
{React.cloneElement(this.props.children, {
|
{React.cloneElement(this.props.children, {
|
||||||
...this.props.children.props,
|
...this.props.children.props,
|
||||||
setAsideFolded: this.setAsideFolded,
|
setAsideFolded: this.setAsideFolded,
|
||||||
setHeaderVisible: this.setHeaderVisible,
|
setHeaderVisible: this.setHeaderVisible,
|
||||||
theme: theme.value,
|
theme: theme.value,
|
||||||
classPrefix: theme.ns
|
classPrefix: theme.ns,
|
||||||
|
locale: this.state.locale
|
||||||
})}
|
})}
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
@ -161,13 +161,14 @@ export default function (schema) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderSchema() {
|
renderSchema() {
|
||||||
const {router, location, theme} = this.props;
|
const {router, location, theme, locale} = this.props;
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
schema,
|
schema,
|
||||||
{
|
{
|
||||||
location,
|
location,
|
||||||
theme
|
theme,
|
||||||
|
locale
|
||||||
},
|
},
|
||||||
this.env
|
this.env
|
||||||
);
|
);
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
"@types/classnames": "^2.2.3",
|
"@types/classnames": "^2.2.3",
|
||||||
"@types/dom-helpers": "^3.4.1",
|
"@types/dom-helpers": "^3.4.1",
|
||||||
"@types/history": "^4.6.0",
|
"@types/history": "^4.6.0",
|
||||||
"@types/hoist-non-react-statics": "^3.0.1",
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
"@types/jest": "^24.0.11",
|
"@types/jest": "^24.0.11",
|
||||||
"@types/jquery": "^3.3.1",
|
"@types/jquery": "^3.3.1",
|
||||||
"@types/lodash": "^4.14.76",
|
"@types/lodash": "^4.14.76",
|
||||||
@ -89,7 +89,7 @@
|
|||||||
"@types/pretty-bytes": "^4.0.0",
|
"@types/pretty-bytes": "^4.0.0",
|
||||||
"@types/prop-types": "^15.5.2",
|
"@types/prop-types": "^15.5.2",
|
||||||
"@types/qs": "^6.5.1",
|
"@types/qs": "^6.5.1",
|
||||||
"@types/react": "^16.8.1",
|
"@types/react": "^16.9.35",
|
||||||
"@types/react-addons-update": "^0.14.19",
|
"@types/react-addons-update": "^0.14.19",
|
||||||
"@types/react-color": "^2.13.3",
|
"@types/react-color": "^2.13.3",
|
||||||
"@types/react-cropper": "^0.10.1",
|
"@types/react-cropper": "^0.10.1",
|
||||||
@ -139,7 +139,7 @@
|
|||||||
"react-testing-library": "6.0.4",
|
"react-testing-library": "6.0.4",
|
||||||
"strip-json-comments": "^2.0.1",
|
"strip-json-comments": "^2.0.1",
|
||||||
"ts-jest": "^24.0.0",
|
"ts-jest": "^24.0.0",
|
||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.3"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"testEnvironment": "jsdom",
|
"testEnvironment": "jsdom",
|
||||||
|
@ -11,7 +11,7 @@ rm -rf lib/node_modules
|
|||||||
rm -rf sdk && fis3 release publish-sdk -c
|
rm -rf sdk && fis3 release publish-sdk -c
|
||||||
|
|
||||||
# 生成 .d.ts 文件
|
# 生成 .d.ts 文件
|
||||||
tsc --allowJs --declaration
|
./node_modules/.bin/tsc --allowJs --declaration
|
||||||
|
|
||||||
cd output
|
cd output
|
||||||
|
|
||||||
|
@ -7,18 +7,16 @@ import React from 'react';
|
|||||||
import {render} from 'react-dom';
|
import {render} from 'react-dom';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface AlertProps {
|
export interface AlertProps extends ThemeProps, LocaleProps {
|
||||||
container?: any;
|
container?: any;
|
||||||
confirmText?: string;
|
confirmText?: string;
|
||||||
cancelText?: string;
|
cancelText?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
confirmBtnLevel?: string;
|
confirmBtnLevel?: string;
|
||||||
alertBtnLevel?: string;
|
alertBtnLevel?: string;
|
||||||
classPrefix: string;
|
|
||||||
classnames: ClassNamesFn;
|
|
||||||
theme?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AlertState {
|
export interface AlertState {
|
||||||
@ -37,7 +35,7 @@ export class Alert extends React.Component<AlertProps, AlertState> {
|
|||||||
const container = document.body;
|
const container = document.body;
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
container.appendChild(div);
|
container.appendChild(div);
|
||||||
render(<ThemedAlert />, div);
|
render(<FinnalAlert />, div);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Alert.instance;
|
return Alert.instance;
|
||||||
@ -150,6 +148,8 @@ export class Alert extends React.Component<AlertProps, AlertState> {
|
|||||||
classnames: cx,
|
classnames: cx,
|
||||||
classPrefix
|
classPrefix
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
show={this.state.show}
|
show={this.state.show}
|
||||||
@ -158,20 +158,22 @@ export class Alert extends React.Component<AlertProps, AlertState> {
|
|||||||
ref={this.modalRef}
|
ref={this.modalRef}
|
||||||
>
|
>
|
||||||
<div className={cx('Modal-header')}>
|
<div className={cx('Modal-header')}>
|
||||||
<div className={cx('Modal-title')}>{this.state.title || title}</div>
|
<div className={cx('Modal-title')}>
|
||||||
|
{__(this.state.title || title)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={cx('Modal-body')}>
|
<div className={cx('Modal-body')}>
|
||||||
<div ref={this.bodyRef} />
|
<div ref={this.bodyRef} />
|
||||||
</div>
|
</div>
|
||||||
<div className={cx('Modal-footer')}>
|
<div className={cx('Modal-footer')}>
|
||||||
{this.state.confirm ? (
|
{this.state.confirm ? (
|
||||||
<Button onClick={this.handleCancel}>{cancelText}</Button>
|
<Button onClick={this.handleCancel}>{__(cancelText)}</Button>
|
||||||
) : null}
|
) : null}
|
||||||
<Button
|
<Button
|
||||||
level={this.state.confirm ? confirmBtnLevel : alertBtnLevel}
|
level={this.state.confirm ? confirmBtnLevel : alertBtnLevel}
|
||||||
onClick={this.handleConfirm}
|
onClick={this.handleConfirm}
|
||||||
>
|
>
|
||||||
{this.state.confirmText || confirmText}
|
{__(this.state.confirmText || confirmText)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
@ -189,5 +191,5 @@ export const confirm: (
|
|||||||
confirmText?: string
|
confirmText?: string
|
||||||
) => Promise<any> = (content, title, confirmText) =>
|
) => Promise<any> = (content, title, confirmText) =>
|
||||||
Alert.getInstance().confirm(content, title, confirmText);
|
Alert.getInstance().confirm(content, title, confirmText);
|
||||||
export const ThemedAlert = themeable(Alert);
|
export const FinnalAlert = themeable(localeable(Alert));
|
||||||
export default ThemedAlert;
|
export default FinnalAlert;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {CheckboxesProps, Checkboxes} from './Checkboxes';
|
import {BaseCheckboxesProps, BaseCheckboxes} from './Checkboxes';
|
||||||
import {Options, Option} from './Select';
|
import {Options, Option} from './Select';
|
||||||
import ListMenu from './ListMenu';
|
import ListMenu from './ListMenu';
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
@ -19,8 +19,9 @@ import ChainedCheckboxes from './ChainedCheckboxes';
|
|||||||
import Spinner from './Spinner';
|
import Spinner from './Spinner';
|
||||||
import TreeRadios from './TreeRadios';
|
import TreeRadios from './TreeRadios';
|
||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
|
import {localeable} from '../locale';
|
||||||
|
|
||||||
export interface AssociatedCheckboxesProps extends CheckboxesProps {
|
export interface AssociatedCheckboxesProps extends BaseCheckboxesProps {
|
||||||
leftOptions: Options;
|
leftOptions: Options;
|
||||||
leftDefaultValue?: any;
|
leftDefaultValue?: any;
|
||||||
leftMode?: 'tree' | 'list';
|
leftMode?: 'tree' | 'list';
|
||||||
@ -42,7 +43,7 @@ export interface AssociatedCheckboxesState {
|
|||||||
leftValue?: Option;
|
leftValue?: Option;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AssociatedCheckboxes extends Checkboxes<
|
export class AssociatedCheckboxes extends BaseCheckboxes<
|
||||||
AssociatedCheckboxesProps,
|
AssociatedCheckboxesProps,
|
||||||
AssociatedCheckboxesState
|
AssociatedCheckboxesState
|
||||||
> {
|
> {
|
||||||
@ -58,7 +59,7 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||||||
const selectdOption = ListRadios.resolveSelected(
|
const selectdOption = ListRadios.resolveSelected(
|
||||||
leftValue,
|
leftValue,
|
||||||
options,
|
options,
|
||||||
option => option.ref
|
(option: Option) => option.ref
|
||||||
);
|
);
|
||||||
|
|
||||||
if (selectdOption && onDeferLoad && selectdOption.defer) {
|
if (selectdOption && onDeferLoad && selectdOption.defer) {
|
||||||
@ -80,7 +81,7 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||||||
const selectdOption = ListRadios.resolveSelected(
|
const selectdOption = ListRadios.resolveSelected(
|
||||||
value,
|
value,
|
||||||
options,
|
options,
|
||||||
option => option.ref
|
(option: Option) => option.ref
|
||||||
);
|
);
|
||||||
|
|
||||||
if (selectdOption && onDeferLoad && selectdOption.defer) {
|
if (selectdOption && onDeferLoad && selectdOption.defer) {
|
||||||
@ -111,8 +112,9 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||||||
const selectdOption = ListRadios.resolveSelected(
|
const selectdOption = ListRadios.resolveSelected(
|
||||||
this.state.leftValue,
|
this.state.leftValue,
|
||||||
options,
|
options,
|
||||||
option => option.ref
|
(option: Option) => option.ref
|
||||||
);
|
);
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('AssociatedCheckboxes', className)}>
|
<div className={cx('AssociatedCheckboxes', className)}>
|
||||||
@ -155,9 +157,9 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectdOption.loading ? (
|
{selectdOption.loading ? (
|
||||||
<p>加载中</p>
|
<p>{__('加载中')}</p>
|
||||||
) : (
|
) : (
|
||||||
<p>点击刷新重新加载</p>
|
<p>{__('点击刷新重新加载')}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : rightMode === 'table' ? (
|
) : rightMode === 'table' ? (
|
||||||
@ -193,12 +195,12 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('AssociatedCheckboxes-box')}>
|
<div className={cx('AssociatedCheckboxes-box')}>
|
||||||
配置错误,选项无法与左侧选项对应
|
{__('配置错误,选项无法与左侧选项对应')}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('AssociatedCheckboxes-box')}>
|
<div className={cx('AssociatedCheckboxes-box')}>
|
||||||
请先选择左侧数据
|
{__('请先选择左侧数据')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -208,7 +210,9 @@ export class AssociatedCheckboxes extends Checkboxes<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(AssociatedCheckboxes, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(AssociatedCheckboxes, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* 级联多选框,支持无限极。从左侧到右侧一层层点选。
|
* 级联多选框,支持无限极。从左侧到右侧一层层点选。
|
||||||
*/
|
*/
|
||||||
import {Checkboxes, CheckboxesProps} from './Checkboxes';
|
import {BaseCheckboxes, BaseCheckboxesProps} from './Checkboxes';
|
||||||
import {themeable} from '../theme';
|
import {themeable} from '../theme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
@ -10,8 +10,9 @@ import {Option} from './Select';
|
|||||||
import {getTreeDepth} from '../utils/helper';
|
import {getTreeDepth} from '../utils/helper';
|
||||||
import times from 'lodash/times';
|
import times from 'lodash/times';
|
||||||
import Spinner from './Spinner';
|
import Spinner from './Spinner';
|
||||||
|
import {localeable} from '../locale';
|
||||||
|
|
||||||
export interface ChainedCheckboxesProps extends CheckboxesProps {
|
export interface ChainedCheckboxesProps extends BaseCheckboxesProps {
|
||||||
defaultSelectedIndex?: string;
|
defaultSelectedIndex?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ export interface ChainedCheckboxesState {
|
|||||||
selected: Array<string>;
|
selected: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ChainedCheckboxes extends Checkboxes<
|
export class ChainedCheckboxes extends BaseCheckboxes<
|
||||||
ChainedCheckboxesProps,
|
ChainedCheckboxesProps,
|
||||||
ChainedCheckboxesState
|
ChainedCheckboxesState
|
||||||
> {
|
> {
|
||||||
@ -122,7 +123,7 @@ export class ChainedCheckboxes extends Checkboxes<
|
|||||||
itemRender
|
itemRender
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
this.valueArray = Checkboxes.value2array(value, options, option2value);
|
this.valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (Array.isArray(options) && options.length) {
|
if (Array.isArray(options) && options.length) {
|
||||||
@ -188,13 +189,15 @@ export class ChainedCheckboxes extends Checkboxes<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('ChainedCheckboxes', className)}>
|
<div className={cx('ChainedCheckboxes', className)}>
|
||||||
{body && body.length ? (
|
{body && body.length ? (
|
||||||
body
|
body
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('ChainedCheckboxes-placeholder')}>
|
<div className={cx('ChainedCheckboxes-placeholder')}>
|
||||||
{placeholder}
|
{__(placeholder)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -203,7 +206,9 @@ export class ChainedCheckboxes extends Checkboxes<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(ChainedCheckboxes, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(ChainedCheckboxes, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -13,9 +13,10 @@ import {Option, value2array, Options} from './Select';
|
|||||||
import find from 'lodash/find';
|
import find from 'lodash/find';
|
||||||
import {autobind, findTree} from '../utils/helper';
|
import {autobind, findTree} from '../utils/helper';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
// import isPlainObject from 'lodash/isPlainObject';
|
// import isPlainObject from 'lodash/isPlainObject';
|
||||||
|
|
||||||
export interface CheckboxesProps extends ThemeProps {
|
export interface BaseCheckboxesProps extends ThemeProps, LocaleProps {
|
||||||
options: Options;
|
options: Options;
|
||||||
className?: string;
|
className?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@ -31,8 +32,8 @@ export interface CheckboxesProps extends ThemeProps {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Checkboxes<
|
export class BaseCheckboxes<
|
||||||
T extends CheckboxesProps = CheckboxesProps,
|
T extends BaseCheckboxesProps = BaseCheckboxesProps,
|
||||||
S = any
|
S = any
|
||||||
> extends React.Component<T, S> {
|
> extends React.Component<T, S> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -68,7 +69,7 @@ export class Checkboxes<
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let valueArray = Checkboxes.value2array(value, options, option2value);
|
let valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
let idx = valueArray.indexOf(option);
|
let idx = valueArray.indexOf(option);
|
||||||
|
|
||||||
if (~idx) {
|
if (~idx) {
|
||||||
@ -115,7 +116,9 @@ export class Checkboxes<
|
|||||||
itemRender
|
itemRender
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let valueArray = Checkboxes.value2array(value, options, option2value);
|
const __ = this.props.translate;
|
||||||
|
|
||||||
|
let valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (Array.isArray(options) && options.length) {
|
if (Array.isArray(options) && options.length) {
|
||||||
@ -142,14 +145,18 @@ export class Checkboxes<
|
|||||||
inline ? 'Checkboxes--inline' : ''
|
inline ? 'Checkboxes--inline' : ''
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{body && body.length ? body : <div>{placeholder}</div>}
|
{body && body.length ? body : <div>{__(placeholder)}</div>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class Checkboxes extends BaseCheckboxes {}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(Checkboxes, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(Checkboxes, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -12,10 +12,11 @@ import {Icon} from './icons';
|
|||||||
import Overlay from './Overlay';
|
import Overlay from './Overlay';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
import PopOver from './PopOver';
|
import PopOver from './PopOver';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
|
import {localeable, LocaleProps} from '../locale';
|
||||||
|
|
||||||
export interface ColorProps {
|
export interface ColorProps extends LocaleProps, ThemeProps {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
format: string;
|
format: string;
|
||||||
// closeOnSelect:boolean;
|
// closeOnSelect:boolean;
|
||||||
@ -25,8 +26,6 @@ export interface ColorProps {
|
|||||||
popOverContainer?: any;
|
popOverContainer?: any;
|
||||||
placement?: string;
|
placement?: string;
|
||||||
value: any;
|
value: any;
|
||||||
classPrefix: string;
|
|
||||||
classnames: ClassNamesFn;
|
|
||||||
onChange: (value: any) => void;
|
onChange: (value: any) => void;
|
||||||
presetColors?: string[];
|
presetColors?: string[];
|
||||||
resetValue?: string;
|
resetValue?: string;
|
||||||
@ -219,6 +218,7 @@ export class ColorControl extends React.PureComponent<
|
|||||||
allowCustomColor
|
allowCustomColor
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const __ = this.props.translate;
|
||||||
const isOpened = this.state.isOpened;
|
const isOpened = this.state.isOpened;
|
||||||
const isFocused = this.state.isFocused;
|
const isFocused = this.state.isFocused;
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ export class ColorControl extends React.PureComponent<
|
|||||||
size={10}
|
size={10}
|
||||||
className={cx('ColorPicker-input')}
|
className={cx('ColorPicker-input')}
|
||||||
value={this.state.inputValue || ''}
|
value={this.state.inputValue || ''}
|
||||||
placeholder={placeholder}
|
placeholder={__(placeholder)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={this.handleInputChange}
|
onChange={this.handleInputChange}
|
||||||
onFocus={this.handleFocus}
|
onFocus={this.handleFocus}
|
||||||
@ -300,7 +300,9 @@ export class ColorControl extends React.PureComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(ColorControl, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(ColorControl, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -11,10 +11,11 @@ import 'moment/locale/zh-cn';
|
|||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
import PopOver from './PopOver';
|
import PopOver from './PopOver';
|
||||||
import Overlay from './Overlay';
|
import Overlay from './Overlay';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import {PlainObject} from '../types';
|
import {PlainObject} from '../types';
|
||||||
import Calendar from './calendar/Calendar';
|
import Calendar from './calendar/Calendar';
|
||||||
import 'react-datetime/css/react-datetime.css';
|
import 'react-datetime/css/react-datetime.css';
|
||||||
|
import {localeable, LocaleProps, TranslateFn} from '../locale';
|
||||||
|
|
||||||
const availableShortcuts: {[propName: string]: any} = {
|
const availableShortcuts: {[propName: string]: any} = {
|
||||||
now: {
|
now: {
|
||||||
@ -97,9 +98,9 @@ const availableShortcuts: {[propName: string]: any} = {
|
|||||||
const advancedShortcuts = [
|
const advancedShortcuts = [
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)hoursago$/,
|
regexp: /^(\d+)hoursago$/,
|
||||||
resolve: (_: string, hours: string) => {
|
resolve: (__: TranslateFn, _: string, hours: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${hours}小时前`,
|
label: __('{{hours}}小时前', {hours}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.subtract(hours, 'hours');
|
return now.subtract(hours, 'hours');
|
||||||
}
|
}
|
||||||
@ -108,9 +109,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)hourslater$/,
|
regexp: /^(\d+)hourslater$/,
|
||||||
resolve: (_: string, hours: string) => {
|
resolve: (__: TranslateFn, _: string, hours: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${hours}小时后`,
|
label: __('{{hours}}小时后', {hours}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.add(hours, 'hours');
|
return now.add(hours, 'hours');
|
||||||
}
|
}
|
||||||
@ -119,9 +120,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)daysago$/,
|
regexp: /^(\d+)daysago$/,
|
||||||
resolve: (_: string, days: string) => {
|
resolve: (__: TranslateFn, _: string, days: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${days}天前`,
|
label: __('{{days}}天前', {days}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.subtract(days, 'days');
|
return now.subtract(days, 'days');
|
||||||
}
|
}
|
||||||
@ -130,9 +131,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)dayslater$/,
|
regexp: /^(\d+)dayslater$/,
|
||||||
resolve: (_: string, days: string) => {
|
resolve: (__: TranslateFn, _: string, days: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${days}天后`,
|
label: __('{{days}}天后', {days}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.add(days, 'days');
|
return now.add(days, 'days');
|
||||||
}
|
}
|
||||||
@ -141,9 +142,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)weeksago$/,
|
regexp: /^(\d+)weeksago$/,
|
||||||
resolve: (_: string, weeks: string) => {
|
resolve: (__: TranslateFn, _: string, weeks: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${weeks}周前`,
|
label: __('{{weeks}}周前', {weeks}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.subtract(weeks, 'weeks');
|
return now.subtract(weeks, 'weeks');
|
||||||
}
|
}
|
||||||
@ -152,9 +153,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)weekslater$/,
|
regexp: /^(\d+)weekslater$/,
|
||||||
resolve: (_: string, weeks: string) => {
|
resolve: (__: TranslateFn, _: string, weeks: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${weeks}周后`,
|
label: __('{{weeks}}周后', {weeks}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.add(weeks, 'weeks');
|
return now.add(weeks, 'weeks');
|
||||||
}
|
}
|
||||||
@ -163,9 +164,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)monthsago$/,
|
regexp: /^(\d+)monthsago$/,
|
||||||
resolve: (_: string, months: string) => {
|
resolve: (__: TranslateFn, _: string, months: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${months}月前`,
|
label: __('{{months}}月前', {months}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.subtract(months, 'months');
|
return now.subtract(months, 'months');
|
||||||
}
|
}
|
||||||
@ -174,9 +175,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)monthslater$/,
|
regexp: /^(\d+)monthslater$/,
|
||||||
resolve: (_: string, months: string) => {
|
resolve: (__: TranslateFn, _: string, months: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${months}月后`,
|
label: __('{{months}}月后', {months}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.add(months, 'months');
|
return now.add(months, 'months');
|
||||||
}
|
}
|
||||||
@ -185,9 +186,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)quartersago$/,
|
regexp: /^(\d+)quartersago$/,
|
||||||
resolve: (_: string, quarters: string) => {
|
resolve: (__: TranslateFn, _: string, quarters: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${quarters}季度前`,
|
label: __('{{quarters}}季度前', {quarters}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.subtract(quarters, 'quarters');
|
return now.subtract(quarters, 'quarters');
|
||||||
}
|
}
|
||||||
@ -196,9 +197,9 @@ const advancedShortcuts = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
regexp: /^(\d+)quarterslater$/,
|
regexp: /^(\d+)quarterslater$/,
|
||||||
resolve: (_: string, quarters: string) => {
|
resolve: (__: TranslateFn, _: string, quarters: string) => {
|
||||||
return {
|
return {
|
||||||
label: `${quarters}季度后`,
|
label: __('{{quarters}}季度后', {quarters}),
|
||||||
date: (now: moment.Moment) => {
|
date: (now: moment.Moment) => {
|
||||||
return now.add(quarters, 'quarters');
|
return now.add(quarters, 'quarters');
|
||||||
}
|
}
|
||||||
@ -226,17 +227,15 @@ export type ShortCuts =
|
|||||||
| ShortCutDate
|
| ShortCutDate
|
||||||
| ShortCutDateRange;
|
| ShortCutDateRange;
|
||||||
|
|
||||||
export interface DateProps {
|
export interface DateProps extends LocaleProps, ThemeProps {
|
||||||
viewMode: 'years' | 'months' | 'days' | 'time';
|
viewMode: 'years' | 'months' | 'days' | 'time';
|
||||||
className?: string;
|
className?: string;
|
||||||
classPrefix: string;
|
|
||||||
classnames: ClassNamesFn;
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
inputFormat?: string;
|
inputFormat?: string;
|
||||||
timeFormat?: string;
|
timeFormat?: string;
|
||||||
format?: string;
|
format?: string;
|
||||||
timeConstrainst?: object;
|
timeConstrainst?: object;
|
||||||
closeOnSelect?: boolean;
|
closeOnSelect: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
minDate?: moment.Moment;
|
minDate?: moment.Moment;
|
||||||
maxDate?: moment.Moment;
|
maxDate?: moment.Moment;
|
||||||
@ -247,7 +246,14 @@ export interface DateProps {
|
|||||||
value: any;
|
value: any;
|
||||||
shortcuts: string | Array<ShortCuts>;
|
shortcuts: string | Array<ShortCuts>;
|
||||||
overlayPlacement: string;
|
overlayPlacement: string;
|
||||||
[propName: string]: any;
|
minTime?: moment.Moment;
|
||||||
|
maxTime?: moment.Moment;
|
||||||
|
dateFormat?: string;
|
||||||
|
timeConstraints?: any;
|
||||||
|
popOverContainer?: any;
|
||||||
|
|
||||||
|
// 下面那个千万不要写,写了就会导致 keyof DateProps 得到的结果是 string | number;
|
||||||
|
// [propName: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatePickerState {
|
export interface DatePickerState {
|
||||||
@ -257,11 +263,8 @@ export interface DatePickerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
||||||
static defaultProps: Pick<
|
static defaultProps = {
|
||||||
DateProps,
|
viewMode: 'days' as 'years' | 'months' | 'days' | 'time',
|
||||||
'viewMode' | 'shortcuts' | 'closeOnSelect' | 'overlayPlacement'
|
|
||||||
> = {
|
|
||||||
viewMode: 'days',
|
|
||||||
shortcuts: '',
|
shortcuts: '',
|
||||||
closeOnSelect: true,
|
closeOnSelect: true,
|
||||||
overlayPlacement: 'auto'
|
overlayPlacement: 'auto'
|
||||||
@ -429,12 +432,14 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
|||||||
return availableShortcuts[key];
|
return availableShortcuts[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
for (let i = 0, len = advancedShortcuts.length; i < len; i++) {
|
for (let i = 0, len = advancedShortcuts.length; i < len; i++) {
|
||||||
let item = advancedShortcuts[i];
|
let item = advancedShortcuts[i];
|
||||||
const m = item.regexp.exec(key);
|
const m = item.regexp.exec(key);
|
||||||
|
|
||||||
if (m) {
|
if (m) {
|
||||||
return item.resolve.apply(item, m);
|
return item.resolve.apply(item, [__, ...m]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,6 +457,8 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
|||||||
} else {
|
} else {
|
||||||
shortcutArr = shortcuts;
|
shortcutArr = shortcuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const __ = this.props.translate;
|
||||||
return (
|
return (
|
||||||
<ul className={`${ns}DatePicker-shortcuts`}>
|
<ul className={`${ns}DatePicker-shortcuts`}>
|
||||||
{shortcutArr.map(item => {
|
{shortcutArr.map(item => {
|
||||||
@ -474,7 +481,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
|||||||
onClick={() => this.selectRannge(shortcut)}
|
onClick={() => this.selectRannge(shortcut)}
|
||||||
key={shortcut.key || shortcut.label}
|
key={shortcut.key || shortcut.label}
|
||||||
>
|
>
|
||||||
<a>{shortcut.label}</a>
|
<a>{__(shortcut.label)}</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -498,9 +505,11 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
|||||||
clearable,
|
clearable,
|
||||||
shortcuts,
|
shortcuts,
|
||||||
utc,
|
utc,
|
||||||
overlayPlacement
|
overlayPlacement,
|
||||||
|
locale
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const __ = this.props.translate;
|
||||||
const isOpened = this.state.isOpened;
|
const isOpened = this.state.isOpened;
|
||||||
let date: moment.Moment | undefined = this.state.value;
|
let date: moment.Moment | undefined = this.state.value;
|
||||||
|
|
||||||
@ -526,7 +535,9 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
|||||||
{date.format(inputFormat)}
|
{date.format(inputFormat)}
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span className={`${ns}DatePicker-placeholder`}>{placeholder}</span>
|
<span className={`${ns}DatePicker-placeholder`}>
|
||||||
|
{__(placeholder)}
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{clearable && !disabled && value ? (
|
{clearable && !disabled && value ? (
|
||||||
@ -565,6 +576,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
|||||||
timeConstraints={timeConstraints}
|
timeConstraints={timeConstraints}
|
||||||
input={false}
|
input={false}
|
||||||
onClose={this.close}
|
onClose={this.close}
|
||||||
|
locale={locale}
|
||||||
// utc={utc}
|
// utc={utc}
|
||||||
/>
|
/>
|
||||||
</PopOver>
|
</PopOver>
|
||||||
@ -575,4 +587,4 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(DatePicker);
|
export default themeable(localeable(DatePicker));
|
||||||
|
@ -13,14 +13,13 @@ import Overlay from './Overlay';
|
|||||||
import {ShortCuts, ShortCutDateRange} from './DatePicker';
|
import {ShortCuts, ShortCutDateRange} from './DatePicker';
|
||||||
import Calendar from './calendar/Calendar';
|
import Calendar from './calendar/Calendar';
|
||||||
import PopOver from './PopOver';
|
import PopOver from './PopOver';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import {PlainObject} from '../types';
|
import {PlainObject} from '../types';
|
||||||
import {noop} from '../utils/helper';
|
import {noop} from '../utils/helper';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface DateRangePickerProps {
|
export interface DateRangePickerProps extends ThemeProps, LocaleProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
classPrefix: string;
|
|
||||||
classnames: ClassNamesFn;
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
theme?: any;
|
theme?: any;
|
||||||
format: string;
|
format: string;
|
||||||
@ -39,7 +38,10 @@ export interface DateRangePickerProps {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
closeOnSelect?: boolean;
|
closeOnSelect?: boolean;
|
||||||
overlayPlacement: string;
|
overlayPlacement: string;
|
||||||
[propName: string]: any;
|
timeFormat?: string;
|
||||||
|
resetValue?: any;
|
||||||
|
popOverContainer?: any;
|
||||||
|
dateFormat?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DateRangePickerState {
|
export interface DateRangePickerState {
|
||||||
@ -106,10 +108,7 @@ const availableRanges: {[propName: string]: any} = {
|
|||||||
return now.startOf('week').add(-1, 'weeks');
|
return now.startOf('week').add(-1, 'weeks');
|
||||||
},
|
},
|
||||||
endDate: (now: moment.Moment) => {
|
endDate: (now: moment.Moment) => {
|
||||||
return now
|
return now.startOf('week').add(-1, 'days').endOf('day');
|
||||||
.startOf('week')
|
|
||||||
.add(-1, 'days')
|
|
||||||
.endOf('day');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -129,10 +128,7 @@ const availableRanges: {[propName: string]: any} = {
|
|||||||
return now.startOf('month').add(-1, 'month');
|
return now.startOf('month').add(-1, 'month');
|
||||||
},
|
},
|
||||||
endDate: (now: moment.Moment) => {
|
endDate: (now: moment.Moment) => {
|
||||||
return now
|
return now.startOf('month').add(-1, 'day').endOf('day');
|
||||||
.startOf('month')
|
|
||||||
.add(-1, 'day')
|
|
||||||
.endOf('day');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -142,10 +138,7 @@ const availableRanges: {[propName: string]: any} = {
|
|||||||
return now.startOf('quarter').add(-1, 'quarter');
|
return now.startOf('quarter').add(-1, 'quarter');
|
||||||
},
|
},
|
||||||
endDate: (now: moment.Moment) => {
|
endDate: (now: moment.Moment) => {
|
||||||
return now
|
return now.startOf('quarter').add(-1, 'day').endOf('day');
|
||||||
.startOf('quarter')
|
|
||||||
.add(-1, 'day')
|
|
||||||
.endOf('day');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -416,6 +409,8 @@ export class DateRangePicker extends React.Component<
|
|||||||
} else {
|
} else {
|
||||||
rangeArr = ranges;
|
rangeArr = ranges;
|
||||||
}
|
}
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul className={`${ns}DateRangePicker-rangers`}>
|
<ul className={`${ns}DateRangePicker-rangers`}>
|
||||||
{rangeArr.map(item => {
|
{rangeArr.map(item => {
|
||||||
@ -442,7 +437,7 @@ export class DateRangePicker extends React.Component<
|
|||||||
onClick={() => this.selectRannge(range)}
|
onClick={() => this.selectRannge(range)}
|
||||||
key={range.key || range.label}
|
key={range.key || range.label}
|
||||||
>
|
>
|
||||||
<a>{range.label}</a>
|
<a>{__(range.label)}</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -551,6 +546,7 @@ export class DateRangePicker extends React.Component<
|
|||||||
const arr = [];
|
const arr = [];
|
||||||
startViewValue && arr.push(startViewValue);
|
startViewValue && arr.push(startViewValue);
|
||||||
endViewValue && arr.push(endViewValue);
|
endViewValue && arr.push(endViewValue);
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -571,11 +567,11 @@ export class DateRangePicker extends React.Component<
|
|||||||
>
|
>
|
||||||
{arr.length ? (
|
{arr.length ? (
|
||||||
<span className={`${ns}DateRangePicker-value`}>
|
<span className={`${ns}DateRangePicker-value`}>
|
||||||
{arr.join(' 至 ')}
|
{arr.join(__(' 至 '))}
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span className={`${ns}DateRangePicker-placeholder`}>
|
<span className={`${ns}DateRangePicker-placeholder`}>
|
||||||
{placeholder}
|
{__(placeholder)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -646,10 +642,10 @@ export class DateRangePicker extends React.Component<
|
|||||||
})}
|
})}
|
||||||
onClick={this.confirm}
|
onClick={this.confirm}
|
||||||
>
|
>
|
||||||
确认
|
{__('确认')}
|
||||||
</a>
|
</a>
|
||||||
<a className="rdtBtn rdtBtnCancel" onClick={this.close}>
|
<a className="rdtBtn rdtBtnCancel" onClick={this.close}>
|
||||||
取消
|
{__('取消')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -661,4 +657,4 @@ export class DateRangePicker extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(DateRangePicker);
|
export default themeable(localeable(DateRangePicker));
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {themeable, ClassNamesFn} from '../theme';
|
import {themeable, ClassNamesFn, ThemeProps} from '../theme';
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface ImageGalleryProps {
|
export interface ImageGalleryProps extends ThemeProps, LocaleProps {
|
||||||
classnames: ClassNamesFn;
|
|
||||||
classPrefix: string;
|
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
modalContainer?: () => HTMLElement;
|
modalContainer?: () => HTMLElement;
|
||||||
}
|
}
|
||||||
@ -87,6 +86,7 @@ export class ImageGallery extends React.Component<
|
|||||||
render() {
|
render() {
|
||||||
const {children, classnames: cx, modalContainer} = this.props;
|
const {children, classnames: cx, modalContainer} = this.props;
|
||||||
const {index, items} = this.state;
|
const {index, items} = this.state;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -103,7 +103,7 @@ export class ImageGallery extends React.Component<
|
|||||||
container={modalContainer}
|
container={modalContainer}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
data-tooltip="关闭"
|
data-tooltip={__('关闭')}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
className={cx('ImageGallery-close')}
|
className={cx('ImageGallery-close')}
|
||||||
onClick={this.close}
|
onClick={this.close}
|
||||||
@ -176,4 +176,4 @@ export class ImageGallery extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(ImageGallery);
|
export default themeable(localeable(ImageGallery));
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import {Checkboxes} from './Checkboxes';
|
import {BaseCheckboxes} from './Checkboxes';
|
||||||
import {themeable} from '../theme';
|
import {themeable} from '../theme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox from './Checkbox';
|
||||||
import {Option} from './Select';
|
import {Option} from './Select';
|
||||||
|
import {localeable} from '../locale';
|
||||||
|
|
||||||
export class ListCheckboxes extends Checkboxes {
|
export class ListCheckboxes extends BaseCheckboxes {
|
||||||
valueArray: Array<Option>;
|
valueArray: Array<Option>;
|
||||||
|
|
||||||
renderOption(option: Option, index: number) {
|
renderOption(option: Option, index: number) {
|
||||||
@ -72,8 +73,9 @@ export class ListCheckboxes extends Checkboxes {
|
|||||||
classnames: cx,
|
classnames: cx,
|
||||||
option2value
|
option2value
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
this.valueArray = Checkboxes.value2array(value, options, option2value);
|
this.valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (Array.isArray(options) && options.length) {
|
if (Array.isArray(options) && options.length) {
|
||||||
@ -85,7 +87,9 @@ export class ListCheckboxes extends Checkboxes {
|
|||||||
{body && body.length ? (
|
{body && body.length ? (
|
||||||
body
|
body
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('ListCheckboxes-placeholder')}>{placeholder}</div>
|
<div className={cx('ListCheckboxes-placeholder')}>
|
||||||
|
{__(placeholder)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -93,7 +97,9 @@ export class ListCheckboxes extends Checkboxes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(ListCheckboxes, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(ListCheckboxes, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import {ThemeProps, themeable} from '../theme';
|
import {ThemeProps, themeable} from '../theme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Options, Option} from './Select';
|
import {Options, Option} from './Select';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface ListMenuProps extends ThemeProps {
|
export interface ListMenuProps extends ThemeProps, LocaleProps {
|
||||||
options: Options;
|
options: Options;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
selectedOptions?: Options;
|
selectedOptions?: Options;
|
||||||
@ -85,6 +86,8 @@ export class ListMenu extends React.Component<ListMenuProps> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {classnames: cx, options, placeholder, prefix, children} = this.props;
|
const {classnames: cx, options, placeholder, prefix, children} = this.props;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('ListMenu')}>
|
<div className={cx('ListMenu')}>
|
||||||
{prefix}
|
{prefix}
|
||||||
@ -98,7 +101,7 @@ export class ListMenu extends React.Component<ListMenuProps> {
|
|||||||
}
|
}
|
||||||
).items
|
).items
|
||||||
) : (
|
) : (
|
||||||
<span className={cx('ListMenu-placeholder')}>{placeholder}</span>
|
<span className={cx('ListMenu-placeholder')}>{__(placeholder)}</span>
|
||||||
)}
|
)}
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
@ -106,4 +109,4 @@ export class ListMenu extends React.Component<ListMenuProps> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(ListMenu);
|
export default themeable(localeable(ListMenu));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Checkboxes} from './Checkboxes';
|
import {BaseCheckboxes} from './Checkboxes';
|
||||||
import {themeable, ThemeProps} from '../theme';
|
import {themeable, ThemeProps} from '../theme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
@ -6,8 +6,9 @@ import Checkbox from './Checkbox';
|
|||||||
import {Option, Options} from './Select';
|
import {Option, Options} from './Select';
|
||||||
import {findTree, autobind} from '../utils/helper';
|
import {findTree, autobind} from '../utils/helper';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface ListRadiosProps extends ThemeProps {
|
export interface BaseRadiosProps extends ThemeProps, LocaleProps {
|
||||||
options: Options;
|
options: Options;
|
||||||
className?: string;
|
className?: string;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
@ -22,9 +23,9 @@ export interface ListRadiosProps extends ThemeProps {
|
|||||||
showRadio?: boolean;
|
showRadio?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ListRadios<
|
export class BaseRadios<
|
||||||
T extends ListRadiosProps = ListRadiosProps,
|
T extends BaseRadiosProps = BaseRadiosProps,
|
||||||
S = any
|
S = {}
|
||||||
> extends React.Component<T, S> {
|
> extends React.Component<T, S> {
|
||||||
selected: Option | undefined | null;
|
selected: Option | undefined | null;
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ export class ListRadios<
|
|||||||
let newValue: Option | null = option;
|
let newValue: Option | null = option;
|
||||||
|
|
||||||
if (clearable) {
|
if (clearable) {
|
||||||
const prevSelected = ListRadios.resolveSelected(
|
const prevSelected = BaseRadios.resolveSelected(
|
||||||
value,
|
value,
|
||||||
options,
|
options,
|
||||||
option2value
|
option2value
|
||||||
@ -120,8 +121,9 @@ export class ListRadios<
|
|||||||
classnames: cx,
|
classnames: cx,
|
||||||
option2value
|
option2value
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
this.selected = ListRadios.resolveSelected(value, options, option2value);
|
this.selected = BaseRadios.resolveSelected(value, options, option2value);
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (Array.isArray(options) && options.length) {
|
if (Array.isArray(options) && options.length) {
|
||||||
@ -133,19 +135,23 @@ export class ListRadios<
|
|||||||
{body && body.length ? (
|
{body && body.length ? (
|
||||||
body
|
body
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('ListRadios-placeholder')}>{placeholder}</div>
|
<div className={cx('ListRadios-placeholder')}>{__(placeholder)}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ListRadios extends BaseRadios {}
|
||||||
|
|
||||||
const themedListRadios = themeable(
|
const themedListRadios = themeable(
|
||||||
uncontrollable(ListRadios, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(ListRadios, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
themedListRadios.resolveSelected = ListRadios.resolveSelected;
|
themedListRadios.resolveSelected = BaseRadios.resolveSelected;
|
||||||
|
|
||||||
export default themedListRadios;
|
export default themedListRadios;
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {themeable, ClassNamesFn} from '../theme';
|
import {themeable, ClassNamesFn, ThemeProps} from '../theme';
|
||||||
import Overlay from './Overlay';
|
import Overlay from './Overlay';
|
||||||
import PopOver from './PopOver';
|
import PopOver from './PopOver';
|
||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
import Alert2 from './Alert2';
|
import Alert2 from './Alert2';
|
||||||
import BaiduMapPicker from './BaiduMapPicker';
|
import BaiduMapPicker from './BaiduMapPicker';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface LocationProps {
|
export interface LocationProps extends ThemeProps, LocaleProps {
|
||||||
vendor: 'baidu' | 'gaode' | 'tenxun';
|
vendor: 'baidu' | 'gaode' | 'tenxun';
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
clearable: boolean;
|
clearable: boolean;
|
||||||
@ -21,8 +22,6 @@ export interface LocationProps {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
onChange: (value: any) => void;
|
onChange: (value: any) => void;
|
||||||
classnames: ClassNamesFn;
|
|
||||||
classPrefix: string;
|
|
||||||
popOverContainer?: any;
|
popOverContainer?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +136,7 @@ export class LocationPicker extends React.Component<
|
|||||||
vendor,
|
vendor,
|
||||||
ak
|
ak
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const __ = this.props.translate;
|
||||||
const {isFocused, isOpened} = this.state;
|
const {isFocused, isOpened} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -161,7 +161,7 @@ export class LocationPicker extends React.Component<
|
|||||||
<span className={cx('LocationPicker-value')}>{value.address}</span>
|
<span className={cx('LocationPicker-value')}>{value.address}</span>
|
||||||
) : (
|
) : (
|
||||||
<span className={cx('LocationPicker-placeholder')}>
|
<span className={cx('LocationPicker-placeholder')}>
|
||||||
{placeholder}
|
{__(placeholder)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -189,8 +189,14 @@ export class LocationPicker extends React.Component<
|
|||||||
style={{width: this.getTarget()?.offsetWidth}}
|
style={{width: this.getTarget()?.offsetWidth}}
|
||||||
>
|
>
|
||||||
{vendor === 'baidu' ? (
|
{vendor === 'baidu' ? (
|
||||||
<BaiduMapPicker ak={ak} value={value} onChange={this.handleChange} />
|
<BaiduMapPicker
|
||||||
) : (<Alert2>{vendor} 地图控件不支持</Alert2>)}
|
ak={ak}
|
||||||
|
value={value}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Alert2>{__('${vendor} 地图控件不支持', {vendor})}</Alert2>
|
||||||
|
)}
|
||||||
</PopOver>
|
</PopOver>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
</div>
|
</div>
|
||||||
@ -198,5 +204,5 @@ export class LocationPicker extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThemedCity = themeable(LocationPicker);
|
const ThemedCity = themeable(localeable(LocationPicker));
|
||||||
export default ThemedCity;
|
export default ThemedCity;
|
||||||
|
@ -14,8 +14,9 @@ import {Portal} from 'react-overlays';
|
|||||||
import {current, addModal, removeModal} from './ModalManager';
|
import {current, addModal, removeModal} from './ModalManager';
|
||||||
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface ModalProps extends ThemeProps {
|
export interface ModalProps extends ThemeProps, LocaleProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
contentClassName?: string;
|
contentClassName?: string;
|
||||||
size?: any;
|
size?: any;
|
||||||
@ -44,33 +45,37 @@ export class Modal extends React.Component<ModalProps, ModalState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static Header = themeable(
|
static Header = themeable(
|
||||||
({
|
localeable(
|
||||||
classnames: cx,
|
({
|
||||||
className,
|
classnames: cx,
|
||||||
showCloseButton,
|
className,
|
||||||
onClose,
|
showCloseButton,
|
||||||
children,
|
onClose,
|
||||||
classPrefix,
|
children,
|
||||||
...rest
|
classPrefix,
|
||||||
}: ThemeProps & {
|
translate: __,
|
||||||
className?: string;
|
...rest
|
||||||
showCloseButton?: boolean;
|
}: ThemeProps &
|
||||||
onClose?: () => void;
|
LocaleProps & {
|
||||||
children?: React.ReactNode;
|
className?: string;
|
||||||
} & React.HTMLAttributes<HTMLDivElement>) => (
|
showCloseButton?: boolean;
|
||||||
<div {...rest} className={cx('Modal-header', className)}>
|
onClose?: () => void;
|
||||||
{showCloseButton !== false ? (
|
children?: React.ReactNode;
|
||||||
<a
|
} & React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
data-tooltip="关闭弹窗"
|
<div {...rest} className={cx('Modal-header', className)}>
|
||||||
data-position="left"
|
{showCloseButton !== false ? (
|
||||||
onClick={onClose}
|
<a
|
||||||
className={cx('Modal-close')}
|
data-tooltip={__('关闭弹窗')}
|
||||||
>
|
data-position="left"
|
||||||
<Icon icon="close" className="icon" />
|
onClick={onClose}
|
||||||
</a>
|
className={cx('Modal-close')}
|
||||||
) : null}
|
>
|
||||||
{children}
|
<Icon icon="close" className="icon" />
|
||||||
</div>
|
</a>
|
||||||
|
) : null}
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -216,9 +221,9 @@ export class Modal extends React.Component<ModalProps, ModalState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const themedModal = themeable(Modal);
|
const FinalModal = themeable(localeable(Modal));
|
||||||
|
|
||||||
export default themedModal as typeof themedModal & {
|
export default FinalModal as typeof FinalModal & {
|
||||||
Header: typeof Modal.Header;
|
Header: typeof Modal.Header;
|
||||||
Title: typeof Modal.Title;
|
Title: typeof Modal.Title;
|
||||||
Body: typeof Modal.Body;
|
Body: typeof Modal.Body;
|
||||||
|
@ -5,10 +5,12 @@ import uncontrollable from 'uncontrollable';
|
|||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface ResultBoxProps
|
export interface ResultBoxProps
|
||||||
extends ThemeProps,
|
extends ThemeProps,
|
||||||
Omit<InputBoxProps, 'result' | 'prefix' | 'onChange'> {
|
LocaleProps,
|
||||||
|
Omit<InputBoxProps, 'result' | 'prefix' | 'onChange' | 'translate'> {
|
||||||
onChange?: (value: string) => void;
|
onChange?: (value: string) => void;
|
||||||
onResultClick?: (e: React.MouseEvent<HTMLElement>) => void;
|
onResultClick?: (e: React.MouseEvent<HTMLElement>) => void;
|
||||||
result?: Array<any>;
|
result?: Array<any>;
|
||||||
@ -96,6 +98,8 @@ export class ResultBox extends React.Component<ResultBoxProps> {
|
|||||||
onResultChange,
|
onResultChange,
|
||||||
onChange,
|
onChange,
|
||||||
onResultClick,
|
onResultClick,
|
||||||
|
translate: __,
|
||||||
|
locale,
|
||||||
...rest
|
...rest
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const isFocused = this.state.isFocused;
|
const isFocused = this.state.isFocused;
|
||||||
@ -124,7 +128,7 @@ export class ResultBox extends React.Component<ResultBoxProps> {
|
|||||||
))
|
))
|
||||||
) : allowInput ? null : (
|
) : allowInput ? null : (
|
||||||
<span className={cx('ResultBox-placeholder')}>
|
<span className={cx('ResultBox-placeholder')}>
|
||||||
{placeholder || '无'}
|
{__(placeholder || '无')}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -163,8 +167,10 @@ export class ResultBox extends React.Component<ResultBoxProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(ResultBox, {
|
localeable(
|
||||||
value: 'onChange',
|
uncontrollable(ResultBox, {
|
||||||
result: 'onResultChange'
|
value: 'onChange',
|
||||||
})
|
result: 'onResultChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -8,8 +8,9 @@ import {Icon} from './icons';
|
|||||||
import {autobind, guid} from '../utils/helper';
|
import {autobind, guid} from '../utils/helper';
|
||||||
import Sortable from 'sortablejs';
|
import Sortable from 'sortablejs';
|
||||||
import {findDOMNode} from 'react-dom';
|
import {findDOMNode} from 'react-dom';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface ResultListProps extends ThemeProps {
|
export interface ResultListProps extends ThemeProps, LocaleProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
value?: Array<Option>;
|
value?: Array<Option>;
|
||||||
onChange?: (value: Array<Option>) => void;
|
onChange?: (value: Array<Option>) => void;
|
||||||
@ -123,7 +124,8 @@ export class ResultList extends React.Component<ResultListProps> {
|
|||||||
disabled,
|
disabled,
|
||||||
title,
|
title,
|
||||||
itemClassName,
|
itemClassName,
|
||||||
sortable
|
sortable,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -163,11 +165,11 @@ export class ResultList extends React.Component<ResultListProps> {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('Selections-placeholder')}>{placeholder}</div>
|
<div className={cx('Selections-placeholder')}>{__(placeholder)}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(ResultList);
|
export default themeable(localeable(ResultList));
|
||||||
|
@ -3,8 +3,9 @@ import {ThemeProps, themeable} from '../theme';
|
|||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface SearchBoxProps extends ThemeProps {
|
export interface SearchBoxProps extends ThemeProps, LocaleProps {
|
||||||
name?: string;
|
name?: string;
|
||||||
onChange?: (text: string) => void;
|
onChange?: (text: string) => void;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@ -47,7 +48,8 @@ export class SearchBox extends React.Component<SearchBoxProps> {
|
|||||||
active,
|
active,
|
||||||
name,
|
name,
|
||||||
onChange,
|
onChange,
|
||||||
placeholder
|
placeholder,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -56,7 +58,7 @@ export class SearchBox extends React.Component<SearchBoxProps> {
|
|||||||
name={name}
|
name={name}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
value={value || ''}
|
value={value || ''}
|
||||||
placeholder={placeholder || '输入关键字'}
|
placeholder={__(placeholder || '输入关键字')}
|
||||||
ref={this.inputRef}
|
ref={this.inputRef}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -75,8 +77,10 @@ export class SearchBox extends React.Component<SearchBoxProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(SearchBox, {
|
localeable(
|
||||||
active: 'onActiveChange',
|
uncontrollable(SearchBox, {
|
||||||
value: 'onChange'
|
active: 'onActiveChange',
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -19,10 +19,11 @@ import isPlainObject from 'lodash/isPlainObject';
|
|||||||
import union from 'lodash/union';
|
import union from 'lodash/union';
|
||||||
import {highlight} from '../renderers/Form/Options';
|
import {highlight} from '../renderers/Form/Options';
|
||||||
import {findDOMNode} from 'react-dom';
|
import {findDOMNode} from 'react-dom';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox from './Checkbox';
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
import {Api} from '../types';
|
import {Api} from '../types';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface Option {
|
export interface Option {
|
||||||
label?: string;
|
label?: string;
|
||||||
@ -273,9 +274,7 @@ export function normalizeOptions(
|
|||||||
|
|
||||||
const DownshiftChangeTypes = Downshift.stateChangeTypes;
|
const DownshiftChangeTypes = Downshift.stateChangeTypes;
|
||||||
|
|
||||||
interface SelectProps extends OptionProps {
|
interface SelectProps extends OptionProps, ThemeProps, LocaleProps {
|
||||||
classPrefix: string;
|
|
||||||
classnames: ClassNamesFn;
|
|
||||||
className?: string;
|
className?: string;
|
||||||
creatable: boolean;
|
creatable: boolean;
|
||||||
createBtnLabel: string;
|
createBtnLabel: string;
|
||||||
@ -629,7 +628,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
|||||||
placeholder,
|
placeholder,
|
||||||
classPrefix: ns,
|
classPrefix: ns,
|
||||||
labelField,
|
labelField,
|
||||||
disabled
|
disabled,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const selection = this.state.selection;
|
const selection = this.state.selection;
|
||||||
@ -638,7 +638,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
|||||||
if (!selection.length) {
|
if (!selection.length) {
|
||||||
return (
|
return (
|
||||||
<div key="placeholder" className={`${ns}Select-placeholder`}>
|
<div key="placeholder" className={`${ns}Select-placeholder`}>
|
||||||
{placeholder}
|
{__(placeholder)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -693,7 +693,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
|||||||
searchPromptText,
|
searchPromptText,
|
||||||
editable,
|
editable,
|
||||||
removable,
|
removable,
|
||||||
overlayPlacement
|
overlayPlacement,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const {selection} = this.state;
|
const {selection} = this.state;
|
||||||
|
|
||||||
@ -732,7 +733,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
|||||||
onFocus: this.onFocus,
|
onFocus: this.onFocus,
|
||||||
onBlur: this.onBlur,
|
onBlur: this.onBlur,
|
||||||
disabled: disabled,
|
disabled: disabled,
|
||||||
placeholder: searchPromptText,
|
placeholder: __(searchPromptText),
|
||||||
onChange: this.handleInputChange,
|
onChange: this.handleInputChange,
|
||||||
ref: this.inputRef
|
ref: this.inputRef
|
||||||
})}
|
})}
|
||||||
@ -747,7 +748,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
|||||||
partial={checkedPartial && !checkedAll}
|
partial={checkedPartial && !checkedAll}
|
||||||
onChange={this.toggleCheckAll}
|
onChange={this.toggleCheckAll}
|
||||||
>
|
>
|
||||||
{checkAllLabel}
|
{__(checkAllLabel)}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
@ -830,13 +831,13 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('Select-noResult')}>{noResultsText}</div>
|
<div className={cx('Select-noResult')}>{__(noResultsText)}</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{creatable && !disabled ? (
|
{creatable && !disabled ? (
|
||||||
<a className={cx('Select-addBtn')} onClick={this.handleAddClick}>
|
<a className={cx('Select-addBtn')} onClick={this.handleAddClick}>
|
||||||
<Icon icon="plus" className="icon" />
|
<Icon icon="plus" className="icon" />
|
||||||
{createBtnLabel}
|
{__(createBtnLabel)}
|
||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@ -942,7 +943,9 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(Select, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(Select, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import {Checkboxes, CheckboxesProps} from './Checkboxes';
|
import {BaseCheckboxes, BaseCheckboxesProps} from './Checkboxes';
|
||||||
import {themeable} from '../theme';
|
import {themeable} from '../theme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox from './Checkbox';
|
||||||
import {Option} from './Select';
|
import {Option} from './Select';
|
||||||
import {resolveVariable} from '../utils/tpl-builtin';
|
import {resolveVariable} from '../utils/tpl-builtin';
|
||||||
|
import {localeable} from '../locale';
|
||||||
|
|
||||||
export interface TableCheckboxesProps extends CheckboxesProps {
|
export interface TableCheckboxesProps extends BaseCheckboxesProps {
|
||||||
columns: Array<{
|
columns: Array<{
|
||||||
name: string;
|
name: string;
|
||||||
label: string;
|
label: string;
|
||||||
@ -24,9 +25,9 @@ export interface TableCheckboxesProps extends CheckboxesProps {
|
|||||||
) => JSX.Element;
|
) => JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TableCheckboxes extends Checkboxes<TableCheckboxesProps> {
|
export class TableCheckboxes extends BaseCheckboxes<TableCheckboxesProps> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
...Checkboxes.defaultProps,
|
...BaseCheckboxes.defaultProps,
|
||||||
cellRender: (
|
cellRender: (
|
||||||
column: {
|
column: {
|
||||||
name: string;
|
name: string;
|
||||||
@ -51,7 +52,7 @@ export class TableCheckboxes extends Checkboxes<TableCheckboxesProps> {
|
|||||||
renderTHead() {
|
renderTHead() {
|
||||||
const {options, classnames: cx, value, option2value} = this.props;
|
const {options, classnames: cx, value, option2value} = this.props;
|
||||||
let columns = this.getColumns();
|
let columns = this.getColumns();
|
||||||
let valueArray = Checkboxes.value2array(value, options, option2value);
|
let valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
const availableOptions = options.filter(option => !option.disabled);
|
const availableOptions = options.filter(option => !option.disabled);
|
||||||
let partialChecked = false;
|
let partialChecked = false;
|
||||||
let allChecked = !!availableOptions.length;
|
let allChecked = !!availableOptions.length;
|
||||||
@ -94,10 +95,11 @@ export class TableCheckboxes extends Checkboxes<TableCheckboxesProps> {
|
|||||||
classnames: cx,
|
classnames: cx,
|
||||||
cellRender,
|
cellRender,
|
||||||
value,
|
value,
|
||||||
option2value
|
option2value,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const columns = this.getColumns();
|
const columns = this.getColumns();
|
||||||
let valueArray = Checkboxes.value2array(value, options, option2value);
|
let valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -123,7 +125,7 @@ export class TableCheckboxes extends Checkboxes<TableCheckboxesProps> {
|
|||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={columns.length}>{placeholder}</td>
|
<td colSpan={columns.length}>{__(placeholder)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -143,7 +145,7 @@ export class TableCheckboxes extends Checkboxes<TableCheckboxesProps> {
|
|||||||
itemRender
|
itemRender
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let valueArray = Checkboxes.value2array(value, options, option2value);
|
let valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (Array.isArray(options) && options.length) {
|
if (Array.isArray(options) && options.length) {
|
||||||
@ -187,7 +189,9 @@ export class TableCheckboxes extends Checkboxes<TableCheckboxesProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(TableCheckboxes, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(TableCheckboxes, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -10,6 +10,7 @@ import {Options, Option} from './Select';
|
|||||||
import Transfer, {TransferProps} from './Transfer';
|
import Transfer, {TransferProps} from './Transfer';
|
||||||
import {themeable} from '../theme';
|
import {themeable} from '../theme';
|
||||||
import AssociatedCheckboxes from './AssociatedCheckboxes';
|
import AssociatedCheckboxes from './AssociatedCheckboxes';
|
||||||
|
import {localeable} from '../locale';
|
||||||
|
|
||||||
export interface TabsTransferProps
|
export interface TabsTransferProps
|
||||||
extends Omit<
|
extends Omit<
|
||||||
@ -101,13 +102,14 @@ export class TabsTransfer extends React.Component<TabsTransferProps> {
|
|||||||
onSearch: searchable,
|
onSearch: searchable,
|
||||||
option2value,
|
option2value,
|
||||||
onDeferLoad,
|
onDeferLoad,
|
||||||
cellRender
|
cellRender,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!Array.isArray(options) || !options.length) {
|
if (!Array.isArray(options) || !options.length) {
|
||||||
return (
|
return (
|
||||||
<div className={cx('TabsTransfer-placeholder')}>
|
<div className={cx('TabsTransfer-placeholder')}>
|
||||||
{placeholder || '暂无可选项'}
|
{__(placeholder || '暂无选项')}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -128,7 +130,7 @@ export class TabsTransfer extends React.Component<TabsTransferProps> {
|
|||||||
>
|
>
|
||||||
{searchResult !== null
|
{searchResult !== null
|
||||||
? [
|
? [
|
||||||
<Tab title="搜索结果" key={0} eventKey={0}>
|
<Tab title={__('搜索结果')} key={0} eventKey={0}>
|
||||||
{this.renderSearchResult(searchResult)}
|
{this.renderSearchResult(searchResult)}
|
||||||
</Tab>
|
</Tab>
|
||||||
]
|
]
|
||||||
@ -210,4 +212,4 @@ export class TabsTransfer extends React.Component<TabsTransferProps> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(TabsTransfer);
|
export default themeable(localeable(TabsTransfer));
|
||||||
|
@ -35,8 +35,9 @@ import 'tinymce/plugins/template';
|
|||||||
import 'tinymce/plugins/nonbreaking';
|
import 'tinymce/plugins/nonbreaking';
|
||||||
import 'tinymce/plugins/emoticons';
|
import 'tinymce/plugins/emoticons';
|
||||||
import 'tinymce/plugins/emoticons/js/emojis';
|
import 'tinymce/plugins/emoticons/js/emojis';
|
||||||
|
import {LocaleProps} from '../locale';
|
||||||
|
|
||||||
interface TinymceEditorProps {
|
interface TinymceEditorProps extends LocaleProps {
|
||||||
model: string;
|
model: string;
|
||||||
onModelChange?: (value: string) => void;
|
onModelChange?: (value: string) => void;
|
||||||
onFocus?: () => void;
|
onFocus?: () => void;
|
||||||
@ -58,12 +59,14 @@ export default class TinymceEditor extends React.Component<TinymceEditorProps> {
|
|||||||
elementRef: React.RefObject<HTMLTextAreaElement> = React.createRef();
|
elementRef: React.RefObject<HTMLTextAreaElement> = React.createRef();
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
const locale = this.props.locale;
|
||||||
|
|
||||||
this.config = {
|
this.config = {
|
||||||
inline: false,
|
inline: false,
|
||||||
skin: false,
|
skin: false,
|
||||||
content_css: false,
|
content_css: false,
|
||||||
height: 400,
|
height: 400,
|
||||||
language: 'zh_CN',
|
language: !locale || locale === 'zh-cn' ? 'zh_CN' : 'en',
|
||||||
plugins: [
|
plugins: [
|
||||||
'advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker',
|
'advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker',
|
||||||
'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking',
|
'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {ThemeProps, themeable} from '../theme';
|
import {ThemeProps, themeable} from '../theme';
|
||||||
import {CheckboxesProps, Checkboxes} from './Checkboxes';
|
import {BaseCheckboxesProps, BaseCheckboxes} from './Checkboxes';
|
||||||
import {Options, Option} from './Select';
|
import {Options, Option} from './Select';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
import ResultList from './ResultList';
|
import ResultList from './ResultList';
|
||||||
@ -13,8 +13,12 @@ import {Icon} from './icons';
|
|||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import ChainedCheckboxes from './ChainedCheckboxes';
|
import ChainedCheckboxes from './ChainedCheckboxes';
|
||||||
import AssociatedCheckboxes from './AssociatedCheckboxes';
|
import AssociatedCheckboxes from './AssociatedCheckboxes';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface TransferProps extends ThemeProps, CheckboxesProps {
|
export interface TransferProps
|
||||||
|
extends ThemeProps,
|
||||||
|
LocaleProps,
|
||||||
|
BaseCheckboxesProps {
|
||||||
inline?: boolean;
|
inline?: boolean;
|
||||||
statistics?: boolean;
|
statistics?: boolean;
|
||||||
showArrow?: boolean;
|
showArrow?: boolean;
|
||||||
@ -98,7 +102,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
@autobind
|
@autobind
|
||||||
toggleAll() {
|
toggleAll() {
|
||||||
const {options, option2value, onChange, value} = this.props;
|
const {options, option2value, onChange, value} = this.props;
|
||||||
let valueArray = Checkboxes.value2array(value, options, option2value);
|
let valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
const availableOptions = flattenTree(options).filter(
|
const availableOptions = flattenTree(options).filter(
|
||||||
(option, index, list) =>
|
(option, index, list) =>
|
||||||
!option.disabled &&
|
!option.disabled &&
|
||||||
@ -185,7 +189,8 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
onSearch,
|
onSearch,
|
||||||
disabled,
|
disabled,
|
||||||
options,
|
options,
|
||||||
statistics
|
statistics,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (selectRender) {
|
if (selectRender) {
|
||||||
@ -206,7 +211,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
{selectTitle}
|
{__(selectTitle)}
|
||||||
{statistics !== false ? (
|
{statistics !== false ? (
|
||||||
<span>
|
<span>
|
||||||
({this.valueArray.length}/{this.availableOptions.length})
|
({this.valueArray.length}/{this.availableOptions.length})
|
||||||
@ -221,7 +226,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
disabled || !options.length ? 'is-disabled' : ''
|
disabled || !options.length ? 'is-disabled' : ''
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
全选
|
{__('全选')}
|
||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@ -231,7 +236,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
<InputBox
|
<InputBox
|
||||||
value={this.state.inputValue}
|
value={this.state.inputValue}
|
||||||
onChange={this.handleSearch}
|
onChange={this.handleSearch}
|
||||||
placeholder="请输入关键字"
|
placeholder={__('请输入关键字')}
|
||||||
clearable={false}
|
clearable={false}
|
||||||
>
|
>
|
||||||
{this.state.searchResult !== null ? (
|
{this.state.searchResult !== null ? (
|
||||||
@ -393,10 +398,11 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
option2value,
|
option2value,
|
||||||
disabled,
|
disabled,
|
||||||
statistics,
|
statistics,
|
||||||
showArrow
|
showArrow,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
this.valueArray = Checkboxes.value2array(value, options, option2value);
|
this.valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
this.availableOptions = flattenTree(options).filter(
|
this.availableOptions = flattenTree(options).filter(
|
||||||
(option, index, list) =>
|
(option, index, list) =>
|
||||||
!option.disabled &&
|
!option.disabled &&
|
||||||
@ -419,7 +425,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
<div className={cx('Transfer-result')}>
|
<div className={cx('Transfer-result')}>
|
||||||
<div className={cx('Transfer-title')}>
|
<div className={cx('Transfer-title')}>
|
||||||
<span>
|
<span>
|
||||||
{resultTitle}
|
{__(resultTitle)}
|
||||||
{statistics !== false ? (
|
{statistics !== false ? (
|
||||||
<span>
|
<span>
|
||||||
({this.valueArray.length}/{this.availableOptions.length})
|
({this.valueArray.length}/{this.availableOptions.length})
|
||||||
@ -433,7 +439,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
disabled || !this.valueArray.length ? 'is-disabled' : ''
|
disabled || !this.valueArray.length ? 'is-disabled' : ''
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
清空
|
{__('清空')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ResultList
|
<ResultList
|
||||||
@ -441,7 +447,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
sortable={sortable}
|
sortable={sortable}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
placeholder="请先选择左侧数据"
|
placeholder={__('请先选择左侧数据')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -450,7 +456,9 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(Transfer, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(Transfer, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -14,15 +14,13 @@ import {
|
|||||||
createObject
|
createObject
|
||||||
} from '../utils/helper';
|
} from '../utils/helper';
|
||||||
import {Option, Options, value2array} from './Select';
|
import {Option, Options, value2array} from './Select';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import {highlight} from '../renderers/Form/Options';
|
import {highlight} from '../renderers/Form/Options';
|
||||||
import {Icon} from './icons';
|
import {Icon} from './icons';
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox from './Checkbox';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
interface TreeSelectorProps {
|
interface TreeSelectorProps extends ThemeProps, LocaleProps {
|
||||||
classPrefix: string;
|
|
||||||
classnames: ClassNamesFn;
|
|
||||||
|
|
||||||
highlightTxt?: string;
|
highlightTxt?: string;
|
||||||
|
|
||||||
showIcon?: boolean;
|
showIcon?: boolean;
|
||||||
@ -421,7 +419,7 @@ export class TreeSelector extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderInput(prfix: JSX.Element | null = null) {
|
renderInput(prfix: JSX.Element | null = null) {
|
||||||
const {classnames: cx} = this.props;
|
const {classnames: cx, translate: __} = this.props;
|
||||||
const {inputValue} = this.state;
|
const {inputValue} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -431,12 +429,12 @@ export class TreeSelector extends React.Component<
|
|||||||
<input
|
<input
|
||||||
onChange={this.handleInputChange}
|
onChange={this.handleInputChange}
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
placeholder="请输入"
|
placeholder={__('请输入')}
|
||||||
/>
|
/>
|
||||||
<a data-tooltip="取消" onClick={this.handleCancel}>
|
<a data-tooltip={__('取消')} onClick={this.handleCancel}>
|
||||||
<Icon icon="close" className="icon" />
|
<Icon icon="close" className="icon" />
|
||||||
</a>
|
</a>
|
||||||
<a data-tooltip="确认" onClick={this.handleConfirm}>
|
<a data-tooltip={__('确认')} onClick={this.handleConfirm}>
|
||||||
<Icon icon="check" className="icon" />
|
<Icon icon="check" className="icon" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -473,7 +471,8 @@ export class TreeSelector extends React.Component<
|
|||||||
removable,
|
removable,
|
||||||
createTip,
|
createTip,
|
||||||
editTip,
|
editTip,
|
||||||
removeTip
|
removeTip,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const {
|
const {
|
||||||
unfolded,
|
unfolded,
|
||||||
@ -611,7 +610,7 @@ export class TreeSelector extends React.Component<
|
|||||||
{creatable && hasAbility(item, 'creatable') ? (
|
{creatable && hasAbility(item, 'creatable') ? (
|
||||||
<a
|
<a
|
||||||
onClick={this.handleAdd.bind(this, item)}
|
onClick={this.handleAdd.bind(this, item)}
|
||||||
data-tooltip={createTip}
|
data-tooltip={__(createTip)}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
>
|
>
|
||||||
<Icon icon="plus" className="icon" />
|
<Icon icon="plus" className="icon" />
|
||||||
@ -621,7 +620,7 @@ export class TreeSelector extends React.Component<
|
|||||||
{removable && hasAbility(item, 'removable') ? (
|
{removable && hasAbility(item, 'removable') ? (
|
||||||
<a
|
<a
|
||||||
onClick={this.handleRemove.bind(this, item)}
|
onClick={this.handleRemove.bind(this, item)}
|
||||||
data-tooltip={removeTip}
|
data-tooltip={__(removeTip)}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
>
|
>
|
||||||
<Icon icon="minus" className="icon" />
|
<Icon icon="minus" className="icon" />
|
||||||
@ -631,7 +630,7 @@ export class TreeSelector extends React.Component<
|
|||||||
{editable && hasAbility(item, 'editable') ? (
|
{editable && hasAbility(item, 'editable') ? (
|
||||||
<a
|
<a
|
||||||
onClick={this.handleEdit.bind(this, item)}
|
onClick={this.handleEdit.bind(this, item)}
|
||||||
data-tooltip={editTip}
|
data-tooltip={__(editTip)}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
>
|
>
|
||||||
<Icon icon="pencil" className="icon" />
|
<Icon icon="pencil" className="icon" />
|
||||||
@ -689,7 +688,8 @@ export class TreeSelector extends React.Component<
|
|||||||
creatable,
|
creatable,
|
||||||
rootCreatable,
|
rootCreatable,
|
||||||
rootCreateTip,
|
rootCreateTip,
|
||||||
disabled
|
disabled,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let options = this.props.options;
|
let options = this.props.options;
|
||||||
const {value, isAdding, addingParent, isEditing, inputValue} = this.state;
|
const {value, isAdding, addingParent, isEditing, inputValue} = this.state;
|
||||||
@ -705,7 +705,7 @@ export class TreeSelector extends React.Component<
|
|||||||
onClick={this.handleAdd.bind(this, null)}
|
onClick={this.handleAdd.bind(this, null)}
|
||||||
>
|
>
|
||||||
<Icon icon="plus" className="icon" />
|
<Icon icon="plus" className="icon" />
|
||||||
<span>{rootCreateTip}</span>
|
<span>{__(rootCreateTip)}</span>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -772,4 +772,4 @@ export class TreeSelector extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(TreeSelector);
|
export default themeable(localeable(TreeSelector));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Checkboxes, CheckboxesProps} from './Checkboxes';
|
import {BaseCheckboxes, BaseCheckboxesProps} from './Checkboxes';
|
||||||
import {themeable} from '../theme';
|
import {themeable} from '../theme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
@ -6,8 +6,9 @@ import Checkbox from './Checkbox';
|
|||||||
import {Option} from './Select';
|
import {Option} from './Select';
|
||||||
import {autobind, eachTree, everyTree} from '../utils/helper';
|
import {autobind, eachTree, everyTree} from '../utils/helper';
|
||||||
import Spinner from './Spinner';
|
import Spinner from './Spinner';
|
||||||
|
import {localeable} from '../locale';
|
||||||
|
|
||||||
export interface TreeCheckboxesProps extends CheckboxesProps {
|
export interface TreeCheckboxesProps extends BaseCheckboxesProps {
|
||||||
expand?: 'all' | 'first' | 'root' | 'none';
|
expand?: 'all' | 'first' | 'root' | 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ export interface TreeCheckboxesState {
|
|||||||
expanded: Array<string>;
|
expanded: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TreeCheckboxes extends Checkboxes<
|
export class TreeCheckboxes extends BaseCheckboxes<
|
||||||
TreeCheckboxesProps,
|
TreeCheckboxesProps,
|
||||||
TreeCheckboxesState
|
TreeCheckboxesState
|
||||||
> {
|
> {
|
||||||
@ -25,7 +26,7 @@ export class TreeCheckboxes extends Checkboxes<
|
|||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
...Checkboxes.defaultProps,
|
...BaseCheckboxes.defaultProps,
|
||||||
expand: 'first' as 'first'
|
expand: 'first' as 'first'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ export class TreeCheckboxes extends Checkboxes<
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let valueArray = Checkboxes.value2array(value, options, option2value);
|
let valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
option.value === void 0 &&
|
option.value === void 0 &&
|
||||||
@ -257,10 +258,11 @@ export class TreeCheckboxes extends Checkboxes<
|
|||||||
className,
|
className,
|
||||||
placeholder,
|
placeholder,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
option2value
|
option2value,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
this.valueArray = Checkboxes.value2array(value, options, option2value);
|
this.valueArray = BaseCheckboxes.value2array(value, options, option2value);
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (Array.isArray(options) && options.length) {
|
if (Array.isArray(options) && options.length) {
|
||||||
@ -272,7 +274,9 @@ export class TreeCheckboxes extends Checkboxes<
|
|||||||
{body && body.length ? (
|
{body && body.length ? (
|
||||||
body
|
body
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('TreeCheckboxes-placeholder')}>{placeholder}</div>
|
<div className={cx('TreeCheckboxes-placeholder')}>
|
||||||
|
{__(placeholder)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -280,7 +284,9 @@ export class TreeCheckboxes extends Checkboxes<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(TreeCheckboxes, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(TreeCheckboxes, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -5,23 +5,24 @@ import Checkbox from './Checkbox';
|
|||||||
import {Option} from './Select';
|
import {Option} from './Select';
|
||||||
import {autobind, eachTree, everyTree} from '../utils/helper';
|
import {autobind, eachTree, everyTree} from '../utils/helper';
|
||||||
import Spinner from './Spinner';
|
import Spinner from './Spinner';
|
||||||
import {ListRadiosProps, ListRadios} from './ListRadios';
|
import {BaseRadiosProps, BaseRadios} from './ListRadios';
|
||||||
|
import {localeable} from '../locale';
|
||||||
|
|
||||||
export interface TreeRadiosProps extends ListRadiosProps {
|
export interface TreeRadiosProps extends BaseRadiosProps {
|
||||||
expand?: 'all' | 'first' | 'root' | 'none';
|
expand: 'all' | 'first' | 'root' | 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TreeRadiosState {
|
export interface TreeRadiosState {
|
||||||
expanded: Array<string>;
|
expanded: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TreeRadios extends ListRadios<TreeRadiosProps, TreeRadiosState> {
|
export class TreeRadios extends BaseRadios<TreeRadiosProps, TreeRadiosState> {
|
||||||
state: TreeRadiosState = {
|
state: TreeRadiosState = {
|
||||||
expanded: []
|
expanded: []
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
...ListRadios.defaultProps,
|
...BaseRadios.defaultProps,
|
||||||
expand: 'first' as 'first'
|
expand: 'first' as 'first'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -168,10 +169,11 @@ export class TreeRadios extends ListRadios<TreeRadiosProps, TreeRadiosState> {
|
|||||||
className,
|
className,
|
||||||
placeholder,
|
placeholder,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
option2value
|
option2value,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
this.selected = ListRadios.resolveSelected(value, options, option2value);
|
this.selected = BaseRadios.resolveSelected(value, options, option2value);
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (Array.isArray(options) && options.length) {
|
if (Array.isArray(options) && options.length) {
|
||||||
@ -183,7 +185,7 @@ export class TreeRadios extends ListRadios<TreeRadiosProps, TreeRadiosState> {
|
|||||||
{body && body.length ? (
|
{body && body.length ? (
|
||||||
body
|
body
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('TreeRadios-placeholder')}>{placeholder}</div>
|
<div className={cx('TreeRadios-placeholder')}>{__(placeholder)}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -191,7 +193,9 @@ export class TreeRadios extends ListRadios<TreeRadiosProps, TreeRadiosState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default themeable(
|
export default themeable(
|
||||||
uncontrollable(TreeRadios, {
|
localeable(
|
||||||
value: 'onChange'
|
uncontrollable(TreeRadios, {
|
||||||
})
|
value: 'onChange'
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@ -2,8 +2,9 @@ import moment from 'moment';
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import DaysView from 'react-datetime/src/DaysView';
|
import DaysView from 'react-datetime/src/DaysView';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {LocaleProps, localeable} from '../../locale';
|
||||||
|
|
||||||
interface CustomDaysViewProps {
|
interface CustomDaysViewProps extends LocaleProps {
|
||||||
classPrefix?: string;
|
classPrefix?: string;
|
||||||
prevIcon?: string;
|
prevIcon?: string;
|
||||||
nextIcon?: string;
|
nextIcon?: string;
|
||||||
@ -36,7 +37,7 @@ interface CustomDaysViewProps {
|
|||||||
handleClickOutside: () => void;
|
handleClickOutside: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CustomDaysView extends DaysView {
|
export class CustomDaysView extends DaysView {
|
||||||
props: CustomDaysViewProps;
|
props: CustomDaysViewProps;
|
||||||
getDaysOfWeek: (locale: any) => any;
|
getDaysOfWeek: (locale: any) => any;
|
||||||
renderDays: () => JSX.Element;
|
renderDays: () => JSX.Element;
|
||||||
@ -160,6 +161,8 @@ export default class CustomDaysView extends DaysView {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tfoot key="tf">
|
<tfoot key="tf">
|
||||||
<tr>
|
<tr>
|
||||||
@ -168,10 +171,10 @@ export default class CustomDaysView extends DaysView {
|
|||||||
{this.props.requiredConfirm ? (
|
{this.props.requiredConfirm ? (
|
||||||
<div key="button" className="rdtActions">
|
<div key="button" className="rdtActions">
|
||||||
<a className="rdtBtn rdtBtnConfirm" onClick={this.confirm}>
|
<a className="rdtBtn rdtBtnConfirm" onClick={this.confirm}>
|
||||||
确认
|
{__('确认')}
|
||||||
</a>
|
</a>
|
||||||
<a className="rdtBtn rdtBtnCancel" onClick={this.cancel}>
|
<a className="rdtBtn rdtBtnCancel" onClick={this.cancel}>
|
||||||
取消
|
{__('取消')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
@ -185,6 +188,7 @@ export default class CustomDaysView extends DaysView {
|
|||||||
const footer = this.renderFooter();
|
const footer = this.renderFooter();
|
||||||
const date = this.props.viewDate;
|
const date = this.props.viewDate;
|
||||||
const locale = date.localeData();
|
const locale = date.localeData();
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
const tableChildren = [
|
const tableChildren = [
|
||||||
<thead key="th">
|
<thead key="th">
|
||||||
@ -206,13 +210,13 @@ export default class CustomDaysView extends DaysView {
|
|||||||
|
|
||||||
<div className="rdtCenter">
|
<div className="rdtCenter">
|
||||||
<a className="rdtSwitch" onClick={this.props.showView('years')}>
|
<a className="rdtSwitch" onClick={this.props.showView('years')}>
|
||||||
{date.format('YYYY年')}
|
{date.format(__('YYYY年'))}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className="rdtSwitch"
|
className="rdtSwitch"
|
||||||
onClick={this.props.showView('months')}
|
onClick={this.props.showView('months')}
|
||||||
>
|
>
|
||||||
{date.format('MM月')}
|
{date.format(__('MMM'))}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -246,3 +250,7 @@ export default class CustomDaysView extends DaysView {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default localeable(
|
||||||
|
(CustomDaysView as any) as React.ComponentClass<CustomDaysViewProps>
|
||||||
|
);
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
import MonthsView from 'react-datetime/src/MonthsView';
|
import MonthsView from 'react-datetime/src/MonthsView';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {LocaleProps, localeable} from '../../locale';
|
||||||
|
|
||||||
export default class CustomMonthsView extends MonthsView {
|
export class CustomMonthsView extends MonthsView {
|
||||||
props: {
|
props: {
|
||||||
viewDate: moment.Moment;
|
viewDate: moment.Moment;
|
||||||
subtractTime: (
|
subtractTime: (
|
||||||
@ -16,7 +17,7 @@ export default class CustomMonthsView extends MonthsView {
|
|||||||
type: string,
|
type: string,
|
||||||
toSelected?: moment.Moment
|
toSelected?: moment.Moment
|
||||||
) => () => void;
|
) => () => void;
|
||||||
};
|
} & LocaleProps;
|
||||||
renderMonths: () => JSX.Element;
|
renderMonths: () => JSX.Element;
|
||||||
renderMonth = (props: any, month: number) => {
|
renderMonth = (props: any, month: number) => {
|
||||||
var localMoment = this.props.viewDate;
|
var localMoment = this.props.viewDate;
|
||||||
@ -34,6 +35,8 @@ export default class CustomMonthsView extends MonthsView {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
render() {
|
render() {
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rdtMonths">
|
<div className="rdtMonths">
|
||||||
<table>
|
<table>
|
||||||
@ -45,7 +48,9 @@ export default class CustomMonthsView extends MonthsView {
|
|||||||
>
|
>
|
||||||
«
|
«
|
||||||
</th>
|
</th>
|
||||||
<th className="rdtSwitch">{this.props.viewDate.year()}年</th>
|
<th className="rdtSwitch">
|
||||||
|
{this.props.viewDate.format(__('YYYY年'))}
|
||||||
|
</th>
|
||||||
<th className="rdtNext" onClick={this.props.addTime(1, 'years')}>
|
<th className="rdtNext" onClick={this.props.addTime(1, 'years')}>
|
||||||
»
|
»
|
||||||
</th>
|
</th>
|
||||||
@ -59,3 +64,5 @@ export default class CustomMonthsView extends MonthsView {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default localeable(CustomMonthsView as any);
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
import YearsView from 'react-datetime/src/YearsView';
|
import YearsView from 'react-datetime/src/YearsView';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {LocaleProps, localeable} from '../../locale';
|
||||||
|
|
||||||
export default class CustomYearsView extends YearsView {
|
export class CustomYearsView extends YearsView {
|
||||||
props: {
|
props: {
|
||||||
viewDate: moment.Moment;
|
viewDate: moment.Moment;
|
||||||
subtractTime: (
|
subtractTime: (
|
||||||
@ -17,7 +18,7 @@ export default class CustomYearsView extends YearsView {
|
|||||||
toSelected?: moment.Moment
|
toSelected?: moment.Moment
|
||||||
) => () => void;
|
) => () => void;
|
||||||
showView: (view: string) => () => void;
|
showView: (view: string) => () => void;
|
||||||
};
|
} & LocaleProps;
|
||||||
renderYears: (year: number) => JSX.Element;
|
renderYears: (year: number) => JSX.Element;
|
||||||
renderYear = (props: any, year: number) => {
|
renderYear = (props: any, year: number) => {
|
||||||
return (
|
return (
|
||||||
@ -29,6 +30,7 @@ export default class CustomYearsView extends YearsView {
|
|||||||
render() {
|
render() {
|
||||||
let year = this.props.viewDate.year();
|
let year = this.props.viewDate.year();
|
||||||
year = year - (year % 10);
|
year = year - (year % 10);
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rdtYears">
|
<div className="rdtYears">
|
||||||
@ -42,7 +44,7 @@ export default class CustomYearsView extends YearsView {
|
|||||||
«
|
«
|
||||||
</th>
|
</th>
|
||||||
<th className="rdtSwitch">
|
<th className="rdtSwitch">
|
||||||
{year}年-{year + 9}年
|
{__('{{from}}年-{{to}}年', {from: year, to: year + 9})}
|
||||||
</th>
|
</th>
|
||||||
<th className="rdtNext" onClick={this.props.addTime(10, 'years')}>
|
<th className="rdtNext" onClick={this.props.addTime(10, 'years')}>
|
||||||
»
|
»
|
||||||
@ -57,3 +59,5 @@ export default class CustomYearsView extends YearsView {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default localeable(CustomYearsView as any);
|
||||||
|
@ -24,7 +24,6 @@ import {
|
|||||||
SchemaNode,
|
SchemaNode,
|
||||||
Schema,
|
Schema,
|
||||||
Action,
|
Action,
|
||||||
Omit,
|
|
||||||
RendererData
|
RendererData
|
||||||
} from './types';
|
} from './types';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
@ -34,11 +33,24 @@ import omit from 'lodash/omit';
|
|||||||
import difference from 'lodash/difference';
|
import difference from 'lodash/difference';
|
||||||
import isPlainObject from 'lodash/isPlainObject';
|
import isPlainObject from 'lodash/isPlainObject';
|
||||||
import Scoped from './Scoped';
|
import Scoped from './Scoped';
|
||||||
import {getTheme, ThemeInstance, ClassNamesFn, ThemeContext} from './theme';
|
import {
|
||||||
|
getTheme,
|
||||||
|
ThemeInstance,
|
||||||
|
ClassNamesFn,
|
||||||
|
ThemeContext,
|
||||||
|
ThemeProps
|
||||||
|
} from './theme';
|
||||||
import find from 'lodash/find';
|
import find from 'lodash/find';
|
||||||
import Alert from './components/Alert2';
|
import Alert from './components/Alert2';
|
||||||
import {LazyComponent} from './components';
|
import {LazyComponent} from './components';
|
||||||
import ImageGallery from './components/ImageGallery';
|
import ImageGallery from './components/ImageGallery';
|
||||||
|
import {
|
||||||
|
TranslateFn,
|
||||||
|
getDefaultLocale,
|
||||||
|
makeTranslator,
|
||||||
|
LocaleContext,
|
||||||
|
LocaleProps
|
||||||
|
} from './locale';
|
||||||
|
|
||||||
export interface TestFunc {
|
export interface TestFunc {
|
||||||
(
|
(
|
||||||
@ -98,11 +110,9 @@ export interface RendererEnv {
|
|||||||
[propName: string]: any;
|
[propName: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RendererProps {
|
export interface RendererProps extends ThemeProps, LocaleProps {
|
||||||
render: (region: string, node: SchemaNode, props?: any) => JSX.Element;
|
render: (region: string, node: SchemaNode, props?: any) => JSX.Element;
|
||||||
env: RendererEnv;
|
env: RendererEnv;
|
||||||
classPrefix: string;
|
|
||||||
classnames: ClassNamesFn;
|
|
||||||
$path: string; // 当前组件所在的层级信息
|
$path: string; // 当前组件所在的层级信息
|
||||||
store?: IIRendererStore;
|
store?: IIRendererStore;
|
||||||
syncSuperStore?: boolean;
|
syncSuperStore?: boolean;
|
||||||
@ -193,7 +203,7 @@ export function filterSchema(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Renderer(config: RendererBasicConfig) {
|
export function Renderer(config: RendererBasicConfig) {
|
||||||
return function<T extends RendererComponent>(component: T): T {
|
return function <T extends RendererComponent>(component: T): T {
|
||||||
const renderer = registerRenderer({
|
const renderer = registerRenderer({
|
||||||
...config,
|
...config,
|
||||||
component: component
|
component: component
|
||||||
@ -215,9 +225,7 @@ export function registerRenderer(config: RendererConfig): RendererConfig {
|
|||||||
|
|
||||||
if (~rendererNames.indexOf(config.name)) {
|
if (~rendererNames.indexOf(config.name)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The renderer with name "${
|
`The renderer with name "${config.name}" has already exists, please try another name!`
|
||||||
config.name
|
|
||||||
}" has already exists, please try another name!`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +330,8 @@ export interface RootRendererProps {
|
|||||||
env: RendererEnv;
|
env: RendererEnv;
|
||||||
theme: string;
|
theme: string;
|
||||||
pathPrefix?: string;
|
pathPrefix?: string;
|
||||||
|
locale?: string;
|
||||||
|
translate?: TranslateFn;
|
||||||
[propName: string]: any;
|
[propName: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,6 +372,8 @@ export class RootRenderer extends React.Component<RootRendererProps> {
|
|||||||
pathPrefix,
|
pathPrefix,
|
||||||
location,
|
location,
|
||||||
data,
|
data,
|
||||||
|
locale,
|
||||||
|
translate,
|
||||||
...rest
|
...rest
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@ -385,28 +397,32 @@ export class RootRenderer extends React.Component<RootRendererProps> {
|
|||||||
return (
|
return (
|
||||||
<RootStoreContext.Provider value={rootStore}>
|
<RootStoreContext.Provider value={rootStore}>
|
||||||
<ThemeContext.Provider value={this.props.theme || 'default'}>
|
<ThemeContext.Provider value={this.props.theme || 'default'}>
|
||||||
<ImageGallery modalContainer={env.getModalContainer}>
|
<LocaleContext.Provider value={this.props.locale!}>
|
||||||
{
|
<ImageGallery modalContainer={env.getModalContainer}>
|
||||||
renderChild(
|
{
|
||||||
pathPrefix || '',
|
renderChild(
|
||||||
isPlainObject(schema)
|
pathPrefix || '',
|
||||||
? {
|
isPlainObject(schema)
|
||||||
type: 'page',
|
? {
|
||||||
...(schema as Schema)
|
type: 'page',
|
||||||
}
|
...(schema as any)
|
||||||
: schema,
|
}
|
||||||
{
|
: schema,
|
||||||
...rest,
|
{
|
||||||
resolveDefinitions: this.resolveDefinitions,
|
...rest,
|
||||||
location: location,
|
resolveDefinitions: this.resolveDefinitions,
|
||||||
data: finalData,
|
location: location,
|
||||||
env,
|
data: finalData,
|
||||||
classnames: theme.classnames,
|
env,
|
||||||
classPrefix: theme.classPrefix
|
classnames: theme.classnames,
|
||||||
}
|
classPrefix: theme.classPrefix,
|
||||||
) as JSX.Element
|
locale,
|
||||||
}
|
translate
|
||||||
</ImageGallery>
|
}
|
||||||
|
) as JSX.Element
|
||||||
|
}
|
||||||
|
</ImageGallery>
|
||||||
|
</LocaleContext.Provider>
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
</RootStoreContext.Provider>
|
</RootStoreContext.Provider>
|
||||||
);
|
);
|
||||||
@ -634,7 +650,7 @@ export function HocStoreFactory(renderer: {
|
|||||||
storeType: string;
|
storeType: string;
|
||||||
extendsData?: boolean;
|
extendsData?: boolean;
|
||||||
}): any {
|
}): any {
|
||||||
return function<T extends React.ComponentType<RendererProps>>(Component: T) {
|
return function <T extends React.ComponentType<RendererProps>>(Component: T) {
|
||||||
type Props = Omit<
|
type Props = Omit<
|
||||||
RendererProps,
|
RendererProps,
|
||||||
'store' | 'data' | 'dataUpdatedAt' | 'scope'
|
'store' | 'data' | 'dataUpdatedAt' | 'scope'
|
||||||
@ -646,8 +662,9 @@ export function HocStoreFactory(renderer: {
|
|||||||
|
|
||||||
@observer
|
@observer
|
||||||
class StoreFactory extends React.Component<Props> {
|
class StoreFactory extends React.Component<Props> {
|
||||||
static displayName = `WithStore(${Component.displayName ||
|
static displayName = `WithStore(${
|
||||||
Component.name})`;
|
Component.displayName || Component.name
|
||||||
|
})`;
|
||||||
static ComposedComponent = Component;
|
static ComposedComponent = Component;
|
||||||
static contextType = RootStoreContext;
|
static contextType = RootStoreContext;
|
||||||
store: IIRendererStore;
|
store: IIRendererStore;
|
||||||
@ -839,7 +856,7 @@ export function HocStoreFactory(renderer: {
|
|||||||
return (
|
return (
|
||||||
<Component
|
<Component
|
||||||
{
|
{
|
||||||
...rest as any /* todo */
|
...(rest as any) /* todo */
|
||||||
}
|
}
|
||||||
{...exprProps}
|
{...exprProps}
|
||||||
ref={this.refFn}
|
ref={this.refFn}
|
||||||
@ -956,6 +973,8 @@ export function render(
|
|||||||
const env = getEnv(store);
|
const env = getEnv(store);
|
||||||
const theme = props.theme || options.theme || 'default';
|
const theme = props.theme || options.theme || 'default';
|
||||||
env.theme = getTheme(theme);
|
env.theme = getTheme(theme);
|
||||||
|
const locale = props.locale || getDefaultLocale();
|
||||||
|
const translate = props.translate || makeTranslator(locale);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScopedRootRenderer
|
<ScopedRootRenderer
|
||||||
@ -965,6 +984,8 @@ export function render(
|
|||||||
rootStore={store}
|
rootStore={store}
|
||||||
env={env}
|
env={env}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
locale={locale}
|
||||||
|
translate={translate}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
119
src/locale.tsx
Normal file
119
src/locale.tsx
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// 多语言支持
|
||||||
|
import React from 'react';
|
||||||
|
import hoistNonReactStatic from 'hoist-non-react-statics';
|
||||||
|
import {resolveVariable} from './utils/tpl-builtin';
|
||||||
|
|
||||||
|
export type TranslateFn<T = any> = (str: T, data?: object) => T;
|
||||||
|
|
||||||
|
interface LocaleConfig {
|
||||||
|
[propsName: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
let defaultLocale: string = 'zh-cn';
|
||||||
|
|
||||||
|
const locales: {
|
||||||
|
[propName: string]: LocaleConfig;
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
export function register(name: string, config: LocaleConfig) {
|
||||||
|
locales[name] = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fns: {
|
||||||
|
[propName: string]: TranslateFn;
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
function format(str: string, data?: object) {
|
||||||
|
return str.replace(/(\\)?\{\{([\s\S]+?)\}\}/g, (_, escape, key) => {
|
||||||
|
if (escape) {
|
||||||
|
return _.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolveVariable(key, data || {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeTranslator(locale?: string): TranslateFn {
|
||||||
|
if (locale && fns[locale]) {
|
||||||
|
return fns[locale];
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn = (str: any, ...args: any[]) => {
|
||||||
|
if (!str || typeof str !== 'string') {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dict = locales[locale!] || locales[defaultLocale];
|
||||||
|
return format(dict?.[str] || str, ...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
locale && (fns[locale] = fn);
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDefaultLocale() {
|
||||||
|
return defaultLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setDefaultLocale(loacle: string) {
|
||||||
|
defaultLocale = loacle;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LocaleProps {
|
||||||
|
locale: string;
|
||||||
|
translate: TranslateFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LocaleContext = React.createContext('');
|
||||||
|
|
||||||
|
export function localeable<
|
||||||
|
T extends React.ComponentType<React.ComponentProps<T> & LocaleProps>
|
||||||
|
>(ComposedComponent: T) {
|
||||||
|
type OuterProps = JSX.LibraryManagedAttributes<
|
||||||
|
T,
|
||||||
|
Omit<React.ComponentProps<T>, keyof LocaleProps>
|
||||||
|
> & {
|
||||||
|
locale?: string;
|
||||||
|
translate?: (str: string, ...args: any[]) => string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = hoistNonReactStatic(
|
||||||
|
class extends React.Component<OuterProps> {
|
||||||
|
static displayName = `I18N(${
|
||||||
|
ComposedComponent.displayName || ComposedComponent.name
|
||||||
|
})`;
|
||||||
|
static contextType = LocaleContext;
|
||||||
|
static ComposedComponent = ComposedComponent;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const locale: string =
|
||||||
|
this.props.locale || this.context || defaultLocale;
|
||||||
|
const translate = this.props.translate || makeTranslator(locale);
|
||||||
|
const injectedProps: {
|
||||||
|
locale: string;
|
||||||
|
translate: TranslateFn;
|
||||||
|
} = {
|
||||||
|
locale,
|
||||||
|
translate: translate!
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LocaleContext.Provider value={locale}>
|
||||||
|
<ComposedComponent
|
||||||
|
{...(this.props as JSX.LibraryManagedAttributes<
|
||||||
|
T,
|
||||||
|
React.ComponentProps<T>
|
||||||
|
>)}
|
||||||
|
{...injectedProps}
|
||||||
|
/>
|
||||||
|
</LocaleContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ComposedComponent
|
||||||
|
);
|
||||||
|
|
||||||
|
return result as typeof result & {
|
||||||
|
ComposedComponent: T;
|
||||||
|
};
|
||||||
|
}
|
153
src/locale/en.ts
Normal file
153
src/locale/en.ts
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
import {register} from '../locale';
|
||||||
|
|
||||||
|
register('en', {
|
||||||
|
'确认': 'Confirm',
|
||||||
|
'取消': 'Cancel',
|
||||||
|
'YYYY年': 'YYYY',
|
||||||
|
'MM月': 'MMM',
|
||||||
|
'{{from}}年-{{to}}年': '{{from}} - {{to}}',
|
||||||
|
'请选择日期': 'Select Date',
|
||||||
|
'请选择日期以及时间': 'Select Datetime',
|
||||||
|
'请选择时间': 'Select Time',
|
||||||
|
'系统消息': 'System Info',
|
||||||
|
'加载中': 'Loading',
|
||||||
|
'点击刷新重新加载': 'Click to refresh',
|
||||||
|
'请先选择左侧数据': 'Select from left first.',
|
||||||
|
'请选择颜色': 'Select color',
|
||||||
|
'现在': 'Now',
|
||||||
|
'今天': 'Today',
|
||||||
|
'昨天': 'Yesterday',
|
||||||
|
'本周一': 'Monday',
|
||||||
|
'本月初': 'Earlier this month',
|
||||||
|
'上个月初': 'Earlier last month',
|
||||||
|
'上个季节初': 'Earlier last quarter',
|
||||||
|
'明天': 'Tomorrow',
|
||||||
|
'本周日': 'Sunday',
|
||||||
|
'本月底': 'last day of this month',
|
||||||
|
'{{hours}}小时前': '{{hours}} hour(s) ago',
|
||||||
|
'{{hours}}小时后': '{{hours}} hour(s) after',
|
||||||
|
'{{days}}天前': '{{days}} day(s) ago',
|
||||||
|
'{{days}}天后': '{{days}} day(s) after',
|
||||||
|
'{{weeks}}周前': '{{weeks}} week(s) ago',
|
||||||
|
'{{weeks}}周后': '{{weeks}} week(s) after',
|
||||||
|
'{{months}}月前': '{{months}} month(s) ago',
|
||||||
|
'{{months}}月后': '{{months}} month(s) after',
|
||||||
|
'{{quarters}}季度前': '{{quarters}} quarter(s) ago',
|
||||||
|
'{{quarters}}季度后': '{{quarters}} quarter(s) after',
|
||||||
|
' 至 ': ' to ',
|
||||||
|
'最近1天': 'Last day',
|
||||||
|
'最近7天': 'Last 7 days',
|
||||||
|
'最近90天': 'Last 90 days',
|
||||||
|
'上周': 'Last week',
|
||||||
|
'本月': 'This month',
|
||||||
|
'上个月': 'Last month',
|
||||||
|
'上个季节': 'Last quarter',
|
||||||
|
'本季度': 'This quarter',
|
||||||
|
'请选择日期范围': 'Select Daterange',
|
||||||
|
'关闭': 'Close',
|
||||||
|
'暂无选项': 'No options',
|
||||||
|
'请选择位置': 'Pick location',
|
||||||
|
'无': 'None',
|
||||||
|
'没有数据': 'No data',
|
||||||
|
'请先选择数据': 'Select data first',
|
||||||
|
'请选择': 'Select',
|
||||||
|
'全选': 'Check all',
|
||||||
|
'搜索结果': 'Search result',
|
||||||
|
'清空': 'Clear',
|
||||||
|
'当前选择': 'Selected',
|
||||||
|
'添加一级节点': 'Add root node',
|
||||||
|
'添加孩子节点': 'Add child',
|
||||||
|
'编辑该节点': 'Edit this node',
|
||||||
|
'移除该节点': 'Remove this node',
|
||||||
|
'请输入': 'Enter',
|
||||||
|
'请输入关键字': 'Enter keywords',
|
||||||
|
'新增选项': 'New option',
|
||||||
|
'请输入街道信息': 'Enter street info',
|
||||||
|
'删除': 'Delete',
|
||||||
|
'新增': 'New',
|
||||||
|
'新增一条数据': 'Add a data',
|
||||||
|
'类型': 'Type',
|
||||||
|
'拖拽排序': 'Drag to sort',
|
||||||
|
'删除失败': 'Delete failed',
|
||||||
|
'确认要删除?': 'Are you sure you want to delete?',
|
||||||
|
'组合表单成员数量不够,低于设定的最小{{minLenth}}个,请添加更多的成员。':
|
||||||
|
'The number of combined form members is not enough. It is lower than the minimum {{minlenth}} set. Please add more members.',
|
||||||
|
'组合表单成员数量超出,超出设定的最大{{maxLength}}个,请删除多余的成员。':
|
||||||
|
'The number of combined form members exceeds the set maximum of {{MaxLength}}}. Please delete the extra members.',
|
||||||
|
'子表单验证失败,请仔细检查': 'Validate failed, please check this Subform.',
|
||||||
|
'成员{{index}}': 'Member {{index}}',
|
||||||
|
'清空数据': 'Clear data',
|
||||||
|
'您选择的文件 {{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} 的限制,请重新选择。':
|
||||||
|
'The file {{filename}} you selected has a size of {actualsize}} which exceeds the maximum limit of {{maxsize}}. Please select again.',
|
||||||
|
|
||||||
|
'您添加的文件{{files}}不符合类型的`{{accept}}`的设定,请仔细检查。':
|
||||||
|
'The file you added {{files}} does not match the setting of the type `{{accept}}`. Please check it carefully.',
|
||||||
|
'把文件拖到这,然后松完成添加!':
|
||||||
|
'Drag the file here, then release to finish adding!',
|
||||||
|
'把图片拖到这,然后松开完成添加!':
|
||||||
|
'Drag the picture here, then release to finish adding!',
|
||||||
|
'重新上传': 'Repick',
|
||||||
|
'重试上传': 'Retry',
|
||||||
|
'继续添加': 'Continue add',
|
||||||
|
'上传文件': 'Upload file',
|
||||||
|
'移除': 'Remove',
|
||||||
|
'暂停上传': 'Pause uplaod',
|
||||||
|
'开始上传': 'Start upload',
|
||||||
|
'已成功上传{{uploaded}}个文件,{{failed}}个文件上传失败,':
|
||||||
|
'Successfully uploaded {{uploaded}} files, failed to upload {{failed}} files,',
|
||||||
|
'失败文件': 'Failed files.',
|
||||||
|
'高度{{height}}px': 'height: {{height}}px',
|
||||||
|
'宽度{{width}}px': 'width: {{width}}px',
|
||||||
|
'尺寸({{width}} x {{height}})': 'size: ({{width}}px x {{height}}px)',
|
||||||
|
'您选择的图片不符合尺寸要求, 请上传{{info}}的图片':
|
||||||
|
'The picture you selected does not meet the size requirements. Please upload the picture of {{info}}',
|
||||||
|
'您选择的图片不符合尺寸要求, 请上传不要超过{{info}}的图片':
|
||||||
|
'The picture you selected does not meet the size requirements. Please upload a picture that does not exceed {{info}}`.',
|
||||||
|
'您选择的图片不符合尺寸要求, 请上传不要小于{{info}}的图片':
|
||||||
|
'The picture you selected does not meet the size requirements. Please upload a picture no less than {{info}}',
|
||||||
|
'您选择的图片不符合尺寸要求, 请上传尺寸比率为 {{ratio}} 的图片':
|
||||||
|
'The picture you selected does not meet the size requirements. Please upload the picture with the size ratio of ${ration}',
|
||||||
|
'文件上传失败请重试': 'File upload failed, please try again',
|
||||||
|
'文件上传中': 'File uploading',
|
||||||
|
'查看大图': 'Zoom In',
|
||||||
|
'裁剪图片': 'Crop picture',
|
||||||
|
'当前状态支持从剪切板中粘贴图片文件。':
|
||||||
|
'The current state supports pasting picture files from the clipboard.',
|
||||||
|
'表单': 'Form',
|
||||||
|
'提交': 'Submit',
|
||||||
|
'初始化失败': 'Initialization failed',
|
||||||
|
'保存成功': 'Saved successfully',
|
||||||
|
'保存失败': 'Save failed',
|
||||||
|
'依赖的部分字段没有通过验证,请注意填写!':
|
||||||
|
'Some of the dependent fields failed to pass the verification, please fill in!',
|
||||||
|
'请输入名称': 'Please enter a name',
|
||||||
|
'编辑{{label}}': 'Edit {{label}}',
|
||||||
|
'每': 'Per',
|
||||||
|
'编辑详情': 'Detail',
|
||||||
|
'删除当前行': 'Delete current row',
|
||||||
|
'操作': 'Operation',
|
||||||
|
'新增一行': 'Add a row',
|
||||||
|
'暂无标签': 'No tag yet',
|
||||||
|
'新增:{{label}}': 'New {{label}}',
|
||||||
|
'顶级': 'Root',
|
||||||
|
'点击复制': 'Copy',
|
||||||
|
'{{page}}/{{lastPage}} 总共:{{total}} 项。':
|
||||||
|
'{{page}} of {{lastPage}} total: {{total}}.',
|
||||||
|
'每页显示': 'Per page',
|
||||||
|
'加载更多': 'Load more',
|
||||||
|
'筛选': 'Filter',
|
||||||
|
'搜索': 'Search',
|
||||||
|
'日期无效': 'Invalid date',
|
||||||
|
'关闭弹窗': 'Close',
|
||||||
|
'链接': 'Link',
|
||||||
|
'当前有 {{modified}} 条记录修改了内容, 但并没有提交。请选择:':
|
||||||
|
'There are currently {{modified}} records that have modified the contents, but they have not been submitted. Please select:',
|
||||||
|
'放弃': 'Give up',
|
||||||
|
'当前有 {{moved}} 条记录修改了顺序, 但并没有提交。请选择:':
|
||||||
|
'There are currently {{moved}} records that have changed the order, but have not been committed. Please select:',
|
||||||
|
'点击开始排序': 'Click to start sorting',
|
||||||
|
'请拖动左边的按钮进行排序': 'Please drag the button on the left to sort',
|
||||||
|
'排序': 'Sort',
|
||||||
|
'正序': 'Asc',
|
||||||
|
'降序': 'Desc'
|
||||||
|
});
|
@ -40,7 +40,6 @@ const ActionProps = [
|
|||||||
];
|
];
|
||||||
import {filterContents} from './Remark';
|
import {filterContents} from './Remark';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable} from '../theme';
|
||||||
import {Omit} from '../types';
|
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
|
|
||||||
export interface ActionProps {
|
export interface ActionProps {
|
||||||
|
@ -1335,16 +1335,20 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderStatistics() {
|
renderStatistics() {
|
||||||
const {store, classnames: cx} = this.props;
|
const {store, classnames: cx, translate: __} = this.props;
|
||||||
|
|
||||||
if (store.lastPage <= 1) {
|
if (store.lastPage <= 1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('Crud-statistics')}>{`${
|
<div className={cx('Crud-statistics')}>
|
||||||
store.page + '/' + store.lastPage
|
{__('{{page}}/{{lastPage}} 总共:{{total}} 项。', {
|
||||||
}总共${store.total}项。`}</div>
|
page: store.page,
|
||||||
|
lastPage: store.lastPage,
|
||||||
|
total: store.total
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1353,7 +1357,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
store,
|
store,
|
||||||
perPageAvailable,
|
perPageAvailable,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
classPrefix: ns
|
classPrefix: ns,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const items = childProps.items;
|
const items = childProps.items;
|
||||||
@ -1371,11 +1376,11 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('Crud-pageSwitch')}>
|
<div className={cx('Crud-pageSwitch')}>
|
||||||
每页显示
|
{__('每页显示')}
|
||||||
<Select
|
<Select
|
||||||
classPrefix={ns}
|
classPrefix={ns}
|
||||||
searchable={false}
|
searchable={false}
|
||||||
placeholder="请选择.."
|
placeholder={__('请选择')}
|
||||||
options={perPages}
|
options={perPages}
|
||||||
value={store.perPage + ''}
|
value={store.perPage + ''}
|
||||||
onChange={(value: any) => this.handleChangePage(1, value.value)}
|
onChange={(value: any) => this.handleChangePage(1, value.value)}
|
||||||
@ -1386,7 +1391,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderLoadMore() {
|
renderLoadMore() {
|
||||||
const {store, classPrefix: ns, classnames: cx} = this.props;
|
const {store, classPrefix: ns, classnames: cx, translate: __} = this.props;
|
||||||
const {page, lastPage} = store;
|
const {page, lastPage} = store;
|
||||||
|
|
||||||
return page < lastPage ? (
|
return page < lastPage ? (
|
||||||
@ -1399,7 +1404,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
size="sm"
|
size="sm"
|
||||||
className="btn-primary"
|
className="btn-primary"
|
||||||
>
|
>
|
||||||
加载更多
|
{__('加载更多')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@ -1408,7 +1413,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderFilterToggler() {
|
renderFilterToggler() {
|
||||||
const {store, classnames: cx} = this.props;
|
const {store, classnames: cx, translate: __} = this.props;
|
||||||
|
|
||||||
if (!store.filterTogggable) {
|
if (!store.filterTogggable) {
|
||||||
return null;
|
return null;
|
||||||
@ -1422,7 +1427,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<i className="fa fa-sliders m-r-sm" />
|
<i className="fa fa-sliders m-r-sm" />
|
||||||
筛选
|
{__('筛选')}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1574,7 +1579,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
classnames: cx,
|
classnames: cx,
|
||||||
labelField,
|
labelField,
|
||||||
labelTpl,
|
labelTpl,
|
||||||
primaryField
|
primaryField,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!store.selectedItems.length) {
|
if (!store.selectedItems.length) {
|
||||||
@ -1587,7 +1593,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
{store.selectedItems.map((item, index) => (
|
{store.selectedItems.map((item, index) => (
|
||||||
<div key={index} className={cx(`Crud-value`)}>
|
<div key={index} className={cx(`Crud-value`)}>
|
||||||
<span
|
<span
|
||||||
data-tooltip="删除"
|
data-tooltip={__('删除')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
className={cx('Crud-valueIcon')}
|
className={cx('Crud-valueIcon')}
|
||||||
onClick={this.unSelectItem.bind(this, item, index)}
|
onClick={this.unSelectItem.bind(this, item, index)}
|
||||||
@ -1605,7 +1611,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
<a onClick={this.clearSelection} className={cx('Crud-selectionClear')}>
|
<a onClick={this.clearSelection} className={cx('Crud-selectionClear')}>
|
||||||
清空
|
{__('清空')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -1633,6 +1639,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
keepItemSelectionOnPageChange,
|
keepItemSelectionOnPageChange,
|
||||||
onAction,
|
onAction,
|
||||||
popOverContainer,
|
popOverContainer,
|
||||||
|
translate: __,
|
||||||
...rest
|
...rest
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@ -1646,9 +1653,9 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
|||||||
? render(
|
? render(
|
||||||
'filter',
|
'filter',
|
||||||
{
|
{
|
||||||
title: '条件过滤',
|
title: __('条件过滤'),
|
||||||
mode: 'inline',
|
mode: 'inline',
|
||||||
submitText: '搜索',
|
submitText: __('搜索'),
|
||||||
...filter,
|
...filter,
|
||||||
type: 'form',
|
type: 'form',
|
||||||
api: null
|
api: null
|
||||||
|
@ -177,9 +177,9 @@ export default class Cards extends React.Component<GridProps, object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
let parent: HTMLElement | Window | null = getScrollParent(findDOMNode(
|
let parent: HTMLElement | Window | null = getScrollParent(
|
||||||
this
|
findDOMNode(this) as HTMLElement
|
||||||
) as HTMLElement);
|
);
|
||||||
if (!parent || parent === document.body) {
|
if (!parent || parent === document.body) {
|
||||||
parent = window;
|
parent = window;
|
||||||
}
|
}
|
||||||
@ -282,9 +282,7 @@ export default class Cards extends React.Component<GridProps, object> {
|
|||||||
const afixedDom = dom.querySelector(`.${ns}Cards-fixedTop`) as HTMLElement;
|
const afixedDom = dom.querySelector(`.${ns}Cards-fixedTop`) as HTMLElement;
|
||||||
|
|
||||||
this.body.offsetWidth &&
|
this.body.offsetWidth &&
|
||||||
(afixedDom.style.cssText = `top: ${offsetY}px;width: ${
|
(afixedDom.style.cssText = `top: ${offsetY}px;width: ${this.body.offsetWidth}px;`);
|
||||||
this.body.offsetWidth
|
|
||||||
}px;`);
|
|
||||||
affixed ? afixedDom.classList.add('in') : afixedDom.classList.remove('in');
|
affixed ? afixedDom.classList.add('in') : afixedDom.classList.remove('in');
|
||||||
// store.markHeaderAffix(clip.top < offsetY && (clip.top + clip.height - 40) > offsetY);
|
// store.markHeaderAffix(clip.top < offsetY && (clip.top + clip.height - 40) > offsetY);
|
||||||
}
|
}
|
||||||
@ -520,9 +518,7 @@ export default class Cards extends React.Component<GridProps, object> {
|
|||||||
<div className={cx('Cards-heading')}>
|
<div className={cx('Cards-heading')}>
|
||||||
{store.modified && !hideQuickSaveBtn ? (
|
{store.modified && !hideQuickSaveBtn ? (
|
||||||
<span>
|
<span>
|
||||||
{`当前有 ${
|
{`当前有 ${store.modified} 条记录修改了内容, 但并没有提交。请选择:`}
|
||||||
store.modified
|
|
||||||
} 条记录修改了内容, 但并没有提交。请选择:`}
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cx('Button Button--xs Button--success m-l-sm')}
|
className={cx('Button Button--xs Button--success m-l-sm')}
|
||||||
@ -753,7 +749,8 @@ export default class Cards extends React.Component<GridProps, object> {
|
|||||||
masonryLayout,
|
masonryLayout,
|
||||||
itemsClassName,
|
itemsClassName,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
data
|
data,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
this.renderedToolbars = []; // 用来记录哪些 toolbar 已经渲染了,已经渲染了就不重复渲染了。
|
this.renderedToolbars = []; // 用来记录哪些 toolbar 已经渲染了,已经渲染了就不重复渲染了。
|
||||||
@ -840,7 +837,7 @@ export default class Cards extends React.Component<GridProps, object> {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('Cards-placeholder')}>
|
<div className={cx('Cards-placeholder')}>
|
||||||
{filter(placeholder, data)}
|
{filter(__(placeholder), data)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ export const HocCopyable = () => (Component: React.ComponentType<any>): any => {
|
|||||||
className,
|
className,
|
||||||
data,
|
data,
|
||||||
noHoc,
|
noHoc,
|
||||||
classnames: cx
|
classnames: cx,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (copyable && !noHoc) {
|
if (copyable && !noHoc) {
|
||||||
@ -55,7 +56,7 @@ export const HocCopyable = () => (Component: React.ComponentType<any>): any => {
|
|||||||
<Component {...this.props} wrapperComponent={''} noHoc />
|
<Component {...this.props} wrapperComponent={''} noHoc />
|
||||||
<i
|
<i
|
||||||
key="edit-btn"
|
key="edit-btn"
|
||||||
data-tooltip="点击复制"
|
data-tooltip={__('点击复制')}
|
||||||
className={cx('Field-copyBtn fa fa-clipboard')}
|
className={cx('Field-copyBtn fa fa-clipboard')}
|
||||||
onClick={this.handleClick.bind(this, content)}
|
onClick={this.handleClick.bind(this, content)}
|
||||||
/>
|
/>
|
||||||
|
@ -55,7 +55,8 @@ export class DateField extends React.Component<DateProps, DateState> {
|
|||||||
placeholder,
|
placeholder,
|
||||||
fromNow,
|
fromNow,
|
||||||
className,
|
className,
|
||||||
classnames: cx
|
classnames: cx,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let viewValue: React.ReactNode = (
|
let viewValue: React.ReactNode = (
|
||||||
<span className="text-muted">{placeholder}</span>
|
<span className="text-muted">{placeholder}</span>
|
||||||
@ -77,7 +78,7 @@ export class DateField extends React.Component<DateProps, DateState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewValue = !viewValue ? (
|
viewValue = !viewValue ? (
|
||||||
<span className="text-danger">日期无效</span>
|
<span className="text-danger">{__('日期无效')}</span>
|
||||||
) : (
|
) : (
|
||||||
viewValue
|
viewValue
|
||||||
);
|
);
|
||||||
|
@ -122,7 +122,7 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildActions(): Array<Action> {
|
buildActions(): Array<Action> {
|
||||||
const {actions, confirm} = this.props;
|
const {actions, confirm, translate: __} = this.props;
|
||||||
|
|
||||||
if (typeof actions !== 'undefined') {
|
if (typeof actions !== 'undefined') {
|
||||||
return actions;
|
return actions;
|
||||||
@ -132,14 +132,14 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
|
|||||||
ret.push({
|
ret.push({
|
||||||
type: 'button',
|
type: 'button',
|
||||||
actionType: 'cancel',
|
actionType: 'cancel',
|
||||||
label: '取消'
|
label: __('取消')
|
||||||
});
|
});
|
||||||
|
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
ret.push({
|
ret.push({
|
||||||
type: 'button',
|
type: 'button',
|
||||||
actionType: 'confirm',
|
actionType: 'confirm',
|
||||||
label: '确认',
|
label: __('确认'),
|
||||||
primary: true
|
primary: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -380,7 +380,8 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
|
|||||||
showCloseButton,
|
showCloseButton,
|
||||||
env,
|
env,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
classPrefix
|
classPrefix,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
// console.log('Render Dialog');
|
// console.log('Render Dialog');
|
||||||
@ -408,7 +409,7 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
|
|||||||
<div className={cx('Modal-header', headerClassName)}>
|
<div className={cx('Modal-header', headerClassName)}>
|
||||||
{showCloseButton !== false && !store.loading ? (
|
{showCloseButton !== false && !store.loading ? (
|
||||||
<a
|
<a
|
||||||
data-tooltip="关闭弹窗"
|
data-tooltip={__('关闭弹窗')}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
onClick={this.handleSelfClose}
|
onClick={this.handleSelfClose}
|
||||||
className={cx('Modal-close')}
|
className={cx('Modal-close')}
|
||||||
@ -417,14 +418,14 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
|
|||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
<div className={cx('Modal-title')}>
|
<div className={cx('Modal-title')}>
|
||||||
{filter(title, store.formData)}
|
{filter(__(title), store.formData)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : title ? (
|
) : title ? (
|
||||||
<div className={cx('Modal-header', headerClassName)}>
|
<div className={cx('Modal-header', headerClassName)}>
|
||||||
{showCloseButton !== false && !store.loading ? (
|
{showCloseButton !== false && !store.loading ? (
|
||||||
<a
|
<a
|
||||||
data-tooltip="关闭弹窗"
|
data-tooltip={__('关闭弹窗')}
|
||||||
onClick={this.handleSelfClose}
|
onClick={this.handleSelfClose}
|
||||||
className={cx('Modal-close')}
|
className={cx('Modal-close')}
|
||||||
>
|
>
|
||||||
@ -437,7 +438,7 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
|
|||||||
</div>
|
</div>
|
||||||
) : showCloseButton !== false && !store.loading ? (
|
) : showCloseButton !== false && !store.loading ? (
|
||||||
<a
|
<a
|
||||||
data-tooltip="关闭弹窗"
|
data-tooltip={__('关闭弹窗')}
|
||||||
onClick={this.handleSelfClose}
|
onClick={this.handleSelfClose}
|
||||||
className={cx('Modal-close')}
|
className={cx('Modal-close')}
|
||||||
>
|
>
|
||||||
|
@ -113,7 +113,7 @@ export default class Drawer extends React.Component<DrawerProps, object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildActions(): Array<Action> {
|
buildActions(): Array<Action> {
|
||||||
const {actions, confirm} = this.props;
|
const {actions, confirm, translate: __} = this.props;
|
||||||
|
|
||||||
if (typeof actions !== 'undefined') {
|
if (typeof actions !== 'undefined') {
|
||||||
return actions;
|
return actions;
|
||||||
@ -123,14 +123,14 @@ export default class Drawer extends React.Component<DrawerProps, object> {
|
|||||||
ret.push({
|
ret.push({
|
||||||
type: 'button',
|
type: 'button',
|
||||||
actionType: 'close',
|
actionType: 'close',
|
||||||
label: '取消'
|
label: __('取消')
|
||||||
});
|
});
|
||||||
|
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
ret.push({
|
ret.push({
|
||||||
type: 'button',
|
type: 'button',
|
||||||
actionType: 'confirm',
|
actionType: 'confirm',
|
||||||
label: '确认',
|
label: __('确认'),
|
||||||
primary: true
|
primary: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,8 @@ export default class CheckboxesControl extends React.Component<
|
|||||||
labelClassName,
|
labelClassName,
|
||||||
creatable,
|
creatable,
|
||||||
addApi,
|
addApi,
|
||||||
createBtnLabel
|
createBtnLabel,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
@ -217,13 +218,13 @@ export default class CheckboxesControl extends React.Component<
|
|||||||
{body && body.length ? (
|
{body && body.length ? (
|
||||||
body
|
body
|
||||||
) : (
|
) : (
|
||||||
<span className={`Form-placeholder`}>{placeholder}</span>
|
<span className={`Form-placeholder`}>{__(placeholder)}</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(creatable || addApi) && !disabled ? (
|
{(creatable || addApi) && !disabled ? (
|
||||||
<a className={cx('Checkboxes-addBtn')} onClick={this.handleAddClick}>
|
<a className={cx('Checkboxes-addBtn')} onClick={this.handleAddClick}>
|
||||||
<Icon icon="plus" className="icon" />
|
<Icon icon="plus" className="icon" />
|
||||||
{createBtnLabel}
|
{__(createBtnLabel)}
|
||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,8 +5,9 @@ import {ClassNamesFn, themeable} from '../../theme';
|
|||||||
import {Select} from '../../components';
|
import {Select} from '../../components';
|
||||||
import {autobind} from '../../utils/helper';
|
import {autobind} from '../../utils/helper';
|
||||||
import {Option} from './Options';
|
import {Option} from './Options';
|
||||||
|
import {localeable, LocaleProps} from '../../locale';
|
||||||
|
|
||||||
export interface CityPickerProps {
|
export interface CityPickerProps extends LocaleProps {
|
||||||
value: any;
|
value: any;
|
||||||
onChange: (value: any) => void;
|
onChange: (value: any) => void;
|
||||||
extractValue: boolean;
|
extractValue: boolean;
|
||||||
@ -226,7 +227,8 @@ export class CityPicker extends React.Component<
|
|||||||
disabled,
|
disabled,
|
||||||
allowCity,
|
allowCity,
|
||||||
allowDistrict,
|
allowDistrict,
|
||||||
allowStreet
|
allowStreet,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {provinceCode, cityCode, districtCode, street} = this.state;
|
const {provinceCode, cityCode, districtCode, street} = this.state;
|
||||||
@ -290,7 +292,7 @@ export class CityPicker extends React.Component<
|
|||||||
value={street}
|
value={street}
|
||||||
onChange={this.handleStreetChange}
|
onChange={this.handleStreetChange}
|
||||||
onBlur={this.handleStreetEnd}
|
onBlur={this.handleStreetEnd}
|
||||||
placeholder="请输入街道信息"
|
placeholder={__('请输入街道信息')}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@ -298,7 +300,7 @@ export class CityPicker extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThemedCity = themeable(CityPicker);
|
const ThemedCity = themeable(localeable(CityPicker));
|
||||||
export default ThemedCity;
|
export default ThemedCity;
|
||||||
|
|
||||||
export interface LocationControlProps extends FormControlProps {
|
export interface LocationControlProps extends FormControlProps {
|
||||||
|
@ -321,7 +321,8 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
deleteApi,
|
deleteApi,
|
||||||
deleteConfirmText,
|
deleteConfirmText,
|
||||||
data,
|
data,
|
||||||
env
|
env,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
@ -333,7 +334,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
|
|
||||||
if (isEffectiveApi(deleteApi, ctx)) {
|
if (isEffectiveApi(deleteApi, ctx)) {
|
||||||
const confirmed = await env.confirm(
|
const confirmed = await env.confirm(
|
||||||
deleteConfirmText ? filter(deleteConfirmText, ctx) : '确认要删除?'
|
deleteConfirmText ? filter(deleteConfirmText, ctx) : __('确认要删除?')
|
||||||
);
|
);
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
// 如果不确认,则跳过!
|
// 如果不确认,则跳过!
|
||||||
@ -343,7 +344,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
const result = await env.fetcher(deleteApi as Api, ctx);
|
const result = await env.fetcher(deleteApi as Api, ctx);
|
||||||
|
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
env.notify('error', '删除失败');
|
env.notify('error', __('删除失败'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,25 +481,34 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(): any {
|
validate(): any {
|
||||||
const {value, minLength, maxLength, messages, nullable} = this.props;
|
const {
|
||||||
|
value,
|
||||||
|
minLength,
|
||||||
|
maxLength,
|
||||||
|
messages,
|
||||||
|
nullable,
|
||||||
|
translate: __
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (minLength && (!Array.isArray(value) || value.length < minLength)) {
|
if (minLength && (!Array.isArray(value) || value.length < minLength)) {
|
||||||
return (
|
return __(
|
||||||
(messages && messages.minLengthValidateFailed) ||
|
(messages && messages.minLengthValidateFailed) ||
|
||||||
`组合表单成员数量不够,低于设定的最小${minLength}个,请添加更多的成员。`
|
'组合表单成员数量不够,低于设定的最小{{minLenth}}个,请添加更多的成员。',
|
||||||
|
{minLength}
|
||||||
);
|
);
|
||||||
} else if (maxLength && Array.isArray(value) && value.length > maxLength) {
|
} else if (maxLength && Array.isArray(value) && value.length > maxLength) {
|
||||||
return (
|
return __(
|
||||||
(messages && messages.maxLengthValidateFailed) ||
|
(messages && messages.maxLengthValidateFailed) ||
|
||||||
`组合表单成员数量超出,超出设定的最大${maxLength}个,请删除多余的成员。`
|
'组合表单成员数量超出,超出设定的最大{{maxLength}}个,请删除多余的成员。',
|
||||||
|
{maxLength}
|
||||||
);
|
);
|
||||||
} else if (this.subForms.length && (!nullable || value)) {
|
} else if (this.subForms.length && (!nullable || value)) {
|
||||||
return Promise.all(this.subForms.map(item => item.validate())).then(
|
return Promise.all(this.subForms.map(item => item.validate())).then(
|
||||||
values => {
|
values => {
|
||||||
if (~values.indexOf(false)) {
|
if (~values.indexOf(false)) {
|
||||||
return (
|
return __(
|
||||||
(messages && messages.validateFailed) ||
|
(messages && messages.validateFailed) ||
|
||||||
'子表单验证失败,请仔细检查'
|
'子表单验证失败,请仔细检查'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,9 +708,8 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderPlaceholder() {
|
renderPlaceholder() {
|
||||||
return (
|
const {placeholder, translate: __} = this.props;
|
||||||
<span className="text-muted">{this.props.placeholder || '没有数据'}</span>
|
return <span className="text-muted">{__(placeholder || '没有数据')}</span>;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTabsMode() {
|
renderTabsMode() {
|
||||||
@ -725,7 +734,8 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
deleteIcon,
|
deleteIcon,
|
||||||
tabsLabelTpl,
|
tabsLabelTpl,
|
||||||
conditions,
|
conditions,
|
||||||
changeImmediately
|
changeImmediately,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let controls = this.props.controls;
|
let controls = this.props.controls;
|
||||||
@ -762,7 +772,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
{
|
{
|
||||||
type: 'dropdown-button',
|
type: 'dropdown-button',
|
||||||
icon: addIcon,
|
icon: addIcon,
|
||||||
label: addButtonText || '新增',
|
label: __(addButtonText || '新增'),
|
||||||
level: 'info',
|
level: 'info',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
closeOnClick: true
|
closeOnClick: true
|
||||||
@ -781,10 +791,10 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
<a
|
<a
|
||||||
onClick={this.addItem}
|
onClick={this.addItem}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
data-tooltip="新增一条数据"
|
data-tooltip={__('新增一条数据')}
|
||||||
>
|
>
|
||||||
{addIcon ? <i className={cx('m-r-xs', addIcon)} /> : null}
|
{addIcon ? <i className={cx('m-r-xs', addIcon)} /> : null}
|
||||||
<span>{addButtonText || '新增'}</span>
|
<span>{__(addButtonText || '新增')}</span>
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
) : null}
|
) : null}
|
||||||
@ -808,7 +818,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
className={cx(
|
className={cx(
|
||||||
`Combo-toolbarBtn ${!store.removable ? 'is-disabled' : ''}`
|
`Combo-toolbarBtn ${!store.removable ? 'is-disabled' : ''}`
|
||||||
)}
|
)}
|
||||||
data-tooltip="删除"
|
data-tooltip={__('删除')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
>
|
>
|
||||||
{deleteIcon ? (
|
{deleteIcon ? (
|
||||||
@ -837,7 +847,11 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Tab
|
<Tab
|
||||||
title={filter(tabsLabelTpl || '成员${index|plus}', data)}
|
title={filter(
|
||||||
|
tabsLabelTpl ||
|
||||||
|
__('成员{{index}}', {index: (data as any).index + 1}),
|
||||||
|
data
|
||||||
|
)}
|
||||||
key={this.keys[index] || (this.keys[index] = guid())}
|
key={this.keys[index] || (this.keys[index] = guid())}
|
||||||
toolbar={toolbar}
|
toolbar={toolbar}
|
||||||
eventKey={index}
|
eventKey={index}
|
||||||
@ -847,7 +861,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
>
|
>
|
||||||
{condition && typeSwitchable !== false ? (
|
{condition && typeSwitchable !== false ? (
|
||||||
<div className={cx('Combo-itemTag')}>
|
<div className={cx('Combo-itemTag')}>
|
||||||
<label>类型</label>
|
<label>{__('类型')}</label>
|
||||||
<Select
|
<Select
|
||||||
onChange={this.handleComboTypeChange.bind(this, index)}
|
onChange={this.handleComboTypeChange.bind(this, index)}
|
||||||
options={(conditions as Array<Condition>).map(item => ({
|
options={(conditions as Array<Condition>).map(item => ({
|
||||||
@ -888,7 +902,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Alert2 level="warning" className="m-b-none">
|
<Alert2 level="warning" className="m-b-none">
|
||||||
数据非法,或者数据已失效,请移除
|
{__('数据非法,或者数据已失效,请移除')}
|
||||||
</Alert2>
|
</Alert2>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -931,7 +945,8 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
conditions,
|
conditions,
|
||||||
lazyLoad,
|
lazyLoad,
|
||||||
changeImmediately,
|
changeImmediately,
|
||||||
placeholder
|
placeholder,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let controls = this.props.controls;
|
let controls = this.props.controls;
|
||||||
@ -990,7 +1005,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
!store.removable ? 'is-disabled' : ''
|
!store.removable ? 'is-disabled' : ''
|
||||||
}`
|
}`
|
||||||
)}
|
)}
|
||||||
data-tooltip="删除"
|
data-tooltip={__('删除')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
>
|
>
|
||||||
{deleteIcon ? (
|
{deleteIcon ? (
|
||||||
@ -1029,7 +1044,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
<div className={cx('Combo-itemDrager')}>
|
<div className={cx('Combo-itemDrager')}>
|
||||||
<a
|
<a
|
||||||
key="drag"
|
key="drag"
|
||||||
data-tooltip="拖拽排序"
|
data-tooltip={__('拖拽排序')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
>
|
>
|
||||||
{dragIcon ? (
|
{dragIcon ? (
|
||||||
@ -1042,7 +1057,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
) : null}
|
) : null}
|
||||||
{condition && typeSwitchable !== false ? (
|
{condition && typeSwitchable !== false ? (
|
||||||
<div className={cx('Combo-itemTag')}>
|
<div className={cx('Combo-itemTag')}>
|
||||||
<label>类型</label>
|
<label>{__('类型')}</label>
|
||||||
<Select
|
<Select
|
||||||
onChange={this.handleComboTypeChange.bind(this, index)}
|
onChange={this.handleComboTypeChange.bind(this, index)}
|
||||||
options={(conditions as Array<Condition>).map(item => ({
|
options={(conditions as Array<Condition>).map(item => ({
|
||||||
@ -1084,7 +1099,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Alert2 level="warning" className="m-b-none">
|
<Alert2 level="warning" className="m-b-none">
|
||||||
数据非法,或者数据已失效,请移除
|
{__('数据非法,或者数据已失效,请移除')}
|
||||||
</Alert2>
|
</Alert2>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -1107,7 +1122,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
{
|
{
|
||||||
type: 'dropdown-button',
|
type: 'dropdown-button',
|
||||||
icon: addIcon,
|
icon: addIcon,
|
||||||
label: addButtonText || '新增',
|
label: __(addButtonText || '新增'),
|
||||||
level: 'info',
|
level: 'info',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
closeOnClick: true
|
closeOnClick: true
|
||||||
@ -1127,18 +1142,20 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={this.addItem}
|
onClick={this.addItem}
|
||||||
className={cx(`Button Combo-addBtn`, addButtonClassName)}
|
className={cx(`Button Combo-addBtn`, addButtonClassName)}
|
||||||
data-tooltip="新增一条数据"
|
data-tooltip={__('新增一条数据')}
|
||||||
>
|
>
|
||||||
{addIcon ? (
|
{addIcon ? (
|
||||||
<i className={cx('Button-icon', addIcon)} />
|
<i className={cx('Button-icon', addIcon)} />
|
||||||
) : null}
|
) : null}
|
||||||
<span>{addButtonText || '新增'}</span>
|
<span>{__(addButtonText || '新增')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
) : null}
|
) : null}
|
||||||
{draggable ? (
|
{draggable ? (
|
||||||
<span className={cx(`Combo-dragableTip`)} ref={this.dragTipRef}>
|
<span className={cx(`Combo-dragableTip`)} ref={this.dragTipRef}>
|
||||||
{Array.isArray(value) && value.length > 1 ? draggableTip : ''}
|
{Array.isArray(value) && value.length > 1
|
||||||
|
? __(draggableTip)
|
||||||
|
: ''}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@ -1159,7 +1176,8 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
noBorder,
|
noBorder,
|
||||||
disabled,
|
disabled,
|
||||||
typeSwitchable,
|
typeSwitchable,
|
||||||
nullable
|
nullable,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let controls = this.props.controls;
|
let controls = this.props.controls;
|
||||||
@ -1183,7 +1201,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
<div className={cx(`Combo-item`)}>
|
<div className={cx(`Combo-item`)}>
|
||||||
{condition && typeSwitchable !== false ? (
|
{condition && typeSwitchable !== false ? (
|
||||||
<div className={cx('Combo-itemTag')}>
|
<div className={cx('Combo-itemTag')}>
|
||||||
<label>类型</label>
|
<label>{__('类型')}</label>
|
||||||
<Select
|
<Select
|
||||||
onChange={this.handleComboTypeChange.bind(this, 0)}
|
onChange={this.handleComboTypeChange.bind(this, 0)}
|
||||||
options={(conditions as Array<Condition>).map(item => ({
|
options={(conditions as Array<Condition>).map(item => ({
|
||||||
@ -1219,14 +1237,14 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Alert2 level="warning" className="m-b-none">
|
<Alert2 level="warning" className="m-b-none">
|
||||||
数据非法,或者数据已失效,请移除
|
{__('数据非法,或者数据已失效,请移除')}
|
||||||
</Alert2>
|
</Alert2>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{value && nullable ? (
|
{value && nullable ? (
|
||||||
<a className={cx('Combo-setNullBtn')} href="#" onClick={this.setNull}>
|
<a className={cx('Combo-setNullBtn')} href="#" onClick={this.setNull}>
|
||||||
清空数据
|
{__('清空数据')}
|
||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
@ -101,6 +101,8 @@ export default class DateControl extends React.PureComponent<
|
|||||||
defaultValue,
|
defaultValue,
|
||||||
defaultData,
|
defaultData,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
...rest
|
...rest
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {maxSize, multiple, maxLength} = this.props;
|
const {maxSize, multiple, maxLength, translate: __} = this.props;
|
||||||
let allowed =
|
let allowed =
|
||||||
multiple && maxLength
|
multiple && maxLength
|
||||||
? maxLength - this.state.files.length
|
? maxLength - this.state.files.length
|
||||||
@ -282,11 +282,14 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
[].slice.call(files, 0, allowed).forEach((file: FileX) => {
|
[].slice.call(files, 0, allowed).forEach((file: FileX) => {
|
||||||
if (maxSize && file.size > maxSize) {
|
if (maxSize && file.size > maxSize) {
|
||||||
this.props.env.alert(
|
this.props.env.alert(
|
||||||
`您选择的文件 ${file.name} 大小为 ${ImageControl.formatFileSize(
|
__(
|
||||||
file.size
|
'您选择的文件 {{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} 的限制,请重新选择。',
|
||||||
)} 超出了最大为 ${ImageControl.formatFileSize(
|
{
|
||||||
maxSize
|
filename: file.name,
|
||||||
)} 的限制,请重新选择`
|
actualSize: ImageControl.formatFileSize(file.size),
|
||||||
|
maxSize: ImageControl.formatFileSize(maxSize)
|
||||||
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
file.state = 'invalid';
|
file.state = 'invalid';
|
||||||
} else {
|
} else {
|
||||||
@ -320,7 +323,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
if (evt.type !== 'change' && evt.type !== 'drop') {
|
if (evt.type !== 'change' && evt.type !== 'drop') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const {multiple, env, accept} = this.props;
|
const {multiple, env, accept, translate: __} = this.props;
|
||||||
|
|
||||||
const files = rejectedFiles.map((file: any) => ({
|
const files = rejectedFiles.map((file: any) => ({
|
||||||
...file,
|
...file,
|
||||||
@ -338,9 +341,10 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
env.alert(
|
env.alert(
|
||||||
`您添加的文件${files.map(
|
__('您添加的文件{{files}}不符合类型的`{{accept}}`的设定,请仔细检查。', {
|
||||||
(item: any) => `【${item.name}】`
|
files: files.map((item: any) => `「${item.name}」`).join(' '),
|
||||||
)}不符合类型的\`${accept}\`设定,请仔细检查。`
|
accept
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +397,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const __ = this.props.translate;
|
||||||
const file = find(
|
const file = find(
|
||||||
this.state.files,
|
this.state.files,
|
||||||
item => item.state === 'pending'
|
item => item.state === 'pending'
|
||||||
@ -463,7 +468,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
this.resolve(
|
this.resolve(
|
||||||
this.state.files.some(file => file.state === 'error')
|
this.state.files.some(file => file.state === 'error')
|
||||||
? '文件上传失败请重试'
|
? __('文件上传失败请重试')
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
this.resolve = undefined;
|
this.resolve = undefined;
|
||||||
@ -489,7 +494,8 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
finishChunkApi,
|
finishChunkApi,
|
||||||
asBase64,
|
asBase64,
|
||||||
asBlob,
|
asBlob,
|
||||||
data
|
data,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (asBase64) {
|
if (asBase64) {
|
||||||
@ -545,7 +551,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
)
|
)
|
||||||
.then(ret => {
|
.then(ret => {
|
||||||
if (ret.status || !ret.data) {
|
if (ret.status || !ret.data) {
|
||||||
throw new Error(ret.msg || '上传失败, 请重试');
|
throw new Error(ret.msg || __('上传失败, 请重试'));
|
||||||
}
|
}
|
||||||
|
|
||||||
onProgress(1);
|
onProgress(1);
|
||||||
@ -565,7 +571,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
cb(error.message || '上传失败, 请重试', file);
|
cb(error.message || __('上传失败, 请重试'), file);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,6 +666,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
let startProgress = 0.2;
|
let startProgress = 0.2;
|
||||||
let endProgress = 0.9;
|
let endProgress = 0.9;
|
||||||
let progressArr: Array<number>;
|
let progressArr: Array<number>;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
interface ObjectState {
|
interface ObjectState {
|
||||||
key: string;
|
key: string;
|
||||||
@ -692,10 +699,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
self
|
self._send(startApi).then(startChunk).catch(reject);
|
||||||
._send(startApi)
|
|
||||||
.then(startChunk)
|
|
||||||
.catch(reject);
|
|
||||||
|
|
||||||
function startChunk(ret: Payload) {
|
function startChunk(ret: Payload) {
|
||||||
onProgress(startProgress);
|
onProgress(startProgress);
|
||||||
@ -703,7 +707,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
progressArr = tasks.map(() => 0);
|
progressArr = tasks.map(() => 0);
|
||||||
|
|
||||||
if (!ret.data) {
|
if (!ret.data) {
|
||||||
throw new Error('接口返回错误,请仔细检查');
|
throw new Error(__('接口返回错误,请仔细检查'));
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -713,7 +717,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
total: tasks.length
|
total: tasks.length
|
||||||
};
|
};
|
||||||
|
|
||||||
mapLimit(tasks, 3, uploadPartFile(state, config), function(
|
mapLimit(tasks, 3, uploadPartFile(state, config), function (
|
||||||
err,
|
err,
|
||||||
results
|
results
|
||||||
) {
|
) {
|
||||||
@ -755,10 +759,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
self
|
self._send(endApi).then(resolve).catch(reject);
|
||||||
._send(endApi)
|
|
||||||
.then(resolve)
|
|
||||||
.catch(reject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadPartFile(state: ObjectState, conf: Partial<FileProps>) {
|
function uploadPartFile(state: ObjectState, conf: Partial<FileProps>) {
|
||||||
@ -853,6 +854,8 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(): any {
|
validate(): any {
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.state.uploading ||
|
this.state.uploading ||
|
||||||
this.state.files.some(item => item.state === 'pending')
|
this.state.files.some(item => item.state === 'pending')
|
||||||
@ -862,7 +865,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
this.startUpload();
|
this.startUpload();
|
||||||
});
|
});
|
||||||
} else if (this.state.files.some(item => item.state === 'error')) {
|
} else if (this.state.files.some(item => item.state === 'error')) {
|
||||||
return '文件上传失败请重试';
|
return __('文件上传失败请重试');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -878,6 +881,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
hideUploadButton,
|
hideUploadButton,
|
||||||
className,
|
className,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
|
translate: __,
|
||||||
render
|
render
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let {files, uploading, error} = this.state;
|
let {files, uploading, error} = this.state;
|
||||||
@ -921,7 +925,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
|
|
||||||
{isDragActive ? (
|
{isDragActive ? (
|
||||||
<div className={cx('FileControl-acceptTip')}>
|
<div className={cx('FileControl-acceptTip')}>
|
||||||
把文件拖到这,然后松完成添加!
|
{__('把文件拖到这,然后松完成添加!')}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@ -935,10 +939,10 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
>
|
>
|
||||||
<Icon icon="upload" className="icon" />
|
<Icon icon="upload" className="icon" />
|
||||||
{!multiple && files.length
|
{!multiple && files.length
|
||||||
? '重新上传'
|
? __('重新上传')
|
||||||
: multiple && files.length
|
: multiple && files.length
|
||||||
? '继续添加'
|
? __('继续添加')
|
||||||
: '上传文件'}
|
: __('上传文件')}
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@ -980,7 +984,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
) : null}
|
) : null}
|
||||||
{file.state !== 'uploading' ? (
|
{file.state !== 'uploading' ? (
|
||||||
<a
|
<a
|
||||||
data-tooltip="移除"
|
data-tooltip={__('移除')}
|
||||||
className={cx('FileControl-clear')}
|
className={cx('FileControl-clear')}
|
||||||
onClick={() => this.removeFile(file, index)}
|
onClick={() => this.removeFile(file, index)}
|
||||||
>
|
>
|
||||||
@ -1024,8 +1028,12 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
|
|
||||||
{failed ? (
|
{failed ? (
|
||||||
<div className={cx('FileControl-sum')}>
|
<div className={cx('FileControl-sum')}>
|
||||||
已成功上传{uploaded}个文件,{failed}个文件上传失败,
|
{__('已成功上传{{uploaded}}个文件,{{failed}}个文件上传失败,', {
|
||||||
<a onClick={this.retry}>重新上传</a>失败文件
|
uploaded,
|
||||||
|
failed
|
||||||
|
})}
|
||||||
|
<a onClick={this.retry}>{__('重试上传')}</a>
|
||||||
|
{__('失败文件。')}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@ -1036,7 +1044,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
|||||||
className={cx('FileControl-uploadBtn')}
|
className={cx('FileControl-uploadBtn')}
|
||||||
onClick={this.toggleUpload}
|
onClick={this.toggleUpload}
|
||||||
>
|
>
|
||||||
{uploading ? '暂停上传' : '开始上传'}
|
{__(uploading ? '暂停上传' : '开始上传')}
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
@ -201,7 +201,8 @@ export default class IconPickerControl extends React.PureComponent<
|
|||||||
classnames: cx,
|
classnames: cx,
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
noDataTip
|
noDataTip,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const options = this.formatOptions();
|
const options = this.formatOptions();
|
||||||
const vendors = this.getVendors();
|
const vendors = this.getVendors();
|
||||||
@ -311,7 +312,7 @@ export default class IconPickerControl extends React.PureComponent<
|
|||||||
: 'IconPickerControl-singleVendor'
|
: 'IconPickerControl-singleVendor'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{noDataTip}
|
{__(noDataTip)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,6 +15,7 @@ import Button from '../../components/Button';
|
|||||||
import accepts from 'attr-accept';
|
import accepts from 'attr-accept';
|
||||||
import {getNameFromUrl} from './File';
|
import {getNameFromUrl} from './File';
|
||||||
import ImageComponent, {ImageThumbProps} from '../Image';
|
import ImageComponent, {ImageThumbProps} from '../Image';
|
||||||
|
import {TranslateFn} from '../../locale';
|
||||||
|
|
||||||
let preventEvent = (e: any) => e.stopPropagation();
|
let preventEvent = (e: any) => e.stopPropagation();
|
||||||
|
|
||||||
@ -139,14 +140,18 @@ export default class ImageControl extends React.Component<
|
|||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sizeInfo(width?: number, height?: number): string {
|
static sizeInfo(
|
||||||
|
width: number | undefined,
|
||||||
|
height: number | undefined,
|
||||||
|
__: TranslateFn
|
||||||
|
): string {
|
||||||
if (!width) {
|
if (!width) {
|
||||||
return `高度${height}px`;
|
return __('高度{{height}}px', {height: height});
|
||||||
} else if (!height) {
|
} else if (!height) {
|
||||||
return `宽度${width}px`;
|
return __('宽度{{width}}px', {width: width});
|
||||||
}
|
}
|
||||||
|
|
||||||
return `尺寸(${width} x ${height})`;
|
return __('尺寸({{width}} x {{height}})', {width, height});
|
||||||
}
|
}
|
||||||
|
|
||||||
state: ImageState = {
|
state: ImageState = {
|
||||||
@ -268,11 +273,12 @@ export default class ImageControl extends React.Component<
|
|||||||
|
|
||||||
buildCrop(props: ImageProps) {
|
buildCrop(props: ImageProps) {
|
||||||
let crop = props.crop;
|
let crop = props.crop;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
if (crop && props.multiple) {
|
if (crop && props.multiple) {
|
||||||
props.env &&
|
props.env &&
|
||||||
props.env.alert &&
|
props.env.alert &&
|
||||||
props.env.alert('图片多选配置和裁剪配置冲突,目前不能二者都支持!');
|
props.env.alert(__('图片多选配置和裁剪配置冲突,目前不能二者都支持!'));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +305,7 @@ export default class ImageControl extends React.Component<
|
|||||||
if (evt.type !== 'change' && evt.type !== 'drop') {
|
if (evt.type !== 'change' && evt.type !== 'drop') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const {multiple, env, accept} = this.props;
|
const {multiple, env, accept, translate: __} = this.props;
|
||||||
|
|
||||||
const files = rejectedFiles.map((file: any) => ({
|
const files = rejectedFiles.map((file: any) => ({
|
||||||
...file,
|
...file,
|
||||||
@ -317,9 +323,10 @@ export default class ImageControl extends React.Component<
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
env.alert(
|
env.alert(
|
||||||
`您添加的文件${files.map(
|
__('您添加的文件{{files}}不符合类型的`{{accept}}`的设定,请仔细检查。', {
|
||||||
(item: any) => `【${item.name}】`
|
files: files.map((file: any) => `「${file.name}」`).join(' '),
|
||||||
)}不符合类型的\`${accept}\`设定,请仔细检查。`
|
accept
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,6 +372,7 @@ export default class ImageControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const env = this.props.env;
|
const env = this.props.env;
|
||||||
|
const __ = this.props.translate;
|
||||||
const file = find(this.files, item => item.state === 'pending') as FileX;
|
const file = find(this.files, item => item.state === 'pending') as FileX;
|
||||||
if (file) {
|
if (file) {
|
||||||
this.current = file;
|
this.current = file;
|
||||||
@ -405,7 +413,7 @@ export default class ImageControl extends React.Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
env.notify('error', error || '图片上传失败,请重试');
|
env.notify('error', error || __('图片上传失败,请重试'));
|
||||||
} else {
|
} else {
|
||||||
newFile = {
|
newFile = {
|
||||||
...obj,
|
...obj,
|
||||||
@ -449,7 +457,7 @@ export default class ImageControl extends React.Component<
|
|||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
this.resolve(
|
this.resolve(
|
||||||
this.files.some(file => file.state === 'error')
|
this.files.some(file => file.state === 'error')
|
||||||
? '文件上传失败请重试'
|
? __('文件上传失败请重试')
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
this.resolve = undefined;
|
this.resolve = undefined;
|
||||||
@ -631,7 +639,7 @@ export default class ImageControl extends React.Component<
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {multiple, maxLength, maxSize, accept} = this.props;
|
const {multiple, maxLength, maxSize, accept, translate: __} = this.props;
|
||||||
let currentFiles = this.files;
|
let currentFiles = this.files;
|
||||||
|
|
||||||
if (!multiple && currentFiles.length) {
|
if (!multiple && currentFiles.length) {
|
||||||
@ -649,11 +657,14 @@ export default class ImageControl extends React.Component<
|
|||||||
[].slice.call(files, 0, allowed).forEach((file: FileX) => {
|
[].slice.call(files, 0, allowed).forEach((file: FileX) => {
|
||||||
if (maxSize && file.size > maxSize) {
|
if (maxSize && file.size > maxSize) {
|
||||||
alert(
|
alert(
|
||||||
`您选择的文件 ${file.name} 大小为 ${ImageControl.formatFileSize(
|
__(
|
||||||
file.size
|
'您选择的文件 {{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} 的限制,请重新选择。',
|
||||||
)} 超出了最大为 ${ImageControl.formatFileSize(
|
{
|
||||||
maxSize
|
filename: file.name,
|
||||||
)} 的限制,请重新选择`
|
actualSize: ImageControl.formatFileSize(file.size),
|
||||||
|
maxSize: ImageControl.formatFileSize(maxSize)
|
||||||
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -691,7 +702,7 @@ export default class ImageControl extends React.Component<
|
|||||||
cb: (error: null | string, file: FileX, obj?: FileValue) => void,
|
cb: (error: null | string, file: FileX, obj?: FileValue) => void,
|
||||||
onProgress: (progress: number) => void
|
onProgress: (progress: number) => void
|
||||||
) {
|
) {
|
||||||
const {limit} = this.props;
|
const {limit, translate: __} = this.props;
|
||||||
|
|
||||||
if (!limit) {
|
if (!limit) {
|
||||||
return this._upload(file, cb, onProgress);
|
return this._upload(file, cb, onProgress);
|
||||||
@ -707,32 +718,33 @@ export default class ImageControl extends React.Component<
|
|||||||
(limit.width && limit.width != width) ||
|
(limit.width && limit.width != width) ||
|
||||||
(limit.height && limit.height != height)
|
(limit.height && limit.height != height)
|
||||||
) {
|
) {
|
||||||
error = `您选择的图片不符合尺寸要求, 请上传${ImageControl.sizeInfo(
|
error = __('您选择的图片不符合尺寸要求, 请上传{{info}}的图片', {
|
||||||
limit.width,
|
info: ImageControl.sizeInfo(limit.width, limit.height, __)
|
||||||
limit.height
|
});
|
||||||
)}的图片`;
|
|
||||||
} else if (
|
} else if (
|
||||||
(limit.maxWidth && limit.maxWidth < width) ||
|
(limit.maxWidth && limit.maxWidth < width) ||
|
||||||
(limit.maxHeight && limit.maxHeight < height)
|
(limit.maxHeight && limit.maxHeight < height)
|
||||||
) {
|
) {
|
||||||
error = `您选择的图片不符合尺寸要求, 请上传不要超过${ImageControl.sizeInfo(
|
error = __('您选择的图片不符合尺寸要求, 请上传不要超过{{info}}的图片', {
|
||||||
limit.maxWidth,
|
info: ImageControl.sizeInfo(limit.maxWidth, limit.maxHeight, __)
|
||||||
limit.maxHeight
|
});
|
||||||
)}的图片`;
|
|
||||||
} else if (
|
} else if (
|
||||||
(limit.minWidth && limit.minWidth > width) ||
|
(limit.minWidth && limit.minWidth > width) ||
|
||||||
(limit.minHeight && limit.minHeight > height)
|
(limit.minHeight && limit.minHeight > height)
|
||||||
) {
|
) {
|
||||||
error = `您选择的图片不符合尺寸要求, 请上传不要小于${ImageControl.sizeInfo(
|
error = __('您选择的图片不符合尺寸要求, 请上传不要小于{{info}}的图片', {
|
||||||
limit.minWidth,
|
info: ImageControl.sizeInfo(limit.minWidth, limit.minHeight, __)
|
||||||
limit.minHeight
|
});
|
||||||
)}的图片`;
|
|
||||||
} else if (
|
} else if (
|
||||||
limit.aspectRatio &&
|
limit.aspectRatio &&
|
||||||
Math.abs(width / height - limit.aspectRatio) > 0.01
|
Math.abs(width / height - limit.aspectRatio) > 0.01
|
||||||
) {
|
) {
|
||||||
error = `您选择的图片不符合尺寸要求, 请上传尺寸比率为 ${limit.aspectRatioLabel ||
|
error = __(
|
||||||
limit.aspectRatio} 的图片`;
|
'您选择的图片不符合尺寸要求, 请上传尺寸比率为 {{ratio}} 的图片',
|
||||||
|
{
|
||||||
|
ratio: limit.aspectRatioLabel || limit.aspectRatio
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -750,10 +762,11 @@ export default class ImageControl extends React.Component<
|
|||||||
cb: (error: null | string, file: Blob, obj?: FileValue) => void,
|
cb: (error: null | string, file: Blob, obj?: FileValue) => void,
|
||||||
onProgress: (progress: number) => void
|
onProgress: (progress: number) => void
|
||||||
) {
|
) {
|
||||||
|
const __ = this.props.translate;
|
||||||
this._send(file, this.props.reciever as string, {}, onProgress)
|
this._send(file, this.props.reciever as string, {}, onProgress)
|
||||||
.then((ret: Payload) => {
|
.then((ret: Payload) => {
|
||||||
if (ret.status) {
|
if (ret.status) {
|
||||||
throw new Error(ret.msg || '上传失败, 请重试');
|
throw new Error(ret.msg || __('上传失败, 请重试'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const obj: FileValue = {
|
const obj: FileValue = {
|
||||||
@ -764,7 +777,7 @@ export default class ImageControl extends React.Component<
|
|||||||
|
|
||||||
cb(null, file, obj);
|
cb(null, file, obj);
|
||||||
})
|
})
|
||||||
.catch(error => cb(error.message || '上传失败,请重试', file));
|
.catch(error => cb(error.message || __('上传失败,请重试'), file));
|
||||||
}
|
}
|
||||||
|
|
||||||
_send(
|
_send(
|
||||||
@ -854,6 +867,8 @@ export default class ImageControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(): any {
|
validate(): any {
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
if (this.state.locked && this.state.lockedReason) {
|
if (this.state.locked && this.state.lockedReason) {
|
||||||
return this.state.lockedReason;
|
return this.state.lockedReason;
|
||||||
} else if (this.state.cropFile) {
|
} else if (this.state.cropFile) {
|
||||||
@ -870,7 +885,7 @@ export default class ImageControl extends React.Component<
|
|||||||
this.startUpload();
|
this.startUpload();
|
||||||
});
|
});
|
||||||
} else if (this.files.some(item => item.state === 'error')) {
|
} else if (this.files.some(item => item.state === 'error')) {
|
||||||
return '文件上传失败请重试';
|
return __('文件上传失败请重试');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -887,7 +902,8 @@ export default class ImageControl extends React.Component<
|
|||||||
hideUploadButton,
|
hideUploadButton,
|
||||||
thumbMode,
|
thumbMode,
|
||||||
thumbRatio,
|
thumbRatio,
|
||||||
reCropable
|
reCropable,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {files, error, crop, uploading, cropFile} = this.state;
|
const {files, error, crop, uploading, cropFile} = this.state;
|
||||||
@ -902,7 +918,7 @@ export default class ImageControl extends React.Component<
|
|||||||
<a
|
<a
|
||||||
className={cx('ImageControl-cropCancel')}
|
className={cx('ImageControl-cropCancel')}
|
||||||
onClick={this.cancelCrop}
|
onClick={this.cancelCrop}
|
||||||
data-tooltip="取消"
|
data-tooltip={__('取消')}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
>
|
>
|
||||||
<Icon icon="close" className="icon" />
|
<Icon icon="close" className="icon" />
|
||||||
@ -910,7 +926,7 @@ export default class ImageControl extends React.Component<
|
|||||||
<a
|
<a
|
||||||
className={cx('ImageControl-cropConfirm')}
|
className={cx('ImageControl-cropConfirm')}
|
||||||
onClick={this.handleCrop}
|
onClick={this.handleCrop}
|
||||||
data-tooltip="确认"
|
data-tooltip={__('确认')}
|
||||||
data-position="left"
|
data-position="left"
|
||||||
>
|
>
|
||||||
<Icon icon="check" className="icon" />
|
<Icon icon="check" className="icon" />
|
||||||
@ -954,7 +970,7 @@ export default class ImageControl extends React.Component<
|
|||||||
'is-reject': isDragReject
|
'is-reject': isDragReject
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
把图片拖到这,然后松开完成添加!
|
{__('把图片拖到这,然后松开完成添加!')}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@ -974,7 +990,7 @@ export default class ImageControl extends React.Component<
|
|||||||
<>
|
<>
|
||||||
<a
|
<a
|
||||||
className={cx('ImageControl-itemClear')}
|
className={cx('ImageControl-itemClear')}
|
||||||
data-tooltip="移除"
|
data-tooltip={__('移除')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
onClick={this.removeFile.bind(
|
onClick={this.removeFile.bind(
|
||||||
this,
|
this,
|
||||||
@ -993,7 +1009,7 @@ export default class ImageControl extends React.Component<
|
|||||||
>
|
>
|
||||||
<Icon icon="retry" className="icon" />
|
<Icon icon="retry" className="icon" />
|
||||||
<p className="ImageControl-itemInfoError">
|
<p className="ImageControl-itemInfoError">
|
||||||
重新上传
|
{__('重新上传')}
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</>
|
</>
|
||||||
@ -1007,7 +1023,7 @@ export default class ImageControl extends React.Component<
|
|||||||
)}
|
)}
|
||||||
key="clear"
|
key="clear"
|
||||||
className={cx('ImageControl-itemClear')}
|
className={cx('ImageControl-itemClear')}
|
||||||
data-tooltip="移除"
|
data-tooltip={__('移除')}
|
||||||
>
|
>
|
||||||
<Icon icon="close" className="icon" />
|
<Icon icon="close" className="icon" />
|
||||||
</a>
|
</a>
|
||||||
@ -1015,7 +1031,7 @@ export default class ImageControl extends React.Component<
|
|||||||
key="info"
|
key="info"
|
||||||
className={cx('ImageControl-itemInfo')}
|
className={cx('ImageControl-itemInfo')}
|
||||||
>
|
>
|
||||||
<p>文件上传中</p>
|
<p>{__('文件上传中')}</p>
|
||||||
<div className={cx('ImageControl-progress')}>
|
<div className={cx('ImageControl-progress')}>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
@ -1067,7 +1083,7 @@ export default class ImageControl extends React.Component<
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<a
|
<a
|
||||||
data-tooltip="查看大图"
|
data-tooltip={__('查看大图')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={file.url || file.preview}
|
href={file.url || file.preview}
|
||||||
@ -1084,7 +1100,7 @@ export default class ImageControl extends React.Component<
|
|||||||
reCropable !== false &&
|
reCropable !== false &&
|
||||||
!disabled ? (
|
!disabled ? (
|
||||||
<a
|
<a
|
||||||
data-tooltip="裁剪图片"
|
data-tooltip={__('裁剪图片')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
onClick={this.editImage.bind(this, key)}
|
onClick={this.editImage.bind(this, key)}
|
||||||
>
|
>
|
||||||
@ -1093,7 +1109,7 @@ export default class ImageControl extends React.Component<
|
|||||||
) : null}
|
) : null}
|
||||||
{!disabled ? (
|
{!disabled ? (
|
||||||
<a
|
<a
|
||||||
data-tooltip="移除"
|
data-tooltip={__('移除')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
onClick={this.removeFile.bind(
|
onClick={this.removeFile.bind(
|
||||||
this,
|
this,
|
||||||
@ -1128,14 +1144,14 @@ export default class ImageControl extends React.Component<
|
|||||||
'is-disabled': disabled
|
'is-disabled': disabled
|
||||||
})}
|
})}
|
||||||
onClick={this.handleSelect}
|
onClick={this.handleSelect}
|
||||||
data-tooltip={placeholder}
|
data-tooltip={__(placeholder)}
|
||||||
data-position="right"
|
data-position="right"
|
||||||
>
|
>
|
||||||
<Icon icon="plus" className="icon" />
|
<Icon icon="plus" className="icon" />
|
||||||
|
|
||||||
{isFocused ? (
|
{isFocused ? (
|
||||||
<span className={cx('ImageControl-pasteTip')}>
|
<span className={cx('ImageControl-pasteTip')}>
|
||||||
当前状态支持从剪切板中粘贴图片文件。
|
{__('当前状态支持从剪切板中粘贴图片文件。')}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</label>
|
</label>
|
||||||
@ -1148,7 +1164,7 @@ export default class ImageControl extends React.Component<
|
|||||||
disabled={!hasPending}
|
disabled={!hasPending}
|
||||||
onClick={this.toggleUpload}
|
onClick={this.toggleUpload}
|
||||||
>
|
>
|
||||||
{uploading ? '暂停上传' : '开始上传'}
|
{__(uploading ? '暂停上传' : '开始上传')}
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ export default class MatrixCheckbox extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
async reload() {
|
async reload() {
|
||||||
const {source, data, env, onChange} = this.props;
|
const {source, data, env, onChange, translate: __} = this.props;
|
||||||
|
|
||||||
if (!isEffectiveApi(source, data) || this.state.loading) {
|
if (!isEffectiveApi(source, data) || this.state.loading) {
|
||||||
return;
|
return;
|
||||||
@ -159,7 +159,7 @@ export default class MatrixCheckbox extends React.Component<
|
|||||||
.fetcher(source, data)
|
.fetcher(source, data)
|
||||||
.then(ret => {
|
.then(ret => {
|
||||||
if (!ret.ok) {
|
if (!ret.ok) {
|
||||||
throw new Error(ret.msg || '数据请求错误');
|
throw new Error(ret.msg || __('数据请求错误'));
|
||||||
}
|
}
|
||||||
if (!this.mounted) {
|
if (!this.mounted) {
|
||||||
return resolve();
|
return resolve();
|
||||||
|
@ -393,7 +393,8 @@ export default class NestedSelectControl extends React.Component<
|
|||||||
options,
|
options,
|
||||||
disabled,
|
disabled,
|
||||||
searchable,
|
searchable,
|
||||||
searchPromptText
|
searchPromptText,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const stack = this.state.stack;
|
const stack = this.state.stack;
|
||||||
@ -410,7 +411,7 @@ export default class NestedSelectControl extends React.Component<
|
|||||||
onFocus={this.onFocus}
|
onFocus={this.onFocus}
|
||||||
onBlur={this.onBlur}
|
onBlur={this.onBlur}
|
||||||
disabled={disabled!!}
|
disabled={disabled!!}
|
||||||
placeholder={searchPromptText}
|
placeholder={__(searchPromptText)}
|
||||||
onChange={this.handleInputChange}
|
onChange={this.handleInputChange}
|
||||||
ref={this.inputRef}
|
ref={this.inputRef}
|
||||||
/>
|
/>
|
||||||
|
@ -539,7 +539,8 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
valueField,
|
valueField,
|
||||||
formItem: model,
|
formItem: model,
|
||||||
createBtnLabel,
|
createBtnLabel,
|
||||||
env
|
env,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
// 禁用或者没有配置 name
|
// 禁用或者没有配置 name
|
||||||
@ -554,7 +555,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
name: labelField || 'label',
|
name: labelField || 'label',
|
||||||
label: false,
|
label: false,
|
||||||
placeholder: '请输入名称'
|
placeholder: __('请输入名称')
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -650,7 +651,8 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
source,
|
source,
|
||||||
data,
|
data,
|
||||||
formItem: model,
|
formItem: model,
|
||||||
optionLabel
|
optionLabel,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (disabled || !model) {
|
if (disabled || !model) {
|
||||||
@ -663,7 +665,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
name: labelField || 'label',
|
name: labelField || 'label',
|
||||||
label: false,
|
label: false,
|
||||||
placeholder: '请输入名称'
|
placeholder: __('请输入名称')
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -673,7 +675,9 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
: await onOpenDialog(
|
: await onOpenDialog(
|
||||||
{
|
{
|
||||||
type: 'dialog',
|
type: 'dialog',
|
||||||
title: `编辑${optionLabel || '选项'}`,
|
title: __('编辑{{label}}', {
|
||||||
|
label: optionLabel || '选项'
|
||||||
|
}),
|
||||||
body: {
|
body: {
|
||||||
type: 'form',
|
type: 'form',
|
||||||
api: editApi,
|
api: editApi,
|
||||||
@ -695,7 +699,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!payload.ok) {
|
if (!payload.ok) {
|
||||||
env.notify('error', payload.msg || '保存失败,请仔细检查');
|
env.notify('error', payload.msg || __('保存失败,请仔细检查'));
|
||||||
result = null;
|
result = null;
|
||||||
} else {
|
} else {
|
||||||
result = payload.data || result;
|
result = payload.data || result;
|
||||||
@ -738,7 +742,8 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
env,
|
env,
|
||||||
formItem: model,
|
formItem: model,
|
||||||
source,
|
source,
|
||||||
valueField
|
valueField,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (disabled || !model) {
|
if (disabled || !model) {
|
||||||
@ -758,7 +763,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
// 通过 deleteApi 删除。
|
// 通过 deleteApi 删除。
|
||||||
try {
|
try {
|
||||||
if (!deleteApi) {
|
if (!deleteApi) {
|
||||||
throw new Error('请配置 deleteApi');
|
throw new Error(__('请配置 deleteApi'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await env.fetcher(deleteApi!, ctx, {
|
const result = await env.fetcher(deleteApi!, ctx, {
|
||||||
@ -766,7 +771,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
env.notify('error', result.msg || '删除失败,请重试');
|
env.notify('error', result.msg || __('删除失败,请重试'));
|
||||||
} else if (source) {
|
} else if (source) {
|
||||||
this.reload();
|
this.reload();
|
||||||
} else {
|
} else {
|
||||||
|
@ -382,7 +382,8 @@ export default class PickerControl extends React.PureComponent<
|
|||||||
placeholder,
|
placeholder,
|
||||||
embed,
|
embed,
|
||||||
value,
|
value,
|
||||||
selectedOptions
|
selectedOptions,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<div className={cx(`PickerControl`, className)}>
|
<div className={cx(`PickerControl`, className)}>
|
||||||
@ -399,7 +400,9 @@ export default class PickerControl extends React.PureComponent<
|
|||||||
>
|
>
|
||||||
<div onClick={this.handleClick} className={cx('Picker-input')}>
|
<div onClick={this.handleClick} className={cx('Picker-input')}>
|
||||||
{!selectedOptions.length && placeholder ? (
|
{!selectedOptions.length && placeholder ? (
|
||||||
<div className={cx('Picker-placeholder')}>{placeholder}</div>
|
<div className={cx('Picker-placeholder')}>
|
||||||
|
{__(placeholder)}
|
||||||
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className={cx('Picker-valueWrap')}>
|
<div className={cx('Picker-valueWrap')}>
|
||||||
@ -427,7 +430,7 @@ export default class PickerControl extends React.PureComponent<
|
|||||||
{render(
|
{render(
|
||||||
'modal',
|
'modal',
|
||||||
{
|
{
|
||||||
title: '请选择',
|
title: __('请选择'),
|
||||||
size: size,
|
size: size,
|
||||||
type: modalMode,
|
type: modalMode,
|
||||||
body: {
|
body: {
|
||||||
|
@ -63,7 +63,8 @@ export default class RadiosControl extends React.Component<RadiosProps, any> {
|
|||||||
classPrefix,
|
classPrefix,
|
||||||
itemClassName,
|
itemClassName,
|
||||||
labelClassName,
|
labelClassName,
|
||||||
labelField
|
labelField,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -78,7 +79,7 @@ export default class RadiosControl extends React.Component<RadiosProps, any> {
|
|||||||
delimiter={delimiter!}
|
delimiter={delimiter!}
|
||||||
labelClassName={labelClassName}
|
labelClassName={labelClassName}
|
||||||
labelField={labelField}
|
labelField={labelField}
|
||||||
placeholder={placeholder}
|
placeholder={__(placeholder)}
|
||||||
options={options}
|
options={options}
|
||||||
columnsCount={columnsCount}
|
columnsCount={columnsCount}
|
||||||
classPrefix={classPrefix}
|
classPrefix={classPrefix}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
*
|
*
|
||||||
* 不建议用,以后可能会删除。可以直接用组合出来,不需要新建一个组件。
|
* 不建议用,以后可能会删除。可以直接用组合出来,不需要新建一个组件。
|
||||||
*/
|
*/
|
||||||
/* eslint fecs-indent: [0, "space", 2, 2] */
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
@ -59,7 +58,13 @@ export default class RepeatControl extends React.Component<RepeatProps, any> {
|
|||||||
renderInput() {
|
renderInput() {
|
||||||
const value = this.props.value;
|
const value = this.props.value;
|
||||||
const parts = value ? value.split(':') : [];
|
const parts = value ? value.split(':') : [];
|
||||||
let {options, placeholder, disabled, classPrefix: ns} = this.props;
|
let {
|
||||||
|
options,
|
||||||
|
placeholder,
|
||||||
|
disabled,
|
||||||
|
classPrefix: ns,
|
||||||
|
translate: __
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
let optionsArray: Array<Option> = [];
|
let optionsArray: Array<Option> = [];
|
||||||
|
|
||||||
@ -69,7 +74,7 @@ export default class RepeatControl extends React.Component<RepeatProps, any> {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
optionsArray.unshift({
|
optionsArray.unshift({
|
||||||
label: placeholder as string,
|
label: __(placeholder as string),
|
||||||
value: ''
|
value: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -182,7 +187,7 @@ export default class RepeatControl extends React.Component<RepeatProps, any> {
|
|||||||
<div className="repeat-control hbox">
|
<div className="repeat-control hbox">
|
||||||
{input ? (
|
{input ? (
|
||||||
<div className="col v-middle" style={{width: 30}}>
|
<div className="col v-middle" style={{width: 30}}>
|
||||||
<span>每</span>
|
<span>{__('每')}</span>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@ -193,7 +198,7 @@ export default class RepeatControl extends React.Component<RepeatProps, any> {
|
|||||||
classPrefix={ns}
|
classPrefix={ns}
|
||||||
className={input ? 'pull-right' : ''}
|
className={input ? 'pull-right' : ''}
|
||||||
options={optionsArray}
|
options={optionsArray}
|
||||||
placeholder={placeholder}
|
placeholder={__(placeholder)}
|
||||||
onChange={this.handleOptionChange}
|
onChange={this.handleOptionChange}
|
||||||
value={parts[0]}
|
value={parts[0]}
|
||||||
clearable={false}
|
clearable={false}
|
||||||
|
@ -34,7 +34,6 @@ export default class RichTextControl extends React.Component<
|
|||||||
videoReciever: '/api/upload/video',
|
videoReciever: '/api/upload/video',
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
options: {
|
options: {
|
||||||
language: 'zh_cn',
|
|
||||||
toolbarButtonsSM: [
|
toolbarButtonsSM: [
|
||||||
'paragraphFormat',
|
'paragraphFormat',
|
||||||
'quote',
|
'quote',
|
||||||
@ -156,7 +155,9 @@ export default class RichTextControl extends React.Component<
|
|||||||
...(props.options && props.options.events),
|
...(props.options && props.options.events),
|
||||||
'froalaEditor.focus': this.handleFocus,
|
'froalaEditor.focus': this.handleFocus,
|
||||||
'froalaEditor.blur': this.handleBlur
|
'froalaEditor.blur': this.handleBlur
|
||||||
}
|
},
|
||||||
|
language:
|
||||||
|
!this.props.locale || this.props.locale === 'zh-cn' ? 'zh_cn' : ''
|
||||||
};
|
};
|
||||||
|
|
||||||
if (props.buttons) {
|
if (props.buttons) {
|
||||||
@ -178,10 +179,15 @@ export default class RichTextControl extends React.Component<
|
|||||||
formData.append('file', blobInfo.blob(), blobInfo.filename());
|
formData.append('file', blobInfo.blob(), blobInfo.filename());
|
||||||
try {
|
try {
|
||||||
const response = await fetcher(props.reciever, formData, {
|
const response = await fetcher(props.reciever, formData, {
|
||||||
method: 'post',
|
method: 'post'
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
ok(response.data?.link || response.data?.url || response.data?.value || (response as any).link);
|
ok(
|
||||||
|
response.data?.link ||
|
||||||
|
response.data?.url ||
|
||||||
|
response.data?.value ||
|
||||||
|
(response as any).link
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
fail(e);
|
fail(e);
|
||||||
@ -212,7 +218,9 @@ export default class RichTextControl extends React.Component<
|
|||||||
disabled,
|
disabled,
|
||||||
size,
|
size,
|
||||||
vendor,
|
vendor,
|
||||||
env
|
env,
|
||||||
|
locale,
|
||||||
|
translate
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const finnalVendor = vendor || (env.richTextToken ? 'froala' : 'tinymce');
|
const finnalVendor = vendor || (env.richTextToken ? 'froala' : 'tinymce');
|
||||||
@ -232,6 +240,8 @@ export default class RichTextControl extends React.Component<
|
|||||||
onBlur={this.handleBlur}
|
onBlur={this.handleBlur}
|
||||||
config={this.config}
|
config={this.config}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
locale={locale}
|
||||||
|
translate={translate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -151,7 +151,8 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
value,
|
value,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
render,
|
render,
|
||||||
data
|
data,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -169,7 +170,7 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
key={key}
|
key={key}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
data-tooltip="删除"
|
data-tooltip={__('删除')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
className={`${ns}Select-valueIcon`}
|
className={`${ns}Select-valueIcon`}
|
||||||
onClick={this.removeItem.bind(this, key)}
|
onClick={this.removeItem.bind(this, key)}
|
||||||
@ -179,7 +180,7 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
<span
|
<span
|
||||||
onClick={this.open.bind(this, key)}
|
onClick={this.open.bind(this, key)}
|
||||||
className={`${ns}SubForm-valueLabel`}
|
className={`${ns}SubForm-valueLabel`}
|
||||||
data-tooltip="编辑详情"
|
data-tooltip={__('编辑详情')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
>
|
>
|
||||||
{(value &&
|
{(value &&
|
||||||
@ -190,7 +191,7 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
'label',
|
'label',
|
||||||
{
|
{
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: btnLabel
|
tpl: __(btnLabel)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: createObject(data, value)
|
data: createObject(data, value)
|
||||||
@ -207,10 +208,10 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
onClick={this.addItem}
|
onClick={this.addItem}
|
||||||
className={cx(`${ns}Button ${ns}SubForm-addBtn`, addButtonClassName)}
|
className={cx(`${ns}Button ${ns}SubForm-addBtn`, addButtonClassName)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
data-tooltip="新增一条数据"
|
data-tooltip={__('新增一条数据')}
|
||||||
>
|
>
|
||||||
<i className="fa fa-plus m-r-xs" />
|
<i className="fa fa-plus m-r-xs" />
|
||||||
<span>新增</span>
|
<span>{__('新增')}</span>
|
||||||
</button>
|
</button>
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -224,7 +225,8 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
labelField,
|
labelField,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
render,
|
render,
|
||||||
data
|
data,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -238,7 +240,7 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
btnClassName
|
btnClassName
|
||||||
)}
|
)}
|
||||||
onClick={this.open.bind(this, 0)}
|
onClick={this.open.bind(this, 0)}
|
||||||
data-tooltip="编辑详情"
|
data-tooltip={__('编辑详情')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
>
|
>
|
||||||
<span className={`${ns}SubForm-valueLabel`}>
|
<span className={`${ns}SubForm-valueLabel`}>
|
||||||
@ -250,7 +252,7 @@ export default class SubFormControl extends React.PureComponent<
|
|||||||
'label',
|
'label',
|
||||||
{
|
{
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: btnLabel
|
tpl: __(btnLabel)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: createObject(data, value)
|
data: createObject(data, value)
|
||||||
|
@ -10,7 +10,7 @@ import omit from 'lodash/omit';
|
|||||||
import {dataMapping} from '../../utils/tpl-builtin';
|
import {dataMapping} from '../../utils/tpl-builtin';
|
||||||
import findIndex from 'lodash/findIndex';
|
import findIndex from 'lodash/findIndex';
|
||||||
import memoize from 'lodash/memoize';
|
import memoize from 'lodash/memoize';
|
||||||
import { SimpleMap } from '../../utils/SimpleMap';
|
import {SimpleMap} from '../../utils/SimpleMap';
|
||||||
|
|
||||||
export interface TableProps extends FormControlProps {
|
export interface TableProps extends FormControlProps {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@ -103,12 +103,18 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(): any {
|
validate(): any {
|
||||||
const {value, minLength, maxLength} = this.props;
|
const {value, minLength, maxLength, translate: __} = this.props;
|
||||||
|
|
||||||
if (minLength && (!Array.isArray(value) || value.length < minLength)) {
|
if (minLength && (!Array.isArray(value) || value.length < minLength)) {
|
||||||
return `组合表单成员数量不够,低于最小的设定${minLength}个,请添加更多的成员。`;
|
return __(
|
||||||
|
'组合表单成员数量不够,低于设定的最小{{minLenth}}个,请添加更多的成员。',
|
||||||
|
{minLength}
|
||||||
|
);
|
||||||
} else if (maxLength && Array.isArray(value) && value.length > maxLength) {
|
} else if (maxLength && Array.isArray(value) && value.length > maxLength) {
|
||||||
return `组合表单成员数量超出,超出最大的设定${maxLength}个,请删除多余的成员。`;
|
return __(
|
||||||
|
'组合表单成员数量超出,超出设定的最大{{maxLength}}个,请删除多余的成员。',
|
||||||
|
{maxLength}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const subForms: Array<any> = [];
|
const subForms: Array<any> = [];
|
||||||
Object.keys(this.subForms).forEach(
|
Object.keys(this.subForms).forEach(
|
||||||
@ -118,7 +124,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
return Promise.all(subForms.map(item => item.validate())).then(
|
return Promise.all(subForms.map(item => item.validate())).then(
|
||||||
values => {
|
values => {
|
||||||
if (~values.indexOf(false)) {
|
if (~values.indexOf(false)) {
|
||||||
return '内部表单验证失败';
|
return __('内部表单验证失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -129,7 +135,15 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
doAction(action: Action, ctx: RendererData, ...rest: Array<any>) {
|
doAction(action: Action, ctx: RendererData, ...rest: Array<any>) {
|
||||||
const {onAction, value, valueField, env, onChange, editable} = this.props;
|
const {
|
||||||
|
onAction,
|
||||||
|
value,
|
||||||
|
valueField,
|
||||||
|
env,
|
||||||
|
onChange,
|
||||||
|
editable,
|
||||||
|
translate: __
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (action.actionType === 'add') {
|
if (action.actionType === 'add') {
|
||||||
const rows = Array.isArray(value) ? value.concat() : [];
|
const rows = Array.isArray(value) ? value.concat() : [];
|
||||||
@ -166,9 +180,9 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
action.actionType === 'delete'
|
action.actionType === 'delete'
|
||||||
) {
|
) {
|
||||||
if (!valueField) {
|
if (!valueField) {
|
||||||
return env.alert('请配置 valueField');
|
return env.alert(__('请配置 valueField'));
|
||||||
} else if (!action.payload) {
|
} else if (!action.payload) {
|
||||||
return env.alert('action 上请配置 payload, 否则不清楚要删除哪个');
|
return env.alert(__('action 上请配置 payload, 否则不清楚要删除哪个'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = Array.isArray(value) ? value.concat() : [];
|
const rows = Array.isArray(value) ? value.concat() : [];
|
||||||
@ -226,7 +240,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
addApi,
|
addApi,
|
||||||
updateApi,
|
updateApi,
|
||||||
data,
|
data,
|
||||||
env
|
env,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
// form 是 lazyChange 的,先让他们 flush, 即把未提交的数据提交。
|
// form 是 lazyChange 的,先让他们 flush, 即把未提交的数据提交。
|
||||||
@ -252,11 +267,13 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (remote && !remote.ok) {
|
if (remote && !remote.ok) {
|
||||||
env.notify('error', remote.msg || '保存失败');
|
env.notify('error', remote.msg || __('保存失败'));
|
||||||
return;
|
return;
|
||||||
} else if (remote && remote.ok) {
|
} else if (remote && remote.ok) {
|
||||||
item = {
|
item = {
|
||||||
...((isNew ? addApi : updateApi) as ApiObject).replaceData ? {} : item,
|
...(((isNew ? addApi : updateApi) as ApiObject).replaceData
|
||||||
|
? {}
|
||||||
|
: item),
|
||||||
...remote.data
|
...remote.data
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -291,7 +308,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
deleteApi,
|
deleteApi,
|
||||||
deleteConfirmText,
|
deleteConfirmText,
|
||||||
env,
|
env,
|
||||||
data
|
data,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let newValue = Array.isArray(value) ? value.concat() : [];
|
let newValue = Array.isArray(value) ? value.concat() : [];
|
||||||
const item = newValue[index];
|
const item = newValue[index];
|
||||||
@ -303,7 +321,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
const ctx = createObject(data, item);
|
const ctx = createObject(data, item);
|
||||||
if (isEffectiveApi(deleteApi, ctx)) {
|
if (isEffectiveApi(deleteApi, ctx)) {
|
||||||
const confirmed = await env.confirm(
|
const confirmed = await env.confirm(
|
||||||
deleteConfirmText ? filter(deleteConfirmText, ctx) : '确认要删除?'
|
deleteConfirmText ? filter(deleteConfirmText, ctx) : __('确认要删除?')
|
||||||
);
|
);
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
// 如果不确认,则跳过!
|
// 如果不确认,则跳过!
|
||||||
@ -313,7 +331,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
const result = await env.fetcher(deleteApi, ctx);
|
const result = await env.fetcher(deleteApi, ctx);
|
||||||
|
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
env.notify('error', '删除失败');
|
env.notify('error', __('删除失败'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,6 +357,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
? props.columns.concat()
|
? props.columns.concat()
|
||||||
: [];
|
: [];
|
||||||
const ns = this.props.classPrefix;
|
const ns = this.props.classPrefix;
|
||||||
|
const __ = this.props.translate;
|
||||||
|
|
||||||
let btns = [];
|
let btns = [];
|
||||||
if (props.addable && props.showAddBtn !== false) {
|
if (props.addable && props.showAddBtn !== false) {
|
||||||
@ -350,7 +369,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
size="sm"
|
size="sm"
|
||||||
key={key}
|
key={key}
|
||||||
level="link"
|
level="link"
|
||||||
tooltip="新增一行"
|
tooltip={__('新增一行')}
|
||||||
tooltipContainer={
|
tooltipContainer={
|
||||||
env && env.getModalContainer ? env.getModalContainer : undefined
|
env && env.getModalContainer ? env.getModalContainer : undefined
|
||||||
}
|
}
|
||||||
@ -399,7 +418,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
size="sm"
|
size="sm"
|
||||||
key={key}
|
key={key}
|
||||||
level="link"
|
level="link"
|
||||||
tooltip="编辑当前行"
|
tooltip={__('编辑当前行')}
|
||||||
tooltipContainer={
|
tooltipContainer={
|
||||||
env && env.getModalContainer ? env.getModalContainer : undefined
|
env && env.getModalContainer ? env.getModalContainer : undefined
|
||||||
}
|
}
|
||||||
@ -423,7 +442,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
size="sm"
|
size="sm"
|
||||||
key={key}
|
key={key}
|
||||||
level="link"
|
level="link"
|
||||||
tooltip="保存"
|
tooltip={__('保存')}
|
||||||
tooltipContainer={
|
tooltipContainer={
|
||||||
env && env.getModalContainer ? env.getModalContainer : undefined
|
env && env.getModalContainer ? env.getModalContainer : undefined
|
||||||
}
|
}
|
||||||
@ -447,7 +466,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
size="sm"
|
size="sm"
|
||||||
key={key}
|
key={key}
|
||||||
level="link"
|
level="link"
|
||||||
tooltip="取消"
|
tooltip={__('取消')}
|
||||||
tooltipContainer={
|
tooltipContainer={
|
||||||
env && env.getModalContainer ? env.getModalContainer : undefined
|
env && env.getModalContainer ? env.getModalContainer : undefined
|
||||||
}
|
}
|
||||||
@ -481,7 +500,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
size="sm"
|
size="sm"
|
||||||
key={key}
|
key={key}
|
||||||
level="link"
|
level="link"
|
||||||
tooltip="删除当前行"
|
tooltip={__('删除当前行')}
|
||||||
tooltipContainer={
|
tooltipContainer={
|
||||||
env && env.getModalContainer ? env.getModalContainer : undefined
|
env && env.getModalContainer ? env.getModalContainer : undefined
|
||||||
}
|
}
|
||||||
@ -503,7 +522,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
type: 'operation',
|
type: 'operation',
|
||||||
buttons: btns,
|
buttons: btns,
|
||||||
width: 150,
|
width: 150,
|
||||||
label: '操作'
|
label: __('操作')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,7 +595,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
buildItems = memoize(
|
buildItems = memoize(
|
||||||
(value: Array<any>, editIndex: number) => {
|
(value: Array<any>, editIndex: number) => {
|
||||||
return value.map((value: any, index: number) =>
|
return value.map((value: any, index: number) =>
|
||||||
index === editIndex ? this.state.editting : value)
|
index === editIndex ? this.state.editting : value
|
||||||
|
);
|
||||||
},
|
},
|
||||||
(...args: Array<any>) => JSON.stringify(args)
|
(...args: Array<any>) => JSON.stringify(args)
|
||||||
);
|
);
|
||||||
@ -592,7 +612,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
draggable,
|
draggable,
|
||||||
addable,
|
addable,
|
||||||
columnsTogglable,
|
columnsTogglable,
|
||||||
combineNum
|
combineNum,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -601,7 +622,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
'body',
|
'body',
|
||||||
{
|
{
|
||||||
type: 'table',
|
type: 'table',
|
||||||
placeholder,
|
placeholder: __(placeholder),
|
||||||
columns: this.state.columns,
|
columns: this.state.columns,
|
||||||
affixHeader: false
|
affixHeader: false
|
||||||
},
|
},
|
||||||
@ -610,12 +631,14 @@ export default class FormTable extends React.Component<TableProps, TableState> {
|
|||||||
saveImmediately: true,
|
saveImmediately: true,
|
||||||
disabled,
|
disabled,
|
||||||
draggable: draggable && !~this.state.editIndex,
|
draggable: draggable && !~this.state.editIndex,
|
||||||
items: this.buildItems((Array.isArray(value) && value.length
|
items: this.buildItems(
|
||||||
? value
|
Array.isArray(value) && value.length
|
||||||
: addable && showAddBtn !== false
|
? value
|
||||||
? [{__isPlaceholder: true}]
|
: addable && showAddBtn !== false
|
||||||
: []
|
? [{__isPlaceholder: true}]
|
||||||
), this.state.editIndex),
|
: [],
|
||||||
|
this.state.editIndex
|
||||||
|
),
|
||||||
getEntryId: this.getEntryId,
|
getEntryId: this.getEntryId,
|
||||||
onSave: this.handleTableSave,
|
onSave: this.handleTableSave,
|
||||||
onSaveOrder: this.handleSaveTableOrder,
|
onSaveOrder: this.handleSaveTableOrder,
|
||||||
|
@ -2,7 +2,7 @@ import {OptionsControlProps, OptionsControl} from './Options';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Api} from '../../types';
|
import {Api} from '../../types';
|
||||||
import Spinner from '../../components/Spinner';
|
import Spinner from '../../components/Spinner';
|
||||||
import {TransferRenderer} from './Transfer';
|
import {BaseTransferRenderer} from './Transfer';
|
||||||
import TabsTransfer from '../../components/TabsTransfer';
|
import TabsTransfer from '../../components/TabsTransfer';
|
||||||
|
|
||||||
export interface TabsTransferProps extends OptionsControlProps {
|
export interface TabsTransferProps extends OptionsControlProps {
|
||||||
@ -16,7 +16,9 @@ export interface TabsTransferProps extends OptionsControlProps {
|
|||||||
@OptionsControl({
|
@OptionsControl({
|
||||||
type: 'tabs-transfer'
|
type: 'tabs-transfer'
|
||||||
})
|
})
|
||||||
export class TabsTransferRenderer extends TransferRenderer<TabsTransferProps> {
|
export class TabsTransferRenderer extends BaseTransferRenderer<
|
||||||
|
TabsTransferProps
|
||||||
|
> {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
className,
|
className,
|
||||||
|
@ -271,7 +271,8 @@ export default class TagControl extends React.PureComponent<
|
|||||||
popOverContainer,
|
popOverContainer,
|
||||||
dropdown,
|
dropdown,
|
||||||
options,
|
options,
|
||||||
optionsTip
|
optionsTip,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const finnalOptions = Array.isArray(options)
|
const finnalOptions = Array.isArray(options)
|
||||||
@ -300,7 +301,7 @@ export default class TagControl extends React.PureComponent<
|
|||||||
{...getInputProps({
|
{...getInputProps({
|
||||||
name,
|
name,
|
||||||
ref: this.input,
|
ref: this.input,
|
||||||
placeholder: placeholder || '暂无标签',
|
placeholder: __(placeholder || '暂无标签'),
|
||||||
value: this.state.inputValue,
|
value: this.state.inputValue,
|
||||||
onKeyDown: this.handleKeyDown,
|
onKeyDown: this.handleKeyDown,
|
||||||
onFocus: this.handleFocus,
|
onFocus: this.handleFocus,
|
||||||
@ -348,7 +349,9 @@ export default class TagControl extends React.PureComponent<
|
|||||||
// 保留原来的展现方式,不推荐
|
// 保留原来的展现方式,不推荐
|
||||||
<div className={cx('TagControl-sug')}>
|
<div className={cx('TagControl-sug')}>
|
||||||
{optionsTip ? (
|
{optionsTip ? (
|
||||||
<div className={cx('TagControl-sugTip')}>{optionsTip}</div>
|
<div className={cx('TagControl-sugTip')}>
|
||||||
|
{__(optionsTip)}
|
||||||
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{options.map((item, index) => (
|
{options.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
|
@ -415,7 +415,8 @@ export default class TextControl extends React.PureComponent<
|
|||||||
labelField,
|
labelField,
|
||||||
valueField,
|
valueField,
|
||||||
multiple,
|
multiple,
|
||||||
spinnerClassName
|
spinnerClassName,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -542,7 +543,7 @@ export default class TextControl extends React.PureComponent<
|
|||||||
>
|
>
|
||||||
{option.isNew ? (
|
{option.isNew ? (
|
||||||
<span>
|
<span>
|
||||||
新增:{option.label}
|
{__('新增:{{label}}', {label: option.label})}
|
||||||
<Icon icon="enter" className="icon" />
|
<Icon icon="enter" className="icon" />
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
|
@ -15,7 +15,7 @@ import find from 'lodash/find';
|
|||||||
import {optionValueCompare} from '../../components/Select';
|
import {optionValueCompare} from '../../components/Select';
|
||||||
import {resolveVariable} from '../../utils/tpl-builtin';
|
import {resolveVariable} from '../../utils/tpl-builtin';
|
||||||
|
|
||||||
export interface TransferProps extends OptionsControlProps {
|
export interface BaseTransferProps extends OptionsControlProps {
|
||||||
showArrow?: boolean;
|
showArrow?: boolean;
|
||||||
sortable?: boolean;
|
sortable?: boolean;
|
||||||
selectMode?: 'table' | 'list' | 'tree' | 'chained' | 'associated';
|
selectMode?: 'table' | 'list' | 'tree' | 'chained' | 'associated';
|
||||||
@ -29,8 +29,8 @@ export interface TransferProps extends OptionsControlProps {
|
|||||||
searchApi?: Api;
|
searchApi?: Api;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TransferRenderer<
|
export class BaseTransferRenderer<
|
||||||
T extends OptionsControlProps = TransferProps
|
T extends OptionsControlProps = BaseTransferProps
|
||||||
> extends React.Component<T> {
|
> extends React.Component<T> {
|
||||||
@autobind
|
@autobind
|
||||||
handleChange(value: Array<Option>) {
|
handleChange(value: Array<Option>) {
|
||||||
@ -212,6 +212,9 @@ export class TransferRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ts 3.9 里面非得这样才不报错,鬼知道为何。
|
||||||
|
export class TransferRender extends BaseTransferRenderer {}
|
||||||
|
|
||||||
export default OptionsControl({
|
export default OptionsControl({
|
||||||
type: 'transfer'
|
type: 'transfer'
|
||||||
})(TransferRenderer);
|
})(TransferRender);
|
||||||
|
@ -69,7 +69,8 @@ export default class TreeControl extends React.Component<TreeProps> {
|
|||||||
removeTip,
|
removeTip,
|
||||||
onDelete,
|
onDelete,
|
||||||
rootCreatable,
|
rootCreatable,
|
||||||
rootCreateTip
|
rootCreateTip,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -84,7 +85,7 @@ export default class TreeControl extends React.Component<TreeProps> {
|
|||||||
joinValues={joinValues}
|
joinValues={joinValues}
|
||||||
extractValue={extractValue}
|
extractValue={extractValue}
|
||||||
delimiter={delimiter}
|
delimiter={delimiter}
|
||||||
placeholder={placeholder}
|
placeholder={__(placeholder)}
|
||||||
options={options}
|
options={options}
|
||||||
multiple={multiple}
|
multiple={multiple}
|
||||||
initiallyOpen={initiallyOpen}
|
initiallyOpen={initiallyOpen}
|
||||||
@ -92,7 +93,7 @@ export default class TreeControl extends React.Component<TreeProps> {
|
|||||||
withChildren={withChildren}
|
withChildren={withChildren}
|
||||||
onlyChildren={onlyChildren}
|
onlyChildren={onlyChildren}
|
||||||
hideRoot={hideRoot}
|
hideRoot={hideRoot}
|
||||||
rootLabel={rootLabel}
|
rootLabel={__(rootLabel)}
|
||||||
rootValue={rootValue}
|
rootValue={rootValue}
|
||||||
showIcon={showIcon}
|
showIcon={showIcon}
|
||||||
showRadio={showRadio}
|
showRadio={showRadio}
|
||||||
|
@ -132,15 +132,21 @@ export default class TreeSelectControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(): any {
|
validate(): any {
|
||||||
const {value, minLength, maxLength, delimiter} = this.props;
|
const {value, minLength, maxLength, delimiter, translate: __} = this.props;
|
||||||
|
|
||||||
let curValue = Array.isArray(value)
|
let curValue = Array.isArray(value)
|
||||||
? value
|
? value
|
||||||
: (value ? String(value) : '').split(delimiter || ',');
|
: (value ? String(value) : '').split(delimiter || ',');
|
||||||
if (minLength && curValue.length < minLength) {
|
if (minLength && curValue.length < minLength) {
|
||||||
return `已选择数量低于设定的最小个数${minLength},请选择更多的选项。`;
|
return __(
|
||||||
|
'已选择数量低于设定的最小个数${minLength},请选择更多的选项。',
|
||||||
|
{minLength}
|
||||||
|
);
|
||||||
} else if (maxLength && curValue.length > maxLength) {
|
} else if (maxLength && curValue.length > maxLength) {
|
||||||
return `已选择数量超出设定的最大个数${maxLength},请取消选择超出的选项。`;
|
return __(
|
||||||
|
'已选择数量超出设定的最大个数{{maxLength}},请取消选择超出的选项。',
|
||||||
|
{maxLength}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +327,8 @@ export default class TreeSelectControl extends React.Component<
|
|||||||
labelField,
|
labelField,
|
||||||
disabled,
|
disabled,
|
||||||
placeholder,
|
placeholder,
|
||||||
classnames: cx
|
classnames: cx,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if ((!multiple || !selectedOptions.length) && this.state.inputValue) {
|
if ((!multiple || !selectedOptions.length) && this.state.inputValue) {
|
||||||
@ -355,7 +362,7 @@ export default class TreeSelectControl extends React.Component<
|
|||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<span key="placeholder" className={cx('TreeSelect-placeholder')}>
|
<span key="placeholder" className={cx('TreeSelect-placeholder')}>
|
||||||
{placeholder}
|
{__(placeholder)}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -386,7 +393,8 @@ export default class TreeSelectControl extends React.Component<
|
|||||||
searchable,
|
searchable,
|
||||||
autoComplete,
|
autoComplete,
|
||||||
maxLength,
|
maxLength,
|
||||||
minLength
|
minLength,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let filtedOptions =
|
let filtedOptions =
|
||||||
@ -420,14 +428,14 @@ export default class TreeSelectControl extends React.Component<
|
|||||||
joinValues={joinValues}
|
joinValues={joinValues}
|
||||||
extractValue={extractValue}
|
extractValue={extractValue}
|
||||||
delimiter={delimiter}
|
delimiter={delimiter}
|
||||||
placeholder={optionsPlaceholder}
|
placeholder={__(optionsPlaceholder)}
|
||||||
options={filtedOptions}
|
options={filtedOptions}
|
||||||
highlightTxt={this.state.inputValue}
|
highlightTxt={this.state.inputValue}
|
||||||
multiple={multiple}
|
multiple={multiple}
|
||||||
initiallyOpen={initiallyOpen}
|
initiallyOpen={initiallyOpen}
|
||||||
unfoldedLevel={unfoldedLevel}
|
unfoldedLevel={unfoldedLevel}
|
||||||
withChildren={withChildren}
|
withChildren={withChildren}
|
||||||
rootLabel={rootLabel}
|
rootLabel={__(rootLabel)}
|
||||||
rootValue={rootValue}
|
rootValue={rootValue}
|
||||||
showIcon={showIcon}
|
showIcon={showIcon}
|
||||||
showRadio={showRadio}
|
showRadio={showRadio}
|
||||||
|
@ -460,13 +460,13 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
submit(fn?: (values: object) => Promise<any>): Promise<any> {
|
submit(fn?: (values: object) => Promise<any>): Promise<any> {
|
||||||
const {store, messages} = this.props;
|
const {store, messages, translate: __} = this.props;
|
||||||
this.flush();
|
this.flush();
|
||||||
|
|
||||||
return store.submit(
|
return store.submit(
|
||||||
fn,
|
fn,
|
||||||
this.hooks['validate' || []],
|
this.hooks['validate' || []],
|
||||||
messages && messages.validateFailed
|
__(messages && messages.validateFailed)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,7 +563,8 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
env,
|
env,
|
||||||
onChange,
|
onChange,
|
||||||
clearPersistDataAfterSubmit,
|
clearPersistDataAfterSubmit,
|
||||||
trimValues
|
trimValues,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
// 做动作之前,先把数据同步一下。
|
// 做动作之前,先把数据同步一下。
|
||||||
@ -581,7 +582,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
if (Array.isArray(action.required) && action.required.length) {
|
if (Array.isArray(action.required) && action.required.length) {
|
||||||
return store.validateFields(action.required).then(result => {
|
return store.validateFields(action.required).then(result => {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
env.notify('error', '依赖的部分字段没有通过验证,请注意填写!');
|
env.notify('error', __('依赖的部分字段没有通过验证,请注意填写!'));
|
||||||
} else {
|
} else {
|
||||||
this.handleAction(
|
this.handleAction(
|
||||||
e,
|
e,
|
||||||
@ -706,15 +707,17 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
} else if (action.actionType === 'ajax') {
|
} else if (action.actionType === 'ajax') {
|
||||||
store.setCurrentAction(action);
|
store.setCurrentAction(action);
|
||||||
if (!isEffectiveApi(action.api)) {
|
if (!isEffectiveApi(action.api)) {
|
||||||
return env.alert(`当 actionType 为 ajax 时,请设置 api 属性`);
|
return env.alert(__(`当 actionType 为 ajax 时,请设置 api 属性`));
|
||||||
}
|
}
|
||||||
|
|
||||||
return store
|
return store
|
||||||
.saveRemote(action.api as Api, data, {
|
.saveRemote(action.api as Api, data, {
|
||||||
successMessage:
|
successMessage: __(
|
||||||
(action.messages && action.messages.success) || saveSuccess,
|
(action.messages && action.messages.success) || saveSuccess
|
||||||
errorMessage:
|
),
|
||||||
|
errorMessage: __(
|
||||||
(action.messages && action.messages.failed) || saveFailed
|
(action.messages && action.messages.failed) || saveFailed
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.then(async response => {
|
.then(async response => {
|
||||||
response &&
|
response &&
|
||||||
@ -833,7 +836,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildActions() {
|
buildActions() {
|
||||||
const {actions, submitText, controls} = this.props;
|
const {actions, submitText, controls, translate: __} = this.props;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
typeof actions !== 'undefined' ||
|
typeof actions !== 'undefined' ||
|
||||||
@ -852,7 +855,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
label: submitText,
|
label: __(submitText),
|
||||||
primary: true
|
primary: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -1126,7 +1129,8 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
bodyClassName,
|
bodyClassName,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
affixFooter,
|
affixFooter,
|
||||||
lazyLoad
|
lazyLoad,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let body: JSX.Element = this.renderBody();
|
let body: JSX.Element = this.renderBody();
|
||||||
@ -1136,7 +1140,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||||||
'body',
|
'body',
|
||||||
{
|
{
|
||||||
type: 'panel',
|
type: 'panel',
|
||||||
title: title
|
title: __(title)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
className: cx(panelClassName, 'Panel--form'),
|
className: cx(panelClassName, 'Panel--form'),
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Renderer, RendererProps} from '../factory';
|
import {Renderer, RendererProps} from '../factory';
|
||||||
import {filter} from '../utils/tpl';
|
import {filter} from '../utils/tpl';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import {autobind} from '../utils/helper';
|
import {autobind} from '../utils/helper';
|
||||||
import {Icon} from '../components/icons';
|
import {Icon} from '../components/icons';
|
||||||
|
import {LocaleProps, localeable} from '../locale';
|
||||||
|
|
||||||
export interface ImageThumbProps {
|
export interface ImageThumbProps extends LocaleProps, ThemeProps {
|
||||||
src: string;
|
src: string;
|
||||||
originalSrc?: string; // 原图
|
originalSrc?: string; // 原图
|
||||||
enlargeAble?: boolean;
|
enlargeAble?: boolean;
|
||||||
@ -19,8 +20,6 @@ export interface ImageThumbProps {
|
|||||||
caption?: string;
|
caption?: string;
|
||||||
thumbMode?: 'w-full' | 'h-full' | 'contain' | 'cover';
|
thumbMode?: 'w-full' | 'h-full' | 'contain' | 'cover';
|
||||||
thumbRatio?: '1:1' | '4:3' | '16:9';
|
thumbRatio?: '1:1' | '4:3' | '16:9';
|
||||||
classnames: ClassNamesFn;
|
|
||||||
classPrefix: string;
|
|
||||||
onLoad?: React.EventHandler<any>;
|
onLoad?: React.EventHandler<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +42,8 @@ export class ImageThumb extends React.Component<ImageThumbProps> {
|
|||||||
title,
|
title,
|
||||||
caption,
|
caption,
|
||||||
onLoad,
|
onLoad,
|
||||||
enlargeAble
|
enlargeAble,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -65,7 +65,7 @@ export class ImageThumb extends React.Component<ImageThumbProps> {
|
|||||||
{enlargeAble ? (
|
{enlargeAble ? (
|
||||||
<div key="overlay" className={cx('Image-overlay')}>
|
<div key="overlay" className={cx('Image-overlay')}>
|
||||||
<a
|
<a
|
||||||
data-tooltip="查看大图"
|
data-tooltip={__('查看大图')}
|
||||||
data-position="bottom"
|
data-position="bottom"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
onClick={this.handleEnlarge}
|
onClick={this.handleEnlarge}
|
||||||
@ -87,7 +87,7 @@ export class ImageThumb extends React.Component<ImageThumbProps> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const ThemedImageThumb = themeable(ImageThumb);
|
const ThemedImageThumb = themeable(localeable(ImageThumb));
|
||||||
export default ThemedImageThumb;
|
export default ThemedImageThumb;
|
||||||
|
|
||||||
export interface ImageFieldProps extends RendererProps {
|
export interface ImageFieldProps extends RendererProps {
|
||||||
|
@ -24,7 +24,8 @@ export class LinkField extends React.Component<LinkProps, object> {
|
|||||||
blank,
|
blank,
|
||||||
htmlTarget,
|
htmlTarget,
|
||||||
data,
|
data,
|
||||||
render
|
render,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let value = this.props.value;
|
let value = this.props.value;
|
||||||
@ -36,7 +37,7 @@ export class LinkField extends React.Component<LinkProps, object> {
|
|||||||
target={htmlTarget || (blank ? '_blank' : '_self')}
|
target={htmlTarget || (blank ? '_blank' : '_self')}
|
||||||
className={cx('Link', className)}
|
className={cx('Link', className)}
|
||||||
>
|
>
|
||||||
{body ? render('body', body) : finnalHref || value || '链接'}
|
{body ? render('body', body) : finnalHref || value || __('链接')}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -167,9 +167,9 @@ export default class List extends React.Component<ListProps, object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
let parent: HTMLElement | Window | null = getScrollParent(findDOMNode(
|
let parent: HTMLElement | Window | null = getScrollParent(
|
||||||
this
|
findDOMNode(this) as HTMLElement
|
||||||
) as HTMLElement);
|
);
|
||||||
if (!parent || parent === document.body) {
|
if (!parent || parent === document.body) {
|
||||||
parent = window;
|
parent = window;
|
||||||
}
|
}
|
||||||
@ -251,9 +251,7 @@ export default class List extends React.Component<ListProps, object> {
|
|||||||
const affixed = clip.top < offsetY && clip.top + clip.height - 40 > offsetY;
|
const affixed = clip.top < offsetY && clip.top + clip.height - 40 > offsetY;
|
||||||
|
|
||||||
this.body.offsetWidth &&
|
this.body.offsetWidth &&
|
||||||
(afixedDom.style.cssText = `top: ${offsetY}px;width: ${
|
(afixedDom.style.cssText = `top: ${offsetY}px;width: ${this.body.offsetWidth}px;`);
|
||||||
this.body.offsetWidth
|
|
||||||
}px;`);
|
|
||||||
affixed ? afixedDom.classList.add('in') : afixedDom.classList.remove('in');
|
affixed ? afixedDom.classList.add('in') : afixedDom.classList.remove('in');
|
||||||
// store.markHeaderAffix(clip.top < offsetY && (clip.top + clip.height - 40) > offsetY);
|
// store.markHeaderAffix(clip.top < offsetY && (clip.top + clip.height - 40) > offsetY);
|
||||||
}
|
}
|
||||||
@ -494,9 +492,7 @@ export default class List extends React.Component<ListProps, object> {
|
|||||||
<div className={cx('List-heading')}>
|
<div className={cx('List-heading')}>
|
||||||
{store.modified && !hideQuickSaveBtn ? (
|
{store.modified && !hideQuickSaveBtn ? (
|
||||||
<span>
|
<span>
|
||||||
{`当前有 ${
|
{`当前有 ${store.modified} 条记录修改了内容, 但并没有提交。请选择:`}
|
||||||
store.modified
|
|
||||||
} 条记录修改了内容, 但并没有提交。请选择:`}
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cx('Button Button--xs Button--success m-l-sm')}
|
className={cx('Button Button--xs Button--success m-l-sm')}
|
||||||
@ -732,7 +728,8 @@ export default class List extends React.Component<ListProps, object> {
|
|||||||
checkOnItemClick,
|
checkOnItemClick,
|
||||||
affixHeader,
|
affixHeader,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
size
|
size,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
this.renderedToolbars = [];
|
this.renderedToolbars = [];
|
||||||
@ -791,7 +788,7 @@ export default class List extends React.Component<ListProps, object> {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={cx('List-placeholder')}>{placeholder}</div>
|
<div className={cx('List-placeholder')}>{__(placeholder)}</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{this.renderFooter()}
|
{this.renderFooter()}
|
||||||
|
@ -128,7 +128,7 @@ export class Navigation extends React.Component<
|
|||||||
return this.receive(query);
|
return this.receive(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {data, env, source} = this.props;
|
const {data, env, source, translate: __} = this.props;
|
||||||
const finalData = values ? createObject(data, values) : data;
|
const finalData = values ? createObject(data, values) : data;
|
||||||
|
|
||||||
if (!isEffectiveApi(source, data)) {
|
if (!isEffectiveApi(source, data)) {
|
||||||
@ -144,7 +144,7 @@ export class Navigation extends React.Component<
|
|||||||
|
|
||||||
if (!payload.ok) {
|
if (!payload.ok) {
|
||||||
this.setState({
|
this.setState({
|
||||||
error: payload.msg || '获取链接错误'
|
error: payload.msg || __('获取链接错误')
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const links = Array.isArray(payload.data)
|
const links = Array.isArray(payload.data)
|
||||||
|
@ -91,7 +91,7 @@ export const HocPopOver = (config: Partial<PopOverConfig> = {}) => (
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildSchema() {
|
buildSchema() {
|
||||||
const {popOver, name, label} = this.props;
|
const {popOver, name, label, translate: __} = this.props;
|
||||||
|
|
||||||
let schema;
|
let schema;
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ export const HocPopOver = (config: Partial<PopOverConfig> = {}) => (
|
|||||||
type: popOver.mode,
|
type: popOver.mode,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
label: '关闭',
|
label: __('关闭'),
|
||||||
type: 'button',
|
type: 'button',
|
||||||
actionType: 'cancel'
|
actionType: 'cancel'
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildSchema() {
|
buildSchema() {
|
||||||
const {quickEdit, name, label} = this.props;
|
const {quickEdit, name, label, translate: __} = this.props;
|
||||||
|
|
||||||
let schema;
|
let schema;
|
||||||
|
|
||||||
@ -372,12 +372,12 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (
|
|||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
label: '取消',
|
label: __('取消'),
|
||||||
actionType: 'cancel'
|
actionType: 'cancel'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: '确认',
|
label: __('确认'),
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
primary: true
|
primary: true
|
||||||
}
|
}
|
||||||
|
@ -213,14 +213,14 @@ export default class Service extends React.Component<ServiceProps> {
|
|||||||
throwErrors: boolean = false,
|
throwErrors: boolean = false,
|
||||||
delegate?: IScopedContext
|
delegate?: IScopedContext
|
||||||
) {
|
) {
|
||||||
const {onAction, store, env, api} = this.props;
|
const {onAction, store, env, api, translate: __} = this.props;
|
||||||
|
|
||||||
if (api && action.actionType === 'ajax') {
|
if (api && action.actionType === 'ajax') {
|
||||||
store.setCurrentAction(action);
|
store.setCurrentAction(action);
|
||||||
store
|
store
|
||||||
.saveRemote(action.api as string, data, {
|
.saveRemote(action.api as string, data, {
|
||||||
successMessage: action.messages && action.messages.success,
|
successMessage: __(action.messages && action.messages.success),
|
||||||
errorMessage: action.messages && action.messages.failed
|
errorMessage: __(action.messages && action.messages.failed)
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
if (action.feedback && isVisible(action.feedback, store.data)) {
|
if (action.feedback && isVisible(action.feedback, store.data)) {
|
||||||
|
@ -959,7 +959,8 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
data,
|
data,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
saveImmediately,
|
saveImmediately,
|
||||||
headingClassName
|
headingClassName,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -971,14 +972,19 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
<div className={cx('Table-heading', headingClassName)} key="heading">
|
<div className={cx('Table-heading', headingClassName)} key="heading">
|
||||||
{!saveImmediately && store.modified && !hideQuickSaveBtn ? (
|
{!saveImmediately && store.modified && !hideQuickSaveBtn ? (
|
||||||
<span>
|
<span>
|
||||||
{`当前有 ${store.modified} 条记录修改了内容, 但并没有提交。请选择:`}
|
{__(
|
||||||
|
'当前有 {{modified}} 条记录修改了内容, 但并没有提交。请选择:',
|
||||||
|
{
|
||||||
|
modified: store.modified
|
||||||
|
}
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cx('Button Button--xs Button--success m-l-sm')}
|
className={cx('Button Button--xs Button--success m-l-sm')}
|
||||||
onClick={this.handleSave}
|
onClick={this.handleSave}
|
||||||
>
|
>
|
||||||
<i className="fa fa-check m-r-xs" />
|
<i className="fa fa-check m-r-xs" />
|
||||||
提交
|
{__('提交')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -986,19 +992,21 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
onClick={this.reset}
|
onClick={this.reset}
|
||||||
>
|
>
|
||||||
<i className="fa fa-times m-r-xs" />
|
<i className="fa fa-times m-r-xs" />
|
||||||
放弃
|
{__('放弃')}
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
) : store.moved ? (
|
) : store.moved ? (
|
||||||
<span>
|
<span>
|
||||||
{`当前有 ${store.moved} 条记录修改了顺序, 但并没有提交。请选择:`}
|
{__('当前有 {{moved}} 条记录修改了顺序, 但并没有提交。请选择:', {
|
||||||
|
moved: store.moved
|
||||||
|
})}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cx('Button Button--xs Button--success m-l-sm')}
|
className={cx('Button Button--xs Button--success m-l-sm')}
|
||||||
onClick={this.handleSaveOrder}
|
onClick={this.handleSaveOrder}
|
||||||
>
|
>
|
||||||
<i className="fa fa-check m-r-xs" />
|
<i className="fa fa-check m-r-xs" />
|
||||||
提交
|
{__('提交')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -1006,7 +1014,7 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
onClick={this.reset}
|
onClick={this.reset}
|
||||||
>
|
>
|
||||||
<i className="fa fa-times m-r-xs" />
|
<i className="fa fa-times m-r-xs" />
|
||||||
放弃
|
{__('放弃')}
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
) : title ? (
|
) : title ? (
|
||||||
@ -1497,7 +1505,14 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderDragToggler() {
|
renderDragToggler() {
|
||||||
const {store, env, draggable, classPrefix: ns, dragIcon} = this.props;
|
const {
|
||||||
|
store,
|
||||||
|
env,
|
||||||
|
draggable,
|
||||||
|
classPrefix: ns,
|
||||||
|
dragIcon,
|
||||||
|
translate: __
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (!draggable || store.isNested) {
|
if (!draggable || store.isNested) {
|
||||||
return null;
|
return null;
|
||||||
@ -1508,7 +1523,7 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
disabled={!!store.modified}
|
disabled={!!store.modified}
|
||||||
classPrefix={ns}
|
classPrefix={ns}
|
||||||
key="dragging-toggle"
|
key="dragging-toggle"
|
||||||
tooltip="点击开始排序"
|
tooltip={__('点击开始排序')}
|
||||||
tooltipContainer={
|
tooltipContainer={
|
||||||
env && env.getModalContainer ? env.getModalContainer : undefined
|
env && env.getModalContainer ? env.getModalContainer : undefined
|
||||||
}
|
}
|
||||||
@ -1587,7 +1602,8 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
showHeader,
|
showHeader,
|
||||||
store,
|
store,
|
||||||
classnames: cx,
|
classnames: cx,
|
||||||
data
|
data,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (showHeader === false) {
|
if (showHeader === false) {
|
||||||
@ -1625,7 +1641,7 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
{child}
|
{child}
|
||||||
{store.dragging ? (
|
{store.dragging ? (
|
||||||
<div className={cx('Table-dragTip')} ref={this.dragTipRef}>
|
<div className={cx('Table-dragTip')} ref={this.dragTipRef}>
|
||||||
请拖动左边的按钮进行排序
|
{__('请拖动左边的按钮进行排序')}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@ -1767,7 +1783,7 @@ export default class Table extends React.Component<TableProps, object> {
|
|||||||
? filter(rowClassNameExpr, item.data)
|
? filter(rowClassNameExpr, item.data)
|
||||||
: rowClassName
|
: rowClassName
|
||||||
)}
|
)}
|
||||||
columns={columns}
|
columns={store.footableColumns}
|
||||||
renderCell={this.renderCell}
|
renderCell={this.renderCell}
|
||||||
render={render}
|
render={render}
|
||||||
onAction={onAction}
|
onAction={onAction}
|
||||||
@ -2160,7 +2176,7 @@ export class HeadCellSearchDropDown extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildSchema() {
|
buildSchema() {
|
||||||
const {searchable, sortable, name, label} = this.props;
|
const {searchable, sortable, name, label, translate: __} = this.props;
|
||||||
|
|
||||||
let schema;
|
let schema;
|
||||||
|
|
||||||
@ -2207,14 +2223,14 @@ export class HeadCellSearchDropDown extends React.Component<
|
|||||||
{
|
{
|
||||||
type: 'button-group',
|
type: 'button-group',
|
||||||
name: 'orderDir',
|
name: 'orderDir',
|
||||||
label: '排序',
|
label: __('排序'),
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
label: '正序',
|
label: __('正序'),
|
||||||
value: 'asc'
|
value: 'asc'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '降序',
|
label: __('降序'),
|
||||||
value: 'desc'
|
value: 'desc'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -2230,12 +2246,12 @@ export class HeadCellSearchDropDown extends React.Component<
|
|||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
label: '取消',
|
label: __('取消'),
|
||||||
actionType: 'cancel'
|
actionType: 'cancel'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: '搜索',
|
label: __('搜索'),
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
primary: true
|
primary: true
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
* @file video
|
* @file video
|
||||||
* @author fex
|
* @author fex
|
||||||
*/
|
*/
|
||||||
/* eslint fecs-indent: [0, "space", 2, 2] */
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
@ -650,7 +650,8 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
|
|||||||
actionNextLabel,
|
actionNextLabel,
|
||||||
actionNextSaveLabel,
|
actionNextSaveLabel,
|
||||||
actionFinishLabel,
|
actionFinishLabel,
|
||||||
render
|
render,
|
||||||
|
translate: __
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!Array.isArray(steps)) {
|
if (!Array.isArray(steps)) {
|
||||||
@ -698,7 +699,7 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
|
|||||||
`prev-btn`,
|
`prev-btn`,
|
||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
label: actionPrevLabel,
|
label: __(actionPrevLabel),
|
||||||
actionType: 'prev',
|
actionType: 'prev',
|
||||||
className: actionClassName
|
className: actionClassName
|
||||||
},
|
},
|
||||||
@ -713,10 +714,10 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
|
|||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
label: !nextStep
|
label: !nextStep
|
||||||
? actionFinishLabel
|
? __(actionFinishLabel)
|
||||||
: !step.api
|
: !step.api
|
||||||
? actionNextLabel
|
? __(actionNextLabel)
|
||||||
: actionNextSaveLabel,
|
: __(actionNextSaveLabel),
|
||||||
actionType: 'next',
|
actionType: 'next',
|
||||||
primary: !nextStep || !!step.api,
|
primary: !nextStep || !!step.api,
|
||||||
className: actionClassName
|
className: actionClassName
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import hoistNonReactStatic from 'hoist-non-react-statics';
|
import hoistNonReactStatic from 'hoist-non-react-statics';
|
||||||
import {ExtractProps, Omit} from './types';
|
|
||||||
|
|
||||||
export type ClassValue =
|
export type ClassValue =
|
||||||
| string
|
| string
|
||||||
@ -117,17 +116,19 @@ export const ThemeContext = React.createContext('theme');
|
|||||||
export let defaultTheme: string = 'default';
|
export let defaultTheme: string = 'default';
|
||||||
|
|
||||||
export function themeable<
|
export function themeable<
|
||||||
T extends React.ComponentType<ThemeProps & ExtractProps<T>>
|
T extends React.ComponentType<React.ComponentProps<T> & ThemeProps>
|
||||||
>(ComposedComponent: T) {
|
>(ComposedComponent: T) {
|
||||||
type ComposedProps = JSX.LibraryManagedAttributes<T, ExtractProps<T>>;
|
type OuterProps = JSX.LibraryManagedAttributes<
|
||||||
type Props = Omit<ComposedProps, keyof ThemeProps> & {
|
T,
|
||||||
|
Omit<React.ComponentProps<T>, keyof ThemeProps>
|
||||||
|
> & {
|
||||||
theme?: string;
|
theme?: string;
|
||||||
classPrefix?: string;
|
classPrefix?: string;
|
||||||
classnames?: ClassNamesFn;
|
classnames?: ClassNamesFn;
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = hoistNonReactStatic(
|
const result = hoistNonReactStatic(
|
||||||
class extends React.Component<Props> {
|
class extends React.Component<OuterProps> {
|
||||||
static displayName = `Themeable(${
|
static displayName = `Themeable(${
|
||||||
ComposedComponent.displayName || ComposedComponent.name
|
ComposedComponent.displayName || ComposedComponent.name
|
||||||
})`;
|
})`;
|
||||||
@ -150,9 +151,10 @@ export function themeable<
|
|||||||
return (
|
return (
|
||||||
<ThemeContext.Provider value={theme}>
|
<ThemeContext.Provider value={theme}>
|
||||||
<ComposedComponent
|
<ComposedComponent
|
||||||
{
|
{...(this.props as JSX.LibraryManagedAttributes<
|
||||||
...(this.props as any) /* todo, 解决这个类型问题 */
|
T,
|
||||||
}
|
React.ComponentProps<T>
|
||||||
|
>)}
|
||||||
{...injectedProps}
|
{...injectedProps}
|
||||||
/>
|
/>
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
|
12
src/types.ts
12
src/types.ts
@ -140,15 +140,15 @@ export interface RendererData {
|
|||||||
type RendererDataAlis = RendererData;
|
type RendererDataAlis = RendererData;
|
||||||
|
|
||||||
export type FunctionPropertyNames<T> = {
|
export type FunctionPropertyNames<T> = {
|
||||||
[K in keyof T]: T[K] extends Function ? K : never
|
[K in keyof T]: T[K] extends Function ? K : never;
|
||||||
}[keyof T];
|
}[keyof T];
|
||||||
|
|
||||||
export interface JSONSchema {
|
export interface JSONSchema {
|
||||||
[propsName: string]: any;
|
[propsName: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Omit<T, K extends keyof T & any> = Pick<T, Exclude<keyof T, K>>;
|
// export type Omit<T, K extends keyof T & any> = Pick<T, Exclude<keyof T, K>>;
|
||||||
export type Override<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;
|
// export type Override<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;
|
||||||
export type ExtractProps<
|
// export type ExtractProps<
|
||||||
TComponentOrTProps
|
// TComponentOrTProps
|
||||||
> = TComponentOrTProps extends React.ComponentType<infer P> ? P : never;
|
// > = TComponentOrTProps extends React.ComponentType<infer P> ? P : never;
|
||||||
|
@ -607,7 +607,7 @@ export function isBreakpoint(str: string): boolean {
|
|||||||
|
|
||||||
const breaks = str.split(/\s*,\s*|\s+/);
|
const breaks = str.split(/\s*,\s*|\s+/);
|
||||||
|
|
||||||
if (window.matchMedia) {
|
if ((window as any).matchMedia) {
|
||||||
return breaks.some(
|
return breaks.some(
|
||||||
item =>
|
item =>
|
||||||
item === '*' ||
|
item === '*' ||
|
||||||
@ -1095,7 +1095,7 @@ export function sortArray<T extends any>(
|
|||||||
field: string,
|
field: string,
|
||||||
dir: -1 | 1
|
dir: -1 | 1
|
||||||
): Array<T> {
|
): Array<T> {
|
||||||
return items.sort((a, b) => {
|
return items.sort((a: any, b: any) => {
|
||||||
let ret: number;
|
let ret: number;
|
||||||
const a1 = a[field];
|
const a1 = a[field];
|
||||||
const b1 = b[field];
|
const b1 = b[field];
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
* @file resize-sensor.js.
|
* @file resize-sensor.js.
|
||||||
* @author fex
|
* @author fex
|
||||||
*/
|
*/
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
class EventQueue {
|
class EventQueue {
|
||||||
q: Array<Function> = [];
|
q: Array<Function> = [];
|
||||||
@ -70,7 +69,7 @@ function attachResizeEvent(element: HTMLElement, resized: Function) {
|
|||||||
|
|
||||||
let lastWidth: number, lastHeight: number;
|
let lastWidth: number, lastHeight: number;
|
||||||
|
|
||||||
const reset = function() {
|
const reset = function () {
|
||||||
expandChild.style.width = expand.offsetWidth + 10 + 'px';
|
expandChild.style.width = expand.offsetWidth + 10 + 'px';
|
||||||
expandChild.style.height = expand.offsetHeight + 10 + 'px';
|
expandChild.style.height = expand.offsetHeight + 10 + 'px';
|
||||||
expand.scrollLeft = expand.scrollWidth;
|
expand.scrollLeft = expand.scrollWidth;
|
||||||
@ -83,13 +82,13 @@ function attachResizeEvent(element: HTMLElement, resized: Function) {
|
|||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
let changed = function() {
|
let changed = function () {
|
||||||
if ((element as any).resizedAttached) {
|
if ((element as any).resizedAttached) {
|
||||||
(element as any).resizedAttached.call();
|
(element as any).resizedAttached.call();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let addEvent = function(el: HTMLElement, name: string, cb: Function) {
|
let addEvent = function (el: HTMLElement, name: string, cb: Function) {
|
||||||
if ((el as any).attachEvent) {
|
if ((el as any).attachEvent) {
|
||||||
(el as any).attachEvent('on' + name, cb);
|
(el as any).attachEvent('on' + name, cb);
|
||||||
} else {
|
} else {
|
||||||
@ -97,7 +96,7 @@ function attachResizeEvent(element: HTMLElement, resized: Function) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let onScroll = function(e: Event) {
|
let onScroll = function (e: Event) {
|
||||||
if (
|
if (
|
||||||
element.offsetWidth != lastWidth ||
|
element.offsetWidth != lastWidth ||
|
||||||
element.offsetHeight != lastHeight
|
element.offsetHeight != lastHeight
|
||||||
@ -132,7 +131,7 @@ export function resizeSensor(
|
|||||||
once: boolean = false
|
once: boolean = false
|
||||||
) {
|
) {
|
||||||
if (once) {
|
if (once) {
|
||||||
attachResizeEvent(element, function(this: any) {
|
attachResizeEvent(element, function (this: any) {
|
||||||
callback.apply(this, arguments);
|
callback.apply(this, arguments);
|
||||||
detach(element);
|
detach(element);
|
||||||
});
|
});
|
||||||
@ -142,7 +141,7 @@ export function resizeSensor(
|
|||||||
attachResizeEvent(element, callback);
|
attachResizeEvent(element, callback);
|
||||||
let detached = false;
|
let detached = false;
|
||||||
|
|
||||||
return function() {
|
return function () {
|
||||||
if (detached) return;
|
if (detached) return;
|
||||||
detached = true;
|
detached = true;
|
||||||
detach(element);
|
detach(element);
|
||||||
|
11
types/uncontrollable/index.d.ts
vendored
11
types/uncontrollable/index.d.ts
vendored
@ -1,7 +1,10 @@
|
|||||||
declare module 'uncontrollable' {
|
declare module 'uncontrollable' {
|
||||||
function uncontrollable<T extends React.ComponentType<any>, P extends {
|
function uncontrollable<
|
||||||
[propName:string]: any
|
T extends Raect.ComponentType<any>,
|
||||||
}>(arg:T, config:P):T;
|
P extends {
|
||||||
|
[propName: string]: any;
|
||||||
|
}
|
||||||
|
>(arg: T, config: P): T;
|
||||||
|
|
||||||
export = uncontrollable;
|
export = uncontrollable;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user