From 26627aba9fe253b65698c61fbc272771e7b48ff5 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Feria Vila <2582866+carlosthe19916@users.noreply.github.com> Date: Thu, 18 Nov 2021 20:52:32 +0100 Subject: [PATCH] Add components --- .../SimplePlaceholder/SimplePlaceholder.tsx | 17 +++ src/components/SimplePlaceholder/index.ts | 1 + src/components/SimpleSelect/SimpleSelect.tsx | 62 ++++++++++ src/components/SimpleSelect/index.ts | 1 + .../SimplePagination.tsx | 58 +++++++++ .../SimpleStateError.tsx | 24 ++++ .../SimpleStateNoData.tsx | 21 ++++ .../SimpleStateNoResults.tsx | 25 ++++ .../SimpleTableWithToolbar/SimpleTable.tsx | 112 ++++++++++++++++++ .../SimpleTableWithToolbar.tsx | 85 +++++++++++++ .../SimpleTableWithToolbar/index.ts | 3 + src/index.ts | 3 + 12 files changed, 412 insertions(+) create mode 100644 src/components/SimplePlaceholder/SimplePlaceholder.tsx create mode 100644 src/components/SimplePlaceholder/index.ts create mode 100644 src/components/SimpleSelect/SimpleSelect.tsx create mode 100644 src/components/SimpleSelect/index.ts create mode 100644 src/components/SimpleTableWithToolbar/SimplePagination.tsx create mode 100644 src/components/SimpleTableWithToolbar/SimpleStateError.tsx create mode 100644 src/components/SimpleTableWithToolbar/SimpleStateNoData.tsx create mode 100644 src/components/SimpleTableWithToolbar/SimpleStateNoResults.tsx create mode 100644 src/components/SimpleTableWithToolbar/SimpleTable.tsx create mode 100644 src/components/SimpleTableWithToolbar/SimpleTableWithToolbar.tsx create mode 100644 src/components/SimpleTableWithToolbar/index.ts diff --git a/src/components/SimplePlaceholder/SimplePlaceholder.tsx b/src/components/SimplePlaceholder/SimplePlaceholder.tsx new file mode 100644 index 0000000..c3779fe --- /dev/null +++ b/src/components/SimplePlaceholder/SimplePlaceholder.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Bullseye, Spinner } from '@patternfly/react-core'; + +export const SimplePlaceholder: React.FC = () => { + return ( + +
+
+ +
+
+

Loading...

+
+
+
+ ); +}; diff --git a/src/components/SimplePlaceholder/index.ts b/src/components/SimplePlaceholder/index.ts new file mode 100644 index 0000000..4204001 --- /dev/null +++ b/src/components/SimplePlaceholder/index.ts @@ -0,0 +1 @@ +export * from './SimplePlaceholder'; diff --git a/src/components/SimpleSelect/SimpleSelect.tsx b/src/components/SimpleSelect/SimpleSelect.tsx new file mode 100644 index 0000000..c5382c8 --- /dev/null +++ b/src/components/SimpleSelect/SimpleSelect.tsx @@ -0,0 +1,62 @@ +import React, { useState } from 'react'; + +import { + Select, + SelectOption, + SelectOptionObject, + SelectOptionProps, + SelectProps, +} from '@patternfly/react-core'; + +export interface OptionWithValue extends SelectOptionObject { + value: T; + props?: Partial; // Extra props for , e.g. children, className +} + +type OptionLike = string | SelectOptionObject | OptionWithValue; + +export interface ISimpleSelectProps + extends Omit< + SelectProps, + 'onChange' | 'isOpen' | 'onToggle' | 'onSelect' | 'selections' | 'value' + > { + 'aria-label': string; + onChange: (selection: OptionLike) => void; + options: OptionLike[]; + value?: OptionLike | OptionLike[]; +} + +export const SimpleSelect: React.FC = ({ + onChange, + options, + value, + placeholderText = 'Select...', + + ...props +}) => { + const [isOpen, setIsOpen] = useState(false); + + return ( + + ); +}; diff --git a/src/components/SimpleSelect/index.ts b/src/components/SimpleSelect/index.ts new file mode 100644 index 0000000..d44fc8e --- /dev/null +++ b/src/components/SimpleSelect/index.ts @@ -0,0 +1 @@ +export * from './SimpleSelect'; diff --git a/src/components/SimpleTableWithToolbar/SimplePagination.tsx b/src/components/SimpleTableWithToolbar/SimplePagination.tsx new file mode 100644 index 0000000..29ea4b4 --- /dev/null +++ b/src/components/SimpleTableWithToolbar/SimplePagination.tsx @@ -0,0 +1,58 @@ +import React from 'react'; + +import { Pagination, PaginationVariant, ToggleTemplate } from '@patternfly/react-core'; + +export interface ISimplePaginationProps { + count: number; + params: { + perPage?: number; + page?: number; + }; + + isTop?: boolean; + isCompact?: boolean; + perPageOptions?: number[]; + onChange: ({ page, perPage }: { page: number; perPage: number }) => void; +} + +export const SimplePagination: React.FC = ({ + count, + params, + isTop, + isCompact, + perPageOptions, + onChange, +}) => { + const mapPerPageOptions = (options: number[]) => { + return options.map((option) => ({ + title: String(option), + value: option, + })); + }; + + const getPerPage = () => { + return params.perPage || 10; + }; + + return ( + { + onChange({ page, perPage: getPerPage() }); + }} + onSetPage={(_, page) => { + onChange({ page, perPage: getPerPage() }); + }} + onPerPageSelect={(_, perPage) => { + onChange({ page: 1, perPage }); + }} + isCompact={isTop || isCompact} + widgetId="pagination-options-menu" + variant={isTop ? PaginationVariant.top : PaginationVariant.bottom} + perPageOptions={mapPerPageOptions(perPageOptions || [10, 20, 50, 100])} + toggleTemplate={(props) => } + /> + ); +}; diff --git a/src/components/SimpleTableWithToolbar/SimpleStateError.tsx b/src/components/SimpleTableWithToolbar/SimpleStateError.tsx new file mode 100644 index 0000000..e75a625 --- /dev/null +++ b/src/components/SimpleTableWithToolbar/SimpleStateError.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { + EmptyState, + EmptyStateIcon, + EmptyStateVariant, + Title, + EmptyStateBody, +} from '@patternfly/react-core'; +import { ExclamationCircleIcon } from '@patternfly/react-icons'; +import { global_danger_color_200 as globalDangerColor200 } from '@patternfly/react-tokens'; + +export const SimpleStateError: React.FC = () => { + return ( + + + + Unable to connect + + + There was an error retrieving data. Check your connection and try again. + + + ); +}; diff --git a/src/components/SimpleTableWithToolbar/SimpleStateNoData.tsx b/src/components/SimpleTableWithToolbar/SimpleStateNoData.tsx new file mode 100644 index 0000000..c43c96a --- /dev/null +++ b/src/components/SimpleTableWithToolbar/SimpleStateNoData.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { + EmptyState, + EmptyStateBody, + EmptyStateIcon, + EmptyStateVariant, + Title, +} from '@patternfly/react-core'; +import { CubesIcon } from '@patternfly/react-icons'; + +export const SimpleStateNoData: React.FC = () => { + return ( + + + + No data available + + No data available to be shown here. + + ); +}; diff --git a/src/components/SimpleTableWithToolbar/SimpleStateNoResults.tsx b/src/components/SimpleTableWithToolbar/SimpleStateNoResults.tsx new file mode 100644 index 0000000..f856e79 --- /dev/null +++ b/src/components/SimpleTableWithToolbar/SimpleStateNoResults.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +import { + EmptyState, + EmptyStateBody, + EmptyStateIcon, + EmptyStateVariant, + Title, +} from '@patternfly/react-core'; +import { SearchIcon } from '@patternfly/react-icons'; + +export const SimpleStateNoResults: React.FC = () => { + return ( + + + + No results found + + + No results match the filter criteria. Remove all filters or clear all filters to show + results. + + + ); +}; diff --git a/src/components/SimpleTableWithToolbar/SimpleTable.tsx b/src/components/SimpleTableWithToolbar/SimpleTable.tsx new file mode 100644 index 0000000..e7a5c60 --- /dev/null +++ b/src/components/SimpleTableWithToolbar/SimpleTable.tsx @@ -0,0 +1,112 @@ +import React from 'react'; +import { Bullseye, Spinner, Skeleton } from '@patternfly/react-core'; +import { Table, TableHeader, TableBody, IRow, TableProps } from '@patternfly/react-table'; + +import { SimpleStateNoData } from './SimpleStateNoData'; +import { SimpleStateNoResults } from './SimpleStateNoResults'; +import { SimpleStateError } from './SimpleStateError'; + +export interface ISimpleTableProps extends TableProps { + isLoading: boolean; + loadingVariant?: 'skeleton' | 'spinner' | 'none'; + fetchError?: any; + + filtersApplied: boolean; + noDataState?: any; + noSearchResultsState?: any; + errorState?: any; +} + +export const SimpleTable: React.FC = ({ + cells, + rows, + 'aria-label': ariaLabel = 'main-table', + + isLoading, + fetchError, + loadingVariant = 'skeleton', + + filtersApplied, + noDataState, + noSearchResultsState, + errorState, + + ...rest +}) => { + if (isLoading && loadingVariant !== 'none') { + let rows: IRow[] = []; + if (loadingVariant === 'skeleton') { + rows = [...Array(10)].map(() => { + return { + cells: [...Array(cells.length)].map(() => ({ + title: , + })), + }; + }); + } else if (loadingVariant === 'spinner') { + rows = [ + { + heightAuto: true, + cells: [ + { + props: { colSpan: 8 }, + title: ( + + + + ), + }, + ], + }, + ]; + } else { + throw new Error('Can not determine the loading state of table'); + } + + return ( + + + +
+ ); + } + + if (fetchError) { + return ( + <> + + + +
+ {errorState ? errorState : } + + ); + } + + if (rows.length === 0) { + return filtersApplied ? ( + <> + + + +
+ {noSearchResultsState ? noSearchResultsState : } + + ) : ( + <> + + + +
+ {noDataState ? noDataState : } + + ); + } + + return ( + + + +
+ ); +}; diff --git a/src/components/SimpleTableWithToolbar/SimpleTableWithToolbar.tsx b/src/components/SimpleTableWithToolbar/SimpleTableWithToolbar.tsx new file mode 100644 index 0000000..ae518c8 --- /dev/null +++ b/src/components/SimpleTableWithToolbar/SimpleTableWithToolbar.tsx @@ -0,0 +1,85 @@ +import React from 'react'; + +import { + Toolbar, + ToolbarContent, + ToolbarItem, + ToolbarItemVariant, + ToolbarToggleGroup, +} from '@patternfly/react-core'; + +import { FilterIcon } from '@patternfly/react-icons'; + +import { SimpleTable, ISimpleTableProps } from './SimpleTable'; +import { SimplePagination } from './SimplePagination'; + +export interface ISimpleTableWithToolbarProps extends ISimpleTableProps { + totalCount: number; + + currentPage: { + page?: number; + perPage?: number; + }; + onPageChange: ({ page, perPage }: { page: number; perPage: number }) => void; + + hasTopPagination?: boolean; + hasBottomPagination?: boolean; + + toolbarBulkSelector?: any; + toolbarToggle?: any; + toolbarActions?: any; + toolbarClearAllFilters?: () => void; +} + +export const SimpleTableWithToolbar: React.FC = ({ + totalCount, + currentPage, + onPageChange, + + hasTopPagination = false, + hasBottomPagination = false, + + toolbarBulkSelector, + toolbarToggle, + toolbarActions, + toolbarClearAllFilters, + + ...rest +}) => { + return ( +
+ + + {toolbarBulkSelector} + {toolbarToggle && ( + } breakpoint="xl"> + {toolbarToggle} + + )} + {toolbarActions} + {hasTopPagination && ( + + + + )} + + + + {hasBottomPagination && ( + + )} +
+ ); +}; diff --git a/src/components/SimpleTableWithToolbar/index.ts b/src/components/SimpleTableWithToolbar/index.ts new file mode 100644 index 0000000..f414296 --- /dev/null +++ b/src/components/SimpleTableWithToolbar/index.ts @@ -0,0 +1,3 @@ +export * from './SimplePagination'; +export * from './SimpleTableWithToolbar'; +export * from './SimpleTable'; diff --git a/src/index.ts b/src/index.ts index 2c2a8f1..1f1db21 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,6 @@ +export * from './components/SimplePlaceholder'; +export * from './components/SimpleSelect'; +export * from './components/SimpleTableWithToolbar'; export * from './components/StatusIcon'; export * from './hooks/useDelete';