feat: ConditionBuilder使用公式输入时支持设定输入框类型

This commit is contained in:
lurunze1226 2023-06-07 21:42:23 +08:00
parent 153443528b
commit d9a9999a8d
14 changed files with 738 additions and 60 deletions

View File

@ -60,13 +60,18 @@ npm run build
npm test --workspaces
# 测试某个用例
npm test --workspace amis inputImage
# <spec-name>为用例名称比如inputImage
npm test --workspace amis <spec-name>
# 查看测试用例覆盖率
npm run coverage
# 更新 snapshot
npm run update-snapshot
# 更新单个 snapshot
# <spec-name>为用例名称比如inputImage
npm run update-snapshot --workspace amis <spec-name>
```
### 发布版本

View File

@ -1090,20 +1090,211 @@ selectMode 为`chained`时,使用`source`字段
}
```
## 配合公式编辑器
> `3.2.0` 及以上版本
可以配置`formula`属性,将字段输入控件变成公式编辑器。
```schema: scope="body"
{
"type": "form",
"debug": true,
"body": [
{
"type": "condition-builder",
"label": "条件组件",
"name": "conditions",
"description": "适合让用户自己拼查询条件,然后后端根据数据生成 query where",
"searchable": true,
"formula": {
"mode":"input-group",
"inputSettings":{},
"allowInput":true,
"mixedMode": true,
"variables": [
{
"label": "表单字段",
"children": [
{
"label": "文章名",
"value": "name",
"tag": "文本"
},
{
"label": "作者",
"value": "author",
"tag": "文本"
},
{
"label": "售价",
"value": "price",
"tag": "数字"
},
{
"label": "出版时间",
"value": "time",
"tag": "时间"
},
{
"label": "版本号",
"value": "version",
"tag": "数字"
},
{
"label": "出版社",
"value": "publisher",
"tag": "文本"
}
]
},
{
"label": "流程字段",
"children": [
{
"label": "联系电话",
"value": "telphone"
},
{
"label": "地址",
"value": "addr"
}
]
},
{
"label": "长文本测试分类长文本测试分类长文本测试分类长文本测试分类",
"children": [
{
"label": "这是一段测试长文本这是一段测试长文本这是一段测试长文本",
"value": "longtext",
"tag": "文本"
}
]
}
]
},
"fields": [
{
"label": "文本",
"type": "text",
"name": "text"
},
{
"label": "数字",
"type": "number",
"name": "number"
},
{
"label": "布尔",
"type": "boolean",
"name": "boolean"
},
{
"label": "选项",
"type": "select",
"name": "select",
"options": [
{
"label": "A",
"value": "a"
},
{
"label": "B",
"value": "b"
},
{
"label": "C",
"value": "c"
},
{
"label": "D",
"value": "d"
},
{
"label": "E",
"value": "e"
}
]
},
{
"label": "动态选项",
"type": "select",
"name": "select2",
"source": "/api/mock2/form/getOptions?waitSeconds=1"
},
{
"label": "日期",
"children": [
{
"label": "日期",
"type": "date",
"name": "date"
},
{
"label": "时间",
"type": "time",
"name": "time"
},
{
"label": "日期时间",
"type": "datetime",
"name": "datetime"
}
]
}
]
}
]
}
```
## 属性表
| 属性名 | 类型 | 默认值 | 说明 |
| -------------- | ------------------ | -------- | ------------------------------ |
| className | `string` | | 外层 dom 类名 |
| fieldClassName | `string` | | 输入字段的类名 |
| source | `string` | | 通过远程拉取配置项 |
| embed | `boolean` | true | 内嵌展示 |
| title | `string` | | 弹窗配置的顶部标题 |
| fields | | | 字段配置 |
| showANDOR | `boolean` | | 用于 simple 模式下显示切换按钮 |
| showNot | `boolean` | | 是否显示「非」按钮 |
| draggable | `boolean` | true | 是否可拖拽 |
| searchable | `boolean` | | 字段是否可搜索 |
| selectMode | `'list'` \| `'tree'` \| `'chained'` | `'list'` | 组合条件左侧选项类型。`'chained'`模式需要`3.2.0及以上版本` |
| addBtnVisibleOn | `string` | | 表达式:控制按钮“添加条件”的显示。参数为`depth`、`breadth`,分别代表深度、长度。表达式需要返回`boolean`类型`3.2.0及以上版本` |
| addGroupBtnVisibleOn | `string` | | 表达式:控制按钮“添加条件组”的显示。参数为`depth`、`breadth`,分别代表深度、长度。表达式需要返回`boolean`类型`3.2.0及以上版本` |
| 属性名 | 类型 | 默认值 | 说明 | 版本 |
| -------------------- | ----------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------- | ------- |
| className | `string` | | 外层 dom 类名 |
| fieldClassName | `string` | | 输入字段的类名 |
| source | `string` | | 通过远程拉取配置项 |
| embed | `boolean` | true | 内嵌展示 |
| title | `string` | | 弹窗配置的顶部标题 |
| fields | | | 字段配置 |
| showANDOR | `boolean` | | 用于 simple 模式下显示切换按钮 |
| showNot | `boolean` | | 是否显示「非」按钮 |
| draggable | `boolean` | true | 是否可拖拽 |
| searchable | `boolean` | | 字段是否可搜索 |
| selectMode | `'list'` \| `'tree'` \| `'chained'` | `'list'` | 组合条件左侧选项类型。`'chained'`模式需要`3.2.0及以上版本` |
| addBtnVisibleOn | `string` | | 表达式:控制按钮“添加条件”的显示。参数为`depth`、`breadth`,分别代表深度、长度。表达式需要返回`boolean`类型 | `3.2.0` |
| addGroupBtnVisibleOn | `string` | | 表达式:控制按钮“添加条件组”的显示。参数为`depth`、`breadth`,分别代表深度、长度。表达式需要返回`boolean`类型 | `3.2.0` |
| inputSettings | `InputSettings` | | 开启公式编辑模式时的输入控件类型 | `3.2.0` |
### InputSettings
```typescript
interface InputSettings {
/* 类型 */
type: 'text' | 'number' | 'boolean' | 'date' | 'time' | 'datetime' | 'select';
/* 数字类型 - 步长 */
step?: number;
/* 数字类型 - 最小值 */
min?: number;
/* 数字类型 - 最大值 */
max?: number;
/* 数字类型 - 精度 */
precision?: number;
/* 日期时间类型 - 格式 */
format?: stirng;
/* 日期时间类型 - 输入框格式 */
inputFormat?: string;
/* 日期时间类型 - 时间格式 */
timeFormat?: string;
/* 选择类型 - 选项集合 */
options?: {label: string; value: any}[];
/* 选择类型 - 是否多选 */
multiple?: boolean;
/* 布尔类型 - 真值 label */
trueLabel?: string;
/* 布尔类型 - 假值 label */
falseLabel?: string;
defaultValue?: any;
}
```

