Skip to content

Commit

Permalink
feat: 🎸 [Table] Added TableActionPosition icon
Browse files Browse the repository at this point in the history
Added possibility to have icon in Table toolbar, passing
TableActionPosition.icon

✅ Closes: 103
  • Loading branch information
luciob committed Sep 10, 2021
1 parent bae2057 commit 71e4c4b
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 27 deletions.
44 changes: 44 additions & 0 deletions src/components/Table/components/ToolbarAction/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { CSSProperties, FC, useCallback, useMemo } from "react";

import { Icons } from "../../../../types/Icon";
import { ITableToolbarAction, TableActionPosition } from "../../../../types/Table";
import { getComposedDataCy } from "../../../../utils";
import Button from "../../../Button";
import IconButton from "../../../IconButton";

const TableToolbarAction: FC<ITableToolbarAction> = ({
callback,
data,
dataCy: externalDataCy,
disabled,
icon: externalIcon,
index,
label,
position,
subpart,
}) => {
const dataCy = useMemo(() => getComposedDataCy(externalDataCy, subpart, label), [externalDataCy, subpart, label]);

const onClick = useCallback(() => callback(data), [callback, data]);

const secondary = useMemo(() => position === TableActionPosition.icon, [position]);

const style = useMemo((): CSSProperties => ({ marginLeft: index > 0 ? "8px" : "none" }), [index]);

if (secondary) {
return (
<IconButton
dataCy={dataCy}
disabled={disabled}
icon={externalIcon || Icons.settings}
onClick={onClick}
style={style}
/>
);
}

const icon = typeof externalIcon === "string" ? { name: externalIcon } : { component: externalIcon };
return <Button dataCy={dataCy} disabled={disabled} icon={icon} label={label} onClick={onClick} style={style} />;
};

export default TableToolbarAction;
75 changes: 48 additions & 27 deletions src/components/Table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { CSSProperties, FC, Fragment, useCallback, useEffect, useMemo, useState } from "react";
import React, { CSSProperties, FC, useCallback, useEffect, useMemo, useState } from "react";
import {
CircularProgress as MUICircularProgress,
Paper as MUIPaper,
Expand All @@ -14,18 +14,17 @@ import {

import { CheckboxSize } from "../../types/Checkbox";
import { Icons, IconSize } from "../../types/Icon";
import { ITable, ITableOnSortCallback, TableActionPosition } from "../../types/Table";
import { ITable, ITableAction, ITableOnSortCallback, TableActionPosition } from "../../types/Table";
import { TypographyVariants } from "../../types/Typography";
import { getComposedDataCy, getObjectProperty, suppressEvent } from "../../utils";
import localized, { ILocalizableProperty } from "../../utils/hocs/localized";
import Button from "../Button";
import Checkbox from "../Checkbox";
import IconButton from "../IconButton";
import Spacer from "../Spacer";
import Typography from "../Typography";

import TableHeadCell from "./components/HeadCell";
import TablePagination from "./components/Pagination";
import TableToolbarAction from "./components/ToolbarAction";
import { CHECKBOX_SELECTION_PATH, TOOLBAR_DIMENSION } from "./utils";

const CHECKBOX_SELECTION_WIDTH = 36;
Expand Down Expand Up @@ -171,16 +170,40 @@ const Table: FC<ITable> = ({
];
}

const defaultActions = actions.filter(({ position }) => !position || position === TableActionPosition.default);
const rowActions = actions.filter(({ position }) => position === TableActionPosition.row);
const selectionActions = actions.filter(({ position }) => position === TableActionPosition.selection);
let rowActions: ITableAction[] = [];
let selectionActions: ITableAction[] = [];
let toolbarActions: ITableAction[] = [];

actions.forEach((action) => {
const { position } = action;
switch (position) {
case TableActionPosition.default:
case TableActionPosition.icon:
toolbarActions = [...toolbarActions, { ...action }];
break;
case TableActionPosition.row:
rowActions = [...rowActions, { ...action }];
break;
case TableActionPosition.selection:
selectionActions = [...selectionActions, { ...action }];
break;
default:
toolbarActions = [...toolbarActions, { ...action, position: TableActionPosition.default }];
break;
}
});

if (!!rowActions.length) {
columns = [
...columns,
{ label: "", path: ROW_ACTION_PATH, width: `${ROW_ACTION_DIMENSION * rowActions.length}px` },
];
}

const defaultActions = toolbarActions.sort(
({ position }, { position: another }) => -1 * position!.localeCompare(another!)
);

return { defaultActions, columns, rowActions, selectionActions };
}, [
actions,
Expand All @@ -193,6 +216,14 @@ const Table: FC<ITable> = ({
onSelectionChange,
]);

const onCallbackData = useMemo(
() =>
rows
.filter((_, index) => selectedRowsIndexes.includes(index))
.map(({ __mosaicTableId, ...internalRow }) => ({ ...internalRow })),
[rows, selectedRowsIndexes]
);

const onSortWrapper: ITableOnSortCallback = useCallback(
(path, ordering) => {
setSorting({ path, ordering });
Expand Down Expand Up @@ -249,26 +280,16 @@ const Table: FC<ITable> = ({
{!selectedRowsIndexes.length ? title : `${selectedRowsIndexes.length} row(s) selected`}
</Typography>
<div style={{ alignItems: "center", display: "flex", justifyContent: "center" }}>
{(!selectedRowsIndexes.length ? defaultActions : selectionActions).map(
({ callback, disabled, icon, label }, index) => (
<Fragment key={`action-${label}`}>
{index > 0 && <Spacer />}
<Button
dataCy={getComposedDataCy(dataCy, SUBPARTS_MAP.action, label)}
disabled={disabled}
icon={typeof icon === "string" ? { name: icon } : { component: icon }}
label={label}
onClick={() =>
callback(
rows
.filter((_, index) => selectedRowsIndexes.includes(index))
.map(({ __mosaicTableId, ...internalRow }) => ({ ...internalRow }))
)
}
/>
</Fragment>
)
)}
{(!selectedRowsIndexes.length ? defaultActions : selectionActions).map((action, index) => (
<TableToolbarAction
{...action}
key={`action-${action.label}`}
data={onCallbackData}
dataCy={dataCy}
index={index}
subpart={SUBPARTS_MAP.action}
/>
))}
</div>
</MUIToolbar>
)}
Expand Down
6 changes: 6 additions & 0 deletions src/types/Table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IPartialIconUtilizer } from "./Icon";

export enum TableActionPosition {
default = "toolbar",
icon = "icon",
row = "row",
selection = "toolbarOnSelect",
}
Expand All @@ -18,6 +19,11 @@ export interface ITableAction extends IPartialIconUtilizer {
position?: TableActionPosition;
}

export interface ITableToolbarAction extends ISubpartItem, ITableAction {
data: object | object[];
index: number;
}

export interface ITableColumn {
label?: string;
padding?: "checkbox" | "normal" | "default" | "none";
Expand Down

0 comments on commit 71e4c4b

Please sign in to comment.