Skip to content

Commit

Permalink
feat(abc:st): add onCell, support colSpan and rowSpan merging
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk committed Jul 19, 2023
1 parent bcd60e6 commit d35d498
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 21 deletions.
73 changes: 73 additions & 0 deletions packages/abc/st/demo/colspan-rowspan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
order: 8
title:
en-US: colSpan and rowSpan
zh-CN: 表格行/列合并
---

## zh-CN

表格支持行/列合并,使用 `onCell` 进行设置,若返回 `colSpan` 或者 `rowSpan` 设值为 0 时,设置的表格不会渲染。

## en-US

The table supports row/column merging, use `onCell` to set, if return `colSpan` or `rowSpan` is set to 0, the set table will not be rendered.

```ts
import { Component } from '@angular/core';

import { STColumn, STData, STOnCellResult } from '@delon/abc/st';

// In the fifth row, other columns are merged into first column
// by setting it's colSpan to be 0
const sharedOnCell = (_: STData, index: number): STOnCellResult => {
if (index === 1) {
return { colSpan: 0 };
}

return {};
};

@Component({
selector: 'app-demo',
template: ` <st #st [data]="url" [ps]="5" [req]="{ params: params }" [columns]="columns" bordered size="middle">
</st>`
})
export class DemoComponent {
url = `/users?total=2&field=list`;
params = { a: 1, b: 2 };

columns: STColumn[] = [
{ title: '编号', index: 'id', sort: true, width: 100 },
{ title: '头像', type: 'img', index: 'picture.thumbnail', width: 60 },
{
title: '邮箱',
index: 'email',
onCell: (_, index) => ({
colSpan: index === 1 ? 5 : 1
})
},
{
title: 'first',
index: 'name.first',
sort: true,
className: 'text-center',
onCell: (_, index) => {
if (index === 3) {
return { rowSpan: 2 };
}
// These two are merged into above cell
if (index === 4) {
return { rowSpan: 0 };
}
if (index === 1) {
return { colSpan: 0 };
}

return {};
}
},
{ title: 'last', index: 'name.last', onCell: sharedOnCell }
];
}
```
3 changes: 2 additions & 1 deletion packages/abc/st/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ class TestComponent {
| `[fixed]` | Set column to be fixed, must specify `width` | `left,right` | - |
| `[format]` | Format value of this column | `(item: STData, col: STColumn, index: number) => string` | - |
| `[className]` | Class name of this column, e.g: `text-center`, `text-right`, `text-error`, pls refer to [Style Tools](/theme/tools) | `string` | - |
| `[colSpan]` | Span of this column's title | `number` | - |
| deprecated `[colSpan]` | Span of this column's title | `number` | - |
| `[onCell]` | Set props on per cell | `(item: T, index: number) => STOnCellResult;` | - |
| `[sort]` | Sort config of this column, Remote Data Configuration**Priority** Rule: <br>`true` allow sorting, should be auto generate compose `compare: (a, b) => a[index] - b[index]` method when data is local<br>`string` corresponding `key` value | `true,string,STColumnSort` | - |
| `[filter]` | Filter config of this column | `STColumnFilter` | - |
| `[selections]` | Config of type is checkbox | `STColumnSelection[]` | - |
Expand Down
3 changes: 2 additions & 1 deletion packages/abc/st/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ class TestComponent {
| `[fixed]` | 固定前后列,当指定时务必指定 `width` 否则视为无效 | `left,right` | - |
| `[format]` | 格式化列值 | `(item: STData, col: STColumn, index: number) => string` | - |
| `[className]` |`class` 属性值,例如:`text-center` 居中; `text-right` 居右; `text-error` 异常色,更多参考[样式工具类](/theme/tools) | `string` | - |
| `[colSpan]` | 合并列 | `number` | - |
| deprecated `[colSpan]` | 合并列 | `number` | - |
| `[onCell]` | 设置单元格属性 | `(item: T, index: number) => STOnCellResult;` | - |
| `[sort]` | 排序配置项,远程数据配置**优先**规则:<br>`true` 表示允许排序,且若数据源为本地数据时会自动生成 `compare: (a, b) => a[index] - b[index]` 方法<br>`string` 表示远程数据排序相对应 `key`| `true,string,STColumnSort` | - |
| `[filter]` | 过滤配置项 | `STColumnFilter` | - |
| `[selections]` | 选择功能配置 | `STColumnSelection[]` | - |
Expand Down
21 changes: 17 additions & 4 deletions packages/abc/st/st-data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
STData,
STMultiSort,
STMultiSortResultType,
STOnCellResult,
STPage,
STReq,
STReqReNameType,
Expand Down Expand Up @@ -204,15 +205,26 @@ export class STDataSource {
}

private get(item: STData, col: _STColumn, idx: number): _STDataValue {
const safeHtml = col.safeType === 'safeHtml';
let onCellResult = typeof col.onCell === 'function' ? col.onCell(item, idx) : null;
if (onCellResult == null && col.colSpan != null) {
onCellResult = { colSpan: col.colSpan };
}
const mergedColSpan = onCellResult?.colSpan ?? 1;
const mergedRowSpan = onCellResult?.rowSpan ?? 1;
const props: STOnCellResult = {
colSpan: mergedColSpan <= 0 ? null : mergedColSpan,
rowSpan: mergedRowSpan <= 0 ? null : mergedRowSpan
};
try {
const safeHtml = col.safeType === 'safeHtml';
if (col.format) {
const formatRes = col.format(item, col, idx) || '';
return {
text: formatRes,
_text: safeHtml ? this.dom.bypassSecurityTrustHtml(formatRes) : formatRes,
org: formatRes,
safeType: col.safeType!
safeType: col.safeType!,
props
};
}

Expand Down Expand Up @@ -261,12 +273,13 @@ export class STDataSource {
org: value,
color,
safeType: col.safeType!,
buttons: []
buttons: [],
props
};
} catch (ex) {
const text = `INVALID DATA`;
console.error(`Failed to get data`, item, col, ex);
return { text, _text: text, org: text, buttons: [], safeType: 'text' };
return { text, _text: text, org: text, buttons: [], safeType: 'text', props };
}
}

Expand Down
32 changes: 19 additions & 13 deletions packages/abc/st/st.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,25 @@
(click)="_stopPropagation($event)"
nzWidth="50px"
></td>
<td
*ngFor="let c of _columns; let cIdx = index"
[nzLeft]="!!c._left"
[nzRight]="!!c._right"
[attr.data-col-index]="cIdx"
[ngClass]="c._className"
[attr.colspan]="c.colSpan"
>
<span *ngIf="responsive" class="ant-table-rep__title">
<ng-template [ngTemplateOutlet]="titleTpl" [ngTemplateOutletContext]="{ $implicit: c.title }"></ng-template>
</span>
<st-td [data]="_data" [i]="i" [index]="index" [c]="c" [cIdx]="cIdx" (n)="_handleTd($event)"></st-td>
</td>
<ng-container *ngFor="let c of _columns; let cIdx = index">
<td
*ngIf="i._values[cIdx].props?.colSpan > 0 && i._values[cIdx].props?.rowSpan > 0"
[nzLeft]="!!c._left"
[nzRight]="!!c._right"
[attr.data-col-index]="cIdx"
[ngClass]="c._className"
[attr.colspan]="i._values[cIdx].props?.colSpan === 1 ? null : i._values[cIdx].props?.colSpan"
[attr.rowspan]="i._values[cIdx].props?.rowSpan === 1 ? null : i._values[cIdx].props?.rowSpan"
>
<span *ngIf="responsive" class="ant-table-rep__title">
<ng-template
[ngTemplateOutlet]="titleTpl"
[ngTemplateOutletContext]="{ $implicit: c.title }"
></ng-template>
</span>
<st-td [data]="_data" [i]="i" [index]="index" [c]="c" [cIdx]="cIdx" (n)="_handleTd($event)"></st-td>
</td>
</ng-container>
</tr>
<tr [nzExpand]="i.expand">
<ng-template
Expand Down
13 changes: 13 additions & 0 deletions packages/abc/st/st.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,16 @@ export interface STColumn<T extends STData = any> {
className?: NgClassType;
/**
* 合并列
*
* @deprecated Will be removed by 17.0.0, Pls use `onCell` instead.
*/
colSpan?: number;
/**
* Table cell supports `colSpan` and `rowSpan`. When each of them is set to 0, the cell will not be rendered.
*
* 表格支持行/列合并,若返回的 `colSpan` 或者 `rowSpan` 设值为 0 时表示不会渲染
*/
onCell?: (item: T, index: number) => STOnCellResult;
/**
* 数字格式,`type=number` 有效
*/
Expand Down Expand Up @@ -1280,3 +1288,8 @@ export interface STCustomRequestOptions {
url: string;
options: STRequestOptions;
}

export interface STOnCellResult {
rowSpan?: number | null;
colSpan?: number | null;
}
3 changes: 2 additions & 1 deletion packages/abc/st/st.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { TemplateRef } from '@angular/core';
import { SafeHtml } from '@angular/platform-browser';

import { STColumn, STColumnButton, STColumnSafeType, STData, STSortMap } from './st.interfaces';
import { STColumn, STColumnButton, STColumnSafeType, STData, STOnCellResult, STSortMap } from './st.interfaces';

/**
* @inner
Expand Down Expand Up @@ -74,4 +74,5 @@ export interface _STDataValue {
color?: string;
safeType: STColumnSafeType;
buttons?: _STColumnButton[];
props?: STOnCellResult | null;
}
48 changes: 47 additions & 1 deletion packages/abc/st/test/st-data-source.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { STDataSource, STDataSourceOptions } from '../st-data-source';
import { ST_DEFAULT_CONFIG } from '../st.config';
import { STColumnButton, STColumnFilterMenu, STData } from '../st.interfaces';
import { _STColumn } from '../st.types';
import { _STColumn, _STDataValue } from '../st.types';

const DEFAULT = {
pi: 1,
Expand Down Expand Up @@ -908,6 +908,52 @@ describe('abc: table: data-souce', () => {
done();
});
});
describe('#onCell', () => {
it('should be working', done => {
const index = 1;
options.data = genData();
options.columns = [
{ index: 'a', onCell: (_, idx) => ({ colSpan: idx === index ? 2 : 1 }) },
{ index: 'b', onCell: (_, idx) => ({ rowSpan: idx === index ? 2 : 1 }) }
] as _STColumn[];
srv.process(options).subscribe(res => {
const values = res.list[index]._values as _STDataValue[];
expect(values[0].props?.colSpan).toBe(2);
expect(values[0].props?.rowSpan).toBe(1);

expect(values[1].props?.colSpan).toBe(1);
expect(values[1].props?.rowSpan).toBe(2);
done();
});
});
it('should be ignore when set 0', done => {
const index = 1;
options.data = genData();
options.columns = [
{ index: 'a', onCell: (_, idx) => ({ colSpan: idx === index ? 0 : 1 }) },
{ index: 'b', onCell: (_, idx) => ({ rowSpan: idx === index ? 0 : 1 }) }
] as _STColumn[];
srv.process(options).subscribe(res => {
const values = res.list[index]._values as _STDataValue[];
expect(values[0].props?.colSpan).toBeNull();
expect(values[0].props?.rowSpan).toBe(1);

expect(values[1].props?.colSpan).toBe(1);
expect(values[1].props?.rowSpan).toBeNull();
done();
});
});
it('@deprecated colSpan', done => {
options.data = genData();
options.columns = [{ index: 'a', colSpan: 2 }] as _STColumn[];
srv.process(options).subscribe(res => {
const values = res.list[0]._values as _STDataValue[];
expect(values[0].props?.colSpan).toBe(2);
expect(values[0].props?.rowSpan).toBe(1);
done();
});
});
});
});

describe('[buttons]', () => {
Expand Down

0 comments on commit d35d498

Please sign in to comment.