Change StatusLabels to Pills (#1867)
* Change StatusLabels to Pills (#1819) * Refactor StatusLabel component to use Pills * Remove StatusLabel component * Remove StatusChip component * Refactor ChannelsAvailibilityDropdown for usage with Pills * Remove AvailabilityStatusLabel * Fix FilterErrorsList dot * Refactor plugin availability * Update messages * Update snapshots & solve rebase conflicts * Fix rebase conflict - duplicate intl * Handle products & collections without channels * Change plugins messages from inactive to deactivated * Remove redundant ChannelConfigPopup * Change AvailabilityMenu from onClick to onHover * Update snapshots & fix rebase conflicts * Add order title * Fix status colors * Remove unused import * Fix extra spacing in unfulfilled pill * Add payment card title & move messages outside file * Fix impromper skeleton rendering in product list * Update snapshots & fix rebase conflicts * Change plugins pills to interactive * Update snapshots * Trigger deployment * Apply minor CR fixes * Change callb acks props to mapped objects in ChannelsAvailabilityMenu * Rebase / update snapshots * Fix fulfilled from label position * Update snapshots * Change messages names in oRderPayment * Fix Pill overflowing * Update snapshots
This commit is contained in:
parent
675a3a959a
commit
f5f4858cf1
49 changed files with 2680 additions and 4972 deletions
|
@ -2040,25 +2040,33 @@
|
|||
"context": "select title",
|
||||
"string": "Select channels you want for {contentType} to be available on"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_1043589445": {
|
||||
"context": "product channel publication status",
|
||||
"string": "hidden"
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_channel": {
|
||||
"context": "Channel label",
|
||||
"string": "Channel"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_1702481199": {
|
||||
"context": "product channel publication date",
|
||||
"string": "published since {date}"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_1944644572": {
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_dropdownLabel": {
|
||||
"context": "product status title",
|
||||
"string": "{count}/{allCount} channels"
|
||||
"string": "{channelCount} {channelCount,plural, =1 {Channel} other {Channels}}"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_3285520461": {
|
||||
"context": "product channel publication date",
|
||||
"string": "Will become available on {date}"
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_noChannels": {
|
||||
"context": "dropdown label when there are no channels assigned",
|
||||
"string": "No channels"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_802058289": {
|
||||
"context": "product status",
|
||||
"string": "Available in {count} out of {allCount, plural, one {# channel} other {# channels}}"
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_published": {
|
||||
"context": "Status label when object is published in a channel",
|
||||
"string": "Published"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_scheduled": {
|
||||
"context": "Status label when object is scheduled to publish in a channel",
|
||||
"string": "Scheduled to publish"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_status": {
|
||||
"context": "Status label",
|
||||
"string": "Status"
|
||||
},
|
||||
"src_dot_components_dot_ChannelsAvailabilityDropdown_dot_unpublished": {
|
||||
"context": "Status label when object is unpublished in a channel",
|
||||
"string": "Unpublished"
|
||||
},
|
||||
"src_dot_components_dot_ColumnPicker_dot_1483881697": {
|
||||
"context": "button",
|
||||
|
@ -2467,18 +2475,6 @@
|
|||
"src_dot_components_dot_SingleSelectField_dot_4205644805": {
|
||||
"string": "No results found"
|
||||
},
|
||||
"src_dot_components_dot_StatusLabel_dot_active": {
|
||||
"context": "status label active",
|
||||
"string": "Active"
|
||||
},
|
||||
"src_dot_components_dot_StatusLabel_dot_deactivated": {
|
||||
"context": "status label deactivated",
|
||||
"string": "Deactivated"
|
||||
},
|
||||
"src_dot_components_dot_StatusLabel_dot_inactive": {
|
||||
"context": "status label inactive",
|
||||
"string": "Inactive"
|
||||
},
|
||||
"src_dot_components_dot_TableHead_dot_868570480": {
|
||||
"string": "Selected {number} items"
|
||||
},
|
||||
|
@ -4377,6 +4373,9 @@
|
|||
"context": "OrderCustomer Fulfillment from Local Warehouse",
|
||||
"string": "Fulfill from Local Stock"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderDetailsPage_dot_580490159": {
|
||||
"string": "Order #{orderNumber}"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderDetailsPage_dot_cancelOrder": {
|
||||
"context": "cancel button",
|
||||
"string": "Cancel order"
|
||||
|
@ -4950,85 +4949,93 @@
|
|||
"context": "dialog header",
|
||||
"string": "Void Payment"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_1322321687": {
|
||||
"context": "order payment",
|
||||
"string": "Refunded amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_1325966144": {
|
||||
"context": "order shipping method name",
|
||||
"string": "Shipping"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_1817306106": {
|
||||
"context": "vat included in order price",
|
||||
"string": "VAT included"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_1934027242": {
|
||||
"context": "voucher type order discount",
|
||||
"string": "Voucher"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_2183023165": {
|
||||
"context": "ordered products",
|
||||
"string": "{quantity} items"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_2320183694": {
|
||||
"context": "order payment",
|
||||
"string": "Captured amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_2392156856": {
|
||||
"context": "staff added type order discount",
|
||||
"string": "Staff added"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_2444197639": {
|
||||
"context": "void payment, button",
|
||||
"string": "Void"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_2845258362": {
|
||||
"context": "button",
|
||||
"string": "Refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_3500506678": {
|
||||
"context": "order, button",
|
||||
"string": "Mark as paid"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_353147224": {
|
||||
"context": "order payment",
|
||||
"string": "Outstanding Balance"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_3720114122": {
|
||||
"context": "order discount",
|
||||
"string": "Discount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_372187363": {
|
||||
"context": "order payment",
|
||||
"string": "Paid with Gift Card"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_3768782744": {
|
||||
"context": "order payment",
|
||||
"string": "Preauthorized amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_3955023266": {
|
||||
"string": "Taxes"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_4211710217": {
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_capture": {
|
||||
"context": "capture payment, button",
|
||||
"string": "Capture"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_781550514": {
|
||||
"context": "order subtotal price",
|
||||
"string": "Subtotal"
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_captured": {
|
||||
"context": "order payment",
|
||||
"string": "Captured amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_878013594": {
|
||||
"context": "order total price",
|
||||
"string": "Total"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_orderPaymentClickAndCollectShippingMethod": {
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_clickAndCollectShippingMethod": {
|
||||
"context": "OrderPayment click&collect shipping method",
|
||||
"string": "click&collect"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_orderPaymentShippingDoesNotApply": {
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_discount": {
|
||||
"context": "order discount",
|
||||
"string": "Discount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_itemCount": {
|
||||
"context": "ordered products",
|
||||
"string": "{quantity} items"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_markAsPaid": {
|
||||
"context": "order, button",
|
||||
"string": "Mark as paid"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_outstanding": {
|
||||
"context": "order payment",
|
||||
"string": "Outstanding Balance"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_paidWithGiftCard": {
|
||||
"context": "order payment",
|
||||
"string": "Paid with Gift Card"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_paymentTitle": {
|
||||
"context": "Payment card title",
|
||||
"string": "Payment status"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_preauthorized": {
|
||||
"context": "order payment",
|
||||
"string": "Preauthorized amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_refund": {
|
||||
"context": "button",
|
||||
"string": "Refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_refunded": {
|
||||
"context": "order payment",
|
||||
"string": "Refunded amount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_shipping": {
|
||||
"context": "order shipping method name",
|
||||
"string": "Shipping"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_shippingDoesNotApply": {
|
||||
"context": "OrderPayment does not require shipping",
|
||||
"string": "does not apply"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_shippingNotApplicable": {
|
||||
"context": "order does not require shipping",
|
||||
"string": "does not apply"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_staffAdded": {
|
||||
"context": "staff added type order discount",
|
||||
"string": "Staff added"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_subtotal": {
|
||||
"context": "order subtotal price",
|
||||
"string": "Subtotal"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_taxes": {
|
||||
"string": "Taxes"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_total": {
|
||||
"context": "order total price",
|
||||
"string": "Total"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_vatIncluded": {
|
||||
"context": "vat included in order price",
|
||||
"string": "VAT included"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_void": {
|
||||
"context": "button",
|
||||
"string": "Refund"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_voucher": {
|
||||
"context": "voucher type order discount",
|
||||
"string": "Voucher"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderProductAddDialog_dot_2272209368": {
|
||||
"context": "variant sku",
|
||||
"string": "SKU {sku}"
|
||||
|
@ -5945,18 +5952,26 @@
|
|||
"src_dot_plugins_dot_components_dot_PluginsList_dot_666641390": {
|
||||
"string": "No plugins found"
|
||||
},
|
||||
"src_dot_plugins_dot_components_dot_PluginsList_dot_active": {
|
||||
"context": "status label active",
|
||||
"string": "Active"
|
||||
},
|
||||
"src_dot_plugins_dot_components_dot_PluginsList_dot_channelLabel": {
|
||||
"context": "table header channel col label",
|
||||
"string": "Channel"
|
||||
},
|
||||
"src_dot_plugins_dot_components_dot_PluginsList_dot_channelTitle": {
|
||||
"context": "plugin channel availability status title",
|
||||
"string": "Active in {activeChannelsCount}"
|
||||
"string": "{activeChannelsCount,plural, =0 {Deactivated} other {Active in {activeChannelsCount}}}"
|
||||
},
|
||||
"src_dot_plugins_dot_components_dot_PluginsList_dot_confLabel": {
|
||||
"context": "table header configuration col label",
|
||||
"string": "Configuration"
|
||||
},
|
||||
"src_dot_plugins_dot_components_dot_PluginsList_dot_deactivated": {
|
||||
"context": "status label deactivated",
|
||||
"string": "Deactivated"
|
||||
},
|
||||
"src_dot_plugins_dot_components_dot_PluginsList_dot_description": {
|
||||
"context": "global config plugin status popup description",
|
||||
"string": "Global plugins are set across all channels in your ecommerce. Only status is shown for those types of plugins"
|
||||
|
|
|
@ -101,7 +101,6 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
|
|||
<CardSpacer />
|
||||
<CollectionProducts
|
||||
disabled={disabled}
|
||||
channelsCount={channelsCount}
|
||||
collection={collection}
|
||||
{...collectionProductsProps}
|
||||
/>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core";
|
||||
import { CollectionListUrlSortField } from "@saleor/collections/urls";
|
||||
import { canBeSorted } from "@saleor/collections/views/CollectionList/sort";
|
||||
import AvailabilityStatusLabel from "@saleor/components/AvailabilityStatusLabel";
|
||||
import { ChannelsAvailabilityDropdown } from "@saleor/components/ChannelsAvailabilityDropdown";
|
||||
import {
|
||||
getChannelAvailabilityColor,
|
||||
getChannelAvailabilityLabel
|
||||
} from "@saleor/components/ChannelsAvailabilityDropdown/utils";
|
||||
import Checkbox from "@saleor/components/Checkbox";
|
||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
|
@ -11,7 +14,7 @@ import TableHead from "@saleor/components/TableHead";
|
|||
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, Pill } from "@saleor/macaw-ui";
|
||||
import { maybe, renderCollection } from "@saleor/misc";
|
||||
import { ChannelProps, ListActions, ListProps, SortPage } from "@saleor/types";
|
||||
import { getArrowDirection } from "@saleor/utils/sort";
|
||||
|
@ -19,7 +22,6 @@ import React from "react";
|
|||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { CollectionList_collections_edges_node } from "../../types/CollectionList";
|
||||
import { messages } from "./messages";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
|
@ -52,14 +54,12 @@ interface CollectionListProps
|
|||
SortPage<CollectionListUrlSortField>,
|
||||
ChannelProps {
|
||||
collections: CollectionList_collections_edges_node[];
|
||||
channelsCount: number;
|
||||
}
|
||||
|
||||
const numberOfColumns = 4;
|
||||
|
||||
const CollectionList: React.FC<CollectionListProps> = props => {
|
||||
const {
|
||||
channelsCount,
|
||||
collections,
|
||||
disabled,
|
||||
settings,
|
||||
|
@ -194,17 +194,16 @@ const CollectionList: React.FC<CollectionListProps> = props => {
|
|||
data-test-availability={!!collection?.channelListings?.length}
|
||||
>
|
||||
{(!collection && <Skeleton />) ||
|
||||
(!collection?.channelListings?.length && "-") ||
|
||||
(collection?.channelListings !== undefined && channel ? (
|
||||
<AvailabilityStatusLabel
|
||||
channel={channel}
|
||||
messages={messages}
|
||||
(channel ? (
|
||||
<Pill
|
||||
label={intl.formatMessage(
|
||||
getChannelAvailabilityLabel(channel)
|
||||
)}
|
||||
color={getChannelAvailabilityColor(channel)}
|
||||
/>
|
||||
) : (
|
||||
<ChannelsAvailabilityDropdown
|
||||
allChannelsCount={channelsCount}
|
||||
channels={collection?.channelListings}
|
||||
showStatus
|
||||
/>
|
||||
))}
|
||||
</TableCell>
|
||||
|
|
|
@ -98,7 +98,6 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
|
|||
/>
|
||||
<CollectionList
|
||||
disabled={disabled}
|
||||
channelsCount={channelsCount}
|
||||
selectedChannelId={selectedChannelId}
|
||||
filterDependency={filterDependency}
|
||||
{...listProps}
|
||||
|
|
|
@ -54,13 +54,11 @@ const useStyles = makeStyles(
|
|||
|
||||
export interface CollectionProductsProps extends PageListProps, ListActions {
|
||||
collection: CollectionDetails_collection;
|
||||
channelsCount: number;
|
||||
onProductUnassign: (id: string, event: React.MouseEvent<any>) => void;
|
||||
}
|
||||
|
||||
const CollectionProducts: React.FC<CollectionProductsProps> = props => {
|
||||
const {
|
||||
channelsCount,
|
||||
collection,
|
||||
disabled,
|
||||
onAdd,
|
||||
|
@ -195,7 +193,6 @@ const CollectionProducts: React.FC<CollectionProductsProps> = props => {
|
|||
"-"
|
||||
) : product?.channelListings !== undefined ? (
|
||||
<ChannelsAvailabilityDropdown
|
||||
allChannelsCount={channelsCount}
|
||||
channels={product?.channelListings}
|
||||
/>
|
||||
) : (
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
export const AvailabilityStatusLabel = ({ channel, messages }) => {
|
||||
const intl = useIntl();
|
||||
const localizeDate = useDateLocalize();
|
||||
|
||||
return (
|
||||
<StatusLabel
|
||||
label={intl.formatMessage(
|
||||
channel.publicationDate
|
||||
? channel.isPublished
|
||||
? messages.published
|
||||
: messages.willBePublished
|
||||
: messages.unpublished,
|
||||
{
|
||||
date: localizeDate(channel.publicationDate, "L")
|
||||
}
|
||||
)}
|
||||
status={
|
||||
channel.publicationDate
|
||||
? channel.isPublished
|
||||
? "success"
|
||||
: "alert"
|
||||
: "error"
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default AvailabilityStatusLabel;
|
|
@ -1,2 +0,0 @@
|
|||
export { default } from "./AvailabilityStatusLabel";
|
||||
export * from "./AvailabilityStatusLabel";
|
|
@ -8,9 +8,7 @@ import ChannelsAvailabilityDropdown, {
|
|||
} from "./ChannelsAvailabilityDropdown";
|
||||
|
||||
const props: ChannelsAvailabilityDropdownProps = {
|
||||
allChannelsCount: 6,
|
||||
channels: productChannels,
|
||||
showStatus: true
|
||||
channels: productChannels
|
||||
};
|
||||
|
||||
storiesOf("Generics / ChannelsAvailabilityDropdown", module)
|
||||
|
|
|
@ -1,140 +1,63 @@
|
|||
import { Menu, MenuItem, Typography } from "@material-ui/core";
|
||||
import { CollectionList_collections_edges_node_channelListings } from "@saleor/collections/types/CollectionList";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
||||
import { Card, Popper } from "@material-ui/core";
|
||||
import { Pill } from "@saleor/macaw-ui";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { useStyles } from "./styles";
|
||||
|
||||
type Channels = Pick<
|
||||
CollectionList_collections_edges_node_channelListings,
|
||||
"isPublished" | "publicationDate" | "channel"
|
||||
>;
|
||||
import ChannelsAvailabilityMenuContent from "../ChannelsAvailabilityMenuContent";
|
||||
import { messages } from "./messages";
|
||||
import {
|
||||
CollectionChannels,
|
||||
getDropdownColor,
|
||||
mapChannelsToPills
|
||||
} from "./utils";
|
||||
|
||||
export interface ChannelsAvailabilityDropdownProps {
|
||||
allChannelsCount: number;
|
||||
channels: Channels[];
|
||||
showStatus?: boolean;
|
||||
channels: CollectionChannels[] | null;
|
||||
}
|
||||
|
||||
const isActive = (channelData: Channels) => channelData?.isPublished;
|
||||
|
||||
export const ChannelsAvailabilityDropdown: React.FC<ChannelsAvailabilityDropdownProps> = ({
|
||||
allChannelsCount,
|
||||
channels,
|
||||
showStatus = false
|
||||
channels
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
const localizeDate = useDateLocalize();
|
||||
const [anchorEl, setAnchorEl] = React.useState(null);
|
||||
const [isPopupOpen, setPopupOpen] = React.useState(false);
|
||||
const anchor = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleClick = event => setAnchorEl(event.currentTarget);
|
||||
const handleClose = () => setAnchorEl(null);
|
||||
const activeInAllChannels = React.useMemo(
|
||||
() => showStatus && channels.every(isActive),
|
||||
[channels, showStatus]
|
||||
);
|
||||
const dropdownColor = React.useMemo(() => getDropdownColor(channels), [
|
||||
channels
|
||||
]);
|
||||
|
||||
if (!channels?.length) {
|
||||
return (
|
||||
<Pill label={intl.formatMessage(messages.noChannels)} color="error" />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div onClick={e => e.stopPropagation()}>
|
||||
<div
|
||||
aria-controls="availability-menu"
|
||||
aria-haspopup="true"
|
||||
role="button"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<StatusLabel
|
||||
label={intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "{count}/{allCount} channels",
|
||||
description: "product status title"
|
||||
},
|
||||
{
|
||||
allCount: allChannelsCount,
|
||||
count: channels.length
|
||||
}
|
||||
)}
|
||||
status={
|
||||
showStatus ? (activeInAllChannels ? "success" : "error") : undefined
|
||||
}
|
||||
<div
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
ref={anchor}
|
||||
onMouseOver={() => setPopupOpen(true)}
|
||||
onMouseLeave={() => setPopupOpen(false)}
|
||||
>
|
||||
<div aria-controls="availability-menu" aria-haspopup="true" role="button">
|
||||
<Pill
|
||||
label={intl.formatMessage(messages.dropdownLabel, {
|
||||
channelCount: channels.length
|
||||
})}
|
||||
color={dropdownColor}
|
||||
onClick={() => null} // required for dashed border
|
||||
/>
|
||||
</div>
|
||||
<Menu
|
||||
id="availability-menu"
|
||||
anchorEl={anchorEl}
|
||||
keepMounted
|
||||
elevation={8}
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleClose}
|
||||
getContentAnchorEl={null}
|
||||
anchorOrigin={{
|
||||
horizontal: "center",
|
||||
vertical: "bottom"
|
||||
}}
|
||||
transformOrigin={{
|
||||
horizontal: "center",
|
||||
vertical: "top"
|
||||
}}
|
||||
>
|
||||
<Typography className={classes.title}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Available in {count} out of {allCount, plural, one {# channel} other {# channels}}"
|
||||
description="product status"
|
||||
values={{
|
||||
allCount: allChannelsCount,
|
||||
count: channels.length
|
||||
}}
|
||||
<Popper anchorEl={anchor.current} open={isPopupOpen} placement={"left"}>
|
||||
<Card elevation={8}>
|
||||
<ChannelsAvailabilityMenuContent
|
||||
pills={mapChannelsToPills(channels)}
|
||||
/>
|
||||
</Typography>
|
||||
<Hr className={classes.hr} />
|
||||
{channels.map(channelData => {
|
||||
const notPublishedText = intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Will become available on {date}",
|
||||
description: "product channel publication date"
|
||||
},
|
||||
{
|
||||
date: localizeDate(channelData.publicationDate, "L")
|
||||
}
|
||||
);
|
||||
|
||||
const publishedText = intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "published since {date}",
|
||||
description: "product channel publication date"
|
||||
},
|
||||
{
|
||||
date: localizeDate(channelData.publicationDate, "L")
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<MenuItem key={channelData.channel.id} className={classes.menuItem}>
|
||||
<StatusLabel
|
||||
label={channelData.channel.name}
|
||||
status={isActive(channelData) ? "success" : "error"}
|
||||
/>
|
||||
<div>
|
||||
<Typography variant="caption" className={classes.caption}>
|
||||
{channelData.isPublished && channelData.publicationDate
|
||||
? publishedText
|
||||
: channelData.publicationDate && !channelData.isPublished
|
||||
? notPublishedText
|
||||
: channelData.isPublished
|
||||
? ""
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "hidden",
|
||||
description: "product channel publication status"
|
||||
})}
|
||||
</Typography>
|
||||
</div>
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</Menu>
|
||||
</Card>
|
||||
</Popper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
36
src/components/ChannelsAvailabilityDropdown/messages.ts
Normal file
36
src/components/ChannelsAvailabilityDropdown/messages.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const messages = defineMessages({
|
||||
status: {
|
||||
defaultMessage: "Status",
|
||||
description: "Status label"
|
||||
},
|
||||
channel: {
|
||||
defaultMessage: "Channel",
|
||||
description: "Channel label"
|
||||
},
|
||||
dropdownLabel: {
|
||||
defaultMessage:
|
||||
"{channelCount} {channelCount,plural, =1 {Channel} other {Channels}}",
|
||||
description: "product status title"
|
||||
},
|
||||
noChannels: {
|
||||
defaultMessage: "No channels",
|
||||
description: "dropdown label when there are no channels assigned"
|
||||
}
|
||||
});
|
||||
|
||||
export const channelStatusMessages = defineMessages({
|
||||
unpublished: {
|
||||
defaultMessage: "Unpublished",
|
||||
description: "Status label when object is unpublished in a channel"
|
||||
},
|
||||
scheduled: {
|
||||
defaultMessage: "Scheduled to publish",
|
||||
description: "Status label when object is scheduled to publish in a channel"
|
||||
},
|
||||
published: {
|
||||
defaultMessage: "Published",
|
||||
description: "Status label when object is published in a channel"
|
||||
}
|
||||
});
|
|
@ -1,21 +0,0 @@
|
|||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
export const useStyles = makeStyles(
|
||||
theme => ({
|
||||
caption: {
|
||||
paddingLeft: theme.spacing(2)
|
||||
},
|
||||
hr: {
|
||||
left: theme.spacing(-1),
|
||||
position: "relative",
|
||||
width: `calc(100% + ${theme.spacing(2)}px)`
|
||||
},
|
||||
menuItem: {
|
||||
display: "block"
|
||||
},
|
||||
title: {
|
||||
padding: theme.spacing(1, 2, 1, 2)
|
||||
}
|
||||
}),
|
||||
{ name: "ChannelsAvailabilityDropdown" }
|
||||
);
|
61
src/components/ChannelsAvailabilityDropdown/utils.ts
Normal file
61
src/components/ChannelsAvailabilityDropdown/utils.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { CollectionList_collections_edges_node_channelListings } from "@saleor/collections/types/CollectionList";
|
||||
import { PillColor } from "@saleor/macaw-ui";
|
||||
import { MessageDescriptor } from "react-intl";
|
||||
|
||||
import { Pill } from "../ChannelsAvailabilityMenuContent";
|
||||
import { channelStatusMessages } from "./messages";
|
||||
|
||||
export type CollectionChannels = Pick<
|
||||
CollectionList_collections_edges_node_channelListings,
|
||||
"isPublished" | "publicationDate" | "channel"
|
||||
>;
|
||||
export type Channels = Pick<
|
||||
CollectionList_collections_edges_node_channelListings,
|
||||
"channel"
|
||||
>;
|
||||
|
||||
export const isActive = (channelData: CollectionChannels) =>
|
||||
channelData?.isPublished;
|
||||
export const isScheduled = (channelData: CollectionChannels) =>
|
||||
channelData?.publicationDate && !channelData?.isPublished;
|
||||
|
||||
export const getDropdownColor = (channels: CollectionChannels[]) => {
|
||||
if (channels.some(isActive)) {
|
||||
return "success";
|
||||
}
|
||||
if (channels.some(isScheduled)) {
|
||||
return "warning";
|
||||
}
|
||||
return "error";
|
||||
};
|
||||
|
||||
export const getChannelAvailabilityColor = (
|
||||
channelData: CollectionChannels
|
||||
): PillColor => {
|
||||
if (isActive(channelData)) {
|
||||
return "success";
|
||||
}
|
||||
if (isScheduled(channelData)) {
|
||||
return "warning";
|
||||
}
|
||||
return "error";
|
||||
};
|
||||
|
||||
export const getChannelAvailabilityLabel = (
|
||||
channelData: CollectionChannels
|
||||
): MessageDescriptor => {
|
||||
if (isActive(channelData)) {
|
||||
return channelStatusMessages.published;
|
||||
}
|
||||
if (isScheduled(channelData)) {
|
||||
return channelStatusMessages.scheduled;
|
||||
}
|
||||
return channelStatusMessages.unpublished;
|
||||
};
|
||||
|
||||
export const mapChannelsToPills = (channelData: CollectionChannels[]): Pill[] =>
|
||||
channelData.map(channel => ({
|
||||
channel: channel.channel,
|
||||
color: getChannelAvailabilityColor(channel),
|
||||
label: getChannelAvailabilityLabel(channel)
|
||||
}));
|
|
@ -0,0 +1,51 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
|
||||
import { CollectionList_collections_edges_node_channelListings_channel } from "@saleor/collections/types/CollectionList";
|
||||
import { Pill, PillColor } from "@saleor/macaw-ui";
|
||||
import ScrollableContent from "@saleor/plugins/components/PluginsList/PluginAvailabilityStatusPopup/ScrollableContent";
|
||||
import React from "react";
|
||||
import { MessageDescriptor } from "react-intl";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { messages } from "../ChannelsAvailabilityDropdown/messages";
|
||||
import { useStyles } from "./styles";
|
||||
|
||||
export interface ChannelsAvailabilityMenuContentProps {
|
||||
pills: Pill[];
|
||||
}
|
||||
export interface Pill {
|
||||
channel: CollectionList_collections_edges_node_channelListings_channel;
|
||||
color: PillColor;
|
||||
label: MessageDescriptor;
|
||||
}
|
||||
|
||||
export const ChannelsAvailabilityMenuContent: React.FC<ChannelsAvailabilityMenuContentProps> = ({
|
||||
pills
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
|
||||
return (
|
||||
<div className={classes.menuContainer}>
|
||||
<div className={classes.row}>
|
||||
<Typography variant="caption" className={classes.caption}>
|
||||
{intl.formatMessage(messages.channel)}
|
||||
</Typography>
|
||||
<Typography variant="caption" className={classes.caption}>
|
||||
{intl.formatMessage(messages.status)}
|
||||
</Typography>
|
||||
</div>
|
||||
<ScrollableContent>
|
||||
{pills.map(pill => (
|
||||
<div key={pill.channel.id} className={classes.row}>
|
||||
<Typography>{pill.channel.name}</Typography>
|
||||
<HorizontalSpacer spacing={4} />
|
||||
<Pill label={intl.formatMessage(pill.label)} color={pill.color} />
|
||||
</div>
|
||||
))}
|
||||
</ScrollableContent>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
ChannelsAvailabilityMenuContent.displayName = "ChannelsAvailabilityMenuContent";
|
||||
export default ChannelsAvailabilityMenuContent;
|
2
src/components/ChannelsAvailabilityMenuContent/index.ts
Normal file
2
src/components/ChannelsAvailabilityMenuContent/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./ChannelsAvailabilityMenuContent";
|
||||
export { default } from "./ChannelsAvailabilityMenuContent";
|
36
src/components/ChannelsAvailabilityMenuContent/styles.ts
Normal file
36
src/components/ChannelsAvailabilityMenuContent/styles.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
export const useStyles = makeStyles(
|
||||
theme => ({
|
||||
menuContainer: {
|
||||
padding: theme.spacing(2)
|
||||
},
|
||||
|
||||
row: {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
|
||||
"&:not(:last-child)": {
|
||||
marginBottom: theme.spacing(2)
|
||||
}
|
||||
},
|
||||
caption: {
|
||||
textTransform: "uppercase",
|
||||
color: theme.palette.saleor.main[3],
|
||||
fontWeight: 500,
|
||||
letterSpacing: "0.1em"
|
||||
},
|
||||
hr: {
|
||||
left: theme.spacing(-1),
|
||||
position: "relative",
|
||||
width: `calc(100% + ${theme.spacing(2)}px)`
|
||||
},
|
||||
menuItem: {
|
||||
display: "block"
|
||||
},
|
||||
title: {
|
||||
padding: theme.spacing(1, 2, 1, 2)
|
||||
}
|
||||
}),
|
||||
{ name: "ChannelsAvailabilityMenuContent" }
|
||||
);
|
|
@ -1,9 +1,7 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import { fade, makeStyles } from "@material-ui/core/styles";
|
||||
import InlineAlert from "@saleor/components/Alert/InlineAlert";
|
||||
import { useStyles as useDotStyles } from "@saleor/components/StatusLabel";
|
||||
import errorTracker from "@saleor/services/errorTracking";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
|
@ -21,7 +19,12 @@ const useStyles = makeStyles(
|
|||
},
|
||||
dot: {
|
||||
backgroundColor: theme.palette.primary.contrastText,
|
||||
marginRight: theme.spacing(1)
|
||||
marginRight: theme.spacing(1),
|
||||
borderRadius: "100%",
|
||||
height: 8,
|
||||
minHeight: 8,
|
||||
width: 8,
|
||||
minWidth: 8
|
||||
},
|
||||
itemContainer: {
|
||||
display: "flex",
|
||||
|
@ -43,7 +46,6 @@ const FilterErrorsList: React.FC<FilterErrorsListProps> = ({
|
|||
errorMessages
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
const dotClasses = useDotStyles({});
|
||||
const intl = useIntl();
|
||||
|
||||
const getErrorMessage = (code: string) => {
|
||||
|
@ -69,7 +71,7 @@ const FilterErrorsList: React.FC<FilterErrorsListProps> = ({
|
|||
<InlineAlert>
|
||||
{errors.map(code => (
|
||||
<div className={classes.itemContainer} key={code}>
|
||||
<div className={classNames(classes.dot, dotClasses.dot)} />
|
||||
<div className={classes.dot} />
|
||||
<Typography className={classes.listItemTitle}>
|
||||
{getErrorMessage(code)}
|
||||
</Typography>
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import Decorator from "@saleor/storybook/Decorator";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import StatusChip from "./StatusChip";
|
||||
import { StatusType } from "./types";
|
||||
|
||||
storiesOf("Generics / Status Chip", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("neutral", () => (
|
||||
<StatusChip label="label" status={StatusType.NEUTRAL} />
|
||||
))
|
||||
.add("error", () => <StatusChip label="label" status={StatusType.ERROR} />)
|
||||
.add("success", () => (
|
||||
<StatusChip label="label" status={StatusType.SUCCESS} />
|
||||
))
|
||||
.add("alert", () => <StatusChip label="label" status={StatusType.ALERT} />);
|
|
@ -1,92 +0,0 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
import { Size } from "../ActionDialog/types";
|
||||
import { StatusType } from "./types";
|
||||
|
||||
export interface StatusChipProps {
|
||||
status?: StatusType;
|
||||
size?: Size;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export const statusChipStyles = {
|
||||
alert: {
|
||||
background: "#FFF4E4"
|
||||
},
|
||||
alertLabel: {
|
||||
color: "#FFB84E"
|
||||
},
|
||||
error: {
|
||||
backgroundColor: "rgba(254, 110, 118, 0.15)"
|
||||
},
|
||||
errorLabel: {
|
||||
color: "#FE6E76"
|
||||
},
|
||||
neutral: {
|
||||
background: "rgba(40, 35, 74, 0.1)"
|
||||
},
|
||||
neutralLabel: {
|
||||
color: "#28234A"
|
||||
},
|
||||
success: {
|
||||
background: "rgba(93, 194, 146, 0.3)"
|
||||
},
|
||||
successLabel: {
|
||||
color: "#5DC292"
|
||||
},
|
||||
lg: {
|
||||
padding: "4px 16px"
|
||||
},
|
||||
lgLabel: {
|
||||
fontSize: "1.5rem"
|
||||
},
|
||||
md: {
|
||||
padding: "4px 16px"
|
||||
},
|
||||
mdLabel: {
|
||||
fontSize: 16
|
||||
}
|
||||
};
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
label: {
|
||||
fontWeight: theme.typography.fontWeightBold,
|
||||
textTransform: "uppercase"
|
||||
},
|
||||
root: {
|
||||
borderRadius: 22,
|
||||
display: "inline-block"
|
||||
},
|
||||
...statusChipStyles
|
||||
}),
|
||||
{ name: "StatusChip" }
|
||||
);
|
||||
|
||||
const StatusChip: React.FC<StatusChipProps> = props => {
|
||||
const { status = StatusType.NEUTRAL, size = "lg", label } = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
if (!label) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames(classes.root, classes[status], classes[size])}>
|
||||
<Typography
|
||||
className={classNames(
|
||||
classes.label,
|
||||
classes[`${status}Label`],
|
||||
classes[`${size}Label`]
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusChip;
|
|
@ -1 +0,0 @@
|
|||
export { default } from "./StatusChip";
|
|
@ -1,6 +0,0 @@
|
|||
export enum StatusType {
|
||||
NEUTRAL = "neutral",
|
||||
ERROR = "error",
|
||||
ALERT = "alert",
|
||||
SUCCESS = "success"
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import grey from "@material-ui/core/colors/grey";
|
||||
import yellow from "@material-ui/core/colors/yellow";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import Label from "@saleor/orders/components/OrderHistory/Label";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
export const useStyles = makeStyles(
|
||||
theme => {
|
||||
const dot = {
|
||||
borderRadius: "100%",
|
||||
height: 8,
|
||||
minHeight: 8,
|
||||
width: 8,
|
||||
minWidth: 8
|
||||
};
|
||||
|
||||
return {
|
||||
dot,
|
||||
container: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
},
|
||||
containerVertical: {
|
||||
alignItems: "flex-start"
|
||||
},
|
||||
textContainer: {
|
||||
marginLeft: theme.spacing(1),
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%"
|
||||
},
|
||||
dotVertical: {
|
||||
marginTop: theme.spacing(1)
|
||||
},
|
||||
alertDot: {
|
||||
backgroundColor: yellow[500],
|
||||
...dot
|
||||
},
|
||||
errorDot: {
|
||||
backgroundColor: theme.palette.error.main,
|
||||
...dot
|
||||
},
|
||||
neutralDot: {
|
||||
backgroundColor: grey[300],
|
||||
...dot
|
||||
},
|
||||
successDot: {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
...dot
|
||||
},
|
||||
span: {
|
||||
display: "inline"
|
||||
}
|
||||
};
|
||||
},
|
||||
{ name: "StatusLabel" }
|
||||
);
|
||||
|
||||
export interface StatusLabelProps {
|
||||
label: string | React.ReactNode;
|
||||
status: "success" | "alert" | "neutral" | "error" | undefined;
|
||||
subtitle?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const StatusLabel: React.FC<StatusLabelProps> = ({
|
||||
className,
|
||||
label,
|
||||
status,
|
||||
subtitle
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames({
|
||||
[classes.container]: true,
|
||||
[classes.containerVertical]: !!subtitle
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={classNames({
|
||||
[className]: true,
|
||||
[classes.dotVertical]: !!subtitle,
|
||||
[classes.successDot]: status === "success",
|
||||
[classes.alertDot]: status === "alert",
|
||||
[classes.neutralDot]: status === "neutral",
|
||||
[classes.errorDot]: status === "error"
|
||||
})}
|
||||
></div>
|
||||
<div className={classes.textContainer}>
|
||||
<Typography>{label}</Typography>
|
||||
{subtitle && <Label text={subtitle} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusLabel;
|
|
@ -1,2 +0,0 @@
|
|||
export { default } from "./StatusLabel";
|
||||
export * from "./StatusLabel";
|
|
@ -1,16 +0,0 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const statusLabelMessages = defineMessages({
|
||||
active: {
|
||||
defaultMessage: "Active",
|
||||
description: "status label active"
|
||||
},
|
||||
inactive: {
|
||||
defaultMessage: "Inactive",
|
||||
description: "status label inactive"
|
||||
},
|
||||
deactivated: {
|
||||
defaultMessage: "Deactivated",
|
||||
description: "status label deactivated"
|
||||
}
|
||||
});
|
|
@ -10,8 +10,7 @@ import { DateTime } from "@saleor/components/Date";
|
|||
import Money from "@saleor/components/Money";
|
||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||
import { Button, makeStyles, Pill } from "@saleor/macaw-ui";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
@ -120,8 +119,8 @@ const CustomerOrders: React.FC<CustomerOrdersProps> = props => {
|
|||
<TableCell>
|
||||
{maybe(() => order.paymentStatus.status) !== undefined ? (
|
||||
order.paymentStatus.status === null ? null : (
|
||||
<StatusLabel
|
||||
status={order.paymentStatus.status}
|
||||
<Pill
|
||||
color={order.paymentStatus.status}
|
||||
label={order.paymentStatus.localized}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -27,7 +27,6 @@ export interface SaleProductsProps extends ListProps, ListActions {
|
|||
products:
|
||||
| SaleDetails_sale_products_edges_node[]
|
||||
| VoucherDetails_voucher_products_edges_node[];
|
||||
channelsCount: number;
|
||||
onProductAssign: () => void;
|
||||
onProductUnassign: (id: string) => void;
|
||||
}
|
||||
|
@ -36,7 +35,6 @@ const numberOfColumns = 5;
|
|||
|
||||
const DiscountProducts: React.FC<SaleProductsProps> = props => {
|
||||
const {
|
||||
channelsCount,
|
||||
products,
|
||||
disabled,
|
||||
pageInfo,
|
||||
|
@ -150,7 +148,6 @@ const DiscountProducts: React.FC<SaleProductsProps> = props => {
|
|||
"-"
|
||||
) : product?.channelListings !== undefined ? (
|
||||
<ChannelsAvailabilityDropdown
|
||||
allChannelsCount={channelsCount}
|
||||
channels={product?.channelListings}
|
||||
/>
|
||||
) : (
|
||||
|
|
|
@ -320,7 +320,6 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
|
|||
onRowClick={onProductClick}
|
||||
pageInfo={pageInfo}
|
||||
products={mapEdgesToItems(sale?.products)}
|
||||
channelsCount={allChannelsCount}
|
||||
isChecked={isChecked}
|
||||
selected={selected}
|
||||
toggle={toggle}
|
||||
|
|
|
@ -350,7 +350,6 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
|
|||
onRowClick={onProductClick}
|
||||
pageInfo={pageInfo}
|
||||
products={mapEdgesToItems(voucher.products)}
|
||||
channelsCount={allChannelsCount}
|
||||
isChecked={isChecked}
|
||||
selected={selected}
|
||||
toggle={toggle}
|
||||
|
|
21
src/misc.ts
21
src/misc.ts
|
@ -9,8 +9,6 @@ import {
|
|||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { MultiAutocompleteChoiceType } from "./components/MultiAutocompleteSelectField";
|
||||
import { StatusType } from "./components/StatusChip/types";
|
||||
import { StatusLabelProps } from "./components/StatusLabel";
|
||||
import { AddressType, AddressTypeInput } from "./customers/types";
|
||||
import {
|
||||
commonStatusMessages,
|
||||
|
@ -21,6 +19,7 @@ import { OrderDetails_order_shippingAddress } from "./orders/types/OrderDetails"
|
|||
import {
|
||||
MutationResultAdditionalProps,
|
||||
PartialMutationProviderOutput,
|
||||
StatusType,
|
||||
UserError
|
||||
} from "./types";
|
||||
import {
|
||||
|
@ -81,7 +80,7 @@ export const removeDoubleSlashes = (url: string) =>
|
|||
export const transformPaymentStatus = (
|
||||
status: string,
|
||||
intl: IntlShape
|
||||
): { localized: string; status: StatusLabelProps["status"] } => {
|
||||
): { localized: string; status: StatusType } => {
|
||||
switch (status) {
|
||||
case PaymentChargeStatusEnum.PARTIALLY_CHARGED:
|
||||
return {
|
||||
|
@ -96,17 +95,17 @@ export const transformPaymentStatus = (
|
|||
case PaymentChargeStatusEnum.PARTIALLY_REFUNDED:
|
||||
return {
|
||||
localized: intl.formatMessage(paymentStatusMessages.partiallyRefunded),
|
||||
status: StatusType.ERROR
|
||||
status: StatusType.INFO
|
||||
};
|
||||
case PaymentChargeStatusEnum.FULLY_REFUNDED:
|
||||
return {
|
||||
localized: intl.formatMessage(paymentStatusMessages.refunded),
|
||||
status: StatusType.SUCCESS
|
||||
status: StatusType.INFO
|
||||
};
|
||||
case PaymentChargeStatusEnum.PENDING:
|
||||
return {
|
||||
localized: intl.formatMessage(paymentStatusMessages.pending),
|
||||
status: StatusType.NEUTRAL
|
||||
status: StatusType.WARNING
|
||||
};
|
||||
case PaymentChargeStatusEnum.REFUSED:
|
||||
return {
|
||||
|
@ -143,7 +142,7 @@ export const transformOrderStatus = (
|
|||
case OrderStatus.PARTIALLY_FULFILLED:
|
||||
return {
|
||||
localized: intl.formatMessage(orderStatusMessages.partiallyFulfilled),
|
||||
status: StatusType.NEUTRAL
|
||||
status: StatusType.WARNING
|
||||
};
|
||||
case OrderStatus.UNFULFILLED:
|
||||
return {
|
||||
|
@ -158,22 +157,22 @@ export const transformOrderStatus = (
|
|||
case OrderStatus.DRAFT:
|
||||
return {
|
||||
localized: intl.formatMessage(orderStatusMessages.draft),
|
||||
status: StatusType.ERROR
|
||||
status: StatusType.INFO
|
||||
};
|
||||
case OrderStatus.UNCONFIRMED:
|
||||
return {
|
||||
localized: intl.formatMessage(orderStatusMessages.unconfirmed),
|
||||
status: StatusType.NEUTRAL
|
||||
status: StatusType.INFO
|
||||
};
|
||||
case OrderStatus.PARTIALLY_RETURNED:
|
||||
return {
|
||||
localized: intl.formatMessage(orderStatusMessages.partiallyReturned),
|
||||
status: StatusType.NEUTRAL
|
||||
status: StatusType.INFO
|
||||
};
|
||||
case OrderStatus.RETURNED:
|
||||
return {
|
||||
localized: intl.formatMessage(orderStatusMessages.returned),
|
||||
status: StatusType.NEUTRAL
|
||||
status: StatusType.INFO
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
|
|
@ -7,7 +7,6 @@ import Form from "@saleor/components/Form";
|
|||
import Grid from "@saleor/components/Grid";
|
||||
import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import PageTitleWithStatusChip from "@saleor/components/PageTitleWithStatusChip";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import { SubmitPromise } from "@saleor/hooks/useForm";
|
||||
|
@ -36,8 +35,8 @@ import OrderFulfilledProductsCard from "../OrderFulfilledProductsCard";
|
|||
import OrderHistory, { FormData as HistoryFormData } from "../OrderHistory";
|
||||
import OrderInvoiceList from "../OrderInvoiceList";
|
||||
import OrderPayment from "../OrderPayment/OrderPayment";
|
||||
import OrderStatusChip from "../OrderStatusChip/OrderStatusChip";
|
||||
import OrderUnfulfilledProductsCard from "../OrderUnfulfilledProductsCard";
|
||||
import Title from "./Title";
|
||||
import { filteredConditionalItems, hasAnyItemsReplaceable } from "./utils";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
|
@ -224,11 +223,7 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
<PageHeader
|
||||
className={classes.header}
|
||||
inline
|
||||
title={
|
||||
<PageTitleWithStatusChip title={order?.number}>
|
||||
<OrderStatusChip order={order} />
|
||||
</PageTitleWithStatusChip>
|
||||
}
|
||||
title={<Title order={order} />}
|
||||
cardMenu={<CardMenu outlined menuItems={selectCardMenuItems} />}
|
||||
/>
|
||||
<div className={classes.date}>
|
||||
|
|
48
src/orders/components/OrderDetailsPage/Title.tsx
Normal file
48
src/orders/components/OrderDetailsPage/Title.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { makeStyles, Pill } from "@saleor/macaw-ui";
|
||||
import { transformOrderStatus } from "@saleor/misc";
|
||||
import { OrderDetails_order } from "@saleor/orders/types/OrderDetails";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
export interface TitleProps {
|
||||
order?: OrderDetails_order;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
container: {
|
||||
alignItems: "center",
|
||||
display: "flex"
|
||||
},
|
||||
statusContainer: {
|
||||
marginLeft: theme.spacing(2)
|
||||
}
|
||||
}),
|
||||
{ name: "OrderDetailsTitle" }
|
||||
);
|
||||
|
||||
const Title: React.FC<TitleProps> = props => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles(props);
|
||||
const { order } = props;
|
||||
|
||||
if (!order) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { localized, status } = transformOrderStatus(order.status, intl);
|
||||
|
||||
return (
|
||||
<div className={classes.container}>
|
||||
{intl.formatMessage(
|
||||
{ defaultMessage: "Order #{orderNumber}" },
|
||||
{ orderNumber: order?.number }
|
||||
)}
|
||||
<div className={classes.statusContainer}>
|
||||
<Pill label={localized} color={status} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Title;
|
|
@ -10,10 +10,9 @@ import { DateTime } from "@saleor/components/Date";
|
|||
import Money from "@saleor/components/Money";
|
||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import TableCellHeader from "@saleor/components/TableCellHeader";
|
||||
import TablePagination from "@saleor/components/TablePagination";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { makeStyles, Pill } from "@saleor/macaw-ui";
|
||||
import {
|
||||
maybe,
|
||||
renderCollection,
|
||||
|
@ -52,11 +51,15 @@ const useStyles = makeStyles(
|
|||
},
|
||||
colTotal: {}
|
||||
},
|
||||
pill: {
|
||||
maxWidth: "100%",
|
||||
...overflowing
|
||||
},
|
||||
colCustomer: overflowing,
|
||||
colDate: {},
|
||||
colFulfillment: overflowing,
|
||||
colFulfillment: {},
|
||||
colNumber: {},
|
||||
colPayment: overflowing,
|
||||
colPayment: {},
|
||||
colTotal: {
|
||||
textAlign: "right"
|
||||
},
|
||||
|
@ -227,8 +230,9 @@ export const OrderList: React.FC<OrderListProps> = props => {
|
|||
<TableCell className={classes.colPayment}>
|
||||
{maybe(() => order.paymentStatus.status) !== undefined ? (
|
||||
order.paymentStatus.status === null ? null : (
|
||||
<StatusLabel
|
||||
status={order.paymentStatus.status}
|
||||
<Pill
|
||||
className={classes.pill}
|
||||
color={order.paymentStatus.status}
|
||||
label={order.paymentStatus.localized}
|
||||
/>
|
||||
)
|
||||
|
@ -238,8 +242,9 @@ export const OrderList: React.FC<OrderListProps> = props => {
|
|||
</TableCell>
|
||||
<TableCell className={classes.colFulfillment}>
|
||||
{maybe(() => order.status) ? (
|
||||
<StatusLabel
|
||||
status={order.status.status}
|
||||
<Pill
|
||||
className={classes.pill}
|
||||
color={order.status.status}
|
||||
label={order.status.localized}
|
||||
/>
|
||||
) : (
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Card, CardContent } from "@material-ui/core";
|
||||
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import { Hr } from "@saleor/components/Hr";
|
||||
import Money from "@saleor/components/Money";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||
import { Button, makeStyles, Pill } from "@saleor/macaw-ui";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
@ -15,7 +15,7 @@ import {
|
|||
OrderStatus
|
||||
} from "../../../types/globalTypes";
|
||||
import { OrderDetails_order } from "../../types/OrderDetails";
|
||||
import messages from "./messages";
|
||||
import { orderPaymentMessages, paymentButtonMessages } from "./messages";
|
||||
import {
|
||||
extractOrderGiftCardUsedAmount,
|
||||
extractOutstandingBalance,
|
||||
|
@ -38,6 +38,9 @@ const useStyles = makeStyles(
|
|||
},
|
||||
totalRow: {
|
||||
fontWeight: 600
|
||||
},
|
||||
titleContainer: {
|
||||
display: "flex"
|
||||
}
|
||||
}),
|
||||
{ name: "OrderPayment" }
|
||||
|
@ -65,10 +68,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
const canMarkAsPaid = maybe(() => order.actions, []).includes(
|
||||
OrderAction.MARK_AS_PAID
|
||||
);
|
||||
const payment = transformPaymentStatus(
|
||||
maybe(() => order.paymentStatus),
|
||||
intl
|
||||
);
|
||||
const payment = transformPaymentStatus(order?.paymentStatus, intl);
|
||||
const refundedAmount = extractRefundedAmount(order);
|
||||
const outstandingBalance = extractOutstandingBalance(order);
|
||||
const usedGiftCardAmount = extractOrderGiftCardUsedAmount(order);
|
||||
|
@ -84,10 +84,10 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
|
||||
if (order.shippingMethodName === null) {
|
||||
return order.collectionPointName == null ? (
|
||||
<FormattedMessage {...messages.orderPaymentShippingDoesNotApply} />
|
||||
<FormattedMessage {...orderPaymentMessages.shippingDoesNotApply} />
|
||||
) : (
|
||||
<FormattedMessage
|
||||
{...messages.orderPaymentClickAndCollectShippingMethod}
|
||||
{...orderPaymentMessages.clickAndCollectShippingMethod}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -98,20 +98,21 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
<Card>
|
||||
<CardTitle
|
||||
title={
|
||||
maybe(() => order.paymentStatus) === undefined ? (
|
||||
!order?.paymentStatus ? (
|
||||
<Skeleton />
|
||||
) : (
|
||||
<div className={classes.header}>
|
||||
<StatusLabel label={payment.localized} status={payment.status} />
|
||||
<div className={classes.titleContainer}>
|
||||
<FormattedMessage {...orderPaymentMessages.paymentTitle} />
|
||||
<HorizontalSpacer spacing={2} />
|
||||
<Pill label={payment.localized} color={payment.status} />
|
||||
</div>
|
||||
{maybe(() => order.status) !== OrderStatus.CANCELED &&
|
||||
(canCapture || canRefund || canVoid || canMarkAsPaid) && (
|
||||
<div>
|
||||
{canCapture && (
|
||||
<Button variant="tertiary" onClick={onCapture}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Capture"
|
||||
description="capture payment, button"
|
||||
/>
|
||||
<FormattedMessage {...paymentButtonMessages.capture} />
|
||||
</Button>
|
||||
)}
|
||||
{canRefund && (
|
||||
|
@ -120,25 +121,18 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
onClick={onRefund}
|
||||
data-test-id="refund-button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Refund"
|
||||
description="button"
|
||||
/>
|
||||
<FormattedMessage {...paymentButtonMessages.refund} />
|
||||
</Button>
|
||||
)}
|
||||
{canVoid && (
|
||||
<Button variant="tertiary" onClick={onVoid}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Void"
|
||||
description="void payment, button"
|
||||
/>
|
||||
<FormattedMessage {...paymentButtonMessages.void} />
|
||||
</Button>
|
||||
)}
|
||||
{canMarkAsPaid && (
|
||||
<Button variant="tertiary" onClick={onMarkAsPaid}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Mark as paid"
|
||||
description="order, button"
|
||||
{...paymentButtonMessages.markAsPaid}
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
|
@ -153,18 +147,14 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Subtotal"
|
||||
description="order subtotal price"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.subtotal} />
|
||||
</td>
|
||||
<td>
|
||||
{maybe(() => order.lines) === undefined ? (
|
||||
<Skeleton />
|
||||
) : (
|
||||
<FormattedMessage
|
||||
defaultMessage="{quantity} items"
|
||||
description="ordered products"
|
||||
{...orderPaymentMessages.itemCount}
|
||||
values={{
|
||||
quantity: order.lines
|
||||
.map(line => line.quantity)
|
||||
|
@ -183,22 +173,15 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage defaultMessage="Taxes" />
|
||||
<FormattedMessage {...orderPaymentMessages.taxes} />
|
||||
</td>
|
||||
<td>
|
||||
{maybe(() => order.total.tax) === undefined ? (
|
||||
<Skeleton />
|
||||
) : order.total.tax.amount > 0 ? (
|
||||
intl.formatMessage({
|
||||
defaultMessage: "VAT included",
|
||||
description: "vat included in order price"
|
||||
})
|
||||
intl.formatMessage(orderPaymentMessages.vatIncluded)
|
||||
) : (
|
||||
intl.formatMessage({
|
||||
defaultMessage: "does not apply",
|
||||
description: "vat not included in order price",
|
||||
id: "orderPaymentVATDoesNotApply"
|
||||
})
|
||||
intl.formatMessage(orderPaymentMessages.vatNotIncluded)
|
||||
)}
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
|
@ -211,10 +194,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Shipping"
|
||||
description="order shipping method name"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.shipping} />
|
||||
</td>
|
||||
<td>{getDeliveryMethodName(order)}</td>
|
||||
<td className={classes.textRight}>
|
||||
|
@ -228,22 +208,13 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
{order?.discounts?.map(discount => (
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Discount"
|
||||
description="order discount"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.discount} />
|
||||
</td>
|
||||
<td>
|
||||
{discount.type === OrderDiscountType.MANUAL ? (
|
||||
<FormattedMessage
|
||||
defaultMessage="Staff added"
|
||||
description="staff added type order discount"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.staffAdded} />
|
||||
) : (
|
||||
<FormattedMessage
|
||||
defaultMessage="Voucher"
|
||||
description="voucher type order discount"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.voucher} />
|
||||
)}
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
|
@ -253,10 +224,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
))}
|
||||
<tr className={classes.totalRow}>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Total"
|
||||
description="order total price"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.total} />
|
||||
</td>
|
||||
<td />
|
||||
<td className={classes.textRight}>
|
||||
|
@ -278,8 +246,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Paid with Gift Card"
|
||||
description="order payment"
|
||||
{...orderPaymentMessages.paidWithGiftCard}
|
||||
/>
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
|
@ -294,10 +261,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
)}
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Preauthorized amount"
|
||||
description="order payment"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.preauthorized} />
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{maybe(() => order.totalAuthorized.amount) === undefined ? (
|
||||
|
@ -309,10 +273,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Captured amount"
|
||||
description="order payment"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.captured} />
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{maybe(() => order.totalCaptured.amount) === undefined ? (
|
||||
|
@ -324,10 +285,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Refunded amount"
|
||||
description="order payment"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.refunded} />
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{refundedAmount?.amount === undefined ? (
|
||||
|
@ -339,10 +297,7 @@ const OrderPayment: React.FC<OrderPaymentProps> = props => {
|
|||
</tr>
|
||||
<tr className={classes.totalRow}>
|
||||
<td>
|
||||
<FormattedMessage
|
||||
defaultMessage="Outstanding Balance"
|
||||
description="order payment"
|
||||
/>
|
||||
<FormattedMessage {...orderPaymentMessages.outstanding} />
|
||||
</td>
|
||||
<td className={classes.textRight}>
|
||||
{outstandingBalance?.amount === undefined ? (
|
||||
|
|
|
@ -1,14 +1,99 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
const messages = defineMessages({
|
||||
orderPaymentClickAndCollectShippingMethod: {
|
||||
export const orderPaymentMessages = defineMessages({
|
||||
clickAndCollectShippingMethod: {
|
||||
defaultMessage: "click&collect",
|
||||
description: "OrderPayment click&collect shipping method"
|
||||
},
|
||||
orderPaymentShippingDoesNotApply: {
|
||||
shippingDoesNotApply: {
|
||||
defaultMessage: "does not apply",
|
||||
description: "OrderPayment does not require shipping"
|
||||
},
|
||||
paymentTitle: {
|
||||
defaultMessage: "Payment status",
|
||||
description: "Payment card title"
|
||||
},
|
||||
subtotal: {
|
||||
defaultMessage: "Subtotal",
|
||||
description: "order subtotal price"
|
||||
},
|
||||
itemCount: {
|
||||
defaultMessage: "{quantity} items",
|
||||
description: "ordered products"
|
||||
},
|
||||
taxes: {
|
||||
defaultMessage: "Taxes"
|
||||
},
|
||||
vatIncluded: {
|
||||
defaultMessage: "VAT included",
|
||||
description: "vat included in order price"
|
||||
},
|
||||
vatNotIncluded: {
|
||||
defaultMessage: "does not apply",
|
||||
description: "vat not included in order price",
|
||||
id: "orderPaymentVATDoesNotApply"
|
||||
},
|
||||
shipping: {
|
||||
defaultMessage: "Shipping",
|
||||
description: "order shipping method name"
|
||||
},
|
||||
shippingNotApplicable: {
|
||||
defaultMessage: "does not apply",
|
||||
description: "order does not require shipping"
|
||||
},
|
||||
discount: {
|
||||
defaultMessage: "Discount",
|
||||
description: "order discount"
|
||||
},
|
||||
staffAdded: {
|
||||
defaultMessage: "Staff added",
|
||||
description: "staff added type order discount"
|
||||
},
|
||||
voucher: {
|
||||
defaultMessage: "Voucher",
|
||||
description: "voucher type order discount"
|
||||
},
|
||||
total: {
|
||||
defaultMessage: "Total",
|
||||
description: "order total price"
|
||||
},
|
||||
preauthorized: {
|
||||
defaultMessage: "Preauthorized amount",
|
||||
description: "order payment"
|
||||
},
|
||||
captured: {
|
||||
defaultMessage: "Captured amount",
|
||||
description: "order payment"
|
||||
},
|
||||
refunded: {
|
||||
defaultMessage: "Refunded amount",
|
||||
description: "order payment"
|
||||
},
|
||||
outstanding: {
|
||||
defaultMessage: "Outstanding Balance",
|
||||
description: "order payment"
|
||||
},
|
||||
paidWithGiftCard: {
|
||||
defaultMessage: "Paid with Gift Card",
|
||||
description: "order payment"
|
||||
}
|
||||
});
|
||||
|
||||
export default messages;
|
||||
export const paymentButtonMessages = defineMessages({
|
||||
capture: {
|
||||
defaultMessage: "Capture",
|
||||
description: "capture payment, button"
|
||||
},
|
||||
refund: {
|
||||
defaultMessage: "Refund",
|
||||
description: "button"
|
||||
},
|
||||
void: {
|
||||
defaultMessage: "Refund",
|
||||
description: "button"
|
||||
},
|
||||
markAsPaid: {
|
||||
defaultMessage: "Mark as paid",
|
||||
description: "order, button"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import DefaultCardTitle from "@saleor/components/CardTitle";
|
||||
import { StatusType } from "@saleor/components/StatusChip/types";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { makeStyles, Pill } from "@saleor/macaw-ui";
|
||||
import { StatusType } from "@saleor/types";
|
||||
import { FulfillmentStatus } from "@saleor/types/globalTypes";
|
||||
import camelCase from "lodash/camelCase";
|
||||
import React from "react";
|
||||
|
@ -14,7 +13,8 @@ const useStyles = makeStyles(
|
|||
theme => ({
|
||||
title: {
|
||||
width: "100%",
|
||||
display: "flex"
|
||||
display: "flex",
|
||||
justifyContent: "space-between"
|
||||
},
|
||||
orderNumber: {
|
||||
display: "inline",
|
||||
|
@ -22,6 +22,7 @@ const useStyles = makeStyles(
|
|||
},
|
||||
warehouseName: {
|
||||
float: "right",
|
||||
alignSelf: "center",
|
||||
color: theme.palette.text.secondary,
|
||||
margin: `auto ${theme.spacing(1)} auto auto`
|
||||
}
|
||||
|
@ -89,19 +90,19 @@ const selectStatus = (status: CardTitleStatus) => {
|
|||
case FulfillmentStatus.FULFILLED:
|
||||
return StatusType.SUCCESS;
|
||||
case FulfillmentStatus.REFUNDED:
|
||||
return StatusType.NEUTRAL;
|
||||
return StatusType.INFO;
|
||||
case FulfillmentStatus.RETURNED:
|
||||
return StatusType.NEUTRAL;
|
||||
return StatusType.INFO;
|
||||
case FulfillmentStatus.REPLACED:
|
||||
return StatusType.NEUTRAL;
|
||||
return StatusType.INFO;
|
||||
case FulfillmentStatus.REFUNDED_AND_RETURNED:
|
||||
return StatusType.NEUTRAL;
|
||||
return StatusType.INFO;
|
||||
case FulfillmentStatus.WAITING_FOR_APPROVAL:
|
||||
return StatusType.ALERT;
|
||||
return StatusType.WARNING;
|
||||
case FulfillmentStatus.CANCELED:
|
||||
return StatusType.ERROR;
|
||||
default:
|
||||
return StatusType.ALERT;
|
||||
return StatusType.WARNING;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -130,36 +131,40 @@ const CardTitle: React.FC<CardTitleProps> = ({
|
|||
);
|
||||
|
||||
const title = (
|
||||
<div className={classes.title}>
|
||||
<>
|
||||
{intl.formatMessage(messageForStatus, {
|
||||
fulfillmentName,
|
||||
quantity: totalQuantity
|
||||
})}
|
||||
<Typography className={classes.orderNumber} variant="body1">
|
||||
{fulfillmentName}
|
||||
</Typography>
|
||||
{!!warehouseName && (
|
||||
<Typography className={classes.warehouseName} variant="caption">
|
||||
<FormattedMessage
|
||||
{...messages.fulfilledFrom}
|
||||
values={{
|
||||
warehouseName
|
||||
}}
|
||||
/>
|
||||
{fulfillmentName && (
|
||||
<Typography className={classes.orderNumber} variant="body1">
|
||||
{fulfillmentName}
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<DefaultCardTitle
|
||||
toolbar={toolbar}
|
||||
title={
|
||||
withStatus ? (
|
||||
<StatusLabel label={title} status={selectStatus(status)} />
|
||||
) : (
|
||||
title
|
||||
)
|
||||
<div className={classes.title}>
|
||||
{withStatus ? (
|
||||
<Pill label={title} color={selectStatus(status)} />
|
||||
) : (
|
||||
title
|
||||
)}
|
||||
{!!warehouseName && (
|
||||
<Typography className={classes.warehouseName} variant="caption">
|
||||
<FormattedMessage
|
||||
{...messages.fulfilledFrom}
|
||||
values={{
|
||||
warehouseName
|
||||
}}
|
||||
/>
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import StatusChip from "@saleor/components/StatusChip";
|
||||
import { transformOrderStatus } from "@saleor/misc";
|
||||
import { OrderDetails_order } from "@saleor/orders/types/OrderDetails";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
interface OrderStatusChipProps {
|
||||
order?: OrderDetails_order;
|
||||
}
|
||||
|
||||
const OrderStatusChip: React.FC<OrderStatusChipProps> = ({ order }) => {
|
||||
const intl = useIntl();
|
||||
|
||||
if (!order) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { localized, status } = transformOrderStatus(order.status, intl);
|
||||
|
||||
return <StatusChip size="md" status={status} label={localized} />;
|
||||
};
|
||||
|
||||
export default OrderStatusChip;
|
|
@ -8,11 +8,10 @@ import {
|
|||
import Checkbox from "@saleor/components/Checkbox";
|
||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import TableCellHeader from "@saleor/components/TableCellHeader";
|
||||
import TableHead from "@saleor/components/TableHead";
|
||||
import TablePagination from "@saleor/components/TablePagination";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { makeStyles, Pill } from "@saleor/macaw-ui";
|
||||
import { maybe, renderCollection } from "@saleor/misc";
|
||||
import { PageListUrlSortField } from "@saleor/pages/urls";
|
||||
import { ListActions, ListProps, SortPage } from "@saleor/types";
|
||||
|
@ -179,7 +178,7 @@ const PageList: React.FC<PageListProps> = props => {
|
|||
<TableCell className={classes.colVisibility}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => (
|
||||
<StatusLabel
|
||||
<Pill
|
||||
label={
|
||||
page.isPublished
|
||||
? intl.formatMessage({
|
||||
|
@ -191,7 +190,7 @@ const PageList: React.FC<PageListProps> = props => {
|
|||
description: "page status"
|
||||
})
|
||||
}
|
||||
status={page.isPublished ? "success" : "error"}
|
||||
color={page.isPublished ? "success" : "error"}
|
||||
/>
|
||||
),
|
||||
<Skeleton />
|
||||
|
|
|
@ -1,27 +1,12 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import { statusLabelMessages } from "@saleor/components/StatusLabel/messages";
|
||||
import { Pill } from "@saleor/macaw-ui";
|
||||
import { Plugins_plugins_edges_node } from "@saleor/plugins/types/Plugins";
|
||||
import { isPluginGlobal } from "@saleor/plugins/views/utils";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { pluginStatusMessages } from "./messages";
|
||||
import { pluginAvailabilityStatusMessages as messages } from "./messages";
|
||||
import {
|
||||
getActiveChannelConfigsCount,
|
||||
getAllChannelConfigsCount
|
||||
} from "./utils";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
() => ({
|
||||
horizontalContainer: {
|
||||
display: "flex",
|
||||
flexDirection: "row"
|
||||
}
|
||||
}),
|
||||
{ name: "ChannelStatusLabel" }
|
||||
);
|
||||
import { getActiveChannelConfigsCount } from "./utils";
|
||||
|
||||
interface PluginAvailabilityStatusProps {
|
||||
plugin: Plugins_plugins_edges_node;
|
||||
|
@ -30,7 +15,6 @@ interface PluginAvailabilityStatusProps {
|
|||
const PluginAvailabilityStatus: React.FC<PluginAvailabilityStatusProps> = ({
|
||||
plugin: { globalConfiguration, channelConfigurations }
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
const intl = useIntl();
|
||||
|
||||
const isGlobalPlugin = isPluginGlobal(globalConfiguration);
|
||||
|
@ -45,26 +29,21 @@ const PluginAvailabilityStatus: React.FC<PluginAvailabilityStatusProps> = ({
|
|||
|
||||
const globalPluginLabel = intl.formatMessage(
|
||||
isStatusActive
|
||||
? statusLabelMessages.active
|
||||
: statusLabelMessages.deactivated
|
||||
? pluginStatusMessages.active
|
||||
: pluginStatusMessages.deactivated
|
||||
);
|
||||
|
||||
return (
|
||||
<StatusLabel
|
||||
<Pill
|
||||
label={
|
||||
isGlobalPlugin ? (
|
||||
globalPluginLabel
|
||||
) : (
|
||||
<div className={classes.horizontalContainer}>
|
||||
<Typography>
|
||||
{`${intl.formatMessage(messages.channelTitle, {
|
||||
activeChannelsCount
|
||||
})}/${getAllChannelConfigsCount(channelConfigurations)}`}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
isGlobalPlugin
|
||||
? globalPluginLabel
|
||||
: intl.formatMessage(messages.channelTitle, {
|
||||
activeChannelsCount
|
||||
})
|
||||
}
|
||||
status={isStatusActive ? "success" : "error"}
|
||||
color={isStatusActive ? "success" : "error"}
|
||||
onClick={() => null} // required for dashed border
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
import { CardContent, Divider, Typography } from "@material-ui/core";
|
||||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import CollectionWithDividers from "@saleor/components/CollectionWithDividers";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import { statusLabelMessages } from "@saleor/components/StatusLabel/messages";
|
||||
import { PluginBaseFragment } from "@saleor/fragments/types/PluginBaseFragment";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { channelConfigPluginMessages as messages } from "../messages";
|
||||
import {
|
||||
getActiveChannelConfigsCount,
|
||||
getAllChannelConfigsCount
|
||||
} from "../utils";
|
||||
import ScrollableContent from "./ScrollableContent";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
itemContainer: {
|
||||
padding: theme.spacing(0, 4)
|
||||
}
|
||||
}),
|
||||
{ name: "ChannelConfigPluginPopupBody" }
|
||||
);
|
||||
|
||||
interface ChannelConfigPluginPopupBodyProps {
|
||||
plugin: PluginBaseFragment;
|
||||
}
|
||||
|
||||
const ChannelConfigPluginPopupBody: React.FC<ChannelConfigPluginPopupBodyProps> = ({
|
||||
plugin: { channelConfigurations }
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
|
||||
return (
|
||||
<>
|
||||
<CardContent>
|
||||
<Typography>
|
||||
{intl.formatMessage(messages.title, {
|
||||
allChannelsCount: getAllChannelConfigsCount(channelConfigurations),
|
||||
activeChannelsCount: getActiveChannelConfigsCount(
|
||||
channelConfigurations
|
||||
)
|
||||
})}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<Divider />
|
||||
<ScrollableContent>
|
||||
<CardSpacer />
|
||||
<CollectionWithDividers
|
||||
collection={channelConfigurations}
|
||||
DividerComponent={CardSpacer}
|
||||
renderItem={({ channel, active }) => (
|
||||
<div className={classes.itemContainer}>
|
||||
<StatusLabel
|
||||
key={channel.id}
|
||||
label={channel.name}
|
||||
status={active ? "success" : "error"}
|
||||
subtitle={intl.formatMessage(
|
||||
active
|
||||
? statusLabelMessages.active
|
||||
: statusLabelMessages.inactive
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<CardSpacer />
|
||||
</ScrollableContent>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChannelConfigPluginPopupBody;
|
|
@ -1,12 +1,12 @@
|
|||
import { CardContent, Typography } from "@material-ui/core";
|
||||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import { statusLabelMessages } from "@saleor/components/StatusLabel/messages";
|
||||
import { PluginBaseFragment } from "@saleor/fragments/types/PluginBaseFragment";
|
||||
import { Pill } from "@saleor/macaw-ui";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { globalConfigPluginMessages as messages } from "../messages";
|
||||
import { pluginStatusMessages } from "../messages";
|
||||
|
||||
interface GlobalConfigPluginPopupBodyProps {
|
||||
plugin: PluginBaseFragment;
|
||||
|
@ -28,10 +28,12 @@ const GlobalConfigPluginPopupBody: React.FC<GlobalConfigPluginPopupBodyProps> =
|
|||
{intl.formatMessage(messages.description)}
|
||||
</Typography>
|
||||
<CardSpacer />
|
||||
<StatusLabel
|
||||
status={active ? "success" : "error"}
|
||||
<Pill
|
||||
color={active ? "success" : "error"}
|
||||
label={intl.formatMessage(
|
||||
active ? statusLabelMessages.active : statusLabelMessages.inactive
|
||||
active
|
||||
? pluginStatusMessages.active
|
||||
: pluginStatusMessages.deactivated
|
||||
)}
|
||||
/>
|
||||
</CardContent>
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import { Card, Popper } from "@material-ui/core";
|
||||
import ChannelsAvailabilityMenuContent from "@saleor/components/ChannelsAvailabilityMenuContent";
|
||||
import { PluginBaseFragment } from "@saleor/fragments/types/PluginBaseFragment";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { isPluginGlobal } from "@saleor/plugins/views/utils";
|
||||
import React from "react";
|
||||
|
||||
import ChannelConfigPluginPopupBody from "./ChannelConfigPluginPopupBody";
|
||||
import { mapPluginsToPills } from "../utils";
|
||||
import GlobalConfigPluginPopupBody from "./GlobalConfigPluginPopupBody";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
() => ({
|
||||
container: {
|
||||
maxWidth: 300,
|
||||
maxWidth: 500,
|
||||
zIndex: 1000
|
||||
}
|
||||
}),
|
||||
|
@ -43,7 +44,9 @@ const PluginAvailabilityStatusPopup: React.FC<PluginAvailabilityStatusPopupProps
|
|||
{isGlobalPlugin ? (
|
||||
<GlobalConfigPluginPopupBody plugin={plugin} />
|
||||
) : (
|
||||
<ChannelConfigPluginPopupBody plugin={plugin} />
|
||||
<ChannelsAvailabilityMenuContent
|
||||
pills={mapPluginsToPills(plugin.channelConfigurations)}
|
||||
/>
|
||||
)}
|
||||
</Card>
|
||||
</Popper>
|
||||
|
|
|
@ -2,7 +2,8 @@ import { defineMessages } from "react-intl";
|
|||
|
||||
export const pluginAvailabilityStatusMessages = defineMessages({
|
||||
channelTitle: {
|
||||
defaultMessage: "Active in {activeChannelsCount}",
|
||||
defaultMessage:
|
||||
"{activeChannelsCount,plural, =0 {Deactivated} other {Active in {activeChannelsCount}}}",
|
||||
description: "plugin channel availability status title"
|
||||
}
|
||||
});
|
||||
|
@ -54,3 +55,14 @@ export const pluginChannelConfigurationCellMessages = defineMessages({
|
|||
id: "pluginChannelConfigurationCellMessages per channel"
|
||||
}
|
||||
});
|
||||
|
||||
export const pluginStatusMessages = defineMessages({
|
||||
active: {
|
||||
defaultMessage: "Active",
|
||||
description: "status label active"
|
||||
},
|
||||
deactivated: {
|
||||
defaultMessage: "Deactivated",
|
||||
description: "status label deactivated"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { Pill } from "@saleor/components/ChannelsAvailabilityMenuContent";
|
||||
import { PluginConfigurationBaseFragment } from "@saleor/fragments/types/PluginConfigurationBaseFragment";
|
||||
import { PillColor } from "@saleor/macaw-ui";
|
||||
import { MessageDescriptor } from "react-intl";
|
||||
|
||||
import { pluginStatusMessages } from "./messages";
|
||||
|
||||
export const getAllChannelConfigsCount = (
|
||||
channelConfigurations: PluginConfigurationBaseFragment[]
|
||||
|
@ -7,3 +12,22 @@ export const getAllChannelConfigsCount = (
|
|||
export const getActiveChannelConfigsCount = (
|
||||
channelConfigurations: PluginConfigurationBaseFragment[]
|
||||
) => channelConfigurations?.filter(({ active }) => !!active).length;
|
||||
|
||||
export const getPluginStatusLabel = (
|
||||
channelData: PluginConfigurationBaseFragment
|
||||
): MessageDescriptor =>
|
||||
channelData.active
|
||||
? pluginStatusMessages.active
|
||||
: pluginStatusMessages.deactivated;
|
||||
export const getPluginStatusColor = (
|
||||
channelData: PluginConfigurationBaseFragment
|
||||
): PillColor => (channelData.active ? "success" : "error");
|
||||
|
||||
export const mapPluginsToPills = (
|
||||
channelConfigurations: PluginConfigurationBaseFragment[]
|
||||
): Pill[] =>
|
||||
channelConfigurations.map(channel => ({
|
||||
channel: channel.channel,
|
||||
color: getPluginStatusColor(channel),
|
||||
label: getPluginStatusLabel(channel)
|
||||
}));
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { IFilter, IFilterElement } from "@saleor/components/Filter";
|
||||
import { statusLabelMessages } from "@saleor/components/StatusLabel/messages";
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import { AutocompleteFilterOpts, FilterOpts } from "@saleor/types";
|
||||
import { PluginConfigurationType } from "@saleor/types/globalTypes";
|
||||
|
@ -10,7 +9,10 @@ import {
|
|||
} from "@saleor/utils/filters/fields";
|
||||
import { defineMessages, IntlShape } from "react-intl";
|
||||
|
||||
import { pluginChannelConfigurationCellMessages } from "../PluginsList/messages";
|
||||
import {
|
||||
pluginChannelConfigurationCellMessages,
|
||||
pluginStatusMessages
|
||||
} from "../PluginsList/messages";
|
||||
|
||||
export enum PluginFilterKeys {
|
||||
active = "active",
|
||||
|
@ -58,8 +60,8 @@ export function createFilterStructure(
|
|||
intl.formatMessage(messages.channelStatusSectionSubtitle),
|
||||
opts.isActive.value,
|
||||
{
|
||||
negative: intl.formatMessage(statusLabelMessages.inactive),
|
||||
positive: intl.formatMessage(statusLabelMessages.active)
|
||||
negative: intl.formatMessage(pluginStatusMessages.deactivated),
|
||||
positive: intl.formatMessage(pluginStatusMessages.active)
|
||||
}
|
||||
)
|
||||
},
|
||||
|
|
|
@ -5,8 +5,11 @@ import {
|
|||
TableRow,
|
||||
Typography
|
||||
} from "@material-ui/core";
|
||||
import AvailabilityStatusLabel from "@saleor/components/AvailabilityStatusLabel";
|
||||
import { ChannelsAvailabilityDropdown } from "@saleor/components/ChannelsAvailabilityDropdown";
|
||||
import {
|
||||
getChannelAvailabilityColor,
|
||||
getChannelAvailabilityLabel
|
||||
} from "@saleor/components/ChannelsAvailabilityDropdown/utils";
|
||||
import Checkbox from "@saleor/components/Checkbox";
|
||||
import Date from "@saleor/components/Date";
|
||||
import MoneyRange from "@saleor/components/MoneyRange";
|
||||
|
@ -20,7 +23,7 @@ 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 { makeStyles } from "@saleor/macaw-ui";
|
||||
import { makeStyles, Pill } from "@saleor/macaw-ui";
|
||||
import { maybe, renderCollection } from "@saleor/misc";
|
||||
import {
|
||||
getAttributeIdFromColumnValue,
|
||||
|
@ -39,7 +42,7 @@ import classNames from "classnames";
|
|||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { columnsMessages, messages } from "./messages";
|
||||
import { columnsMessages } from "./messages";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
|
@ -116,13 +119,11 @@ interface ProductListProps
|
|||
gridAttributes: GridAttributes_grid_edges_node[];
|
||||
products: ProductList_products_edges_node[];
|
||||
loading: boolean;
|
||||
channelsCount: number;
|
||||
}
|
||||
|
||||
export const ProductList: React.FC<ProductListProps> = props => {
|
||||
const {
|
||||
activeAttributeSortId,
|
||||
channelsCount,
|
||||
settings,
|
||||
disabled,
|
||||
isChecked,
|
||||
|
@ -397,20 +398,19 @@ export const ProductList: React.FC<ProductListProps> = props => {
|
|||
!!product?.channelListings?.length
|
||||
}
|
||||
>
|
||||
{(!product && <Skeleton />) ||
|
||||
(!product?.channelListings?.length && "-") ||
|
||||
(product?.channelListings !== undefined && channel ? (
|
||||
<AvailabilityStatusLabel
|
||||
channel={channel}
|
||||
messages={messages}
|
||||
{(product &&
|
||||
(channel ? (
|
||||
<Pill
|
||||
label={intl.formatMessage(
|
||||
getChannelAvailabilityLabel(channel)
|
||||
)}
|
||||
color={getChannelAvailabilityColor(channel)}
|
||||
/>
|
||||
) : (
|
||||
<ChannelsAvailabilityDropdown
|
||||
allChannelsCount={channelsCount}
|
||||
channels={product?.channelListings}
|
||||
showStatus
|
||||
/>
|
||||
))}
|
||||
))) ?? <Skeleton />}
|
||||
</TableCell>
|
||||
</DisplayColumn>
|
||||
{gridAttributesFromSettings.map(gridAttribute => (
|
||||
|
|
|
@ -245,7 +245,6 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
|
|||
loading={loading}
|
||||
gridAttributes={gridAttributes}
|
||||
settings={settings}
|
||||
channelsCount={channelsCount}
|
||||
selectedChannelId={selectedChannelId}
|
||||
onUpdateListSettings={onUpdateListSettings}
|
||||
filterDependency={filterDependency}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,7 +36,6 @@ function loadStories() {
|
|||
require("./stories/components/SaveFilterTabDialog");
|
||||
require("./stories/components/SingleSelectField");
|
||||
require("./stories/components/Skeleton");
|
||||
require("./stories/components/StatusLabel");
|
||||
require("./stories/components/TablePagination");
|
||||
require("./stories/components/Timeline");
|
||||
require("./stories/components/Weight");
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
import StatusLabel from "@saleor/components/StatusLabel";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import CardDecorator from "../../CardDecorator";
|
||||
import Decorator from "../../Decorator";
|
||||
|
||||
storiesOf("Generics / StatusLabel", module)
|
||||
.addDecorator(CardDecorator)
|
||||
.addDecorator(Decorator)
|
||||
.add("when success", () => (
|
||||
<StatusLabel label="Example label" status="success" />
|
||||
))
|
||||
.add("when neutral", () => (
|
||||
<StatusLabel label="Example label" status="neutral" />
|
||||
))
|
||||
.add("when error", () => (
|
||||
<StatusLabel label="Example label" status="error" />
|
||||
));
|
|
@ -217,3 +217,10 @@ export interface AutocompleteFilterOpts
|
|||
}
|
||||
|
||||
export type Ids = string[];
|
||||
|
||||
export enum StatusType {
|
||||
INFO = "info",
|
||||
ERROR = "error",
|
||||
WARNING = "warning",
|
||||
SUCCESS = "success"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue