fix: 修复 mapping 结合其他组件兜底显示时取值错误 Close: #9613

This commit is contained in:
2betop 2024-02-19 14:36:31 +08:00
parent 85995ded15
commit 2f92d68d79
2 changed files with 259 additions and 162 deletions

View File

@ -1,137 +1,156 @@
import {render} from '@testing-library/react'; import {render} from '@testing-library/react';
import '../../src'; import '../../src';
import {render as amisRender} from '../../src'; import {render as amisRender} from '../../src';
import {makeEnv} from '../helper'; import {makeEnv, wait} from '../helper';
const tag = (label: string) => render( const tag = (label: string) =>
amisRender( render(amisRender({type: 'tag', label}, {}, makeEnv({}))).container;
{type: 'tag', label},
{},
makeEnv({})
)
).container;
test('Renderer:mapping width object map', async () => { test('Renderer:mapping width object map', async () => {
const setup = (value?: any) => render( const setup = (value?: any) =>
amisRender( render(
{ amisRender(
type: 'mapping', {
map: { type: 'mapping',
1: "漂亮", map: {
2: "开心", 1: '漂亮',
3: "惊吓", 2: '开心',
4: "紧张", 3: '惊吓',
'*': '其他', 4: '紧张',
'*': '其他'
},
...(value !== undefined ? {value} : {})
}, },
...(value !== undefined ? {value} : {}) {},
}, makeEnv({})
{}, )
makeEnv({}) ).container;
)
).container;
const noValue = setup().querySelector('.cxd-MappingField .text-muted')! as HTMLElement; const noValue = setup().querySelector(
'.cxd-MappingField .text-muted'
)! as HTMLElement;
expect(noValue.innerHTML).toBe('-'); expect(noValue.innerHTML).toBe('-');
const value1 = setup(1).querySelector('.cxd-MappingField .cxd-TplField span')! as HTMLElement; const value1 = setup(1).querySelector(
'.cxd-MappingField .cxd-TplField span'
)! as HTMLElement;
expect(value1.innerHTML).toBe('漂亮'); expect(value1.innerHTML).toBe('漂亮');
const value5 = setup(5).querySelector('.cxd-MappingField .cxd-TplField span')! as HTMLElement; const value5 = setup(5).querySelector(
'.cxd-MappingField .cxd-TplField span'
)! as HTMLElement;
expect(value5.innerHTML).toBe('其他'); expect(value5.innerHTML).toBe('其他');
}); });
test('Renderer:mapping width array map', async () => { test('Renderer:mapping width array map', async () => {
const setup = (value?: any) => render( const setup = (value?: any) =>
amisRender( render(
{ amisRender(
type: 'mapping', {
map: [ type: 'mapping',
{1: "漂亮"}, map: [
{2: "开心"}, {1: '漂亮'},
{3: "惊吓"}, {2: '开心'},
{4: "紧张"}, {3: '惊吓'},
{'*': '其他'} {4: '紧张'},
], {'*': '其他'}
...(value !== undefined ? {value} : {}) ],
}, ...(value !== undefined ? {value} : {})
{}, },
makeEnv({}) {},
) makeEnv({})
).container; )
).container;
const noValue = setup().querySelector('.cxd-MappingField .text-muted')! as HTMLElement; const noValue = setup().querySelector(
'.cxd-MappingField .text-muted'
)! as HTMLElement;
expect(noValue.innerHTML).toBe('-'); expect(noValue.innerHTML).toBe('-');
const value1 = setup(1).querySelector('.cxd-MappingField .cxd-TplField span')! as HTMLElement; const value1 = setup(1).querySelector(
'.cxd-MappingField .cxd-TplField span'
)! as HTMLElement;
expect(value1.innerHTML).toBe('漂亮'); expect(value1.innerHTML).toBe('漂亮');
const value5 = setup(5).querySelector('.cxd-MappingField .cxd-TplField span')! as HTMLElement; const value5 = setup(5).querySelector(
'.cxd-MappingField .cxd-TplField span'
)! as HTMLElement;
expect(value5.innerHTML).toBe('其他'); expect(value5.innerHTML).toBe('其他');
}); });
test('Renderer:mapping attr: valueField and labelField', async () => { test('Renderer:mapping attr: valueField and labelField', async () => {
const setup = (value?: any) => render( const setup = (value?: any) =>
amisRender( render(
{ amisRender(
type: 'mapping', {
map: [ type: 'mapping',
{ map: [
name: 1, {
text: '漂亮' name: 1,
}, text: '漂亮'
{ },
name: 2, {
text: '开心' name: 2,
}, text: '开心'
{ },
name: '*', {
text: '其他' name: '*',
} text: '其他'
], }
labelField: 'text', ],
valueField: 'name', labelField: 'text',
...(value !== undefined ? {value} : {}) valueField: 'name',
}, ...(value !== undefined ? {value} : {})
{}, },
makeEnv({}) {},
) makeEnv({})
).container; )
).container;
const noValue = setup().querySelector('.cxd-MappingField .text-muted')! as HTMLElement; const noValue = setup().querySelector(
'.cxd-MappingField .text-muted'
)! as HTMLElement;
expect(noValue.innerHTML).toBe('-'); expect(noValue.innerHTML).toBe('-');
const value1 = setup(1).querySelector('.cxd-MappingField .cxd-TplField span')! as HTMLElement; const value1 = setup(1).querySelector(
'.cxd-MappingField .cxd-TplField span'
)! as HTMLElement;
expect(value1.innerHTML).toBe('漂亮'); expect(value1.innerHTML).toBe('漂亮');
const value5 = setup(5).querySelector('.cxd-MappingField .cxd-TplField span')! as HTMLElement; const value5 = setup(5).querySelector(
'.cxd-MappingField .cxd-TplField span'
)! as HTMLElement;
expect(value5.innerHTML).toBe('其他'); expect(value5.innerHTML).toBe('其他');
}); });
test('Renderer:mapping attr: itemSchema when simple map', async () => { test('Renderer:mapping attr: itemSchema when simple map', async () => {
const setup = (value?: any) => render( const setup = (value?: any) =>
amisRender( render(
{ amisRender(
type: 'mapping', {
map: [ type: 'mapping',
{1: "漂亮"}, map: [
{2: "开心"}, {1: '漂亮'},
{3: "惊吓"}, {2: '开心'},
{4: "紧张"}, {3: '惊吓'},
{'*': '其他'} {4: '紧张'},
], {'*': '其他'}
valueField: 'name', ],
...(value !== undefined ? {value} : {}), valueField: 'name',
itemSchema: { ...(value !== undefined ? {value} : {}),
type: 'tag', itemSchema: {
label: '${item}' type: 'tag',
} label: '${item}'
}, }
{}, },
makeEnv({}) {},
) makeEnv({})
).container; )
).container;
const noValue = setup().querySelector('.cxd-MappingField .text-muted')! as HTMLElement; const noValue = setup().querySelector(
'.cxd-MappingField .text-muted'
)! as HTMLElement;
expect(noValue.innerHTML).toBe('-'); expect(noValue.innerHTML).toBe('-');
const value1 = setup(1).querySelector('.cxd-MappingField')! as HTMLElement; const value1 = setup(1).querySelector('.cxd-MappingField')! as HTMLElement;
@ -142,37 +161,40 @@ test('Renderer:mapping attr: itemSchema when simple map', async () => {
}); });
test('Renderer:mapping attr: itemSchema when normal map', async () => { test('Renderer:mapping attr: itemSchema when normal map', async () => {
const setup = (value?: any) => render( const setup = (value?: any) =>
amisRender( render(
{ amisRender(
type: 'mapping', {
map: [ type: 'mapping',
{ map: [
name: 1, {
text: '漂亮' name: 1,
}, text: '漂亮'
{ },
name: 2, {
text: '开心' name: 2,
}, text: '开心'
{ },
name: '*', {
text: '其他' name: '*',
text: '其他'
}
],
valueField: 'name',
...(value !== undefined ? {value} : {}),
itemSchema: {
type: 'tag',
label: '${name} ${text}'
} }
], },
valueField: 'name', {},
...(value !== undefined ? {value} : {}), makeEnv({})
itemSchema: { )
type: 'tag', ).container;
label: '${name} ${text}'
}
},
{},
makeEnv({})
)
).container;
const noValue = setup().querySelector('.cxd-MappingField .text-muted')! as HTMLElement; const noValue = setup().querySelector(
'.cxd-MappingField .text-muted'
)! as HTMLElement;
expect(noValue.innerHTML).toBe('-'); expect(noValue.innerHTML).toBe('-');
const value1 = setup(1).querySelector('.cxd-MappingField')! as HTMLElement; const value1 = setup(1).querySelector('.cxd-MappingField')! as HTMLElement;
@ -204,23 +226,24 @@ test('Renderer:mapping', async () => {
}); });
test('Renderer:mapping html', async () => { test('Renderer:mapping html', async () => {
const setup = (value?: any) => render( const setup = (value?: any) =>
amisRender( render(
{ amisRender(
type: 'mapping', {
map: { type: 'mapping',
1: "<span class='label label-info'>漂亮</span>", map: {
2: "<span class='label label-success'>开心</span>", 1: "<span class='label label-info'>漂亮</span>",
3: "<span class='label label-danger'>惊吓</span>", 2: "<span class='label label-success'>开心</span>",
4: "<span class='label label-warning'>紧张</span>", 3: "<span class='label label-danger'>惊吓</span>",
'*': '其他' 4: "<span class='label label-warning'>紧张</span>",
'*': '其他'
},
...(value !== undefined ? {value} : {})
}, },
...(value !== undefined ? {value} : {}) {},
}, makeEnv({})
{}, )
makeEnv({}) ).container;
)
).container;
expect(setup()).toMatchSnapshot(); expect(setup()).toMatchSnapshot();
expect(setup(1)).toMatchSnapshot(); expect(setup(1)).toMatchSnapshot();
@ -228,25 +251,28 @@ test('Renderer:mapping html', async () => {
}); });
test('Renderer:mapping schema', async () => { test('Renderer:mapping schema', async () => {
const setup = (value?: any) => render( const setup = (value?: any) =>
amisRender( render(
{ amisRender(
type: 'mapping', {
map: { type: 'mapping',
1: {type: 'tag', label: '漂亮'}, map: {
2: {type: 'tag', label: '开心'}, 1: {type: 'tag', label: '漂亮'},
3: {type: 'tag', label: '惊吓'}, 2: {type: 'tag', label: '开心'},
4: {type: 'tag', label: '紧张'}, 3: {type: 'tag', label: '惊吓'},
'*': {type: 'tag', label: '其他'} 4: {type: 'tag', label: '紧张'},
'*': {type: 'tag', label: '其他'}
},
...(value !== undefined ? {value} : {})
}, },
...(value !== undefined ? {value} : {}) {},
}, makeEnv({})
{}, )
makeEnv({}) ).container;
)
).container;
const noValue = setup().querySelector('.cxd-MappingField .text-muted')! as HTMLElement; const noValue = setup().querySelector(
'.cxd-MappingField .text-muted'
)! as HTMLElement;
expect(noValue.innerHTML).toBe('-'); expect(noValue.innerHTML).toBe('-');
const value1 = setup(1).querySelector('.cxd-MappingField')! as HTMLElement; const value1 = setup(1).querySelector('.cxd-MappingField')! as HTMLElement;
@ -255,3 +281,68 @@ test('Renderer:mapping schema', async () => {
const value5 = setup(5).querySelector('.cxd-MappingField')! as HTMLElement; const value5 = setup(5).querySelector('.cxd-MappingField')! as HTMLElement;
expect(value5.innerHTML).toBe(tag('其他').innerHTML); expect(value5.innerHTML).toBe(tag('其他').innerHTML);
}); });
// 对应 issue https://github.com/baidu/amis/issues/9613
test('Renderer:mapping schema status', async () => {
const {container, getByText} = render(
amisRender(
{
type: 'page',
data: {
items: [
{
status: 1,
id: 1
}
]
},
body: [
{
type: 'table',
title: '表格',
columns: [
{
name: 'id',
label: 'ID'
},
{
name: 'status',
label: '状态2',
type: 'mapping',
map: {
'*': {
type: 'status',
map: {
'0': 'schedule',
'1': 'rolling',
'2': 'success',
'3': 'fail',
'4': 'warning'
},
labelMap: {
'2': '任务成功',
'1': '处理中',
'3': '异常终止',
'0': '等待中',
'4': '已过期'
}
}
}
}
]
}
]
},
{},
makeEnv({})
)
);
await wait(200);
expect(
[].slice
.call(container.querySelectorAll('tbody td'))
.map((td: any) => td.textContent)
).toEqual(['1', '处理中']);
});

View File

@ -253,7 +253,7 @@ export const MappingField = withStore(props =>
} }
renderViewValue(value: any) { renderViewValue(value: any) {
const {render, itemSchema, data, labelField} = this.props; const {render, itemSchema, data, labelField, name} = this.props;
if (!itemSchema) { if (!itemSchema) {
let label = value; let label = value;
@ -265,6 +265,12 @@ export const MappingField = withStore(props =>
// object 也没有 type不能作为schema渲染 // object 也没有 type不能作为schema渲染
// 默认取 label 字段 // 默认取 label 字段
label = value['label']; label = value['label'];
} else {
// 不会下发 value 了,所以要把 name 下发一下
label = {
name,
...label
};
} }
} else { } else {
label = value[labelField || 'label']; label = value[labelField || 'label'];