View File

@ -1,4 +1,3 @@
import {attachmentAdpator} from 'amis-core';
import omit from 'lodash/omit';
import {Api, ApiObject, EventTrack, fetcherResult, Payload} from '../types';
import {fetcherConfig} from '../factory';

View File

@ -11,7 +11,7 @@ $Table-strip-bg: transparent;
--primary-onHover: var(--colors-brand-6);
--primary-onActive: var(--colors-brand-4);
--secondary: var(--colors-neutral-text-4); // secondary 颜色需进一步确认
--secondary: var(--colors-neutral-text-4); /* secondary 颜色需进一步确认 */
--secondary-onHover: var(--colors-neutral-text-6);
--secondary-onActive: var(--colors-neutral-text-4);
@ -763,9 +763,10 @@ $Table-strip-bg: transparent;
--ColumnToggler-item-dragBar-color: #d8d8d8;
--InputFormula-header-bgColor: #fafafa;
--InputFormula-icon-size: #{px2rem(24px)};
--InputFormula-icon-size: #{px2rem(18px)};
--InputFormula-icon-color-onActive: var(--colors-brand-5);
--InputFormula-code-bgColor: var(--colors-neutral-fill-10);
--InputFormula-input-schema-height: var(--sizes-base-12);
--UserSelect--post-bg: var(--colors-brand-6);
--UserSelect--department-bg: #ffab52;

View File

@ -510,10 +510,15 @@
.#{$ns}FormulaPicker.is-input-group {
border: var(--Form-input-borderWidth) solid var(--Form-input-borderColor);
padding: var(--Form-input-paddingY) var(--Form-input-paddingX);
padding: 0 var(--Form-input-paddingX) 0 0;
border-radius: var(--borderRadius);
background-color: #fff;
height: var(--Form-input-height);
&.#{$ns}FormulaPicker--text {
padding: var(--Form-input-paddingY) var(--Form-input-paddingX);
}
.#{$ns}FormulaPicker-input {
display: flex;
align-items: center;
@ -521,19 +526,49 @@
padding: 0;
border: 0;
margin: 0;
margin-right: #{px2rem(10px)};
max-width: unset;
&:focus {
border: none;
outline: none;
box-sizing: none;
}
&-number,
&-select,
&-boolean,
&-date,
&-time,
&-datetime {
height: var(--InputFormula-input-schema-height);
padding-left: var(--Form-input-paddingX);
}
&-number {
.#{$ns}Number-handler-wrap {
height: unset; /* 避免调节器超出Input框 */
}
}
&-variable {
border: none;
min-height: unset;
line-height: #{px2rem(18px)};
padding-top: 0;
padding-bottom: 0;
}
}
.#{$ns}FormulaPicker-toggler {
.icon-function {
transform: scale(1.8);
transform: scale(1.3);
}
.icon-ellipsis-v {
transform: rotate(90deg);
}
&:hover {
cursor: pointer;
}

