Merge pull request #779 from mirumee/fix/multiple-value-attribute-1399
Fix multiple value dropdown
This commit is contained in:
commit
fb2957e2f5
3 changed files with 127 additions and 31 deletions
|
@ -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)
|
||||
)}
|
||||
|
|
111
src/products/utils/handlers.test.ts
Normal file
111
src/products/utils/handlers.test.ts
Normal 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);
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue