Remove attribute selection

This commit is contained in:
dominik-zeglen 2019-10-03 16:49:58 +02:00
parent 0148bc4527
commit 36396c9d3e
8 changed files with 47 additions and 149 deletions

View file

@ -1,77 +0,0 @@
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import makeStyles from "@material-ui/styles/makeStyles";
import React from "react";
import { FormattedMessage } from "react-intl";
import Checkbox from "@saleor/components/Checkbox";
import { maybe, renderCollection } from "@saleor/misc";
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
import { ProductVariantCreateFormData } from "./form";
export interface ProductVariantCreateAttributesProps {
attributes: ProductDetails_product_productType_variantAttributes[];
data: ProductVariantCreateFormData;
onAttributeClick: (id: string) => void;
}
const useStyles = makeStyles({
checkboxCell: {
paddingLeft: 0
},
wideCell: {
width: "100%"
}
});
const ProductVariantCreateAttributes: React.FC<
ProductVariantCreateAttributesProps
> = props => {
const { attributes, data, onAttributeClick } = props;
const classes = useStyles(props);
return (
<Table key="table">
<TableBody>
{renderCollection(
attributes,
attribute => {
if (!attribute) {
return null;
}
const isChecked = !!data.attributes.find(
selectedAttribute => selectedAttribute.id === attribute.id
);
return (
<TableRow key={maybe(() => attribute.id)}>
<TableCell padding="checkbox" className={classes.checkboxCell}>
<Checkbox
checked={isChecked}
disableClickPropagation={true}
onChange={() => onAttributeClick(attribute.id)}
/>
</TableCell>
<TableCell className={classes.wideCell}>
{attribute.name}
</TableCell>
</TableRow>
);
},
() => (
<TableRow>
<TableCell colSpan={2}>
<FormattedMessage defaultMessage="This product type has no variant attributes" />
</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
);
};
ProductVariantCreateAttributes.displayName = "ProductVariantCreateAttributes";
export default ProductVariantCreateAttributes;

View file

@ -5,7 +5,6 @@ import { ProductDetails_product_productType_variantAttributes } from "@saleor/pr
import { ProductVariantBulkCreate_productVariantBulkCreate_bulkProductErrors } from "@saleor/products/types/ProductVariantBulkCreate";
import { isSelected } from "@saleor/utils/lists";
import { ProductVariantCreateFormData } from "./form";
import ProductVariantCreateAttributes from "./ProductVariantCreateAttributes";
import ProductVariantCreatePrices from "./ProductVariantCreatePrices";
import ProductVariantCreateSummary from "./ProductVariantCreateSummary";
import ProductVariantCreateTabs from "./ProductVariantCreateTabs";
@ -54,18 +53,6 @@ const ProductVariantCreateContent: React.FC<
<div>
<ProductVariantCreateTabs step={step} />
<div className={classes.root}>
{step === "attributes" && (
<ProductVariantCreateAttributes
attributes={attributes}
data={data}
onAttributeClick={attributeId =>
dispatchFormDataAction({
attributeId,
type: "selectAttribute"
})
}
/>
)}
{step === "values" && (
<ProductVariantCreateValues
attributes={selectedAttributes}

View file

@ -9,7 +9,7 @@ import React from "react";
import { FormattedMessage } from "react-intl";
import { ProductVariantBulkCreateInput } from "../../../types/globalTypes";
import { initialForm, ProductVariantCreateFormData } from "./form";
import { createInitialForm, ProductVariantCreateFormData } from "./form";
import ProductVariantCreateContent, {
ProductVariantCreateContentProps
} from "./ProductVariantCreateContent";
@ -32,8 +32,6 @@ function canHitNext(
data: ProductVariantCreateFormData
): boolean {
switch (step) {
case "attributes":
return data.attributes.length > 0;
case "values":
return data.attributes.every(attribute => attribute.values.length > 0);
case "prices":
@ -77,6 +75,7 @@ export interface ProductVariantCreateDialogProps
ProductVariantCreateContentProps,
"data" | "dispatchFormDataAction" | "step"
> {
defaultPrice: string;
open: boolean;
onClose: () => void;
onSubmit: (data: ProductVariantBulkCreateInput[]) => void;
@ -85,17 +84,19 @@ export interface ProductVariantCreateDialogProps
const ProductVariantCreateDialog: React.FC<
ProductVariantCreateDialogProps
> = props => {
const { open, onClose, onSubmit, ...contentProps } = props;
const {
attributes,
defaultPrice,
open,
onClose,
onSubmit,
...contentProps
} = props;
const classes = useStyles(props);
const [step, setStep] = React.useState<ProductVariantCreateStep>(
"attributes"
);
const [step, setStep] = React.useState<ProductVariantCreateStep>("values");
function handleNextStep() {
switch (step) {
case "attributes":
setStep("values");
break;
case "values":
setStep("prices");
break;
@ -107,9 +108,6 @@ const ProductVariantCreateDialog: React.FC<
function handlePrevStep() {
switch (step) {
case "values":
setStep("attributes");
break;
case "prices":
setStep("values");
break;
@ -121,7 +119,16 @@ const ProductVariantCreateDialog: React.FC<
const [data, dispatchFormDataAction] = React.useReducer(
reduceProductVariantCreateFormData,
initialForm
createInitialForm(attributes, defaultPrice)
);
React.useEffect(
() =>
dispatchFormDataAction({
data: createInitialForm(attributes, defaultPrice),
type: "reload"
}),
[attributes.length]
);
return (
@ -135,6 +142,7 @@ const ProductVariantCreateDialog: React.FC<
<DialogContent className={classes.content}>
<ProductVariantCreateContent
{...contentProps}
attributes={attributes}
data={data}
dispatchFormDataAction={dispatchFormDataAction}
step={step}
@ -144,7 +152,7 @@ const ProductVariantCreateDialog: React.FC<
<Button className={classes.button} onClick={onClose}>
<FormattedMessage defaultMessage="Cancel" description="button" />
</Button>
{step !== "attributes" && (
{step !== "values" && (
<Button
className={classes.button}
color="primary"

View file

@ -13,13 +13,6 @@ interface Step {
}
function getSteps(intl: IntlShape): Step[] {
return [
{
label: intl.formatMessage({
defaultMessage: "Choose Attributes",
description: "variant creation step"
}),
value: "attributes"
},
{
label: intl.formatMessage({
defaultMessage: "Select Values",

View file

@ -1,3 +1,4 @@
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
import { ProductVariantBulkCreateInput } from "../../../types/globalTypes";
export interface AttributeValue {
@ -21,12 +22,18 @@ export interface ProductVariantCreateFormData {
variants: ProductVariantBulkCreateInput[];
}
export const initialForm: ProductVariantCreateFormData = {
attributes: [],
export const createInitialForm = (
attributes: ProductDetails_product_productType_variantAttributes[],
price: string
): ProductVariantCreateFormData => ({
attributes: attributes.map(attribute => ({
id: attribute.id,
values: []
})),
price: {
all: true,
attribute: undefined,
value: "",
value: price || "",
values: []
},
stock: {
@ -36,4 +43,4 @@ export const initialForm: ProductVariantCreateFormData = {
values: []
},
variants: []
};
});

View file

@ -6,7 +6,7 @@ import {
updateAtIndex
} from "@saleor/utils/lists";
import { createVariants } from "./createVariants";
import { initialForm, ProductVariantCreateFormData } from "./form";
import { ProductVariantCreateFormData } from "./form";
export type ProductVariantCreateReducerActionType =
| "applyPriceToAll"
@ -21,13 +21,14 @@ export type ProductVariantCreateReducerActionType =
| "changeAttributeValueStock"
| "changeVariantData"
| "deleteVariant"
| "selectAttribute"
| "reload"
| "selectValue";
export type VariantField = "stock" | "price" | "sku";
export interface ProductVariantCreateReducerAction {
all?: boolean;
attributeId?: string;
data?: ProductVariantCreateFormData;
field?: VariantField;
type: ProductVariantCreateReducerActionType;
value?: string;
@ -35,31 +36,12 @@ export interface ProductVariantCreateReducerAction {
variantIndex?: number;
}
function selectAttribute(
state: ProductVariantCreateFormData,
attributeId: string
): ProductVariantCreateFormData {
const attributes = toggle(
{
id: attributeId,
values: []
},
state.attributes,
(a, b) => a.id === b.id
);
return {
...initialForm,
attributes
};
}
function selectValue(
state: ProductVariantCreateFormData,
prevState: ProductVariantCreateFormData,
attributeId: string,
valueId: string
): ProductVariantCreateFormData {
const attribute = state.attributes.find(
const attribute = prevState.attributes.find(
attribute => attribute.id === attributeId
);
const values = toggle(valueId, attribute.values, (a, b) => a === b);
@ -68,11 +50,11 @@ function selectValue(
id: attributeId,
values
},
remove(attribute, state.attributes, (a, b) => a.id === b.id)
remove(attribute, prevState.attributes, (a, b) => a.id === b.id)
);
return {
...initialForm,
...prevState,
attributes: updatedAttributes
};
}
@ -310,9 +292,6 @@ function reduceProductVariantCreateFormData(
action: ProductVariantCreateReducerAction
) {
switch (action.type) {
case "selectAttribute":
return selectAttribute(prevState, action.attributeId);
case "selectValue":
return selectValue(prevState, action.attributeId, action.valueId);
@ -341,6 +320,8 @@ function reduceProductVariantCreateFormData(
);
case "deleteVariant":
return deleteVariant(prevState, action.variantIndex);
case "reload":
return action.data;
default:
return prevState;
}

View file

@ -1,5 +1 @@
export type ProductVariantCreateStep =
| "attributes"
| "values"
| "prices"
| "summary";
export type ProductVariantCreateStep = "values" | "prices" | "summary";

View file

@ -353,6 +353,9 @@ export const ProductUpdate: React.StatelessComponent<ProductUpdateProps> = ({
</DialogContentText>
</ActionDialog>
<ProductVariantCreateDialog
defaultPrice={maybe(() =>
data.product.basePrice.amount.toFixed(2)
)}
errors={maybe(
() =>
bulkProductVariantCreate.opts.data