View File

@ -47,7 +47,19 @@ export class Value extends React.Component<ValueProps> {
onChange,
disabled
});
input = <FormulaPicker {...formula} />;
const inputSettings =
field.type !== 'custom' && formula?.inputSettings
? {
...formula?.inputSettings,
...field,
multiple:
field.type === 'select' &&
op &&
typeof op === 'string' &&
['select_any_in', 'select_not_any_in'].includes(op)
}
: undefined;
input = <FormulaPicker {...formula} inputSettings={inputSettings} />;
} else if (field.type === 'text') {
input = (
<InputBox
@ -105,7 +117,7 @@ export class Value extends React.Component<ValueProps> {
} else if (field.type === 'datetime') {
input = (
<DatePicker
placeholder={__(field.placeholder) || 'Time.placeholder'}
placeholder={__(field.placeholder) || __('Time.placeholder')}
format={field.format || ''}
inputFormat={field.inputFormat || 'YYYY-MM-DD HH:mm'}
value={value ?? field.defaultValue}

View File

@ -0,0 +1,323 @@
import React, {useEffect, useCallback} from 'react';
import moment from 'moment';
import pick from 'lodash/pick';
import {
noop,
themeable,
ThemeProps,
localeable,
LocaleProps,
uncontrollable,
findTree,
isExpression
} from 'amis-core';
import {FormulaEditor, VariableItem} from './Editor';
import ResultBox from '../ResultBox';
import Select from '../Select';
import NumberInput from '../NumberInput';
import DatePicker from '../DatePicker';
import Tag from '../Tag';
import type {FormulaPickerProps} from './Picker';
export interface FormulaInputProps
extends Pick<
FormulaPickerProps,
| 'className'
| 'disabled'
| 'evalMode'
| 'allowInput'
| 'placeholder'
| 'clearable'
| 'borderMode'
| 'variables'
| 'inputSettings'
>,
ThemeProps,
LocaleProps {
/**
*
*/
value?: string;
mixedMode?: boolean;
variables?: VariableItem[];
popOverContainer?: any;
/**
* Change事件回调
*/
onChange?: (value: string | any[]) => void;
/**
*
*/
itemRender?: (value: any) => JSX.Element | string;
}
const FormulaInput: React.FC<FormulaInputProps> = props => {
const {
translate: __,
className,
classnames: cx,
allowInput,
placeholder,
borderMode,
evalMode,
mixedMode,
value,
variables,
inputSettings = {type: 'text'},
popOverContainer,
onChange,
itemRender
} = props;
const schemaType = inputSettings.type;
/** 自上层共享的属性 */
const sharedProps = pick(props, ['disabeld', 'clearable']);
const pipInValue = useCallback(
(value?: any) => {
return value;
},
['value']
);
const pipOutValue = useCallback(
(origin: any) => {
let result = origin;
if (origin === undefined) {
onChange?.(result);
return;
}
if (schemaType === 'boolean') {
result = origin.value;
} else if (schemaType === 'select') {
result = Array.isArray(origin)
? origin.map(item => item.value)
: origin.value;
}
onChange?.(result);
},
['onChange']
);
const FormulaCmpt = ({value}: {value: string}) => {
return (
<ResultBox
className={cx(`FormulaPicker-input-variable`)}
allowInput={false}
value={pipInValue(value)}
result={
value == null
? void 0
: FormulaEditor.highlightValue(value, variables!, evalMode)
}
itemRender={(item: any) => {
return (
<div
className={cx('FormulaPicker-ResultBox')}
dangerouslySetInnerHTML={{__html: item.html}}
/>
);
}}
onResultChange={noop}
onChange={pipOutValue}
onClear={() => pipOutValue(undefined)}
clearable={true}
/>
);
};
const cmptValue = pipInValue(value ?? inputSettings.defaultValue);
const targetVariable =
variables && cmptValue != null && typeof cmptValue === 'string'
? findTree(variables, item => {
return mixedMode
? cmptValue.replace(/^\$\{/, '').replace(/\}$/, '') === item?.value
: cmptValue === item?.value;
})
: null;
if (
isExpression(cmptValue) ||
targetVariable ||
(schemaType === 'number' &&
cmptValue != null &&
typeof cmptValue !== 'number') ||
(['date', 'time', 'datetime'].includes(schemaType) &&
!moment(cmptValue).isValid()) ||
(schemaType === 'select' &&
cmptValue != null &&
!(inputSettings?.options ?? []).some(
(item: any) => item?.value === cmptValue
)) ||
(schemaType === 'boolean' &&
cmptValue != null &&
typeof cmptValue !== 'boolean')
) {
const varName =
cmptValue && mixedMode
? cmptValue.replace(/^\$\{/, '').replace(/\}$/, '')
: cmptValue;
const resultValue = targetVariable?.value ?? varName;
return (
<ResultBox
className={cx(`FormulaPicker-input-variable`)}
allowInput={false}
value={resultValue}
result={
resultValue == null
? void 0
: FormulaEditor.highlightValue(resultValue, variables!, evalMode)
}
itemRender={(item: any) => {
return (
<div
className={cx('FormulaPicker-ResultBox')}
dangerouslySetInnerHTML={{__html: item.html}}
/>
);
}}
onResultChange={noop}
onChange={pipOutValue}
onClear={() => pipOutValue(undefined)}
clearable={true}
/>
);
}
if (schemaType === 'number') {
return (
<NumberInput
{...sharedProps}
className={cx(className, 'FormulaPicker-input-number')}
borderMode="none"
placeholder={__(placeholder ?? 'NumberInput.placeholder')}
step={inputSettings.step}
min={inputSettings.minimum}
max={inputSettings.maximum}
precision={inputSettings.precision}
value={cmptValue}
onChange={pipOutValue}
/>
);
} else if (schemaType === 'date') {
const cmptValue = pipInValue(value ?? inputSettings.defaultValue);
return (
<DatePicker
{...sharedProps}
className={cx(className, 'FormulaPicker-input-date')}
borderMode="none"
closeOnSelect={true}
placeholder={__(placeholder ?? 'Date.placeholder')}
format={inputSettings.format || 'YYYY-MM-DD'}
inputFormat={inputSettings.inputFormat || 'YYYY-MM-DD'}
timeFormat=""
popOverContainer={popOverContainer}
value={cmptValue}
onChange={pipOutValue}
/>
);
} else if (schemaType === 'time') {
return (
<DatePicker
{...sharedProps}
className={cx(className, 'FormulaPicker-input-time')}
viewMode="time"
borderMode="none"
closeOnSelect={true}
placeholder={__(placeholder ?? 'Time.placeholder')}
format={inputSettings.format || 'HH:mm'}
inputFormat={inputSettings.inputFormat || 'HH:mm'}
dateFormat=""
timeFormat={inputSettings.format || 'HH:mm'}
popOverContainer={popOverContainer}
value={pipInValue(value ?? inputSettings.defaultValue)}
onChange={pipOutValue}
/>
);
} else if (schemaType === 'datetime') {
return (
<DatePicker
{...sharedProps}
className={cx(className, 'FormulaPicker-input-datetime')}
borderMode="none"
closeOnSelect={true}
placeholder={__(placeholder ?? 'Time.placeholder')}
format={inputSettings.format || ''}
inputFormat={inputSettings.inputFormat || 'YYYY-MM-DD HH:mm'}
timeFormat={inputSettings.timeFormat || 'HH:mm'}
popOverContainer={popOverContainer}
value={pipInValue(value ?? inputSettings.defaultValue)}
onChange={pipOutValue}
/>
);
} else if (schemaType === 'select' || schemaType === 'boolean') {
return (
<Select
{...sharedProps}
className={cx(className, `FormulaPicker-input-${schemaType}`)}
borderMode="none"
multiple={schemaType === 'boolean' ? false : inputSettings.multiple}
options={
schemaType === 'boolean'
? [
{
label: __(inputSettings?.trueLabel ?? 'FormulaInput.True'),
value: true
},
{
label: __(inputSettings?.falseLabel ?? 'FormulaInput.False'),
value: false
}
]
: inputSettings.options ?? []
}
value={pipInValue(value)}
renderValueLabel={option => {
const label = option.label?.toString() ?? '';
return schemaType === 'boolean' || !inputSettings.multiple ? (
<Tag label={label} className={cx('rounded')} />
) : (
<>{label}</>
);
}}
onChange={pipOutValue}
/>
);
} else {
return (
<ResultBox
{...sharedProps}
className={cx(className)}
allowInput={allowInput}
borderMode={borderMode}
placeholder={placeholder}
value={pipInValue(value)}
result={
allowInput || !value
? void 0
: FormulaEditor.highlightValue(value, variables!, evalMode)
}
itemRender={itemRender}
onResultChange={noop}
onChange={pipOutValue}
/>
);
}
};
export default themeable(
localeable(
uncontrollable(FormulaInput, {
value: 'onChange'
})
)
);

View File

@ -17,7 +17,10 @@ import {
themeable,
localeable,
parse,
Evaluator
isMobile,
Evaluator,
evaluate,
isPureVariable
} from 'amis-core';
import Editor from './Editor';
import ResultBox from '../ResultBox';
@ -25,7 +28,24 @@ import Button from '../Button';
import {Icon} from '../icons';
import Modal from '../Modal';
import PopUp from '../PopUp';
import {isMobile} from 'amis-core';
import FormulaInput from './Input';
export const InputSchemaType = [
'text',
'number',
'boolean',
'date',
'time',
'datetime',
'select'
] as const;
export type FormulaPickerInputSettingType = (typeof InputSchemaType)[number];
export interface FormulaPickerInputSettings {
type: FormulaPickerInputSettingType;
[propName: string]: any;
}
export interface FormulaPickerProps
extends Omit<FormulaEditorProps, 'variables'> {
@ -113,6 +133,11 @@ export interface FormulaPickerProps
*/
data?: any;
/**
*
*/
inputSettings?: FormulaPickerInputSettings;
/**
* variables functions
*/
@ -140,10 +165,9 @@ export interface FormulaPickerProps
export interface FormulaPickerState {
isOpened: boolean;
value: string;
value: any;
editorValue: string;
isError: boolean | string;
variables?: Array<VariableItem>;
functions?: Array<FuncGroup>;
variableMode?: any;
@ -172,16 +196,29 @@ export class FormulaPicker extends React.Component<
}
componentDidUpdate(prevProps: FormulaPickerProps) {
const value = this.props.value;
const {value} = this.props;
if (value !== prevProps.value) {
this.setState({
value: typeof value === 'string' ? value : '',
value: typeof value === 'string' || !this.isTextInput() ? value : '',
editorValue: this.value2EditorValue(this.props)
});
}
}
value2EditorValue(props: FormulaPickerProps) {
const {value} = props;
if (!this.isTextInput()) {
let editorValue = '';
try {
editorValue = JSON.stringify(value);
} catch (error) {}
return editorValue;
}
if (props.mixedMode) {
if (
typeof props.value === 'string' &&
@ -196,6 +233,16 @@ export class FormulaPicker extends React.Component<
return String(props.value || '');
}
isTextInput() {
const {inputSettings} = this.props;
return (
!inputSettings ||
inputSettings?.type === 'text' ||
!InputSchemaType.includes(inputSettings?.type)
);
}
@autobind
handleConfirm() {
const value = this.state.value;
@ -214,6 +261,7 @@ export class FormulaPicker extends React.Component<
if (allowInput) {
return '';
}
return (
<div
className={cx('FormulaPicker-ResultBox')}
@ -243,9 +291,35 @@ export class FormulaPicker extends React.Component<
@autobind
handleEditorConfirm() {
const {translate: __} = this.props;
const value = this.state.editorValue;
this.confirm(value);
const {translate: __, inputSettings} = this.props;
const {editorValue} = this.state;
if (this.isTextInput()) {
return this.confirm(editorValue);
} else if (inputSettings) {
let result = editorValue;
const schemaType = inputSettings?.type;
try {
const ast = parse(editorValue, {evalMode: true, allowFilter: false});
if (
schemaType === 'select' &&
inputSettings.multiple &&
ast.type === 'array'
) {
result = ast.members.map((i: any) => i.value);
} else if (ast.type === 'literal' || ast.type === 'string') {
result = ast.value ?? '';
}
} catch (error) {
this.setState({isError: error?.message ?? true});
return;
}
this.setState({isError: false});
return this.confirm(result);
}
}
confirm(value: string) {
@ -315,7 +389,28 @@ export class FormulaPicker extends React.Component<
@autobind
validate(value: string) {
const {translate: __} = this.props;
const {translate: __, inputSettings} = this.props;
/** 处理非文本输入场景 */
if (inputSettings && !this.isTextInput()) {
const schemaType = inputSettings?.type;
const errorMsg = __('FormulaEditor.invalidValue');
/** 变量类型 */
if (typeof value === 'string') {
return true;
}
if (['number', 'boolean'].includes(schemaType)) {
return typeof value === schemaType ? true : errorMsg;
} else if (['text', 'date', 'time', 'datetime'].includes(schemaType)) {
return typeof value === 'string' ? true : errorMsg;
} else if (schemaType === 'select' && inputSettings.multiple) {
return Array.isArray(value) ? true : errorMsg;
} else {
return true;
}
}
try {
value &&
@ -360,6 +455,7 @@ export class FormulaPicker extends React.Component<
evalMode,
popOverContainer,
useMobileUI,
inputSettings,
...rest
} = this.props;
const {isOpened, value, editorValue, isError} = this.state;
@ -378,8 +474,11 @@ export class FormulaPicker extends React.Component<
<div
className={cx(
'FormulaPicker',
className,
mode === 'input-group' ? 'is-input-group' : ''
mode === 'input-group' ? 'is-input-group' : '',
{
'FormulaPicker--text': this.isTextInput()
},
className
)}
style={style}
>
@ -439,10 +538,7 @@ export class FormulaPicker extends React.Component<
disabled={disabled}
borderMode={borderMode}
placeholder={placeholder}
useMobileUI={useMobileUI}
showArrow={false}
/>
<Button
className={cx('FormulaPicker-action')}
onClick={this.handleClick}
@ -458,32 +554,24 @@ export class FormulaPicker extends React.Component<
)}
{mode === 'input-group' && (
<>
<ResultBox
<FormulaInput
className={cx(
'FormulaPicker-input',
isOpened ? 'is-active' : '',
!!isError ? 'is-error' : ''
)}
inputSettings={inputSettings}
allowInput={allowInput}
clearable={clearable}
evalMode={evalMode}
mixedMode={mixedMode}
variables={this.state.variables!}
value={value}
result={
allowInput
? void 0
: FormulaEditor.highlightValue(
value,
this.state.variables!,
this.props.evalMode
)
}
itemRender={this.renderFormulaValue}
onResultChange={noop}
onChange={this.handleInputChange}
disabled={disabled}
borderMode={borderMode}
placeholder={placeholder}
useMobileUI={useMobileUI}
showArrow={false}
/>
<a

View File

@ -1,4 +1,10 @@
<svg t="1642059003991" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="6131" >
<path d="M510.665143 801.536c13.037714 0 22.253714-7.296 22.253714-20.333714 0-5.76-1.536-8.832-5.76-16.896-46.811429-72.502857-73.289143-155.757714-73.289143-245.924572 0-87.094857 24.941714-174.189714 73.289143-247.076571 4.205714-8.045714 5.76-11.117714 5.76-16.877714 0-12.288-9.216-20.333714-22.253714-20.333715-12.672 0-23.04 5.741714-35.291429 22.637715-57.563429 73.270857-86.710857 164.571429-86.710857 261.266285s27.995429 185.307429 86.692572 260.900572c12.288 16.877714 22.637714 22.637714 35.291428 22.637714z m391.716571 0c12.653714 0 22.637714-5.76 34.925715-22.637714C995.986286 703.305143 1024 614.692571 1024 517.997714c0-96.676571-28.781714-187.977143-86.710857-261.266285-12.269714-16.896-22.253714-22.637714-34.907429-22.637715-13.037714 0-22.253714 8.045714-22.253714 20.333715 0 5.76 1.152 8.813714 5.376 16.877714 48.731429 72.886857 73.654857 160 73.654857 247.076571 0 90.148571-26.843429 173.421714-73.270857 245.942857-4.608 8.045714-5.76 11.117714-5.76 16.877715 0 12.269714 9.216 20.333714 22.253714 20.333714z m-850.578285-0.768c75.190857 0 110.098286-32.237714 128.128-118.564571l43.739428-209.865143h69.449143c22.253714 0 36.443429-11.885714 36.443429-31.085715 0-16.475429-10.733714-26.843429-28.379429-26.843428h-64.841143l10.733714-52.169143c9.984-48.731429 25.325714-68.681143 67.913143-68.681143 6.144 0 12.269714-0.384 16.493715-0.768 19.2-1.92 27.611429-10.752 27.611428-27.245714 0-21.485714-18.011429-31.085714-54.857143-31.085714-73.270857 0-110.866286 36.461714-127.744 118.564571l-13.056 61.385143H115.858286c-22.235429 0-36.827429 11.885714-36.827429 31.085714 0 16.493714 11.136 26.843429 28.781714 26.843429h43.337143L108.982857 673.005714C98.194286 723.254857 82.468571 741.668571 41.435429 741.668571c-5.376 0-10.368 0.384-14.189715 0.768-17.664 2.304-27.245714 11.885714-27.245714 28.013715 0 20.717714 17.645714 30.317714 51.803429 30.317714z m539.044571-100.918857c12.653714 0 21.101714-4.205714 30.683429-18.029714l84.022857-119.698286h1.536l85.942857 121.618286c9.6 13.44 18.797714 16.109714 28.013714 16.109714 18.413714 0 30.701714-13.037714 30.701714-28.763429 0-7.296-2.304-14.189714-7.314285-20.717714l-98.194286-133.522286 98.194286-131.602285c5.010286-6.509714 7.314286-13.421714 7.314285-21.485715 0-16.493714-13.824-27.995429-29.165714-27.995428-13.805714 0-21.869714 6.912-29.165714 18.029714l-80.950857 118.546286h-1.92l-81.334857-118.930286c-7.296-11.136-16.493714-17.645714-31.085715-17.645714-17.645714 0-31.085714 14.189714-31.085714 29.531428 0 11.136 3.090286 18.048 8.466286 24.557715l93.220571 125.074285-98.980571 136.96c-5.76 7.314286-6.912 13.824-6.912 21.504 0 14.957714 12.672 26.459429 28.013714 26.459429z" p-id="6132"></path>
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>fx</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="fx">
<rect x="0" y="0" width="16" height="16"></rect>
<path d="M6.85458095,1.4369501 C7.71952092,0.883033689 9.14623722,0.984136878 9.82754043,1.06050205 C10.1144049,1.09276903 10.7457242,1.15084958 10.6805277,1.77252664 C10.6294571,2.26943806 9.89599674,2.21888646 9.7014939,2.21888646 C9.48535769,2.21888646 9.2659886,2.19876183 9.04755999,2.18089337 L8.82959943,2.1646059 C7.92402473,2.10678268 7.05892911,2.21764793 6.53620481,4.11618461 L6.21348223,5.68866187 L7.84556744,5.68866187 C8.14547125,5.68866187 8.38887144,5.92958862 8.38887144,6.22644479 C8.38887144,6.52330096 8.14547125,6.76422771 7.84556744,6.76422771 L5.98203473,6.76422771 L4.51511393,13.8963048 C4.51511393,13.8963048 4.37385489,15.042858 3.66212666,14.9987598 C3.63797714,14.9972618 3.61487053,14.9948005 3.5927662,14.9914342 C3.56428372,14.9965963 3.53191413,15 3.49937138,15 L1.46666667,15 C1.20893378,15 1,14.7910662 1,14.5333333 L1,14.5005208 C0.999354255,14.259116 1.18292475,14.0570646 1.42329087,14.0346853 C1.93951851,13.9857578 2.38825526,13.9043655 2.76950112,13.7905085 C2.88970413,13.7546105 2.99265144,13.7126424 3.07834304,13.6646043 C3.13612492,13.6324776 3.19778289,13.6139204 3.25964158,13.6078865 L4.67484531,6.76422771 L2.46685786,6.76422771 C2.18325317,6.76422771 1.95723871,6.54696341 1.93333333,6.27269412 L1.945,6.342 L1.95324336,6.32324571 C1.96746558,6.3067537 1.99022114,6.29312987 1.99875447,6.27376968 C1.98595447,6.2576362 1.94115447,6.24365384 1.94115447,6.22644479 L1.941,6.319 L1.93333333,6.27269412 C1.95524659,5.81127637 2.14698763,5.70504184 2.39724012,5.69054037 L2.46685786,5.68866187 L4.90846603,5.68866187 L5.24857433,4.08391763 C5.48980131,2.9481201 5.98746777,1.99301764 6.85458095,1.4369501 Z M14.7335755,5.87796146 C14.9009132,5.96723342 14.9878418,6.07048774 14.9987079,6.18664885 C15.0084874,6.30280996 14.9628498,6.41681994 14.8585355,6.52975435 L12.8950348,8.6378634 L14.8324569,11.2676219 C14.8933069,11.3461382 14.9085194,11.440788 14.873748,11.5440423 C14.8433229,11.6494478 14.7064103,11.7225862 14.5249468,11.8193872 C14.3282708,11.9215659 14.1576733,11.9118858 14.0359732,11.8785433 C13.9175329,11.8441252 13.8110453,11.7666844 13.7219435,11.6494478 L12.0876851,9.50907173 L10.1046255,11.6386921 C9.86774493,11.8925256 9.59935275,11.9301704 9.2929293,11.7505509 C9.16688277,11.6774125 8.93652187,11.4063699 8.90935667,11.2837554 C8.88327808,11.1622164 8.93217544,11.0342241 9.05822197,10.8976272 L11.2509969,8.53568465 L9.65368315,6.44370909 C9.58740006,6.34798373 9.58088042,6.23612488 9.6330376,6.10920811 C9.68302157,5.98229134 9.80146184,5.90700173 9.92750837,5.83278769 C10.1089719,5.7316845 10.2752229,5.7284578 10.3980096,5.7381379 C10.5218829,5.74566686 10.6338036,5.81557864 10.7370313,5.94464654 L12.0648663,7.65802292 L13.6719595,5.92528635 C13.8110453,5.772556 13.9686035,5.71877771 14.1207286,5.67575508 C14.2717671,5.63273244 14.5705843,5.78761392 14.7335755,5.87796146 Z" id="形状结合备份" fill="#2C313C" fill-rule="nonzero"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -385,6 +385,8 @@ register('de-DE', {
'FormulaEditor.function': 'Funktion',
'FormulaEditor.invalidData':
'Überprüfungsfehler, position or reason is {{err}}',
'FormulaEditor.invalidValue':
'Überprüfungsfehler, reason is Falsches Werteformat',
'pullRefresh.pullingText': 'Zum Aktualisieren nach unten ziehen...',
'pullRefresh.loosingText': 'Zum Aktualisieren freigeben...',
'pullRefresh.loadingText': 'Laden...',
@ -410,5 +412,7 @@ register('de-DE', {
'JSONSchema.key': 'Key',
'JSONSchema.array_items': 'Items',
'TimeNow': 'Jetzt',
'Steps.step': 'Schritt {{index}}'
'Steps.step': 'Schritt {{index}}',
'FormulaInput.True': 'Treu',
'FormulaInput.False': 'Falsch'
});

View File

@ -372,6 +372,7 @@ register('en-US', {
'FormulaEditor.variable': 'Variable',
'FormulaEditor.function': 'Function',
'FormulaEditor.invalidData': 'invalid data, position or reason is {{err}}',
'FormulaEditor.invalidValue': 'invalid value, reason is wrong value format',
'pullRefresh.pullingText': 'Pull down to refresh...',
'pullRefresh.loosingText': 'Release to refresh...',
'pullRefresh.loadingText': 'Loading...',
@ -399,5 +400,7 @@ register('en-US', {
'TimeNow': 'Now',
'IconSelect.all': 'All',
'IconSelect.choice': 'Icon selection',
'Steps.step': 'Step {{index}}'
'Steps.step': 'Step {{index}}',
'FormulaInput.True': 'True',
'FormulaInput.False': 'False'
});

View File

@ -365,6 +365,7 @@ register('zh-CN', {
'FormulaEditor.variable': '变量',
'FormulaEditor.function': '函数',
'FormulaEditor.invalidData': '公式值校验错误,错误的位置/原因是 {{err}}',
'FormulaEditor.invalidValue': '值校验错误,错误的原因是值格式错误',
'pullRefresh.pullingText': '下拉即可刷新...',
'pullRefresh.loosingText': '释放即可刷新...',
'pullRefresh.loadingText': '加载中...',
@ -394,5 +395,7 @@ register('zh-CN', {
'TimeNow': '此刻',
'IconSelect.all': '全部',
'IconSelect.choice': '图标选择',
'Steps.step': '第 {{index}} 步'
'Steps.step': '第 {{index}} 步',
'FormulaInput.True': '真',
'FormulaInput.False': '假'
});

View File

@ -195,7 +195,7 @@ exports[`Renderer:input-formula 1`] = `
</span>
</label>
<div
class="cxd-FormulaPicker cxd-Form-control"
class="cxd-FormulaPicker cxd-FormulaPicker--text cxd-Form-control"
>
<div
class="cxd-ResultBox cxd-FormulaPicker-input cxd-ResultBox--borderFull"
@ -487,7 +487,7 @@ exports[`Renderer:input-formula button 1`] = `
</span>
</label>
<div
class="cxd-FormulaPicker cxd-Form-control"
class="cxd-FormulaPicker cxd-FormulaPicker--text cxd-Form-control"
>
<button
class="cxd-Button cxd-Button--default cxd-Button--size-default cxd-FormulaPicker-action w-full"
@ -765,7 +765,7 @@ exports[`Renderer:input-formula input-group 1`] = `
</span>
</label>
<div
class="cxd-FormulaPicker cxd-Form-control is-input-group"
class="cxd-FormulaPicker is-input-group cxd-FormulaPicker--text cxd-Form-control"
>
<div
class="cxd-ResultBox cxd-FormulaPicker-input cxd-ResultBox--borderFull"

View File

@ -9,6 +9,7 @@ import type {
FuncGroup,
VariableItem
} from 'amis-ui/lib/components/formula/Editor';
import type {FormulaPickerInputSettings} from 'amis-ui/lib/components/formula/Picker';
/**
* InputFormula
@ -120,6 +121,11 @@ export interface InputFormulaControlSchema extends FormBaseControlSchema {
* name: 用于避免循环绑定自身导致无限渲染
*/
selfVariableName?: string;
/**
*
*/
inputSettings?: FormulaPickerInputSettings;
}
export interface InputFormulaProps
@ -198,6 +204,7 @@ export class InputFormulaRenderer extends React.Component<InputFormulaProps> {
onPickerOpen,
selfVariableName,
env,
inputSettings,
useMobileUI
} = this.props;
let {variables, functions} = this.props;
@ -229,6 +236,7 @@ export class InputFormulaRenderer extends React.Component<InputFormulaProps> {
borderMode={borderMode}
placeholder={placeholder}
mode={inputMode}
inputSettings={inputSettings}
btnLabel={btnLabel}
level={level}
btnSize={btnSize}