From 736b53418a3b3394dc967458d03d4c0ebcadabdd Mon Sep 17 00:00:00 2001 From: Eric Briscoe Date: Wed, 9 Nov 2022 14:33:27 -0800 Subject: [PATCH] feat: create table component based on ant design Table (#21520) Co-authored-by: Lyndsi Kay Williams <55605634+lyndsiWilliams@users.noreply.github.com> Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> --- superset-frontend/.storybook/main.js | 3 +- superset-frontend/.storybook/preview.jsx | 10 +- .../src/components/Button/index.tsx | 4 +- .../src/components/DesignSystem.stories.mdx | 25 + .../src/components/Dropdown/index.tsx | 26 +- .../components/Loading/Loading.stories.tsx | 4 +- .../src/components/Loading/Loading.test.tsx | 4 +- .../src/components/Loading/index.tsx | 6 +- ...ew.stories.mdx => MetadataBar.stories.mdx} | 20 +- .../MetadataBar/MetadataBar.stories.tsx | 10 +- .../src/components/Table/Table.overview.mdx | 260 +++++++++++ .../src/components/Table/Table.stories.tsx | 432 ++++++++++++++++++ .../src/components/Table/Table.test.tsx | 80 ++++ .../ActionCell/ActionCell.overview.mdx | 69 +++ .../ActionCell/ActionCell.stories.tsx | 36 ++ .../ActionCell/ActionCell.test.tsx | 50 ++ .../cell-renderers/ActionCell/fixtures.ts | 47 ++ .../Table/cell-renderers/ActionCell/index.tsx | 145 ++++++ .../ButtonCell/ButtonCell.stories.tsx | 62 +++ .../ButtonCell/ButtonCell.test.tsx | 40 ++ .../Table/cell-renderers/ButtonCell/index.tsx | 58 +++ .../NumericCell/NumericCell.stories.tsx | 47 ++ .../NumericCell/NumericCell.test.tsx | 49 ++ .../cell-renderers/NumericCell/index.tsx | 418 +++++++++++++++++ .../Table/cell-renderers/fixtures.ts | 25 + .../src/components/Table/index.tsx | 326 +++++++++++++ .../src/components/Table/sorters.test.ts | 100 ++++ .../src/components/Table/sorters.ts | 36 ++ .../Table/utils/InteractiveTableUtils.ts | 233 ++++++++++ .../src/components/Table/utils/utils.test.ts | 48 ++ .../src/components/Table/utils/utils.ts | 40 ++ .../src/components/atomic-design.png | Bin 0 -> 163100 bytes superset-frontend/src/types/files.d.ts | 1 + superset-frontend/webpack.config.js | 2 +- 34 files changed, 2692 insertions(+), 24 deletions(-) create mode 100644 superset-frontend/src/components/DesignSystem.stories.mdx rename superset-frontend/src/components/MetadataBar/{Overview.stories.mdx => MetadataBar.stories.mdx} (88%) create mode 100644 superset-frontend/src/components/Table/Table.overview.mdx create mode 100644 superset-frontend/src/components/Table/Table.stories.tsx create mode 100644 superset-frontend/src/components/Table/Table.test.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.overview.mdx create mode 100644 superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.stories.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.test.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/ActionCell/fixtures.ts create mode 100644 superset-frontend/src/components/Table/cell-renderers/ActionCell/index.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.stories.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.test.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/ButtonCell/index.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.stories.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.test.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/NumericCell/index.tsx create mode 100644 superset-frontend/src/components/Table/cell-renderers/fixtures.ts create mode 100644 superset-frontend/src/components/Table/index.tsx create mode 100644 superset-frontend/src/components/Table/sorters.test.ts create mode 100644 superset-frontend/src/components/Table/sorters.ts create mode 100644 superset-frontend/src/components/Table/utils/InteractiveTableUtils.ts create mode 100644 superset-frontend/src/components/Table/utils/utils.test.ts create mode 100644 superset-frontend/src/components/Table/utils/utils.ts create mode 100644 superset-frontend/src/components/atomic-design.png diff --git a/superset-frontend/.storybook/main.js b/superset-frontend/.storybook/main.js index 8a004ba3e..b8f15b569 100644 --- a/superset-frontend/.storybook/main.js +++ b/superset-frontend/.storybook/main.js @@ -24,7 +24,8 @@ module.exports = { builder: 'webpack5', }, stories: [ - '../src/@(components|common|filters|explore)/**/*.stories.@(tsx|jsx|mdx)', + '../src/@(components|common|filters|explore)/**/*.stories.@(tsx|jsx)', + '../src/@(components|common|filters|explore)/**/*.*.@(mdx)', ], addons: [ '@storybook/addon-essentials', diff --git a/superset-frontend/.storybook/preview.jsx b/superset-frontend/.storybook/preview.jsx index d98a55506..fa0c90887 100644 --- a/superset-frontend/.storybook/preview.jsx +++ b/superset-frontend/.storybook/preview.jsx @@ -68,7 +68,15 @@ addParameters({ ['Controls', 'Display', 'Feedback', 'Input', '*'], ['Overview', 'Examples', '*'], 'Design System', - ['Foundations', 'Components', 'Patterns', '*'], + [ + 'Introduction', + 'Foundations', + 'Components', + ['Overview', 'Examples', '*'], + 'Patterns', + '*', + ], + ['Overview', 'Examples', '*'], '*', ], }, diff --git a/superset-frontend/src/components/Button/index.tsx b/superset-frontend/src/components/Button/index.tsx index b4152ea98..05a1a3ad7 100644 --- a/superset-frontend/src/components/Button/index.tsx +++ b/superset-frontend/src/components/Button/index.tsx @@ -39,11 +39,13 @@ export type ButtonStyle = | 'link' | 'dashed'; +export type ButtonSize = 'default' | 'small' | 'xsmall'; + export type ButtonProps = Omit & Pick & { tooltip?: string; className?: string; - buttonSize?: 'default' | 'small' | 'xsmall'; + buttonSize?: ButtonSize; buttonStyle?: ButtonStyle; cta?: boolean; showMarginRight?: boolean; diff --git a/superset-frontend/src/components/DesignSystem.stories.mdx b/superset-frontend/src/components/DesignSystem.stories.mdx new file mode 100644 index 000000000..e00612c5b --- /dev/null +++ b/superset-frontend/src/components/DesignSystem.stories.mdx @@ -0,0 +1,25 @@ +import { Meta, Source } from '@storybook/addon-docs'; +import AtomicDesign from './atomic-design.png'; + + + +# Superset Design System + +A design system is a complete set of standards intended to manage design at scale using reusable components and patterns. + +You can get an overview of Atomic Design concepts and a link to the full book on the topic here: + + + Intro to Atomic Design + + +While the Superset Design System will use Atomic Design principles, we choose a different language to describe the elements. + +| Atomic Design | Atoms | Molecules | Organisms | Templates | Pages / Screens | +| :-------------- | :---------: | :--------: | :-------: | :-------: | :-------------: | +| Superset Design | Foundations | Components | Patterns | Templates | Features | + +Atoms = Foundations, Molecules = Components, Organisms = Patterns, Templates = Templates, Pages / Screens = Features diff --git a/superset-frontend/src/components/Dropdown/index.tsx b/superset-frontend/src/components/Dropdown/index.tsx index bd01aabb4..c40f47957 100644 --- a/superset-frontend/src/components/Dropdown/index.tsx +++ b/superset-frontend/src/components/Dropdown/index.tsx @@ -20,6 +20,7 @@ import React, { RefObject } from 'react'; import { AntdDropdown } from 'src/components'; import { DropDownProps } from 'antd/lib/dropdown'; import { styled } from '@superset-ui/core'; +import Icons from 'src/components/Icons'; const MenuDots = styled.div` width: ${({ theme }) => theme.gridUnit * 0.75}px; @@ -66,14 +67,35 @@ const MenuDotsWrapper = styled.div` padding-left: ${({ theme }) => theme.gridUnit}px; `; +export enum IconOrientation { + VERTICAL = 'vertical', + HORIZONTAL = 'horizontal', +} export interface DropdownProps extends DropDownProps { overlay: React.ReactElement; + iconOrientation?: IconOrientation; } -export const Dropdown = ({ overlay, ...rest }: DropdownProps) => ( +const RenderIcon = ( + iconOrientation: IconOrientation = IconOrientation.VERTICAL, +) => { + const component = + iconOrientation === IconOrientation.HORIZONTAL ? ( + + ) : ( + + ); + return component; +}; + +export const Dropdown = ({ + overlay, + iconOrientation = IconOrientation.VERTICAL, + ...rest +}: DropdownProps) => ( - + {RenderIcon(iconOrientation)} ); diff --git a/superset-frontend/src/components/Loading/Loading.stories.tsx b/superset-frontend/src/components/Loading/Loading.stories.tsx index 9f079848b..0c80c6f0f 100644 --- a/superset-frontend/src/components/Loading/Loading.stories.tsx +++ b/superset-frontend/src/components/Loading/Loading.stories.tsx @@ -40,7 +40,7 @@ export const LoadingGallery = () => ( }} >

{position}

- + ))} @@ -71,7 +71,7 @@ InteractiveLoading.story = { }; InteractiveLoading.args = { - image: '/src/assets/images/loading.gif', + image: '', className: '', }; diff --git a/superset-frontend/src/components/Loading/Loading.test.tsx b/superset-frontend/src/components/Loading/Loading.test.tsx index d6ea8581c..7325c9304 100644 --- a/superset-frontend/src/components/Loading/Loading.test.tsx +++ b/superset-frontend/src/components/Loading/Loading.test.tsx @@ -26,11 +26,9 @@ test('Rerendering correctly with default props', () => { render(); const loading = screen.getByRole('status'); const classNames = loading.getAttribute('class')?.split(' '); - const imagePath = loading.getAttribute('src'); const ariaLive = loading.getAttribute('aria-live'); const ariaLabel = loading.getAttribute('aria-label'); expect(loading).toBeInTheDocument(); - expect(imagePath).toBe('/static/assets/images/loading.gif'); expect(classNames).toContain('floating'); expect(classNames).toContain('loading'); expect(ariaLive).toContain('polite'); @@ -56,7 +54,7 @@ test('support for extra classes', () => { expect(classNames).toContain('extra-class'); }); -test('Diferent image path', () => { +test('Different image path', () => { render(); const loading = screen.getByRole('status'); const imagePath = loading.getAttribute('src'); diff --git a/superset-frontend/src/components/Loading/index.tsx b/superset-frontend/src/components/Loading/index.tsx index 6ba6fb45c..97cd553ad 100644 --- a/superset-frontend/src/components/Loading/index.tsx +++ b/superset-frontend/src/components/Loading/index.tsx @@ -20,6 +20,7 @@ import React from 'react'; import { styled } from '@superset-ui/core'; import cls from 'classnames'; +import Loader from 'src/assets/images/loading.gif'; export type PositionOption = | 'floating' @@ -35,6 +36,7 @@ export interface Props { const LoaderImg = styled.img` z-index: 99; width: 50px; + height: unset; position: relative; margin: 10px; &.inline { @@ -57,14 +59,14 @@ const LoaderImg = styled.img` `; export default function Loading({ position = 'floating', - image = '/static/assets/images/loading.gif', + image, className, }: Props) { return ( + -# Usage +# Metadata bar -The metadata bar component is used to display additional information about an entity. Some of the common applications in Superset are: +The metadata bar component is used to display additional information about an entity. + +## Usage + +Some of the common applications in Superset are: - Display the chart's metadata in Explore to help the user understand what dashboards this chart is added to and get to know the details of the chart - Display the database's metadata in a drill to detail modal to help the user understand what data they are looking at while accessing the feature in the dashboard -# Variations +## Basic example + + + +## Variations The metadata bar is by default a static component (besides the links in text). The variations in this component are related to content and entity type as all of the details are predefined @@ -25,7 +33,7 @@ have the same icon and when hovered it will present who created the entity, its To extend the list of content types, a developer needs to request the inclusion of the new type in the design system. This process is important to make sure the new type is reviewed by the design team, improving Superset consistency. -To check each content type in detail and its interactions, check the [MetadataBar](/story/metadatabar--component) page. +To check each content type in detail and its interactions, check the [MetadataBar](/story/design-system-components-metadatabar-examples--basic) page. Below you can find the configurations for each content type: + +# Table + +A table is UI that allows the user to explore data in a tabular format. + +## Usage + +Common table applications in Superset: + +- Display lists of user-generated entities (e.g. dashboard, charts, queries) for further exploration and use +- Display data that can help the user make a decision (e.g. query results) + +This component provides a general use Table. + +--- + +### [Basic example](./?path=/docs/design-system-components-table-examples--basic) + + + +### Data and Columns + +To set the visible columns and data for the table you use the `columns` and `data` props. + +
+ +The basic table example for the `columns` prop is: + +``` +const basicColumns: = [ + { + title: 'Name', + dataIndex: 'name', + key: 'name', + width: 150, + sorter: (a: BasicData, b: BasicData) => + alphabeticalSort('name', a, b), + }, + { + title: 'Category', + dataIndex: 'category', + key: 'category', + sorter: (a: BasicData, b: BasicData) => + alphabeticalSort('category', a, b), + }, + { + title: 'Price', + dataIndex: 'price', + key: 'price', + sorter: (a: BasicData, b: BasicData) => + numericalSort('price', a, b), + }, + { + title: 'Description', + dataIndex: 'description', + key: 'description', + }, +]; +``` + +The data prop is: + +``` +const basicData: = [ + { + key: 1, + name: 'Floppy Disk 10 pack', + category: 'Disk Storage', + price: '9.99' + description: 'A real blast from the past', + }, + { + key: 2, + name: 'DVD 100 pack', + category: 'Optical Storage', + price: '27.99' + description: 'Still pretty ancient', + }, + { + key: 3, + name: '128 GB SSD', + category: 'Hardrive', + price: '49.99' + description: 'Reliable and fast data storage', + }, +]; +``` + +
+ +### Column Sort Functions + +To ensure consistency for column sorting and to avoid redundant definitions for common column sorters, reusable sort functions are provided. +When defining the object for the `columns` prop you can provide an optional attribute `sorter`. +The function provided in the `sorter` prop is given the entire record representing a row as props `a` and `b`. +When using a provided sorter function the pattern is to wrap the call to the sorter with an inline function, then specify the specific attribute value from `dataIndex`, representing a column +of the data object for that row, as the first argument of the sorter function. + +#### alphabeticalSort + +The alphabeticalSort is for columns that display a string of text. + +
+ +``` +import { alphabeticalSort } from 'src/components/Table/sorters'; + +const basicColumns = [ + { + title: 'Column Name', + dataIndex: 'columnName', + key: 'columnName', + sorter: (a, b) => + alphabeticalSort('columnName', a, b), + } +] +``` + +
+ +#### numericSort + +The numericalSort is for columns that display a numeric value. + +
+ +``` +import { numericalSort } from './sorters'; + +const basicColumns = [ + { + title: 'Height', + dataIndex: 'height', + key: 'height', + sorter: (a, b) => + numericalSort('height', a, b), + } +] +``` + +
+ +If a different sort option is needed, consider adding it as a reusable sort function following the pattern provided above. + +--- + +### Cell Content Renderers + +By default, each column will render the value as simple text. Often you will want to show formatted values, such as a numeric column showing as currency, or a more complex component such as a button or action menu as a cell value. +Cell Renderers are React components provided to the optional `render` attribute on a column definition that enables injecting a specific React component to enable this. + + + +For convenience and consistency, the Table component provides pre-built Cell Renderers for: +The following data types can be displayed in table cells. + +- Text (default) +- [Button Cell](./?path=/docs/design-system-components-table-cell-renderers-buttoncell--basic) +- [Numeric Cell](./docs/design-system-components-table-cell-renderers-numericcell--basic) + - Support Locale and currency formatting + - w/ icons - Coming Soon +- [Action Menu Cell](./?path=/docs/design-system-components-table-cell-renderers-actioncell-overview--page) +- Provide a list of menu options with callback functions that retain a reference to the row the menu is defined for +- Custom + - You can provide your own React component as a cell renderer in cases not supported + +--- + +### Loading + +The table can be set to a loading state simply by setting the loading prop to true | false + + + +--- + +### Pagination + +The table displays a set number of rows at a time, the user navigates the table via pagination. Use in scenarios where the user is searching for a specific piece of content. +The default page size and page size options for the menu are configurable via the `pageSizeOptions` and `defaultPageSize` props. +NOTE: Pagination controls will only display when the data for the table has more records than the default page size. + + + +``` + +``` + +--- + +## Integration Checklist + +The following specifications are required every time a table is used. These choices should be intentional based on the specific user needs for the table instance. + +
+ +- [ ] Size + - Large + - Small +- Columns + - [ ] Number of + - [ ] Contents + - [ ] Order + - [ ] Widths +- Column headers + - [ ] Labels + - [ ] Has tooltip + - [ ] Tooltip text +- [ ] Default sort +- Functionality + - [ ] Can sort columns + - [ ] Can filter columns +- [ ] Loading + - Pagination + - [ ] Number of rows per page + - Infinite scroll +- [ ] Has toolbar + - [ ] Has table title + - [ ] Label + - [ ] Has buttons + - [ ] Labels + - [ ] Actions + - [ ] Has search + +
+ +--- + +## Experimental features + +The Table component has features that are still experimental and can be used at your own risk. +These features are intended to be made fully stable in future releases. + +### Resizable Columns + +The prop `resizable` enables table columns to be resized by the user dragging from the right edge of each +column to increase or decrease the columns' width + + + +### Drag & Drop Columns + +The prop `reorderable` can enable column drag and drop reordering as well as dragging a column to another component. If you want to accept the drop event of a Table Column +you can register `onDragOver` and `onDragDrop` event handlers on the destination component. In the `onDragDrop` handler you can check for `SUPERSET_TABLE_COLUMN` +as the getData key as shown below. + +``` +import { SUPERSET_TABLE_COLUMN } from 'src/components/table'; + +const handleDrop = (ev:Event) => { + const json = ev.dataTransfer?.getData?.(SUPERSET_TABLE_COLUMN); + const data = JSON.parse(json); + // ... do something with the data here +} +``` + + diff --git a/superset-frontend/src/components/Table/Table.stories.tsx b/superset-frontend/src/components/Table/Table.stories.tsx new file mode 100644 index 000000000..90ee3448c --- /dev/null +++ b/superset-frontend/src/components/Table/Table.stories.tsx @@ -0,0 +1,432 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useState } from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import { supersetTheme, ThemeProvider } from '@superset-ui/core'; +import { Table, TableSize, SUPERSET_TABLE_COLUMN, ColumnsType } from './index'; +import { numericalSort, alphabeticalSort } from './sorters'; +import ButtonCell from './cell-renderers/ButtonCell'; +import ActionCell from './cell-renderers/ActionCell'; +import { exampleMenuOptions } from './cell-renderers/ActionCell/fixtures'; +import NumericCell, { + CurrencyCode, + LocaleCode, + Style, +} from './cell-renderers/NumericCell'; + +export default { + title: 'Design System/Components/Table/Examples', + component: Table, + argTypes: { onClick: { action: 'clicked' } }, +} as ComponentMeta; + +export interface BasicData { + name: string; + category: string; + price: number; + description?: string; + key: number; +} + +export interface RendererData { + key: number; + buttonCell: string; + textCell: string; + euroCell: number; + dollarCell: number; +} + +export interface ExampleData { + title: string; + name: string; + age: number; + address: string; + tags?: string[]; + key: number; +} + +function generateValues(amount: number): object { + const cells = {}; + for (let i = 0; i < amount; i += 1) { + cells[`col-${i}`] = `Text ${i}`; + } + return cells; +} + +function generateColumns(amount: number): ColumnsType[] { + const newCols: any[] = []; + for (let i = 0; i < amount; i += 1) { + newCols.push({ + title: `Column Header ${i}`, + dataIndex: `col-${i}`, + key: `col-${i}`, + }); + } + return newCols as ColumnsType[]; +} +const recordCount = 200; +const columnCount = 12; +const randomCols: ColumnsType[] = generateColumns(columnCount); + +const basicData: BasicData[] = [ + { + key: 1, + name: 'Floppy Disk 10 pack', + category: 'Disk Storage', + price: 9.99, + description: 'A real blast from the past', + }, + { + key: 2, + name: 'DVD 100 pack', + category: 'Optical Storage', + price: 27.99, + description: 'Still pretty ancient', + }, + { + key: 3, + name: '128 GB SSD', + category: 'Hardrive', + price: 49.99, + description: 'Reliable and fast data storage', + }, +]; + +const basicColumns: ColumnsType = [ + { + title: 'Name', + dataIndex: 'name', + key: 'name', + width: 150, + sorter: (a: BasicData, b: BasicData) => alphabeticalSort('name', a, b), + }, + { + title: 'Category', + dataIndex: 'category', + key: 'category', + sorter: (a: BasicData, b: BasicData) => alphabeticalSort('category', a, b), + }, + { + title: 'Price', + dataIndex: 'price', + key: 'price', + sorter: (a: BasicData, b: BasicData) => numericalSort('price', a, b), + }, + { + title: 'Description', + dataIndex: 'description', + key: 'description', + }, +]; + +const bigColumns: ColumnsType = [ + { + title: 'Name', + dataIndex: 'name', + key: 'name', + render: (text: string, row: object, index: number) => ( + + ), + width: 150, + }, + { + title: 'Age', + dataIndex: 'age', + key: 'age', + }, + { + title: 'Address', + dataIndex: 'address', + key: 'address', + }, + ...(randomCols as ColumnsType), +]; + +const rendererColumns: ColumnsType = [ + { + title: 'Button Cell', + dataIndex: 'buttonCell', + key: 'buttonCell', + width: 150, + render: (text: string, data: object, index: number) => ( + + ), + }, + { + title: 'Text Cell', + dataIndex: 'textCell', + key: 'textCell', + }, + { + title: 'Euro Cell', + dataIndex: 'euroCell', + key: 'euroCell', + render: (value: number) => ( + + ), + }, + { + title: 'Dollar Cell', + dataIndex: 'dollarCell', + key: 'dollarCell', + render: (value: number) => ( + + ), + }, + { + dataIndex: 'actions', + key: 'actions', + render: (text: string, row: object) => ( + + ), + width: 32, + fixed: 'right', + }, +]; + +const baseData: any[] = [ + { + key: 1, + name: 'John Brown', + age: 32, + address: 'New York No. 1 Lake Park', + tags: ['nice', 'developer'], + ...generateValues(columnCount), + }, + { + key: 2, + name: 'Jim Green', + age: 42, + address: 'London No. 1 Lake Park', + tags: ['loser'], + ...generateValues(columnCount), + }, + { + key: 3, + name: 'Joe Black', + age: 32, + address: 'Sidney No. 1 Lake Park', + tags: ['cool', 'teacher'], + ...generateValues(columnCount), + }, +]; + +const bigdata: any[] = []; +for (let i = 0; i < recordCount; i += 1) { + bigdata.push({ + key: i + baseData.length, + name: `Dynamic record ${i}`, + age: 32 + i, + address: `DynamoCity, Dynamic Lane no. ${i}`, + ...generateValues(columnCount), + }); +} + +export const Basic: ComponentStory = args => ( + +
+
+ + +); + +function handlers(record: object, rowIndex: number) { + return { + onClick: action( + `row onClick, row: ${rowIndex}, record: ${JSON.stringify(record)}`, + ), // click row + onDoubleClick: action( + `row onDoubleClick, row: ${rowIndex}, record: ${JSON.stringify(record)}`, + ), // double click row + onContextMenu: action( + `row onContextMenu, row: ${rowIndex}, record: ${JSON.stringify(record)}`, + ), // right button click row + onMouseEnter: action(`Mouse Enter, row: ${rowIndex}`), // mouse enter row + onMouseLeave: action(`Mouse Leave, row: ${rowIndex}`), // mouse leave row + }; +} + +Basic.args = { + data: basicData, + columns: basicColumns, + size: TableSize.SMALL, + onRow: handlers, + pageSizeOptions: ['5', '10', '15', '20', '25'], + defaultPageSize: 10, +}; + +export const ManyColumns: ComponentStory = args => ( + +
+
+ + +); + +ManyColumns.args = { + data: bigdata, + columns: bigColumns, + size: TableSize.SMALL, + resizable: true, + reorderable: true, + height: 350, +}; + +export const Loading: ComponentStory = args => ( + +
+ +); + +Loading.args = { + data: basicData, + columns: basicColumns, + size: TableSize.SMALL, + loading: true, +}; + +export const ResizableColumns: ComponentStory = args => ( + +
+
+ + +); + +ResizableColumns.args = { + data: basicData, + columns: basicColumns, + size: TableSize.SMALL, + resizable: true, +}; + +export const ReorderableColumns: ComponentStory = args => { + const [droppedItem, setDroppedItem] = useState(); + const dragOver = (ev: React.DragEvent) => { + ev.preventDefault(); + const element: HTMLElement | null = ev?.currentTarget as HTMLElement; + if (element?.style) { + element.style.border = '1px dashed green'; + } + }; + + const dragOut = (ev: React.DragEvent) => { + ev.preventDefault(); + const element: HTMLElement | null = ev?.currentTarget as HTMLElement; + if (element?.style) { + element.style.border = '1px solid grey'; + } + }; + + const dragDrop = (ev: React.DragEvent) => { + const data = ev.dataTransfer?.getData?.(SUPERSET_TABLE_COLUMN); + const element: HTMLElement | null = ev?.currentTarget as HTMLElement; + if (element?.style) { + element.style.border = '1px solid grey'; + } + setDroppedItem(data); + }; + return ( + +
+
) => dragOver(ev)} + onDragLeave={(ev: React.DragEvent) => dragOut(ev)} + onDrop={(ev: React.DragEvent) => dragDrop(ev)} + style={{ + width: '100%', + height: '40px', + border: '1px solid grey', + marginBottom: '8px', + padding: '8px', + borderRadius: '4px', + }} + > + {droppedItem ?? 'Drop column here...'} +
+
+ + + ); +}; + +ReorderableColumns.args = { + data: basicData, + columns: basicColumns, + size: TableSize.SMALL, + reorderable: true, +}; + +const rendererData: RendererData[] = [ + { + key: 1, + buttonCell: 'Click Me', + textCell: 'Some text', + euroCell: 45.5, + dollarCell: 45.5, + }, + { + key: 2, + buttonCell: 'I am a button', + textCell: 'More text', + euroCell: 1700, + dollarCell: 1700, + }, + { + key: 3, + buttonCell: 'Button 3', + textCell: 'The third string of text', + euroCell: 500.567, + dollarCell: 500.567, + }, +]; + +export const CellRenderers: ComponentStory = args => ( + +
+
+ + +); + +CellRenderers.args = { + data: rendererData, + columns: rendererColumns, + size: TableSize.SMALL, + reorderable: true, +}; diff --git a/superset-frontend/src/components/Table/Table.test.tsx b/superset-frontend/src/components/Table/Table.test.tsx new file mode 100644 index 000000000..eded7efeb --- /dev/null +++ b/superset-frontend/src/components/Table/Table.test.tsx @@ -0,0 +1,80 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, screen, waitFor } from 'spec/helpers/testing-library'; +import type { ColumnsType } from 'antd/es/table'; +import { Table, TableSize } from './index'; + +interface BasicData { + columnName: string; + columnType: string; + dataType: string; +} + +const testData: BasicData[] = [ + { + columnName: 'Number', + columnType: 'Numerical', + dataType: 'number', + }, + { + columnName: 'String', + columnType: 'Physical', + dataType: 'string', + }, + { + columnName: 'Date', + columnType: 'Virtual', + dataType: 'date', + }, +]; + +const testColumns: ColumnsType = [ + { + title: 'Column Name', + dataIndex: 'columnName', + key: 'columnName', + }, + { + title: 'Column Type', + dataIndex: 'columnType', + key: 'columnType', + }, + { + title: 'Data Type', + dataIndex: 'dataType', + key: 'dataType', + }, +]; + +test('renders with default props', async () => { + render( +
, + ); + await waitFor(() => + testColumns.forEach(column => + expect(screen.getByText(column.title as string)).toBeInTheDocument(), + ), + ); + testData.forEach(row => { + expect(screen.getByText(row.columnName)).toBeInTheDocument(); + expect(screen.getByText(row.columnType)).toBeInTheDocument(); + expect(screen.getByText(row.dataType)).toBeInTheDocument(); + }); +}); diff --git a/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.overview.mdx b/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.overview.mdx new file mode 100644 index 000000000..09e1b5ed6 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.overview.mdx @@ -0,0 +1,69 @@ +import { Meta, Source, Story, ArgsTable } from '@storybook/addon-docs'; + + + +# ActionCell + +An ActionCell is used to display an overflow icon that opens a menu allowing the user to take actions +specific to the data in the table row that the cell is a member of. + +### [Basic example](./?path=/docs/design-system-components-table-cell-renderers-actioncell--basic) + + + +--- + +## Usage + +The action cell accepts an array of objects that define the label, tooltip, onClick callback functions, +and an optional data payload to be provided back to the onClick handler function. + +### [Basic example](./?path=/docs/design-system-components-table-cell-renderers-actioncell--basic) + + + +``` +import { ActionMenuItem } from 'src/components/Table/cell-renderers/index'; + +export const exampleMenuOptions: ActionMenuItem[] = [ + { + label: 'Action 1', + tooltip: "This is a tip, don't spend it all in one place", + onClick: (item: ActionMenuItem) => { + // eslint-disable-next-line no-alert + alert(JSON.stringify(item)); + }, + payload: { + taco: 'spicy chicken', + }, + }, + { + label: 'Action 2', + tooltip: 'This is another tip', + onClick: (item: ActionMenuItem) => { + // eslint-disable-next-line no-alert + alert(JSON.stringify(item)); + }, + payload: { + taco: 'saucy tofu', + }, + }, +]; + +``` + +Within the context of adding an action cell to cell definitions provided to the table using the ActionCell component +for the return value from the render function on the cell definition. See the [Basic example](./?path=/docs/design-system-components-table-examples--basic) + +``` +import ActionCell from './index'; + +const cellExample = [ + { + title: 'Actions', + dataIndex: 'actions', + key: 'actions', + render: () => , + } +] +``` diff --git a/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.stories.tsx b/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.stories.tsx new file mode 100644 index 000000000..d51dbcc55 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.stories.tsx @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import ActionCell from './index'; +import { exampleMenuOptions, exampleRow } from './fixtures'; + +export default { + title: 'Design System/Components/Table/Cell Renderers/ActionCell', + component: ActionCell, +} as ComponentMeta; + +export const Basic: ComponentStory = args => ( + +); + +Basic.args = { + menuOptions: exampleMenuOptions, + row: exampleRow, +}; diff --git a/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.test.tsx b/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.test.tsx new file mode 100644 index 000000000..5da7453aa --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ActionCell/ActionCell.test.tsx @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import ActionCell, { appendDataToMenu } from './index'; +import { exampleMenuOptions, exampleRow } from './fixtures'; + +test('renders with default props', async () => { + const clickHandler = jest.fn(); + exampleMenuOptions[0].onClick = clickHandler; + render(); + // Open the menu + userEvent.click(await screen.findByTestId('dropdown-trigger')); + // verify all of the menu items are being displayed + exampleMenuOptions.forEach((item, index) => { + expect(screen.getByText(item.label)).toBeInTheDocument(); + if (index === 0) { + // verify the menu items' onClick gets invoked + userEvent.click(screen.getByText(item.label)); + } + }); + expect(clickHandler).toHaveBeenCalled(); +}); + +/** + * Validate that the appendDataToMenu utility function used within the + * Action cell menu rendering works as expected + */ +test('appendDataToMenu utility', () => { + exampleMenuOptions.forEach(item => expect(item?.row).toBeUndefined()); + const modifiedMenuOptions = appendDataToMenu(exampleMenuOptions, exampleRow); + modifiedMenuOptions.forEach(item => expect(item?.row).toBeDefined()); +}); diff --git a/superset-frontend/src/components/Table/cell-renderers/ActionCell/fixtures.ts b/superset-frontend/src/components/Table/cell-renderers/ActionCell/fixtures.ts new file mode 100644 index 000000000..a0569b699 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ActionCell/fixtures.ts @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { action } from '@storybook/addon-actions'; +import { ActionMenuItem } from './index'; + +export const exampleMenuOptions: ActionMenuItem[] = [ + { + label: 'Action 1', + tooltip: "This is a tip, don't spend it all in one place", + onClick: action('menu item onClick'), + payload: { + taco: 'spicy chicken', + }, + }, + { + label: 'Action 2', + tooltip: 'This is another tip', + onClick: action('menu item onClick'), + payload: { + taco: 'saucy tofu', + }, + }, +]; + +export const exampleRow = { + key: 1, + buttonCell: 'Click Me', + textCell: 'Some text', + euroCell: 45.5, + dollarCell: 45.5, +}; diff --git a/superset-frontend/src/components/Table/cell-renderers/ActionCell/index.tsx b/superset-frontend/src/components/Table/cell-renderers/ActionCell/index.tsx new file mode 100644 index 000000000..b6ba57420 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ActionCell/index.tsx @@ -0,0 +1,145 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useState, useEffect } from 'react'; +import { styled } from '@superset-ui/core'; +import { Dropdown, IconOrientation } from 'src/components/Dropdown'; +import { Menu } from 'src/components/Menu'; +import { MenuProps } from 'antd/lib/menu'; + +/** + * Props interface for Action Cell Renderer + */ +export interface ActionCellProps { + /** + * The Menu option presented to user when menu displays + */ + menuOptions: ActionMenuItem[]; + /** + * Object representing the data rendering the Table row with attribute for each column + */ + row: object; +} + +export interface ActionMenuItem { + /** + * Click handler specific to the menu item + * @param menuItem The definition of the menu item that was clicked + * @returns ActionMenuItem + */ + onClick: (menuItem: ActionMenuItem) => void; + /** + * Label user will see displayed in the list of menu options + */ + label: string; + /** + * Optional tooltip user will see if they hover over the menu option to get more context + */ + tooltip?: string; + /** + * Optional variable that can contain data relevant to the menu item that you + * want easy access to in the callback function for the menu + */ + payload?: any; + /** + * Object representing the data rendering the Table row with attribute for each column + */ + row?: object; +} + +/** + * Props interface for ActionMenu + */ +export interface ActionMenuProps { + menuOptions: ActionMenuItem[]; + setVisible: (visible: boolean) => void; +} + +const SHADOW = + 'box-shadow: 0px 3px 6px -4px rgba(0, 0, 0, 0.12), 0px 9px 28px 8px rgba(0, 0, 0, 0.05)'; +const FILTER = 'drop-shadow(0px 6px 16px rgba(0, 0, 0, 0.08))'; + +const StyledMenu = styled(Menu)` + box-shadow: ${SHADOW} !important; + filter: ${FILTER} !important; + border-radius: 2px !important; + -webkit-box-shadow: ${SHADOW} !important; +`; + +export const appendDataToMenu = ( + options: ActionMenuItem[], + row: object, +): ActionMenuItem[] => { + const newOptions = options?.map?.(option => ({ + ...option, + row, + })); + return newOptions; +}; + +function ActionMenu(props: ActionMenuProps) { + const { menuOptions, setVisible } = props; + const handleClick: MenuProps['onClick'] = ({ key }) => { + setVisible?.(false); + const menuItem = menuOptions[key]; + if (menuItem) { + menuItem?.onClick?.(menuItem); + } + }; + + return ( + + {menuOptions?.map?.((option: ActionMenuItem, index: number) => ( + {option?.label} + ))} + + ); +} + +export function ActionCell(props: ActionCellProps) { + const { menuOptions, row } = props; + const [visible, setVisible] = useState(false); + const [appendedMenuOptions, setAppendedMenuOptions] = useState( + appendDataToMenu(menuOptions, row), + ); + + useEffect(() => { + const newOptions = appendDataToMenu(menuOptions, row); + setAppendedMenuOptions(newOptions); + }, [menuOptions, row]); + + const handleVisibleChange = (flag: boolean) => { + setVisible(flag); + }; + return ( + + } + disabled={ + !(appendedMenuOptions?.length && appendedMenuOptions.length > 0) + } + visible={visible} + /> + ); +} + +export default ActionCell; diff --git a/superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.stories.tsx b/superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.stories.tsx new file mode 100644 index 000000000..707e758ee --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.stories.tsx @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import { ButtonCell } from './index'; + +export default { + title: 'Design System/Components/Table/Cell Renderers/ButtonCell', + component: ButtonCell, +} as ComponentMeta; + +const clickHandler = action('button cell onClick'); + +export const Basic: ComponentStory = args => ( + +); + +Basic.args = { + onClick: clickHandler, + label: 'Primary', + row: { + key: 1, + buttonCell: 'Click Me', + textCell: 'Some text', + euroCell: 45.5, + dollarCell: 45.5, + }, +}; + +export const Secondary: ComponentStory = args => ( + +); + +Secondary.args = { + onClick: clickHandler, + label: 'Secondary', + buttonStyle: 'secondary', + row: { + key: 1, + buttonCell: 'Click Me', + textCell: 'Some text', + euroCell: 45.5, + dollarCell: 45.5, + }, +}; diff --git a/superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.test.tsx b/superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.test.tsx new file mode 100644 index 000000000..dbdb8fd4f --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ButtonCell/ButtonCell.test.tsx @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import ButtonCell from './index'; +import { exampleRow } from '../fixtures'; + +test('renders with default props', async () => { + const clickHandler = jest.fn(); + const BUTTON_LABEL = 'Button Label'; + + render( + , + ); + await userEvent.click(screen.getByText(BUTTON_LABEL)); + expect(clickHandler).toHaveBeenCalled(); +}); diff --git a/superset-frontend/src/components/Table/cell-renderers/ButtonCell/index.tsx b/superset-frontend/src/components/Table/cell-renderers/ButtonCell/index.tsx new file mode 100644 index 000000000..c5739a386 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/ButtonCell/index.tsx @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import Button, { ButtonStyle, ButtonSize } from 'src/components/Button'; + +type onClickFunction = (row: object, index: number) => void; + +export interface ButtonCellProps { + label: string; + onClick: onClickFunction; + row: object; + index: number; + tooltip?: string; + buttonStyle?: ButtonStyle; + buttonSize?: ButtonSize; +} + +export function ButtonCell(props: ButtonCellProps) { + const { + label, + onClick, + row, + index, + tooltip, + buttonStyle = 'primary', + buttonSize = 'small', + } = props; + + return ( + + ); +} + +export default ButtonCell; diff --git a/superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.stories.tsx b/superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.stories.tsx new file mode 100644 index 000000000..bb0b52fe6 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.stories.tsx @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { CurrencyCode, LocaleCode, NumericCell, Style } from './index'; + +export default { + title: 'Design System/Components/Table/Cell Renderers/NumericCell', + component: NumericCell, +} as ComponentMeta; + +export const Basic: ComponentStory = args => ( + +); + +Basic.args = { + value: 5678943, +}; + +export const FrenchLocale: ComponentStory = args => ( + +); + +FrenchLocale.args = { + value: 5678943, + locale: LocaleCode.fr, + options: { + style: Style.CURRENCY, + currency: CurrencyCode.EUR, + }, +}; diff --git a/superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.test.tsx b/superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.test.tsx new file mode 100644 index 000000000..b76a5bef6 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/NumericCell/NumericCell.test.tsx @@ -0,0 +1,49 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import NumericCell, { CurrencyCode, LocaleCode, Style } from './index'; + +test('renders with French locale and Euro currency format', () => { + render( + , + ); + expect(screen.getByText('5 678 943,00 €')).toBeInTheDocument(); +}); + +test('renders with English US locale and USD currency format', () => { + render( + , + ); + expect(screen.getByText('$5,678,943.00')).toBeInTheDocument(); +}); diff --git a/superset-frontend/src/components/Table/cell-renderers/NumericCell/index.tsx b/superset-frontend/src/components/Table/cell-renderers/NumericCell/index.tsx new file mode 100644 index 000000000..5e6d61aa4 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/NumericCell/index.tsx @@ -0,0 +1,418 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { logging } from '@superset-ui/core'; + +export interface NumericCellProps { + /** + * The number to display (before optional formatting applied) + */ + value: number; + /** + * ISO 639-1 language code with optional region or script modifier (e.g. en_US). + */ + locale?: LocaleCode; + /** + * Options for number formatting + */ + options?: NumberOptions; +} + +interface NumberOptions { + /** + * Style of number to display + */ + style?: Style; + + /** + * ISO 4217 currency code + */ + currency?: CurrencyCode; + + /** + * Languages in the form of a ISO 639-1 language code with optional region or script modifier (e.g. de_AT). + */ + maximumFractionDigits?: number; + + /** + * A number from 1 to 21 (default is 21) + */ + maximumSignificantDigits?: number; + + /** + * A number from 0 to 20 (default is 3) + */ + minimumFractionDigits?: number; + + /** + * A number from 1 to 21 (default is 1) + */ + minimumIntegerDigits?: number; + + /** + * A number from 1 to 21 (default is 21) + */ + minimumSignificantDigits?: number; +} + +export enum Style { + CURRENCY = 'currency', + DECIMAL = 'decimal', + PERCENT = 'percent', +} + +export enum CurrencyDisplay { + SYMBOL = 'symbol', + CODE = 'code', + NAME = 'name', +} + +export enum LocaleCode { + af = 'af', + ak = 'ak', + sq = 'sq', + am = 'am', + ar = 'ar', + hy = 'hy', + as = 'as', + az = 'az', + bm = 'bm', + bn = 'bn', + eu = 'eu', + be = 'be', + bs = 'bs', + br = 'br', + bg = 'bg', + my = 'my', + ca = 'ca', + ce = 'ce', + zh = 'zh', + zh_Hans = 'zh-Hans', + zh_Hant = 'zh-Hant', + cu = 'cu', + kw = 'kw', + co = 'co', + hr = 'hr', + cs = 'cs', + da = 'da', + nl = 'nl', + nl_BE = 'nl-BE', + dz = 'dz', + en = 'en', + en_AU = 'en-AU', + en_CA = 'en-CA', + en_GB = 'en-GB', + en_US = 'en-US', + eo = 'eo', + et = 'et', + ee = 'ee', + fo = 'fo', + fi = 'fi', + fr = 'fr', + fr_CA = 'fr-CA', + fr_CH = 'fr-CH', + ff = 'ff', + gl = 'gl', + lg = 'lg', + ka = 'ka', + de = 'de', + de_AT = 'de-AT', + de_CH = 'de-CH', + el = 'el', + gu = 'gu', + ht = 'ht', + ha = 'ha', + he = 'he', + hi = 'hi', + hu = 'hu', + is = 'is', + ig = 'ig', + id = 'id', + ia = 'ia', + ga = 'ga', + it = 'it', + ja = 'ja', + jv = 'jv', + kl = 'kl', + kn = 'kn', + ks = 'ks', + kk = 'kk', + km = 'km', + ki = 'ki', + rw = 'rw', + ko = 'ko', + ku = 'ku', + ky = 'ky', + lo = 'lo', + la = 'la', + lv = 'lv', + ln = 'ln', + lt = 'lt', + lu = 'lu', + lb = 'lb', + mk = 'mk', + mg = 'mg', + ms = 'ms', + ml = 'ml', + mt = 'mt', + gv = 'gv', + mi = 'mi', + mr = 'mr', + mn = 'mn', + ne = 'ne', + nd = 'nd', + se = 'se', + nb = 'nb', + nn = 'nn', + ny = 'ny', + or = 'or', + om = 'om', + os = 'os', + ps = 'ps', + fa = 'fa', + fa_AF = 'fa-AF', + pl = 'pl', + pt = 'pt', + pt_BR = 'pt-BR', + pt_PT = 'pt-PT', + pa = 'pa', + qu = 'qu', + ro = 'ro', + ro_MD = 'ro-MD', + rm = 'rm', + rn = 'rn', + ru = 'ru', + sm = 'sm', + sg = 'sg', + sa = 'sa', + gd = 'gd', + sr = 'sr', + sn = 'sn', + ii = 'ii', + sd = 'sd', + si = 'si', + sk = 'sk', + sl = 'sl', + so = 'so', + st = 'st', + es = 'es', + es_ES = 'es-ES', + es_MX = 'es-MX', + su = 'su', + sw = 'sw', + sw_CD = 'sw-CD', + sv = 'sv', + tg = 'tg', + ta = 'ta', + tt = 'tt', + te = 'te', + th = 'th', + bo = 'bo', + ti = 'ti', + to = 'to', + tr = 'tr', + tk = 'tk', + uk = 'uk', + ur = 'ur', + ug = 'ug', + uz = 'uz', + vi = 'vi', + vo = 'vo', + cy = 'cy', + fy = 'fy', + wo = 'wo', + xh = 'xh', + yi = 'yi', + yo = 'yo', + zu = 'zu', +} + +export enum CurrencyCode { + AED = 'AED', + AFN = 'AFN', + ALL = 'ALL', + AMD = 'AMD', + ANG = 'ANG', + AOA = 'AOA', + ARS = 'ARS', + AUD = 'AUD', + AWG = 'AWG', + AZN = 'AZN', + BAM = 'BAM', + BBD = 'BBD', + BDT = 'BDT', + BGN = 'BGN', + BHD = 'BHD', + BIF = 'BIF', + BMD = 'BMD', + BND = 'BND', + BOB = 'BOB', + BRL = 'BRL', + BSD = 'BSD', + BTN = 'BTN', + BWP = 'BWP', + BYN = 'BYN', + BZD = 'BZD', + CAD = 'CAD', + CDF = 'CDF', + CHF = 'CHF', + CLP = 'CLP', + CNY = 'CNY', + COP = 'COP', + CRC = 'CRC', + CUC = 'CUC', + CUP = 'CUP', + CVE = 'CVE', + CZK = 'CZK', + DJF = 'DJF', + DKK = 'DKK', + DOP = 'DOP', + DZD = 'DZD', + EGP = 'EGP', + ERN = 'ERN', + ETB = 'ETB', + EUR = 'EUR', + FJD = 'FJD', + FKP = 'FKP', + GBP = 'GBP', + GEL = 'GEL', + GHS = 'GHS', + GIP = 'GIP', + GMD = 'GMD', + GNF = 'GNF', + GTQ = 'GTQ', + GYD = 'GYD', + HKD = 'HKD', + HNL = 'HNL', + HRK = 'HRK', + HTG = 'HTG', + HUF = 'HUF', + IDR = 'IDR', + ILS = 'ILS', + INR = 'INR', + IQD = 'IQD', + IRR = 'IRR', + ISK = 'ISK', + JMD = 'JMD', + JOD = 'JOD', + JPY = 'JPY', + KES = 'KES', + KGS = 'KGS', + KHR = 'KHR', + KMF = 'KMF', + KPW = 'KPW', + KRW = 'KRW', + KWD = 'KWD', + KYD = 'KYD', + KZT = 'KZT', + LAK = 'LAK', + LBP = 'LBP', + LKR = 'LKR', + LRD = 'LRD', + LSL = 'LSL', + LYD = 'LYD', + MAD = 'MAD', + MDL = 'MDL', + MGA = 'MGA', + MKD = 'MKD', + MMK = 'MMK', + MNT = 'MNT', + MOP = 'MOP', + MRU = 'MRU', + MUR = 'MUR', + MVR = 'MVR', + MWK = 'MWK', + MXN = 'MXN', + MYR = 'MYR', + MZN = 'MZN', + NAD = 'NAD', + NGN = 'NGN', + NIO = 'NIO', + NOK = 'NOK', + NPR = 'NPR', + NZD = 'NZD', + OMR = 'OMR', + PAB = 'PAB', + PEN = 'PEN', + PGK = 'PGK', + PHP = 'PHP', + PKR = 'PKR', + PLN = 'PLN', + PYG = 'PYG', + QAR = 'QAR', + RON = 'RON', + RSD = 'RSD', + RUB = 'RUB', + RWF = 'RWF', + SAR = 'SAR', + SBD = 'SBD', + SCR = 'SCR', + SDG = 'SDG', + SEK = 'SEK', + SGD = 'SGD', + SHP = 'SHP', + SLL = 'SLL', + SOS = 'SOS', + SRD = 'SRD', + SSP = 'SSP', + STN = 'STN', + SVC = 'SVC', + SYP = 'SYP', + SZL = 'SZL', + THB = 'THB', + TJS = 'TJS', + TMT = 'TMT', + TND = 'TND', + TOP = 'TOP', + TRY = 'TRY', + TTD = 'TTD', + TWD = 'TWD', + TZS = 'TZS', + UAH = 'UAH', + UGX = 'UGX', + USD = 'USD', + UYU = 'UYU', + UZS = 'UZS', + VES = 'VES', + VND = 'VND', + VUV = 'VUV', + WST = 'WST', + XAF = 'XAF', + XCD = 'XCD', + XOF = 'XOF', + XPF = 'XPF', + YER = 'YER', + ZAR = 'ZAR', + ZMW = 'ZMW', + ZWL = 'ZWL', +} + +export function NumericCell(props: NumericCellProps) { + const { value, locale = LocaleCode.en_US, options } = props; + let displayValue = value?.toString() ?? value; + try { + displayValue = value?.toLocaleString?.(locale, options); + } catch (e) { + logging.error(e); + } + + return {displayValue}; +} + +export default NumericCell; diff --git a/superset-frontend/src/components/Table/cell-renderers/fixtures.ts b/superset-frontend/src/components/Table/cell-renderers/fixtures.ts new file mode 100644 index 000000000..9b2070b03 --- /dev/null +++ b/superset-frontend/src/components/Table/cell-renderers/fixtures.ts @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +export const exampleRow = { + key: 1, + buttonCell: 'Click Me', + textCell: 'Some text', + euroCell: 45.5, + dollarCell: 45.5, +}; diff --git a/superset-frontend/src/components/Table/index.tsx b/superset-frontend/src/components/Table/index.tsx new file mode 100644 index 000000000..d5f449c75 --- /dev/null +++ b/superset-frontend/src/components/Table/index.tsx @@ -0,0 +1,326 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useState, useEffect, useRef, ReactElement } from 'react'; +import { Table as AntTable, ConfigProvider } from 'antd'; +import type { + ColumnType, + ColumnGroupType, + TableProps as AntTableProps, +} from 'antd/es/table'; +import { t, useTheme, logging } from '@superset-ui/core'; +import Loading from 'src/components/Loading'; +import styled, { StyledComponent } from '@emotion/styled'; +import InteractiveTableUtils from './utils/InteractiveTableUtils'; + +export const SUPERSET_TABLE_COLUMN = 'superset/table-column'; +export interface TableDataType { + key: React.Key; +} + +export declare type ColumnsType = ( + | ColumnGroupType + | ColumnType +)[]; + +export enum SelectionType { + 'DISABLED' = 'disabled', + 'SINGLE' = 'single', + 'MULTI' = 'multi', +} + +export interface Locale { + /** + * Text contained within the Table UI. + */ + filterTitle: string; + filterConfirm: string; + filterReset: string; + filterEmptyText: string; + filterCheckall: string; + filterSearchPlaceholder: string; + emptyText: string; + selectAll: string; + selectInvert: string; + selectNone: string; + selectionAll: string; + sortTitle: string; + expand: string; + collapse: string; + triggerDesc: string; + triggerAsc: string; + cancelSort: string; +} + +export interface TableProps extends AntTableProps { + /** + * Data that will populate the each row and map to the column key. + */ + data: object[]; + /** + * Table column definitions. + */ + columns: ColumnsType; + /** + * Array of row keys to represent list of selected rows. + */ + selectedRows?: React.Key[]; + /** + * Callback function invoked when a row is selected by user. + */ + handleRowSelection?: Function; + /** + * Controls the size of the table. + */ + size: TableSize; + /** + * Adjusts the padding around elements for different amounts of spacing between elements. + */ + selectionType?: SelectionType; + /* + * Places table in visual loading state. Use while waiting to retrieve data or perform an async operation that will update the table. + */ + loading?: boolean; + /** + * Uses a sticky header which always displays when vertically scrolling the table. Default: true + */ + sticky?: boolean; + /** + * Controls if columns are resizable by user. + */ + resizable?: boolean; + /** + * EXPERIMENTAL: Controls if columns are re-orderable by user drag drop. + */ + reorderable?: boolean; + /** + * Default number of rows table will display per page of data. + */ + defaultPageSize?: number; + /** + * Array of numeric options for the number of rows table will display per page of data. + * The user can select from these options in the page size drop down menu. + */ + pageSizeOptions?: string[]; + /** + * Set table to display no data even if data has been provided + */ + hideData?: boolean; + /** + * emptyComponent + */ + emptyComponent?: ReactElement; + /** + * Enables setting the text displayed in various components and tooltips within the Table UI. + */ + locale?: Locale; + /** + * Restricts the visible height of the table and allows for internal scrolling within the table + * when the number of rows exceeds the visible space. + */ + height?: number; +} + +export enum TableSize { + SMALL = 'small', + MIDDLE = 'middle', +} + +const defaultRowSelection: React.Key[] = []; +// This accounts for the tables header and pagination if user gives table instance a height. this is a temp solution +const HEIGHT_OFFSET = 108; + +const StyledTable: StyledComponent = styled(AntTable)` + ${({ theme, height }) => ` + .ant-table-body { + overflow: scroll; + height: ${height ? `${height - HEIGHT_OFFSET}px` : undefined}; + } + + th.ant-table-cell { + font-weight: ${theme.typography.weights.bold}; + color: ${theme.colors.grayscale.dark1}; + user-select: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .ant-pagination-item-active { + border-color: ${theme.colors.primary.base}; + } + `} +`; + +const defaultLocale = { + filterTitle: t('Filter menu'), + filterConfirm: t('OK'), + filterReset: t('Reset'), + filterEmptyText: t('No filters'), + filterCheckall: t('Select all items'), + filterSearchPlaceholder: t('Search in filters'), + emptyText: t('No data'), + selectAll: t('Select current page'), + selectInvert: t('Invert current page'), + selectNone: t('Clear all data'), + selectionAll: t('Select all data'), + sortTitle: t('Sort'), + expand: t('Expand row'), + collapse: t('Collapse row'), + triggerDesc: t('Click to sort descending'), + triggerAsc: t('Click to sort ascending'), + cancelSort: t('Click to cancel sorting'), +}; + +const selectionMap = {}; +selectionMap[SelectionType.MULTI] = 'checkbox'; +selectionMap[SelectionType.SINGLE] = 'radio'; +selectionMap[SelectionType.DISABLED] = null; + +export function Table(props: TableProps) { + const { + data, + columns, + selectedRows = defaultRowSelection, + handleRowSelection, + size, + selectionType = SelectionType.DISABLED, + sticky = true, + loading = false, + resizable = false, + reorderable = false, + defaultPageSize = 15, + pageSizeOptions = ['5', '15', '25', '50', '100'], + hideData = false, + emptyComponent, + locale, + ...rest + } = props; + + const wrapperRef = useRef(null); + const [derivedColumns, setDerivedColumns] = useState(columns); + const [pageSize, setPageSize] = useState(defaultPageSize); + const [mergedLocale, setMergedLocale] = useState({ ...defaultLocale }); + const [selectedRowKeys, setSelectedRowKeys] = + useState(selectedRows); + const interactiveTableUtils = useRef(null); + + const onSelectChange = (newSelectedRowKeys: React.Key[]) => { + setSelectedRowKeys(newSelectedRowKeys); + handleRowSelection?.(newSelectedRowKeys); + }; + + const selectionTypeValue = selectionMap[selectionType]; + const rowSelection = { + type: selectionTypeValue, + selectedRowKeys, + onChange: onSelectChange, + }; + + const renderEmpty = () => + emptyComponent ??
{mergedLocale.emptyText}
; + + // Log use of experimental features + useEffect(() => { + if (reorderable === true) { + logging.warn( + 'EXPERIMENTAL FEATURE ENABLED: The "reorderable" prop of Table is experimental and NOT recommended for use in production deployments.', + ); + } + if (resizable === true) { + logging.warn( + 'EXPERIMENTAL FEATURE ENABLED: The "resizable" prop of Table is experimental and NOT recommended for use in production deployments.', + ); + } + }, [reorderable, resizable]); + + useEffect(() => { + let updatedLocale; + if (locale) { + // This spread allows for locale to only contain a subset of locale overrides on props + updatedLocale = { ...defaultLocale, ...locale }; + } else { + updatedLocale = { ...defaultLocale }; + } + setMergedLocale(updatedLocale); + }, [locale]); + + useEffect(() => { + if (interactiveTableUtils.current) { + interactiveTableUtils.current?.clearListeners(); + } + const table = wrapperRef.current?.getElementsByTagName('table')[0]; + if (table) { + interactiveTableUtils.current = new InteractiveTableUtils( + table, + derivedColumns, + setDerivedColumns, + ); + if (reorderable) { + interactiveTableUtils?.current?.initializeDragDropColumns( + reorderable, + table, + ); + } + if (resizable) { + interactiveTableUtils?.current?.initializeResizableColumns( + resizable, + table, + ); + } + } + return () => { + interactiveTableUtils?.current?.clearListeners?.(); + }; + /** + * We DO NOT want this effect to trigger when derivedColumns changes as it will break functionality + * The exclusion from the effect dependencies is intentional and should not be modified + */ + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [wrapperRef, reorderable, resizable, interactiveTableUtils]); + + const theme = useTheme(); + + return ( + +
+ }} + hasData={hideData ? false : data} + rowSelection={selectionTypeValue ? rowSelection : undefined} + columns={derivedColumns} + dataSource={hideData ? [undefined] : data} + size={size} + sticky={sticky} + pagination={{ + hideOnSinglePage: true, + pageSize, + pageSizeOptions, + onShowSizeChange: (page: number, size: number) => setPageSize(size), + }} + showSorterTooltip={false} + locale={mergedLocale} + theme={theme} + /> +
+
+ ); +} + +export default Table; diff --git a/superset-frontend/src/components/Table/sorters.test.ts b/superset-frontend/src/components/Table/sorters.test.ts new file mode 100644 index 000000000..80bc0a20c --- /dev/null +++ b/superset-frontend/src/components/Table/sorters.test.ts @@ -0,0 +1,100 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { alphabeticalSort, numericalSort } from './sorters'; + +const rows = [ + { + name: 'Deathstar Lamp', + category: 'Lamp', + cost: 75.99, + }, + { + name: 'Desk Lamp', + category: 'Lamp', + cost: 15.99, + }, + { + name: 'Bedside Lamp', + category: 'Lamp', + cost: 15.99, + }, + { name: 'Drafting Desk', category: 'Desk', cost: 125 }, + { name: 'Sit / Stand Desk', category: 'Desk', cost: 275.99 }, +]; + +/** + * NOTE: Sorters for antd table use < 0, 0, > 0 for sorting + * -1 or less means the first item comes after the second item + * 0 means the items sort values is equivalent + * 1 or greater means the first item comes before the second item + */ +test('alphabeticalSort sorts correctly', () => { + expect(alphabeticalSort('name', rows[0], rows[1])).toBe(-1); + expect(alphabeticalSort('name', rows[1], rows[0])).toBe(1); + expect(alphabeticalSort('category', rows[1], rows[0])).toBe(0); +}); + +test('numericalSort sorts correctly', () => { + expect(numericalSort('cost', rows[1], rows[2])).toBe(0); + expect(numericalSort('cost', rows[1], rows[0])).toBeLessThan(0); + expect(numericalSort('cost', rows[4], rows[1])).toBeGreaterThan(0); +}); + +/** + * We want to make sure our sorters do not throw runtime errors given bad inputs. + * Runtime Errors in a sorter will cause a catastrophic React lifecycle error and produce white screen of death + * In the case the sorter cannot perform the comparison it should return undefined and the next sort step will proceed without error + */ +test('alphabeticalSort bad inputs no errors', () => { + // @ts-ignore + expect(alphabeticalSort('name', null, null)).toBe(undefined); + // incorrect non-object values + // @ts-ignore + expect(alphabeticalSort('name', 3, [])).toBe(undefined); + // incorrect object values without specificed key + expect(alphabeticalSort('name', {}, {})).toBe(undefined); + // Object as value for name when it should be a string + expect( + alphabeticalSort( + 'name', + { name: { title: 'the name attribute should not be an object' } }, + { name: 'Doug' }, + ), + ).toBe(undefined); +}); + +test('numericalSort bad inputs no errors', () => { + // @ts-ignore + expect(numericalSort('name', undefined, undefined)).toBe(NaN); + // @ts-ignore + expect(numericalSort('name', null, null)).toBe(NaN); + // incorrect non-object values + // @ts-ignore + expect(numericalSort('name', 3, [])).toBe(NaN); + // incorrect object values without specified key + expect(numericalSort('name', {}, {})).toBe(NaN); + // Object as value for name when it should be a string + expect( + numericalSort( + 'name', + { name: { title: 'the name attribute should not be an object' } }, + { name: 'Doug' }, + ), + ).toBe(NaN); +}); diff --git a/superset-frontend/src/components/Table/sorters.ts b/superset-frontend/src/components/Table/sorters.ts new file mode 100644 index 000000000..3f06071aa --- /dev/null +++ b/superset-frontend/src/components/Table/sorters.ts @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @param key The name of the row's attribute used to compare values for alphabetical sorting + * @param a First row object to compare + * @param b Second row object to compare + * @returns number + */ +export const alphabeticalSort = (key: string, a: object, b: object): number => + a?.[key]?.localeCompare?.(b?.[key]); + +/** + * @param key The name of the row's attribute used to compare values for numerical sorting + * @param a First row object to compare + * @param b Second row object to compare + * @returns number + */ +export const numericalSort = (key: string, a: object, b: object): number => + a?.[key] - b?.[key]; diff --git a/superset-frontend/src/components/Table/utils/InteractiveTableUtils.ts b/superset-frontend/src/components/Table/utils/InteractiveTableUtils.ts new file mode 100644 index 000000000..94977413e --- /dev/null +++ b/superset-frontend/src/components/Table/utils/InteractiveTableUtils.ts @@ -0,0 +1,233 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import type { ColumnsType } from 'antd/es/table'; +import { SUPERSET_TABLE_COLUMN } from 'src/components/Table'; +import { withinRange } from './utils'; + +interface IInteractiveColumn extends HTMLElement { + mouseDown: boolean; + oldX: number; + oldWidth: number; + draggable: boolean; +} +export default class InteractiveTableUtils { + tableRef: HTMLTableElement | null; + + columnRef: IInteractiveColumn | null; + + setDerivedColumns: Function; + + isDragging: boolean; + + resizable: boolean; + + reorderable: boolean; + + derivedColumns: ColumnsType; + + RESIZE_INDICATOR_THRESHOLD: number; + + constructor( + tableRef: HTMLTableElement, + derivedColumns: ColumnsType, + setDerivedColumns: Function, + ) { + this.setDerivedColumns = setDerivedColumns; + this.tableRef = tableRef; + this.isDragging = false; + this.RESIZE_INDICATOR_THRESHOLD = 8; + this.resizable = false; + this.reorderable = false; + this.derivedColumns = [...derivedColumns]; + document.addEventListener('mouseup', this.handleMouseup); + } + + clearListeners = () => { + document.removeEventListener('mouseup', this.handleMouseup); + this.initializeResizableColumns(false, this.tableRef); + this.initializeDragDropColumns(false, this.tableRef); + }; + + setTableRef = (table: HTMLTableElement) => { + this.tableRef = table; + }; + + getColumnIndex = (): number => { + let index = -1; + const parent = this.columnRef?.parentNode; + if (parent) { + index = Array.prototype.indexOf.call(parent.children, this.columnRef); + } + return index; + }; + + handleColumnDragStart = (ev: DragEvent): void => { + const target = ev?.currentTarget as IInteractiveColumn; + if (target) { + this.columnRef = target; + } + this.isDragging = true; + const index = this.getColumnIndex(); + const columnData = this.derivedColumns[index]; + const dragData = { index, columnData }; + ev?.dataTransfer?.setData(SUPERSET_TABLE_COLUMN, JSON.stringify(dragData)); + }; + + handleDragDrop = (ev: DragEvent): void => { + const data = ev.dataTransfer?.getData?.(SUPERSET_TABLE_COLUMN); + if (data) { + ev.preventDefault(); + const parent = (ev.currentTarget as HTMLElement) + ?.parentNode as HTMLElement; + const dropIndex = Array.prototype.indexOf.call( + parent.children, + ev.currentTarget, + ); + const dragIndex = this.getColumnIndex(); + const columnsCopy = [...this.derivedColumns]; + const removedItem = columnsCopy.slice(dragIndex, dragIndex + 1); + columnsCopy.splice(dragIndex, 1); + columnsCopy.splice(dropIndex, 0, removedItem[0]); + this.derivedColumns = [...columnsCopy]; + this.setDerivedColumns(columnsCopy); + } + }; + + allowDrop = (ev: DragEvent): void => { + ev.preventDefault(); + }; + + handleMouseDown = (event: MouseEvent) => { + const target = event?.currentTarget as IInteractiveColumn; + if (target) { + this.columnRef = target; + if ( + event && + withinRange( + event.offsetX, + target.offsetWidth, + this.RESIZE_INDICATOR_THRESHOLD, + ) + ) { + target.mouseDown = true; + target.oldX = event.x; + target.oldWidth = target.offsetWidth; + target.draggable = false; + } else if (this.reorderable) { + target.draggable = true; + } + } + }; + + handleMouseMove = (event: MouseEvent) => { + if (this.resizable === true && !this.isDragging) { + const target = event.currentTarget as IInteractiveColumn; + if ( + event && + withinRange( + event.offsetX, + target.offsetWidth, + this.RESIZE_INDICATOR_THRESHOLD, + ) + ) { + target.style.cursor = 'col-resize'; + } else { + target.style.cursor = 'default'; + } + + const column = this.columnRef; + if (column?.mouseDown) { + let width = column.oldWidth; + const diff = event.x - column.oldX; + if (column.oldWidth + (event.x - column.oldX) > 0) { + width = column.oldWidth + diff; + } + const colIndex = this.getColumnIndex(); + if (!Number.isNaN(colIndex)) { + const columnDef = { ...this.derivedColumns[colIndex] }; + columnDef.width = width; + this.derivedColumns[colIndex] = columnDef; + this.setDerivedColumns([...this.derivedColumns]); + } + } + } + }; + + handleMouseup = () => { + if (this.columnRef) { + this.columnRef.mouseDown = false; + this.columnRef.style.cursor = 'default'; + this.columnRef.draggable = false; + } + this.isDragging = false; + }; + + initializeResizableColumns = ( + resizable = false, + table: HTMLTableElement | null, + ) => { + this.tableRef = table; + const header: HTMLTableRowElement | undefined = this.tableRef?.rows?.[0]; + if (header) { + const { cells } = header; + const len = cells.length; + for (let i = 0; i < len; i += 1) { + const cell = cells[i]; + if (resizable === true) { + this.resizable = true; + cell.addEventListener('mousedown', this.handleMouseDown); + cell.addEventListener('mousemove', this.handleMouseMove, true); + } else { + this.resizable = false; + cell.removeEventListener('mousedown', this.handleMouseDown); + cell.removeEventListener('mousemove', this.handleMouseMove, true); + } + } + } + }; + + initializeDragDropColumns = ( + reorderable = false, + table: HTMLTableElement | null, + ) => { + this.tableRef = table; + const header: HTMLTableRowElement | undefined = this.tableRef?.rows?.[0]; + if (header) { + const { cells } = header; + const len = cells.length; + for (let i = 0; i < len; i += 1) { + const cell = cells[i]; + if (reorderable === true) { + this.reorderable = true; + cell.addEventListener('mousedown', this.handleMouseDown); + cell.addEventListener('dragover', this.allowDrop); + cell.addEventListener('dragstart', this.handleColumnDragStart); + cell.addEventListener('drop', this.handleDragDrop); + } else { + this.reorderable = false; + cell.draggable = false; + cell.removeEventListener('mousedown', this.handleMouseDown); + cell.removeEventListener('dragover', this.allowDrop); + cell.removeEventListener('dragstart', this.handleColumnDragStart); + cell.removeEventListener('drop', this.handleDragDrop); + } + } + } + }; +} diff --git a/superset-frontend/src/components/Table/utils/utils.test.ts b/superset-frontend/src/components/Table/utils/utils.test.ts new file mode 100644 index 000000000..eff50f158 --- /dev/null +++ b/superset-frontend/src/components/Table/utils/utils.test.ts @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { withinRange } from './utils'; + +test('withinRange supported positive numbers', () => { + // Valid inputs within range + expect(withinRange(50, 60, 16)).toBeTruthy(); + + // Valid inputs outside of range + expect(withinRange(40, 60, 16)).toBeFalsy(); +}); + +test('withinRange unsupported negative numbers', () => { + // Negative numbers not supported + expect(withinRange(65, 60, -16)).toBeFalsy(); + expect(withinRange(-60, -65, 16)).toBeFalsy(); + expect(withinRange(-60, -65, 16)).toBeFalsy(); + expect(withinRange(-60, 65, 16)).toBeFalsy(); +}); + +test('withinRange invalid inputs', () => { + // Invalid inputs should return falsy and not throw an error + // We need ts-ignore here to be able to pass invalid values and pass linting + // @ts-ignore + expect(withinRange(null, 60, undefined)).toBeFalsy(); + // @ts-ignore + expect(withinRange([], 'hello', {})).toBeFalsy(); + // @ts-ignore + expect(withinRange([], undefined, {})).toBeFalsy(); + // @ts-ignore + expect(withinRange([], 'hello', {})).toBeFalsy(); +}); diff --git a/superset-frontend/src/components/Table/utils/utils.ts b/superset-frontend/src/components/Table/utils/utils.ts new file mode 100644 index 000000000..5b4e4d13b --- /dev/null +++ b/superset-frontend/src/components/Table/utils/utils.ts @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Method to check if a number is within inclusive range between a maximum value minus a threshold + * Invalid non numeric inputs will not error, but will return false + * + * @param value number coordinate to determine if it is within bounds of the targetCoordinate - threshold. Must be positive and less than maximum. + * @param maximum number max value for the test range. Must be positive and greater than value + * @param threshold number values to determine a range from maximum - threshold. Must be positive and greater than zero. + * @returns boolean + */ +export const withinRange = ( + value: number, + maximum: number, + threshold: number, +): boolean => { + let within = false; + const diff = maximum - value; + if (diff > 0 && diff <= threshold) { + within = true; + } + return within; +}; diff --git a/superset-frontend/src/components/atomic-design.png b/superset-frontend/src/components/atomic-design.png new file mode 100644 index 0000000000000000000000000000000000000000..e44c5f34a54ebbdd26a30adc43339e40b954914c GIT binary patch literal 163100 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%0DCrlvHPL7w{ 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 Zw1XC2;iH1K&DRJYZB2vwW$HFz{{!AVv(Nwl literal 0 HcmV?d00001 diff --git a/superset-frontend/src/types/files.d.ts b/superset-frontend/src/types/files.d.ts index c694d13cf..c4f304b57 100644 --- a/superset-frontend/src/types/files.d.ts +++ b/superset-frontend/src/types/files.d.ts @@ -18,3 +18,4 @@ */ declare module '*.svg'; +declare module '*.gif'; diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js index 10284097e..9994b1dd7 100644 --- a/superset-frontend/webpack.config.js +++ b/superset-frontend/webpack.config.js @@ -447,7 +447,7 @@ const config = { type: 'asset/resource', }, { - test: /\.(stories|story)\.mdx$/, + test: /\.mdx$/, use: [ { loader: 'babel-loader',