From 437e8a4537629dd7a9a544bfff96359cd09c4fe3 Mon Sep 17 00:00:00 2001 From: sam-m-m Date: Thu, 3 Dec 2020 13:36:46 -0800 Subject: [PATCH 1/2] enhance #162 - Table: Auto hide/show pagination based on row count --- src/components/Table/Table.stories.tsx | 44 ++------- src/components/Table/__tests__/Table.test.tsx | 26 ++--- .../Table/fixtures/4_sample_data.ts | 94 +++++-------------- .../Table/fixtures/5_sample_data.ts | 78 +++++++++++++++ src/components/Table/index.tsx | 17 ++-- 5 files changed, 130 insertions(+), 129 deletions(-) create mode 100644 src/components/Table/fixtures/5_sample_data.ts diff --git a/src/components/Table/Table.stories.tsx b/src/components/Table/Table.stories.tsx index 137d6770..384e5844 100644 --- a/src/components/Table/Table.stories.tsx +++ b/src/components/Table/Table.stories.tsx @@ -1,13 +1,13 @@ import { action } from '@storybook/addon-actions' -import cloneDeep from 'lodash/cloneDeep' import { Story } from '@storybook/react/types-6-0' +import tableData4 from './fixtures/4_sample_data' import { DataId, Table, TableProps } from '.' import React, { Key, useState } from 'react' import tableData0, { Person } from './fixtures/0_sample_data' import tableData1, { File } from './fixtures/1_sample_data' import tableData2, { Client } from './fixtures/2_sample_data' import tableData3, { Client1 } from './fixtures/3_sample_data' -import tableData4, { Dot } from './fixtures/4_sample_data' +import tableData5, { Dot } from './fixtures/5_sample_data' const commonArgTypes = { activeRowKey: { @@ -71,9 +71,7 @@ const SimpleTemplate: Story> = args => ( {...args} /> ) export const Simple = SimpleTemplate.bind({}) -Simple.args = { - ...tableData0 -} +Simple.args = tableData0 Simple.argTypes = { ...commonArgTypes, columns: { @@ -110,9 +108,7 @@ const NumberTemplate: Story> = args => ( ) export const Number = NumberTemplate.bind({}) -Number.args = { - ...tableData1 -} +Number.args = tableData1 Number.argTypes = { ...commonArgTypes, columns: { @@ -169,13 +165,12 @@ type NumberType = NumberDefaultType | NumberDate | NumberByteType` } } } + const MixedTemplate: Story> = args => ( {...args} /> ) export const Mixed = MixedTemplate.bind({}) -Mixed.args = { - ...tableData2 -} +Mixed.args = tableData2 Mixed.argTypes = { ...commonArgTypes, columns: { @@ -236,34 +231,11 @@ MissingCells.argTypes = { } export const Paginated = NumberTemplate.bind({}) - -const paginatedData = [ - ...cloneDeep(tableData1.data), - ...cloneDeep(tableData1.data.slice(0, 3)), - ...cloneDeep(tableData1.data), - ...cloneDeep(tableData1.data.slice(1, 4)), - ...cloneDeep(tableData1.data), - ...cloneDeep(tableData1.data.slice(0, 2)), - ...cloneDeep(tableData1.data.slice(0, 2)), - ...cloneDeep(tableData1.data.slice(0, 2)), - ...cloneDeep(tableData1.data) -] - -Paginated.args = { - columns: tableData1.columns, - data: paginatedData.map((item, i) => { - item.id = i - return item - }) -} +Paginated.args = tableData4 Paginated.argTypes = commonArgTypes const ColoredDotTemplate: Story> = args => ( {...args} /> ) - export const ColoredDot = ColoredDotTemplate.bind({}) -ColoredDot.args = { - ...tableData4, - pagination: false -} +ColoredDot.args = tableData5 diff --git a/src/components/Table/__tests__/Table.test.tsx b/src/components/Table/__tests__/Table.test.tsx index bf16ef4b..c4833d94 100644 --- a/src/components/Table/__tests__/Table.test.tsx +++ b/src/components/Table/__tests__/Table.test.tsx @@ -4,6 +4,7 @@ import React from 'react' import { Input as AntDInput, Table as AntDTable } from 'antd' import mockData, { Data, dateFormat } from '__mocks__/table_mock_data' import mockData0, { Person } from '../fixtures/0_sample_data' +import mockData1, { File } from '../fixtures/4_sample_data' import { mount, ReactWrapper } from 'enzyme' import { Table, TableProps } from '..' @@ -215,7 +216,7 @@ describe('Table onRowClick, activeRowKey', () => { expect(wrapper.find(AntDTable).props().onRow).toBeFalsy() }) - it('applies the active row styles if activeRowKey index passed with a valid key', () => { + it('applies the active row styles if activeRowKey index is passed with a valid key', () => { wrapper = mount( createTable({ ...mockData0, @@ -224,7 +225,6 @@ describe('Table onRowClick, activeRowKey', () => { }) ) - // eslint-disable-next-line quotes const tableRow = wrapper.find('tr[data-row-key=0]') expect(tableRow.getDOMNode().classList.toString()).toContain('active') @@ -232,25 +232,29 @@ describe('Table onRowClick, activeRowKey', () => { }) describe('Table pagination', () => { - it('does not pass pagination prop to AntD Table if it is true', () => { + it('does not show pagination if there are less than 10 rows', () => { wrapper = mount( createTable({ - ...mockData0, - pagination: true + ...mockData0 }) ) - expect(wrapper.find(AntDTable).props().pagination).toBeUndefined() + expect(wrapper.find(AntDTable).props().pagination).toBe(false) + + expect(wrapper.find('.ant-pagination').exists()).toBeFalsy() }) - it('passes pagination prop to AntD Table as if it is false', () => { + it('shows pagination if there are more than 10 rows', () => { wrapper = mount( - createTable({ - ...mockData0, - pagination: false + createTable({ + ...mockData1 }) ) - expect(wrapper.find(AntDTable).props().pagination).toBe(false) + expect(wrapper.find(AntDTable).props().pagination).toEqual({ + showSizeChanger: false + }) + + expect(wrapper.find('.ant-pagination').exists()).toBeTruthy() }) }) diff --git a/src/components/Table/fixtures/4_sample_data.ts b/src/components/Table/fixtures/4_sample_data.ts index bbb058c7..2cd45850 100644 --- a/src/components/Table/fixtures/4_sample_data.ts +++ b/src/components/Table/fixtures/4_sample_data.ts @@ -1,78 +1,26 @@ -import { ColumnFormats } from '../types' -import { styleguide } from 'components/assets/styles' -import { ThemeType } from 'components' -import { ColumnType, ColumnTypes, TableProps } from '../.' +import cloneDeep from 'lodash/cloneDeep' +import { TableProps } from '..' +import tableData1, { File } from './1_sample_data' -const { - colors: { blacks, oranges } -} = styleguide - -export interface Dot { - statusLabel: string - id: number | string - ingestionStatus: string -} - -const { coloredDot } = ColumnFormats -const { component, string } = ColumnTypes - -const columns: ColumnType[] = [ - { - dataIndex: 'statusLabel', - title: 'Status Label', - type: string - }, - { - dataIndex: 'ingestionStatus', - format: coloredDot, - renderProps: { - colorMap: { - disabled: null, - hasIssues: { - colors: { - [ThemeType.light]: oranges.base, - [ThemeType.dark]: oranges.base - }, - tooltipText: 'Test' - }, - needsConfig: { - colors: { - [ThemeType.light]: blacks['lighten-40'], - [ThemeType.dark]: blacks['lighten-70'] - }, - tooltipText: 'Needs Config' - }, - ok: null - } - }, - title: 'Ingestion Status', - type: component - } +const paginatedData = [ + ...cloneDeep(tableData1.data), + ...cloneDeep(tableData1.data.slice(0, 3)), + ...cloneDeep(tableData1.data), + ...cloneDeep(tableData1.data.slice(1, 4)), + ...cloneDeep(tableData1.data), + ...cloneDeep(tableData1.data.slice(0, 2)), + ...cloneDeep(tableData1.data.slice(0, 2)), + ...cloneDeep(tableData1.data.slice(0, 2)), + ...cloneDeep(tableData1.data) ] -const data: Dot[] = [ - { - id: 0, - ingestionStatus: 'ok', - statusLabel: 'ok' - }, - { - id: 1, - ingestionStatus: 'needsConfig', - statusLabel: 'needs config' - }, - { - id: 2, - ingestionStatus: 'disabled', - statusLabel: 'paused' - }, - { - id: 3, - ingestionStatus: 'hasIssues', - statusLabel: 'issues' - } -] - -const tableData4: TableProps = { columns, data } +const tableData4: TableProps = { + columns: tableData1.columns, + data: paginatedData.map((item, i) => { + item.id = i + return item + }) +} +export type { File } export default tableData4 diff --git a/src/components/Table/fixtures/5_sample_data.ts b/src/components/Table/fixtures/5_sample_data.ts new file mode 100644 index 00000000..585e6ada --- /dev/null +++ b/src/components/Table/fixtures/5_sample_data.ts @@ -0,0 +1,78 @@ +import { ColumnFormats } from '../types' +import { styleguide } from 'components/assets/styles' +import { ThemeType } from 'components' +import { ColumnType, ColumnTypes, TableProps } from '..' + +const { + colors: { blacks, oranges } +} = styleguide + +export interface Dot { + statusLabel: string + id: number | string + ingestionStatus: string +} + +const { coloredDot } = ColumnFormats +const { component, string } = ColumnTypes + +const columns: ColumnType[] = [ + { + dataIndex: 'statusLabel', + title: 'Status Label', + type: string + }, + { + dataIndex: 'ingestionStatus', + format: coloredDot, + renderProps: { + colorMap: { + disabled: null, + hasIssues: { + colors: { + [ThemeType.light]: oranges.base, + [ThemeType.dark]: oranges.base + }, + tooltipText: 'Test' + }, + needsConfig: { + colors: { + [ThemeType.light]: blacks['lighten-40'], + [ThemeType.dark]: blacks['lighten-70'] + }, + tooltipText: 'Needs Config' + }, + ok: null + } + }, + title: 'Ingestion Status', + type: component + } +] + +const data: Dot[] = [ + { + id: 0, + ingestionStatus: 'ok', + statusLabel: 'ok' + }, + { + id: 1, + ingestionStatus: 'needsConfig', + statusLabel: 'needs config' + }, + { + id: 2, + ingestionStatus: 'disabled', + statusLabel: 'paused' + }, + { + id: 3, + ingestionStatus: 'hasIssues', + statusLabel: 'issues' + } +] + +const tableData4: TableProps = { columns, data } + +export default tableData4 diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index a4bc31ef..eee4fca2 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -54,10 +54,6 @@ export interface TableProps extends CommonComponentProps { * Optional callback that runs when a table row is clicked */ onRowClick?: OnRowClick> - /** - * Optional prop to show or hide pagination. Pagination is present on the bottom right by default. - */ - pagination?: boolean /** * Optional prop to enable/disable table search */ @@ -68,6 +64,9 @@ export interface TableProps extends CommonComponentProps { searchProps?: SearchProps } +/* TODO: Add Table props to allow customization of pagination. */ +type Pagination = false | { showSizeChanger: false } + // eslint-disable-next-line comma-spacing export const Table = ({ activeRowKey = '', @@ -76,12 +75,12 @@ export const Table = ({ data, dataTag, onRowClick, - pagination, search = true, searchProps = {} as SearchProps }: TableProps) => { const [searchTerm, setSearchTerm] = useState('') const [filteredData, setFilteredData] = useState[]>([]) + const [pagination, setPagination] = useState(false) const tableClasses = useStyles({ onRowClick, @@ -98,6 +97,9 @@ export const Table = ({ useEffect(() => { setMappedData(mapData>(data)) + + if (data.length > 10) setPagination({ showSizeChanger: false }) + else setPagination(false) }, [data]) useEffect(() => { @@ -154,10 +156,6 @@ export const Table = ({ }) } - if (!pagination) { - optionalProps.pagination = pagination - } - return (
{search && ( @@ -171,6 +169,7 @@ export const Table = ({ Date: Thu, 3 Dec 2020 14:38:03 -0800 Subject: [PATCH 2/2] enhance #162 - Update FormToggle width --- .../Form/FormToggle/FormToggle.test.tsx | 46 +++++++++++++++++-- src/components/Form/FormToggle/index.tsx | 10 ++-- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/components/Form/FormToggle/FormToggle.test.tsx b/src/components/Form/FormToggle/FormToggle.test.tsx index a5ddc38b..7e83ffb5 100644 --- a/src/components/Form/FormToggle/FormToggle.test.tsx +++ b/src/components/Form/FormToggle/FormToggle.test.tsx @@ -1,6 +1,6 @@ import { Controller } from 'react-hook-form' +import { defaultFieldWidth } from 'components/assets/styles/styleguide' import FieldContext from '../FieldContext' -import FieldLabel from '../FieldLabel' import React from 'react' import { Toggle } from 'components/Toggle' import FormToggle, { FormToggleProps } from './index' @@ -78,7 +78,7 @@ describe('FormToggle', () => { expect(mockOnChange).toHaveBeenCalled() }) - it('should not render the label with the default width if fullWidth is passed as true', () => { + it('renders component with max-width of defaultFieldWith if fullWidth is not passed as true', () => { const div = document.createElement('div') div.setAttribute('id', 'container') document.body.appendChild(div) @@ -91,7 +91,11 @@ describe('FormToggle', () => { onSubmit: mockOnSubmit }} > - + , { attachTo: document.getElementById('container') @@ -99,9 +103,41 @@ describe('FormToggle', () => { ) const style = window.getComputedStyle( - wrapper.find(FieldLabel).getDOMNode() + wrapper.find(FormToggle).getDOMNode() ) - expect(style.width).not.toEqual(255) + expect(parseInt(style.maxWidth)).toEqual(parseInt(defaultFieldWidth)) + }) + + it('renders component with max-width of 100% if fullWidth is passed as true', () => { + const div = document.createElement('div') + div.setAttribute('id', 'container-1') + document.body.appendChild(div) + + wrapper = mount( + + + , + { + attachTo: document.getElementById('container-1') + } + ) + + const style = window.getComputedStyle( + wrapper.find(FormToggle).getDOMNode() + ) + + expect(style.maxWidth).toEqual('100%') }) }) diff --git a/src/components/Form/FormToggle/index.tsx b/src/components/Form/FormToggle/index.tsx index 2674bb34..5b062422 100644 --- a/src/components/Form/FormToggle/index.tsx +++ b/src/components/Form/FormToggle/index.tsx @@ -2,8 +2,11 @@ import { BaseFieldProps } from '../types' import { createUseStyles } from 'react-jss' import FieldLabel from '../FieldLabel' import { getFormFieldDataTag } from '../utils' -import { styleguide } from 'components/assets/styles' import { Controller, useFormContext } from 'react-hook-form' +import { + defaultFieldWidth, + styleguide +} from 'components/assets/styles/styleguide' import FieldContext, { FieldContextProps } from '../FieldContext' import React, { FC, useContext } from 'react' import { Toggle, ToggleProps } from 'components/Toggle' @@ -13,13 +16,14 @@ const { flexAlignCenter, font, spacing } = styleguide const useStyles = createUseStyles({ container: { ...flexAlignCenter, + maxWidth: ({ fullWidth }) => (fullWidth ? '100%' : defaultFieldWidth), padding: `${spacing.m}px 0` }, label: { ...font.body, paddingBottom: 0, - paddingRight: spacing.s, - width: ({ fullWidth }) => (fullWidth ? '100%' : 255) + paddingRight: spacing.l, + width: 'unset' } })