Skip to content

Commit 21eacd7

Browse files
witoszekdevCopilot
andauthored
Add create new option, add query for missing elements in combobobx (#6278)
* wip: add missing create new option, add query when no elements are found * add method to transform option, add more comments * add tests * remove failing tests covered by macaw * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * update complicated mock for react-intl * update test with better description * Add changeset * fix failing test add better description --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 944569d commit 21eacd7

9 files changed

Lines changed: 824 additions & 57 deletions

File tree

.changeset/lovely-bananas-own.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"saleor-dashboard": patch
3+
---
4+
5+
Fix combobox components in Attribute selection. "Add new value" option was added again for clear UX. New values are added when clicked "Save" in the form, like previously. Fixed fetching more items in the combobox: now when user enters a value in the input, we fetch options using input from user as `query` parameter.

src/attributes/utils/handlers.test.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,14 @@ describe("Sending only changed attributes", () => {
279279
});
280280

281281
describe("works with select attributes", () => {
282+
const SKIP_SUBMIT = Symbol("SKIP_SUBMIT");
283+
282284
test.each`
283285
newAttr | oldAttr | expected
284-
${null} | ${null} | ${null}
285-
${"my value"} | ${"my value"} | ${null}
286-
${"my value"} | ${null} | ${["my value"]}
287-
${null} | ${"my value"} | ${[]}
286+
${null} | ${null} | ${SKIP_SUBMIT}
287+
${"my value"} | ${"my value"} | ${SKIP_SUBMIT}
288+
${"my value"} | ${null} | ${{ value: "my value" }}
289+
${null} | ${"my value"} | ${null}
288290
`("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
289291
const attribute = createSelectAttribute(newAttr);
290292
const prevAttribute = createSelectAttribute(oldAttr);
@@ -293,7 +295,8 @@ describe("Sending only changed attributes", () => {
293295
prevAttributes: [prevAttribute],
294296
updatedFileAttributes: [],
295297
});
296-
const expectedResult = expected !== null ? [{ id: ATTR_ID, values: expected }] : [];
298+
// "skip" means the attribute hasn't changed, and won't be included in mutation
299+
const expectedResult = expected !== SKIP_SUBMIT ? [{ id: ATTR_ID, dropdown: expected }] : [];
297300

298301
expect(result).toEqual(expectedResult);
299302
});
@@ -302,10 +305,10 @@ describe("Sending only changed attributes", () => {
302305
describe("works with required select attributes", () => {
303306
test.each`
304307
newAttr | oldAttr | expected
305-
${null} | ${null} | ${[]}
306-
${"my value"} | ${"my value"} | ${["my value"]}
307-
${"my value"} | ${null} | ${["my value"]}
308-
${null} | ${"my value"} | ${[]}
308+
${null} | ${null} | ${null}
309+
${"my value"} | ${"my value"} | ${{ value: "my value" }}
310+
${"my value"} | ${null} | ${{ value: "my value" }}
311+
${null} | ${"my value"} | ${null}
309312
`("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
310313
const attribute = createSelectAttribute(newAttr, true);
311314
const prevAttribute = createSelectAttribute(oldAttr, true);
@@ -314,7 +317,7 @@ describe("Sending only changed attributes", () => {
314317
prevAttributes: [prevAttribute],
315318
updatedFileAttributes: [],
316319
});
317-
const expectedResult = expected !== null ? [{ id: ATTR_ID, values: expected }] : [];
320+
const expectedResult = [{ id: ATTR_ID, dropdown: expected }];
318321

319322
expect(result).toEqual(expectedResult);
320323
});
@@ -925,10 +928,10 @@ describe("prepareAttributesInput", () => {
925928
});
926929

927930
// Assert
928-
expect(result).toEqual([{ id: ATTR_ID, values: ["val-1"] }]);
931+
expect(result).toEqual([{ id: ATTR_ID, dropdown: { value: "val-1" } }]);
929932
});
930933

931-
it("should create input without null values for dropdowns", () => {
934+
it("should create input with null dropdown for empty dropdowns", () => {
932935
// Arrange & Act
933936
const attribute = createDropdownAttribute(null);
934937
const prevAttribute = createDropdownAttribute("val-1");
@@ -939,7 +942,7 @@ describe("prepareAttributesInput", () => {
939942
});
940943

941944
// Assert
942-
expect(result).toEqual([{ id: ATTR_ID, values: [] }]);
945+
expect(result).toEqual([{ id: ATTR_ID, dropdown: null }]);
943946
});
944947
});
945948

src/attributes/utils/handlers.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,11 @@ export const prepareAttributesInput = ({
394394
}
395395

396396
if (inputType === AttributeInputTypeEnum.DROPDOWN) {
397+
const dropdownValue = attr.value[0];
398+
397399
attrInput.push({
398400
id: attr.id,
399-
values: attr.value.filter(value => value !== null),
401+
dropdown: dropdownValue ? { value: dropdownValue } : null,
400402
});
401403

402404
return attrInput;

src/components/Attributes/AttributeRow.tsx

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,18 @@ import {
1010
getMultiChoices,
1111
getMultiDisplayValue,
1212
getReferenceDisplayValue,
13-
getSingleChoices,
14-
getSingleDisplayValue,
1513
getTruncatedTextValue,
1614
} from "@dashboard/components/Attributes/utils";
1715
import FileUploadField from "@dashboard/components/FileUploadField";
1816
import RichTextEditor from "@dashboard/components/RichTextEditor";
1917
import SortableChipsField from "@dashboard/components/SortableChipsField";
2018
import { AttributeInputTypeEnum } from "@dashboard/graphql";
21-
import { Box, DynamicCombobox, Input, Select, Text } from "@saleor/macaw-ui-next";
19+
import { Box, Input, Select, Text } from "@saleor/macaw-ui-next";
2220
import { useIntl } from "react-intl";
2321

2422
import { Multiselect } from "../Combobox";
2523
import { DateTimeField } from "../DateTimeField";
24+
import { DropdownRow } from "./DropdownRow";
2625
import { SingleReferenceField } from "./SingleReferenceField";
2726
import { AttributeRowProps } from "./types";
2827

@@ -42,7 +41,7 @@ const AttributeRow = ({
4241
fetchMoreAttributeValues,
4342
onAttributeSelectBlur,
4443
richTextGetters,
45-
}: AttributeRowProps) => {
44+
}: AttributeRowProps): JSX.Element => {
4645
const intl = useIntl();
4746

4847
switch (attribute.data.inputType) {
@@ -96,36 +95,16 @@ const AttributeRow = ({
9695
);
9796
case AttributeInputTypeEnum.DROPDOWN:
9897
return (
99-
<BasicAttributeRow label={attribute.label}>
100-
<DynamicCombobox
101-
size="small"
102-
disabled={disabled}
103-
options={getSingleChoices(attributeValues)}
104-
value={
105-
attribute.value[0]
106-
? {
107-
value: attribute.value[0],
108-
label: getSingleDisplayValue(attribute, attributeValues),
109-
}
110-
: null
111-
}
112-
error={!!error}
113-
helperText={getErrorMessage(error, intl)}
114-
name={`attribute:${attribute.label}`}
115-
id={`attribute:${attribute.label}`}
116-
label=""
117-
onChange={option => onChange(attribute.id, option?.value ?? "")}
118-
onFocus={() => {
119-
fetchAttributeValues("", attribute.id);
120-
}}
121-
onBlur={onAttributeSelectBlur}
122-
onScrollEnd={() => {
123-
if (fetchMoreAttributeValues?.hasMore) {
124-
fetchMoreAttributeValues.onFetchMore();
125-
}
126-
}}
127-
/>
128-
</BasicAttributeRow>
98+
<DropdownRow
99+
attribute={attribute}
100+
attributeValues={attributeValues}
101+
disabled={disabled}
102+
error={error}
103+
onChange={onChange}
104+
fetchAttributeValues={fetchAttributeValues}
105+
fetchMoreAttributeValues={fetchMoreAttributeValues}
106+
onAttributeSelectBlur={onAttributeSelectBlur}
107+
/>
129108
);
130109
case AttributeInputTypeEnum.SWATCH:
131110
return (

0 commit comments

Comments
 (0)