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/lab": "^4.0.0-alpha.58",
|
||||
"@material-ui/styles": "^4.11.4",
|
||||
"@saleor/macaw-ui": "^0.3.1",
|
||||
"@saleor/macaw-ui": "0.3.1",
|
||||
"@saleor/sdk": "^0.4.2",
|
||||
"@sentry/react": "^6.0.0",
|
||||
"@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 { useUser } from "@saleor/auth";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||
|
@ -28,7 +27,6 @@ export const ChannelsAvailabilityWrapper: React.FC<ChannelsAvailabilityWrapperPr
|
|||
} = props;
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
const { user } = useUser();
|
||||
const channelsAvailabilityText = intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
|
@ -51,10 +49,7 @@ export const ChannelsAvailabilityWrapper: React.FC<ChannelsAvailabilityWrapperPr
|
|||
description: "section header"
|
||||
})}
|
||||
toolbar={
|
||||
<RequirePermissions
|
||||
userPermissions={user?.userPermissions || []}
|
||||
requiredPermissions={managePermissions}
|
||||
>
|
||||
<RequirePermissions requiredPermissions={managePermissions}>
|
||||
<Button
|
||||
onClick={openModal}
|
||||
data-test-id="channels-availability-manage-button"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { FetchMoreProps, SearchPageProps } from "@saleor/types";
|
||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import { MessageDescriptor } from "react-intl";
|
||||
|
||||
import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
|
||||
|
@ -34,6 +35,7 @@ export interface IFilterElement<T extends string = string>
|
|||
multipleFields?: IFilterElement[];
|
||||
id?: string;
|
||||
dependencies?: string[];
|
||||
permissions?: PermissionEnum[];
|
||||
}
|
||||
|
||||
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 { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
|
@ -16,15 +17,19 @@ export function hasPermissions(
|
|||
export interface RequirePermissionsProps {
|
||||
children: React.ReactNode | React.ReactNodeArray;
|
||||
requiredPermissions: PermissionEnum[];
|
||||
userPermissions: User_userPermissions[];
|
||||
}
|
||||
|
||||
const RequirePermissions: React.FC<RequirePermissionsProps> = ({
|
||||
children,
|
||||
requiredPermissions,
|
||||
userPermissions
|
||||
}) =>
|
||||
hasPermissions(userPermissions, requiredPermissions) ? <>{children}</> : null;
|
||||
requiredPermissions
|
||||
}) => {
|
||||
const userPermissions = useUserPermissions();
|
||||
|
||||
return userPermissions &&
|
||||
hasPermissions(userPermissions, requiredPermissions) ? (
|
||||
<>{children}</>
|
||||
) : null;
|
||||
};
|
||||
|
||||
RequirePermissions.displayName = "RequirePermissions";
|
||||
export default RequirePermissions;
|
||||
|
|
|
@ -5,6 +5,7 @@ import Grid from "@saleor/components/Grid";
|
|||
import Metadata from "@saleor/components/Metadata/Metadata";
|
||||
import { MetadataFormData } from "@saleor/components/Metadata/types";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import { UpdateCustomer_customerUpdate_errors } from "@saleor/customers/types/UpdateCustomer";
|
||||
import { AccountErrorFragment } from "@saleor/fragments/types/AccountErrorFragment";
|
||||
|
@ -13,6 +14,7 @@ import { SubmitPromise } from "@saleor/hooks/useForm";
|
|||
import { sectionNames } from "@saleor/intl";
|
||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||
import { Backlink } from "@saleor/macaw-ui";
|
||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import { mapEdgesToItems, mapMetadataItemToInput } from "@saleor/utils/maps";
|
||||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||
import React from "react";
|
||||
|
@ -105,12 +107,16 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
|
|||
onChange={change}
|
||||
/>
|
||||
<CardSpacer />
|
||||
<RequirePermissions
|
||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||
>
|
||||
<CustomerOrders
|
||||
orders={mapEdgesToItems(customer?.orders)}
|
||||
onViewAllOrdersClick={onViewAllOrdersClick}
|
||||
onRowClick={onRowClick}
|
||||
/>
|
||||
<CardSpacer />
|
||||
</RequirePermissions>
|
||||
<Metadata data={data} onChange={changeMetadata} />
|
||||
</div>
|
||||
<div>
|
||||
|
@ -122,7 +128,11 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
|
|||
<CardSpacer />
|
||||
<CustomerStats customer={customer} />
|
||||
<CardSpacer />
|
||||
<RequirePermissions
|
||||
requiredPermissions={[PermissionEnum.MANAGE_GIFT_CARD]}
|
||||
>
|
||||
<CustomerGiftCardsCard />
|
||||
</RequirePermissions>
|
||||
</div>
|
||||
</Grid>
|
||||
<Savebar
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core";
|
||||
import { useUserPermissions } from "@saleor/auth/hooks/useUserPermissions";
|
||||
import Checkbox from "@saleor/components/Checkbox";
|
||||
import RequirePermissions, {
|
||||
hasPermissions
|
||||
} from "@saleor/components/RequirePermissions";
|
||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import TableCellHeader from "@saleor/components/TableCellHeader";
|
||||
|
@ -7,8 +11,9 @@ import TableHead from "@saleor/components/TableHead";
|
|||
import TablePagination from "@saleor/components/TablePagination";
|
||||
import { CustomerListUrlSortField } from "@saleor/customers/urls";
|
||||
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 { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import { getArrowDirection } from "@saleor/utils/sort";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
@ -45,7 +50,7 @@ export interface CustomerListProps
|
|||
customers: ListCustomers_customers_edges_node[];
|
||||
}
|
||||
|
||||
const numberOfColumns = 4;
|
||||
const numberOfColumns = 3;
|
||||
|
||||
const CustomerList: React.FC<CustomerListProps> = props => {
|
||||
const {
|
||||
|
@ -66,12 +71,18 @@ const CustomerList: React.FC<CustomerListProps> = props => {
|
|||
isChecked
|
||||
} = props;
|
||||
|
||||
const userPermissions = useUserPermissions();
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<ResponsiveTable>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
colSpan={
|
||||
hasPermissions(userPermissions, [PermissionEnum.MANAGE_ORDERS])
|
||||
? numberOfColumns
|
||||
: numberOfColumns - 1
|
||||
}
|
||||
selected={selected}
|
||||
disabled={disabled}
|
||||
items={customers}
|
||||
|
@ -101,6 +112,9 @@ const CustomerList: React.FC<CustomerListProps> = props => {
|
|||
>
|
||||
<FormattedMessage defaultMessage="Customer Email" />
|
||||
</TableCellHeader>
|
||||
<RequirePermissions
|
||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||
>
|
||||
<TableCellHeader
|
||||
direction={
|
||||
sort.sort === CustomerListUrlSortField.orders
|
||||
|
@ -113,6 +127,7 @@ const CustomerList: React.FC<CustomerListProps> = props => {
|
|||
>
|
||||
<FormattedMessage defaultMessage="No. of Orders" />
|
||||
</TableCellHeader>
|
||||
</RequirePermissions>
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
|
@ -155,14 +170,15 @@ const CustomerList: React.FC<CustomerListProps> = props => {
|
|||
{getUserName(customer)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colEmail}>
|
||||
{maybe<React.ReactNode>(() => customer.email, <Skeleton />)}
|
||||
{customer?.email ?? <Skeleton />}
|
||||
</TableCell>
|
||||
<RequirePermissions
|
||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||
>
|
||||
<TableCell className={classes.colOrders}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => customer.orders.totalCount,
|
||||
<Skeleton />
|
||||
)}
|
||||
{customer?.orders?.totalCount ?? <Skeleton />}
|
||||
</TableCell>
|
||||
</RequirePermissions>
|
||||
</TableRow>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Card } from "@material-ui/core";
|
||||
import { useUserPermissions } from "@saleor/auth/hooks/useUserPermissions";
|
||||
import Container from "@saleor/components/Container";
|
||||
import FilterBar from "@saleor/components/FilterBar";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
|
@ -48,7 +49,8 @@ const CustomerListPage: React.FC<CustomerListPageProps> = ({
|
|||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const structure = createFilterStructure(intl, filterOpts);
|
||||
const userPermissions = useUserPermissions();
|
||||
const structure = createFilterStructure(intl, filterOpts, userPermissions);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
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 { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import {
|
||||
createDateField,
|
||||
createNumberField
|
||||
|
@ -28,7 +31,8 @@ const messages = defineMessages({
|
|||
|
||||
export function createFilterStructure(
|
||||
intl: IntlShape,
|
||||
opts: CustomerListFilterOpts
|
||||
opts: CustomerListFilterOpts,
|
||||
userPermissions: User_userPermissions[]
|
||||
): IFilter<CustomerFilterKeys> {
|
||||
return [
|
||||
{
|
||||
|
@ -45,7 +49,8 @@ export function createFilterStructure(
|
|||
intl.formatMessage(messages.numberOfOrders),
|
||||
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 { DateTime } from "@saleor/components/Date";
|
||||
import { Hr } from "@saleor/components/Hr";
|
||||
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { maybe } from "../../../misc";
|
||||
import { CustomerDetails_user } from "../../types/CustomerDetails";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
|
@ -44,8 +45,7 @@ const CustomerStats: React.FC<CustomerStatsProps> = props => {
|
|||
<Typography className={classes.label} variant="caption">
|
||||
<FormattedMessage defaultMessage="Last login" />
|
||||
</Typography>
|
||||
{maybe(
|
||||
() => (
|
||||
{customer ? (
|
||||
<Typography variant="h6" className={classes.value}>
|
||||
{customer.lastLogin === null ? (
|
||||
"-"
|
||||
|
@ -53,17 +53,17 @@ const CustomerStats: React.FC<CustomerStatsProps> = props => {
|
|||
<DateTime date={customer.lastLogin} />
|
||||
)}
|
||||
</Typography>
|
||||
),
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</CardContent>
|
||||
<RequirePermissions requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}>
|
||||
<Hr />
|
||||
<CardContent>
|
||||
<Typography className={classes.label} variant="caption">
|
||||
<FormattedMessage defaultMessage="Last order" />
|
||||
</Typography>
|
||||
{maybe(
|
||||
() => (
|
||||
{customer && customer.lastPlacedOrder ? (
|
||||
<Typography variant="h6" className={classes.value}>
|
||||
{customer.lastPlacedOrder.edges.length === 0 ? (
|
||||
"-"
|
||||
|
@ -73,10 +73,11 @@ const CustomerStats: React.FC<CustomerStatsProps> = props => {
|
|||
/>
|
||||
)}
|
||||
</Typography>
|
||||
),
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</CardContent>
|
||||
</RequirePermissions>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@ const customerList = gql`
|
|||
$last: Int
|
||||
$filter: CustomerFilterInput
|
||||
$sort: UserSortingInput
|
||||
$PERMISSION_MANAGE_ORDERS: Boolean!
|
||||
) {
|
||||
customers(
|
||||
after: $after
|
||||
|
@ -39,7 +40,7 @@ const customerList = gql`
|
|||
edges {
|
||||
node {
|
||||
...CustomerFragment
|
||||
orders {
|
||||
orders @include(if: $PERMISSION_MANAGE_ORDERS) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
|
@ -60,10 +61,10 @@ export const useCustomerListQuery = makeQuery<
|
|||
|
||||
const customerDetails = gql`
|
||||
${customerDetailsFragment}
|
||||
query CustomerDetails($id: ID!) {
|
||||
query CustomerDetails($id: ID!, $PERMISSION_MANAGE_ORDERS: Boolean!) {
|
||||
user(id: $id) {
|
||||
...CustomerDetailsFragment
|
||||
orders(last: 5) {
|
||||
orders(last: 5) @include(if: $PERMISSION_MANAGE_ORDERS) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
|
@ -79,7 +80,7 @@ const customerDetails = gql`
|
|||
}
|
||||
}
|
||||
}
|
||||
lastPlacedOrder: orders(last: 1) {
|
||||
lastPlacedOrder: orders(last: 1) @include(if: $PERMISSION_MANAGE_ORDERS) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
|
|
|
@ -135,4 +135,5 @@ export interface CustomerDetails {
|
|||
|
||||
export interface CustomerDetailsVariables {
|
||||
id: string;
|
||||
PERMISSION_MANAGE_ORDERS: boolean;
|
||||
}
|
||||
|
|
|
@ -53,4 +53,5 @@ export interface ListCustomersVariables {
|
|||
last?: number | null;
|
||||
filter?: CustomerFilterInput | null;
|
||||
sort?: UserSortingInput | null;
|
||||
PERMISSION_MANAGE_ORDERS: boolean;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { createFilterStructure } from "@saleor/customers/components/CustomerListPage";
|
||||
import { CustomerListUrlFilters } from "@saleor/customers/urls";
|
||||
import { date } from "@saleor/fixtures";
|
||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import { getFilterQueryParams } from "@saleor/utils/filters";
|
||||
import { stringifyQs } from "@saleor/utils/urls";
|
||||
import { getExistingKeys, setFilterOptsStatus } from "@test/filters";
|
||||
|
@ -31,7 +32,9 @@ describe("Filtering query params", () => {
|
|||
describe("Filtering URL params", () => {
|
||||
const intl = createIntl(config);
|
||||
|
||||
const filters = createFilterStructure(intl, {
|
||||
const filters = createFilterStructure(
|
||||
intl,
|
||||
{
|
||||
joined: {
|
||||
active: false,
|
||||
value: {
|
||||
|
@ -46,7 +49,20 @@ describe("Filtering URL params", () => {
|
|||
min: "1"
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
[
|
||||
{
|
||||
code: PermissionEnum.MANAGE_USERS,
|
||||
name: "Manage customers.",
|
||||
__typename: "UserPermission"
|
||||
},
|
||||
{
|
||||
code: PermissionEnum.MANAGE_ORDERS,
|
||||
name: "Manage orders..",
|
||||
__typename: "UserPermission"
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
it("should be empty if no active filters", () => {
|
||||
const filterQueryParams = getFilterQueryParams(
|
||||
|
|
|
@ -10,7 +10,6 @@ import RequirePermissions from "@saleor/components/RequirePermissions";
|
|||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { UserPermissionProps } from "@saleor/types";
|
||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
@ -33,7 +32,7 @@ const useStyles = makeStyles(
|
|||
{ name: "HomeNotificationTable" }
|
||||
);
|
||||
|
||||
interface HomeNotificationTableProps extends UserPermissionProps {
|
||||
interface HomeNotificationTableProps {
|
||||
ordersToCapture: number;
|
||||
ordersToFulfill: number;
|
||||
productsOutOfStock: number;
|
||||
|
@ -53,7 +52,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
|||
ordersToCapture,
|
||||
ordersToFulfill,
|
||||
productsOutOfStock,
|
||||
userPermissions,
|
||||
noChannel
|
||||
} = props;
|
||||
|
||||
|
@ -67,7 +65,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
|||
<TableBody className={classes.tableRow}>
|
||||
{noChannel && (
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_CHANNELS]}
|
||||
>
|
||||
<TableRow hover={true} onClick={onCreateNewChannelClick}>
|
||||
|
@ -83,7 +80,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
|||
</RequirePermissions>
|
||||
)}
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||
>
|
||||
<TableRow hover={true} onClick={onOrdersToFulfillClick}>
|
||||
|
@ -128,7 +124,6 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
|||
</TableRow>
|
||||
</RequirePermissions>
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
||||
>
|
||||
<TableRow hover={true} onClick={onProductsOutOfStockClick}>
|
||||
|
|
|
@ -5,7 +5,6 @@ import Money from "@saleor/components/Money";
|
|||
import RequirePermissions from "@saleor/components/RequirePermissions";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { UserPermissionProps } from "@saleor/types";
|
||||
import { PermissionEnum } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
|
||||
|
@ -44,7 +43,7 @@ const useStyles = makeStyles(
|
|||
{ name: "HomePage" }
|
||||
);
|
||||
|
||||
export interface HomePageProps extends UserPermissionProps {
|
||||
export interface HomePageProps {
|
||||
activities: Home_activities_edges_node[];
|
||||
orders: number | null;
|
||||
ordersToCapture: number | null;
|
||||
|
@ -76,7 +75,6 @@ const HomePage: React.FC<HomePageProps> = props => {
|
|||
ordersToCapture = 0,
|
||||
ordersToFulfill = 0,
|
||||
productsOutOfStock = 0,
|
||||
userPermissions = [],
|
||||
noChannel
|
||||
} = props;
|
||||
|
||||
|
@ -89,7 +87,6 @@ const HomePage: React.FC<HomePageProps> = props => {
|
|||
<Grid>
|
||||
<div>
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||
>
|
||||
<div className={classes.cardContainer}>
|
||||
|
@ -141,13 +138,11 @@ const HomePage: React.FC<HomePageProps> = props => {
|
|||
ordersToCapture={ordersToCapture}
|
||||
ordersToFulfill={ordersToFulfill}
|
||||
productsOutOfStock={productsOutOfStock}
|
||||
userPermissions={userPermissions}
|
||||
noChannel={noChannel}
|
||||
/>
|
||||
<CardSpacer />
|
||||
{topProducts && (
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[
|
||||
PermissionEnum.MANAGE_ORDERS,
|
||||
PermissionEnum.MANAGE_PRODUCTS
|
||||
|
@ -165,7 +160,6 @@ const HomePage: React.FC<HomePageProps> = props => {
|
|||
{activities && (
|
||||
<div>
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||
>
|
||||
<HomeActivityCard
|
||||
|
|
|
@ -65,7 +65,6 @@ const HomeSection = () => {
|
|||
ordersToFulfill={data?.ordersToFulfill?.totalCount}
|
||||
productsOutOfStock={data?.productsOutOfStock.totalCount}
|
||||
userName={getUserName(user, true)}
|
||||
userPermissions={user?.userPermissions}
|
||||
noChannel={noChannel}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -12,7 +12,7 @@ import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
|||
import { buttonMessages } from "@saleor/intl";
|
||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||
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 createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
||||
import React from "react";
|
||||
|
@ -55,9 +55,7 @@ export interface CustomerEditData {
|
|||
prevUserEmail?: string;
|
||||
}
|
||||
|
||||
export interface OrderCustomerProps
|
||||
extends Partial<FetchMoreProps>,
|
||||
UserPermissionProps {
|
||||
export interface OrderCustomerProps extends Partial<FetchMoreProps> {
|
||||
order: OrderDetails_order;
|
||||
users?: SearchCustomers_search_edges_node[];
|
||||
loading?: boolean;
|
||||
|
@ -79,7 +77,6 @@ const OrderCustomer: React.FC<OrderCustomerProps> = props => {
|
|||
loading,
|
||||
order,
|
||||
users,
|
||||
userPermissions,
|
||||
onCustomerEdit,
|
||||
onBillingAddressEdit,
|
||||
onFetchMore: onFetchMoreUsers,
|
||||
|
@ -131,7 +128,6 @@ const OrderCustomer: React.FC<OrderCustomerProps> = props => {
|
|||
toolbar={
|
||||
!!canEditCustomer && (
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||
>
|
||||
<Button
|
||||
|
@ -209,7 +205,6 @@ const OrderCustomer: React.FC<OrderCustomerProps> = props => {
|
|||
{user.email}
|
||||
</Typography>
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_USERS]}
|
||||
>
|
||||
<div>
|
||||
|
|
|
@ -15,7 +15,6 @@ import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
|||
import { Backlink } from "@saleor/macaw-ui";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import OrderChannelSectionCard from "@saleor/orders/components/OrderChannelSectionCard";
|
||||
import { UserPermissionProps } from "@saleor/types";
|
||||
import { mapMetadataItemToInput } from "@saleor/utils/maps";
|
||||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||
import React from "react";
|
||||
|
@ -55,7 +54,7 @@ const useStyles = makeStyles(
|
|||
}
|
||||
);
|
||||
|
||||
export interface OrderDetailsPageProps extends UserPermissionProps {
|
||||
export interface OrderDetailsPageProps {
|
||||
order: OrderDetails_order;
|
||||
shop: OrderDetails_shop;
|
||||
shippingMethods?: Array<{
|
||||
|
@ -114,7 +113,6 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
order,
|
||||
shop,
|
||||
saveButtonBarState,
|
||||
userPermissions,
|
||||
onBack,
|
||||
onBillingAddressEdit,
|
||||
onFulfillmentApprove,
|
||||
|
@ -299,7 +297,6 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
canEditAddresses={canEditAddresses}
|
||||
canEditCustomer={false}
|
||||
order={order}
|
||||
userPermissions={userPermissions}
|
||||
onBillingAddressEdit={onBillingAddressEdit}
|
||||
onShippingAddressEdit={onShippingAddressEdit}
|
||||
onProfileView={onProfileView}
|
||||
|
|
|
@ -14,7 +14,7 @@ import { Backlink } from "@saleor/macaw-ui";
|
|||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import DraftOrderChannelSectionCard from "@saleor/orders/components/DraftOrderChannelSectionCard";
|
||||
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 { useIntl } from "react-intl";
|
||||
|
||||
|
@ -37,9 +37,7 @@ const useStyles = makeStyles(
|
|||
{ name: "OrderDraftPage" }
|
||||
);
|
||||
|
||||
export interface OrderDraftPageProps
|
||||
extends FetchMoreProps,
|
||||
UserPermissionProps {
|
||||
export interface OrderDraftPageProps extends FetchMoreProps {
|
||||
disabled: boolean;
|
||||
order: OrderDetails_order;
|
||||
users: SearchCustomers_search_edges_node[];
|
||||
|
@ -85,8 +83,7 @@ const OrderDraftPage: React.FC<OrderDraftPageProps> = props => {
|
|||
onProfileView,
|
||||
order,
|
||||
users,
|
||||
usersLoading,
|
||||
userPermissions
|
||||
usersLoading
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
|
@ -147,7 +144,6 @@ const OrderDraftPage: React.FC<OrderDraftPageProps> = props => {
|
|||
loading={usersLoading}
|
||||
order={order}
|
||||
users={users}
|
||||
userPermissions={userPermissions}
|
||||
onBillingAddressEdit={onBillingAddressEdit}
|
||||
onCustomerEdit={onCustomerEdit}
|
||||
onFetchMore={onFetchMore}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { useUser } from "@saleor/auth";
|
||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
||||
|
@ -84,7 +83,6 @@ export const OrderDraftDetails: React.FC<OrderDraftDetailsProps> = ({
|
|||
}) => {
|
||||
const order = data.order;
|
||||
const navigate = useNavigator();
|
||||
const { user } = useUser();
|
||||
|
||||
const {
|
||||
loadMore,
|
||||
|
@ -214,7 +212,6 @@ export const OrderDraftDetails: React.FC<OrderDraftDetailsProps> = ({
|
|||
}
|
||||
saveButtonBarState="default"
|
||||
onProfileView={() => navigate(customerUrl(order.user.id))}
|
||||
userPermissions={user?.userPermissions || []}
|
||||
/>
|
||||
</OrderLineDiscountProvider>
|
||||
</OrderDiscountProvider>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { useUser } from "@saleor/auth";
|
||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
|
@ -95,7 +94,6 @@ export const OrderNormalDetails: React.FC<OrderNormalDetailsProps> = ({
|
|||
const order = data?.order;
|
||||
const shop = data?.shop;
|
||||
const navigate = useNavigator();
|
||||
const { user } = useUser();
|
||||
|
||||
const warehouses = useWarehouseList({
|
||||
displayLoader: true,
|
||||
|
@ -168,7 +166,6 @@ export const OrderNormalDetails: React.FC<OrderNormalDetailsProps> = ({
|
|||
]
|
||||
)}
|
||||
shippingMethods={data?.order?.shippingMethods || []}
|
||||
userPermissions={user?.userPermissions || []}
|
||||
onOrderCancel={() => openModal("cancel")}
|
||||
onOrderFulfill={() => navigate(orderFulfillUrl(id))}
|
||||
onFulfillmentApprove={fulfillmentId =>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { useUser } from "@saleor/auth";
|
||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||
import { useCustomerAddressesQuery } from "@saleor/customers/queries";
|
||||
|
@ -109,7 +108,6 @@ export const OrderUnconfirmedDetails: React.FC<OrderUnconfirmedDetailsProps> = (
|
|||
const order = data.order;
|
||||
const shop = data.shop;
|
||||
const navigate = useNavigator();
|
||||
const { user } = useUser();
|
||||
|
||||
const {
|
||||
loadMore,
|
||||
|
@ -201,7 +199,6 @@ export const OrderUnconfirmedDetails: React.FC<OrderUnconfirmedDetailsProps> = (
|
|||
]
|
||||
)}
|
||||
shippingMethods={data?.order?.shippingMethods || []}
|
||||
userPermissions={user?.userPermissions || []}
|
||||
onOrderCancel={() => openModal("cancel")}
|
||||
onOrderFulfill={() => navigate(orderFulfillUrl(id))}
|
||||
onFulfillmentApprove={fulfillmentId =>
|
||||
|
|
|
@ -28,7 +28,6 @@ export interface ShippingZonesListPageProps
|
|||
const ShippingZonesListPage: React.FC<ShippingZonesListPageProps> = ({
|
||||
defaultWeightUnit,
|
||||
disabled,
|
||||
userPermissions,
|
||||
onBack,
|
||||
onSubmit,
|
||||
...listProps
|
||||
|
@ -52,7 +51,6 @@ const ShippingZonesListPage: React.FC<ShippingZonesListPageProps> = ({
|
|||
</div>
|
||||
<div>
|
||||
<RequirePermissions
|
||||
userPermissions={userPermissions}
|
||||
requiredPermissions={[PermissionEnum.MANAGE_SETTINGS]}
|
||||
>
|
||||
<ShippingWeightUnitForm
|
||||
|
|
|
@ -73323,7 +73323,7 @@ exports[`Storyshots Views / Customers / Customer list default 1`] = `
|
|||
>
|
||||
<td
|
||||
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
||||
colspan="4"
|
||||
colspan="3"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
||||
|
@ -74994,7 +74994,7 @@ exports[`Storyshots Views / Customers / Customer list loading 1`] = `
|
|||
>
|
||||
<td
|
||||
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
||||
colspan="4"
|
||||
colspan="3"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
||||
|
@ -75348,7 +75348,7 @@ exports[`Storyshots Views / Customers / Customer list no data 1`] = `
|
|||
>
|
||||
<td
|
||||
class="MuiTableCell-root-id MuiTableCell-footer-id"
|
||||
colspan="4"
|
||||
colspan="3"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root-id MuiToolbar-regular-id Pagination-toolbar-id"
|
||||
|
@ -75420,7 +75420,7 @@ exports[`Storyshots Views / Customers / Customer list no data 1`] = `
|
|||
>
|
||||
<td
|
||||
class="MuiTableCell-root-id MuiTableCell-body-id"
|
||||
colspan="4"
|
||||
colspan="3"
|
||||
>
|
||||
No customers found
|
||||
</td>
|
||||
|
@ -235532,107 +235532,7 @@ exports[`Storyshots Views / Shipping / Shipping zones list default 1`] = `
|
|||
</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>
|
||||
|
@ -235953,107 +235853,7 @@ exports[`Storyshots Views / Shipping / Shipping zones list loading 1`] = `
|
|||
</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>
|
||||
|
@ -236255,107 +236055,7 @@ exports[`Storyshots Views / Shipping / Shipping zones list no data 1`] = `
|
|||
</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>
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
import ActionDialog from "@saleor/components/ActionDialog";
|
||||
import ActionDialogComponent from "@saleor/components/ActionDialog";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import Decorator from "../../Decorator";
|
||||
import { MockedUserProvider } from "../customers/MockedUserProvider";
|
||||
|
||||
const ActionDialog = props => (
|
||||
<MockedUserProvider>
|
||||
<ActionDialogComponent {...props} />
|
||||
</MockedUserProvider>
|
||||
);
|
||||
|
||||
storiesOf("Generics / ActionDialog", module)
|
||||
.addDecorator(Decorator)
|
||||
|
|
|
@ -2,11 +2,12 @@ import { AccountErrorCode } from "@saleor/types/globalTypes";
|
|||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import CustomerDetailsPage, {
|
||||
import CustomerDetailsPageComponent, {
|
||||
CustomerDetailsPageProps
|
||||
} from "../../../customers/components/CustomerDetailsPage";
|
||||
import { customer } from "../../../customers/fixtures";
|
||||
import Decorator from "../../Decorator";
|
||||
import { MockedUserProvider } from "./MockedUserProvider";
|
||||
|
||||
const props: Omit<CustomerDetailsPageProps, "classes"> = {
|
||||
customer,
|
||||
|
@ -28,6 +29,12 @@ interface CustomerDetailsPageErrors {
|
|||
note: string;
|
||||
}
|
||||
|
||||
const CustomerDetailsPage = props => (
|
||||
<MockedUserProvider>
|
||||
<CustomerDetailsPageComponent {...props} />
|
||||
</MockedUserProvider>
|
||||
);
|
||||
|
||||
storiesOf("Views / Customers / Customer details", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("default", () => <CustomerDetailsPage {...props} />)
|
||||
|
|
|
@ -2,7 +2,7 @@ import { CustomerListUrlSortField } from "@saleor/customers/urls";
|
|||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import CustomerListPage, {
|
||||
import CustomerListPageComponent, {
|
||||
CustomerListPageProps
|
||||
} from "../../../customers/components/CustomerListPage";
|
||||
import { customerList } from "../../../customers/fixtures";
|
||||
|
@ -15,6 +15,7 @@ import {
|
|||
tabPageProps
|
||||
} from "../../../fixtures";
|
||||
import Decorator from "../../Decorator";
|
||||
import { MockedUserProvider } from "./MockedUserProvider";
|
||||
|
||||
const props: CustomerListPageProps = {
|
||||
...filterPageProps,
|
||||
|
@ -46,6 +47,12 @@ const props: CustomerListPageProps = {
|
|||
}
|
||||
};
|
||||
|
||||
const CustomerListPage = props => (
|
||||
<MockedUserProvider>
|
||||
<CustomerListPageComponent {...props} />
|
||||
</MockedUserProvider>
|
||||
);
|
||||
|
||||
storiesOf("Views / Customers / Customer list", module)
|
||||
.addDecorator(Decorator)
|
||||
.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 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 Decorator from "../../Decorator";
|
||||
import { MockedUserProvider } from "../customers/MockedUserProvider";
|
||||
|
||||
const shop = shopFixture(placeholderImage);
|
||||
|
||||
|
@ -25,8 +28,17 @@ const homePageProps: Omit<HomePageProps, "classes"> = {
|
|||
productsOutOfStock: shop.productsOutOfStock.totalCount,
|
||||
sales: shop.salesToday.gross,
|
||||
topProducts: mapEdgesToItems(shop.productTopToday),
|
||||
userName: "admin@example.com",
|
||||
userPermissions: adminUserPermissions
|
||||
userName: "admin@example.com"
|
||||
};
|
||||
|
||||
const HomePage = props => {
|
||||
const customPermissions = props?.customPermissions;
|
||||
|
||||
return (
|
||||
<MockedUserProvider customPermissions={customPermissions}>
|
||||
<HomePageComponent {...props} />
|
||||
</MockedUserProvider>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf("Views / HomePage", module)
|
||||
|
@ -49,12 +61,12 @@ storiesOf("Views / HomePage", module)
|
|||
<HomePage {...homePageProps} topProducts={[]} activities={[]} />
|
||||
))
|
||||
.add("no permissions", () => (
|
||||
<HomePage {...homePageProps} userPermissions={[]} />
|
||||
<HomePage {...homePageProps} customPermissions={[]} />
|
||||
))
|
||||
.add("product permissions", () => (
|
||||
<HomePage
|
||||
{...homePageProps}
|
||||
userPermissions={adminUserPermissions.filter(
|
||||
customPermissions={adminUserPermissions.filter(
|
||||
perm => perm.code === PermissionEnum.MANAGE_PRODUCTS
|
||||
)}
|
||||
/>
|
||||
|
@ -62,7 +74,7 @@ storiesOf("Views / HomePage", module)
|
|||
.add("order permissions", () => (
|
||||
<HomePage
|
||||
{...homePageProps}
|
||||
userPermissions={adminUserPermissions.filter(
|
||||
customPermissions={adminUserPermissions.filter(
|
||||
perm => perm.code === PermissionEnum.MANAGE_ORDERS
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { adminUserPermissions } from "@saleor/fixtures";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import OrderCustomer, {
|
||||
import OrderCustomerComponent, {
|
||||
OrderCustomerProps
|
||||
} from "../../../orders/components/OrderCustomer";
|
||||
import { clients, order as orderFixture } from "../../../orders/fixtures";
|
||||
import Decorator from "../../Decorator";
|
||||
import { MockedUserProvider } from "../customers/MockedUserProvider";
|
||||
|
||||
const order = orderFixture("");
|
||||
|
||||
|
@ -19,10 +19,19 @@ const props: Omit<OrderCustomerProps, "classes"> = {
|
|||
onProfileView: () => undefined,
|
||||
onShippingAddressEdit: undefined,
|
||||
order,
|
||||
userPermissions: adminUserPermissions,
|
||||
users: clients
|
||||
};
|
||||
|
||||
const OrderCustomer = props => {
|
||||
const customPermissions = props?.customPermissions;
|
||||
|
||||
return (
|
||||
<MockedUserProvider customPermissions={customPermissions}>
|
||||
<OrderCustomerComponent {...props} />
|
||||
</MockedUserProvider>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf("Orders / OrderCustomer", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("default", () => <OrderCustomer {...props} />)
|
||||
|
@ -40,5 +49,5 @@ storiesOf("Orders / OrderCustomer", module)
|
|||
<OrderCustomer {...props} canEditAddresses={true} canEditCustomer={true} />
|
||||
))
|
||||
.add("no user permissions", () => (
|
||||
<OrderCustomer {...props} userPermissions={[]} />
|
||||
<OrderCustomer {...props} customPermissions={[]} />
|
||||
));
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import placeholderImage from "@assets/images/placeholder60x60.png";
|
||||
import { adminUserPermissions } from "@saleor/fixtures";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
|
@ -43,8 +42,7 @@ const props: Omit<OrderDetailsPageProps, "classes"> = {
|
|||
onSubmit: () => undefined,
|
||||
order,
|
||||
shop: shopFixture,
|
||||
saveButtonBarState: "default",
|
||||
userPermissions: adminUserPermissions
|
||||
saveButtonBarState: "default"
|
||||
};
|
||||
|
||||
storiesOf("Views / Orders / Order details", module)
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import placeholderImage from "@assets/images/placeholder60x60.png";
|
||||
import { adminUserPermissions, fetchMoreProps } from "@saleor/fixtures";
|
||||
import { fetchMoreProps } from "@saleor/fixtures";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import OrderDraftPage, {
|
||||
import OrderDraftPageComponent, {
|
||||
OrderDraftPageProps
|
||||
} from "../../../../orders/components/OrderDraftPage";
|
||||
import { clients, draftOrder } from "../../../../orders/fixtures";
|
||||
import Decorator from "../../../Decorator";
|
||||
import { MockedUserProvider } from "../../customers/MockedUserProvider";
|
||||
import { getDiscountsProvidersWrapper } from "./utils";
|
||||
|
||||
const order = draftOrder(placeholderImage);
|
||||
|
@ -31,13 +32,22 @@ const props: Omit<OrderDraftPageProps, "classes"> = {
|
|||
onShippingMethodEdit: undefined,
|
||||
order,
|
||||
saveButtonBarState: "default",
|
||||
userPermissions: adminUserPermissions,
|
||||
users: clients,
|
||||
usersLoading: false
|
||||
};
|
||||
|
||||
const DiscountsDecorator = getDiscountsProvidersWrapper(order);
|
||||
|
||||
const OrderDraftPage = props => {
|
||||
const customPermissions = props?.customPermissions;
|
||||
|
||||
return (
|
||||
<MockedUserProvider customPermissions={customPermissions}>
|
||||
<OrderDraftPageComponent {...props} />
|
||||
</MockedUserProvider>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf("Views / Orders / Order draft", module)
|
||||
.addDecorator(Decorator)
|
||||
.addDecorator(DiscountsDecorator)
|
||||
|
@ -49,5 +59,5 @@ storiesOf("Views / Orders / Order draft", module)
|
|||
<OrderDraftPage {...props} order={{ ...order, lines: [] }} />
|
||||
))
|
||||
.add("no user permissions", () => (
|
||||
<OrderDraftPage {...props} userPermissions={[]} />
|
||||
<OrderDraftPage {...props} customPermissions={[]} />
|
||||
));
|
||||
|
|
Loading…
Reference in a new issue