Browse Source

feat(table): support empty filters #1201 (#1329)

Co-authored-by: shijia.me <[email protected]>
走鹃 2 years ago
parent
commit
477748d1d7

+ 11 - 0
cypress/integration/table.spec.js

@@ -117,4 +117,15 @@ describe('table', () => {
         cy.get('.semi-table-tbody .semi-table-row').eq(0).should('contain', 'Semi Design 设计稿0.fig');
         cy.get('.semi-table-tbody .semi-table-row').eq(1).should('contain', 'Semi Pro 设计稿1.fig');
     });
+
+    it('empty filters', () => {
+        cy.visit('http://localhost:6006/iframe.html?id=table--empty-filters&args=&viewMode=story');
+        // filter title with `Semi Pro`
+        cy.get('.semi-input').type('Semi Pro');
+        // expect title contains `Semi Pro`
+        cy.get('.semi-table-body .semi-table-row').eq(0).contains('Semi Pro');
+        cy.get('.semi-table-body .semi-table-row').eq(1).contains('Semi Pro');
+        cy.get('.semi-table-body .semi-table-row').eq(2).contains('Semi Pro');
+        cy.contains('显示第 1 条-第 10 条,共 23 条');
+    });
 });

+ 2 - 4
packages/semi-foundation/table/foundation.ts

@@ -130,8 +130,8 @@ class TableFoundation<RecordType> extends BaseFoundation<TableAdapter<RecordType
      * init filteredValue of filtering column, use defaultFilteredValue or [] when it is undefined
      */
     static initFilteredValue(column: BaseColumnProps<unknown>) {
-        const { defaultFilteredValue, filteredValue, filters } = column;
-        const hasFilter = Array.isArray(filters) && filters.length;
+        const { defaultFilteredValue, filteredValue, onFilter } = column;
+        const hasFilter = isFunction(onFilter);
         if (hasFilter && isUndefined(filteredValue)) {
             if (Array.isArray(defaultFilteredValue) && defaultFilteredValue.length) {
                 column.filteredValue = defaultFilteredValue;
@@ -253,8 +253,6 @@ class TableFoundation<RecordType> extends BaseFoundation<TableAdapter<RecordType
                 const currentFilteredValue = query.filteredValue ? query.filteredValue : query.defaultFilteredValue;
                 return (
                     isFunction(query.onFilter) &&
-                    Array.isArray(query.filters) &&
-                    query.filters.length &&
                     Array.isArray(currentFilteredValue) &&
                     currentFilteredValue.length
                 );

+ 2 - 2
packages/semi-foundation/table/utils.ts

@@ -480,9 +480,9 @@ export interface GetAllDisabledRowKeysProps {
 
 export function warnIfNoDataIndex(column: Record<string, any>) {
     if (typeof column === 'object' && column !== null) {
-        const { filters, sorter, dataIndex } = column;
+        const { filters, sorter, dataIndex, onFilter } = column;
         const logger = new Logger('[@douyinfe/semi-ui Table]');
-        if ((Array.isArray(filters) || isFunction(sorter)) && isNullOrUndefined(dataIndex) ) {
+        if ((Array.isArray(filters) || isFunction(onFilter) || isFunction(sorter)) && isNullOrUndefined(dataIndex) ) {
             logger.warn(`The column with sorter or filter must pass the 'dataIndex' prop`);
         }
     }

+ 1 - 0
packages/semi-ui/table/Table.tsx

@@ -602,6 +602,7 @@ class Table<RecordType extends Record<string, any>> extends BaseComponent<Normal
                 ) {
                     this.foundation.initExpandedRowKeys(handledProps);
                 }
+                states.pagination = handledProps.pagination;
             }
 
             // Centrally update paging related state

+ 85 - 0
packages/semi-ui/table/_story/v2/emptyFilters.tsx

@@ -0,0 +1,85 @@
+import React, { useState, useEffect, useMemo } from 'react';
+import { Table, Avatar, Input } from '../../../index';
+import { ColumnProps, ChangeInfoFilter } from '../../interface';
+
+const DAY = 24 * 60 * 60 * 1000;
+const figmaIconUrl = 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png';
+
+function App() {
+    const [dataSource, setData] = useState([]);
+    const [filteredValue, setFilteredValue] = useState([]);
+
+    const scroll = useMemo(() => ({ y: 300 }), []);
+
+    const columns: ColumnProps[] = [
+        {
+            title: '标题',
+            dataIndex: 'name',
+            width: 400,
+            render: (text, record, index) => {
+                return (
+                    <div>
+                        <Avatar size="small" shape="square" src={figmaIconUrl} style={{ marginRight: 12 }}></Avatar>
+                        {text}
+                    </div>
+                );
+            },
+            onFilter: (value, record) => record.name.includes(value),
+            filteredValue: filteredValue,
+        },
+        {
+            title: '大小',
+            dataIndex: 'size',
+            sorter: (a, b) => a.size - b.size > 0 ? 1 : -1,
+            render: (text) => `${text} KB`
+        },
+        {
+            title: '所有者',
+            dataIndex: 'owner',
+            render: (text, record, index) => {
+                return (
+                    <div>
+                        <Avatar size="small" color={record.avatarBg} style={{ marginRight: 4 }}>{typeof text === 'string' && text.slice(0, 1)}</Avatar>
+                        {text}
+                    </div>
+                );
+            }
+
+        }
+    ];
+
+    const getData = (total) => {
+        const data = [];
+        for (let i = 0; i < total; i++) {
+            const isSemiDesign = i % 2 === 0;
+            const randomNumber = (i * 1000) % 199;
+            data.push({
+                key: '' + i,
+                name: isSemiDesign ? `Semi Design 设计稿${i}.fig` : `Semi Pro 设计稿${i}.fig`,
+                owner: isSemiDesign ? '姜鹏志' : '郝宣',
+                size: randomNumber,
+                avatarBg: isSemiDesign ? 'grey' : 'red'
+            });
+        }
+        return data;
+    };
+
+    const handleFilterChange = (value: string) => {
+        setFilteredValue([value]);
+    };
+
+    useEffect(() => {
+        const data = getData(46);
+        setData(data);
+    }, []);
+
+    return (
+        <div>
+            <Input placeholder="筛选标题" style={{ width: 200 }} value={filteredValue[0]} onChange={handleFilterChange}></Input>
+            <Table columns={columns} dataSource={dataSource} scroll={scroll} onChange={console.log} />
+        </div >
+    );
+}
+
+App.storyName = 'filters 空';
+export default App;

+ 2 - 1
packages/semi-ui/table/_story/v2/index.js

@@ -11,4 +11,5 @@ export { default as FixedVirtualizedEmpty } from './FixedVirtualizedEmpty';
 export { default as FixedFilter } from './FixedFilter';
 export { default as FixedSorter } from './FixedSorter';
 export { default as stickyHeaderTable } from './stickyHeader';
-export { default as Fixed1188 } from './Fixed1188';
+export { default as Fixed1188 } from './Fixed1188';
+export { default as EmptyFilters } from './emptyFilters';