Variant attribute values pagination (#1133)

* Implement attribute values pagination in variant pages

* Implement attribute values pagination in variant creator

* Update variant creator design bugs

* Fix deleting attribute value error

* Refactor attribute value handling in variant creator

* Update after review

* Create local pagination state for attribute values

* Fix autocomplete select field scrolling on fetch more

* Change onAttributeSelect to onAttributeFocus

* Update cypress test function with attribute values pagination
This commit is contained in:
Dawid Tarasiuk 2021-06-08 08:58:36 +02:00
parent 988b191690
commit d342bdb63b
54 changed files with 1922 additions and 1144 deletions

View file

@ -10,7 +10,13 @@ export function createAttribute(name, attributeValues = ["value"]) {
attribute{ attribute{
id id
name name
values{name} choices(first: 100){
edges{
node{
name
}
}
}
} }
attributeErrors{ attributeErrors{
field field

View file

@ -5643,6 +5643,10 @@
"context": "variant name", "context": "variant name",
"string": "Variant" "string": "Variant"
}, },
"src_dot_products_dot_components_dot_ProductVariantCreatorPage_dot_multipleValueLabel": {
"context": "attribute values",
"string": "Values"
},
"src_dot_products_dot_components_dot_ProductVariantDeleteDialog_dot_1583616500": { "src_dot_products_dot_components_dot_ProductVariantDeleteDialog_dot_1583616500": {
"context": "button", "context": "button",
"string": "Delete variant" "string": "Delete variant"

View file

@ -60,8 +60,7 @@ export type AttributeUrlDialog =
| "remove" | "remove"
| "remove-value" | "remove-value"
| "remove-values"; | "remove-values";
export type AttributeUrlQueryParams = Pagination & export type AttributeUrlQueryParams = BulkAction &
BulkAction &
Dialog<AttributeUrlDialog> & Dialog<AttributeUrlDialog> &
SingleAction; SingleAction;
export const attributePath = (id: string) => urlJoin(attributeSection, id); export const attributePath = (id: string) => urlJoin(attributeSection, id);

View file

@ -1,9 +1,9 @@
import useListSettings from "@saleor/hooks/useListSettings"; import useListSettings from "@saleor/hooks/useListSettings";
import useLocalPaginator, {
useLocalPaginationState
} from "@saleor/hooks/useLocalPaginator";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import usePaginator, {
createPaginationState
} from "@saleor/hooks/usePaginator";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews, ReorderEvent } from "@saleor/types"; import { ListViews, ReorderEvent } from "@saleor/types";
@ -47,7 +47,6 @@ interface AttributeDetailsProps {
const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => { const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
const navigate = useNavigator(); const navigate = useNavigator();
const paginate = usePaginator();
const notify = useNotifier(); const notify = useNotifier();
const intl = useIntl(); const intl = useIntl();
const [updateMetadata] = useMetadataUpdate({}); const [updateMetadata] = useMetadataUpdate({});
@ -62,20 +61,26 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
ListViews.ATTRIBUTE_VALUE_LIST ListViews.ATTRIBUTE_VALUE_LIST
); );
const [
valuesPaginationState,
setValuesPaginationState
] = useLocalPaginationState(settings?.rowNumber);
const { data, loading } = useAttributeDetailsQuery({ const { data, loading } = useAttributeDetailsQuery({
variables: { variables: {
id, id,
firstValues: settings?.rowNumber, firstValues: valuesPaginationState.first,
afterValues: params.after lastValues: valuesPaginationState.last,
afterValues: valuesPaginationState.after,
beforeValues: valuesPaginationState.before
}, },
skip: !settings skip: !settings
}); });
const paginationState = createPaginationState(settings?.rowNumber, params); const paginateValues = useLocalPaginator(setValuesPaginationState);
const { loadNextPage, loadPreviousPage, pageInfo } = paginate( const { loadNextPage, loadPreviousPage, pageInfo } = paginateValues(
data?.attribute?.choices?.pageInfo, data?.attribute?.choices?.pageInfo,
paginationState, valuesPaginationState
params
); );
const [attributeDelete, attributeDeleteOpts] = useAttributeDeleteMutation({ const [attributeDelete, attributeDeleteOpts] = useAttributeDeleteMutation({
@ -197,8 +202,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
id: data.attribute.choices.edges[oldIndex].node.id, id: data.attribute.choices.edges[oldIndex].node.id,
sortOrder: newIndex - oldIndex sortOrder: newIndex - oldIndex
}, },
firstValues: settings.rowNumber, firstValues: valuesPaginationState.first,
afterValues: params.after lastValues: valuesPaginationState.last,
afterValues: valuesPaginationState.after,
beforeValues: valuesPaginationState.before
} }
}); });
@ -288,8 +295,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
attributeValueDelete({ attributeValueDelete({
variables: { variables: {
id: params.id, id: params.id,
firstValues: settings.rowNumber, firstValues: valuesPaginationState.first,
afterValues: params.after lastValues: valuesPaginationState.last,
afterValues: valuesPaginationState.after,
beforeValues: valuesPaginationState.before
} }
}) })
} }
@ -308,8 +317,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
variables: { variables: {
id, id,
input, input,
firstValues: settings.rowNumber, firstValues: valuesPaginationState.first,
afterValues: params.after lastValues: valuesPaginationState.last,
afterValues: valuesPaginationState.after,
beforeValues: valuesPaginationState.before
} }
}) })
} }
@ -335,8 +346,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
value => params.id === value.node.id value => params.id === value.node.id
).node.id, ).node.id,
input, input,
firstValues: settings.rowNumber, firstValues: valuesPaginationState.first,
afterValues: params.after lastValues: valuesPaginationState.last,
afterValues: valuesPaginationState.after,
beforeValues: valuesPaginationState.before
} }
}) })
} }

View file

@ -57,7 +57,7 @@ export interface AttributeRowHandlers {
onReferencesReorder: FormsetChange<ReorderEvent>; onReferencesReorder: FormsetChange<ReorderEvent>;
fetchAttributeValues: (query: string) => void; fetchAttributeValues: (query: string) => void;
fetchMoreAttributeValues: FetchMoreProps; fetchMoreAttributeValues: FetchMoreProps;
onAttributeSelect: (id: string) => void; onAttributeFocus: (id: string) => void;
} }
interface AttributeRowProps extends AttributeRowHandlers { interface AttributeRowProps extends AttributeRowHandlers {
@ -82,7 +82,7 @@ const AttributeRow: React.FC<AttributeRowProps> = ({
onChange, onChange,
fetchAttributeValues, fetchAttributeValues,
fetchMoreAttributeValues, fetchMoreAttributeValues,
onAttributeSelect onAttributeFocus
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const classes = useStyles({}); const classes = useStyles({});
@ -149,7 +149,7 @@ const AttributeRow: React.FC<AttributeRowProps> = ({
allowCustomValues={true} allowCustomValues={true}
fetchChoices={fetchAttributeValues} fetchChoices={fetchAttributeValues}
{...fetchMoreAttributeValues} {...fetchMoreAttributeValues}
onClick={() => onAttributeSelect(attribute.id)} onFocus={() => onAttributeFocus(attribute.id)}
/> />
</BasicAttributeRow> </BasicAttributeRow>
); );
@ -211,7 +211,7 @@ const AttributeRow: React.FC<AttributeRowProps> = ({
allowCustomValues={true} allowCustomValues={true}
fetchChoices={fetchAttributeValues} fetchChoices={fetchAttributeValues}
{...fetchMoreAttributeValues} {...fetchMoreAttributeValues}
onClick={() => onAttributeSelect(attribute.id)} onFocus={() => onAttributeFocus(attribute.id)}
/> />
</BasicAttributeRow> </BasicAttributeRow>
); );

View file

@ -18,7 +18,7 @@ const props: AttributesProps = {
onReferencesAddClick: () => undefined, onReferencesAddClick: () => undefined,
onReferencesRemove: () => undefined, onReferencesRemove: () => undefined,
onReferencesReorder: () => undefined, onReferencesReorder: () => undefined,
onAttributeSelect: () => undefined, onAttributeFocus: () => undefined,
fetchAttributeValues: () => undefined, fetchAttributeValues: () => undefined,
fetchMoreAttributeValues: fetchMoreProps fetchMoreAttributeValues: fetchMoreProps
}; };

View file

@ -44,7 +44,7 @@ export interface AttributesProps extends AttributeRowHandlers {
ProductErrorWithAttributesFragment | PageErrorWithAttributesFragment ProductErrorWithAttributesFragment | PageErrorWithAttributesFragment
>; >;
title?: React.ReactNode; title?: React.ReactNode;
onAttributeSelect: (id: string) => void; onAttributeFocus: (id: string) => void;
} }
const useStyles = makeStyles( const useStyles = makeStyles(

View file

@ -85,7 +85,7 @@ export interface MultiAutocompleteSelectFieldProps
testId?: string; testId?: string;
fetchChoices?: (value: string) => void; fetchChoices?: (value: string) => void;
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
onClick?: () => void; onFocus?: () => void;
} }
const DebounceAutocomplete: React.ComponentType<DebounceProps< const DebounceAutocomplete: React.ComponentType<DebounceProps<
@ -110,7 +110,7 @@ const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFie
testId, testId,
fetchChoices, fetchChoices,
onChange, onChange,
onClick, onFocus,
onFetchMore, onFetchMore,
...rest ...rest
} = props; } = props;
@ -165,10 +165,10 @@ const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFie
</div> </div>
), ),
id: undefined, id: undefined,
onClick: (cb: () => void) => { onClick: toggleMenu,
toggleMenu(cb); onFocus: () => {
if (onClick) { if (onFocus) {
onClick(); onFocus();
} }
} }
}} }}

View file

@ -46,7 +46,7 @@ export interface SingleAutocompleteSelectFieldProps
InputProps?: InputProps; InputProps?: InputProps;
fetchChoices?: (value: string) => void; fetchChoices?: (value: string) => void;
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
onClick?: () => void; onFocus?: () => void;
FormHelperTextProps?: ExtendedFormHelperTextProps; FormHelperTextProps?: ExtendedFormHelperTextProps;
nakedInput?: boolean; nakedInput?: boolean;
} }
@ -76,7 +76,7 @@ const SingleAutocompleteSelectFieldComponent: React.FC<SingleAutocompleteSelectF
fetchChoices, fetchChoices,
onChange, onChange,
onFetchMore, onFetchMore,
onClick, onFocus,
FormHelperTextProps, FormHelperTextProps,
nakedInput = false, nakedInput = false,
...rest ...rest
@ -168,10 +168,10 @@ const SingleAutocompleteSelectFieldComponent: React.FC<SingleAutocompleteSelectF
error, error,
id: undefined, id: undefined,
onBlur: handleBlur, onBlur: handleBlur,
onClick: (cb: () => void) => { onClick: toggleMenu,
toggleMenu(cb); onFocus: () => {
if (onClick) { if (onFocus) {
onClick(); onFocus();
} }
} }
}; };

View file

