Add permission-based restrictions in Customer views (#1879)
* Update customer queries - add permissions * Filter the customer filter by permissions * Code refactor + optionally render components based on permissions * Update stories * Minor code refactor * Move useUserPermissions to RequirePermissions component * Change user provider component name * Change macaw-ui version
This commit is contained in:
parent
8ab05ab8e1
commit
9a7c9a3bc3
33 changed files with 257 additions and 453 deletions
|
@ -28,7 +28,7 @@
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.58",
|
"@material-ui/lab": "^4.0.0-alpha.58",
|
||||||
"@material-ui/styles": "^4.11.4",
|
"@material-ui/styles": "^4.11.4",
|
||||||
"@saleor/macaw-ui": "^0.3.1",
|
"@saleor/macaw-ui": "0.3.1",
|
||||||
"@saleor/sdk": "^0.4.2",
|
"@saleor/sdk": "^0.4.2",
|
||||||
"@sentry/react": "^6.0.0",
|
"@sentry/react": "^6.0.0",
|
||||||
"@types/faker": "^5.1.6",
|
"@types/faker": "^5.1.6",
|
||||||
|
|
3
src/auth/hooks/useUserPermissions.ts
Normal file
3
src/auth/hooks/useUserPermissions.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { useUser } from "..";
|
||||||
|
|
||||||
|
export const useUserPermissions = () => useUser().user?.userPermissions;
|
|
@ -1,5 +1,4 @@
|
||||||
import { Card, CardContent, Typography } from "@material-ui/core";
|
import { Card, CardContent, Typography } from "@material-ui/core";
|
||||||
import { useUser } from "@saleor/auth";
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import Hr from "@saleor/components/Hr";
|
import Hr from "@saleor/components/Hr";
|
||||||
import RequirePermissions from "@saleor/components/RequirePermissions";
|
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||||
|
@ -28,7 +27,6 @@ export const ChannelsAvailabilityWrapper: React.FC<ChannelsAvailabilityWrapperPr
|
||||||
} = props;
|
} = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const classes = useStyles({});
|
const classes = useStyles({});
|
||||||
const { user } = useUser();
|
|
||||||
const channelsAvailabilityText = intl.formatMessage(
|
const channelsAvailabilityText = intl.formatMessage(
|
||||||
{
|
{
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
|
@ -51,10 +49,7 @@ export const ChannelsAvailabilityWrapper: React.FC<ChannelsAvailabilityWrapperPr
|
||||||
description: "section header"
|
description: "section header"
|
||||||
})}
|
})}
|
||||||
toolbar={
|
toolbar={
|
||||||
<RequirePermissions
|
<RequirePermissions requiredPermissions={managePermissions}>
|
||||||
userPermissions={user?.userPermissions || []}
|
|
||||||
requiredPermissions={managePermissions}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
onClick={openModal}
|
onClick={openModal}
|
||||||
data-test-id="channels-availability-manage-button"
|
data-test-id="channels-availability-manage-button"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { FetchMoreProps, SearchPageProps } from "@saleor/types";
|
import { FetchMoreProps, SearchPageProps } from "@saleor/types";
|
||||||
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import { MessageDescriptor } from "react-intl";
|
import { MessageDescriptor } from "react-intl";
|
||||||
|
|
||||||
import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
|
import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
|
||||||
|
@ -34,6 +35,7 @@ export interface IFilterElement<T extends string = string>
|
||||||
multipleFields?: IFilterElement[];
|
multipleFields?: IFilterElement[];
|
||||||
id?: string;
|
id?: string;
|
||||||
dependencies?: string[];
|
dependencies?: string[];
|
||||||
|
permissions?: PermissionEnum[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FilterBaseFieldProps<T extends string = string> {
|
export interface FilterBaseFieldProps<T extends string = string> {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { useUserPermissions } from "@saleor/auth/hooks/useUserPermissions";
|
||||||
import { User_userPermissions } from "@saleor/fragments/types/User";
|
import { User_userPermissions } from "@saleor/fragments/types/User";
|
||||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -16,15 +17,19 @@ export function hasPermissions(
|
||||||
export interface RequirePermissionsProps {
|
export interface RequirePermissionsProps {
|
||||||
children: React.ReactNode | React.ReactNodeArray;
|
children: React.ReactNode | React.ReactNodeArray;
|
||||||
requiredPermissions: PermissionEnum[];
|
requiredPermissions: PermissionEnum[];
|
||||||
userPermissions: User_userPermissions[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const RequirePermissions: React.FC<RequirePermissionsProps> = ({
|
const RequirePermissions: React.FC<RequirePermissionsProps> = ({
|
||||||
children,
|
children,
|
||||||
requiredPermissions,
|
requiredPermissions
|
||||||
userPermissions
|
}) => {
|
||||||
}) =>
|
const userPermissions = useUserPermissions();
|
||||||
hasPermissions(userPermissions, requiredPermissions) ? <>{children}</> : null;
|
|
||||||
|
return userPermissions &&
|
||||||
|
hasPermissions(userPermissions, requiredPermissions) ? (
|
||||||
|
<>{children}</>
|
||||||
|
) : null;
|
||||||
|
};
|
||||||
|
|
||||||
RequirePermissions.displayName = "RequirePermissions";
|
RequirePermissions.displayName = "RequirePermissions";
|
||||||
export default RequirePermissions;
|
export default RequirePermissions;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import Grid from "@saleor/components/Grid";
|
||||||
import Metadata from "@saleor/components/Metadata/Metadata";
|
import Metadata from "@saleor/components/Metadata/Metadata";
|
||||||
import { MetadataFormData } from "@saleor/components/Metadata/types";
|
import { MetadataFormData } from "@saleor/components/Metadata/types";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
|
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||||
import Savebar from "@saleor/components/Savebar";
|
import Savebar from "@saleor/components/Savebar";
|
||||||
import { UpdateCustomer_customerUpdate_errors } from "@saleor/customers/types/UpdateCustomer";
|
import { UpdateCustomer_customerUpdate_errors } from "@saleor/customers/types/UpdateCustomer";
|
||||||
import { AccountErrorFragment } from "@saleor/fragments/types/AccountErrorFragment";
|
import { AccountErrorFragment } from "@saleor/fragments/types/AccountErrorFragment";
|
||||||
|
@ -13,6 +14,7 @@ import { SubmitPromise } from "@saleor/hooks/useForm";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||||
import { Backlink } from "@saleor/macaw-ui";
|
import { Backlink } from "@saleor/macaw-ui";
|
||||||
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import { mapEdgesToItems, mapMetadataItemToInput } from "@saleor/utils/maps";
|
import { mapEdgesToItems, mapMetadataItemToInput } from "@saleor/utils/maps";
|
||||||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -105,12 +107,16 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
|
||||||
onChange={change}
|
onChange={change}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<CustomerOrders
|
<RequirePermissions
|
||||||
orders={mapEdgesToItems(customer?.orders)}
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
onViewAllOrdersClick={onViewAllOrdersClick}
|
>
|
||||||
onRowClick={onRowClick}
|
<CustomerOrders
|
||||||
/>
|
orders={mapEdgesToItems(customer?.orders)}
|
||||||
<CardSpacer />
|
onViewAllOrdersClick={onViewAllOrdersClick}
|
||||||
|
onRowClick={onRowClick}
|
||||||
|
/>
|
||||||
|
<CardSpacer />
|
||||||
|
</RequirePermissions>
|
||||||
<Metadata data={data} onChange={changeMetadata} />
|
<Metadata data={data} onChange={changeMetadata} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -122,7 +128,11 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<CustomerStats customer={customer} />
|
<CustomerStats customer={customer} />
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<CustomerGiftCardsCard />
|
<RequirePermissions
|
||||||
|
requiredPermissions={[PermissionEnum.MANAGE_GIFT_CARD]}
|
||||||
|
>
|
||||||
|
<CustomerGiftCardsCard />
|
||||||
|
</RequirePermissions>
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Savebar
|
<Savebar
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core";
|
import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core";
|
||||||
|
import { useUserPermissions } from "@saleor/auth/hooks/useUserPermissions";
|
||||||
import Checkbox from "@saleor/components/Checkbox";
|
import Checkbox from "@saleor/components/Checkbox";
|
||||||
|
import RequirePermissions, {
|
||||||
|
hasPermissions
|
||||||
|
} from "@saleor/components/RequirePermissions";
|
||||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import TableCellHeader from "@saleor/components/TableCellHeader";
|
import TableCellHeader from "@saleor/components/TableCellHeader";
|
||||||
|
@ -7,8 +11,9 @@ import TableHead from "@saleor/components/TableHead";
|
||||||
import TablePagination from "@saleor/components/TablePagination";
|
import TablePagination from "@saleor/components/TablePagination";
|
||||||
import { CustomerListUrlSortField } from "@saleor/customers/urls";
|
import { CustomerListUrlSortField } from "@saleor/customers/urls";
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
import { getUserName, maybe, renderCollection } from "@saleor/misc";
|
import { getUserName, renderCollection } from "@saleor/misc";
|
||||||
import { ListActions, ListProps, SortPage } from "@saleor/types";
|
import { ListActions, ListProps, SortPage } from "@saleor/types";
|
||||||
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
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 } from "react-intl";
|
||||||
|
@ -45,7 +50,7 @@ export interface CustomerListProps
|
||||||
customers: ListCustomers_customers_edges_node[];
|
customers: ListCustomers_customers_edges_node[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const numberOfColumns = 4;
|
const numberOfColumns = 3;
|
||||||
|
|
||||||
const CustomerList: React.FC<CustomerListProps> = props => {
|
const CustomerList: React.FC<CustomerListProps> = props => {
|
||||||
const {
|
const {
|
||||||
|
@ -66,12 +71,18 @@ const CustomerList: React.FC<CustomerListProps> = props => {
|
||||||
isChecked
|
isChecked
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const userPermissions = useUserPermissions();
|
||||||
|
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ResponsiveTable>
|
<ResponsiveTable>
|
||||||
<TableHead
|
<TableHead
|
||||||
colSpan={numberOfColumns}
|
colSpan={
|
||||||
|
hasPermissions(userPermissions, [PermissionEnum.MANAGE_ORDERS])
|
||||||
|
? numberOfColumns
|
||||||
|
: numberOfColumns - 1
|
||||||
|
}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
items={customers}
|
items={customers}
|
||||||
|
@ -101,18 +112,22 @@ const CustomerList: React.FC<CustomerListProps> = props => {
|
||||||
>
|
>
|
||||||
<FormattedMessage defaultMessage="Customer Email" />
|
<FormattedMessage defaultMessage="Customer Email" />
|
||||||
</TableCellHeader>
|
</TableCellHeader>
|
||||||
<TableCellHeader
|
<RequirePermissions
|
||||||
direction={
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
sort.sort === CustomerListUrlSortField.orders
|
|
||||||
? getArrowDirection(sort.asc)
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
textAlign="center"
|
|
||||||
onClick={() => onSort(CustomerListUrlSortField.orders)}
|
|
||||||
className={classes.colOrders}
|
|
||||||
>
|
>
|
||||||
<FormattedMessage defaultMessage="No. of Orders" />
|
<TableCellHeader
|
||||||
</TableCellHeader>
|
direction={
|
||||||
|
sort.sort === CustomerListUrlSortField.orders
|
||||||
|
? getArrowDirection(sort.asc)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
textAlign="center"
|
||||||
|
onClick={() => onSort(CustomerListUrlSortField.orders)}
|
||||||
|
className={classes.colOrders}
|
||||||
|
>
|
||||||
|
<FormattedMessage defaultMessage="No. of Orders" />
|
||||||
|
</TableCellHeader>
|
||||||
|
</RequirePermissions>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableFooter>
|
<TableFooter>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
@ -155,14 +170,15 @@ const CustomerList: React.FC<CustomerListProps> = props => {
|
||||||
{getUserName(customer)}
|
{getUserName(customer)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className={classes.colEmail}>
|
<TableCell className={classes.colEmail}>
|
||||||
{maybe<React.ReactNode>(() => customer.email, <Skeleton />)}
|
{customer?.email ?? <Skeleton />}
|
||||||
</TableCell>
|
|
||||||
<TableCell className={classes.colOrders}>
|
|
||||||
{maybe<React.ReactNode>(
|
|
||||||
() => customer.orders.totalCount,
|
|
||||||
<Skeleton />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<RequirePermissions
|
||||||
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
|
>
|
||||||
|
<TableCell className={classes.colOrders}>
|
||||||
|
{customer?.orders?.totalCount ?? <Skeleton />}
|
||||||
|
</TableCell>
|
||||||
|
</RequirePermissions>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Card } from "@material-ui/core";
|
import { Card } from "@material-ui/core";
|
||||||
|
import { useUserPermissions } from "@saleor/auth/hooks/useUserPermissions";
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
import FilterBar from "@saleor/components/FilterBar";
|
import FilterBar from "@saleor/components/FilterBar";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
|
@ -48,7 +49,8 @@ const CustomerListPage: React.FC<CustomerListPageProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const structure = createFilterStructure(intl, filterOpts);
|
const userPermissions = useUserPermissions();
|
||||||
|
const structure = createFilterStructure(intl, filterOpts, userPermissions);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { IFilter } from "@saleor/components/Filter";
|
import { IFilter } from "@saleor/components/Filter";
|
||||||
|
import { hasPermissions } from "@saleor/components/RequirePermissions";
|
||||||
|
import { User_userPermissions } from "@saleor/fragments/types/User";
|
||||||
import { FilterOpts, MinMax } from "@saleor/types";
|
import { FilterOpts, MinMax } from "@saleor/types";
|
||||||
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import {
|
import {
|
||||||
createDateField,
|
createDateField,
|
||||||
createNumberField
|
createNumberField
|
||||||
|
@ -28,7 +31,8 @@ const messages = defineMessages({
|
||||||
|
|
||||||
export function createFilterStructure(
|
export function createFilterStructure(
|
||||||
intl: IntlShape,
|
intl: IntlShape,
|
||||||
opts: CustomerListFilterOpts
|
opts: CustomerListFilterOpts,
|
||||||
|
userPermissions: User_userPermissions[]
|
||||||
): IFilter<CustomerFilterKeys> {
|
): IFilter<CustomerFilterKeys> {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -45,7 +49,8 @@ export function createFilterStructure(
|
||||||
intl.formatMessage(messages.numberOfOrders),
|
intl.formatMessage(messages.numberOfOrders),
|
||||||
opts.numberOfOrders.value
|
opts.numberOfOrders.value
|
||||||
),
|
),
|
||||||
active: opts.numberOfOrders.active
|
active: opts.numberOfOrders.active,
|
||||||
|
permissions: [PermissionEnum.MANAGE_ORDERS]
|
||||||
}
|
}
|
||||||
];
|
].filter(filter => hasPermissions(userPermissions, filter.permissions ?? []));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,13 @@ import { Card, CardContent, Typography } from "@material-ui/core";
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { DateTime } from "@saleor/components/Date";
|
import { DateTime } from "@saleor/components/Date";
|
||||||
import { Hr } from "@saleor/components/Hr";
|
import { Hr } from "@saleor/components/Hr";
|
||||||
|
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { maybe } from "../../../misc";
|
|
||||||
import { CustomerDetails_user } from "../../types/CustomerDetails";
|
import { CustomerDetails_user } from "../../types/CustomerDetails";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
@ -44,26 +45,25 @@ const CustomerStats: React.FC<CustomerStatsProps> = props => {
|
||||||
<Typography className={classes.label} variant="caption">
|
<Typography className={classes.label} variant="caption">
|
||||||
<FormattedMessage defaultMessage="Last login" />
|
<FormattedMessage defaultMessage="Last login" />
|
||||||
</Typography>
|
</Typography>
|
||||||
{maybe(
|
{customer ? (
|
||||||
() => (
|
<Typography variant="h6" className={classes.value}>
|
||||||
<Typography variant="h6" className={classes.value}>
|
{customer.lastLogin === null ? (
|
||||||
{customer.lastLogin === null ? (
|
"-"
|
||||||
"-"
|
) : (
|
||||||
) : (
|
<DateTime date={customer.lastLogin} />
|
||||||
<DateTime date={customer.lastLogin} />
|
)}
|
||||||
)}
|
</Typography>
|
||||||
</Typography>
|
) : (
|
||||||
),
|
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<Hr />
|
<RequirePermissions requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}>
|
||||||
<CardContent>
|
<Hr />
|
||||||
<Typography className={classes.label} variant="caption">
|
<CardContent>
|
||||||
<FormattedMessage defaultMessage="Last order" />
|
<Typography className={classes.label} variant="caption">
|
||||||
</Typography>
|
<FormattedMessage defaultMessage="Last order" />
|
||||||
{maybe(
|
</Typography>
|
||||||
() => (
|
{customer && customer.lastPlacedOrder ? (
|
||||||
<Typography variant="h6" className={classes.value}>
|
<Typography variant="h6" className={classes.value}>
|
||||||
{customer.lastPlacedOrder.edges.length === 0 ? (
|
{customer.lastPlacedOrder.edges.length === 0 ? (
|
||||||
"-"
|
"-"
|
||||||
|
@ -73,10 +73,11 @@ const CustomerStats: React.FC<CustomerStatsProps> = props => {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Typography>
|
</Typography>
|
||||||
),
|
) : (
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
</RequirePermissions>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,6 +27,7 @@ const customerList = gql`
|
||||||
$last: Int
|
$last: Int
|
||||||
$filter: CustomerFilterInput
|
$filter: CustomerFilterInput
|
||||||
$sort: UserSortingInput
|
$sort: UserSortingInput
|
||||||
|
$PERMISSION_MANAGE_ORDERS: Boolean!
|
||||||
) {
|
) {
|
||||||
customers(
|
customers(
|
||||||
after: $after
|
after: $after
|
||||||
|
@ -39,7 +40,7 @@ const customerList = gql`
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...CustomerFragment
|
...CustomerFragment
|
||||||
orders {
|
orders @include(if: $PERMISSION_MANAGE_ORDERS) {
|
||||||
totalCount
|
totalCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,10 +61,10 @@ export const useCustomerListQuery = makeQuery<
|
||||||
|
|
||||||
const customerDetails = gql`
|
const customerDetails = gql`
|
||||||
${customerDetailsFragment}
|
${customerDetailsFragment}
|
||||||
query CustomerDetails($id: ID!) {
|
query CustomerDetails($id: ID!, $PERMISSION_MANAGE_ORDERS: Boolean!) {
|
||||||
user(id: $id) {
|
user(id: $id) {
|
||||||
...CustomerDetailsFragment
|
...CustomerDetailsFragment
|
||||||
orders(last: 5) {
|
orders(last: 5) @include(if: $PERMISSION_MANAGE_ORDERS) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
|
@ -79,7 +80,7 @@ const customerDetails = gql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastPlacedOrder: orders(last: 1) {
|
lastPlacedOrder: orders(last: 1) @include(if: $PERMISSION_MANAGE_ORDERS) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
|
|
|
@ -135,4 +135,5 @@ export interface CustomerDetails {
|
||||||
|
|
||||||
export interface CustomerDetailsVariables {
|
export interface CustomerDetailsVariables {
|
||||||
id: string;
|
id: string;
|
||||||
|
PERMISSION_MANAGE_ORDERS: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,4 +53,5 @@ export interface ListCustomersVariables {
|
||||||
last?: number | null;
|
last?: number | null;
|
||||||
filter?: CustomerFilterInput | null;
|
filter?: CustomerFilterInput | null;
|
||||||
sort?: UserSortingInput | null;
|
sort?: UserSortingInput | null;
|
||||||
|
PERMISSION_MANAGE_ORDERS: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { createFilterStructure } from "@saleor/customers/components/CustomerListPage";
|
import { createFilterStructure } from "@saleor/customers/components/CustomerListPage";
|
||||||
import { CustomerListUrlFilters } from "@saleor/customers/urls";
|
import { CustomerListUrlFilters } from "@saleor/customers/urls";
|
||||||
import { date } from "@saleor/fixtures";
|
import { date } from "@saleor/fixtures";
|
||||||
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import { getFilterQueryParams } from "@saleor/utils/filters";
|
import { getFilterQueryParams } from "@saleor/utils/filters";
|
||||||
import { stringifyQs } from "@saleor/utils/urls";
|
import { stringifyQs } from "@saleor/utils/urls";
|
||||||
import { getExistingKeys, setFilterOptsStatus } from "@test/filters";
|
import { getExistingKeys, setFilterOptsStatus } from "@test/filters";
|
||||||
|
@ -31,22 +32,37 @@ describe("Filtering query params", () => {
|
||||||
describe("Filtering URL params", () => {
|
describe("Filtering URL params", () => {
|
||||||
const intl = createIntl(config);
|
const intl = createIntl(config);
|
||||||
|
|
||||||
const filters = createFilterStructure(intl, {
|
const filters = createFilterStructure(
|
||||||
joined: {
|
intl,
|
||||||
active: false,
|
{
|
||||||
value: {
|
joined: {
|
||||||
max: date.to,
|
active: false,
|
||||||
min: date.from
|
value: {
|
||||||
|
max: date.to,
|
||||||
|
min: date.from
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numberOfOrders: {
|
||||||
|
active: false,
|
||||||
|
value: {
|
||||||
|
max: "5",
|
||||||
|
min: "1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
numberOfOrders: {
|
[
|
||||||
active: false,
|
{
|
||||||
value: {
|
code: PermissionEnum.MANAGE_USERS,
|
||||||
max: "5",
|
name: "Manage customers.",
|
||||||
min: "1"
|
__typename: "UserPermission"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: PermissionEnum.MANAGE_ORDERS,
|
||||||
|
name: "Manage orders..",
|
||||||
|
__typename: "UserPermission"
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
});
|
);
|
||||||
|
|
||||||
it("should be empty if no active filters", () => {
|
it("should be empty if no active filters", () => {
|
||||||
const filterQueryParams = getFilterQueryParams(
|
const filterQueryParams = getFilterQueryParams(
|
||||||
|
|
|
@ -10,7 +10,6 @@ import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
import { UserPermissionProps } from "@saleor/types";
|
|
||||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
@ -33,7 +32,7 @@ const useStyles = makeStyles(
|
||||||
{ name: "HomeNotificationTable" }
|
{ name: "HomeNotificationTable" }
|
||||||
);
|
);
|
||||||
|
|
||||||
interface HomeNotificationTableProps extends UserPermissionProps {
|
interface HomeNotificationTableProps {
|
||||||
ordersToCapture: number;
|
ordersToCapture: number;
|
||||||
ordersToFulfill: number;
|
ordersToFulfill: number;
|
||||||
productsOutOfStock: number;
|
productsOutOfStock: number;
|
||||||
|
@ -53,7 +52,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
||||||
ordersToCapture,
|
ordersToCapture,
|
||||||
ordersToFulfill,
|
ordersToFulfill,
|
||||||
productsOutOfStock,
|
productsOutOfStock,
|
||||||
userPermissions,
|
|
||||||
noChannel
|
noChannel
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
@ -67,7 +65,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
||||||
<TableBody className={classes.tableRow}>
|
<TableBody className={classes.tableRow}>
|
||||||
{noChannel && (
|
{noChannel && (
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_CHANNELS]}
|
requiredPermissions={[PermissionEnum.MANAGE_CHANNELS]}
|
||||||
>
|
>
|
||||||
<TableRow hover={true} onClick={onCreateNewChannelClick}>
|
<TableRow hover={true} onClick={onCreateNewChannelClick}>
|
||||||
|
@ -83,7 +80,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
||||||
</RequirePermissions>
|
</RequirePermissions>
|
||||||
)}
|
)}
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
>
|
>
|
||||||
<TableRow hover={true} onClick={onOrdersToFulfillClick}>
|
<TableRow hover={true} onClick={onOrdersToFulfillClick}>
|
||||||
|
@ -128,7 +124,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</RequirePermissions>
|
</RequirePermissions>
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
requiredPermissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
||||||
>
|
>
|
||||||
<TableRow hover={true} onClick={onProductsOutOfStockClick}>
|
<TableRow hover={true} onClick={onProductsOutOfStockClick}>
|
||||||
|
|
|
@ -5,7 +5,6 @@ import Money from "@saleor/components/Money";
|
||||||
import RequirePermissions from "@saleor/components/RequirePermissions";
|
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
import { UserPermissionProps } from "@saleor/types";
|
|
||||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ const useStyles = makeStyles(
|
||||||
{ name: "HomePage" }
|
{ name: "HomePage" }
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface HomePageProps extends UserPermissionProps {
|
export interface HomePageProps {
|
||||||
activities: Home_activities_edges_node[];
|
activities: Home_activities_edges_node[];
|
||||||
orders: number | null;
|
orders: number | null;
|
||||||
ordersToCapture: number | null;
|
ordersToCapture: number | null;
|
||||||
|
@ -76,7 +75,6 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
ordersToCapture = 0,
|
ordersToCapture = 0,
|
||||||
ordersToFulfill = 0,
|
ordersToFulfill = 0,
|
||||||
productsOutOfStock = 0,
|
productsOutOfStock = 0,
|
||||||
userPermissions = [],
|
|
||||||
noChannel
|
noChannel
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
@ -89,7 +87,6 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
<Grid>
|
<Grid>
|
||||||
<div>
|
<div>
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
>
|
>
|
||||||
<div className={classes.cardContainer}>
|
<div className={classes.cardContainer}>
|
||||||
|
@ -141,13 +138,11 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
ordersToCapture={ordersToCapture}
|
ordersToCapture={ordersToCapture}
|
||||||
ordersToFulfill={ordersToFulfill}
|
ordersToFulfill={ordersToFulfill}
|
||||||
productsOutOfStock={productsOutOfStock}
|
productsOutOfStock={productsOutOfStock}
|
||||||
userPermissions={userPermissions}
|
|
||||||
noChannel={noChannel}
|
noChannel={noChannel}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
{topProducts && (
|
{topProducts && (
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[
|
requiredPermissions={[
|
||||||
PermissionEnum.MANAGE_ORDERS,
|
PermissionEnum.MANAGE_ORDERS,
|
||||||
PermissionEnum.MANAGE_PRODUCTS
|
PermissionEnum.MANAGE_PRODUCTS
|
||||||
|
@ -165,7 +160,6 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
{activities && (
|
{activities && (
|
||||||
<div>
|
<div>
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
>
|
>
|
||||||
<HomeActivityCard
|
<HomeActivityCard
|
||||||
|
|
|
@ -65,7 +65,6 @@ const HomeSection = () => {
|
||||||
ordersToFulfill={data?.ordersToFulfill?.totalCount}
|
ordersToFulfill={data?.ordersToFulfill?.totalCount}
|
||||||
productsOutOfStock={data?.productsOutOfStock.totalCount}
|
productsOutOfStock={data?.productsOutOfStock.totalCount}
|
||||||
userName={getUserName(user, true)}
|
userName={getUserName(user, true)}
|
||||||
userPermissions={user?.userPermissions}
|
|
||||||
noChannel={noChannel}
|
noChannel={noChannel}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,7 +12,7 @@ import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
|
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
|
||||||
import { FetchMoreProps, UserPermissionProps } from "@saleor/types";
|
import { FetchMoreProps } from "@saleor/types";
|
||||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||||
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -55,9 +55,7 @@ export interface CustomerEditData {
|
||||||
prevUserEmail?: string;
|
prevUserEmail?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderCustomerProps
|
export interface OrderCustomerProps extends Partial<FetchMoreProps> {
|
||||||
extends Partial<FetchMoreProps>,
|
|
||||||
UserPermissionProps {
|
|
||||||
order: OrderDetails_order;
|
order: OrderDetails_order;
|
||||||
users?: SearchCustomers_search_edges_node[];
|
users?: SearchCustomers_search_edges_node[];
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
|
@ -79,7 +77,6 @@ const OrderCustomer: React.FC<OrderCustomerProps> = props => {
|
||||||
loading,
|
loading,
|
||||||
order,
|
order,
|
||||||
users,
|
users,
|
||||||
userPermissions,
|
|
||||||
onCustomerEdit,
|
onCustomerEdit,
|
||||||
onBillingAddressEdit,
|
onBillingAddressEdit,
|
||||||
onFetchMore: onFetchMoreUsers,
|
onFetchMore: onFetchMoreUsers,
|
||||||
|
@ -131,7 +128,6 @@ const OrderCustomer: React.FC<OrderCustomerProps> = props => {
|
||||||
toolbar={
|
toolbar={
|
||||||
!!canEditCustomer && (
|
!!canEditCustomer && (
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
@ -209,7 +205,6 @@ const OrderCustomer: React.FC<OrderCustomerProps> = props => {
|
||||||
{user.email}
|
{user.email}
|
||||||
</Typography>
|
</Typography>
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_USERS]}
|
requiredPermissions={[PermissionEnum.MANAGE_USERS]}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -15,7 +15,6 @@ import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||||
import { Backlink } from "@saleor/macaw-ui";
|
import { Backlink } from "@saleor/macaw-ui";
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
import OrderChannelSectionCard from "@saleor/orders/components/OrderChannelSectionCard";
|
import OrderChannelSectionCard from "@saleor/orders/components/OrderChannelSectionCard";
|
||||||
import { UserPermissionProps } from "@saleor/types";
|
|
||||||
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
||||||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -55,7 +54,7 @@ const useStyles = makeStyles(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface OrderDetailsPageProps extends UserPermissionProps {
|
export interface OrderDetailsPageProps {
|
||||||
order: OrderDetails_order;
|
order: OrderDetails_order;
|
||||||
shop: OrderDetails_shop;
|
shop: OrderDetails_shop;
|
||||||
shippingMethods?: Array<{
|
shippingMethods?: Array<{
|
||||||
|
@ -114,7 +113,6 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
||||||
order,
|
order,
|
||||||
shop,
|
shop,
|
||||||
saveButtonBarState,
|
saveButtonBarState,
|
||||||
userPermissions,
|
|
||||||
onBack,
|
onBack,
|
||||||
onBillingAddressEdit,
|
onBillingAddressEdit,
|
||||||
onFulfillmentApprove,
|
onFulfillmentApprove,
|
||||||
|
@ -299,7 +297,6 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
||||||
canEditAddresses={canEditAddresses}
|
canEditAddresses={canEditAddresses}
|
||||||
canEditCustomer={false}
|
canEditCustomer={false}
|
||||||
order={order}
|
order={order}
|
||||||
userPermissions={userPermissions}
|
|
||||||
onBillingAddressEdit={onBillingAddressEdit}
|
onBillingAddressEdit={onBillingAddressEdit}
|
||||||
onShippingAddressEdit={onShippingAddressEdit}
|
onShippingAddressEdit={onShippingAddressEdit}
|
||||||
onProfileView={onProfileView}
|
onProfileView={onProfileView}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { Backlink } from "@saleor/macaw-ui";
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
import DraftOrderChannelSectionCard from "@saleor/orders/components/DraftOrderChannelSectionCard";
|
import DraftOrderChannelSectionCard from "@saleor/orders/components/DraftOrderChannelSectionCard";
|
||||||
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
|
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
|
||||||
import { FetchMoreProps, UserPermissionProps } from "@saleor/types";
|
import { FetchMoreProps } from "@saleor/types";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -37,9 +37,7 @@ const useStyles = makeStyles(
|
||||||
{ name: "OrderDraftPage" }
|
{ name: "OrderDraftPage" }
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface OrderDraftPageProps
|
export interface OrderDraftPageProps extends FetchMoreProps {
|
||||||
extends FetchMoreProps,
|
|
||||||
UserPermissionProps {
|
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
order: OrderDetails_order;
|
order: OrderDetails_order;
|
||||||
users: SearchCustomers_search_edges_node[];
|
users: SearchCustomers_search_edges_node[];
|
||||||
|
@ -85,8 +83,7 @@ const OrderDraftPage: React.FC<OrderDraftPageProps> = props => {
|
||||||
onProfileView,
|
onProfileView,
|
||||||
order,
|
order,
|
||||||
users,
|
users,
|
||||||
usersLoading,
|
usersLoading
|
||||||
userPermissions
|
|
||||||
} = props;
|
} = props;
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
|
@ -147,7 +144,6 @@ const OrderDraftPage: React.FC<OrderDraftPageProps> = props => {
|
||||||
loading={usersLoading}
|
loading={usersLoading}
|
||||||
order={order}
|
order={order}
|
||||||
users={users}
|
users={users}
|
||||||
userPermissions={userPermissions}
|
|
||||||
onBillingAddressEdit={onBillingAddressEdit}
|
onBillingAddressEdit={onBillingAddressEdit}
|
||||||
onCustomerEdit={onCustomerEdit}
|
onCustomerEdit={onCustomerEdit}
|
||||||
onFetchMore={onFetchMore}
|
onFetchMore={onFetchMore}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { useUser } from "@saleor/auth";
|
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||||
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
||||||
|
@ -84,7 +83,6 @@ export const OrderDraftDetails: React.FC<OrderDraftDetailsProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const order = data.order;
|
const order = data.order;
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const { user } = useUser();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loadMore,
|
loadMore,
|
||||||
|
@ -214,7 +212,6 @@ export const OrderDraftDetails: React.FC<OrderDraftDetailsProps> = ({
|
||||||
}
|
}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
onProfileView={() => navigate(customerUrl(order.user.id))}
|
onProfileView={() => navigate(customerUrl(order.user.id))}
|
||||||
userPermissions={user?.userPermissions || []}
|
|
||||||
/>
|
/>
|
||||||
</OrderLineDiscountProvider>
|
</OrderLineDiscountProvider>
|
||||||
</OrderDiscountProvider>
|
</OrderDiscountProvider>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { useUser } from "@saleor/auth";
|
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
|
@ -95,7 +94,6 @@ export const OrderNormalDetails: React.FC<OrderNormalDetailsProps> = ({
|
||||||
const order = data?.order;
|
const order = data?.order;
|
||||||
const shop = data?.shop;
|
const shop = data?.shop;
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const { user } = useUser();
|
|
||||||
|
|
||||||
const warehouses = useWarehouseList({
|
const warehouses = useWarehouseList({
|
||||||
displayLoader: true,
|
displayLoader: true,
|
||||||
|
@ -168,7 +166,6 @@ export const OrderNormalDetails: React.FC<OrderNormalDetailsProps> = ({
|
||||||
]
|
]
|
||||||
)}
|
)}
|
||||||
shippingMethods={data?.order?.shippingMethods || []}
|
shippingMethods={data?.order?.shippingMethods || []}
|
||||||
userPermissions={user?.userPermissions || []}
|
|
||||||
onOrderCancel={() => openModal("cancel")}
|
onOrderCancel={() => openModal("cancel")}
|
||||||
onOrderFulfill={() => navigate(orderFulfillUrl(id))}
|
onOrderFulfill={() => navigate(orderFulfillUrl(id))}
|
||||||
onFulfillmentApprove={fulfillmentId =>
|
onFulfillmentApprove={fulfillmentId =>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { useUser } from "@saleor/auth";
|
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||||
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
||||||
|
@ -109,7 +108,6 @@ export const OrderUnconfirmedDetails: React.FC<OrderUnconfirmedDetailsProps> = (
|
||||||
const order = data.order;
|
const order = data.order;
|
||||||
const shop = data.shop;
|
const shop = data.shop;
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const { user } = useUser();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loadMore,
|
loadMore,
|
||||||
|
@ -201,7 +199,6 @@ export const OrderUnconfirmedDetails: React.FC<OrderUnconfirmedDetailsProps> = (
|
||||||
]
|
]
|
||||||
)}
|
)}
|
||||||
shippingMethods={data?.order?.shippingMethods || []}
|
shippingMethods={data?.order?.shippingMethods || []}
|
||||||
userPermissions={user?.userPermissions || []}
|
|
||||||
onOrderCancel={() => openModal("cancel")}
|
onOrderCancel={() => openModal("cancel")}
|
||||||
onOrderFulfill={() => navigate(orderFulfillUrl(id))}
|
onOrderFulfill={() => navigate(orderFulfillUrl(id))}
|
||||||
onFulfillmentApprove={fulfillmentId =>
|
onFulfillmentApprove={fulfillmentId =>
|
||||||
|
|
|
@ -28,7 +28,6 @@ export interface ShippingZonesListPageProps
|
||||||
const ShippingZonesListPage: React.FC<ShippingZonesListPageProps> = ({
|
const ShippingZonesListPage: React.FC<ShippingZonesListPageProps> = ({
|
||||||
defaultWeightUnit,
|
defaultWeightUnit,
|
||||||
disabled,
|
disabled,
|
||||||
userPermissions,
|
|
||||||
onBack,
|
onBack,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
...listProps
|
...listProps
|
||||||
|
@ -52,7 +51,6 @@ const ShippingZonesListPage: React.FC<ShippingZonesListPageProps> = ({
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<RequirePermissions
|
<RequirePermissions
|
||||||
userPermissions={userPermissions}
|
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_SETTINGS]}
|
requiredPermissions={[PermissionEnum.MANAGE_SETTINGS]}
|
||||||
>
|
>
|
||||||
<ShippingWeightUnitForm
|
<ShippingWeightUnitForm
|
||||||
|
|
|
@ -73323,7 +73323,7 @@ exports[`Storyshots Views / Customers / Customer list default 1`] = `
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
||||||
colspan="4"
|
colspan="3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
||||||
|
@ -74994,7 +74994,7 @@ exports[`Storyshots Views / Customers / Customer list loading 1`] = `
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
||||||
colspan="4"
|
colspan="3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
||||||
|
@ -75348,7 +75348,7 @@ exports[`Storyshots Views / Customers / Customer list no data 1`] = `
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
||||||
colspan="4"
|
colspan="3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
||||||
|
@ -75420,7 +75420,7 @@ exports[`Storyshots Views / Customers / Customer list no data 1`] = `
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="MuiTableCell-root-id MuiTableCell-body-id"
|
class="MuiTableCell-root-id MuiTableCell-body-id"
|
||||||
colspan="4"
|
colspan="3"
|
||||||
>
|
>
|
||||||
No customers found
|
No customers found
|
||||||
</td>
|
</td>
|
||||||
|
@ -235532,107 +235532,7 @@ exports[`Storyshots Views / Shipping / Shipping zones list default 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div />
|
||||||
<form>
|
|
||||||
<div
|
|
||||||
class="MuiPaper-root-id MuiCard-root-id MuiPaper-elevation0-id MuiPaper-rounded-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiCardHeader-root-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiCardHeader-content-id"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="MuiTypography-root-id MuiCardHeader-title-id MuiTypography-h5-id MuiTypography-displayBlock-id"
|
|
||||||
>
|
|
||||||
Configuration
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="MuiCardContent-root-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiFormControl-root-id SingleSelectField-formControl-id"
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
class="MuiFormLabel-root-id MuiInputLabel-root-id SingleSelectField-label-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-filled-id MuiFormLabel-filled-id"
|
|
||||||
data-shrink="true"
|
|
||||||
>
|
|
||||||
Shipping Weight Unit
|
|
||||||
</label>
|
|
||||||
<div
|
|
||||||
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-haspopup="listbox"
|
|
||||||
aria-labelledby="mui-component-select-unit"
|
|
||||||
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id"
|
|
||||||
id="mui-component-select-unit"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
KG
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSelect-nativeInput-id"
|
|
||||||
name="unit"
|
|
||||||
tabindex="-1"
|
|
||||||
value="KG"
|
|
||||||
/>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root-id MuiSelect-icon-id MuiSelect-iconOutlined-id"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7 10l5 5 5-5z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<fieldset
|
|
||||||
aria-hidden="true"
|
|
||||||
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
|
|
||||||
style="padding-left:8px"
|
|
||||||
>
|
|
||||||
<legend
|
|
||||||
class="PrivateNotchedOutline-legend-id"
|
|
||||||
style="width:143px"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</legend>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-filled-id"
|
|
||||||
>
|
|
||||||
This unit will be used as default shipping weight
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="MuiCardActions-root-id MuiCardActions-spacing-id"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-outlined-id MuiButton-outlinedPrimary-id MuiButton-outlinedSizeSmall-id MuiButton-sizeSmall-id"
|
|
||||||
data-test-id="save-unit"
|
|
||||||
tabindex="0"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="MuiButton-label-id"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -235953,107 +235853,7 @@ exports[`Storyshots Views / Shipping / Shipping zones list loading 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div />
|
||||||
<form>
|
|
||||||
<div
|
|
||||||
class="MuiPaper-root-id MuiCard-root-id MuiPaper-elevation0-id MuiPaper-rounded-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiCardHeader-root-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiCardHeader-content-id"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="MuiTypography-root-id MuiCardHeader-title-id MuiTypography-h5-id MuiTypography-displayBlock-id"
|
|
||||||
>
|
|
||||||
Configuration
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="MuiCardContent-root-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiFormControl-root-id SingleSelectField-formControl-id"
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
class="MuiFormLabel-root-id MuiInputLabel-root-id SingleSelectField-label-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-filled-id MuiFormLabel-disabled-id MuiInputLabel-disabled-id MuiFormLabel-filled-id"
|
|
||||||
data-shrink="true"
|
|
||||||
>
|
|
||||||
Shipping Weight Unit
|
|
||||||
</label>
|
|
||||||
<div
|
|
||||||
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-disabled="true"
|
|
||||||
aria-haspopup="listbox"
|
|
||||||
aria-labelledby="mui-component-select-unit"
|
|
||||||
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiSelect-disabled-id"
|
|
||||||
id="mui-component-select-unit"
|
|
||||||
role="button"
|
|
||||||
>
|
|
||||||
KG
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSelect-nativeInput-id"
|
|
||||||
name="unit"
|
|
||||||
tabindex="-1"
|
|
||||||
value="KG"
|
|
||||||
/>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root-id MuiSelect-icon-id MuiSelect-iconOutlined-id MuiSelect-disabled-id"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7 10l5 5 5-5z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<fieldset
|
|
||||||
aria-hidden="true"
|
|
||||||
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
|
|
||||||
style="padding-left:8px"
|
|
||||||
>
|
|
||||||
<legend
|
|
||||||
class="PrivateNotchedOutline-legend-id"
|
|
||||||
style="width:143px"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</legend>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-disabled-id MuiFormHelperText-filled-id"
|
|
||||||
>
|
|
||||||
This unit will be used as default shipping weight
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="MuiCardActions-root-id MuiCardActions-spacing-id"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-outlined-id MuiButton-outlinedPrimary-id MuiButton-outlinedSizeSmall-id MuiButton-sizeSmall-id"
|
|
||||||
data-test-id="save-unit"
|
|
||||||
tabindex="0"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="MuiButton-label-id"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -236255,107 +236055,7 @@ exports[`Storyshots Views / Shipping / Shipping zones list no data 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div />
|
||||||
<form>
|
|
||||||
<div
|
|
||||||
class="MuiPaper-root-id MuiCard-root-id MuiPaper-elevation0-id MuiPaper-rounded-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiCardHeader-root-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiCardHeader-content-id"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="MuiTypography-root-id MuiCardHeader-title-id MuiTypography-h5-id MuiTypography-displayBlock-id"
|
|
||||||
>
|
|
||||||
Configuration
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="MuiCardContent-root-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="MuiFormControl-root-id SingleSelectField-formControl-id"
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
class="MuiFormLabel-root-id MuiInputLabel-root-id SingleSelectField-label-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-filled-id MuiFormLabel-filled-id"
|
|
||||||
data-shrink="true"
|
|
||||||
>
|
|
||||||
Shipping Weight Unit
|
|
||||||
</label>
|
|
||||||
<div
|
|
||||||
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-haspopup="listbox"
|
|
||||||
aria-labelledby="mui-component-select-unit"
|
|
||||||
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id"
|
|
||||||
id="mui-component-select-unit"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
KG
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSelect-nativeInput-id"
|
|
||||||
name="unit"
|
|
||||||
tabindex="-1"
|
|
||||||
value="KG"
|
|
||||||
/>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root-id MuiSelect-icon-id MuiSelect-iconOutlined-id"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7 10l5 5 5-5z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<fieldset
|
|
||||||
aria-hidden="true"
|
|
||||||
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
|
|
||||||
style="padding-left:8px"
|
|
||||||
>
|
|
||||||
<legend
|
|
||||||
class="PrivateNotchedOutline-legend-id"
|
|
||||||
style="width:143px"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</legend>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-filled-id"
|
|
||||||
>
|
|
||||||
This unit will be used as default shipping weight
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="MuiCardActions-root-id MuiCardActions-spacing-id"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-outlined-id MuiButton-outlinedPrimary-id MuiButton-outlinedSizeSmall-id MuiButton-sizeSmall-id"
|
|
||||||
data-test-id="save-unit"
|
|
||||||
tabindex="0"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="MuiButton-label-id"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
import ActionDialog from "@saleor/components/ActionDialog";
|
import ActionDialogComponent from "@saleor/components/ActionDialog";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
import { MockedUserProvider } from "../customers/MockedUserProvider";
|
||||||
|
|
||||||
|
const ActionDialog = props => (
|
||||||
|
<MockedUserProvider>
|
||||||
|
<ActionDialogComponent {...props} />
|
||||||
|
</MockedUserProvider>
|
||||||
|
);
|
||||||
|
|
||||||
storiesOf("Generics / ActionDialog", module)
|
storiesOf("Generics / ActionDialog", module)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
|
|
|
@ -2,11 +2,12 @@ import { AccountErrorCode } from "@saleor/types/globalTypes";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import CustomerDetailsPage, {
|
import CustomerDetailsPageComponent, {
|
||||||
CustomerDetailsPageProps
|
CustomerDetailsPageProps
|
||||||
} from "../../../customers/components/CustomerDetailsPage";
|
} from "../../../customers/components/CustomerDetailsPage";
|
||||||
import { customer } from "../../../customers/fixtures";
|
import { customer } from "../../../customers/fixtures";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
import { MockedUserProvider } from "./MockedUserProvider";
|
||||||
|
|
||||||
const props: Omit<CustomerDetailsPageProps, "classes"> = {
|
const props: Omit<CustomerDetailsPageProps, "classes"> = {
|
||||||
customer,
|
customer,
|
||||||
|
@ -28,6 +29,12 @@ interface CustomerDetailsPageErrors {
|
||||||
note: string;
|
note: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CustomerDetailsPage = props => (
|
||||||
|
<MockedUserProvider>
|
||||||
|
<CustomerDetailsPageComponent {...props} />
|
||||||
|
</MockedUserProvider>
|
||||||
|
);
|
||||||
|
|
||||||
storiesOf("Views / Customers / Customer details", module)
|
storiesOf("Views / Customers / Customer details", module)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
.add("default", () => <CustomerDetailsPage {...props} />)
|
.add("default", () => <CustomerDetailsPage {...props} />)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { CustomerListUrlSortField } from "@saleor/customers/urls";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import CustomerListPage, {
|
import CustomerListPageComponent, {
|
||||||
CustomerListPageProps
|
CustomerListPageProps
|
||||||
} from "../../../customers/components/CustomerListPage";
|
} from "../../../customers/components/CustomerListPage";
|
||||||
import { customerList } from "../../../customers/fixtures";
|
import { customerList } from "../../../customers/fixtures";
|
||||||
|
@ -15,6 +15,7 @@ import {
|
||||||
tabPageProps
|
tabPageProps
|
||||||
} from "../../../fixtures";
|
} from "../../../fixtures";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
import { MockedUserProvider } from "./MockedUserProvider";
|
||||||
|
|
||||||
const props: CustomerListPageProps = {
|
const props: CustomerListPageProps = {
|
||||||
...filterPageProps,
|
...filterPageProps,
|
||||||
|
@ -46,6 +47,12 @@ const props: CustomerListPageProps = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CustomerListPage = props => (
|
||||||
|
<MockedUserProvider>
|
||||||
|
<CustomerListPageComponent {...props} />
|
||||||
|
</MockedUserProvider>
|
||||||
|
);
|
||||||
|
|
||||||
storiesOf("Views / Customers / Customer list", module)
|
storiesOf("Views / Customers / Customer list", module)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
.add("default", () => <CustomerListPage {...props} />)
|
.add("default", () => <CustomerListPage {...props} />)
|
||||||
|
|
31
src/storybook/stories/customers/MockedUserProvider.tsx
Normal file
31
src/storybook/stories/customers/MockedUserProvider.tsx
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { UserContext } from "@saleor/auth";
|
||||||
|
import { adminUserPermissions } from "@saleor/fixtures";
|
||||||
|
import { User_userPermissions } from "@saleor/fragments/types/User";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
export const MockedUserProvider: React.FC<{
|
||||||
|
customPermissions?: User_userPermissions[];
|
||||||
|
}> = ({ customPermissions, children }) => (
|
||||||
|
<UserContext.Provider
|
||||||
|
value={{
|
||||||
|
login: undefined,
|
||||||
|
loginByExternalPlugin: undefined,
|
||||||
|
logout: undefined,
|
||||||
|
requestLoginByExternalPlugin: undefined,
|
||||||
|
authenticating: false,
|
||||||
|
authenticated: false,
|
||||||
|
user: {
|
||||||
|
id: "0",
|
||||||
|
email: "email@email.me",
|
||||||
|
firstName: "user",
|
||||||
|
lastName: "user",
|
||||||
|
isStaff: true,
|
||||||
|
userPermissions: customPermissions ?? adminUserPermissions,
|
||||||
|
avatar: null,
|
||||||
|
__typename: "User"
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</UserContext.Provider>
|
||||||
|
);
|
|
@ -5,9 +5,12 @@ import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import HomePage, { HomePageProps } from "../../../home/components/HomePage";
|
import HomePageComponent, {
|
||||||
|
HomePageProps
|
||||||
|
} from "../../../home/components/HomePage";
|
||||||
import { shop as shopFixture } from "../../../home/fixtures";
|
import { shop as shopFixture } from "../../../home/fixtures";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
import { MockedUserProvider } from "../customers/MockedUserProvider";
|
||||||
|
|
||||||
const shop = shopFixture(placeholderImage);
|
const shop = shopFixture(placeholderImage);
|
||||||
|
|
||||||
|
@ -25,8 +28,17 @@ const homePageProps: Omit<HomePageProps, "classes"> = {
|
||||||
productsOutOfStock: shop.productsOutOfStock.totalCount,
|
productsOutOfStock: shop.productsOutOfStock.totalCount,
|
||||||
sales: shop.salesToday.gross,
|
sales: shop.salesToday.gross,
|
||||||
topProducts: mapEdgesToItems(shop.productTopToday),
|
topProducts: mapEdgesToItems(shop.productTopToday),
|
||||||
userName: "admin@example.com",
|
userName: "admin@example.com"
|
||||||
userPermissions: adminUserPermissions
|
};
|
||||||
|
|
||||||
|
const HomePage = props => {
|
||||||
|
const customPermissions = props?.customPermissions;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MockedUserProvider customPermissions={customPermissions}>
|
||||||
|
<HomePageComponent {...props} />
|
||||||
|
</MockedUserProvider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Views / HomePage", module)
|
storiesOf("Views / HomePage", module)
|
||||||
|
@ -49,12 +61,12 @@ storiesOf("Views / HomePage", module)
|
||||||
<HomePage {...homePageProps} topProducts={[]} activities={[]} />
|
<HomePage {...homePageProps} topProducts={[]} activities={[]} />
|
||||||
))
|
))
|
||||||
.add("no permissions", () => (
|
.add("no permissions", () => (
|
||||||
<HomePage {...homePageProps} userPermissions={[]} />
|
<HomePage {...homePageProps} customPermissions={[]} />
|
||||||
))
|
))
|
||||||
.add("product permissions", () => (
|
.add("product permissions", () => (
|
||||||
<HomePage
|
<HomePage
|
||||||
{...homePageProps}
|
{...homePageProps}
|
||||||
userPermissions={adminUserPermissions.filter(
|
customPermissions={adminUserPermissions.filter(
|
||||||
perm => perm.code === PermissionEnum.MANAGE_PRODUCTS
|
perm => perm.code === PermissionEnum.MANAGE_PRODUCTS
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -62,7 +74,7 @@ storiesOf("Views / HomePage", module)
|
||||||
.add("order permissions", () => (
|
.add("order permissions", () => (
|
||||||
<HomePage
|
<HomePage
|
||||||
{...homePageProps}
|
{...homePageProps}
|
||||||
userPermissions={adminUserPermissions.filter(
|
customPermissions={adminUserPermissions.filter(
|
||||||
perm => perm.code === PermissionEnum.MANAGE_ORDERS
|
perm => perm.code === PermissionEnum.MANAGE_ORDERS
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { adminUserPermissions } from "@saleor/fixtures";
|
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import OrderCustomer, {
|
import OrderCustomerComponent, {
|
||||||
OrderCustomerProps
|
OrderCustomerProps
|
||||||
} from "../../../orders/components/OrderCustomer";
|
} from "../../../orders/components/OrderCustomer";
|
||||||
import { clients, order as orderFixture } from "../../../orders/fixtures";
|
import { clients, order as orderFixture } from "../../../orders/fixtures";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
import { MockedUserProvider } from "../customers/MockedUserProvider";
|
||||||
|
|
||||||
const order = orderFixture("");
|
const order = orderFixture("");
|
||||||
|
|
||||||
|
@ -19,10 +19,19 @@ const props: Omit<OrderCustomerProps, "classes"> = {
|
||||||
onProfileView: () => undefined,
|
onProfileView: () => undefined,
|
||||||
onShippingAddressEdit: undefined,
|
onShippingAddressEdit: undefined,
|
||||||
order,
|
order,
|
||||||
userPermissions: adminUserPermissions,
|
|
||||||
users: clients
|
users: clients
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const OrderCustomer = props => {
|
||||||
|
const customPermissions = props?.customPermissions;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MockedUserProvider customPermissions={customPermissions}>
|
||||||
|
<OrderCustomerComponent {...props} />
|
||||||
|
</MockedUserProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
storiesOf("Orders / OrderCustomer", module)
|
storiesOf("Orders / OrderCustomer", module)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
.add("default", () => <OrderCustomer {...props} />)
|
.add("default", () => <OrderCustomer {...props} />)
|
||||||
|
@ -40,5 +49,5 @@ storiesOf("Orders / OrderCustomer", module)
|
||||||
<OrderCustomer {...props} canEditAddresses={true} canEditCustomer={true} />
|
<OrderCustomer {...props} canEditAddresses={true} canEditCustomer={true} />
|
||||||
))
|
))
|
||||||
.add("no user permissions", () => (
|
.add("no user permissions", () => (
|
||||||
<OrderCustomer {...props} userPermissions={[]} />
|
<OrderCustomer {...props} customPermissions={[]} />
|
||||||
));
|
));
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import placeholderImage from "@assets/images/placeholder60x60.png";
|
import placeholderImage from "@assets/images/placeholder60x60.png";
|
||||||
import { adminUserPermissions } from "@saleor/fixtures";
|
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
@ -43,8 +42,7 @@ const props: Omit<OrderDetailsPageProps, "classes"> = {
|
||||||
onSubmit: () => undefined,
|
onSubmit: () => undefined,
|
||||||
order,
|
order,
|
||||||
shop: shopFixture,
|
shop: shopFixture,
|
||||||
saveButtonBarState: "default",
|
saveButtonBarState: "default"
|
||||||
userPermissions: adminUserPermissions
|
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Views / Orders / Order details", module)
|
storiesOf("Views / Orders / Order details", module)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import placeholderImage from "@assets/images/placeholder60x60.png";
|
import placeholderImage from "@assets/images/placeholder60x60.png";
|
||||||
import { adminUserPermissions, fetchMoreProps } from "@saleor/fixtures";
|
import { fetchMoreProps } from "@saleor/fixtures";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import OrderDraftPage, {
|
import OrderDraftPageComponent, {
|
||||||
OrderDraftPageProps
|
OrderDraftPageProps
|
||||||
} from "../../../../orders/components/OrderDraftPage";
|
} from "../../../../orders/components/OrderDraftPage";
|
||||||
import { clients, draftOrder } from "../../../../orders/fixtures";
|
import { clients, draftOrder } from "../../../../orders/fixtures";
|
||||||
import Decorator from "../../../Decorator";
|
import Decorator from "../../../Decorator";
|
||||||
|
import { MockedUserProvider } from "../../customers/MockedUserProvider";
|
||||||
import { getDiscountsProvidersWrapper } from "./utils";
|
import { getDiscountsProvidersWrapper } from "./utils";
|
||||||
|
|
||||||
const order = draftOrder(placeholderImage);
|
const order = draftOrder(placeholderImage);
|
||||||
|
@ -31,13 +32,22 @@ const props: Omit<OrderDraftPageProps, "classes"> = {
|
||||||
onShippingMethodEdit: undefined,
|
onShippingMethodEdit: undefined,
|
||||||
order,
|
order,
|
||||||
saveButtonBarState: "default",
|
saveButtonBarState: "default",
|
||||||
userPermissions: adminUserPermissions,
|
|
||||||
users: clients,
|
users: clients,
|
||||||
usersLoading: false
|
usersLoading: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const DiscountsDecorator = getDiscountsProvidersWrapper(order);
|
const DiscountsDecorator = getDiscountsProvidersWrapper(order);
|
||||||
|
|
||||||
|
const OrderDraftPage = props => {
|
||||||
|
const customPermissions = props?.customPermissions;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MockedUserProvider customPermissions={customPermissions}>
|
||||||
|
<OrderDraftPageComponent {...props} />
|
||||||
|
</MockedUserProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
storiesOf("Views / Orders / Order draft", module)
|
storiesOf("Views / Orders / Order draft", module)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
.addDecorator(DiscountsDecorator)
|
.addDecorator(DiscountsDecorator)
|
||||||
|
@ -49,5 +59,5 @@ storiesOf("Views / Orders / Order draft", module)
|
||||||
<OrderDraftPage {...props} order={{ ...order, lines: [] }} />
|
<OrderDraftPage {...props} order={{ ...order, lines: [] }} />
|
||||||
))
|
))
|
||||||
.add("no user permissions", () => (
|
.add("no user permissions", () => (
|
||||||
<OrderDraftPage {...props} userPermissions={[]} />
|
<OrderDraftPage {...props} customPermissions={[]} />
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in a new issue