Merge pull request #779 from mirumee/fix/multiple-value-attribute-1399

Fix multiple value dropdown
This commit is contained in:
Marcin Gębala 2020-10-20 08:24:49 +02:00 committed by GitHub
commit fb2957e2f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 127 additions and 31 deletions

View file

@ -170,13 +170,15 @@ const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFie
/>
{isOpen && (!!inputValue || !!choices.length) && (
<MultiAutocompleteSelectFieldContent
add={{
...add,
onClick: () => {
add.onClick();
closeMenu();
add={
add && {
...add,
onClick: () => {
add.onClick();
closeMenu();
}
}
}}
}
choices={choices.filter(
choice => !value.includes(choice.value)
)}

View file

@ -0,0 +1,111 @@
import { FormsetData } from "@saleor/hooks/useFormset";
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
import { ProductAttributeInputData } from "../components/ProductAttributes";
import { createAttributeMultiChangeHandler } from "./handlers";
const attributes: FormsetData<ProductAttributeInputData, string[]> = [
{
data: {
inputType: AttributeInputTypeEnum.DROPDOWN,
isRequired: false,
values: [
{
__typename: "AttributeValue",
id: "attrv-1",
name: "Attribute 1 Value 1",
slug: "attr-1-v-1"
}
]
},
id: "attr-1",
label: "Attribute 1",
value: []
},
{
data: {
inputType: AttributeInputTypeEnum.MULTISELECT,
isRequired: false,
values: [
{
__typename: "AttributeValue",
id: "attrv-2",
name: "Attribute 2 Value 1",
slug: "attr-2-v-1"
},
{
__typename: "AttributeValue",
id: "attrv-3",
name: "Attribute 2 Value 2",
slug: "attr-2-v-2"
},
{
__typename: "AttributeValue",
id: "attrv-4",
name: "Attribute 2 Value 3",
slug: "attr-2-v-3"
}
]
},
id: "attr-2",
label: "Attribute 2",
value: ["attr-2-v-3"]
}
];
describe("Multiple select", () => {
it("is able to select value", () => {
const change = jest.fn();
const trigger = jest.fn();
const handler = createAttributeMultiChangeHandler(
change,
attributes,
trigger
);
handler("attr-2", "attr-2-v-1");
expect(change).toHaveBeenCalledTimes(1);
expect(change.mock.calls[0][0]).toBe("attr-2");
expect(change.mock.calls[0][1]).toHaveLength(2);
expect(change.mock.calls[0][1][0]).toBe("attr-2-v-3");
expect(change.mock.calls[0][1][1]).toBe("attr-2-v-1");
expect(trigger).toHaveBeenCalledTimes(1);
});
it("is able to deselect value", () => {
const change = jest.fn();
const trigger = jest.fn();
const handler = createAttributeMultiChangeHandler(
change,
attributes,
trigger
);
handler("attr-2", "attr-2-v-3");
expect(change).toHaveBeenCalledTimes(1);
expect(change.mock.calls[0][0]).toBe("attr-2");
expect(change.mock.calls[0][1]).toHaveLength(0);
expect(trigger).toHaveBeenCalledTimes(1);
});
it("is able to add custom value", () => {
const change = jest.fn();
const trigger = jest.fn();
const handler = createAttributeMultiChangeHandler(
change,
attributes,
trigger
);
handler("attr-2", "A Value");
expect(change).toHaveBeenCalledTimes(1);
expect(change.mock.calls[0][0]).toBe("attr-2");
expect(change.mock.calls[0][1]).toHaveLength(2);
expect(change.mock.calls[0][1][0]).toBe("attr-2-v-3");
expect(change.mock.calls[0][1][1]).toBe("A Value");
expect(trigger).toHaveBeenCalledTimes(1);
});
});

View file

@ -1,4 +1,3 @@
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
import { FormChange } from "@saleor/hooks/useForm";
import { FormsetChange, FormsetData } from "@saleor/hooks/useFormset";
import { toggle } from "@saleor/utils/lists";
@ -18,38 +17,22 @@ export function createAttributeChangeHandler(
export function createAttributeMultiChangeHandler(
changeAttributeData: FormsetChange<string[]>,
attributes: FormsetData<ProductAttributeInputData>,
attributes: FormsetData<ProductAttributeInputData, string[]>,
triggerChange: () => void
): FormsetChange {
return (attributeId: string, value: string) => {
const attributeValue = attributes
.find(attribute => attribute.id === attributeId)
.data.values.find(attributeValue => attributeValue.slug === value);
const valueChoice = {
label: attributeValue ? attributeValue.name : value,
value
};
const itemIndex = attributes.findIndex(item => item.id === attributeId);
const attributeValues: MultiAutocompleteChoiceType[] = attributes[
itemIndex
].data.values.map(value => ({
label: value.name,
value: value.id
}));
const attribute = attributes.find(
attribute => attribute.id === attributeId
);
const newAttributeValues = toggle(
valueChoice,
attributeValues,
(a, b) => a.value === b.value
value,
attribute.value,
(a, b) => a === b
);
triggerChange();
changeAttributeData(
attributeId,
newAttributeValues.map(({ value }) => value)
);
changeAttributeData(attributeId, newAttributeValues);
};
}