@ -151,7 +151,8 @@ const SingleAutocompleteSelectFieldContent: React.FC<SingleAutocompleteSelectFie
const anchor = React.useRef<HTMLDivElement>(); const anchor = React.useRef<HTMLDivElement>();
const scrollPosition = useElementScroll(anchor); const scrollPosition = useElementScroll(anchor);
const [calledForMore, setCalledForMore] = React.useState(false); const [calledForMore, setCalledForMore] = React.useState(false);
const [slice, setSlice] = React.useState(sliceSize); const [slice, setSlice] = React.useState(onFetchMore ? 10000 : sliceSize);
const [initialized, setInitialized] = React.useState(false);
const scrolledToBottom = isScrolledToBottom(anchor, scrollPosition, offset); const scrolledToBottom = isScrolledToBottom(anchor, scrollPosition, offset);
@ -159,20 +160,27 @@ const SingleAutocompleteSelectFieldContent: React.FC<SingleAutocompleteSelectFie
if (!calledForMore && onFetchMore && scrolledToBottom) { if (!calledForMore && onFetchMore && scrolledToBottom) {
onFetchMore(); onFetchMore();
setCalledForMore(true); setCalledForMore(true);
} else if (scrolledToBottom) { } else if (scrolledToBottom && !onFetchMore) {
setSlice(slice => slice + sliceSize); setSlice(slice => slice + sliceSize);
} }
}, [scrolledToBottom]); }, [scrolledToBottom]);
React.useEffect(() => { React.useEffect(() => {
if (!onFetchMore) {
setSlice(sliceSize); setSlice(sliceSize);
if (anchor.current?.scrollTo) { }
if (anchor.current?.scrollTo && !initialized) {
anchor.current.scrollTo({ anchor.current.scrollTo({
top: 0 top: 0
}); });
setInitialized(true);
} }
}, [choices?.length]); }, [choices?.length]);
React.useEffect(() => {
setInitialized(false);
}, [inputValue]);
React.useEffect(() => { React.useEffect(() => {
if (calledForMore && !loading) { if (calledForMore && !loading) {
setCalledForMore(false); setCalledForMore(false);
@ -183,6 +191,8 @@ const SingleAutocompleteSelectFieldContent: React.FC<SingleAutocompleteSelectFie
item: "" item: ""
}); });
const choicesToDisplay = choices.slice(0, slice);
return ( return (
<Paper className={classes.root}> <Paper className={classes.root}>
<div <div
@ -244,7 +254,7 @@ const SingleAutocompleteSelectFieldContent: React.FC<SingleAutocompleteSelectFie
{choices.length > 0 && (!!add || displayCustomValue) && ( {choices.length > 0 && (!!add || displayCustomValue) && (
<Hr className={classes.hr} /> <Hr className={classes.hr} />
)} )}
{choices.slice(0, slice).map((suggestion, index) => { {choicesToDisplay.map((suggestion, index) => {
const choiceIndex = getChoiceIndex( const choiceIndex = getChoiceIndex(
index, index,
emptyOption, emptyOption,

View file

@ -246,6 +246,7 @@ export const productFragmentDetails = gql`
`; `;
export const variantAttributeFragment = gql` export const variantAttributeFragment = gql`
${attributeValueListFragment}
fragment VariantAttributeFragment on Attribute { fragment VariantAttributeFragment on Attribute {
id id
name name
@ -254,14 +255,14 @@ export const variantAttributeFragment = gql`
entityType entityType
valueRequired valueRequired
unit unit
# values( choices(
# first: $firstValues first: $firstValues
# after: $afterValues after: $afterValues
# last: $lastValues last: $lastValues
# before: $beforeValues before: $beforeValues
# ) { ) {
# ...AttributeValueListFragment ...AttributeValueListFragment
# } }
} }
`; `;

View file

@ -21,7 +21,7 @@ export interface ProductVariant_privateMetadata {
value: string; value: string;
} }
export interface ProductVariant_selectionAttributes_attribute_values_pageInfo { export interface ProductVariant_selectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -29,32 +29,32 @@ export interface ProductVariant_selectionAttributes_attribute_values_pageInfo {
startCursor: string | null; startCursor: string | null;
} }
export interface ProductVariant_selectionAttributes_attribute_values_edges_node_file { export interface ProductVariant_selectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface ProductVariant_selectionAttributes_attribute_values_edges_node { export interface ProductVariant_selectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: ProductVariant_selectionAttributes_attribute_values_edges_node_file | null; file: ProductVariant_selectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface ProductVariant_selectionAttributes_attribute_values_edges { export interface ProductVariant_selectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: ProductVariant_selectionAttributes_attribute_values_edges_node; node: ProductVariant_selectionAttributes_attribute_choices_edges_node;
} }
export interface ProductVariant_selectionAttributes_attribute_values { export interface ProductVariant_selectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: ProductVariant_selectionAttributes_attribute_values_pageInfo; pageInfo: ProductVariant_selectionAttributes_attribute_choices_pageInfo;
edges: ProductVariant_selectionAttributes_attribute_values_edges[]; edges: ProductVariant_selectionAttributes_attribute_choices_edges[];
} }
export interface ProductVariant_selectionAttributes_attribute { export interface ProductVariant_selectionAttributes_attribute {
@ -66,7 +66,7 @@ export interface ProductVariant_selectionAttributes_attribute {
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: ProductVariant_selectionAttributes_attribute_values | null; choices: ProductVariant_selectionAttributes_attribute_choices | null;
} }
export interface ProductVariant_selectionAttributes_values_file { export interface ProductVariant_selectionAttributes_values_file {
@ -91,7 +91,7 @@ export interface ProductVariant_selectionAttributes {
values: (ProductVariant_selectionAttributes_values | null)[]; values: (ProductVariant_selectionAttributes_values | null)[];
} }
export interface ProductVariant_nonSelectionAttributes_attribute_values_pageInfo { export interface ProductVariant_nonSelectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -99,32 +99,32 @@ export interface ProductVariant_nonSelectionAttributes_attribute_values_pageInfo
startCursor: string | null; startCursor: string | null;
} }
export interface ProductVariant_nonSelectionAttributes_attribute_values_edges_node_file { export interface ProductVariant_nonSelectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface ProductVariant_nonSelectionAttributes_attribute_values_edges_node { export interface ProductVariant_nonSelectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: ProductVariant_nonSelectionAttributes_attribute_values_edges_node_file | null; file: ProductVariant_nonSelectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface ProductVariant_nonSelectionAttributes_attribute_values_edges { export interface ProductVariant_nonSelectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: ProductVariant_nonSelectionAttributes_attribute_values_edges_node; node: ProductVariant_nonSelectionAttributes_attribute_choices_edges_node;
} }
export interface ProductVariant_nonSelectionAttributes_attribute_values { export interface ProductVariant_nonSelectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: ProductVariant_nonSelectionAttributes_attribute_values_pageInfo; pageInfo: ProductVariant_nonSelectionAttributes_attribute_choices_pageInfo;
edges: ProductVariant_nonSelectionAttributes_attribute_values_edges[]; edges: ProductVariant_nonSelectionAttributes_attribute_choices_edges[];
} }
export interface ProductVariant_nonSelectionAttributes_attribute { export interface ProductVariant_nonSelectionAttributes_attribute {
@ -136,7 +136,7 @@ export interface ProductVariant_nonSelectionAttributes_attribute {
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: ProductVariant_nonSelectionAttributes_attribute_values | null; choices: ProductVariant_nonSelectionAttributes_attribute_choices | null;
} }
export interface ProductVariant_nonSelectionAttributes_values_file { export interface ProductVariant_nonSelectionAttributes_values_file {

View file

@ -9,7 +9,7 @@ import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum }
// GraphQL fragment: SelectedVariantAttributeFragment // GraphQL fragment: SelectedVariantAttributeFragment
// ==================================================== // ====================================================
export interface SelectedVariantAttributeFragment_attribute_values_pageInfo { export interface SelectedVariantAttributeFragment_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -17,32 +17,32 @@ export interface SelectedVariantAttributeFragment_attribute_values_pageInfo {
startCursor: string | null; startCursor: string | null;
} }
export interface SelectedVariantAttributeFragment_attribute_values_edges_node_file { export interface SelectedVariantAttributeFragment_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface SelectedVariantAttributeFragment_attribute_values_edges_node { export interface SelectedVariantAttributeFragment_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: SelectedVariantAttributeFragment_attribute_values_edges_node_file | null; file: SelectedVariantAttributeFragment_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface SelectedVariantAttributeFragment_attribute_values_edges { export interface SelectedVariantAttributeFragment_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: SelectedVariantAttributeFragment_attribute_values_edges_node; node: SelectedVariantAttributeFragment_attribute_choices_edges_node;
} }
export interface SelectedVariantAttributeFragment_attribute_values { export interface SelectedVariantAttributeFragment_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: SelectedVariantAttributeFragment_attribute_values_pageInfo; pageInfo: SelectedVariantAttributeFragment_attribute_choices_pageInfo;
edges: SelectedVariantAttributeFragment_attribute_values_edges[]; edges: SelectedVariantAttributeFragment_attribute_choices_edges[];
} }
export interface SelectedVariantAttributeFragment_attribute { export interface SelectedVariantAttributeFragment_attribute {
@ -54,7 +54,7 @@ export interface SelectedVariantAttributeFragment_attribute {
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: SelectedVariantAttributeFragment_attribute_values | null; choices: SelectedVariantAttributeFragment_attribute_choices | null;
} }
export interface SelectedVariantAttributeFragment_values_file { export interface SelectedVariantAttributeFragment_values_file {

View file

@ -9,7 +9,7 @@ import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum }
// GraphQL fragment: VariantAttributeFragment // GraphQL fragment: VariantAttributeFragment
// ==================================================== // ====================================================
export interface VariantAttributeFragment_values_pageInfo { export interface VariantAttributeFragment_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -17,32 +17,32 @@ export interface VariantAttributeFragment_values_pageInfo {
startCursor: string | null; startCursor: string | null;
} }
export interface VariantAttributeFragment_values_edges_node_file { export interface VariantAttributeFragment_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface VariantAttributeFragment_values_edges_node { export interface VariantAttributeFragment_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: VariantAttributeFragment_values_edges_node_file | null; file: VariantAttributeFragment_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface VariantAttributeFragment_values_edges { export interface VariantAttributeFragment_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: VariantAttributeFragment_values_edges_node; node: VariantAttributeFragment_choices_edges_node;
} }
export interface VariantAttributeFragment_values { export interface VariantAttributeFragment_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: VariantAttributeFragment_values_pageInfo; pageInfo: VariantAttributeFragment_choices_pageInfo;
edges: VariantAttributeFragment_values_edges[]; edges: VariantAttributeFragment_choices_edges[];
} }
export interface VariantAttributeFragment { export interface VariantAttributeFragment {
@ -54,5 +54,5 @@ export interface VariantAttributeFragment {
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: VariantAttributeFragment_values | null; choices: VariantAttributeFragment_choices | null;
} }

View file

@ -0,0 +1,79 @@
import { useState } from "react";
export interface PageInfo {
endCursor: string;
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor: string;
}
export interface PaginationState {
after?: string;
before?: string;
first?: number;
last?: number;
}
export function useLocalPaginationState(
paginateBy: number
): [PaginationState, (paginationState: PaginationState) => void] {
const [state, setState] = useState<PaginationState>({
first: paginateBy
});
const setPaginationState = (paginationState: PaginationState) => {
if (paginationState.after) {
setState({
after: paginationState.after,
first: paginateBy
});
} else if (paginationState.before) {
setState({
before: paginationState.before,
last: paginateBy
});
} else {
setState({
first: paginateBy
});
}
};
return [state, setPaginationState];
}
function useLocalPaginator(
setPaginationState: (paginationState: PaginationState) => void
) {
function paginate(pageInfo: PageInfo, paginationState: PaginationState) {
const loadNextPage = () =>
setPaginationState({
...paginationState,
after: pageInfo.endCursor,
before: undefined
});
const loadPreviousPage = () =>
setPaginationState({
...paginationState,
after: undefined,
before: pageInfo.startCursor
});
const newPageInfo = pageInfo
? {
...pageInfo,
hasNextPage: !!paginationState.before || pageInfo.hasNextPage,
hasPreviousPage: !!paginationState.after || pageInfo.hasPreviousPage
}
: undefined;
return {
loadNextPage,
loadPreviousPage,
pageInfo: newPageInfo
};
}
return paginate;
}
export default useLocalPaginator;

View file

@ -167,7 +167,7 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
onReferencesReorder={handlers.reorderAttributeValue} onReferencesReorder={handlers.reorderAttributeValue}
fetchAttributeValues={() => undefined} fetchAttributeValues={() => undefined}
fetchMoreAttributeValues={undefined} fetchMoreAttributeValues={undefined}
onAttributeSelect={() => undefined} onAttributeFocus={() => undefined}
/> />
)} )}
<CardSpacer /> <CardSpacer />

View file

@ -75,7 +75,7 @@ interface ProductCreatePageProps {
fetchCollections: (data: string) => void; fetchCollections: (data: string) => void;
fetchProductTypes: (data: string) => void; fetchProductTypes: (data: string) => void;
fetchAttributeValues: (query: string) => void; fetchAttributeValues: (query: string) => void;
onAttributeSelect: (id: string) => void; onAttributeFocus: (id: string) => void;
onWarehouseConfigure: () => void; onWarehouseConfigure: () => void;
openChannelsModal: () => void; openChannelsModal: () => void;
onChannelsChange: (data: ChannelData[]) => void; onChannelsChange: (data: ChannelData[]) => void;
@ -131,7 +131,7 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
fetchMoreAttributeValues, fetchMoreAttributeValues,
onCloseDialog, onCloseDialog,
onSelectProductType, onSelectProductType,
onAttributeSelect onAttributeFocus
}: ProductCreatePageProps) => { }: ProductCreatePageProps) => {
const intl = useIntl(); const intl = useIntl();
@ -243,7 +243,7 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
onReferencesReorder={handlers.reorderAttributeValue} onReferencesReorder={handlers.reorderAttributeValue}
fetchAttributeValues={fetchAttributeValues} fetchAttributeValues={fetchAttributeValues}
fetchMoreAttributeValues={fetchMoreAttributeValues} fetchMoreAttributeValues={fetchMoreAttributeValues}
onAttributeSelect={onAttributeSelect} onAttributeFocus={onAttributeFocus}
/> />
)} )}
<CardSpacer /> <CardSpacer />

View file

@ -60,7 +60,7 @@ const props: ProductUpdatePageProps = {
onVariantsAdd: () => undefined, onVariantsAdd: () => undefined,
onWarehouseConfigure: () => undefined, onWarehouseConfigure: () => undefined,
openChannelsModal: () => undefined, openChannelsModal: () => undefined,
onAttributeSelect: () => undefined, onAttributeFocus: () => undefined,
placeholderImage, placeholderImage,
product, product,
referencePages: [], referencePages: [],

View file

@ -102,7 +102,7 @@ export interface ProductUpdatePageProps extends ListActions, ChannelProps {
fetchReferencePages?: (data: string) => void; fetchReferencePages?: (data: string) => void;
fetchReferenceProducts?: (data: string) => void; fetchReferenceProducts?: (data: string) => void;
fetchAttributeValues: (query: string) => void; fetchAttributeValues: (query: string) => void;
onAttributeSelect: (id: string) => void; onAttributeFocus: (id: string) => void;
onAssignReferencesClick: (attribute: AttributeInput) => void; onAssignReferencesClick: (attribute: AttributeInput) => void;
onCloseDialog: () => void; onCloseDialog: () => void;
onVariantsAdd: () => void; onVariantsAdd: () => void;
@ -196,7 +196,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
onCloseDialog, onCloseDialog,
channelsWithVariantsData, channelsWithVariantsData,
onChannelsChange, onChannelsChange,
onAttributeSelect onAttributeFocus
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
@ -319,7 +319,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
onReferencesReorder={handlers.reorderAttributeValue} onReferencesReorder={handlers.reorderAttributeValue}
fetchAttributeValues={fetchAttributeValues} fetchAttributeValues={fetchAttributeValues}
fetchMoreAttributeValues={fetchMoreAttributeValues} fetchMoreAttributeValues={fetchMoreAttributeValues}
onAttributeSelect={onAttributeSelect} onAttributeFocus={onAttributeFocus}
/> />
)} )}
<CardSpacer /> <CardSpacer />

View file

@ -8,8 +8,8 @@ import SingleAutocompleteSelectField, {
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment"; import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment";
import { import {
ProductVariant_nonSelectionAttributes_attribute_values_edges, ProductVariant_nonSelectionAttributes_attribute_choices_edges,
ProductVariant_selectionAttributes_attribute_values_edges ProductVariant_selectionAttributes_attribute_choices_edges
} from "@saleor/fragments/types/ProductVariant"; } from "@saleor/fragments/types/ProductVariant";
import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset"; import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
@ -19,8 +19,8 @@ import { useIntl } from "react-intl";
export interface VariantAttributeInputData { export interface VariantAttributeInputData {
values: Array< values: Array<
| ProductVariant_selectionAttributes_attribute_values_edges | ProductVariant_selectionAttributes_attribute_choices_edges
| ProductVariant_nonSelectionAttributes_attribute_values_edges | ProductVariant_nonSelectionAttributes_attribute_choices_edges
>; >;
} }
export type VariantAttributeInput = FormsetAtomicData< export type VariantAttributeInput = FormsetAtomicData<

View file

@ -17,6 +17,7 @@ import Metadata from "@saleor/components/Metadata";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar"; import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment"; import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment";
import { SearchAttributeValues_attribute_choices_edges_node } from "@saleor/searches/types/SearchAttributeValues";
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts";
import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses";
@ -69,6 +70,7 @@ interface ProductVariantCreatePageProps {
weightUnit: string; weightUnit: string;
referencePages?: SearchPages_search_edges_node[]; referencePages?: SearchPages_search_edges_node[];
referenceProducts?: SearchProducts_search_edges_node[]; referenceProducts?: SearchProducts_search_edges_node[];
attributeValues: SearchAttributeValues_attribute_choices_edges_node[];
onBack: () => void; onBack: () => void;
onSubmit: (data: ProductVariantCreateData) => void; onSubmit: (data: ProductVariantCreateData) => void;
onVariantClick: (variantId: string) => void; onVariantClick: (variantId: string) => void;
@ -76,10 +78,13 @@ interface ProductVariantCreatePageProps {
onWarehouseConfigure: () => void; onWarehouseConfigure: () => void;
assignReferencesAttributeId?: string; assignReferencesAttributeId?: string;
onAssignReferencesClick: (attribute: AttributeInput) => void; onAssignReferencesClick: (attribute: AttributeInput) => void;
onAttributeFocus: (id: string) => void;
fetchReferencePages?: (data: string) => void; fetchReferencePages?: (data: string) => void;
fetchReferenceProducts?: (data: string) => void; fetchReferenceProducts?: (data: string) => void;
fetchAttributeValues: (query: string) => void;
fetchMoreReferencePages?: FetchMoreProps; fetchMoreReferencePages?: FetchMoreProps;
fetchMoreReferenceProducts?: FetchMoreProps; fetchMoreReferenceProducts?: FetchMoreProps;
fetchMoreAttributeValues?: FetchMoreProps;
onCloseDialog: () => void; onCloseDialog: () => void;
} }
@ -94,17 +99,21 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
weightUnit, weightUnit,
referencePages = [], referencePages = [],
referenceProducts = [], referenceProducts = [],
attributeValues,
onBack, onBack,
onSubmit, onSubmit,
onVariantClick, onVariantClick,
onVariantReorder, onVariantReorder,
onWarehouseConfigure, onWarehouseConfigure,
onAttributeFocus,
assignReferencesAttributeId, assignReferencesAttributeId,
onAssignReferencesClick, onAssignReferencesClick,
fetchReferencePages, fetchReferencePages,
fetchReferenceProducts, fetchReferenceProducts,
fetchAttributeValues,
fetchMoreReferencePages, fetchMoreReferencePages,
fetchMoreReferenceProducts, fetchMoreReferenceProducts,
fetchMoreAttributeValues,
onCloseDialog onCloseDialog
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
@ -173,7 +182,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
attribute.data.variantAttributeScope === attribute.data.variantAttributeScope ===
VariantAttributeScope.NOT_VARIANT_SELECTION VariantAttributeScope.NOT_VARIANT_SELECTION
)} )}
attributeValues={[]} attributeValues={attributeValues}
loading={disabled} loading={disabled}
disabled={disabled} disabled={disabled}
errors={errors} errors={errors}
@ -183,9 +192,9 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
onReferencesRemove={handlers.selectAttributeReference} onReferencesRemove={handlers.selectAttributeReference}
onReferencesAddClick={onAssignReferencesClick} onReferencesAddClick={onAssignReferencesClick}
onReferencesReorder={handlers.reorderAttributeValue} onReferencesReorder={handlers.reorderAttributeValue}
fetchAttributeValues={() => undefined} fetchAttributeValues={fetchAttributeValues}
fetchMoreAttributeValues={undefined} fetchMoreAttributeValues={fetchMoreAttributeValues}
onAttributeSelect={() => undefined} onAttributeFocus={onAttributeFocus}
/> />
<CardSpacer /> <CardSpacer />
<Attributes <Attributes
@ -195,7 +204,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
attribute.data.variantAttributeScope === attribute.data.variantAttributeScope ===
VariantAttributeScope.VARIANT_SELECTION VariantAttributeScope.VARIANT_SELECTION
)} )}
attributeValues={[]} attributeValues={attributeValues}
loading={disabled} loading={disabled}
disabled={disabled} disabled={disabled}
errors={errors} errors={errors}
@ -205,9 +214,9 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
onReferencesRemove={handlers.selectAttributeReference} onReferencesRemove={handlers.selectAttributeReference}
onReferencesAddClick={onAssignReferencesClick} onReferencesAddClick={onAssignReferencesClick}
onReferencesReorder={handlers.reorderAttributeValue} onReferencesReorder={handlers.reorderAttributeValue}
fetchAttributeValues={() => undefined} fetchAttributeValues={fetchAttributeValues}
fetchMoreAttributeValues={undefined} fetchMoreAttributeValues={fetchMoreAttributeValues}
onAttributeSelect={() => undefined} onAttributeFocus={onAttributeFocus}
/> />
<CardSpacer /> <CardSpacer />
<ProductShipping <ProductShipping

