From cec406b0ec481370651dd3781a59806480a0ffef Mon Sep 17 00:00:00 2001 From: liuguihua Date: Thu, 20 Apr 2023 20:41:35 +0800 Subject: [PATCH 001/274] =?UTF-8?q?feat(amis-editor):=E5=A2=9E=E5=8A=A0inp?= =?UTF-8?q?utText=E3=80=81textArea=E6=9C=80=E5=A4=A7=E5=AD=97=E6=95=B0?= =?UTF-8?q?=E9=85=8D=E7=BD=AE&=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E5=8F=98=E9=87=8F=E8=BF=87=E9=95=BF=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-editor-core/scss/_data-chain.scss | 1 + packages/amis-editor/src/plugin/Form/InputText.tsx | 7 +++++++ packages/amis-editor/src/plugin/Form/Textarea.tsx | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/packages/amis-editor-core/scss/_data-chain.scss b/packages/amis-editor-core/scss/_data-chain.scss index af69398fb..2066e7d37 100644 --- a/packages/amis-editor-core/scss/_data-chain.scss +++ b/packages/amis-editor-core/scss/_data-chain.scss @@ -35,5 +35,6 @@ &-main { flex-grow: 1; flex-basis: auto; + overflow-x: auto; } } diff --git a/packages/amis-editor/src/plugin/Form/InputText.tsx b/packages/amis-editor/src/plugin/Form/InputText.tsx index f1db15d7c..7afa399e1 100644 --- a/packages/amis-editor/src/plugin/Form/InputText.tsx +++ b/packages/amis-editor/src/plugin/Form/InputText.tsx @@ -218,6 +218,13 @@ export class TextControlPlugin extends BasePlugin { getSchemaTpl('showCounter', { visibleOn: `${isText} || ${isPassword}` }), + { + name: 'maxLength', + label: tipedLabel('最大字数', '限制输入输入最大字数量'), + type: 'input-number', + min: 0, + step: 1 + }, { name: 'addOn', label: tipedLabel('AddOn', '输入框左侧或右侧的附加挂件'), diff --git a/packages/amis-editor/src/plugin/Form/Textarea.tsx b/packages/amis-editor/src/plugin/Form/Textarea.tsx index e2ae25414..fd47ede50 100644 --- a/packages/amis-editor/src/plugin/Form/Textarea.tsx +++ b/packages/amis-editor/src/plugin/Form/Textarea.tsx @@ -136,6 +136,13 @@ export class TextareaControlPlugin extends BasePlugin { ) }), getSchemaTpl('showCounter'), + { + name: 'maxLength', + label: tipedLabel('最大字数', '限制输入输入最大字数量'), + type: 'input-number', + min: 0, + step: 1 + }, getSchemaTpl('labelRemark'), getSchemaTpl('remark'), getSchemaTpl('placeholder'), From 129129f45e6337c24669070938cee12cab860ae3 Mon Sep 17 00:00:00 2001 From: liuguihua Date: Thu, 20 Apr 2023 21:13:38 +0800 Subject: [PATCH 002/274] =?UTF-8?q?feat(amis-editor):=E5=A2=9E=E5=8A=A0inp?= =?UTF-8?q?utText=E3=80=81textArea=E6=9C=80=E5=A4=A7=E5=AD=97=E6=95=B0?= =?UTF-8?q?=E9=85=8D=E7=BD=AE&=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E5=8F=98=E9=87=8F=E8=BF=87=E9=95=BF=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-editor/src/plugin/Form/InputText.tsx | 2 +- packages/amis-editor/src/plugin/Form/Textarea.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/amis-editor/src/plugin/Form/InputText.tsx b/packages/amis-editor/src/plugin/Form/InputText.tsx index 7afa399e1..e092b9652 100644 --- a/packages/amis-editor/src/plugin/Form/InputText.tsx +++ b/packages/amis-editor/src/plugin/Form/InputText.tsx @@ -220,7 +220,7 @@ export class TextControlPlugin extends BasePlugin { }), { name: 'maxLength', - label: tipedLabel('最大字数', '限制输入输入最大字数量'), + label: tipedLabel('最大字数', '限制输入最多文字数量'), type: 'input-number', min: 0, step: 1 diff --git a/packages/amis-editor/src/plugin/Form/Textarea.tsx b/packages/amis-editor/src/plugin/Form/Textarea.tsx index fd47ede50..27380b2eb 100644 --- a/packages/amis-editor/src/plugin/Form/Textarea.tsx +++ b/packages/amis-editor/src/plugin/Form/Textarea.tsx @@ -138,7 +138,7 @@ export class TextareaControlPlugin extends BasePlugin { getSchemaTpl('showCounter'), { name: 'maxLength', - label: tipedLabel('最大字数', '限制输入输入最大字数量'), + label: tipedLabel('最大字数', '限制输入最多文字数量'), type: 'input-number', min: 0, step: 1 From 0859983daab732139ab76f27ea02720a81c39bd8 Mon Sep 17 00:00:00 2001 From: sqzhou Date: Fri, 14 Apr 2023 17:26:07 +0800 Subject: [PATCH 003/274] =?UTF-8?q?feat:=20select=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E9=95=BF=E5=BA=A6&nestSelect=E7=9A=84=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E9=95=BF=E5=BA=A6&=E6=96=87=E6=9C=AC=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scss/components/form/_nested-select.scss | 2 + .../amis-ui/scss/components/form/_select.scss | 1 + .../amis/src/renderers/Form/NestedSelect.tsx | 47 ++++++++++++++++--- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/amis-ui/scss/components/form/_nested-select.scss b/packages/amis-ui/scss/components/form/_nested-select.scss index 71823d0b4..287be633b 100644 --- a/packages/amis-ui/scss/components/form/_nested-select.scss +++ b/packages/amis-ui/scss/components/form/_nested-select.scss @@ -2,6 +2,7 @@ position: relative; .#{$ns}NestedSelect-menu { + min-width: px2rem(100px); padding-top: px2rem(4px); padding-bottom: px2rem(4px); box-shadow: 0 px2rem(2px) px2rem(8px) 0 rgba(7, 12, 20, 0.12); @@ -76,6 +77,7 @@ height: px2rem(32px); overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; &.is-disabled { cursor: not-allowed; color: var(--text--muted-color); diff --git a/packages/amis-ui/scss/components/form/_select.scss b/packages/amis-ui/scss/components/form/_select.scss index d483fa5a7..dabac7e60 100644 --- a/packages/amis-ui/scss/components/form/_select.scss +++ b/packages/amis-ui/scss/components/form/_select.scss @@ -150,6 +150,7 @@ .#{$ns}PopOver.#{$ns}Select-popover { margin-top: px2rem(4px); .#{$ns}Select-menu { + min-width: px2rem(100px); .#{$ns}Select-option { line-height: var(--select-base-default-option-line-height); } diff --git a/packages/amis/src/renderers/Form/NestedSelect.tsx b/packages/amis/src/renderers/Form/NestedSelect.tsx index f095318a4..c8979f5e6 100644 --- a/packages/amis/src/renderers/Form/NestedSelect.tsx +++ b/packages/amis/src/renderers/Form/NestedSelect.tsx @@ -17,6 +17,7 @@ import { autobind, flattenTree, filterTree, + getTreeDepth, string2regExp, getTreeAncestors, getTreeParent, @@ -110,6 +111,8 @@ export default class NestedSelectControl extends React.Component< checkAllLabel: 'Select.checkAll', hideNodePathLabel: false }; + outTarget: React.RefObject = React.createRef(); + outTargetWidth?: number; target: any; input: HTMLInputElement; state: NestedSelectState = { @@ -157,6 +160,7 @@ export default class NestedSelectControl extends React.Component< @autobind handleOutClick(e: React.MouseEvent) { const {options} = this.props; + this.outTargetWidth = this.outTarget.current?.clientWidth e.defaultPrevented || this.setState({ isOpened: true @@ -225,10 +229,18 @@ export default class NestedSelectControl extends React.Component< } const ancestors = getTreeAncestors(options, option, true); + const optionText = option[labelField || 'label']; + const splitJoin = ' / '; + + const title = ancestors + ? ancestors.map((item) => item[labelField || 'label']).join(splitJoin) + : optionText; + return ( {ancestors ? ancestors.map((item, index) => { @@ -240,11 +252,11 @@ export default class NestedSelectControl extends React.Component< {regexp.test(value) || regexp.test(label) ? renderTextByKeyword(label, inputValue) : label} - {!isEnd && ' / '} + {!isEnd && splitJoin} ); }) - : option[labelField || 'label']} + : optionText} ); } @@ -577,6 +589,20 @@ export default class NestedSelectControl extends React.Component< isPrevented || onChange(newValue); } + @autobind + getMenuSelectMenuStyle() { + const {options} = this.props; + const width = this.outTargetWidth; + const depth = getTreeDepth(options); + let style = {}; + if (width) { + style = { + width: width / depth + } + } + return style; + } + renderOptions() { const { multiple, @@ -596,11 +622,15 @@ export default class NestedSelectControl extends React.Component< const stack = this.state.stack; let partialChecked = this.partialChecked(propOptions); let allChecked = this.allChecked(propOptions); - + return ( <> {stack.map((options, index) => ( -
+
{multiple && checkAll && index === 0 ? (
- {option[labelField || 'label']} + {label}
{option.children && option.children.length ? ( @@ -719,7 +752,7 @@ export default class NestedSelectControl extends React.Component< // 一个stack一个menu const resultBody = ( -
+
{flattenTreeWithNodes.length ? ( flattenTreeWithNodes.map((option, index) => { const ancestors = getTreeAncestors(propOptions, option as any); @@ -878,7 +911,7 @@ export default class NestedSelectControl extends React.Component< const mobileUI = useMobileUI && isMobile(); return ( -
+
Date: Thu, 11 May 2023 20:11:27 +0800 Subject: [PATCH 004/274] =?UTF-8?q?fix:drawer=20data=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=97=B6=5F=5Fundefined=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/store/iRenderer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/amis-core/src/store/iRenderer.ts b/packages/amis-core/src/store/iRenderer.ts index 9b1de701b..e68d3743c 100644 --- a/packages/amis-core/src/store/iRenderer.ts +++ b/packages/amis-core/src/store/iRenderer.ts @@ -211,11 +211,11 @@ export const iRendererStore = StoreNode.named('iRendererStore') const clonedAction = { ...self.action, - dialog: { - ...self.action.dialog + drawer: { + ...self.action.drawer } }; - delete clonedAction.dialog.data; + delete clonedAction.drawer.data; self.action = clonedAction; } else { self.drawerData = data; From 2af2f35fa6182f0cd43a0490e006a077e9e4f480 Mon Sep 17 00:00:00 2001 From: lurunze1226 Date: Thu, 11 May 2023 20:34:41 +0800 Subject: [PATCH 005/274] =?UTF-8?q?fix:=20InputTable=E4=BD=BF=E7=94=A8oper?= =?UTF-8?q?ation=E5=88=97=E6=97=A0=E6=B3=95=E6=AD=A3=E5=B8=B8=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/form/input-table.md | 36 +++++++++++++------ .../amis/src/renderers/Form/InputTable.tsx | 24 ++++++++----- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/docs/zh-CN/components/form/input-table.md b/docs/zh-CN/components/form/input-table.md index 90d5267bd..38712d7e4 100755 --- a/docs/zh-CN/components/form/input-table.md +++ b/docs/zh-CN/components/form/input-table.md @@ -249,6 +249,7 @@ order: 54 "type": "input-table", "name": "table", "label": "Table", + "needConfirm": false, "columns": [ { "label": "A", @@ -257,6 +258,17 @@ order: 54 { "label": "B", "name": "b" + }, + { + "type": "operation", + "label": "操作", + "buttons": [ + { + "label": "删除", + "type": "button", + "level": "link" + } + ] } ] }, @@ -789,6 +801,7 @@ order: 54 ] } ``` + ## 表单项校验 > 2.8.1 及以上版本 @@ -853,13 +866,13 @@ order: 54 ## 属性表 | 属性名 | 类型 | 默认值 | 说明 | -| ---------------------------- | ----------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------- | +| ---------------------------- | ----------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------- | --- | | type | `string` | `"input-table"` | 指定为 Table 渲染器 | | addable | `boolean` | `false` | 是否可增加一行 | | editable | `boolean` | `false` | 是否可编辑 | | removable | `boolean` | `false` | 是否可删除 | -| showTableAddBtn | `boolean` | `true` | 是否显示表格操作栏添加按钮,前提是要开启可新增功能 | -| showFooterAddBtn | `boolean` | `true` | 是否显示表格下方添加按,前提是要开启可新增功能 |钮 | +| showTableAddBtn | `boolean` | `true` | 是否显示表格操作栏添加按钮,前提是要开启可新增功能 | +| showFooterAddBtn | `boolean` | `true` | 是否显示表格下方添加按,前提是要开启可新增功能 | 钮 | | addApi | [API](../../../docs/types/api) | - | 新增时提交的 API | | footerAddBtn | [SchemaNode](../../docs/types/schemanode) | - | 底部新增按钮配置 | | updateApi | [API](../../../docs/types/api) | - | 修改时提交的 API | @@ -887,9 +900,10 @@ order: 54 | columns[x].quickEditOnUpdate | `boolean` 或者 `object` | - | 可以用来区分新建模式和更新模式的编辑配置 | ## 事件表 -当前组件会对外派发以下事件,可以通过onEvent来监听这些事件,并通过actions来配置执行的动作,在actions中可以通过${事件参数名}来获取事件产生的数据(< 2.3.2 及以下版本 为 ${event.data.[事件参数名]}),详细请查看事件动作。 -[name]表示当前组件绑定的名称,即name属性,如果没有配置name属性,则通过value取值。 +当前组件会对外派发以下事件,可以通过 onEvent 来监听这些事件,并通过 actions 来配置执行的动作,在 actions 中可以通过${事件参数名}来获取事件产生的数据(< 2.3.2 及以下版本 为 ${event.data.[事件参数名]}),详细请查看事件动作。 + +[name]表示当前组件绑定的名称,即 name 属性,如果没有配置 name 属性,则通过 value 取值。 | 事件名称 | 事件参数 | 说明 | | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | @@ -910,10 +924,10 @@ order: 54 当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。 -| 动作名称 | 动作配置 | 说明 | -| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | -| addItem | `item: object\|Array` 添加的数据
`index: number` 指定添加的位置,如果未指定则在数据尾端插入 | 在已有数据的基础上插入数据 | +| 动作名称 | 动作配置 | 说明 | +| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| addItem | `item: object\|Array` 添加的数据
`index: number` 指定添加的位置,如果未指定则在数据尾端插入 | 在已有数据的基础上插入数据 | | deleteItem | `condition:` 删除条件[表达式](../../../docs/concepts/expression),用于支持批量删除的场景
`index: number ` 指定删除哪一行数据 | 删除某一行数据 | -| setValue | `value: object \| Array` 替换的值
`index?: number` 可选,替换第几行数据,如果没有指定,则替换全部表格数据 | 替换表格数据 | -| clear | - | 清空表格数据 | -| reset | - | 将表格数据重置为`resetValue`,若没有配置`resetValue`,则清空表格数据 | +| setValue | `value: object \| Array` 替换的值
`index?: number` 可选,替换第几行数据,如果没有指定,则替换全部表格数据 | 替换表格数据 | +| clear | - | 清空表格数据 | +| reset | - | 将表格数据重置为`resetValue`,若没有配置`resetValue`,则清空表格数据 | diff --git a/packages/amis/src/renderers/Form/InputTable.tsx b/packages/amis/src/renderers/Form/InputTable.tsx index 7497b2423..55fdcff81 100644 --- a/packages/amis/src/renderers/Form/InputTable.tsx +++ b/packages/amis/src/renderers/Form/InputTable.tsx @@ -989,14 +989,18 @@ export default class FormTable extends React.Component { ? omit(column, ['quickEdit']) : { ...column, - quickEdit: { - ...this.columnToQuickEdit(column), - ...quickEdit, - saveImmediately: true, - mode: 'inline', - disabled, - static: isStatic - } + ...(column.type === 'operation' + ? {} + : { + quickEdit: { + ...this.columnToQuickEdit(column), + ...quickEdit, + saveImmediately: true, + mode: 'inline', + disabled, + static: isStatic + } + }) }; }); } else if ( @@ -1234,6 +1238,10 @@ export default class FormTable extends React.Component { ? operation.buttons.concat() : []; operation.buttons.unshift.apply(operation.buttons, btns); + + if (operation.hasOwnProperty('quickEdit')) { + delete operation.quickEdit; + } } if (showIndex) { From 520673c506130556595a97560b7ca6341780d088 Mon Sep 17 00:00:00 2001 From: liuguihua Date: Thu, 11 May 2023 20:43:31 +0800 Subject: [PATCH 006/274] =?UTF-8?q?feat(amis):input-image=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=BF=87=E5=A4=A7=E6=8F=90=E7=A4=BA=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amis/src/renderers/Form/InputImage.tsx | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/amis/src/renderers/Form/InputImage.tsx b/packages/amis/src/renderers/Form/InputImage.tsx index a7aa9e6c8..6711acb61 100644 --- a/packages/amis/src/renderers/Form/InputImage.tsx +++ b/packages/amis/src/renderers/Form/InputImage.tsx @@ -14,11 +14,13 @@ import {FileRejection, ErrorCode, DropEvent} from 'react-dropzone'; import 'blueimp-canvastoblob'; import find from 'lodash/find'; import {Payload, ActionObject} from 'amis-core'; -import {buildApi, +import { + buildApi, isEffectiveApi, normalizeApi, isApiOutdated, - isApiOutdatedWithData} from 'amis-core'; + isApiOutdatedWithData +} from 'amis-core'; import {createObject, qsstringify, guid, isEmpty, qsparse} from 'amis-core'; import {Icon, TooltipWrapper, Button} from 'amis-ui'; import accepts from 'attr-accept'; @@ -629,8 +631,10 @@ export default class ImageControl extends React.Component< }); } // 文件太大 - else if (err.code === ErrorCode.FileTooLarge) { - return __('File.sizeLimit', {maxSize}); + else if (err.code === ErrorCode.FileTooLarge && maxSize) { + return __('File.sizeLimit', { + maxSize: prettyBytes(maxSize, 1024) + }); } }) .join('; '); @@ -1926,11 +1930,11 @@ export default class ImageControl extends React.Component< props.data, prevProps.data ) || - isApiOutdatedWithData( - props.receiver, - prevProps.receiver, - props.data, - prevProps.data - )) + isApiOutdatedWithData( + props.receiver, + prevProps.receiver, + props.data, + prevProps.data + )) }) export class ImageControlRenderer extends ImageControl {} From 3607984f9c1e4966992845fa1713747697102f8c Mon Sep 17 00:00:00 2001 From: qkiroc <30946345+qkiroc@users.noreply.github.com> Date: Thu, 11 May 2023 20:49:11 +0800 Subject: [PATCH 007/274] =?UTF-8?q?editor:=20=E5=A4=96=E8=A7=82=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E6=94=AF=E6=8C=81=E9=80=89=E6=8B=A9=E5=9B=BE=E7=89=87?= =?UTF-8?q?=20(#6854)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com> --- packages/amis-editor/src/plugin/Button.tsx | 1 + packages/amis-editor/src/plugin/Form/InputImage.tsx | 3 +-- packages/amis-editor/src/renderer/style-control/helper.tsx | 1 + packages/amis-editor/src/tpl/style.tsx | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/amis-editor/src/plugin/Button.tsx b/packages/amis-editor/src/plugin/Button.tsx index 357bf42e5..f0a8a0ffe 100644 --- a/packages/amis-editor/src/plugin/Button.tsx +++ b/packages/amis-editor/src/plugin/Button.tsx @@ -130,6 +130,7 @@ export class ButtonPlugin extends BasePlugin { name: `themeCss.className.background:${state}`, labelMode: 'input', needGradient: true, + needImage: true, visibleOn: visibleOn, editorThemePath: `button1.type.\${level}.${state}.body.bg-color` }), diff --git a/packages/amis-editor/src/plugin/Form/InputImage.tsx b/packages/amis-editor/src/plugin/Form/InputImage.tsx index 191713e55..0d958af04 100644 --- a/packages/amis-editor/src/plugin/Form/InputImage.tsx +++ b/packages/amis-editor/src/plugin/Form/InputImage.tsx @@ -25,7 +25,6 @@ const inputStateFunc = (visibleOn: string, state: string) => { label: '文字', name: `${addBtnCssClassName}.color:${state}`, labelMode: 'input', - needGradient: true, visibleOn: visibleOn, editorThemePath: `${editorPath}.${state}.body.color` }), @@ -34,6 +33,7 @@ const inputStateFunc = (visibleOn: string, state: string) => { name: `${addBtnCssClassName}.background:${state}`, labelMode: 'input', needGradient: true, + needImage: true, visibleOn: visibleOn, editorThemePath: `${editorPath}.${state}.body.bg-color` }), @@ -41,7 +41,6 @@ const inputStateFunc = (visibleOn: string, state: string) => { label: '图标', name: `${addBtnCssClassName}.icon-color:${state}`, labelMode: 'input', - needGradient: true, visibleOn: visibleOn, editorThemePath: `${editorPath}.${state}.body.icon-color` }) diff --git a/packages/amis-editor/src/renderer/style-control/helper.tsx b/packages/amis-editor/src/renderer/style-control/helper.tsx index 3b46e90e6..4116bded2 100644 --- a/packages/amis-editor/src/renderer/style-control/helper.tsx +++ b/packages/amis-editor/src/renderer/style-control/helper.tsx @@ -52,6 +52,7 @@ export const inputStateFunc = ( name: `${className}.background:${state}`, labelMode: 'input', needGradient: true, + needImage: true, visibleOn: visibleOn, editorThemePath: `${path}.${state}.body.bg-color` }), diff --git a/packages/amis-editor/src/tpl/style.tsx b/packages/amis-editor/src/tpl/style.tsx index 8ce8e5375..3fc751010 100644 --- a/packages/amis-editor/src/tpl/style.tsx +++ b/packages/amis-editor/src/tpl/style.tsx @@ -619,6 +619,7 @@ setSchemaTpl( label: '背景', needCustom: true, needGradient: true, + needImage: true, labelMode: 'input' }), getSchemaTpl('theme:shadow', { From bbd0b570019a0bfd992ef986e352f194197689cb Mon Sep 17 00:00:00 2001 From: liaoxuezhi <2betop.cn@gmail.com> Date: Thu, 11 May 2023 21:55:41 +0800 Subject: [PATCH 008/274] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=20scaffoldF?= =?UTF-8?q?orm=20=E5=AE=9E=E7=8E=B0=E7=BB=9F=E4=B8=80=E7=94=A8=20store=20?= =?UTF-8?q?=E6=9D=A5=E6=8E=A7=E5=88=B6=20(#6860)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/renderers/Options.tsx | 18 ++++--- .../src/component/ScaffoldModal.tsx | 49 +++++-------------- packages/amis-editor-core/src/store/editor.ts | 15 +++++- packages/amis/src/renderers/CRUD.tsx | 5 ++ 4 files changed, 42 insertions(+), 45 deletions(-) diff --git a/packages/amis-core/src/renderers/Options.tsx b/packages/amis-core/src/renderers/Options.tsx index 4b3862531..4d86c694a 100644 --- a/packages/amis-core/src/renderers/Options.tsx +++ b/packages/amis-core/src/renderers/Options.tsx @@ -803,14 +803,16 @@ export function registerOptionsControl(config: OptionsConfig) { return; } - return formItem.loadOptions( - source, - data, - undefined, - false, - isInit ? setPrinstineValue : onChange, - setError - ); + return isAlive(formItem) + ? formItem.loadOptions( + source, + data, + undefined, + false, + isInit ? setPrinstineValue : onChange, + setError + ) + : undefined; } @autobind diff --git a/packages/amis-editor-core/src/component/ScaffoldModal.tsx b/packages/amis-editor-core/src/component/ScaffoldModal.tsx index f30f40854..88c286a3a 100644 --- a/packages/amis-editor-core/src/component/ScaffoldModal.tsx +++ b/packages/amis-editor-core/src/component/ScaffoldModal.tsx @@ -4,7 +4,6 @@ import {EditorStoreType} from '../store/editor'; import {render, Modal, getTheme, Icon, Spinner, Button} from 'amis'; import {observer} from 'mobx-react'; import {autobind, isObject} from '../util'; -import {createObject} from 'amis-core'; export interface SubEditorProps { store: EditorStoreType; @@ -12,23 +11,8 @@ export interface SubEditorProps { theme?: string; } -interface ScaffoldState { - step: number; -} - @observer -export class ScaffoldModal extends React.Component< - SubEditorProps, - ScaffoldState -> { - constructor(props: SubEditorProps) { - super(props); - - this.state = { - step: 0 - }; - } - +export class ScaffoldModal extends React.Component { @autobind handleConfirm([values]: any) { const store = this.props.store; @@ -47,7 +31,7 @@ export class ScaffoldModal extends React.Component< store.scaffoldForm?.callback(values); store.closeScaffoldForm(); - this.setState({step: 0}); + store.scaffoldForm?.stepsBody && store.setScaffoldStep(0); } buildSchema() { @@ -91,9 +75,6 @@ export class ScaffoldModal extends React.Component< api: scaffoldFormContext.api, ...layout, wrapperComponent: 'div', - data: { - __step: 0 - }, [scaffoldFormContext.controls ? 'controls' : 'body']: body }; // const {store} = this.props; @@ -151,27 +132,25 @@ export class ScaffoldModal extends React.Component< @autobind goToNextStep() { // 不能更新props的data,控制amis不重新渲染,否则数据会重新初始化 + const store = this.props.store; const form = this.amisScope?.getComponents()[0].props.store; - const step = this.state.step + 1; + const step = store.scaffoldFormStep + 1; form.setValueByName('__step', step); // 控制按钮 - this.setState({ - step - }); + store.setScaffoldStep(step); } @autobind goToPrevStep() { // 不能更新props的data,控制amis不重新渲染,否则数据会重新初始化 + const store = this.props.store; const form = this.amisScope?.getComponents()[0].props.store; - const step = this.state.step - 1; + const step = store.scaffoldFormStep - 1; form.setValueByName('__step', step); // 控制按钮 - this.setState({ - step - }); + store.setScaffoldStep(step); } @autobind @@ -206,7 +185,7 @@ export class ScaffoldModal extends React.Component< @autobind handleCancelClick() { this.props.store.closeScaffoldForm(); - this.setState({step: 0}); + this.props.store.setScaffoldStep(0); } render() { @@ -216,8 +195,9 @@ export class ScaffoldModal extends React.Component< const isStepBody = !!scaffoldFormContext?.stepsBody; const isLastStep = - isStepBody && this.state.step === scaffoldFormContext!.body.length - 1; - const isFirstStep = isStepBody && this.state.step === 0; + isStepBody && + store.scaffoldFormStep === scaffoldFormContext!.body.length - 1; + const isFirstStep = isStepBody && store.scaffoldFormStep === 0; return ( ()), + scaffoldFormStep: 0, scaffoldFormBuzy: false, scaffoldError: '', @@ -997,6 +999,13 @@ export const MainStore = types 1, true ); + }, + + get scaffoldData() { + return createObject(self.ctx, { + ...(self.scaffoldForm?.value || {}), + __step: self.scaffoldFormStep + }); } }; }) @@ -1671,6 +1680,10 @@ export const MainStore = types self.scaffoldFormBuzy = !!value; }, + setScaffoldStep(value: number) { + self.scaffoldFormStep = value; + }, + setScaffoldError(msg: string = '') { self.scaffoldError = msg; }, diff --git a/packages/amis/src/renderers/CRUD.tsx b/packages/amis/src/renderers/CRUD.tsx index 5c58d7e7e..10c137dda 100644 --- a/packages/amis/src/renderers/CRUD.tsx +++ b/packages/amis/src/renderers/CRUD.tsx @@ -50,6 +50,7 @@ import type {CardsRendererEvent} from './Cards'; import {isPureVariable, resolveVariableAndFilter, parseQuery} from 'amis-core'; import type {PaginationProps} from './Pagination'; +import {isAlive} from 'mobx-state-tree'; export type CRUDBultinToolbarType = | 'columns-toggler' @@ -1186,6 +1187,10 @@ export default class CRUD extends React.Component { columns: store.columns ?? columns }) .then(async value => { + if (!isAlive(store)) { + return value; + } + const {page, lastPage, data, msg, error} = store; if (isInit) { From 04453bce0f1aae2cda1ecaa1bdc48ece226c7290 Mon Sep 17 00:00:00 2001 From: liaoxuezhi <2betop.cn@gmail.com> Date: Fri, 12 May 2023 13:16:50 +0800 Subject: [PATCH 009/274] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20#6372=20?= =?UTF-8?q?=E5=BC=95=E5=85=A5=E7=9A=84=E5=88=B7=E6=96=B0=E7=9B=AE=E6=A0=87?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=BC=A0=E9=80=92=E5=A4=8D=E6=9D=82=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=9A=84=E9=97=AE=E9=A2=98=20(#6864)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/RootRenderer.tsx | 4 ++-- packages/amis-core/src/Scoped.tsx | 17 +++++++++++++++ packages/amis-core/src/index.tsx | 5 +++-- packages/amis-core/src/renderers/Form.tsx | 22 +++++++++++++------- packages/amis/src/renderers/CRUD.tsx | 14 ++++++------- packages/amis/src/renderers/CRUD2.tsx | 8 +++---- packages/amis/src/renderers/Dialog.tsx | 7 +++++-- packages/amis/src/renderers/Drawer.tsx | 7 +++++-- packages/amis/src/renderers/Page.tsx | 7 +++++-- packages/amis/src/renderers/Service.tsx | 7 +++++-- packages/amis/src/renderers/Table2/index.tsx | 7 ++++--- packages/amis/src/renderers/Wizard.tsx | 14 ++++++++----- 12 files changed, 81 insertions(+), 38 deletions(-) diff --git a/packages/amis-core/src/RootRenderer.tsx b/packages/amis-core/src/RootRenderer.tsx index 532221b94..bb9a398a3 100644 --- a/packages/amis-core/src/RootRenderer.tsx +++ b/packages/amis-core/src/RootRenderer.tsx @@ -1,7 +1,7 @@ import {observer} from 'mobx-react'; import React from 'react'; import type {RootProps} from './Root'; -import {IScopedContext, ScopedContext} from './Scoped'; +import {IScopedContext, ScopedContext, filterTarget} from './Scoped'; import {IRootStore, RootStore} from './store/root'; import {ActionObject} from './types'; import {bulkBindFunctions, guid, isVisible} from './utils/helper'; @@ -202,7 +202,7 @@ export class RootRenderer extends React.Component { action.reload && this.reloadTarget( delegate || (this.context as IScopedContext), - filter(action.reload, ctx), + filterTarget(action.reload, ctx), store.data ); }) diff --git a/packages/amis-core/src/Scoped.tsx b/packages/amis-core/src/Scoped.tsx index 9b0ef6afc..59dbf8612 100644 --- a/packages/amis-core/src/Scoped.tsx +++ b/packages/amis-core/src/Scoped.tsx @@ -23,6 +23,23 @@ import {RendererData, ActionObject} from './types'; import {isPureVariable} from './utils/isPureVariable'; import {filter} from './utils'; +/** + * target 里面可能包含 ?xxx=xxx,这种情况下,需要把 ?xxx=xxx 保留下来,然后对前面的部分进行 filter + * 因为后面会对 query 部分做不一样的处理。会保留原始的值。而不是会转成字符串。 + * @param target + * @param data + * @returns + */ +export function filterTarget(target: string, data: Record) { + const idx = target.indexOf('?'); + + if (~idx) { + return filter(target.slice(0, idx), data) + target.slice(idx); + } + + return filter(target, data, '| raw'); +} + export interface ScopedComponentType extends React.Component { focus?: () => void; doAction?: ( diff --git a/packages/amis-core/src/index.tsx b/packages/amis-core/src/index.tsx index 991835e93..48d809120 100644 --- a/packages/amis-core/src/index.tsx +++ b/packages/amis-core/src/index.tsx @@ -43,7 +43,7 @@ import { } from './locale'; import type {LocaleProps, TranslateFn} from './locale'; -import Scoped, {ScopedContext} from './Scoped'; +import Scoped, {ScopedContext, filterTarget} from './Scoped'; import type {ScopedComponentType, IScopedContext} from './Scoped'; import { @@ -189,7 +189,8 @@ export { IColumn2, IRow2, OnEventProps, - FormSchemaBase + FormSchemaBase, + filterTarget }; export function render( diff --git a/packages/amis-core/src/renderers/Form.tsx b/packages/amis-core/src/renderers/Form.tsx index c5d6736f1..c57ea3e4c 100644 --- a/packages/amis-core/src/renderers/Form.tsx +++ b/packages/amis-core/src/renderers/Form.tsx @@ -35,7 +35,12 @@ import { import debouce from 'lodash/debounce'; import flatten from 'lodash/flatten'; import find from 'lodash/find'; -import {ScopedContext, IScopedContext, ScopedComponentType} from '../Scoped'; +import { + ScopedContext, + IScopedContext, + ScopedComponentType, + filterTarget +} from '../Scoped'; import {IComboStore} from '../store/combo'; import {dataMapping} from '../utils/tpl-builtin'; @@ -1096,11 +1101,11 @@ export default class Form extends React.Component { dispatchEvent('validateSucc', this.props.data); if (target) { - this.submitToTarget(filter(target, values), values); + this.submitToTarget(filterTarget(target, values), values); dispatchEvent('submitSucc', createObject(this.props.data, values)); } else if (action.actionType === 'reload') { action.target && - this.reloadTarget(filter(action.target, values), values); + this.reloadTarget(filterTarget(action.target, values), values); } else if (action.actionType === 'dialog') { store.openDialog(data); } else if (action.actionType === 'drawer') { @@ -1200,7 +1205,7 @@ export default class Form extends React.Component { finalRedirect && env.jumpTo(finalRedirect, action); } else if (action.reload || reload) { this.reloadTarget( - filter(action.reload || reload!, store.data), + filterTarget(action.reload || reload!, store.data), store.data ); } @@ -1266,7 +1271,10 @@ export default class Form extends React.Component { redirect && env.jumpTo(redirect, action); action.reload && - this.reloadTarget(filter(action.reload, store.data), store.data); + this.reloadTarget( + filterTarget(action.reload, store.data), + store.data + ); action.close && this.closeTarget(action.close); }) .catch(e => { @@ -1278,11 +1286,11 @@ export default class Form extends React.Component { } else if (action.actionType === 'reload') { store.setCurrentAction(action); if (action.target) { - this.reloadTarget(filter(action.target, data), data); + this.reloadTarget(filterTarget(action.target, data), data); } else { this.receive(data); } - // action.target && this.reloadTarget(action.target, data); + // action.target && this.reloadTarget(filterTarget(action.target, data), data); } else if (onAction) { // 不识别的丢给上层去处理。 return onAction(e, action, data, throwErrors, delegate || this.context); diff --git a/packages/amis/src/renderers/CRUD.tsx b/packages/amis/src/renderers/CRUD.tsx index 10c137dda..04ce39c01 100644 --- a/packages/amis/src/renderers/CRUD.tsx +++ b/packages/amis/src/renderers/CRUD.tsx @@ -2,7 +2,7 @@ import React from 'react'; import isEqual from 'lodash/isEqual'; import pickBy from 'lodash/pickBy'; import omitBy from 'lodash/omitBy'; -import {Renderer, RendererProps} from 'amis-core'; +import {Renderer, RendererProps, filterTarget} from 'amis-core'; import {SchemaNode, Schema, ActionObject, PlainObject} from 'amis-core'; import {CRUDStore, ICRUDStore} from 'amis-core'; import { @@ -714,7 +714,7 @@ export default class CRUD extends React.Component { const redirect = action.redirect && filter(action.redirect, data); redirect && !action.blank && env.jumpTo(redirect, action); action.reload - ? this.reloadTarget(filter(action.reload, data), data) + ? this.reloadTarget(filterTarget(action.reload, data), data) : redirect ? null : this.search(undefined, undefined, true, true); @@ -813,7 +813,7 @@ export default class CRUD extends React.Component { } action.reload - ? this.reloadTarget(filter(action.reload, data), data) + ? this.reloadTarget(filterTarget(action.reload, data), data) : this.search( {[pageField || 'page']: 1}, undefined, @@ -1081,7 +1081,7 @@ export default class CRUD extends React.Component { const reload = action.reload ?? dialogAction.reload; if (reload) { - this.reloadTarget(filter(reload, ctx), ctx); + this.reloadTarget(filterTarget(reload, ctx), ctx); } let redirect = action.redirect ?? dialogAction.redirect; @@ -1350,7 +1350,7 @@ export default class CRUD extends React.Component { .then(() => { const finalReload = options?.reload ?? reload; finalReload - ? this.reloadTarget(filter(finalReload, data), data) + ? this.reloadTarget(filterTarget(finalReload, data), data) : this.search(undefined, undefined, true, true); }) .catch(() => {}); @@ -1372,7 +1372,7 @@ export default class CRUD extends React.Component { .then(() => { const finalReload = options?.reload ?? reload; finalReload - ? this.reloadTarget(filter(finalReload, data), data) + ? this.reloadTarget(filterTarget(finalReload, data), data) : this.search(undefined, undefined, true, true); }) .catch(() => { @@ -1477,7 +1477,7 @@ export default class CRUD extends React.Component { store .saveRemote(saveOrderApi, model) .then(() => { - reload && this.reloadTarget(filter(reload, model), model); + reload && this.reloadTarget(filterTarget(reload, model), model); this.search(undefined, undefined, true, true); }) .catch(() => {}); diff --git a/packages/amis/src/renderers/CRUD2.tsx b/packages/amis/src/renderers/CRUD2.tsx index bf2f747b3..11d0aea9d 100644 --- a/packages/amis/src/renderers/CRUD2.tsx +++ b/packages/amis/src/renderers/CRUD2.tsx @@ -1,6 +1,6 @@ import React from 'react'; import omitBy from 'lodash/omitBy'; -import {Renderer, RendererProps} from 'amis-core'; +import {Renderer, RendererProps, filterTarget} from 'amis-core'; import {CRUDStore, ICRUDStore} from 'amis-core'; import { createObject, @@ -676,7 +676,7 @@ export default class CRUD2 extends React.Component { errorMessage: messages && messages.saveSuccess }) .then(() => { - reload && this.reloadTarget(filter(reload, data), data); + reload && this.reloadTarget(filterTarget(reload, data), data); this.getData(undefined, undefined, true); }) .catch(() => {}); @@ -696,7 +696,7 @@ export default class CRUD2 extends React.Component { store .saveRemote(quickSaveItemApi, sendData) .then(() => { - reload && this.reloadTarget(filter(reload, data), data); + reload && this.reloadTarget(filterTarget(reload, data), data); this.getData(undefined, undefined, true); }) @@ -803,7 +803,7 @@ export default class CRUD2 extends React.Component { store .saveRemote(saveOrderApi, model) .then(() => { - reload && this.reloadTarget(filter(reload, model), model); + reload && this.reloadTarget(filterTarget(reload, model), model); this.getData(undefined, undefined, true); }) .catch(() => {}); diff --git a/packages/amis/src/renderers/Dialog.tsx b/packages/amis/src/renderers/Dialog.tsx index ae0d2a117..a8a2a50f2 100644 --- a/packages/amis/src/renderers/Dialog.tsx +++ b/packages/amis/src/renderers/Dialog.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {ScopedContext, IScopedContext} from 'amis-core'; +import {ScopedContext, IScopedContext, filterTarget} from 'amis-core'; import {Renderer, RendererProps} from 'amis-core'; import {SchemaNode, Schema, ActionObject} from 'amis-core'; import {filter} from 'amis-core'; @@ -914,7 +914,10 @@ export class DialogRenderer extends Dialog { action.redirect && filter(action.redirect, store.data); reidrect && env.jumpTo(reidrect, action); action.reload && - this.reloadTarget(filter(action.reload, store.data), store.data); + this.reloadTarget( + filterTarget(action.reload, store.data), + store.data + ); if (action.close) { action.close === true ? this.handleSelfClose() diff --git a/packages/amis/src/renderers/Drawer.tsx b/packages/amis/src/renderers/Drawer.tsx index 6abdb43b9..88c69f25c 100644 --- a/packages/amis/src/renderers/Drawer.tsx +++ b/packages/amis/src/renderers/Drawer.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {ScopedContext, IScopedContext} from 'amis-core'; +import {ScopedContext, IScopedContext, filterTarget} from 'amis-core'; import {Renderer, RendererProps} from 'amis-core'; import {SchemaNode, Schema, ActionObject} from 'amis-core'; import {Drawer as DrawerContainer, SpinnerExtraProps} from 'amis-ui'; @@ -859,7 +859,10 @@ export class DrawerRenderer extends Drawer { action.redirect && filter(action.redirect, store.data); redirect && env.jumpTo(redirect, action); action.reload && - this.reloadTarget(filter(action.reload, store.data), store.data); + this.reloadTarget( + filterTarget(action.reload, store.data), + store.data + ); if (action.close) { action.close === true diff --git a/packages/amis/src/renderers/Page.tsx b/packages/amis/src/renderers/Page.tsx index 970ea0948..4ad499f87 100644 --- a/packages/amis/src/renderers/Page.tsx +++ b/packages/amis/src/renderers/Page.tsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {Renderer, RendererProps} from 'amis-core'; +import {Renderer, RendererProps, filterTarget} from 'amis-core'; import {observer} from 'mobx-react'; import {ServiceStore, IServiceStore} from 'amis-core'; import { @@ -513,7 +513,10 @@ export default class Page extends React.Component { action.redirect && filter(action.redirect, store.data); redirect && env.jumpTo(redirect, action); action.reload && - this.reloadTarget(filter(action.reload, store.data), store.data); + this.reloadTarget( + filterTarget(action.reload, store.data), + store.data + ); }) .catch(e => { if (throwErrors || action.countDown) { diff --git a/packages/amis/src/renderers/Service.tsx b/packages/amis/src/renderers/Service.tsx index 95cb6227c..e269ae929 100644 --- a/packages/amis/src/renderers/Service.tsx +++ b/packages/amis/src/renderers/Service.tsx @@ -1,7 +1,7 @@ import React from 'react'; import extend from 'lodash/extend'; import cloneDeep from 'lodash/cloneDeep'; -import {Renderer, RendererProps} from 'amis-core'; +import {Renderer, RendererProps, filterTarget} from 'amis-core'; import {ServiceStore, IServiceStore} from 'amis-core'; import {Api, RendererData, ActionObject} from 'amis-core'; import {filter, evalExpression} from 'amis-core'; @@ -702,7 +702,10 @@ export default class Service extends React.Component { action.redirect && filter(action.redirect, store.data); redirect && env.jumpTo(redirect, action); action.reload && - this.reloadTarget(filter(action.reload, store.data), store.data); + this.reloadTarget( + filterTarget(action.reload, store.data), + store.data + ); }) .catch(e => { if (throwErrors || action.countDown) { diff --git a/packages/amis/src/renderers/Table2/index.tsx b/packages/amis/src/renderers/Table2/index.tsx index 177c40544..890c3f6ef 100644 --- a/packages/amis/src/renderers/Table2/index.tsx +++ b/packages/amis/src/renderers/Table2/index.tsx @@ -25,7 +25,8 @@ import { ITableStore2, IRow2, ClassNamesFn, - isArrayChildrenModified + isArrayChildrenModified, + filterTarget } from 'amis-core'; import {Icon, Table, Spinner, BadgeObject, SpinnerExtraProps} from 'amis-ui'; import type { @@ -944,7 +945,7 @@ export default class Table2 extends React.Component { errorMessage: messages && messages.saveSuccess }) .then(() => { - reload && this.reloadTarget(filter(reload, data), data); + reload && this.reloadTarget(filterTarget(reload, data), data); }) .catch(() => {}); } else { @@ -963,7 +964,7 @@ export default class Table2 extends React.Component { store .saveRemote(quickSaveItemApi, sendData) .then(() => { - reload && this.reloadTarget(filter(reload, data), data); + reload && this.reloadTarget(filterTarget(reload, data), data); }) .catch(() => { options?.resetOnFailed && this.reset(); diff --git a/packages/amis/src/renderers/Wizard.tsx b/packages/amis/src/renderers/Wizard.tsx index ed6db0739..1a75ec7d8 100644 --- a/packages/amis/src/renderers/Wizard.tsx +++ b/packages/amis/src/renderers/Wizard.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {ScopedContext, IScopedContext} from 'amis-core'; +import {ScopedContext, IScopedContext, filterTarget} from 'amis-core'; import {Renderer, RendererProps} from 'amis-core'; import {ServiceStore, IServiceStore} from 'amis-core'; import {Api, ActionObject} from 'amis-core'; @@ -675,11 +675,15 @@ export default class Wizard extends React.Component { reidrect && env.jumpTo(reidrect, action); action.reload && - this.reloadTarget(filter(action.reload, store.data), store.data); + this.reloadTarget( + filterTarget(action.reload, store.data), + store.data + ); }) .catch(reason => {}); } else if (action.actionType === 'reload') { - action.target && this.reloadTarget(filter(action.target, data), data); + action.target && + this.reloadTarget(filterTarget(action.target, data), data); } else if (action.actionType === 'goto-step') { const targetStep = (data as any).step; @@ -783,7 +787,7 @@ export default class Wizard extends React.Component { // 最后一步 if (target) { - this.submitToTarget(filter(target, store.data), store.data); + this.submitToTarget(filterTarget(target, store.data), store.data); this.setState({completeStep: steps.length}); } else if (action.api || step.api || api) { let finnalAsyncApi = action.asyncApi || step.asyncApi || asyncApi; @@ -872,7 +876,7 @@ export default class Wizard extends React.Component { env.jumpTo(finalRedirect, action); } else if (action.reload || step.reload || reload) { this.reloadTarget( - filter(action.reload || step.reload || reload!, store.data), + filterTarget(action.reload || step.reload || reload!, store.data), store.data ); } From e000a3ddaa4d02bc55d472923526f81fa68c0080 Mon Sep 17 00:00:00 2001 From: liuguihua Date: Fri, 12 May 2023 15:16:31 +0800 Subject: [PATCH 010/274] =?UTF-8?q?feat(amis):input-image=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=BF=87=E5=A4=A7=E6=8F=90=E7=A4=BA=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis/src/renderers/Form/InputImage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/amis/src/renderers/Form/InputImage.tsx b/packages/amis/src/renderers/Form/InputImage.tsx index 6711acb61..d6876c559 100644 --- a/packages/amis/src/renderers/Form/InputImage.tsx +++ b/packages/amis/src/renderers/Form/InputImage.tsx @@ -631,9 +631,9 @@ export default class ImageControl extends React.Component< }); } // 文件太大 - else if (err.code === ErrorCode.FileTooLarge && maxSize) { + else if (err.code === ErrorCode.FileTooLarge) { return __('File.sizeLimit', { - maxSize: prettyBytes(maxSize, 1024) + maxSize: prettyBytes(maxSize as number, 1024) }); } }) From e73426d5f1781e00522650ea783f758a92458358 Mon Sep 17 00:00:00 2001 From: lengshengren <379306634@qq.com> Date: Fri, 12 May 2023 15:26:54 +0800 Subject: [PATCH 011/274] =?UTF-8?q?fix:=20input=20number=20=E5=85=BC?= =?UTF-8?q?=E5=AE=B91.x=20=E6=B2=A1=E6=9C=89=E8=AE=BE=E7=BD=AE=E7=B2=BE?= =?UTF-8?q?=E5=BA=A6=E4=B9=9F=E5=8F=AF=E4=BB=A5=E5=BD=95=E5=85=A5=E5=B0=8F?= =?UTF-8?q?=E6=95=B0=20(#6469)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 排序字段中间态 orderDir 没有置空问题 * 修改代码规范 * 去掉 setting.json 配置 里的ts 格式 * 格式化代码 * 兼容input-number * 兼容input-number * 兼容1.x 精度是undefined 默认是可以输入小数 * 解决差异 * Delete docs.json * 还原 docs.json * 只修改渲染器影响范围小点 --------- Co-authored-by: srleng Co-authored-by: liaoxuezhi <2betop.cn@gmail.com> --- packages/amis-ui/src/components/NumberInput.tsx | 2 +- packages/amis/src/renderers/Form/InputNumber.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/amis-ui/src/components/NumberInput.tsx b/packages/amis-ui/src/components/NumberInput.tsx index 69b7deeda..a96fbef01 100644 --- a/packages/amis-ui/src/components/NumberInput.tsx +++ b/packages/amis-ui/src/components/NumberInput.tsx @@ -209,6 +209,7 @@ export class NumberInput extends React.Component { const {min, max, step, precision, resetValue, clearValueOnEmpty, onChange} = this.props; const finalPrecision = NumberInput.normalizePrecision(precision, step); + const result = NumberInput.normalizeValue( value, min, @@ -218,7 +219,6 @@ export class NumberInput extends React.Component { clearValueOnEmpty, this.isBig ); - onChange?.(result); } diff --git a/packages/amis/src/renderers/Form/InputNumber.tsx b/packages/amis/src/renderers/Form/InputNumber.tsx index c4cdef6df..0fc033c52 100644 --- a/packages/amis/src/renderers/Form/InputNumber.tsx +++ b/packages/amis/src/renderers/Form/InputNumber.tsx @@ -162,6 +162,7 @@ export default class NumberControl extends React.Component< input?: HTMLInputElement; static defaultProps: Partial = { step: 1, + precision: 2, resetValue: '', clearValueOnEmpty: false }; From 182b41a838225f1fc9a57b1d80443da512622a94 Mon Sep 17 00:00:00 2001 From: lghxuelang <963601654@qq.com> Date: Fri, 12 May 2023 15:27:22 +0800 Subject: [PATCH 012/274] =?UTF-8?q?feat(amis):=20input-image=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=BF=87=E5=A4=A7=E6=8F=90=E7=A4=BA=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20(#6859)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(amis-editor):增加inputText、textArea最大字数配置&修复上下文变量过长显示问题 * feat(amis-editor):增加inputText、textArea最大字数配置&修复上下文变量过长显示问题 * feat(amis):input-image文件过大提示显示优化 * feat(amis):input-image文件过大提示显示优化 --------- Co-authored-by: liuguihua --- .../amis/src/renderers/Form/InputImage.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/amis/src/renderers/Form/InputImage.tsx b/packages/amis/src/renderers/Form/InputImage.tsx index a7aa9e6c8..d6876c559 100644 --- a/packages/amis/src/renderers/Form/InputImage.tsx +++ b/packages/amis/src/renderers/Form/InputImage.tsx @@ -14,11 +14,13 @@ import {FileRejection, ErrorCode, DropEvent} from 'react-dropzone'; import 'blueimp-canvastoblob'; import find from 'lodash/find'; import {Payload, ActionObject} from 'amis-core'; -import {buildApi, +import { + buildApi, isEffectiveApi, normalizeApi, isApiOutdated, - isApiOutdatedWithData} from 'amis-core'; + isApiOutdatedWithData +} from 'amis-core'; import {createObject, qsstringify, guid, isEmpty, qsparse} from 'amis-core'; import {Icon, TooltipWrapper, Button} from 'amis-ui'; import accepts from 'attr-accept'; @@ -630,7 +632,9 @@ export default class ImageControl extends React.Component< } // 文件太大 else if (err.code === ErrorCode.FileTooLarge) { - return __('File.sizeLimit', {maxSize}); + return __('File.sizeLimit', { + maxSize: prettyBytes(maxSize as number, 1024) + }); } }) .join('; '); @@ -1926,11 +1930,11 @@ export default class ImageControl extends React.Component< props.data, prevProps.data ) || - isApiOutdatedWithData( - props.receiver, - prevProps.receiver, - props.data, - prevProps.data - )) + isApiOutdatedWithData( + props.receiver, + prevProps.receiver, + props.data, + prevProps.data + )) }) export class ImageControlRenderer extends ImageControl {} From b2022d83d6eda2a3141f658c3cd2d945714aa697 Mon Sep 17 00:00:00 2001 From: lvxiaojiao Date: Fri, 12 May 2023 16:21:15 +0800 Subject: [PATCH 013/274] =?UTF-8?q?chore:crud=E6=94=AF=E6=8C=81canAccessSu?= =?UTF-8?q?perData&=E6=96=87=E6=A1=A3=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/crud.md | 17 ++++++++++++----- packages/amis/src/renderers/Table/TableCell.tsx | 4 +++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/zh-CN/components/crud.md b/docs/zh-CN/components/crud.md index 0a4e03ce4..a3cc31799 100755 --- a/docs/zh-CN/components/crud.md +++ b/docs/zh-CN/components/crud.md @@ -107,7 +107,11 @@ CRUD,即增删改查组件,主要用来展现数据列表,并支持各类 } ``` -## 数据源接口数据结构要求 +## 数据源接口 + +### 数据结构 + +CRUD 组件对数据源接口的数据结构要求如下: - `items`或`rows`:用于返回数据源数据,格式是数组 - `total`: 用于返回数据库中一共有多少条数据,用于生成分页 @@ -174,9 +178,11 @@ CRUD,即增删改查组件,主要用来展现数据列表,并支持各类 如果不需要分页,或者配置了 `loadDataOnce` 则可以忽略掉 `total` 和 `hasNext` 参数。 -> 如果 api 地址中有变量,比如 `/api/mock2/sample/${id}`,amis 就不会自动加上分页参数,需要自己加上,改成 `/api/mock2/sample/${id}?page=${page}&perPage=${perPage}` +### Query 参数 -## 分页参数 +数据源接口地址可以通过变量实现动态拼接,例如: `/api/mock2/sample/${id}`,但需要注意的是接口地址拼接变量后,amis 就不会自动追加默认参数了,例如:分页参数、查询参数等,如需追加,可以自行拼接,例如: `/api/mock2/sample/${id}?page=${page}&perPage=${perPage}` + +### 分页参数 默认的分页参数是 `page` 和 `perPage`,page 代表页数,比如第一页,perPage 代表每页显示几行。 @@ -558,7 +564,7 @@ Cards 模式支持 [Cards](./cards) 中的所有功能。 大部分表格展示有对数据进行检索的需求,CRUD 自身支持通过配置`filter`,实现查询条件过滤表单。`filter` 配置实际上同 [Form](./form/index) 组件,因此支持绝大部分`form`的功能。 -在条件搜索区的 `Engine` 输入框中输入任意值查询会发现结果中 `ID` 为 1 - 3 的 `Rendering engine` 列因为返回值中没有对应字段值,被错误填入了与 `filter` 中相同 `name` 的字段值,这是因为表格 Cell 通过[数据链](../../docs/concepts/datascope-and-datachain)获取到了上层数据域 `filter` 中相同字段的数据值。这种情况可以在 CRUD `columns` 对应列配置`"canAccessSuperData": false`禁止访问父级数据域(比如: `Platform`列)。 +在条件搜索区的 `Engine` 输入框中输入任意值查询会发现结果中 `ID` 为 1 - 3 的 `Rendering engine` 列因为返回值中没有对应字段值,被错误填入了与 `filter` 中相同 `name` 的字段值,这是因为表格 Cell 通过[数据链](../../docs/concepts/datascope-and-datachain)获取到了上层数据域 `filter` 中相同字段的数据值。这种情况可以在 CRUD `columns` 对应列配置`"canAccessSuperData": false`禁止访问父级数据域(比如: `Platform`列),或者 CRUD`"canAccessSuperData": false`追加配置禁止所有列访问父级数据域。 ```schema: scope="body" { @@ -2896,9 +2902,10 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据, | footerToolbar | Array | `['statistics', 'pagination']` | 底部工具栏配置 | | alwaysShowPagination | `boolean` | `false` | 是否总是显示分页 | | affixHeader | `boolean` | `true` | 是否固定表头(table 下) | -| autoGenerateFilter | `Object \| boolean` | | 是否开启查询区域,开启后会根据列元素的 `searchable` 属性值,自动生成查询条件表单 | +| autoGenerateFilter | `Object \| boolean` | | 是否开启查询区域,开启后会根据列元素的 `searchable` 属性值,自动生成查询条件表单 | | resetPageAfterAjaxItemAction | `boolean` | `false` | 单条数据 ajax 操作后是否重置页码为第一页 | | autoFillHeight | `boolean` 丨 `{height: number}` | | 内容区域自适应高度 | +| canAccessSuperData | `boolean` | `true` | 指定是否可以自动获取上层的数据并映射到表格行数据上 | 注意除了上面这些属性,CRUD 在不同模式下的属性需要参考各自的文档,比如 diff --git a/packages/amis/src/renderers/Table/TableCell.tsx b/packages/amis/src/renderers/Table/TableCell.tsx index eb4e3b403..3f9848b59 100644 --- a/packages/amis/src/renderers/Table/TableCell.tsx +++ b/packages/amis/src/renderers/Table/TableCell.tsx @@ -72,7 +72,9 @@ export class TableCell extends React.Component { className: innerClassName, type: (column && column.type) || 'plain' }; - const canAccessSuperData = schema?.canAccessSuperData !== false; + // 表的比列的优先级高 + const canAccessSuperData = + this.props.canAccessSuperData ?? schema?.canAccessSuperData !== false; // 如果本来就是 type 为 button,不要删除,其他情况下都应该删除。 if (schema.type !== 'button' && schema.type !== 'dropdown-button') { From e8b8b21e2e8e9469418aa4664ab5c45546c38b0d Mon Sep 17 00:00:00 2001 From: lvxiaojiao Date: Fri, 12 May 2023 16:23:59 +0800 Subject: [PATCH 014/274] =?UTF-8?q?chore:crud=E6=94=AF=E6=8C=81canAccessSu?= =?UTF-8?q?perData&=E6=96=87=E6=A1=A3=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/crud.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-CN/components/crud.md b/docs/zh-CN/components/crud.md index a3cc31799..29df2bd29 100755 --- a/docs/zh-CN/components/crud.md +++ b/docs/zh-CN/components/crud.md @@ -564,7 +564,7 @@ Cards 模式支持 [Cards](./cards) 中的所有功能。 大部分表格展示有对数据进行检索的需求,CRUD 自身支持通过配置`filter`,实现查询条件过滤表单。`filter` 配置实际上同 [Form](./form/index) 组件,因此支持绝大部分`form`的功能。 -在条件搜索区的 `Engine` 输入框中输入任意值查询会发现结果中 `ID` 为 1 - 3 的 `Rendering engine` 列因为返回值中没有对应字段值,被错误填入了与 `filter` 中相同 `name` 的字段值,这是因为表格 Cell 通过[数据链](../../docs/concepts/datascope-and-datachain)获取到了上层数据域 `filter` 中相同字段的数据值。这种情况可以在 CRUD `columns` 对应列配置`"canAccessSuperData": false`禁止访问父级数据域(比如: `Platform`列),或者 CRUD`"canAccessSuperData": false`追加配置禁止所有列访问父级数据域。 +在条件搜索区的 `Engine` 输入框中输入任意值查询会发现结果中 `ID` 为 1 - 3 的 `Rendering engine` 列因为返回值中没有对应字段值,被错误填入了与 `filter` 中相同 `name` 的字段值,这是因为表格 Cell 通过[数据链](../../docs/concepts/datascope-and-datachain)获取到了上层数据域 `filter` 中相同字段的数据值。这种情况可以在 CRUD `columns` 对应列配置`"canAccessSuperData": false`禁止访问父级数据域(比如: `Platform`列),或者 CRUD 追加`"canAccessSuperData": false`配置禁止所有列访问父级数据域。 ```schema: scope="body" { From 87de75681d8b38f636c55eef5fc1f28c54bad36a Mon Sep 17 00:00:00 2001 From: lvxiaojiao Date: Fri, 12 May 2023 16:31:51 +0800 Subject: [PATCH 015/274] =?UTF-8?q?chore:crud=E6=94=AF=E6=8C=81canAccessSu?= =?UTF-8?q?perData&=E6=96=87=E6=A1=A3=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/crud.md | 2 +- packages/amis/src/renderers/Table/TableCell.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh-CN/components/crud.md b/docs/zh-CN/components/crud.md index 29df2bd29..6e55bc0ce 100755 --- a/docs/zh-CN/components/crud.md +++ b/docs/zh-CN/components/crud.md @@ -2905,7 +2905,7 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据, | autoGenerateFilter | `Object \| boolean` | | 是否开启查询区域,开启后会根据列元素的 `searchable` 属性值,自动生成查询条件表单 | | resetPageAfterAjaxItemAction | `boolean` | `false` | 单条数据 ajax 操作后是否重置页码为第一页 | | autoFillHeight | `boolean` 丨 `{height: number}` | | 内容区域自适应高度 | -| canAccessSuperData | `boolean` | `true` | 指定是否可以自动获取上层的数据并映射到表格行数据上 | +| canAccessSuperData | `boolean` | `true` | 指定是否可以自动获取上层的数据并映射到表格行数据上,如果列也配置了该属性,则列的优先级更高 | 注意除了上面这些属性,CRUD 在不同模式下的属性需要参考各自的文档,比如 diff --git a/packages/amis/src/renderers/Table/TableCell.tsx b/packages/amis/src/renderers/Table/TableCell.tsx index 3f9848b59..d594a4389 100644 --- a/packages/amis/src/renderers/Table/TableCell.tsx +++ b/packages/amis/src/renderers/Table/TableCell.tsx @@ -72,9 +72,9 @@ export class TableCell extends React.Component { className: innerClassName, type: (column && column.type) || 'plain' }; - // 表的比列的优先级高 + // 列比表的的优先级高 const canAccessSuperData = - this.props.canAccessSuperData ?? schema?.canAccessSuperData !== false; + (schema?.canAccessSuperData ?? this.props.canAccessSuperData) !== false; // 如果本来就是 type 为 button,不要删除,其他情况下都应该删除。 if (schema.type !== 'button' && schema.type !== 'dropdown-button') { From 2adb2354dbe4aba6ee655f8ddc2553a96c622509 Mon Sep 17 00:00:00 2001 From: wuduoyi Date: Fri, 12 May 2023 18:42:22 +0800 Subject: [PATCH 016/274] =?UTF-8?q?fix:=20input-excel=20=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=20hidden=20=E7=9A=84=20worksheet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis/src/renderers/Form/InputExcel.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/amis/src/renderers/Form/InputExcel.tsx b/packages/amis/src/renderers/Form/InputExcel.tsx index d99e22b2c..0de944c0d 100644 --- a/packages/amis/src/renderers/Form/InputExcel.tsx +++ b/packages/amis/src/renderers/Form/InputExcel.tsx @@ -124,6 +124,11 @@ export default class ExcelControl extends React.PureComponent< let sheetsResult: any = []; if (allSheets) { workbook.eachSheet((worksheet: any) => { + const sheetState = worksheet.state || 'visible'; + // hidden 的不处理 + if (sheetState === 'hidden') { + return; + } if (parseImage) { sheetsResult.push({ sheetName: worksheet.name, From 3bbf35fa515fe8f881213c19b22a5c387592c54e Mon Sep 17 00:00:00 2001 From: wuduoyi Date: Fri, 12 May 2023 18:50:46 +0800 Subject: [PATCH 017/274] =?UTF-8?q?fix:=20input-excel=20=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=20hidden=20=E7=9A=84=20worksheet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis/src/renderers/Form/InputExcel.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/amis/src/renderers/Form/InputExcel.tsx b/packages/amis/src/renderers/Form/InputExcel.tsx index 0de944c0d..9225c3e02 100644 --- a/packages/amis/src/renderers/Form/InputExcel.tsx +++ b/packages/amis/src/renderers/Form/InputExcel.tsx @@ -143,7 +143,16 @@ export default class ExcelControl extends React.PureComponent< } }); } else { - const worksheet = workbook.worksheets[0]; + let worksheet; + for (const sheet of workbook.worksheets) { + const sheetState = sheet.state || 'visible'; + // hidden 的不处理 + if (sheetState === 'hidden') { + continue; + } + worksheet = sheet; + break; + } if (parseImage) { const images = this.readImages(worksheet, workbook); From 77eef8b546d7eae2b880262e9d9d17cab60439ee Mon Sep 17 00:00:00 2001 From: wuduoyi Date: Fri, 12 May 2023 18:53:59 +0800 Subject: [PATCH 018/274] =?UTF-8?q?fix:=20input-excel=20=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=20hidden=20=E7=9A=84=20worksheet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis/src/renderers/Form/InputExcel.tsx | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/amis/src/renderers/Form/InputExcel.tsx b/packages/amis/src/renderers/Form/InputExcel.tsx index 9225c3e02..c7236479f 100644 --- a/packages/amis/src/renderers/Form/InputExcel.tsx +++ b/packages/amis/src/renderers/Form/InputExcel.tsx @@ -143,16 +143,9 @@ export default class ExcelControl extends React.PureComponent< } }); } else { - let worksheet; - for (const sheet of workbook.worksheets) { - const sheetState = sheet.state || 'visible'; - // hidden 的不处理 - if (sheetState === 'hidden') { - continue; - } - worksheet = sheet; - break; - } + const worksheet = workbook.worksheets.find( + (sheet: any) => sheet.state !== 'hidden' + ); if (parseImage) { const images = this.readImages(worksheet, workbook); From 59155be4a19892785c065d26786441e0e891671e Mon Sep 17 00:00:00 2001 From: liuguihua Date: Fri, 12 May 2023 20:05:42 +0800 Subject: [PATCH 019/274] =?UTF-8?q?feat(amis):CRUD=E5=88=97=E5=A4=B4?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E6=97=B6=E5=85=88=E9=87=8D=E7=BD=AE=E9=A1=B5?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Table/HeadCellFilterDropdown.tsx | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/amis/src/renderers/Table/HeadCellFilterDropdown.tsx b/packages/amis/src/renderers/Table/HeadCellFilterDropdown.tsx index 9ed966db4..0cc283d3b 100644 --- a/packages/amis/src/renderers/Table/HeadCellFilterDropdown.tsx +++ b/packages/amis/src/renderers/Table/HeadCellFilterDropdown.tsx @@ -29,7 +29,12 @@ export interface HeadCellFilterProps extends RendererProps { data: any; name: string; filterable: QuickFilterConfig; - onQuery: (values: object) => void; + onQuery: ( + values: object, + forceReload?: boolean, + replace?: boolean, + resetPage?: boolean + ) => void; } export class HeadCellFilterDropDown extends React.Component< @@ -211,9 +216,14 @@ export class HeadCellFilterDropDown extends React.Component< return; } - onQuery({ - [name]: value - }); + onQuery( + { + [name]: value + }, + false, + false, + true + ); this.close(); } @@ -247,9 +257,14 @@ export class HeadCellFilterDropDown extends React.Component< handleReset() { const {name, onQuery} = this.props; - onQuery({ - [name]: undefined - }); + onQuery( + { + [name]: undefined + }, + false, + false, + true + ); this.close(); } From 390883c79ee49ef0fb7f4a7eb048414574d856c6 Mon Sep 17 00:00:00 2001 From: sqzhou Date: Mon, 15 May 2023 12:14:08 +0800 Subject: [PATCH 020/274] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dselect?= =?UTF-8?q?=E5=BC=B9=E6=A1=86=E5=9B=A0=E4=B8=BA=E6=9C=80=E5=B0=8F=E4=B8=BA?= =?UTF-8?q?100px=E5=AF=BC=E8=87=B4=E7=9A=84curd=E5=88=86=E9=A1=B5=E4=B8=8B?= =?UTF-8?q?=E6=8B=89=E7=9A=84=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=20(#6881?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-ui/scss/components/form/_select.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/amis-ui/scss/components/form/_select.scss b/packages/amis-ui/scss/components/form/_select.scss index dabac7e60..d483fa5a7 100644 --- a/packages/amis-ui/scss/components/form/_select.scss +++ b/packages/amis-ui/scss/components/form/_select.scss @@ -150,7 +150,6 @@ .#{$ns}PopOver.#{$ns}Select-popover { margin-top: px2rem(4px); .#{$ns}Select-menu { - min-width: px2rem(100px); .#{$ns}Select-option { line-height: var(--select-base-default-option-line-height); } From 20a329766ef2b9660722832b4200c5fcaa5c61c2 Mon Sep 17 00:00:00 2001 From: wuduoyi Date: Mon, 15 May 2023 12:22:09 +0800 Subject: [PATCH 021/274] =?UTF-8?q?feat:=20log=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=AE=80=E5=8D=95=20ansi=20=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=EF=BC=8C=E5=8F=AF=E9=85=8D=E7=BD=AE=20credentials=20?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=20Closes=20#6039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/log.md | 25 ++--- packages/amis/src/renderers/Log.tsx | 92 +++++++++++++++--- .../__tests__/xlsx/simple/init.xlsx | Bin 0 -> 8821 bytes 3 files changed, 92 insertions(+), 25 deletions(-) create mode 100644 packages/ooxml-viewer/__tests__/xlsx/simple/init.xlsx diff --git a/docs/zh-CN/components/log.md b/docs/zh-CN/components/log.md index 0b5743d4f..85e65b735 100644 --- a/docs/zh-CN/components/log.md +++ b/docs/zh-CN/components/log.md @@ -93,7 +93,6 @@ public class StreamingResponseBodyController { 2. 设置 `maxLength`,限制最大显示行数 - 优点:某一行日志很长的时候会自动折行 - 缺点:无法查看之前的日志 -3. 试试通过 `"disableColor": false` 关闭 ANSI 颜色 ## 自动滚动到底部 @@ -160,14 +159,16 @@ public class StreamingResponseBodyController { ## 属性表 -| 属性名 | 类型 | 默认值 | 说明 | -| ----------- | --------- | ------ | -------------------------------------------------------- | -| height | `number` | 500 | 展示区域高度 | -| className | `string` | | 外层 CSS 类名 | -| autoScroll | `boolean` | true | 是否自动滚动 | -| placeholder | `string` | | 加载中的文字 | -| encoding | `string` | utf-8 | 返回内容的字符编码 | -| source | `string` | | 接口 | -| rowHeight | `number` | | 设置每行高度,将会开启虚拟渲染 | -| maxLength | `number` | | 最大显示行数 | -| operation | `Array` | | 可选日志操作:['stop','restart',clear','showLineNumber','filter'] | +| 属性名 | 类型 | 默认值 | 说明 | +| ------------ | --------- | --------- | ----------------------------------------------------------------- | +| height | `number` | 500 | 展示区域高度 | +| className | `string` | | 外层 CSS 类名 | +| autoScroll | `boolean` | true | 是否自动滚动 | +| disableColor | `boolean` | false | 是否禁用 ansi 颜色支持 | +| placeholder | `string` | | 加载中的文字 | +| encoding | `string` | utf-8 | 返回内容的字符编码 | +| source | `string` | | 接口 | +| credentials | `string` | 'include' | fetch 的 credentials 设置 | +| rowHeight | `number` | | 设置每行高度,将会开启虚拟渲染 | +| maxLength | `number` | | 最大显示行数 | +| operation | `Array` | | 可选日志操作:['stop','restart',clear','showLineNumber','filter'] | diff --git a/packages/amis/src/renderers/Log.tsx b/packages/amis/src/renderers/Log.tsx index 67547898b..0890c98eb 100644 --- a/packages/amis/src/renderers/Log.tsx +++ b/packages/amis/src/renderers/Log.tsx @@ -6,6 +6,29 @@ import {buildApi, isApiOutdated, Renderer, RendererProps} from 'amis-core'; import {BaseSchema} from '../Schema'; import {Icon, SearchBox, VirtualList} from 'amis-ui'; +const foregroundColors = { + '30': 'black', + '31': 'red', + '32': 'green', + '33': 'yellow', + '34': 'blue', + '35': 'magenta', + '36': 'cyan', + '37': 'white', + '90': 'grey' +} as {[key: string]: string}; + +const backgroundColors = { + '40': 'black', + '41': 'red', + '42': 'green', + '43': 'yellow', + '44': 'blue', + '45': 'magenta', + '46': 'cyan', + '47': 'white' +} as {[key: string]: string}; + export type LogOperation = | 'stop' | 'restart' @@ -62,6 +85,11 @@ export interface LogSchema extends BaseSchema { * 一些可操作选项 */ operation?: Array; + + /** + * credentials 配置 + */ + credentials?: string; } export interface LogProps @@ -179,14 +207,10 @@ export class Log extends React.Component { filterWord = (logs: string[], lastLine: string, word: string) => { let originLogs = logs; let originLastLine = lastLine; - if ( - word !== '' && - word !== undefined && - word !== null && - word.length > 0) { + if (word !== '' && word !== undefined && word !== null && word.length > 0) { logs = logs.filter(line => line.includes(word)); if (!lastLine.includes(word)) { - lastLine = ""; + lastLine = ''; } } this.setState({ @@ -194,12 +218,20 @@ export class Log extends React.Component { lastLine: lastLine, logs: logs, originLogs: originLogs, - originLastLine: originLastLine, + originLastLine: originLastLine }); - } + }; async loadLogs() { - const {source, data, env, translate: __, encoding, maxLength} = this.props; + const { + source, + data, + env, + translate: __, + encoding, + maxLength, + credentials = 'include' + } = this.props; // 因为这里返回结果是流式的,和普通 api 请求不一样,如果直接用 fetcher 经过 responseAdaptor 可能会导致出错,所以就直接 fetch 了 const api = buildApi(source, data); if (!api.url) { @@ -209,7 +241,7 @@ export class Log extends React.Component { method: api.method?.toLocaleUpperCase() || 'GET', headers: (api.headers as Record) || undefined, body: api.data ? JSON.stringify(api.data) : undefined, - credentials: 'include' + credentials: credentials as RequestCredentials }); if (res.status === 200) { const body = res.body; @@ -262,18 +294,46 @@ export class Log extends React.Component { } } + // 简单支持 ansi 颜色,只支持一行,不支持嵌套 + ansiColrToHtml(line: string) { + const {disableColor} = this.props; + if (disableColor === true) { + return line; + } + const match = line.match(/\u001b\[([^m]+)m/); + if (match) { + const colorNumber = match[1]; + if (colorNumber) { + line = line.replace(/\u001b[^m]*?m/g, ''); + if (colorNumber in foregroundColors) { + return ( + {line} + ); + } else if (colorNumber in backgroundColors) { + return ( + + {line.replace(/\u001b[^m]*?m/g, '')} + + ); + } + } + } + + return line; + } + renderHighlightWord(line: string) { const {classnames: cx} = this.props; let {filterWord} = this.state; if (filterWord === '') { - return line; + return this.ansiColrToHtml(line); } let items = line.split(filterWord); return items.map((item, index) => { if (index < items.length - 1) { return ( - {item} + {this.ansiColrToHtml(item)} {filterWord} ); @@ -404,7 +464,13 @@ export class Log extends React.Component { this.filterWord(this.state.originLogs, this.state.lastLine, value)} + onChange={value => + this.filterWord( + this.state.originLogs, + this.state.lastLine, + value + ) + } value={this.state.filterWord} /> )} diff --git a/packages/ooxml-viewer/__tests__/xlsx/simple/init.xlsx b/packages/ooxml-viewer/__tests__/xlsx/simple/init.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b769a3156a3a30aee010d610d5dd277c939f5348 GIT binary patch literal 8821 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 TvkL&ALO(uG_Ff|Y`R)G!PrX5O literal 0 HcmV?d00001 From 3df8f173d6711fa5a0fd7dc6cadedf9c869b740f Mon Sep 17 00:00:00 2001 From: wuduoyi Date: Mon, 15 May 2023 12:37:41 +0800 Subject: [PATCH 022/274] =?UTF-8?q?docs:=20registerFilter=20=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=90=8D=E4=B8=8D=E8=A6=81=E5=8A=A0=20-?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/concepts/data-mapping.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/zh-CN/concepts/data-mapping.md b/docs/zh-CN/concepts/data-mapping.md index 8a8808fa8..e53f5f5e7 100755 --- a/docs/zh-CN/concepts/data-mapping.md +++ b/docs/zh-CN/concepts/data-mapping.md @@ -1833,6 +1833,8 @@ ${xxx|filter1|filter2|...} amis npm 包里面暴露了 `registerFilter` 方法,通过它可以添加自己的过滤器逻辑。 +> 注意方法名不要出现 - 号,比如 a-b,要改成 a_b + 如: ```ts @@ -1850,12 +1852,12 @@ registerFilter('count', (input: string) => ```ts import {registerFilter} from 'amis'; -registerFilter('my-replace', (input: string, search: string, repalceWith) => +registerFilter('my_replace', (input: string, search: string, repalceWith) => typeof input === 'string' ? input.replace(search, repalceWith) : input ); ``` -用法为 `${xxxx|my-replace:aaaa:bbbb}` +用法为 `${xxxx|my_replace:aaaa:bbbb}` ### 在 JS SDK 中自定义过滤器 From 57ea031dce3c5d7d93631a3126aed9741d154492 Mon Sep 17 00:00:00 2001 From: wuduoyi Date: Mon, 15 May 2023 13:14:45 +0800 Subject: [PATCH 023/274] =?UTF-8?q?docs:=20=E5=A2=9E=E5=8A=A0=20crud=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=20query=20=E5=8F=82=E6=95=B0=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=20Closes=20#6219?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/crud.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/zh-CN/components/crud.md b/docs/zh-CN/components/crud.md index 6e55bc0ce..8a641900c 100755 --- a/docs/zh-CN/components/crud.md +++ b/docs/zh-CN/components/crud.md @@ -182,14 +182,24 @@ CRUD 组件对数据源接口的数据结构要求如下: 数据源接口地址可以通过变量实现动态拼接,例如: `/api/mock2/sample/${id}`,但需要注意的是接口地址拼接变量后,amis 就不会自动追加默认参数了,例如:分页参数、查询参数等,如需追加,可以自行拼接,例如: `/api/mock2/sample/${id}?page=${page}&perPage=${perPage}` -### 分页参数 - 默认的分页参数是 `page` 和 `perPage`,page 代表页数,比如第一页,perPage 代表每页显示几行。 如果要其它格式,比如转成 `limit` 和 `offset`,可以使用公式来转换,比如 `/api/mock2/sample?limit=${perPage}&offset=${(page - 1) * perPage}` +### 参数汇总 + +这里汇总一下 CRUD 里默认用到的 query 列表 + +| query 名 | 类型 | 说明 | +| -------- | ------------ | ------------------------------ | +| page | number | 分页,从 1 开始 | +| perPage | number | 每页数量 | +| orderBy | string | 排序字段,目前 CRUD 只支持一个 | +| orderDir | 'asc'/'desc' | 排序方式 | +| keywords | string | 搜索关键字 | + ## 功能 既然这个渲染器叫增删改查,那接下来分开介绍这几个功能吧。 From 0e0ae4841dbcd487b19cf3b801e3cff0e099cf0c Mon Sep 17 00:00:00 2001 From: 2betop <2betop.cn@gmail.com> Date: Mon, 15 May 2023 14:42:56 +0800 Subject: [PATCH 024/274] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20treeSelect?= =?UTF-8?q?=20=E9=80=89=E9=A1=B9=E5=9B=9E=E6=98=BE=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20Close:=20#6873?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis/src/renderers/Form/TreeSelect.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/amis/src/renderers/Form/TreeSelect.tsx b/packages/amis/src/renderers/Form/TreeSelect.tsx index 95cf14fbb..3e5580824 100644 --- a/packages/amis/src/renderers/Form/TreeSelect.tsx +++ b/packages/amis/src/renderers/Form/TreeSelect.tsx @@ -430,8 +430,7 @@ export default class TreeSelectControl extends React.Component< !find(combinedOptions, (item: Option) => item.value == option.value) ) { combinedOptions.push({ - ...option, - visible: false + ...option }); } }); From acf4070de01b7cb86002fb26d726fc7f46e696b7 Mon Sep 17 00:00:00 2001 From: liaoxuezhi <2betop.cn@gmail.com> Date: Mon, 15 May 2023 15:26:05 +0800 Subject: [PATCH 025/274] chore: expose getIconNames Close: #6831 (#6870) --- packages/amis-ui/src/components/icons.tsx | 4 ++++ packages/amis-ui/src/components/index.tsx | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/amis-ui/src/components/icons.tsx b/packages/amis-ui/src/components/icons.tsx index 78e2f9a43..3f5d93c1d 100644 --- a/packages/amis-ui/src/components/icons.tsx +++ b/packages/amis-ui/src/components/icons.tsx @@ -118,6 +118,10 @@ const iconFactory: { [propName: string]: React.ElementType<{}>; } = {}; +export function getIconNames() { + return Object.keys(iconFactory); +} + export function getIcon(key: string) { return iconFactory[key]; } diff --git a/packages/amis-ui/src/components/index.tsx b/packages/amis-ui/src/components/index.tsx index b3d3fffb3..83dd8ad13 100644 --- a/packages/amis-ui/src/components/index.tsx +++ b/packages/amis-ui/src/components/index.tsx @@ -76,7 +76,7 @@ import PickerContainer from './PickerContainer'; import InputJSONSchema from './json-schema'; import {Badge, withBadge} from './Badge'; import type {BadgeObject} from './Badge'; -import {getIcon, Icon, registerIcon} from './icons'; +import {getIcon, getIconNames, Icon, registerIcon} from './icons'; import {withRemoteConfig} from './WithRemoteConfig'; import type {RemoteOptionsProps} from './WithRemoteConfig'; import ConditionBuilder from './condition-builder'; @@ -224,6 +224,7 @@ export { UserSelect, UserTabSelect, getIcon, + getIconNames, registerIcon, Badge, HeadCellDropDown, From ca17320ad9b772541ee013c5459012a0e50f44b0 Mon Sep 17 00:00:00 2001 From: liaoxuezhi <2betop.cn@gmail.com> Date: Mon, 15 May 2023 15:26:38 +0800 Subject: [PATCH 026/274] =?UTF-8?q?chore:=20GridNav=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20contentClassName=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A1=B9=E5=86=85=E5=AE=B9=20className=20clo?= =?UTF-8?q?se:=20#6865=20(#6868)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/grid-nav.md | 5 +---- index.html | 11 ++++++++++- packages/amis-ui/src/components/GridNav.tsx | 8 ++++---- packages/amis/src/renderers/GridNav.tsx | 21 +++++++++++++++++---- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/docs/zh-CN/components/grid-nav.md b/docs/zh-CN/components/grid-nav.md index 2e764bebd..7c05a6062 100644 --- a/docs/zh-CN/components/grid-nav.md +++ b/docs/zh-CN/components/grid-nav.md @@ -351,6 +351,7 @@ order: 54 | type | `string` | `grid-nav` | | | className | `string` | | 外层 CSS 类名 | | itemClassName | `string` | | 列表项 css 类名 | +| contentClassName | `string` | | 列表项内容 css 类名 | | value | `Array` | | 图片数组 | | source | `string` | | 数据源 | | square | `boolean` | | 是否将列表项固定为正方形 | @@ -367,7 +368,3 @@ order: 54 | options.link | `string` | | 内部页面路径或外部跳转 URL 地址,优先级高于 clickAction | | options.blank | `boolean` | | 是否新页面打开,link 为 url 时有效 | | options.clickAction | `ActionSchema` | | 列表项点击交互 详见 [Action](./action) | - -``` - -``` diff --git a/index.html b/index.html index 599515299..7aaa7a912 100644 --- a/index.html +++ b/index.html @@ -56,8 +56,17 @@ ); document.head.appendChild(link); }); + + // helper 放在末尾提高优先级 + const helper = document.createElement('link'); + helper.setAttribute('rel', 'stylesheet'); + helper.setAttribute( + 'href', + new URL(`./packages/amis-ui/scss/helper.scss`, import.meta.url).href + ); + document.head.appendChild(helper); - + diff --git a/packages/amis-ui/src/components/GridNav.tsx b/packages/amis-ui/src/components/GridNav.tsx index efdd65528..30ae15015 100644 --- a/packages/amis-ui/src/components/GridNav.tsx +++ b/packages/amis-ui/src/components/GridNav.tsx @@ -4,7 +4,7 @@ */ import React, {useMemo} from 'react'; -import {ClassNamesFn} from 'amis-core'; +import {ClassName, ClassNamesFn} from 'amis-core'; import {Badge, BadgeProps} from './Badge'; export type GridNavDirection = 'horizontal' | 'vertical'; @@ -27,7 +27,7 @@ export interface GridNavProps { /** 列数 */ columnNum?: number; className?: string; - itemClassName?: string; + itemClassName?: ClassName; classnames: ClassNamesFn; style?: React.CSSProperties; children?: React.ReactNode | Array; @@ -40,9 +40,9 @@ export interface GridNavItemProps { text?: string | React.ReactNode; /** 图标名称或图片链接 */ icon?: string | React.ReactNode; - className?: string; + className?: ClassName; style?: React.CSSProperties; - contentClassName?: string; + contentClassName?: ClassName; contentStyle?: React.CSSProperties; children?: React.ReactNode; classnames: ClassNamesFn; diff --git a/packages/amis/src/renderers/GridNav.tsx b/packages/amis/src/renderers/GridNav.tsx index ec2fa88f5..17b569fe6 100644 --- a/packages/amis/src/renderers/GridNav.tsx +++ b/packages/amis/src/renderers/GridNav.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {Renderer, RendererProps} from 'amis-core'; +import {ClassName, Renderer, RendererProps} from 'amis-core'; import {autobind, getPropValue} from 'amis-core'; import {isPureVariable, resolveVariableAndFilter} from 'amis-core'; import { @@ -64,7 +64,12 @@ export interface ListSchema extends BaseSchema { /** * 列表项类名 */ - itemClassName?: string; + itemClassName?: ClassName; + + /** + * 列表项内容类名 + */ + contentClassName?: ClassName; /** * 静态图片列表配置 @@ -154,8 +159,15 @@ export default class List extends React.Component { } render() { - const {itemClassName, style, source, data, options, classnames} = - this.props; + const { + itemClassName, + style, + contentClassName, + source, + data, + options, + classnames + } = this.props; let value = getPropValue(this.props); let list: any = []; @@ -185,6 +197,7 @@ export default class List extends React.Component { item.clickAction || item.link ? this.handleClick(item) : undefined } className={itemClassName} + contentClassName={contentClassName} text={item.text} icon={item.icon} classnames={classnames} From 14eb876139ffdf71075bddd305c7ba0a5e795971 Mon Sep 17 00:00:00 2001 From: Song Mingxu Date: Mon, 15 May 2023 15:26:59 +0800 Subject: [PATCH 027/274] =?UTF-8?q?=E4=B8=BAicon=E5=A2=9E=E5=8A=A0data=20u?= =?UTF-8?q?rl=E6=94=AF=E6=8C=81=EF=BC=8C=E5=90=8C=E6=97=B6=E5=B0=86?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=9B=BE=E6=A0=87=E7=9A=84className=E7=94=9F?= =?UTF-8?q?=E6=95=88=EF=BC=8C=E6=96=B9=E4=BE=BF=E4=BD=BF=E7=94=A8helper?= =?UTF-8?q?=E7=B1=BB=20(#6878)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Song Mingxu --- packages/amis/src/renderers/Icon.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/amis/src/renderers/Icon.tsx b/packages/amis/src/renderers/Icon.tsx index 6386f814f..2b7466e21 100644 --- a/packages/amis/src/renderers/Icon.tsx +++ b/packages/amis/src/renderers/Icon.tsx @@ -141,7 +141,8 @@ export class Icon extends React.Component { ); } - const isURLIcon = icon?.indexOf('.') !== -1; + const isURLIcon = + icon?.indexOf('.') !== -1 || icon.startsWith('data:image/'); let iconPrefix = ''; if (vendor === 'iconfont') { iconPrefix = `iconfont icon-${icon}`; @@ -154,7 +155,7 @@ export class Icon extends React.Component { } return isURLIcon ? ( Date: Mon, 15 May 2023 15:35:10 +0800 Subject: [PATCH 028/274] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E9=80=89=E9=A1=B9=E5=8F=AF=E8=83=BD=E6=8A=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=8F=AA=E8=AF=BB=E5=B1=9E=E6=80=A7=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-ui/src/components/Tree.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/amis-ui/src/components/Tree.tsx b/packages/amis-ui/src/components/Tree.tsx index 3dfae5bf2..6a12550e4 100644 --- a/packages/amis-ui/src/components/Tree.tsx +++ b/packages/amis-ui/src/components/Tree.tsx @@ -449,7 +449,7 @@ export class TreeSelector extends React.Component< return; } - if (onlyLeaf && (Array.isArray(node.children) && node.children.length)) { + if (onlyLeaf && Array.isArray(node.children) && node.children.length) { return; } @@ -878,8 +878,10 @@ export class TreeSelector extends React.Component< } else if (this.isUnfolded(parent)) { this.relations.set(item, parent); // 父节点是展开的状态 - item.level = level; - flattenedOptions.push(item); + flattenedOptions.push({ + ...item, + level + }); } } ); @@ -1096,7 +1098,7 @@ export class TreeSelector extends React.Component< const iconValue = item[iconField] || (enableDefaultIcon !== false - ? (Array.isArray(item.children) && item.children.length) + ? Array.isArray(item.children) && item.children.length ? 'folder' : 'file' : false); @@ -1159,7 +1161,9 @@ export class TreeSelector extends React.Component< From cc5850d17f722d27fc1f3fcfa893f0385f86aadc Mon Sep 17 00:00:00 2001 From: heqiang Date: Mon, 15 May 2023 15:41:04 +0800 Subject: [PATCH 029/274] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=AF=BC=E5=85=A5=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-ui/src/components/AssociatedSelection.tsx | 3 +-- packages/amis-ui/src/components/UserSelect.tsx | 2 +- packages/amis-ui/src/components/UserTabSelect.tsx | 2 +- packages/amis-ui/src/components/index.tsx | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/amis-ui/src/components/AssociatedSelection.tsx b/packages/amis-ui/src/components/AssociatedSelection.tsx index 181d3bb1f..f43c7aacc 100644 --- a/packages/amis-ui/src/components/AssociatedSelection.tsx +++ b/packages/amis-ui/src/components/AssociatedSelection.tsx @@ -12,7 +12,6 @@ import {themeable} from 'amis-core'; import {uncontrollable} from 'amis-core'; import GroupedSelection from './GroupedSelection'; import TableSelection from './TableSelection'; -import GroupedSelecton from './GroupedSelection'; import ChainedSelection from './ChainedSelection'; import {Icon} from './icons'; import {localeable} from 'amis-core'; @@ -154,7 +153,7 @@ export class AssociatedSelection extends BaseSelection< loadingConfig={loadingConfig} /> ) : ( - Date: Mon, 15 May 2023 17:30:11 +0800 Subject: [PATCH 030/274] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E9=80=89=E9=A1=B9=E5=8F=AF=E8=83=BD=E6=8A=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=8F=AA=E8=AF=BB=E5=B1=9E=E6=80=A7=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-ui/src/components/Tree.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/amis-ui/src/components/Tree.tsx b/packages/amis-ui/src/components/Tree.tsx index 6a12550e4..d4546a799 100644 --- a/packages/amis-ui/src/components/Tree.tsx +++ b/packages/amis-ui/src/components/Tree.tsx @@ -210,6 +210,7 @@ export class TreeSelector extends React.Component< unfolded: WeakMap = new WeakMap(); // key: child option, value: parent option; relations: WeakMap = new WeakMap(); + levels: WeakMap = new WeakMap(); dragNode: Option | null; dropInfo: IDropInfo | null; @@ -287,6 +288,11 @@ export class TreeSelector extends React.Component< } } + componentWillUnmount(): void { + // clear data + this.relations = this.unfolded = this.levels = new WeakMap() as any; + } + /** * 展开懒加载节点的父节点 */ @@ -877,11 +883,9 @@ export class TreeSelector extends React.Component< flattenedOptions.push(item); } else if (this.isUnfolded(parent)) { this.relations.set(item, parent); + this.levels.set(item, level); // 父节点是展开的状态 - flattenedOptions.push({ - ...item, - level - }); + flattenedOptions.push(item); } } ); @@ -1102,7 +1106,7 @@ export class TreeSelector extends React.Component< ? 'folder' : 'file' : false); - const level = item.level ? item.level - 1 : 0; + const level = this.levels.has(item) ? this.levels.get(item)! - 1 : 0; let body = null; From 696ba2543b0aa9d75e5194c31202051bd2df7432 Mon Sep 17 00:00:00 2001 From: 2betop <2betop.cn@gmail.com> Date: Mon, 15 May 2023 17:54:58 +0800 Subject: [PATCH 031/274] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E5=8D=87=E7=BA=A7=20?= =?UTF-8?q?lerna?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e2d6ab262..0ae96a4f7 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "jest": "^29.0.3", "jest-environment-jsdom": "^29.0.3", "js-yaml": "^4.1.0", - "lerna": "^5.5.2", + "lerna": "^6.6.2", "magic-string": "^0.26.7", "marked": "^4.2.1", "monaco-editor": "0.30.1", From 77d4a0ebca7be3a1b16ae6fac8ca5b035eae3a87 Mon Sep 17 00:00:00 2001 From: lvxiaojiao Date: Mon, 15 May 2023 19:43:18 +0800 Subject: [PATCH 032/274] =?UTF-8?q?fix:=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=A4=9A=E4=BD=99=E4=B8=8A=E4=B8=8B=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-editor/src/plugin/CRUD.tsx | 19 ++++++++----------- packages/amis-editor/src/plugin/Form/Form.tsx | 2 +- packages/amis-editor/src/plugin/Page.tsx | 2 +- packages/amis-editor/src/plugin/Service.tsx | 2 +- packages/amis-editor/src/plugin/Wizard.tsx | 2 +- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/packages/amis-editor/src/plugin/CRUD.tsx b/packages/amis-editor/src/plugin/CRUD.tsx index c906f468d..c96c47477 100644 --- a/packages/amis-editor/src/plugin/CRUD.tsx +++ b/packages/amis-editor/src/plugin/CRUD.tsx @@ -1847,18 +1847,15 @@ export class CRUDPlugin extends BasePlugin { const jsonschema: any = { $id: 'crudFetchInitedData', type: 'object', - ...jsonToJsonSchema( - omit(data, 'selectedItems', 'unSelectedItems'), - (type: string, key: string) => { - if (type === 'array' && key === 'items') { - return '数据列表'; - } - if (type === 'number' && key === 'count') { - return '总行数'; - } - return key; + ...jsonToJsonSchema(data.responseData, (type: string, key: string) => { + if (type === 'array' && key === 'items') { + return '数据列表'; } - ) + if (type === 'number' && key === 'count') { + return '总行数'; + } + return key; + }) }; scope?.removeSchema(jsonschema.$id); diff --git a/packages/amis-editor/src/plugin/Form/Form.tsx b/packages/amis-editor/src/plugin/Form/Form.tsx index 995fd06d5..23daa4212 100644 --- a/packages/amis-editor/src/plugin/Form/Form.tsx +++ b/packages/amis-editor/src/plugin/Form/Form.tsx @@ -942,7 +942,7 @@ export class FormPlugin extends BasePlugin { const scope = this.manager.dataSchema.getScope(`${node.id}-${node.type}`); const jsonschema: any = { $id: 'formInitedData', - ...jsonToJsonSchema(data) + ...jsonToJsonSchema(data.responseData) }; scope?.removeSchema(jsonschema.$id); diff --git a/packages/amis-editor/src/plugin/Page.tsx b/packages/amis-editor/src/plugin/Page.tsx index af2b29d07..850416692 100644 --- a/packages/amis-editor/src/plugin/Page.tsx +++ b/packages/amis-editor/src/plugin/Page.tsx @@ -370,7 +370,7 @@ export class PagePlugin extends BasePlugin { const scope = this.manager.dataSchema.getScope(`${node.id}-${node.type}`); const jsonschema: any = { $id: 'pageInitedData', - ...jsonToJsonSchema(data) + ...jsonToJsonSchema(data.responseData) }; scope?.removeSchema(jsonschema.$id); diff --git a/packages/amis-editor/src/plugin/Service.tsx b/packages/amis-editor/src/plugin/Service.tsx index 430399dc2..dfe5c3286 100644 --- a/packages/amis-editor/src/plugin/Service.tsx +++ b/packages/amis-editor/src/plugin/Service.tsx @@ -282,7 +282,7 @@ export class ServicePlugin extends BasePlugin { const scope = this.manager.dataSchema.getScope(`${node.id}-${node.type}`); const jsonschema: any = { $id: 'serviceFetchInitedData', - ...jsonToJsonSchema(data) + ...jsonToJsonSchema(data.responseData) }; scope?.removeSchema(jsonschema.$id); diff --git a/packages/amis-editor/src/plugin/Wizard.tsx b/packages/amis-editor/src/plugin/Wizard.tsx index ca4921731..6a3499420 100644 --- a/packages/amis-editor/src/plugin/Wizard.tsx +++ b/packages/amis-editor/src/plugin/Wizard.tsx @@ -953,7 +953,7 @@ export class WizardPlugin extends BasePlugin { const scope = this.manager.dataSchema.getScope(`${node.id}-${node.type}`); const jsonschema: any = { $id: 'wizardInitedData', - ...jsonToJsonSchema(data) + ...jsonToJsonSchema(data.responseData) }; scope?.removeSchema(jsonschema.$id); From fb63b27eaca3495aed5621272697c130d56971cf Mon Sep 17 00:00:00 2001 From: liaoxuezhi <2betop.cn@gmail.com> Date: Mon, 15 May 2023 22:10:11 +0800 Subject: [PATCH 033/274] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20inputTable?= =?UTF-8?q?=20ui=20=E7=BB=84=E4=BB=B6=E5=88=A0=E9=99=A4=E4=B8=AD=E9=97=B4?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=90=8E=E4=BF=AE=E6=94=B9=E5=90=8E=E9=9D=A2?= =?UTF-8?q?=E7=9A=84=E8=A1=8C=E5=AF=BC=E8=87=B4=E6=95=B0=E6=8D=AE=E6=B7=B7?= =?UTF-8?q?=E4=B9=B1=E7=9A=84=E9=97=AE=E9=A2=98=20(#6892)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-ui/src/components/Combo.tsx | 8 ++++- .../amis-ui/src/components/InputTable.tsx | 36 +++++++++++-------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/amis-ui/src/components/Combo.tsx b/packages/amis-ui/src/components/Combo.tsx index 1500271b8..e1724c18e 100644 --- a/packages/amis-ui/src/components/Combo.tsx +++ b/packages/amis-ui/src/components/Combo.tsx @@ -326,7 +326,13 @@ export function ComboItem({ classnames: cx, formRef }: ComboItemProps) { - const methods = useSubForm(value, translate, data => update(index, data)); + const indexRef = React.useRef(index); + React.useEffect(() => { + indexRef.current = index; + }, [index]); + const methods = useSubForm(value, translate, (data: any) => + update(indexRef.current!, data) + ); React.useEffect(() => { formRef?.(methods, index); return () => { diff --git a/packages/amis-ui/src/components/InputTable.tsx b/packages/amis-ui/src/components/InputTable.tsx index fee519240..49e8eac7e 100644 --- a/packages/amis-ui/src/components/InputTable.tsx +++ b/packages/amis-ui/src/components/InputTable.tsx @@ -77,11 +77,11 @@ export function InputTable({ }: InputTabbleProps) { const subForms = React.useRef>({}); const subFormRef = React.useCallback( - (subform: UseFormReturn | null, index: number) => { + (subform: UseFormReturn | null, id: string) => { if (subform) { - subForms.current[index] = subform; + subForms.current[id] = subform; } else { - delete subForms.current[index]; + delete subForms.current[id]; } }, [subForms] @@ -143,17 +143,18 @@ export function InputTable({ control }); - const {trigger} = useFormContext(); + const {trigger, setValue} = useFormContext(); // useFieldArray 的 update 会更新行 id,导致重新渲染 // 正在编辑中的元素失去焦点,所以自己写一个 const lightUpdate = React.useCallback( (index: number, value: any) => { - const arr = control._getFieldArray(name); - arr[index] = {...value}; - control._updateFieldArray(name, arr); - trigger(name); - control._subjects.watch.next({}); + // const arr = control._getFieldArray(name); + // arr[index] = {...value}; + // control._updateFieldArray(name, arr); + // trigger(name); + // control._subjects.watch.next({}); + setValue(`${name}.${index}`, value); }, [control] ); @@ -263,7 +264,7 @@ export interface InputTableRowProps { index: number; translate: TranslateFn; classnames: ClassNamesFn; - formRef: (form: UseFormReturn | null, index: number) => void; + formRef: (form: UseFormReturn | null, id: string) => void; } export function InputTableRow({ @@ -275,13 +276,20 @@ export function InputTableRow({ formRef, classnames: cx }: InputTableRowProps) { - const methods = useSubForm(value, translate, data => update(index, data)); + const indexRef = React.useRef(index); React.useEffect(() => { - formRef?.(methods, index); + indexRef.current = index; + }, [index]); + + const methods = useSubForm(value, translate, (data: any) => + update(indexRef.current!, data) + ); + React.useEffect(() => { + formRef?.(methods, value.id); return () => { - formRef?.(null, index); + formRef?.(null, value.id); }; - }, [methods]); + }, [methods, value.id]); return ( <> From b93673adb386b4e4cdf7d49af3babbd4de6237ff Mon Sep 17 00:00:00 2001 From: liaoxuezhi <2betop.cn@gmail.com> Date: Mon, 15 May 2023 22:10:40 +0800 Subject: [PATCH 034/274] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20mapping=20?= =?UTF-8?q?=E5=85=B3=E8=81=94=E6=8E=A5=E5=8F=A3=E6=A8=A1=E5=BC=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=88=86=E9=A1=B5=E6=97=B6=E5=AD=97=E5=85=B8=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E4=B8=A2=E5=A4=B1=E7=9A=84=E9=97=AE=E9=A2=98=20(#6893?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis/src/renderers/Mapping.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/amis/src/renderers/Mapping.tsx b/packages/amis/src/renderers/Mapping.tsx index ba544a9b5..f213af91f 100644 --- a/packages/amis/src/renderers/Mapping.tsx +++ b/packages/amis/src/renderers/Mapping.tsx @@ -171,7 +171,11 @@ export const MappingField = withStore(props => componentDidUpdate(prevProps: MappingProps) { const props = this.props; const {store, source, data} = this.props; - store.syncProps(props, prevProps, ['valueField', 'map']); + store.syncProps( + props, + prevProps, + source ? ['valueField'] : ['valueField', 'map'] + ); if (isPureVariable(source)) { const prev = resolveVariableAndFilter( From be640ac18adb7e739559b6d3b94915185992799a Mon Sep 17 00:00:00 2001 From: 2betop <2betop.cn@gmail.com> Date: Tue, 16 May 2023 10:09:31 +0800 Subject: [PATCH 035/274] =?UTF-8?q?=E7=B2=BE=E5=BA=A6=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=AE=BE=E7=BD=AE,=E5=85=88=E8=BF=98?= =?UTF-8?q?=E5=8E=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis/src/renderers/Form/InputNumber.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/amis/src/renderers/Form/InputNumber.tsx b/packages/amis/src/renderers/Form/InputNumber.tsx index 0fc033c52..c4cdef6df 100644 --- a/packages/amis/src/renderers/Form/InputNumber.tsx +++ b/packages/amis/src/renderers/Form/InputNumber.tsx @@ -162,7 +162,6 @@ export default class NumberControl extends React.Component< input?: HTMLInputElement; static defaultProps: Partial = { step: 1, - precision: 2, resetValue: '', clearValueOnEmpty: false }; From fe472304fd341c5036d7b1484bfba735b2f30b6f Mon Sep 17 00:00:00 2001 From: ranqirong <274544338@qq.com> Date: Tue, 16 May 2023 11:41:21 +0800 Subject: [PATCH 036/274] =?UTF-8?q?feat:=20select=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E6=90=9C=E7=B4=A2=E6=94=AF=E6=8C=81=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E8=BF=87=E6=BB=A4=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-ui/src/components/Select.tsx | 42 +++++++++++++++++---- packages/amis/src/renderers/Form/Select.tsx | 18 ++++++++- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/packages/amis-ui/src/components/Select.tsx b/packages/amis-ui/src/components/Select.tsx index b51faa430..4a016baa6 100644 --- a/packages/amis-ui/src/components/Select.tsx +++ b/packages/amis-ui/src/components/Select.tsx @@ -16,7 +16,6 @@ import {PopOver} from 'amis-core'; import TooltipWrapper from './TooltipWrapper'; import Downshift, {ControllerStateAndHelpers} from 'downshift'; import {closeIcon, Icon} from './icons'; -// @ts-ignore import {matchSorter} from 'match-sorter'; import { noop, @@ -47,6 +46,15 @@ import type {TooltipObject} from '../components/TooltipWrapper'; export {Option, Options}; +export const defaultFilterOption = ( + options: Option[], + inputValue: string, + option: {keys: string[]}, + matchFn = matchSorter +): Option[] => matchFn(options, inputValue, option); + +export type FilterOption = typeof defaultFilterOption; + export interface OptionProps { className?: string; multi?: boolean; @@ -375,6 +383,11 @@ interface SelectProps * 收纳标签的Popover配置 */ overflowTagPopover?: TooltipObject; + + /** + * 检索函数 + */ + filterOption?: FilterOption; } interface SelectState { @@ -573,15 +586,22 @@ export class Select extends React.Component { simpleValue, checkAllBySearch, labelField, - valueField + valueField, + filterOption = defaultFilterOption } = this.props; + const inputValue = this.state.inputValue; let {selection} = this.state; let filtedOptions: Array