From 6539f491b467bee505658db457d5f90fcf699495 Mon Sep 17 00:00:00 2001 From: 2betop <2698393+2betop@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:20:34 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20CRUD=20=E8=B0=83=E6=95=B4=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E5=A4=96=E5=9B=B4=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-ui/scss/_mixins.scss | 13 +-- packages/amis-ui/scss/_properties.scss | 1 + packages/amis-ui/scss/components/_crud.scss | 5 ++ .../amis-ui/scss/components/form/_picker.scss | 25 +++--- .../amis/__tests__/renderers/Picker.test.tsx | 8 +- .../__snapshots__/Picker.test.tsx.snap | 34 +++----- packages/amis/src/renderers/CRUD.tsx | 81 +++++++++++++------ packages/amis/src/renderers/Form/Picker.tsx | 44 +++++----- 8 files changed, 119 insertions(+), 92 deletions(-) diff --git a/packages/amis-ui/scss/_mixins.scss b/packages/amis-ui/scss/_mixins.scss index f4c902b12d1..8cda387d219 100644 --- a/packages/amis-ui/scss/_mixins.scss +++ b/packages/amis-ui/scss/_mixins.scss @@ -661,7 +661,8 @@ line-height: calc( var(--Form-input-lineHeight) * var(--Form-input-fontSize) - #{px2rem(2px)} ); - display: inline-block; + display: inline-flex; + align-items: center; font-size: var(--Pick-base-value-fontSize); color: var(--Pick-base-value-color); font-weight: var(--Pick-base-value-fontWeight); @@ -682,9 +683,6 @@ var(--Pick-base-top-right-border-radius) var(--Pick-base-bottom-right-border-radius) var(--Pick-base-bottom-left-border-radius); - margin-right: var(--gap-xs); - margin-bottom: var(--gap-xs); - margin-top: var(--gap-xs); max-width: px2rem(150px); overflow: hidden; text-overflow: ellipsis; @@ -696,7 +694,10 @@ &.is-disabled { pointer-events: none; - opacity: var(--Button-onDisabled-opacity); + + .#{$ns}#{$component-prefix}-valueIcon { + opacity: var(--Button-onDisabled-opacity); + } } } @@ -704,7 +705,7 @@ color: var(--Pick-base-value-icon-color); cursor: pointer; border-right: px2rem(1px) solid var(--Form-selectValue-borderColor); - padding: 1px 5px; + padding: 0 5px; &:hover { background: var(--Pick-base-value-hover-icon-color); diff --git a/packages/amis-ui/scss/_properties.scss b/packages/amis-ui/scss/_properties.scss index 668498456d4..51873ee173e 100644 --- a/packages/amis-ui/scss/_properties.scss +++ b/packages/amis-ui/scss/_properties.scss @@ -179,6 +179,7 @@ $Table-strip-bg: transparent; --ButtonGroup-divider-width: #{px2rem(1px)}; --ButtonGroup-divider-color: #fff; --ButtonGroup-borderWidth: var(--borders-width-2); + --Button-onDisabled-opacity: 0.3; --Breadcrumb-item-fontSize: var(--fontSizeMd); --Breadcrumb-item-default-color: var(--colors-neutral-text-5); diff --git a/packages/amis-ui/scss/components/_crud.scss b/packages/amis-ui/scss/components/_crud.scss index fceeddf2f25..d8fb7d24ad4 100644 --- a/packages/amis-ui/scss/components/_crud.scss +++ b/packages/amis-ui/scss/components/_crud.scss @@ -9,6 +9,10 @@ &-selection { margin-bottom: var(--gap-base); + display: flex; + flex-wrap: wrap; + gap: var(--gap-xs); + line-height: 1; &-overflow { &-wrapper { @@ -25,6 +29,7 @@ (var(--Picker-tag-height) + var(--Picker-tag-marginBottom)) * 5 ); + gap: var(--gap-xs); @include tag-item(Crud); } } diff --git a/packages/amis-ui/scss/components/form/_picker.scss b/packages/amis-ui/scss/components/form/_picker.scss index 44f2bc5cfc2..d1ddd720bae 100644 --- a/packages/amis-ui/scss/components/form/_picker.scss +++ b/packages/amis-ui/scss/components/form/_picker.scss @@ -71,7 +71,8 @@ font-size: var(--Pick-base-placeholder-fontSize); font-weight: var(--Pick-base-placeholder-fontWeight); user-select: none; - position: absolute; + flex: 1; + min-width: 0; // margin-top: 2 * var(--Form-input-borderWidth); line-height: var(--Form-input-lineHeight); padding: var(--Pick-base-paddingTop) var(--Pick-base-paddingRight) @@ -95,15 +96,15 @@ var(--Pick-base-left-border-color); } - .#{$ns}Picker-values { - display: inline; + // .#{$ns}Picker-values { + // display: inline; - .#{$ns}OverflowTpl { - .#{$ns}Picker-valueLabel { - pointer-events: auto; - } - } - } + // .#{$ns}OverflowTpl { + // .#{$ns}Picker-valueLabel { + // pointer-events: auto; + // } + // } + // } &-valueWrap { flex-grow: 1; @@ -117,8 +118,9 @@ } .#{$ns}Picker-valueWrap { - margin-bottom: calc(var(--gap-xs) * -1); - line-height: 1; + display: flex; + flex-wrap: wrap; + gap: var(--gap-xs); } /* tag 样式 */ @@ -176,6 +178,7 @@ (var(--Picker-tag-height) + var(--Picker-tag-marginBottom)) * 5 ); + gap: var(--gap-xs); @include tag-item(Picker); } } diff --git a/packages/amis/__tests__/renderers/Picker.test.tsx b/packages/amis/__tests__/renderers/Picker.test.tsx index ff47b73e018..389ad81ecb4 100644 --- a/packages/amis/__tests__/renderers/Picker.test.tsx +++ b/packages/amis/__tests__/renderers/Picker.test.tsx @@ -296,13 +296,15 @@ describe('5. Renderer:Picker with overflowConfig', () => { await wait(500); - const tags = container.querySelector('.cxd-Picker-values'); + const tags = container.querySelector('.cxd-Picker-valueWrap'); expect(tags).toBeInTheDocument(); /** tag 元素数量正确 */ - expect(tags?.childElementCount).toEqual(3); + expect(tags?.childElementCount).toEqual(4); // 还有个 input /** 收纳标签文案正确 */ - expect(tags?.lastElementChild).toHaveTextContent('+ 1 ...'); + expect(tags?.lastElementChild?.previousSibling).toHaveTextContent( + '+ 1 ...' + ); }); test('5-2. Renderer:Picker embeded', async () => { diff --git a/packages/amis/__tests__/renderers/__snapshots__/Picker.test.tsx.snap b/packages/amis/__tests__/renderers/__snapshots__/Picker.test.tsx.snap index 49cf54bec3e..1a7a4ed50a7 100644 --- a/packages/amis/__tests__/renderers/__snapshots__/Picker.test.tsx.snap +++ b/packages/amis/__tests__/renderers/__snapshots__/Picker.test.tsx.snap @@ -38,16 +38,6 @@ exports[`1. Renderer:Picker base 1`] = ` > picker-placeholder -
-
- -
@@ -267,22 +257,18 @@ exports[`1. Renderer:Picker base 2`] = ` class="cxd-Picker-valueWrap" >
-
- - × - - - B - -
+ × + + + B +
= [ 'selected' ]; -export default class CRUD extends React.Component { +export default class CRUD extends React.Component { static propsList: Array = [ 'bulkActions', 'itemActions', @@ -528,7 +537,7 @@ export default class CRUD extends React.Component { omitBy(onEvent, (event, key: any) => !INNER_EVENTS.includes(key)) ); - constructor(props: CRUDProps) { + constructor(props: T) { super(props); this.controlRef = this.controlRef.bind(this); @@ -811,6 +820,11 @@ export default class CRUD extends React.Component { const redirect = action.redirect && filter(action.redirect, data); redirect && action.blank && env.jumpTo(redirect, action, data); + // 如果 api 无效,或者不满足发送条件,则直接返回 + if (!isEffectiveApi(action.api, data)) { + return; + } + return store .saveRemote(action.api!, data, { successMessage: @@ -977,7 +991,7 @@ export default class CRUD extends React.Component { handleFilterInit(values: object) { const {defaultParams, data, store, orderBy, orderDir, dispatchEvent} = this.props; - const params = {...defaultParams}; + const params: any = {...defaultParams}; if (orderBy) { params['orderBy'] = orderBy; @@ -1967,11 +1981,14 @@ export default class CRUD extends React.Component { } clearSelection() { - const {store} = this.props; - const selected = store.selectedItems.concat(); - const unSelected = store.unSelectedItems.concat(selected); + const {store, itemCheckableOn} = this.props; + const [unchecked, checked] = partition( + store.selectedItems, + item => !itemCheckableOn || evalExpression(itemCheckableOn, item) + ); + const unSelected = store.unSelectedItems.concat(unchecked); - store.setSelectedItems([]); + store.setSelectedItems(checked); store.setUnSelectedItems(unSelected); } @@ -2468,12 +2485,12 @@ export default class CRUD extends React.Component { if (toolbar) { if (Array.isArray(headerToolbar)) { headerToolbar = toolbarInline - ? headerToolbar.concat(toolbar) - : [headerToolbar, toolbar]; + ? headerToolbar.concat(toolbar as any) + : ([headerToolbar, toolbar] as any); } else if (headerToolbar) { - headerToolbar = [headerToolbar, toolbar]; + headerToolbar = [headerToolbar, toolbar] as any; } else { - headerToolbar = toolbar; + headerToolbar = toolbar as any; } } @@ -2493,13 +2510,15 @@ export default class CRUD extends React.Component { if (toolbar) { if (Array.isArray(footerToolbar)) { - footerToolbar = toolbarInline - ? footerToolbar.concat(toolbar) - : [footerToolbar, toolbar]; + footerToolbar = ( + toolbarInline + ? footerToolbar.concat(toolbar as any) + : [footerToolbar, toolbar] + ) as any; } else if (footerToolbar) { - footerToolbar = [footerToolbar, toolbar]; + footerToolbar = [footerToolbar, toolbar] as any; } else { - footerToolbar = toolbar; + footerToolbar = toolbar as any; } } @@ -2514,11 +2533,19 @@ export default class CRUD extends React.Component { primaryField, valueField, translate: __, - env + env, + itemCheckableOn } = this.props; + const checkable = itemCheckableOn + ? evalExpression(itemCheckableOn, item) + : true; + return ( -
+
{ } } -@Renderer({ - type: 'crud', - storeType: CRUDStore.name, - isolateScope: true -}) -export class CRUDRenderer extends CRUD { +export class CRUDRendererBase extends CRUD { static contextType = ScopedContext; - constructor(props: CRUDProps, context: IScopedContext) { + constructor(props: T, context: IScopedContext) { super(props); const scoped = context; @@ -2908,3 +2930,10 @@ export class CRUDRenderer extends CRUD { return store.getData(data); } } + +@Renderer({ + type: 'crud', + storeType: CRUDStore.name, + isolateScope: true +}) +export class CRUDRenderer extends CRUDRendererBase {} diff --git a/packages/amis/src/renderers/Form/Picker.tsx b/packages/amis/src/renderers/Form/Picker.tsx index 5bae47343d3..02ed3994a81 100644 --- a/packages/amis/src/renderers/Form/Picker.tsx +++ b/packages/amis/src/renderers/Form/Picker.tsx @@ -157,13 +157,13 @@ export default class PickerControl extends React.PureComponent< placement: 'top', trigger: 'hover', showArrow: false, - offset: [0, -10] + offset: [0, -5] }, overflowTagPopoverInCRUD: { placement: 'bottom', trigger: 'hover', showArrow: false, - offset: [0, 10] + offset: [0, 0] } } }; @@ -641,7 +641,7 @@ export default class PickerControl extends React.PureComponent< } return ( -
+ <> {tags.map((item, index) => { if (enableOverflow && index === maxTagCount) { return ( @@ -697,7 +697,7 @@ export default class PickerControl extends React.PureComponent< return this.renderTag(item, index); })} -
+ ); } @@ -804,24 +804,24 @@ export default class PickerControl extends React.PureComponent<
{__(placeholder)}
- ) : null} - -
- {this.renderValues()} - - -
+ ) : ( +
+ {this.renderValues()} + + +
+ )} {clearable && !disabled && selectedOptions.length ? (