View file

@ -1,7 +1,7 @@
import { attributes } from "@saleor/attributes/fixtures"; import { attributes } from "@saleor/attributes/fixtures";
import { productChannels } from "@saleor/channels/fixtures"; import { productChannels } from "@saleor/channels/fixtures";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import { limitsReached } from "@saleor/fixtures"; import { fetchMoreProps, limitsReached } from "@saleor/fixtures";
import { ProductVariantBulkCreate_productVariantBulkCreate_errors } from "@saleor/products/types/ProductVariantBulkCreate"; import { ProductVariantBulkCreate_productVariantBulkCreate_errors } from "@saleor/products/types/ProductVariantBulkCreate";
import { ProductErrorCode } from "@saleor/types/globalTypes"; import { ProductErrorCode } from "@saleor/types/globalTypes";
import { warehouseList } from "@saleor/warehouses/fixtures"; import { warehouseList } from "@saleor/warehouses/fixtures";
@ -60,7 +60,10 @@ const stock: Stock = {
const dataAttributes = selectedAttributes.map(attribute => ({ const dataAttributes = selectedAttributes.map(attribute => ({
id: attribute.id, id: attribute.id,
values: attribute.choices.edges values: attribute.choices.edges
.map(value => value.node.slug) .map(value => ({
slug: value.node.slug,
value: value.node
}))
.filter((_, valueIndex) => valueIndex % 2 !== 1) .filter((_, valueIndex) => valueIndex % 2 !== 1)
})); }));
@ -89,6 +92,9 @@ const data: ProductVariantCreateFormData = {
}; };
const props: ProductVariantCreatorContentProps = { const props: ProductVariantCreatorContentProps = {
attributes: [0, 1, 4, 6].map(index => attributes[index]), attributes: [0, 1, 4, 6].map(index => attributes[index]),
attributeValues: [],
fetchAttributeValues: () => undefined,
fetchMoreAttributeValues: fetchMoreProps,
channelListings: productChannels.map(listing => ({ channelListings: productChannels.map(listing => ({
currency: listing.pricing?.priceRange?.start?.net.currency, currency: listing.pricing?.priceRange?.start?.net.currency,
id: listing.channel.id, id: listing.channel.id,
@ -103,7 +109,8 @@ const props: ProductVariantCreatorContentProps = {
errors: [], errors: [],
variantsLeft: 6, variantsLeft: 6,
step: ProductVariantCreatorStep.values, step: ProductVariantCreatorStep.values,
warehouses: warehouseList warehouses: warehouseList,
onAttributeFocus: () => undefined
}; };
storiesOf("Views / Products / Create multiple variants", module) storiesOf("Views / Products / Create multiple variants", module)

View file

@ -2,6 +2,8 @@ import { ChannelPriceData } from "@saleor/channels/utils";
import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment";
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails"; import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
import { ProductVariantBulkCreate_productVariantBulkCreate_errors } from "@saleor/products/types/ProductVariantBulkCreate"; import { ProductVariantBulkCreate_productVariantBulkCreate_errors } from "@saleor/products/types/ProductVariantBulkCreate";
import { SearchAttributeValues_attribute_choices_edges_node } from "@saleor/searches/types/SearchAttributeValues";
import { FetchMoreProps } from "@saleor/types";
import { isSelected } from "@saleor/utils/lists"; import { isSelected } from "@saleor/utils/lists";
import React from "react"; import React from "react";
@ -17,6 +19,7 @@ import { ProductVariantCreatorStep } from "./types";
export interface ProductVariantCreatorContentProps { export interface ProductVariantCreatorContentProps {
attributes: ProductDetails_product_productType_variantAttributes[]; attributes: ProductDetails_product_productType_variantAttributes[];
attributeValues: SearchAttributeValues_attribute_choices_edges_node[];
channelListings: ChannelPriceData[]; channelListings: ChannelPriceData[];
data: ProductVariantCreateFormData; data: ProductVariantCreateFormData;
dispatchFormDataAction: React.Dispatch<ProductVariantCreateReducerAction>; dispatchFormDataAction: React.Dispatch<ProductVariantCreateReducerAction>;
@ -24,17 +27,24 @@ export interface ProductVariantCreatorContentProps {
step: ProductVariantCreatorStep; step: ProductVariantCreatorStep;
variantsLeft: number | null; variantsLeft: number | null;
warehouses: WarehouseFragment[]; warehouses: WarehouseFragment[];
fetchAttributeValues: (query: string) => void;
fetchMoreAttributeValues?: FetchMoreProps;
onAttributeFocus: (id: string) => void;
} }
const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps> = ({ const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps> = ({
attributes, attributes,
attributeValues,
fetchAttributeValues,
fetchMoreAttributeValues,
channelListings, channelListings,
data, data,
dispatchFormDataAction, dispatchFormDataAction,
errors, errors,
step, step,
variantsLeft, variantsLeft,
warehouses warehouses,
onAttributeFocus
}) => { }) => {
const selectedAttributes = attributes.filter(attribute => const selectedAttributes = attributes.filter(attribute =>
isSelected( isSelected(
@ -49,17 +59,21 @@ const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps>
{step === ProductVariantCreatorStep.values && ( {step === ProductVariantCreatorStep.values && (
<ProductVariantCreateValues <ProductVariantCreateValues
attributes={selectedAttributes} attributes={selectedAttributes}
attributeValues={attributeValues}
fetchAttributeValues={fetchAttributeValues}
fetchMoreAttributeValues={fetchMoreAttributeValues}
data={data} data={data}
variantsLeft={variantsLeft} variantsLeft={variantsLeft}
onValueClick={(attributeId, valueId) => onValueClick={(attributeId, value) =>
dispatchFormDataAction({ dispatchFormDataAction({
selectValue: { selectValue: {
attributeId, attributeId,
valueId value
}, },
type: ProductVariantCreateReducerActionType.selectValue type: ProductVariantCreateReducerActionType.selectValue
}) })
} }
onAttributeFocus={onAttributeFocus}
/> />
)} )}
{step === ProductVariantCreatorStep.prices && ( {step === ProductVariantCreatorStep.prices && (

View file

@ -1,4 +1,5 @@
import { Button, Typography } from "@material-ui/core"; import { Button, Typography } from "@material-ui/core";
import { drawerWidthExpanded } from "@saleor/components/AppLayout/consts";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Hr from "@saleor/components/Hr"; import Hr from "@saleor/components/Hr";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
@ -28,8 +29,13 @@ const useStyles = makeStyles(
}, },
content: { content: {
overflowX: "visible", overflowX: "visible",
overflowY: "hidden", [theme.breakpoints.up("md")]: {
width: 800 position: "absolute",
width: `calc(100vw - ${drawerWidthExpanded}px + ${theme.spacing(6)}px)`,
maxWidth: `calc(${theme.breakpoints.width("lg")}px - ${theme.spacing(
6
)}px)`
}
}, },
description: { description: {
marginTop: theme.spacing() marginTop: theme.spacing()
@ -185,7 +191,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = props
React.useEffect(reloadForm, [attributes.length, warehouses.length]); React.useEffect(reloadForm, [attributes.length, warehouses.length]);
const variantsLeft = limits.allowedUsage.productVariants const variantsLeft = limits?.allowedUsage.productVariants
? limits.allowedUsage.productVariants - limits.currentUsage.productVariants ? limits.allowedUsage.productVariants - limits.currentUsage.productVariants
: null; : null;
@ -237,6 +243,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = props
)} )}
</PageHeader> </PageHeader>
<Hr className={classes.hr} /> <Hr className={classes.hr} />
<div className={classes.content}>
<ProductVariantCreatorContent <ProductVariantCreatorContent
{...contentProps} {...contentProps}
attributes={attributes} attributes={attributes}
@ -248,6 +255,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = props
step={step} step={step}
warehouses={warehouses} warehouses={warehouses}
/> />
</div>
</Container> </Container>
); );
}; };

View file

@ -20,7 +20,7 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { ProductDetails_product_productType_variantAttributes } from "../../types/ProductDetails"; import { ProductDetails_product_productType_variantAttributes } from "../../types/ProductDetails";
import { ChannelPrice, ProductVariantCreateFormData } from "./form"; import { Attribute, ChannelPrice, ProductVariantCreateFormData } from "./form";
export interface ProductVariantCreatorSummaryProps { export interface ProductVariantCreatorSummaryProps {
attributes: ProductDetails_product_productType_variantAttributes[]; attributes: ProductDetails_product_productType_variantAttributes[];
@ -113,18 +113,18 @@ const useStyles = makeStyles<ProductVariantCreatorSummaryProps, ClassKey>(
function getVariantName( function getVariantName(
variant: ProductVariantBulkCreateInput, variant: ProductVariantBulkCreateInput,
attributes: ProductDetails_product_productType_variantAttributes[] attributes: Attribute[]
): string[] { ): string[] {
return attributes.reduce( return attributes.reduce(
(acc, attribute) => [ (acc, attribute) => [
...acc, ...acc,
attribute.choices.edges.find( attribute.values?.find(
value => value =>
value.node.slug === value?.slug ===
variant.attributes.find( variant.attributes.find(
variantAttribute => variantAttribute.id === attribute.id variantAttribute => variantAttribute.id === attribute.id
).values[0] ).values[0]
).node.name )?.value?.name
], ],
[] []
); );
@ -132,7 +132,6 @@ function getVariantName(
const ProductVariantCreatorSummary: React.FC<ProductVariantCreatorSummaryProps> = props => { const ProductVariantCreatorSummary: React.FC<ProductVariantCreatorSummaryProps> = props => {
const { const {
attributes,
channelListings, channelListings,
data, data,
errors, errors,
@ -220,7 +219,7 @@ const ProductVariantCreatorSummary: React.FC<ProductVariantCreatorSummaryProps>
.join(":")} .join(":")}
> >
<div className={classNames(classes.col, classes.colName)}> <div className={classNames(classes.col, classes.colName)}>
{getVariantName(variant, attributes).map( {getVariantName(variant, data.attributes).map(
(value, valueIndex) => ( (value, valueIndex) => (
<span <span
className={classes.attributeValue} className={classes.attributeValue}

View file

@ -1,17 +1,30 @@
import { Card, CardContent } from "@material-ui/core"; import { Card, CardContent } from "@material-ui/core";
import Alert from "@saleor/components/Alert/Alert"; import Alert from "@saleor/components/Alert/Alert";
import { getMultiChoices } from "@saleor/components/Attributes/utils";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; import MultiAutocompleteSelectField from "@saleor/components/MultiAutocompleteSelectField";
import Debounce from "@saleor/components/Debounce";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { AttributeValueFragment } from "@saleor/fragments/types/AttributeValueFragment";
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails"; import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
import { makeStyles } from "@saleor/theme"; import { SearchAttributeValues_attribute_choices_edges_node } from "@saleor/searches/types/SearchAttributeValues";
import { isSelected } from "@saleor/utils/lists"; import { FetchMoreProps } from "@saleor/types";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { defineMessages, FormattedMessage, useIntl } from "react-intl";
import { ProductVariantCreateFormData } from "./form"; import {
Attribute,
AttributeValue,
ProductVariantCreateFormData
} from "./form";
const messages = defineMessages({
multipleValueLabel: {
defaultMessage: "Values",
description: "attribute values"
}
});
export function getVariantsNumber(data: ProductVariantCreateFormData): number { export function getVariantsNumber(data: ProductVariantCreateFormData): number {
return data.attributes.reduce( return data.attributes.reduce(
@ -20,30 +33,64 @@ export function getVariantsNumber(data: ProductVariantCreateFormData): number {
); );
} }
export function getMultiValues(
attributes: Attribute[],
attribute: ProductDetails_product_productType_variantAttributes
) {
return attributes
.find(getById(attribute.id))
?.values?.map(value => value.slug);
}
export function getMultiDisplayValues(
attributes: Attribute[],
attribute: ProductDetails_product_productType_variantAttributes
) {
return attributes.find(getById(attribute.id))?.values.map(value => ({
label: value.value?.name,
value: value.slug
}));
}
export interface ProductVariantCreatorValuesProps { export interface ProductVariantCreatorValuesProps {
attributes: ProductDetails_product_productType_variantAttributes[]; attributes: ProductDetails_product_productType_variantAttributes[];
attributeValues: SearchAttributeValues_attribute_choices_edges_node[];
fetchAttributeValues: (query: string) => void;
fetchMoreAttributeValues?: FetchMoreProps;
data: ProductVariantCreateFormData; data: ProductVariantCreateFormData;
variantsLeft: number | null; variantsLeft: number | null;
onValueClick: (attributeId: string, valueId: string) => void; onValueClick: (
attributeId: string,
value: AttributeValue<AttributeValueFragment>
) => void;
onAttributeFocus: (id: string) => void;
} }
const useStyles = makeStyles(
theme => ({
valueContainer: {
display: "grid",
gridColumnGap: theme.spacing(3),
gridTemplateColumns: "repeat(5, 1fr)"
}
}),
{ name: "ProductVariantCreatorValues" }
);
const ProductVariantCreatorValues: React.FC<ProductVariantCreatorValuesProps> = props => { const ProductVariantCreatorValues: React.FC<ProductVariantCreatorValuesProps> = props => {
const { attributes, data, variantsLeft, onValueClick } = props; const {
const classes = useStyles(props); attributes,
attributeValues,
fetchAttributeValues,
fetchMoreAttributeValues,
data,
variantsLeft,
onValueClick,
onAttributeFocus
} = props;
const intl = useIntl(); const intl = useIntl();
const variantsNumber = getVariantsNumber(data); const variantsNumber = getVariantsNumber(data);
const handleValueClick = (attributeId: string, valueSlug: string) => {
const dataAttribute = data.attributes.find(getById(attributeId));
onValueClick(attributeId, {
slug: valueSlug,
value:
dataAttribute?.values.find(value => value.slug === valueSlug)?.value ||
attributeValues.find(value => value.slug === valueSlug)
});
};
return ( return (
<> <>
{variantsLeft !== null && ( {variantsLeft !== null && (
@ -67,32 +114,24 @@ const ProductVariantCreatorValues: React.FC<ProductVariantCreatorValuesProps> =
<React.Fragment key={attribute.id}> <React.Fragment key={attribute.id}>
<Card> <Card>
<CardTitle title={attribute?.name || <Skeleton />} /> <CardTitle title={attribute?.name || <Skeleton />} />
<CardContent <CardContent data-test-id="value-container">
className={classes.valueContainer} <MultiAutocompleteSelectField
data-test-id="value-container" choices={getMultiChoices(attributeValues)}
> displayValues={getMultiDisplayValues(
{attribute.choices.edges.map(({ node: value }) => ( data.attributes,
<Debounce attribute
debounceFn={() => onValueClick(attribute.id, value.slug)}
time={100}
key={value.slug}
>
{change => (
<ControlledCheckbox
checked={isSelected(
value.slug,
data.attributes.find(
dataAttribute => attribute.id === dataAttribute.id
)?.values || [],
(a, b) => a === b
)} )}
name={`value:${value.slug}`} name={`attribute:${attribute.name}`}
label={value.name} label={intl.formatMessage(messages.multipleValueLabel)}
onChange={change} value={getMultiValues(data.attributes, attribute)}
onChange={event =>
handleValueClick(attribute.id, event.target.value)
}
allowCustomValues={true}
fetchChoices={fetchAttributeValues}
{...fetchMoreAttributeValues}
onFocus={() => onAttributeFocus(attribute.id)}
/> />
)}
</Debounce>
))}
</CardContent> </CardContent>
</Card> </Card>
<CardSpacer /> <CardSpacer />

View file

@ -6,22 +6,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],
@ -561,22 +627,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],
@ -1116,22 +1248,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],
@ -1171,22 +1369,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],
@ -1677,22 +1941,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],
@ -2138,22 +2468,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],
@ -2644,22 +3040,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],
@ -3067,22 +3529,88 @@ Object {
Object { Object {
"id": "attr-1", "id": "attr-1",
"values": Array [ "values": Array [
"val-1-1", Object {
"val-1-7", "slug": "val-1-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-1",
"name": "val-1-1",
"reference": null,
"richText": null,
"slug": "val-1-1",
},
},
Object {
"slug": "val-1-7",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-1-7",
"name": "val-1-7",
"reference": null,
"richText": null,
"slug": "val-1-7",
},
},
], ],
}, },
Object { Object {
"id": "attr-2", "id": "attr-2",
"values": Array [ "values": Array [
"val-2-2", Object {
"val-2-4", "slug": "val-2-2",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-2",
"name": "val-2-2",
"reference": null,
"richText": null,
"slug": "val-2-2",
},
},
Object {
"slug": "val-2-4",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-2-4",
"name": "val-2-4",
"reference": null,
"richText": null,
"slug": "val-2-4",
},
},
], ],
}, },
Object { Object {
"id": "attr-4", "id": "attr-4",
"values": Array [ "values": Array [
"val-4-1", Object {
"val-4-5", "slug": "val-4-1",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-1",
"name": "val-4-1",
"reference": null,
"richText": null,
"slug": "val-4-1",
},
},
Object {
"slug": "val-4-5",
"value": Object {
"__typename": "AttributeValue",
"file": null,
"id": "val-4-5",
"name": "val-4-5",
"reference": null,
"richText": null,
"slug": "val-4-5",
},
},
], ],
}, },
], ],

View file

@ -63,7 +63,7 @@ describe("Creates variant matrix", () => {
attribute: attribute.id, attribute: attribute.id,
mode: "attribute", mode: "attribute",
values: attribute.values.map((attributeValue, index) => ({ values: attribute.values.map((attributeValue, index) => ({
slug: attributeValue, slug: attributeValue.slug,
value: channels.map(channel => ({ value: channels.map(channel => ({
channelId: channel.id, channelId: channel.id,
price: (channel.price + index).toString() price: (channel.price + index).toString()
@ -97,7 +97,7 @@ describe("Creates variant matrix", () => {
variant => variant =>
variant.attributes.find( variant.attributes.find(
variantAttribute => variantAttribute.id === attribute.id variantAttribute => variantAttribute.id === attribute.id
).values[0] === attributeValue ).values[0] === attributeValue.slug
) )
.forEach(variant => { .forEach(variant => {
variant.channelListings.map((channel, index) => { variant.channelListings.map((channel, index) => {
@ -128,7 +128,7 @@ describe("Creates variant matrix", () => {
attribute: attribute.id, attribute: attribute.id,
mode: "attribute", mode: "attribute",
values: attribute.values.map((attributeValue, attributeValueIndex) => ({ values: attribute.values.map((attributeValue, attributeValueIndex) => ({
slug: attributeValue, slug: attributeValue.slug,
value: stock.map( value: stock.map(
(_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1) (_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1)
) )
@ -154,7 +154,7 @@ describe("Creates variant matrix", () => {
variant => variant =>
variant.attributes.find( variant.attributes.find(
variantAttribute => variantAttribute.id === attribute.id variantAttribute => variantAttribute.id === attribute.id
).values[0] === attributeValue ).values[0] === attributeValue.slug
) )
.forEach(variant => { .forEach(variant => {
variant.stocks.forEach((_, stockIndex) => { variant.stocks.forEach((_, stockIndex) => {
@ -179,7 +179,7 @@ describe("Creates variant matrix", () => {
attribute: attribute.id, attribute: attribute.id,
mode: "attribute", mode: "attribute",
values: attribute.values.map((attributeValue, index) => ({ values: attribute.values.map((attributeValue, index) => ({
slug: attributeValue, slug: attributeValue.slug,
value: channels.map(channel => ({ value: channels.map(channel => ({
channelId: channel.id, channelId: channel.id,
price: (channel.price + index).toString() price: (channel.price + index).toString()
@ -191,7 +191,7 @@ describe("Creates variant matrix", () => {
attribute: attribute.id, attribute: attribute.id,
mode: "attribute", mode: "attribute",
values: attribute.values.map((attributeValue, attributeValueIndex) => ({ values: attribute.values.map((attributeValue, attributeValueIndex) => ({
slug: attributeValue, slug: attributeValue.slug,
value: stock.map( value: stock.map(
(_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1) (_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1)
) )
@ -213,7 +213,7 @@ describe("Creates variant matrix", () => {
variant => variant =>
variant.attributes.find( variant.attributes.find(
variantAttribute => variantAttribute.id === attribute.id variantAttribute => variantAttribute.id === attribute.id
).values[0] === attributeValue ).values[0] === attributeValue.slug
) )
.forEach(variant => { .forEach(variant => {
variant.channelListings.map((channel, index) => { variant.channelListings.map((channel, index) => {
@ -230,7 +230,7 @@ describe("Creates variant matrix", () => {
variant => variant =>
variant.attributes.find( variant.attributes.find(
variantAttribute => variantAttribute.id === attribute.id variantAttribute => variantAttribute.id === attribute.id
).values[0] === attributeValue ).values[0] === attributeValue.slug
) )
.forEach(variant => { .forEach(variant => {
variant.stocks.forEach((_, stockIndex) => { variant.stocks.forEach((_, stockIndex) => {

View file

@ -112,11 +112,11 @@ function addAttributeToVariant(
attribute: Attribute, attribute: Attribute,
variant: CreateVariantInput variant: CreateVariantInput
): CreateVariantInput[] { ): CreateVariantInput[] {
return attribute.values.map(attributeValueSlug => [ return attribute.values.map(attributeValue => [
...variant, ...variant,
{ {
attributeId: attribute.id, attributeId: attribute.id,
attributeValueSlug attributeValueSlug: attributeValue.slug
} }
]); ]);
} }

View file

@ -20,25 +20,69 @@ export const attributes = [
id: "attr-1", id: "attr-1",
values: Array(9) values: Array(9)
.fill(0) .fill(0)
.map((_, index) => `val-1-${index + 1}`) .map((_, index) => ({
slug: `val-1-${index + 1}`,
value: {
__typename: "AttributeValue" as "AttributeValue",
id: `val-1-${index + 1}`,
name: `val-1-${index + 1}`,
slug: `val-1-${index + 1}`,
file: null,
reference: null,
richText: null
}
}))
}, },
{ {
id: "attr-2", id: "attr-2",
values: Array(6) values: Array(6)
.fill(0) .fill(0)
.map((_, index) => `val-2-${index + 1}`) .map((_, index) => ({
slug: `val-2-${index + 1}`,
value: {
__typename: "AttributeValue" as "AttributeValue",
id: `val-2-${index + 1}`,
name: `val-2-${index + 1}`,
slug: `val-2-${index + 1}`,
file: null,
reference: null,
richText: null
}
}))
}, },
{ {
id: "attr-3", id: "attr-3",
values: Array(4) values: Array(4)
.fill(0) .fill(0)
.map((_, index) => `val-3-${index + 1}`) .map((_, index) => ({
slug: `val-3-${index + 1}`,
value: {
__typename: "AttributeValue" as "AttributeValue",
id: `val-3-${index + 1}`,
name: `val-3-${index + 1}`,
slug: `val-3-${index + 1}`,
file: null,
reference: null,
richText: null
}
}))
}, },
{ {
id: "attr-4", id: "attr-4",
values: Array(11) values: Array(11)
.fill(0) .fill(0)
.map((_, index) => `val-4-${index + 1}`) .map((_, index) => ({
slug: `val-4-${index + 1}`,
value: {
__typename: "AttributeValue" as "AttributeValue",
id: `val-4-${index + 1}`,
name: `val-4-${index + 1}`,
slug: `val-4-${index + 1}`,
file: null,
reference: null,
richText: null
}
}))
} }
]; ];
@ -116,7 +160,7 @@ const price: Price = {
mode: "attribute", mode: "attribute",
values: [ values: [
{ {
slug: thirdStep.attributes[1].values[0], slug: thirdStep.attributes[1].values[0].slug,
value: [ value: [
{ channelId: channels[0].id, price: "0" }, { channelId: channels[0].id, price: "0" },
{ channelId: channels[1].id, price: "2" }, { channelId: channels[1].id, price: "2" },
@ -124,7 +168,7 @@ const price: Price = {
] ]
}, },
{ {
slug: thirdStep.attributes[1].values[1], slug: thirdStep.attributes[1].values[1].slug,
value: [ value: [
{ channelId: channels[0].id, price: "0" }, { channelId: channels[0].id, price: "0" },
{ channelId: channels[1].id, price: "2" }, { channelId: channels[1].id, price: "2" },
@ -139,11 +183,11 @@ const stock: Stock = {
value: [], value: [],
values: [ values: [
{ {
slug: thirdStep.attributes[2].values[0], slug: thirdStep.attributes[2].values[0].slug,
value: [50, 20, 45, 75] value: [50, 20, 45, 75]
}, },
{ {
slug: thirdStep.attributes[2].values[1], slug: thirdStep.attributes[2].values[1].slug,
value: [80, 50, 85, 105] value: [80, 50, 85, 105]
} }
] ]

View file

@ -1,4 +1,5 @@
import { ChannelPriceData } from "@saleor/channels/utils"; import { ChannelPriceData } from "@saleor/channels/utils";
import { AttributeValueFragment } from "@saleor/fragments/types/AttributeValueFragment";
import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment";
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails"; import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
@ -28,7 +29,7 @@ export interface Stock {
} }
export interface Attribute { export interface Attribute {
id: string; id: string;
values: string[]; values: Array<AttributeValue<AttributeValueFragment>>;
} }
export interface ProductVariantCreateFormData { export interface ProductVariantCreateFormData {
attributes: Attribute[]; attributes: Attribute[];

View file

@ -23,14 +23,14 @@ describe("Reducer is able to", () => {
{ {
selectValue: { selectValue: {
attributeId: attributes[0].id, attributeId: attributes[0].id,
valueId: attributes[0].values[0] value: attributes[0].values[0]
}, },
type: ProductVariantCreateReducerActionType.selectValue type: ProductVariantCreateReducerActionType.selectValue
}, },
{ {
selectValue: { selectValue: {
attributeId: attributes[0].id, attributeId: attributes[0].id,
valueId: attributes[0].values[6] value: attributes[0].values[6]
}, },
type: ProductVariantCreateReducerActionType.selectValue type: ProductVariantCreateReducerActionType.selectValue
@ -38,28 +38,28 @@ describe("Reducer is able to", () => {
{ {
selectValue: { selectValue: {
attributeId: attributes[1].id, attributeId: attributes[1].id,
valueId: attributes[1].values[1] value: attributes[1].values[1]
}, },
type: ProductVariantCreateReducerActionType.selectValue type: ProductVariantCreateReducerActionType.selectValue
}, },
{ {
selectValue: { selectValue: {
attributeId: attributes[1].id, attributeId: attributes[1].id,
valueId: attributes[1].values[3] value: attributes[1].values[3]
}, },
type: ProductVariantCreateReducerActionType.selectValue type: ProductVariantCreateReducerActionType.selectValue
}, },
{ {
selectValue: { selectValue: {
attributeId: attributes[3].id, attributeId: attributes[3].id,
valueId: attributes[3].values[0] value: attributes[3].values[0]
}, },
type: ProductVariantCreateReducerActionType.selectValue type: ProductVariantCreateReducerActionType.selectValue
}, },
{ {
selectValue: { selectValue: {
attributeId: attributes[3].id, attributeId: attributes[3].id,
valueId: attributes[3].values[4] value: attributes[3].values[4]
}, },
type: ProductVariantCreateReducerActionType.selectValue type: ProductVariantCreateReducerActionType.selectValue
} }
@ -164,7 +164,7 @@ describe("Reducer is able to", () => {
changeAttributeValuePrice: { changeAttributeValuePrice: {
channelId: channels[0].id, channelId: channels[0].id,
price: value.toString(), price: value.toString(),
valueId: attribute.values[0] valueId: attribute.values[0].slug
}, },
type: ProductVariantCreateReducerActionType.changeAttributeValuePrice type: ProductVariantCreateReducerActionType.changeAttributeValuePrice
}, },
@ -172,7 +172,7 @@ describe("Reducer is able to", () => {
changeAttributeValuePrice: { changeAttributeValuePrice: {
channelId: channels[1].id, channelId: channels[1].id,
price: (value + 6).toString(), price: (value + 6).toString(),
valueId: attribute.values[1] valueId: attribute.values[1].slug
}, },
type: ProductVariantCreateReducerActionType.changeAttributeValuePrice type: ProductVariantCreateReducerActionType.changeAttributeValuePrice
}, },
@ -209,7 +209,7 @@ describe("Reducer is able to", () => {
{ {
changeAttributeValueStock: { changeAttributeValueStock: {
quantity, quantity,
valueId: attribute.values[0], valueId: attribute.values[0].slug,
warehouseIndex: 0 warehouseIndex: 0
}, },
type: ProductVariantCreateReducerActionType.changeAttributeValueStock type: ProductVariantCreateReducerActionType.changeAttributeValueStock
@ -217,7 +217,7 @@ describe("Reducer is able to", () => {
{ {
changeAttributeValueStock: { changeAttributeValueStock: {
quantity: quantity + 6, quantity: quantity + 6,
valueId: attribute.values[1], valueId: attribute.values[1].slug,
warehouseIndex: 0 warehouseIndex: 0
}, },
type: ProductVariantCreateReducerActionType.changeAttributeValueStock type: ProductVariantCreateReducerActionType.changeAttributeValueStock

View file

@ -1,3 +1,4 @@
import { AttributeValueFragment } from "@saleor/fragments/types/AttributeValueFragment";
import { StockInput } from "@saleor/types/globalTypes"; import { StockInput } from "@saleor/types/globalTypes";
import { import {
add, add,
@ -10,6 +11,7 @@ import {
import { createVariants } from "./createVariants"; import { createVariants } from "./createVariants";
import { import {
AttributeValue,
ProductVariantCreateFormData, ProductVariantCreateFormData,
VariantCreatorPricesAndSkuMode VariantCreatorPricesAndSkuMode
} from "./form"; } from "./form";
@ -72,19 +74,22 @@ export interface ProductVariantCreateReducerAction {
reload?: { reload?: {
data?: ProductVariantCreateFormData; data?: ProductVariantCreateFormData;
}; };
selectValue?: Record<"attributeId" | "valueId", string>; selectValue?: {
attributeId: string;
value: AttributeValue<AttributeValueFragment>;
};
type: ProductVariantCreateReducerActionType; type: ProductVariantCreateReducerActionType;
} }
function selectValue( function selectValue(
prevState: ProductVariantCreateFormData, prevState: ProductVariantCreateFormData,
attributeId: string, attributeId: string,
valueSlug: string value: AttributeValue<AttributeValueFragment>
): ProductVariantCreateFormData { ): ProductVariantCreateFormData {
const attribute = prevState.attributes.find( const attribute = prevState.attributes.find(
attribute => attribute.id === attributeId attribute => attribute.id === attributeId
); );
const values = toggle(valueSlug, attribute.values, (a, b) => a === b); const values = toggle(value, attribute.values, (a, b) => a.slug === b.slug);
const updatedAttributes = add( const updatedAttributes = add(
{ {
id: attributeId, id: attributeId,
@ -97,7 +102,7 @@ function selectValue(
prevState.price.attribute === attributeId prevState.price.attribute === attributeId
? toggle( ? toggle(
{ {
slug: valueSlug, slug: value.slug,
value: [] value: []
}, },
prevState.price.values, prevState.price.values,
@ -109,7 +114,7 @@ function selectValue(
prevState.stock.attribute === attributeId prevState.stock.attribute === attributeId
? toggle( ? toggle(
{ {
slug: valueSlug, slug: value.slug,
value: [] value: []
}, },
prevState.stock.values, prevState.stock.values,
@ -237,8 +242,8 @@ function changeApplyPriceToAttributeId(
const attribute = state.attributes.find( const attribute = state.attributes.find(
attribute => attribute.id === attributeId attribute => attribute.id === attributeId
); );
const values = attribute.values.map(slug => ({ const values = attribute.values.map(value => ({
slug, slug: value.slug,
value: [] value: []
})); }));
@ -259,8 +264,8 @@ function changeApplyStockToAttributeId(
const attribute = state.attributes.find( const attribute = state.attributes.find(
attribute => attribute.id === attributeId attribute => attribute.id === attributeId
); );
const values = attribute.values.map(slug => ({ const values = attribute.values.map(value => ({
slug, slug: value.slug,
value: [] value: []
})); }));
@ -435,7 +440,7 @@ function reduceProductVariantCreateFormData(
return selectValue( return selectValue(
prevState, prevState,
action.selectValue.attributeId, action.selectValue.attributeId,
action.selectValue.valueId action.selectValue.value
); );
case ProductVariantCreateReducerActionType.applyPriceToAll: case ProductVariantCreateReducerActionType.applyPriceToAll:
return applyPriceToAll(prevState, action.applyPriceOrStockToAll.mode); return applyPriceToAll(prevState, action.applyPriceOrStockToAll.mode);

View file

@ -17,7 +17,9 @@ export function getPriceAttributeValues(
.choices.edges.filter(value => .choices.edges.filter(value =>
data.attributes data.attributes
.find(attribute => attribute.id === data.price.attribute) .find(attribute => attribute.id === data.price.attribute)
.values.includes(value.node.slug) .values.some(
attributeValue => attributeValue.slug === value.node.slug
)
) )
.map(value => value.node) .map(value => value.node)
: []; : [];
@ -35,7 +37,9 @@ export function getStockAttributeValues(
.choices.edges.filter(value => .choices.edges.filter(value =>
data.attributes data.attributes
.find(attribute => attribute.id === data.stock.attribute) .find(attribute => attribute.id === data.stock.attribute)
.values.includes(value.node.slug) .values.some(
attributeValue => attributeValue.slug === value.node.slug
)
) )
.map(value => value.node) .map(value => value.node)
: []; : [];

View file

@ -22,6 +22,7 @@ import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/Prod
import { ProductVariant } from "@saleor/fragments/types/ProductVariant"; import { ProductVariant } from "@saleor/fragments/types/ProductVariant";
import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment";
import { VariantUpdate_productVariantUpdate_errors } from "@saleor/products/types/VariantUpdate"; import { VariantUpdate_productVariantUpdate_errors } from "@saleor/products/types/VariantUpdate";
import { SearchAttributeValues_attribute_choices_edges_node } from "@saleor/searches/types/SearchAttributeValues";
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts";
import { FetchMoreProps, ReorderAction } from "@saleor/types"; import { FetchMoreProps, ReorderAction } from "@saleor/types";
@ -87,11 +88,15 @@ interface ProductVariantPageProps {
warehouses: WarehouseFragment[]; warehouses: WarehouseFragment[];
referencePages?: SearchPages_search_edges_node[]; referencePages?: SearchPages_search_edges_node[];
referenceProducts?: SearchProducts_search_edges_node[]; referenceProducts?: SearchProducts_search_edges_node[];
attributeValues: SearchAttributeValues_attribute_choices_edges_node[];
fetchMoreReferencePages?: FetchMoreProps; fetchMoreReferencePages?: FetchMoreProps;
fetchMoreReferenceProducts?: FetchMoreProps; fetchMoreReferenceProducts?: FetchMoreProps;
fetchMoreAttributeValues?: FetchMoreProps;
fetchReferencePages?: (data: string) => void; fetchReferencePages?: (data: string) => void;
fetchReferenceProducts?: (data: string) => void; fetchReferenceProducts?: (data: string) => void;
fetchAttributeValues: (query: string) => void;
onAssignReferencesClick: (attribute: AttributeInput) => void; onAssignReferencesClick: (attribute: AttributeInput) => void;
onAttributeFocus: (id: string) => void;
onCloseDialog: () => void; onCloseDialog: () => void;
onVariantReorder: ReorderAction; onVariantReorder: ReorderAction;
onAdd(); onAdd();
@ -118,6 +123,7 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
warehouses, warehouses,
referencePages = [], referencePages = [],
referenceProducts = [], referenceProducts = [],
attributeValues,
onAdd, onAdd,
onBack, onBack,
onDelete, onDelete,
@ -127,12 +133,15 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
onVariantReorder, onVariantReorder,
onSetDefaultVariant, onSetDefaultVariant,
onWarehouseConfigure, onWarehouseConfigure,
onAttributeFocus,
assignReferencesAttributeId, assignReferencesAttributeId,
onAssignReferencesClick, onAssignReferencesClick,
fetchReferencePages, fetchReferencePages,
fetchReferenceProducts, fetchReferenceProducts,
fetchAttributeValues,
fetchMoreReferencePages, fetchMoreReferencePages,
fetchMoreReferenceProducts, fetchMoreReferenceProducts,
fetchMoreAttributeValues,
onCloseDialog onCloseDialog
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
@ -226,7 +235,7 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
attribute.data.variantAttributeScope === attribute.data.variantAttributeScope ===
VariantAttributeScope.NOT_VARIANT_SELECTION VariantAttributeScope.NOT_VARIANT_SELECTION
)} )}
attributeValues={[]} attributeValues={attributeValues}
loading={loading} loading={loading}
disabled={loading} disabled={loading}
errors={errors} errors={errors}
@ -236,9 +245,9 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
onReferencesRemove={handlers.selectAttributeReference} onReferencesRemove={handlers.selectAttributeReference}
onReferencesAddClick={onAssignReferencesClick} onReferencesAddClick={onAssignReferencesClick}
onReferencesReorder={handlers.reorderAttributeValue} onReferencesReorder={handlers.reorderAttributeValue}
fetchAttributeValues={() => undefined} fetchAttributeValues={fetchAttributeValues}
fetchMoreAttributeValues={undefined} fetchMoreAttributeValues={fetchMoreAttributeValues}
onAttributeSelect={() => undefined} onAttributeFocus={onAttributeFocus}
/> />
<CardSpacer /> <CardSpacer />
<Attributes <Attributes
@ -250,7 +259,7 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
attribute.data.variantAttributeScope === attribute.data.variantAttributeScope ===
VariantAttributeScope.VARIANT_SELECTION VariantAttributeScope.VARIANT_SELECTION
)} )}
attributeValues={[]} attributeValues={attributeValues}
loading={loading} loading={loading}
disabled={loading} disabled={loading}
errors={errors} errors={errors}
@ -260,9 +269,9 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
onReferencesRemove={handlers.selectAttributeReference} onReferencesRemove={handlers.selectAttributeReference}
onReferencesAddClick={onAssignReferencesClick} onReferencesAddClick={onAssignReferencesClick}
onReferencesReorder={handlers.reorderAttributeValue} onReferencesReorder={handlers.reorderAttributeValue}
fetchAttributeValues={() => undefined} fetchAttributeValues={fetchAttributeValues}
fetchMoreAttributeValues={undefined} fetchMoreAttributeValues={fetchMoreAttributeValues}
onAttributeSelect={() => undefined} onAttributeFocus={onAttributeFocus}
/> />
<CardSpacer /> <CardSpacer />
<ProductVariantMedia <ProductVariantMedia

View file

@ -336,7 +336,7 @@ export const product: (
slug: "attachment", slug: "attachment",
valueRequired: true, valueRequired: true,
unit: null, unit: null,
values: { choices: {
__typename: "AttributeValueCountableConnection", __typename: "AttributeValueCountableConnection",
pageInfo: { pageInfo: {
endCursor: "WyI4IiwgIjMiXQ==", endCursor: "WyI4IiwgIjMiXQ==",
@ -377,7 +377,7 @@ export const product: (
slug: "color", slug: "color",
valueRequired: true, valueRequired: true,
unit: null, unit: null,
values: { choices: {
__typename: "AttributeValueCountableConnection", __typename: "AttributeValueCountableConnection",
pageInfo: { pageInfo: {
endCursor: "WyI4IiwgIjMiXQ==", endCursor: "WyI4IiwgIjMiXQ==",
@ -2885,7 +2885,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({
slug: "attachment", slug: "attachment",
valueRequired: true, valueRequired: true,
unit: null, unit: null,
values: { choices: {
__typename: "AttributeValueCountableConnection", __typename: "AttributeValueCountableConnection",
pageInfo: { pageInfo: {
endCursor: "WyI4IiwgIjMiXQ==", endCursor: "WyI4IiwgIjMiXQ==",
@ -3168,7 +3168,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({
slug: "Borders", slug: "Borders",
valueRequired: true, valueRequired: true,
unit: null, unit: null,
values: { choices: {
__typename: "AttributeValueCountableConnection", __typename: "AttributeValueCountableConnection",
pageInfo: { pageInfo: {
endCursor: "WyI4IiwgIjMiXQ==", endCursor: "WyI4IiwgIjMiXQ==",
@ -3230,7 +3230,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({
slug: "Legacy", slug: "Legacy",
valueRequired: true, valueRequired: true,
unit: null, unit: null,
values: { choices: {
__typename: "AttributeValueCountableConnection", __typename: "AttributeValueCountableConnection",
pageInfo: { pageInfo: {
endCursor: "WyI4IiwgIjMiXQ==", endCursor: "WyI4IiwgIjMiXQ==",

View file

@ -334,7 +334,11 @@ export const variantUpdateMutation = gql`
$sku: String $sku: String
$trackInventory: Boolean! $trackInventory: Boolean!
$stocks: [StockInput!]! $stocks: [StockInput!]!
$weight: WeightScalar # $firstValues: Int # $afterValues: String # $lastValues: Int # $beforeValues: String $weight: WeightScalar
$firstValues: Int
$afterValues: String
$lastValues: Int
$beforeValues: String
) { ) {
productVariantUpdate( productVariantUpdate(
id: $id id: $id
@ -394,7 +398,11 @@ export const variantCreateMutation = gql`
${fragmentVariant} ${fragmentVariant}
${productErrorWithAttributesFragment} ${productErrorWithAttributesFragment}
mutation VariantCreate( mutation VariantCreate(
$input: ProductVariantCreateInput! # $firstValues: Int # $afterValues: String # $lastValues: Int # $beforeValues: String $input: ProductVariantCreateInput!
$firstValues: Int
$afterValues: String
$lastValues: Int
$beforeValues: String
) { ) {
productVariantCreate(input: $input) { productVariantCreate(input: $input) {
errors { errors {

View file

@ -282,7 +282,11 @@ export const useProductTypeQuery = makeQuery<ProductType, ProductTypeVariables>(
const productVariantQuery = gql` const productVariantQuery = gql`
${fragmentVariant} ${fragmentVariant}
query ProductVariantDetails( query ProductVariantDetails(
$id: ID! # $firstValues: Int # $afterValues: String # $lastValues: Int # $beforeValues: String $id: ID!
$firstValues: Int
$afterValues: String
$lastValues: Int
$beforeValues: String
) { ) {
productVariant(id: $id) { productVariant(id: $id) {
...ProductVariant ...ProductVariant
@ -297,7 +301,11 @@ export const useProductVariantQuery = makeQuery<
const productVariantCreateQuery = gql` const productVariantCreateQuery = gql`
${variantAttributeFragment} ${variantAttributeFragment}
query ProductVariantCreateData( query ProductVariantCreateData(
$id: ID! # $firstValues: Int # $afterValues: String # $lastValues: Int # $beforeValues: String $id: ID!
$firstValues: Int
$afterValues: String
$lastValues: Int
$beforeValues: String
) { ) {
product(id: $id) { product(id: $id) {
id id

View file

@ -9,7 +9,7 @@ import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum }
// GraphQL query operation: CreateMultipleVariantsData // GraphQL query operation: CreateMultipleVariantsData
// ==================================================== // ====================================================
export interface CreateMultipleVariantsData_product_attributes_attribute_values_pageInfo { export interface CreateMultipleVariantsData_product_attributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -17,32 +17,32 @@ export interface CreateMultipleVariantsData_product_attributes_attribute_values_
startCursor: string | null; startCursor: string | null;
} }
export interface CreateMultipleVariantsData_product_attributes_attribute_values_edges_node_file { export interface CreateMultipleVariantsData_product_attributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface CreateMultipleVariantsData_product_attributes_attribute_values_edges_node { export interface CreateMultipleVariantsData_product_attributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: CreateMultipleVariantsData_product_attributes_attribute_values_edges_node_file | null; file: CreateMultipleVariantsData_product_attributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface CreateMultipleVariantsData_product_attributes_attribute_values_edges { export interface CreateMultipleVariantsData_product_attributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: CreateMultipleVariantsData_product_attributes_attribute_values_edges_node; node: CreateMultipleVariantsData_product_attributes_attribute_choices_edges_node;
} }
export interface CreateMultipleVariantsData_product_attributes_attribute_values { export interface CreateMultipleVariantsData_product_attributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: CreateMultipleVariantsData_product_attributes_attribute_values_pageInfo; pageInfo: CreateMultipleVariantsData_product_attributes_attribute_choices_pageInfo;
edges: CreateMultipleVariantsData_product_attributes_attribute_values_edges[]; edges: CreateMultipleVariantsData_product_attributes_attribute_choices_edges[];
} }
export interface CreateMultipleVariantsData_product_attributes_attribute { export interface CreateMultipleVariantsData_product_attributes_attribute {
@ -54,7 +54,7 @@ export interface CreateMultipleVariantsData_product_attributes_attribute {
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: CreateMultipleVariantsData_product_attributes_attribute_values | null; choices: CreateMultipleVariantsData_product_attributes_attribute_choices | null;
} }
export interface CreateMultipleVariantsData_product_attributes_values_file { export interface CreateMultipleVariantsData_product_attributes_values_file {
@ -79,7 +79,7 @@ export interface CreateMultipleVariantsData_product_attributes {
values: (CreateMultipleVariantsData_product_attributes_values | null)[]; values: (CreateMultipleVariantsData_product_attributes_values | null)[];
} }
export interface CreateMultipleVariantsData_product_productType_variantAttributes_values_pageInfo { export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -87,39 +87,39 @@ export interface CreateMultipleVariantsData_product_productType_variantAttribute
startCursor: string | null; startCursor: string | null;
} }
export interface CreateMultipleVariantsData_product_productType_variantAttributes_values_edges_node_file { export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface CreateMultipleVariantsData_product_productType_variantAttributes_values_edges_node { export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: CreateMultipleVariantsData_product_productType_variantAttributes_values_edges_node_file | null; file: CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface CreateMultipleVariantsData_product_productType_variantAttributes_values_edges { export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: CreateMultipleVariantsData_product_productType_variantAttributes_values_edges_node; node: CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges_node;
} }
export interface CreateMultipleVariantsData_product_productType_variantAttributes_values { export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: CreateMultipleVariantsData_product_productType_variantAttributes_values_pageInfo; pageInfo: CreateMultipleVariantsData_product_productType_variantAttributes_choices_pageInfo;
edges: CreateMultipleVariantsData_product_productType_variantAttributes_values_edges[]; edges: CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges[];
} }
export interface CreateMultipleVariantsData_product_productType_variantAttributes { export interface CreateMultipleVariantsData_product_productType_variantAttributes {
__typename: "Attribute"; __typename: "Attribute";
id: string; id: string;
name: string | null; name: string | null;
values: CreateMultipleVariantsData_product_productType_variantAttributes_values | null; choices: CreateMultipleVariantsData_product_productType_variantAttributes_choices | null;
} }
export interface CreateMultipleVariantsData_product_productType { export interface CreateMultipleVariantsData_product_productType {

View file

@ -28,7 +28,7 @@ export interface ProductVariantCreateData_product_channelListings {
channel: ProductVariantCreateData_product_channelListings_channel; channel: ProductVariantCreateData_product_channelListings_channel;
} }
export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values_pageInfo { export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -36,32 +36,32 @@ export interface ProductVariantCreateData_product_productType_selectionVariantAt
startCursor: string | null; startCursor: string | null;
} }
export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges_node_file { export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges_node { export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges_node_file | null; file: ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges { export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges_node; node: ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges_node;
} }
export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values { export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: ProductVariantCreateData_product_productType_selectionVariantAttributes_values_pageInfo; pageInfo: ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_pageInfo;
edges: ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges[]; edges: ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges[];
} }
export interface ProductVariantCreateData_product_productType_selectionVariantAttributes { export interface ProductVariantCreateData_product_productType_selectionVariantAttributes {
@ -73,10 +73,10 @@ export interface ProductVariantCreateData_product_productType_selectionVariantAt
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: ProductVariantCreateData_product_productType_selectionVariantAttributes_values | null; choices: ProductVariantCreateData_product_productType_selectionVariantAttributes_choices | null;
} }
export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_pageInfo { export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -84,32 +84,32 @@ export interface ProductVariantCreateData_product_productType_nonSelectionVarian
startCursor: string | null; startCursor: string | null;
} }
export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges_node_file { export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges_node { export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges_node_file | null; file: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges { export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges_node; node: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges_node;
} }
export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values { export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_pageInfo; pageInfo: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_pageInfo;
edges: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges[]; edges: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges[];
} }
export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes { export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes {
@ -121,7 +121,7 @@ export interface ProductVariantCreateData_product_productType_nonSelectionVarian
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values | null; choices: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices | null;
} }
export interface ProductVariantCreateData_product_productType { export interface ProductVariantCreateData_product_productType {

View file

@ -21,7 +21,7 @@ export interface ProductVariantDetails_productVariant_privateMetadata {
value: string; value: string;
} }
export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values_pageInfo { export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -29,32 +29,32 @@ export interface ProductVariantDetails_productVariant_selectionAttributes_attrib
startCursor: string | null; startCursor: string | null;
} }
export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges_node_file { export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges_node { export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges_node_file | null; file: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges { export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges_node; node: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges_node;
} }
export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values { export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: ProductVariantDetails_productVariant_selectionAttributes_attribute_values_pageInfo; pageInfo: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_pageInfo;
edges: ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges[]; edges: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges[];
} }
export interface ProductVariantDetails_productVariant_selectionAttributes_attribute { export interface ProductVariantDetails_productVariant_selectionAttributes_attribute {
@ -66,7 +66,7 @@ export interface ProductVariantDetails_productVariant_selectionAttributes_attrib
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: ProductVariantDetails_productVariant_selectionAttributes_attribute_values | null; choices: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices | null;
} }
export interface ProductVariantDetails_productVariant_selectionAttributes_values_file { export interface ProductVariantDetails_productVariant_selectionAttributes_values_file {
@ -91,7 +91,7 @@ export interface ProductVariantDetails_productVariant_selectionAttributes {
values: (ProductVariantDetails_productVariant_selectionAttributes_values | null)[]; values: (ProductVariantDetails_productVariant_selectionAttributes_values | null)[];
} }
export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_pageInfo { export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -99,32 +99,32 @@ export interface ProductVariantDetails_productVariant_nonSelectionAttributes_att
startCursor: string | null; startCursor: string | null;
} }
export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges_node_file { export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges_node { export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges_node_file | null; file: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges { export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges_node; node: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges_node;
} }
export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values { export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_pageInfo; pageInfo: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_pageInfo;
edges: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges[]; edges: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges[];
} }
export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute { export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute {
@ -136,7 +136,7 @@ export interface ProductVariantDetails_productVariant_nonSelectionAttributes_att
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values | null; choices: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices | null;
} }
export interface ProductVariantDetails_productVariant_nonSelectionAttributes_values_file { export interface ProductVariantDetails_productVariant_nonSelectionAttributes_values_file {

View file

@ -28,7 +28,7 @@ export interface VariantCreate_productVariantCreate_productVariant_privateMetada
value: string; value: string;
} }
export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_pageInfo { export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -36,32 +36,32 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr
startCursor: string | null; startCursor: string | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges_node_file { export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges_node { export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges_node_file | null; file: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges { export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges_node; node: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges_node;
} }
export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values { export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_pageInfo; pageInfo: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_pageInfo;
edges: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges[]; edges: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges[];
} }
export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute { export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute {
@ -73,7 +73,7 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values | null; choices: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_values_file { export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_values_file {
@ -98,7 +98,7 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr
values: (VariantCreate_productVariantCreate_productVariant_selectionAttributes_values | null)[]; values: (VariantCreate_productVariantCreate_productVariant_selectionAttributes_values | null)[];
} }
export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_pageInfo { export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -106,32 +106,32 @@ export interface VariantCreate_productVariantCreate_productVariant_nonSelectionA
startCursor: string | null; startCursor: string | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges_node_file { export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges_node { export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges_node_file | null; file: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges { export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges_node; node: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges_node;
} }
export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values { export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_pageInfo; pageInfo: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo;
edges: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges[]; edges: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges[];
} }
export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute { export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute {
@ -143,7 +143,7 @@ export interface VariantCreate_productVariantCreate_productVariant_nonSelectionA
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values | null; choices: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices | null;
} }
export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_values_file { export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_values_file {

View file

@ -28,7 +28,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_privateMetada
value: string; value: string;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_pageInfo { export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -36,32 +36,32 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr
startCursor: string | null; startCursor: string | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges_node_file { export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges_node { export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges_node_file | null; file: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges { export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges_node; node: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges_node;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values { export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_pageInfo; pageInfo: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo;
edges: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges[]; edges: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges[];
} }
export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute { export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute {
@ -73,7 +73,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values | null; choices: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_values_file { export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_values_file {
@ -98,7 +98,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr
values: (VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_values | null)[]; values: (VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_values | null)[];
} }
export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_pageInfo { export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -106,32 +106,32 @@ export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionA
startCursor: string | null; startCursor: string | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node_file { export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node { export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node_file | null; file: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges { export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node; node: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values { export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_pageInfo; pageInfo: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo;
edges: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges[]; edges: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges[];
} }
export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute { export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute {
@ -143,7 +143,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionA
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values | null; choices: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices | null;
} }
export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_values_file { export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_values_file {
@ -359,7 +359,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_private
value: string; value: string;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_pageInfo { export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -367,32 +367,32 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti
startCursor: string | null; startCursor: string | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges_node_file { export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges_node { export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges_node_file | null; file: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges { export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges_node; node: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges_node;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values { export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_pageInfo; pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo;
edges: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges[]; edges: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges[];
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute { export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute {
@ -404,7 +404,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values | null; choices: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_values_file { export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_values_file {
@ -429,7 +429,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti
values: (VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_values | null)[]; values: (VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_values | null)[];
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_pageInfo { export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo {
__typename: "PageInfo"; __typename: "PageInfo";
endCursor: string | null; endCursor: string | null;
hasNextPage: boolean; hasNextPage: boolean;
@ -437,32 +437,32 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSele
startCursor: string | null; startCursor: string | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node_file { export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file {
__typename: "File"; __typename: "File";
url: string; url: string;
contentType: string | null; contentType: string | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node { export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node {
__typename: "AttributeValue"; __typename: "AttributeValue";
id: string; id: string;
name: string | null; name: string | null;
slug: string | null; slug: string | null;
file: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node_file | null; file: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node_file | null;
reference: string | null; reference: string | null;
richText: any | null; richText: any | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges { export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges {
__typename: "AttributeValueCountableEdge"; __typename: "AttributeValueCountableEdge";
cursor: string; cursor: string;
node: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges_node; node: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges_node;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values { export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices {
__typename: "AttributeValueCountableConnection"; __typename: "AttributeValueCountableConnection";
pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_pageInfo; pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo;
edges: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges[]; edges: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges[];
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute { export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute {
@ -474,7 +474,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSele
entityType: AttributeEntityTypeEnum | null; entityType: AttributeEntityTypeEnum | null;
valueRequired: boolean; valueRequired: boolean;
unit: MeasurementUnitsEnum | null; unit: MeasurementUnitsEnum | null;
values: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values | null; choices: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices | null;
} }
export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_values_file { export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_values_file {

View file

@ -89,7 +89,7 @@ export function getAttributeInputFromAttributes(
entityType: attribute.entityType, entityType: attribute.entityType,
inputType: attribute.inputType, inputType: attribute.inputType,
isRequired: attribute.valueRequired, isRequired: attribute.valueRequired,
values: mapEdgesToItems(attribute.values), values: mapEdgesToItems(attribute.choices),
unit: attribute.unit, unit: attribute.unit,
variantAttributeScope variantAttributeScope
}, },
@ -109,7 +109,7 @@ export function getAttributeInputFromSelectedAttributes(
inputType: attribute.attribute.inputType, inputType: attribute.attribute.inputType,
isRequired: attribute.attribute.valueRequired, isRequired: attribute.attribute.valueRequired,
selectedValues: attribute.values, selectedValues: attribute.values,
values: mapEdgesToItems(attribute.attribute.values), values: mapEdgesToItems(attribute.attribute.choices),
unit: attribute.attribute.unit, unit: attribute.attribute.unit,
variantAttributeScope variantAttributeScope
}, },

View file

@ -103,17 +103,17 @@ export const ProductCreateView: React.FC<ProductCreateProps> = ({ params }) => {
} = useProductSearch({ } = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA variables: DEFAULT_INITIAL_SEARCH_DATA
}); });
const [selectedAttribute, setSelectedAttribute] = useState<string>(); const [focusedAttribute, setFocusedAttribute] = useState<string>();
const { const {
loadMore: loadMoreAttributeValues, loadMore: loadMoreAttributeValues,
search: searchAttributeValues, search: searchAttributeValues,
result: searchAttributeValuesOpts result: searchAttributeValuesOpts
} = useAttributeValueSearch({ } = useAttributeValueSearch({
variables: { variables: {
id: selectedAttribute, id: focusedAttribute,
...DEFAULT_INITIAL_SEARCH_DATA ...DEFAULT_INITIAL_SEARCH_DATA
}, },
skip: !selectedAttribute skip: !focusedAttribute
}); });
const warehouses = useWarehouseList({ const warehouses = useWarehouseList({
displayLoader: true, displayLoader: true,
@ -348,7 +348,7 @@ export const ProductCreateView: React.FC<ProductCreateProps> = ({ params }) => {
onCloseDialog={() => navigate(productAddUrl())} onCloseDialog={() => navigate(productAddUrl())}
selectedProductType={selectedProductType?.productType} selectedProductType={selectedProductType?.productType}
onSelectProductType={id => setSelectedProductTypeId(id)} onSelectProductType={id => setSelectedProductTypeId(id)}
onAttributeSelect={setSelectedAttribute} onAttributeFocus={setFocusedAttribute}
/> />
</> </>
); );

View file

@ -141,17 +141,17 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
} = useProductSearch({ } = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA variables: DEFAULT_INITIAL_SEARCH_DATA
}); });
const [selectedAttribute, setSelectedAttribute] = useState<string>(); const [focusedAttribute, setFocusedAttribute] = useState<string>();
const { const {
loadMore: loadMoreAttributeValues, loadMore: loadMoreAttributeValues,
search: searchAttributeValues, search: searchAttributeValues,
result: searchAttributeValuesOpts result: searchAttributeValuesOpts
} = useAttributeValueSearch({ } = useAttributeValueSearch({
variables: { variables: {
id: selectedAttribute, id: focusedAttribute,
...DEFAULT_INITIAL_SEARCH_DATA ...DEFAULT_INITIAL_SEARCH_DATA
}, },
skip: !selectedAttribute skip: !focusedAttribute
}); });
const warehouses = useWarehouseList({ const warehouses = useWarehouseList({
displayLoader: true, displayLoader: true,
@ -605,7 +605,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
fetchMoreReferenceProducts={fetchMoreReferenceProducts} fetchMoreReferenceProducts={fetchMoreReferenceProducts}
fetchMoreAttributeValues={fetchMoreAttributeValues} fetchMoreAttributeValues={fetchMoreAttributeValues}
onCloseDialog={() => navigate(productUrl(id))} onCloseDialog={() => navigate(productUrl(id))}
onAttributeSelect={setSelectedAttribute} onAttributeFocus={setFocusedAttribute}
/> />
<ActionDialog <ActionDialog
open={params.action === "remove"} open={params.action === "remove"}

View file

@ -23,6 +23,7 @@ import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { useProductVariantChannelListingUpdate } from "@saleor/products/mutations"; import { useProductVariantChannelListingUpdate } from "@saleor/products/mutations";
import { ProductVariantDetails_productVariant } from "@saleor/products/types/ProductVariantDetails"; import { ProductVariantDetails_productVariant } from "@saleor/products/types/ProductVariantDetails";
import useAttributeValueSearch from "@saleor/searches/useAttributeValueSearch";
import usePageSearch from "@saleor/searches/usePageSearch"; import usePageSearch from "@saleor/searches/usePageSearch";
import useProductSearch from "@saleor/searches/useProductSearch"; import useProductSearch from "@saleor/searches/useProductSearch";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
@ -92,7 +93,8 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
const { data, loading } = useProductVariantQuery({ const { data, loading } = useProductVariantQuery({
displayLoader: true, displayLoader: true,
variables: { variables: {
id: variantId id: variantId,
firstValues: 10
} }
}); });
const [updateMetadata] = useMetadataUpdate({}); const [updateMetadata] = useMetadataUpdate({});
@ -254,7 +256,8 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
sku: data.sku, sku: data.sku,
stocks: data.updateStocks.map(mapFormsetStockToStockInput), stocks: data.updateStocks.map(mapFormsetStockToStockInput),
trackInventory: data.trackInventory, trackInventory: data.trackInventory,
weight: weight(data.weight) weight: weight(data.weight),
firstValues: 10
} }
}); });
await handleSubmitChannels(data, variant); await handleSubmitChannels(data, variant);
@ -297,6 +300,18 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
} = useProductSearch({ } = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA variables: DEFAULT_INITIAL_SEARCH_DATA
}); });
const [focusedAttribute, setFocusedAttribute] = useState<string>();
const {
loadMore: loadMoreAttributeValues,
search: searchAttributeValues,
result: searchAttributeValuesOpts
} = useAttributeValueSearch({
variables: {
id: focusedAttribute,
...DEFAULT_INITIAL_SEARCH_DATA
},
skip: !focusedAttribute
});
const fetchMoreReferencePages = { const fetchMoreReferencePages = {
hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage,
@ -308,6 +323,16 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
loading: searchProductsOpts.loading, loading: searchProductsOpts.loading,
onFetchMore: loadMoreProducts onFetchMore: loadMoreProducts
}; };
const fetchMoreAttributeValues = {
hasMore: !!searchAttributeValuesOpts.data?.attribute?.choices?.pageInfo
?.hasNextPage,
loading: !!searchAttributeValuesOpts.loading,
onFetchMore: loadMoreAttributeValues
};
const attributeValues = mapEdgesToItems(
searchAttributeValuesOpts?.data?.attribute.choices
);
return ( return (
<> <>
@ -316,6 +341,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
defaultWeightUnit={shop?.defaultWeightUnit} defaultWeightUnit={shop?.defaultWeightUnit}
defaultVariantId={data?.productVariant.product.defaultVariant?.id} defaultVariantId={data?.productVariant.product.defaultVariant?.id}
errors={errors} errors={errors}
attributeValues={attributeValues}
channels={channels} channels={channels}
channelErrors={ channelErrors={
updateChannelsOpts?.data?.productVariantChannelListingUpdate updateChannelsOpts?.data?.productVariantChannelListingUpdate
@ -351,9 +377,12 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
fetchMoreReferencePages={fetchMoreReferencePages} fetchMoreReferencePages={fetchMoreReferencePages}
fetchReferenceProducts={searchProducts} fetchReferenceProducts={searchProducts}
fetchMoreReferenceProducts={fetchMoreReferenceProducts} fetchMoreReferenceProducts={fetchMoreReferenceProducts}
fetchAttributeValues={searchAttributeValues}
fetchMoreAttributeValues={fetchMoreAttributeValues}
onCloseDialog={() => onCloseDialog={() =>
navigate(productVariantEditUrl(productId, variantId)) navigate(productVariantEditUrl(productId, variantId))
} }
onAttributeFocus={setFocusedAttribute}
/> />
<ProductVariantDeleteDialog <ProductVariantDeleteDialog
confirmButtonState={deleteVariantOpts.status} confirmButtonState={deleteVariantOpts.status}

View file

@ -11,6 +11,7 @@ import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import { useFileUploadMutation } from "@saleor/files/mutations"; import { useFileUploadMutation } from "@saleor/files/mutations";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import useAttributeValueSearch from "@saleor/searches/useAttributeValueSearch";
import usePageSearch from "@saleor/searches/usePageSearch"; import usePageSearch from "@saleor/searches/usePageSearch";
import useProductSearch from "@saleor/searches/useProductSearch"; import useProductSearch from "@saleor/searches/useProductSearch";
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler"; import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
@ -21,7 +22,7 @@ import {
} from "@saleor/utils/metadata/updateMetadata"; } from "@saleor/utils/metadata/updateMetadata";
import { useWarehouseList } from "@saleor/warehouses/queries"; import { useWarehouseList } from "@saleor/warehouses/queries";
import { warehouseAddPath } from "@saleor/warehouses/urls"; import { warehouseAddPath } from "@saleor/warehouses/urls";
import React from "react"; import React, { useState } from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { weight } from "../../misc"; import { weight } from "../../misc";
@ -62,7 +63,10 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
const { data, loading: productLoading } = useProductVariantCreateQuery({ const { data, loading: productLoading } = useProductVariantCreateQuery({
displayLoader: true, displayLoader: true,
variables: { id: productId } variables: {
id: productId,
firstValues: 10
}
}); });
const [uploadFile, uploadFileOpts] = useFileUploadMutation({}); const [uploadFile, uploadFileOpts] = useFileUploadMutation({});
@ -126,7 +130,8 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
})), })),
trackInventory: true, trackInventory: true,
weight: weight(formData.weight) weight: weight(formData.weight)
} },
firstValues: 10
} }
}); });
const id = result.data?.productVariantCreate?.productVariant?.id; const id = result.data?.productVariantCreate?.productVariant?.id;
@ -163,6 +168,18 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
} = useProductSearch({ } = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA variables: DEFAULT_INITIAL_SEARCH_DATA
}); });
const [focusedAttribute, setFocusedAttribute] = useState<string>();
const {
loadMore: loadMoreAttributeValues,
search: searchAttributeValues,
result: searchAttributeValuesOpts
} = useAttributeValueSearch({
variables: {
id: focusedAttribute,
...DEFAULT_INITIAL_SEARCH_DATA
},
skip: !focusedAttribute
});
const fetchMoreReferencePages = { const fetchMoreReferencePages = {
hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage,
@ -174,6 +191,16 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
loading: searchProductsOpts.loading, loading: searchProductsOpts.loading,
onFetchMore: loadMoreProducts onFetchMore: loadMoreProducts
}; };
const fetchMoreAttributeValues = {
hasMore: !!searchAttributeValuesOpts.data?.attribute?.choices?.pageInfo
?.hasNextPage,
loading: !!searchAttributeValuesOpts.loading,
onFetchMore: loadMoreAttributeValues
};
const attributeValues = mapEdgesToItems(
searchAttributeValuesOpts?.data?.attribute.choices
);
const disableForm = const disableForm =
productLoading || productLoading ||
@ -198,6 +225,7 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
description: "header" description: "header"
})} })}
product={data?.product} product={data?.product}
attributeValues={attributeValues}
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onVariantClick={handleVariantClick} onVariantClick={handleVariantClick}
@ -216,7 +244,10 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
fetchMoreReferencePages={fetchMoreReferencePages} fetchMoreReferencePages={fetchMoreReferencePages}
fetchReferenceProducts={searchProducts} fetchReferenceProducts={searchProducts}
fetchMoreReferenceProducts={fetchMoreReferenceProducts} fetchMoreReferenceProducts={fetchMoreReferenceProducts}
fetchAttributeValues={searchAttributeValues}
fetchMoreAttributeValues={fetchMoreAttributeValues}
onCloseDialog={() => navigate(productVariantAddUrl(productId))} onCloseDialog={() => navigate(productVariantAddUrl(productId))}
onAttributeFocus={setFocusedAttribute}
/> />
</> </>
); );

View file

@ -1,12 +1,14 @@
import { useShopLimitsQuery } from "@saleor/components/Shop/query"; import { useShopLimitsQuery } from "@saleor/components/Shop/query";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { useProductVariantBulkCreateMutation } from "@saleor/products/mutations"; import { useProductVariantBulkCreateMutation } from "@saleor/products/mutations";
import { useCreateMultipleVariantsData } from "@saleor/products/queries"; import { useCreateMultipleVariantsData } from "@saleor/products/queries";
import { productUrl } from "@saleor/products/urls"; import { productUrl } from "@saleor/products/urls";
import useAttributeValueSearch from "@saleor/searches/useAttributeValueSearch";
import { mapEdgesToItems } from "@saleor/utils/maps"; import { mapEdgesToItems } from "@saleor/utils/maps";
import React from "react"; import React, { useState } from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import ProductVariantCreatorPage from "../../components/ProductVariantCreatorPage"; import ProductVariantCreatorPage from "../../components/ProductVariantCreatorPage";
@ -23,7 +25,10 @@ const ProductVariantCreator: React.FC<ProductVariantCreatorProps> = ({
const intl = useIntl(); const intl = useIntl();
const { data } = useCreateMultipleVariantsData({ const { data } = useCreateMultipleVariantsData({
displayLoader: true, displayLoader: true,
variables: { id } variables: {
id,
firstValues: 10
}
}); });
const [ const [
bulkProductVariantCreate, bulkProductVariantCreate,
@ -48,6 +53,30 @@ const ProductVariantCreator: React.FC<ProductVariantCreatorProps> = ({
} }
}); });
const [focusedAttribute, setFocusedAttribute] = useState<string>();
const {
loadMore: loadMoreAttributeValues,
search: searchAttributeValues,
result: searchAttributeValuesOpts
} = useAttributeValueSearch({
variables: {
id: focusedAttribute,
...DEFAULT_INITIAL_SEARCH_DATA
},
skip: !focusedAttribute
});
const fetchMoreAttributeValues = {
hasMore: !!searchAttributeValuesOpts.data?.attribute?.choices?.pageInfo
?.hasNextPage,
loading: !!searchAttributeValuesOpts.loading,
onFetchMore: loadMoreAttributeValues
};
const attributeValues = mapEdgesToItems(
searchAttributeValuesOpts?.data?.attribute.choices
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -67,12 +96,10 @@ const ProductVariantCreator: React.FC<ProductVariantCreatorProps> = ({
name: listing.channel.name, name: listing.channel.name,
price: "" price: ""
}))} }))}
attributes={ attributes={data?.product?.productType?.variantAttributes || []}
data?.product?.productType?.variantAttributes?.map(attr => ({ attributeValues={attributeValues}
...attr, fetchAttributeValues={searchAttributeValues}
choices: attr.values fetchMoreAttributeValues={fetchMoreAttributeValues}
})) || []
}
limits={limitOpts.data?.shop?.limits} limits={limitOpts.data?.shop?.limits}
onSubmit={inputs => onSubmit={inputs =>
bulkProductVariantCreate({ bulkProductVariantCreate({
@ -80,6 +107,7 @@ const ProductVariantCreator: React.FC<ProductVariantCreatorProps> = ({
}) })
} }
warehouses={mapEdgesToItems(data?.warehouses)} warehouses={mapEdgesToItems(data?.warehouses)}
onAttributeFocus={setFocusedAttribute}
/> />
</> </>
); );

File diff suppressed because it is too large Load diff

View file

@ -56,7 +56,7 @@ storiesOf("Views / Products / Create product", module)
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onSelectProductType={() => undefined} onSelectProductType={() => undefined}
onAttributeSelect={() => undefined} onAttributeFocus={() => undefined}
/> />
)) ))
.add("When loading", () => ( .add("When loading", () => (
@ -93,7 +93,7 @@ storiesOf("Views / Products / Create product", module)
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onSelectProductType={() => undefined} onSelectProductType={() => undefined}
onAttributeSelect={() => undefined} onAttributeFocus={() => undefined}
/> />
)) ))
.add("form errors", () => ( .add("form errors", () => (
@ -145,6 +145,6 @@ storiesOf("Views / Products / Create product", module)
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onSelectProductType={() => undefined} onSelectProductType={() => undefined}
onAttributeSelect={() => undefined} onAttributeFocus={() => undefined}
/> />
)); ));

View file

@ -70,7 +70,7 @@ const props: ProductUpdatePageProps = {
onVariantsAdd: () => undefined, onVariantsAdd: () => undefined,
onWarehouseConfigure: () => undefined, onWarehouseConfigure: () => undefined,
openChannelsModal: () => undefined, openChannelsModal: () => undefined,
onAttributeSelect: () => undefined, onAttributeFocus: () => undefined,
placeholderImage, placeholderImage,
product, product,
referencePages: [], referencePages: [],

View file

@ -36,8 +36,11 @@ storiesOf("Views / Products / Create product variant", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)) ))
.add("with errors", () => ( .add("with errors", () => (
@ -76,8 +79,11 @@ storiesOf("Views / Products / Create product variant", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)) ))
.add("when loading data", () => ( .add("when loading data", () => (
@ -97,8 +103,11 @@ storiesOf("Views / Products / Create product variant", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)) ))
.add("add first variant", () => ( .add("add first variant", () => (
@ -121,8 +130,11 @@ storiesOf("Views / Products / Create product variant", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)) ))
.add("no warehouses", () => ( .add("no warehouses", () => (
@ -142,7 +154,10 @@ storiesOf("Views / Products / Create product variant", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)); ));

View file

@ -35,8 +35,11 @@ storiesOf("Views / Products / Product variant details", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)) ))
.add("when loading data", () => ( .add("when loading data", () => (
@ -61,8 +64,11 @@ storiesOf("Views / Products / Product variant details", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)) ))
.add("no warehouses", () => ( .add("no warehouses", () => (
@ -86,8 +92,11 @@ storiesOf("Views / Products / Product variant details", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)) ))
.add("attribute errors", () => ( .add("attribute errors", () => (
@ -139,7 +148,10 @@ storiesOf("Views / Products / Product variant details", module)
onWarehouseConfigure={() => undefined} onWarehouseConfigure={() => undefined}
referencePages={[]} referencePages={[]}
referenceProducts={[]} referenceProducts={[]}
attributeValues={[]}
fetchAttributeValues={() => undefined}
onAssignReferencesClick={() => undefined} onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined} onCloseDialog={() => undefined}
onAttributeFocus={() => undefined}
/> />
)); ));