Add hover tooltip on sorting disabled columns (#1811)

* Add hover tooltip on sorting disabled columns in lists (#1784)

* Update macaw

* Add TooltipTableCellHeader component

* Add filterDependency type to lists

* Add tooltip to conditional columns in Voucher List

* Add tooltip to conditional columns in Sale List

* Add tooltip to conditional columns in Collection List

* Add tooltip to conditional columns in Product List

* Update snapshots

* Improve component clarity

* Change TableCellHeader to React.forwardRef component

* Change TooltipTableCellHeader to use TableCellHeader

* Remove RefTableCellHeader

* Bump macaw

* Update snapshots

* Remove merge conflict leftovers

* Add tooltip header to gift card list

* Refactor gift card list tooltip

Co-authored-by: Wojciech <wojciech.mista@hotmail.com>
This commit is contained in:
Michał Droń 2022-02-02 09:48:12 +01:00 committed by GitHub
parent f9e1bb0569
commit 519b816afa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 211 additions and 99 deletions

View file

@ -2501,6 +2501,9 @@
"src_dot_components_dot_Timeline_dot_3028189627": { "src_dot_components_dot_Timeline_dot_3028189627": {
"string": "Leave your note here..." "string": "Leave your note here..."
}, },
"src_dot_components_dot_TooltipTableCellHeader_dot_noFilterSelected": {
"string": "Sorting by this column requires active filter: {filterName}"
},
"src_dot_components_dot_UserChip_dot_21332146": { "src_dot_components_dot_UserChip_dot_21332146": {
"context": "button", "context": "button",
"string": "Log out" "string": "Log out"

View file

@ -9,12 +9,14 @@ import Skeleton from "@saleor/components/Skeleton";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader";
import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import { maybe, renderCollection } from "@saleor/misc"; import { maybe, renderCollection } from "@saleor/misc";
import { ChannelProps, ListActions, ListProps, SortPage } from "@saleor/types"; import { ChannelProps, ListActions, ListProps, SortPage } from "@saleor/types";
import { getArrowDirection } from "@saleor/utils/sort"; import { getArrowDirection } from "@saleor/utils/sort";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { CollectionList_collections_edges_node } from "../../types/CollectionList"; import { CollectionList_collections_edges_node } from "../../types/CollectionList";
import { messages } from "./messages"; import { messages } from "./messages";
@ -73,10 +75,12 @@ const CollectionList: React.FC<CollectionListProps> = props => {
selectedChannelId, selectedChannelId,
toggle, toggle,
toggleAll, toggleAll,
toolbar toolbar,
filterDependency
} = props; } = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl();
return ( return (
<ResponsiveTable> <ResponsiveTable>
@ -111,7 +115,7 @@ const CollectionList: React.FC<CollectionListProps> = props => {
> >
<FormattedMessage defaultMessage="No. of Products" /> <FormattedMessage defaultMessage="No. of Products" />
</TableCellHeader> </TableCellHeader>
<TableCellHeader <TooltipTableCellHeader
direction={ direction={
sort.sort === CollectionListUrlSortField.available sort.sort === CollectionListUrlSortField.available
? getArrowDirection(sort.asc) ? getArrowDirection(sort.asc)
@ -125,12 +129,15 @@ const CollectionList: React.FC<CollectionListProps> = props => {
!!selectedChannelId !!selectedChannelId
) )
} }
tooltip={intl.formatMessage(commonTooltipMessages.noFilterSelected, {
filterName: filterDependency.label
})}
> >
<FormattedMessage <FormattedMessage
defaultMessage="Availability" defaultMessage="Availability"
description="collection availability" description="collection availability"
/> />
</TableCellHeader> </TooltipTableCellHeader>
</TableHead> </TableHead>
<TableFooter> <TableFooter>
<TableRow> <TableRow>

View file

@ -1,6 +1,7 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import { CollectionListUrlSortField } from "@saleor/collections/urls"; import { CollectionListUrlSortField } from "@saleor/collections/urls";
import { Container } from "@saleor/components/Container"; import { Container } from "@saleor/components/Container";
import { getByName } from "@saleor/components/Filter/utils";
import FilterBar from "@saleor/components/FilterBar"; import FilterBar from "@saleor/components/FilterBar";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
@ -57,6 +58,8 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
const intl = useIntl(); const intl = useIntl();
const filterStructure = createFilterStructure(intl, filterOpts); const filterStructure = createFilterStructure(intl, filterOpts);
const filterDependency = filterStructure.find(getByName("channel"));
return ( return (
<Container> <Container>
<PageHeader title={intl.formatMessage(sectionNames.collections)}> <PageHeader title={intl.formatMessage(sectionNames.collections)}>
@ -97,6 +100,7 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
disabled={disabled} disabled={disabled}
channelsCount={channelsCount} channelsCount={channelsCount}
selectedChannelId={selectedChannelId} selectedChannelId={selectedChannelId}
filterDependency={filterDependency}
{...listProps} {...listProps}
/> />
</Card> </Card>

View file

@ -63,61 +63,64 @@ export interface TableCellHeaderProps extends TableCellProps {
disabled?: boolean; disabled?: boolean;
} }
const TableCellHeader: React.FC<TableCellHeaderProps> = props => { const TableCellHeader = React.forwardRef<unknown, TableCellHeaderProps>(
const classes = useStyles(props); (props, ref) => {
const { const classes = useStyles(props);
arrowPosition, const {
children, arrowPosition,
className, children,
direction, className,
textAlign, direction,
disabled = false, textAlign,
onClick, disabled = false,
title, onClick,
...rest title,
} = props; ...rest
} = props;
return ( return (
<TableCell <TableCell
{...rest} {...rest}
onClick={e => { innerRef={ref}
if (disabled || !onClick) { onClick={e => {
e.preventDefault(); if (disabled || !onClick) {
} else { e.preventDefault();
onClick(e); } else {
} onClick(e);
}} }
className={classNames(classes.root, className, { }}
[classes.disabled]: disabled, className={classNames(classes.root, className, {
[classes.notSortable]: !onClick [classes.disabled]: disabled,
})} [classes.notSortable]: !onClick
>
<div
className={classNames(classes.labelContainer, {
[classes.labelContainerActive]: !!direction && !!arrowPosition,
[classes.labelContainerCenter]: textAlign === "center",
[classes.labelContainerRight]: textAlign === "right"
})} })}
> >
{!!direction && arrowPosition === "left" && ( <div
<ArrowSort className={classNames(classes.labelContainer, {
className={classNames(classes.arrow, classes.arrowLeft, { [classes.labelContainerActive]: !!direction && !!arrowPosition,
[classes.arrowUp]: direction === "asc" [classes.labelContainerCenter]: textAlign === "center",
})} [classes.labelContainerRight]: textAlign === "right"
/> })}
)} >
<div className={classes.label}>{children}</div> {!!direction && arrowPosition === "left" && (
{!!direction && arrowPosition === "right" && ( <ArrowSort
<ArrowSort className={classNames(classes.arrow, classes.arrowLeft, {
className={classNames(classes.arrow, { [classes.arrowUp]: direction === "asc"
[classes.arrowUp]: direction === "asc" })}
})} />
/> )}
)} <div className={classes.label}>{children}</div>
</div> {!!direction && arrowPosition === "right" && (
</TableCell> <ArrowSort
); className={classNames(classes.arrow, {
}; [classes.arrowUp]: direction === "asc"
})}
/>
)}
</div>
</TableCell>
);
}
);
TableCellHeader.displayName = "TableCellHeader"; TableCellHeader.displayName = "TableCellHeader";
TableCellHeader.defaultProps = { TableCellHeader.defaultProps = {

View file

@ -0,0 +1,30 @@
import { Tooltip } from "@saleor/macaw-ui";
import React from "react";
import TableCellHeader, { TableCellHeaderProps } from "../TableCellHeader";
interface TooltipTableCellHeaderProps extends TableCellHeaderProps {
tooltip?: string | React.ReactNodeArray;
}
export const TooltipTableCellHeader: React.FC<TooltipTableCellHeaderProps> = props => {
const { children, tooltip, disabled, ...rest } = props;
const tooltipDisabled = () => {
if (!tooltip) {
return true;
}
return !disabled;
};
return (
<Tooltip title={tooltip} placement="top" disabled={tooltipDisabled()}>
<TableCellHeader disabled={disabled} {...rest}>
{children}
</TableCellHeader>
</Tooltip>
);
};
TooltipTableCellHeader.displayName = "TooltipTableCellHeader";
export default TooltipTableCellHeader;

View file

@ -0,0 +1,2 @@
export { default } from "./TooltipTableCellHeader";
export * from "./TooltipTableCellHeader";

View file

@ -0,0 +1,8 @@
import { defineMessages } from "react-intl";
export const commonTooltipMessages = defineMessages({
noFilterSelected: {
defaultMessage:
"Sorting by this column requires active filter: {filterName}"
}
});

View file

@ -8,6 +8,8 @@ import Skeleton from "@saleor/components/Skeleton";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader";
import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages";
import { SaleListUrlSortField } from "@saleor/discounts/urls"; import { SaleListUrlSortField } from "@saleor/discounts/urls";
import { canBeSorted } from "@saleor/discounts/views/SaleList/sort"; import { canBeSorted } from "@saleor/discounts/views/SaleList/sort";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
@ -17,7 +19,7 @@ import { SaleType } from "@saleor/types/globalTypes";
import { getArrowDirection } from "@saleor/utils/sort"; import { getArrowDirection } from "@saleor/utils/sort";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { SaleList_sales_edges_node } from "../../types/SaleList"; import { SaleList_sales_edges_node } from "../../types/SaleList";
@ -83,10 +85,12 @@ const SaleList: React.FC<SaleListProps> = props => {
sort, sort,
toggle, toggle,
toggleAll, toggleAll,
toolbar toolbar,
filterDependency
} = props; } = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl();
const numberOfColumns = sales?.length === 0 ? 4 : 5; const numberOfColumns = sales?.length === 0 ? 4 : 5;
return ( return (
@ -138,7 +142,7 @@ const SaleList: React.FC<SaleListProps> = props => {
> >
<FormattedMessage defaultMessage="Ends" description="sale end date" /> <FormattedMessage defaultMessage="Ends" description="sale end date" />
</TableCellHeader> </TableCellHeader>
<TableCellHeader <TooltipTableCellHeader
direction={ direction={
sort.sort === SaleListUrlSortField.value sort.sort === SaleListUrlSortField.value
? getArrowDirection(sort.asc) ? getArrowDirection(sort.asc)
@ -149,10 +153,13 @@ const SaleList: React.FC<SaleListProps> = props => {
disabled={ disabled={
!canBeSorted(SaleListUrlSortField.value, !!selectedChannelId) !canBeSorted(SaleListUrlSortField.value, !!selectedChannelId)
} }
tooltip={intl.formatMessage(commonTooltipMessages.noFilterSelected, {
filterName: filterDependency.label
})}
className={classes.colValue} className={classes.colValue}
> >
<FormattedMessage defaultMessage="Value" description="sale value" /> <FormattedMessage defaultMessage="Value" description="sale value" />
</TableCellHeader> </TooltipTableCellHeader>
</TableHead> </TableHead>
<TableFooter> <TableFooter>
<TableRow> <TableRow>

View file

@ -1,5 +1,6 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import { getByName } from "@saleor/components/Filter/utils";
import FilterBar from "@saleor/components/FilterBar"; import FilterBar from "@saleor/components/FilterBar";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import { SaleListUrlSortField } from "@saleor/discounts/urls"; import { SaleListUrlSortField } from "@saleor/discounts/urls";
@ -51,6 +52,8 @@ const SaleListPage: React.FC<SaleListPageProps> = ({
const intl = useIntl(); const intl = useIntl();
const structure = createFilterStructure(intl, filterOpts); const structure = createFilterStructure(intl, filterOpts);
const filterDependency = structure.find(getByName("channel"));
return ( return (
<Container> <Container>
<PageHeader title={intl.formatMessage(sectionNames.sales)}> <PageHeader title={intl.formatMessage(sectionNames.sales)}>
@ -78,7 +81,7 @@ const SaleListPage: React.FC<SaleListPageProps> = ({
onTabDelete={onTabDelete} onTabDelete={onTabDelete}
onTabSave={onTabSave} onTabSave={onTabSave}
/> />
<SaleList {...listProps} /> <SaleList filterDependency={filterDependency} {...listProps} />
</Card> </Card>
</Container> </Container>
); );

View file

@ -8,6 +8,8 @@ import Skeleton from "@saleor/components/Skeleton";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader";
import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages";
import { VoucherListUrlSortField } from "@saleor/discounts/urls"; import { VoucherListUrlSortField } from "@saleor/discounts/urls";
import { canBeSorted } from "@saleor/discounts/views/VoucherList/sort"; import { canBeSorted } from "@saleor/discounts/views/VoucherList/sort";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
@ -18,7 +20,7 @@ import { getArrowDirection } from "@saleor/utils/sort";
import { getFooterColSpanWithBulkActions } from "@saleor/utils/tables"; import { getFooterColSpanWithBulkActions } from "@saleor/utils/tables";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { VoucherList_vouchers_edges_node } from "../../types/VoucherList"; import { VoucherList_vouchers_edges_node } from "../../types/VoucherList";
@ -101,10 +103,12 @@ const VoucherList: React.FC<VoucherListProps> = props => {
sort, sort,
toggle, toggle,
toggleAll, toggleAll,
toolbar toolbar,
filterDependency
} = props; } = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl();
return ( return (
<ResponsiveTable> <ResponsiveTable>
@ -128,7 +132,7 @@ const VoucherList: React.FC<VoucherListProps> = props => {
> >
<FormattedMessage defaultMessage="Code" description="voucher code" /> <FormattedMessage defaultMessage="Code" description="voucher code" />
</TableCellHeader> </TableCellHeader>
<TableCellHeader <TooltipTableCellHeader
direction={ direction={
sort.sort === VoucherListUrlSortField.minSpent sort.sort === VoucherListUrlSortField.minSpent
? getArrowDirection(sort.asc) ? getArrowDirection(sort.asc)
@ -140,12 +144,15 @@ const VoucherList: React.FC<VoucherListProps> = props => {
!canBeSorted(VoucherListUrlSortField.minSpent, !!selectedChannelId) !canBeSorted(VoucherListUrlSortField.minSpent, !!selectedChannelId)
} }
className={classes.colMinSpent} className={classes.colMinSpent}
tooltip={intl.formatMessage(commonTooltipMessages.noFilterSelected, {
filterName: filterDependency.label
})}
> >
<FormattedMessage <FormattedMessage
defaultMessage="Min. Spent" defaultMessage="Min. Spent"
description="minimum amount of spent money to activate voucher" description="minimum amount of spent money to activate voucher"
/> />
</TableCellHeader> </TooltipTableCellHeader>
<TableCellHeader <TableCellHeader
direction={ direction={
sort.sort === VoucherListUrlSortField.startDate sort.sort === VoucherListUrlSortField.startDate
@ -176,7 +183,7 @@ const VoucherList: React.FC<VoucherListProps> = props => {
description="voucher is active until date" description="voucher is active until date"
/> />
</TableCellHeader> </TableCellHeader>
<TableCellHeader <TooltipTableCellHeader
direction={ direction={
sort.sort === VoucherListUrlSortField.value sort.sort === VoucherListUrlSortField.value
? getArrowDirection(sort.asc) ? getArrowDirection(sort.asc)
@ -188,12 +195,15 @@ const VoucherList: React.FC<VoucherListProps> = props => {
!canBeSorted(VoucherListUrlSortField.minSpent, !!selectedChannelId) !canBeSorted(VoucherListUrlSortField.minSpent, !!selectedChannelId)
} }
className={classes.colValue} className={classes.colValue}
tooltip={intl.formatMessage(commonTooltipMessages.noFilterSelected, {
filterName: filterDependency.label
})}
> >
<FormattedMessage <FormattedMessage
defaultMessage="Value" defaultMessage="Value"
description="voucher value" description="voucher value"
/> />
</TableCellHeader> </TooltipTableCellHeader>
<TableCellHeader <TableCellHeader
direction={ direction={
sort.sort === VoucherListUrlSortField.limit sort.sort === VoucherListUrlSortField.limit

View file

@ -1,5 +1,6 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import { getByName } from "@saleor/components/Filter/utils";
import FilterBar from "@saleor/components/FilterBar"; import FilterBar from "@saleor/components/FilterBar";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import { VoucherListUrlSortField } from "@saleor/discounts/urls"; import { VoucherListUrlSortField } from "@saleor/discounts/urls";
@ -50,6 +51,8 @@ const VoucherListPage: React.FC<VoucherListPageProps> = ({
const intl = useIntl(); const intl = useIntl();
const structure = createFilterStructure(intl, filterOpts); const structure = createFilterStructure(intl, filterOpts);
const filterDependency = structure.find(getByName("channel"));
return ( return (
<Container> <Container>
<PageHeader title={intl.formatMessage(sectionNames.vouchers)}> <PageHeader title={intl.formatMessage(sectionNames.vouchers)}>
@ -80,7 +83,7 @@ const VoucherListPage: React.FC<VoucherListPageProps> = ({
onTabDelete={onTabDelete} onTabDelete={onTabDelete}
onTabSave={onTabSave} onTabSave={onTabSave}
/> />
<VoucherList {...listProps} /> <VoucherList filterDependency={filterDependency} {...listProps} />
</Card> </Card>
</Container> </Container>
); );

View file

@ -164,7 +164,7 @@ export function getFilterQueryParam(
} }
} }
const messages = defineMessages({ export const messages = defineMessages({
balanceAmountLabel: { balanceAmountLabel: {
defaultMessage: "Amount", defaultMessage: "Amount",
description: "amount filter label" description: "amount filter label"

View file

@ -5,6 +5,8 @@ import TableCellHeader, {
TableCellHeaderProps TableCellHeaderProps
} from "@saleor/components/TableCellHeader"; } from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader";
import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages";
import Label, { import Label, {
LabelSizes LabelSizes
} from "@saleor/orders/components/OrderHistory/Label"; } from "@saleor/orders/components/OrderHistory/Label";
@ -12,6 +14,7 @@ import { getArrowDirection } from "@saleor/utils/sort";
import React from "react"; import React from "react";
import { MessageDescriptor, useIntl } from "react-intl"; import { MessageDescriptor, useIntl } from "react-intl";
import { messages as filterLabels } from "../../GiftCardListSearchAndFilters/filters";
import { giftCardsListTableMessages as messages } from "../../messages"; import { giftCardsListTableMessages as messages } from "../../messages";
import useGiftCardListDialogs from "../../providers/GiftCardListDialogsProvider/hooks/useGiftCardListDialogs"; import useGiftCardListDialogs from "../../providers/GiftCardListDialogsProvider/hooks/useGiftCardListDialogs";
import useGiftCardListSort from "../../providers/GiftCardListDialogsProvider/hooks/useGiftCardListSort"; import useGiftCardListSort from "../../providers/GiftCardListDialogsProvider/hooks/useGiftCardListSort";
@ -27,7 +30,6 @@ interface HeaderItem {
options?: TableCellHeaderProps; options?: TableCellHeaderProps;
onClick?: () => void; onClick?: () => void;
direction?: TableCellHeaderArrowDirection; direction?: TableCellHeaderArrowDirection;
canBeSorted?: boolean;
} }
interface GiftCardsListTableHeaderProps { interface GiftCardsListTableHeaderProps {
@ -68,19 +70,28 @@ const GiftCardsListTableHeader: React.FC<GiftCardsListTableHeaderProps> = ({
title: messages.giftCardsTableColumnCustomerTitle, title: messages.giftCardsTableColumnCustomerTitle,
onClick: () => onSort(GiftCardUrlSortField.usedBy), onClick: () => onSort(GiftCardUrlSortField.usedBy),
direction: getDirection(GiftCardUrlSortField.usedBy) direction: getDirection(GiftCardUrlSortField.usedBy)
},
{
title: messages.giftCardsTableColumnBalanceTitle,
options: {
className: classes.colBalance,
textAlign: "right"
},
onClick: () => onSort(GiftCardUrlSortField.balance),
direction: getDirection(GiftCardUrlSortField.balance),
canBeSorted: canBeSorted(GiftCardUrlSortField.balance, isCurrencySelected)
} }
]; ];
const headerTooltipItem: HeaderItem & {
disabled: boolean;
tooltip: string | React.ReactNodeArray;
} = {
title: messages.giftCardsTableColumnBalanceTitle,
options: {
className: classes.colBalance,
textAlign: "right"
},
onClick: () => onSort(GiftCardUrlSortField.balance),
direction: getDirection(GiftCardUrlSortField.balance),
disabled: !canBeSorted(GiftCardUrlSortField.balance, isCurrencySelected),
tooltip: intl.formatMessage(commonTooltipMessages.noFilterSelected, {
filterName: <b>{filterLabels.currencyLabel.defaultMessage}</b>
})
};
const { title, ...headerTooltipItemProps } = headerTooltipItem;
return ( return (
<> <>
<colgroup> <colgroup>
@ -105,18 +116,22 @@ const GiftCardsListTableHeader: React.FC<GiftCardsListTableHeaderProps> = ({
</div> </div>
} }
> >
{headerItems.map( {headerItems.map(({ title, options, onClick, direction }) => (
({ title, options, onClick, direction, canBeSorted = true }) => ( <TableCellHeader
<TableCellHeader {...options}
{...options} onClick={onClick}
onClick={onClick} direction={direction}
disabled={!canBeSorted} key={title.defaultMessage}
direction={direction} >
> <Label text={intl.formatMessage(title)} size={LabelSizes.md} />
<Label text={intl.formatMessage(title)} size={LabelSizes.md} /> </TableCellHeader>
</TableCellHeader> ))}
) <TooltipTableCellHeader {...headerTooltipItemProps}>
)} <Label
text={intl.formatMessage(headerTooltipItem.title)}
size={LabelSizes.md}
/>
</TooltipTableCellHeader>
<TableCell className={classes.colDelete} /> <TableCell className={classes.colDelete} />
</TableHead> </TableHead>
</> </>

View file

@ -17,6 +17,8 @@ import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader";
import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages";
import { ProductListColumns } from "@saleor/config"; import { ProductListColumns } from "@saleor/config";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import { maybe, renderCollection } from "@saleor/misc"; import { maybe, renderCollection } from "@saleor/misc";
@ -35,7 +37,7 @@ import TDisplayColumn, {
import { getArrowDirection } from "@saleor/utils/sort"; import { getArrowDirection } from "@saleor/utils/sort";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { columnsMessages, messages } from "./messages"; import { columnsMessages, messages } from "./messages";
@ -137,10 +139,12 @@ export const ProductList: React.FC<ProductListProps> = props => {
onUpdateListSettings, onUpdateListSettings,
onRowClick, onRowClick,
onSort, onSort,
selectedChannelId selectedChannelId,
filterDependency
} = props; } = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl();
const gridAttributesFromSettings = settings.columns.filter( const gridAttributesFromSettings = settings.columns.filter(
isAttributeColumnValue isAttributeColumnValue
); );
@ -215,7 +219,7 @@ export const ProductList: React.FC<ProductListProps> = props => {
column="availability" column="availability"
displayColumns={settings.columns} displayColumns={settings.columns}
> >
<TableCellHeader <TooltipTableCellHeader
data-test-id="colAvailabilityHeader" data-test-id="colAvailabilityHeader"
className={classes.colPublished} className={classes.colPublished}
direction={ direction={
@ -230,9 +234,13 @@ export const ProductList: React.FC<ProductListProps> = props => {
!!selectedChannelId !!selectedChannelId
) )
} }
tooltip={intl.formatMessage(
commonTooltipMessages.noFilterSelected,
{ filterName: filterDependency.label }
)}
> >
<FormattedMessage {...columnsMessages.availability} /> <FormattedMessage {...columnsMessages.availability} />
</TableCellHeader> </TooltipTableCellHeader>
</DisplayColumn> </DisplayColumn>
{gridAttributesFromSettings.map(gridAttributeFromSettings => { {gridAttributesFromSettings.map(gridAttributeFromSettings => {
const attributeId = getAttributeIdFromColumnValue( const attributeId = getAttributeIdFromColumnValue(
@ -278,7 +286,7 @@ export const ProductList: React.FC<ProductListProps> = props => {
</TableCellHeader> </TableCellHeader>
</DisplayColumn> </DisplayColumn>
<DisplayColumn column="price" displayColumns={settings.columns}> <DisplayColumn column="price" displayColumns={settings.columns}>
<TableCellHeader <TooltipTableCellHeader
data-test-id="colPriceHeader" data-test-id="colPriceHeader"
className={classes.colPrice} className={classes.colPrice}
direction={ direction={
@ -291,9 +299,13 @@ export const ProductList: React.FC<ProductListProps> = props => {
disabled={ disabled={
!canBeSorted(ProductListUrlSortField.price, !!selectedChannelId) !canBeSorted(ProductListUrlSortField.price, !!selectedChannelId)
} }
tooltip={intl.formatMessage(
commonTooltipMessages.noFilterSelected,
{ filterName: filterDependency.label }
)}
> >
<FormattedMessage {...columnsMessages.price} /> <FormattedMessage {...columnsMessages.price} />
</TableCellHeader> </TooltipTableCellHeader>
</DisplayColumn> </DisplayColumn>
</TableHead> </TableHead>
<TableFooter> <TableFooter>

View file

@ -6,6 +6,7 @@ import ColumnPicker, {
ColumnPickerChoice ColumnPickerChoice
} from "@saleor/components/ColumnPicker"; } from "@saleor/components/ColumnPicker";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import { getByName } from "@saleor/components/Filter/utils";
import FilterBar from "@saleor/components/FilterBar"; import FilterBar from "@saleor/components/FilterBar";
import LimitReachedAlert from "@saleor/components/LimitReachedAlert"; import LimitReachedAlert from "@saleor/components/LimitReachedAlert";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
@ -114,6 +115,8 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
const filterStructure = createFilterStructure(intl, filterOpts); const filterStructure = createFilterStructure(intl, filterOpts);
const filterDependency = filterStructure.find(getByName("channel"));
const columns: ColumnPickerChoice[] = [ const columns: ColumnPickerChoice[] = [
{ {
label: intl.formatMessage(columnsMessages.price), label: intl.formatMessage(columnsMessages.price),
@ -241,6 +244,7 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
channelsCount={channelsCount} channelsCount={channelsCount}
selectedChannelId={selectedChannelId} selectedChannelId={selectedChannelId}
onUpdateListSettings={onUpdateListSettings} onUpdateListSettings={onUpdateListSettings}
filterDependency={filterDependency}
/> />
</Card> </Card>
</Container> </Container>

View file

@ -1,7 +1,7 @@
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import { MutationResult } from "react-apollo"; import { MutationResult } from "react-apollo";
import { IFilter } from "./components/Filter"; import { IFilter, IFilterElement } from "./components/Filter";
import { MultiAutocompleteChoiceType } from "./components/MultiAutocompleteSelectField"; import { MultiAutocompleteChoiceType } from "./components/MultiAutocompleteSelectField";
import { User_userPermissions } from "./fragments/types/User"; import { User_userPermissions } from "./fragments/types/User";
@ -61,6 +61,7 @@ export interface ListProps<TColumns extends string = string> {
value: ListSettings<TColumns>[T] value: ListSettings<TColumns>[T]
) => void; ) => void;
onListSettingsReset?: () => void; onListSettingsReset?: () => void;
filterDependency?: IFilterElement;
} }
export interface SortPage<TSortKey extends string> { export interface SortPage<TSortKey extends string> {