diff --git a/cypress/apiRequests/Attribute.js b/cypress/apiRequests/Attribute.js index 1ea732286..b25cd9380 100644 --- a/cypress/apiRequests/Attribute.js +++ b/cypress/apiRequests/Attribute.js @@ -10,7 +10,13 @@ export function createAttribute(name, attributeValues = ["value"]) { attribute{ id name - values{name} + choices(first: 100){ + edges{ + node{ + name + } + } + } } attributeErrors{ field diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index abada90d7..acd8a4cfb 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -5643,6 +5643,10 @@ "context": "variant name", "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": { "context": "button", "string": "Delete variant" diff --git a/src/attributes/urls.ts b/src/attributes/urls.ts index b73292eea..9e498a6d9 100644 --- a/src/attributes/urls.ts +++ b/src/attributes/urls.ts @@ -60,8 +60,7 @@ export type AttributeUrlDialog = | "remove" | "remove-value" | "remove-values"; -export type AttributeUrlQueryParams = Pagination & - BulkAction & +export type AttributeUrlQueryParams = BulkAction & Dialog & SingleAction; export const attributePath = (id: string) => urlJoin(attributeSection, id); diff --git a/src/attributes/views/AttributeDetails/AttributeDetails.tsx b/src/attributes/views/AttributeDetails/AttributeDetails.tsx index d538af9eb..9f47dde4c 100644 --- a/src/attributes/views/AttributeDetails/AttributeDetails.tsx +++ b/src/attributes/views/AttributeDetails/AttributeDetails.tsx @@ -1,9 +1,9 @@ import useListSettings from "@saleor/hooks/useListSettings"; +import useLocalPaginator, { + useLocalPaginationState +} from "@saleor/hooks/useLocalPaginator"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; -import usePaginator, { - createPaginationState -} from "@saleor/hooks/usePaginator"; import { commonMessages } from "@saleor/intl"; import { maybe } from "@saleor/misc"; import { ListViews, ReorderEvent } from "@saleor/types"; @@ -47,7 +47,6 @@ interface AttributeDetailsProps { const AttributeDetails: React.FC = ({ id, params }) => { const navigate = useNavigator(); - const paginate = usePaginator(); const notify = useNotifier(); const intl = useIntl(); const [updateMetadata] = useMetadataUpdate({}); @@ -62,20 +61,26 @@ const AttributeDetails: React.FC = ({ id, params }) => { ListViews.ATTRIBUTE_VALUE_LIST ); + const [ + valuesPaginationState, + setValuesPaginationState + ] = useLocalPaginationState(settings?.rowNumber); + const { data, loading } = useAttributeDetailsQuery({ variables: { id, - firstValues: settings?.rowNumber, - afterValues: params.after + firstValues: valuesPaginationState.first, + lastValues: valuesPaginationState.last, + afterValues: valuesPaginationState.after, + beforeValues: valuesPaginationState.before }, skip: !settings }); - const paginationState = createPaginationState(settings?.rowNumber, params); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( + const paginateValues = useLocalPaginator(setValuesPaginationState); + const { loadNextPage, loadPreviousPage, pageInfo } = paginateValues( data?.attribute?.choices?.pageInfo, - paginationState, - params + valuesPaginationState ); const [attributeDelete, attributeDeleteOpts] = useAttributeDeleteMutation({ @@ -197,8 +202,10 @@ const AttributeDetails: React.FC = ({ id, params }) => { id: data.attribute.choices.edges[oldIndex].node.id, sortOrder: newIndex - oldIndex }, - firstValues: settings.rowNumber, - afterValues: params.after + firstValues: valuesPaginationState.first, + lastValues: valuesPaginationState.last, + afterValues: valuesPaginationState.after, + beforeValues: valuesPaginationState.before } }); @@ -288,8 +295,10 @@ const AttributeDetails: React.FC = ({ id, params }) => { attributeValueDelete({ variables: { id: params.id, - firstValues: settings.rowNumber, - afterValues: params.after + firstValues: valuesPaginationState.first, + lastValues: valuesPaginationState.last, + afterValues: valuesPaginationState.after, + beforeValues: valuesPaginationState.before } }) } @@ -308,8 +317,10 @@ const AttributeDetails: React.FC = ({ id, params }) => { variables: { id, input, - firstValues: settings.rowNumber, - afterValues: params.after + firstValues: valuesPaginationState.first, + lastValues: valuesPaginationState.last, + afterValues: valuesPaginationState.after, + beforeValues: valuesPaginationState.before } }) } @@ -335,8 +346,10 @@ const AttributeDetails: React.FC = ({ id, params }) => { value => params.id === value.node.id ).node.id, input, - firstValues: settings.rowNumber, - afterValues: params.after + firstValues: valuesPaginationState.first, + lastValues: valuesPaginationState.last, + afterValues: valuesPaginationState.after, + beforeValues: valuesPaginationState.before } }) } diff --git a/src/components/Attributes/AttributeRow.tsx b/src/components/Attributes/AttributeRow.tsx index fbe99e2d5..bc124a401 100644 --- a/src/components/Attributes/AttributeRow.tsx +++ b/src/components/Attributes/AttributeRow.tsx @@ -57,7 +57,7 @@ export interface AttributeRowHandlers { onReferencesReorder: FormsetChange; fetchAttributeValues: (query: string) => void; fetchMoreAttributeValues: FetchMoreProps; - onAttributeSelect: (id: string) => void; + onAttributeFocus: (id: string) => void; } interface AttributeRowProps extends AttributeRowHandlers { @@ -82,7 +82,7 @@ const AttributeRow: React.FC = ({ onChange, fetchAttributeValues, fetchMoreAttributeValues, - onAttributeSelect + onAttributeFocus }) => { const intl = useIntl(); const classes = useStyles({}); @@ -149,7 +149,7 @@ const AttributeRow: React.FC = ({ allowCustomValues={true} fetchChoices={fetchAttributeValues} {...fetchMoreAttributeValues} - onClick={() => onAttributeSelect(attribute.id)} + onFocus={() => onAttributeFocus(attribute.id)} /> ); @@ -211,7 +211,7 @@ const AttributeRow: React.FC = ({ allowCustomValues={true} fetchChoices={fetchAttributeValues} {...fetchMoreAttributeValues} - onClick={() => onAttributeSelect(attribute.id)} + onFocus={() => onAttributeFocus(attribute.id)} /> ); diff --git a/src/components/Attributes/Attributes.stories.tsx b/src/components/Attributes/Attributes.stories.tsx index 5f35f9d7f..e77a52bd3 100644 --- a/src/components/Attributes/Attributes.stories.tsx +++ b/src/components/Attributes/Attributes.stories.tsx @@ -18,7 +18,7 @@ const props: AttributesProps = { onReferencesAddClick: () => undefined, onReferencesRemove: () => undefined, onReferencesReorder: () => undefined, - onAttributeSelect: () => undefined, + onAttributeFocus: () => undefined, fetchAttributeValues: () => undefined, fetchMoreAttributeValues: fetchMoreProps }; diff --git a/src/components/Attributes/Attributes.tsx b/src/components/Attributes/Attributes.tsx index ca90268e1..05f448059 100644 --- a/src/components/Attributes/Attributes.tsx +++ b/src/components/Attributes/Attributes.tsx @@ -44,7 +44,7 @@ export interface AttributesProps extends AttributeRowHandlers { ProductErrorWithAttributesFragment | PageErrorWithAttributesFragment >; title?: React.ReactNode; - onAttributeSelect: (id: string) => void; + onAttributeFocus: (id: string) => void; } const useStyles = makeStyles( diff --git a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx index 47ab95654..69c101406 100644 --- a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx +++ b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx @@ -85,7 +85,7 @@ export interface MultiAutocompleteSelectFieldProps testId?: string; fetchChoices?: (value: string) => void; onChange: (event: React.ChangeEvent) => void; - onClick?: () => void; + onFocus?: () => void; } const DebounceAutocomplete: React.ComponentType ), id: undefined, - onClick: (cb: () => void) => { - toggleMenu(cb); - if (onClick) { - onClick(); + onClick: toggleMenu, + onFocus: () => { + if (onFocus) { + onFocus(); } } }} diff --git a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx index e15c6cd54..9daac63ef 100644 --- a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx +++ b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx @@ -46,7 +46,7 @@ export interface SingleAutocompleteSelectFieldProps InputProps?: InputProps; fetchChoices?: (value: string) => void; onChange: (event: React.ChangeEvent) => void; - onClick?: () => void; + onFocus?: () => void; FormHelperTextProps?: ExtendedFormHelperTextProps; nakedInput?: boolean; } @@ -76,7 +76,7 @@ const SingleAutocompleteSelectFieldComponent: React.FC void) => { - toggleMenu(cb); - if (onClick) { - onClick(); + onClick: toggleMenu, + onFocus: () => { + if (onFocus) { + onFocus(); } } }; diff --git a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx index 5304112fe..df244f096 100644 --- a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx +++ b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx @@ -151,7 +151,8 @@ const SingleAutocompleteSelectFieldContent: React.FC(); const scrollPosition = useElementScroll(anchor); 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); @@ -159,20 +160,27 @@ const SingleAutocompleteSelectFieldContent: React.FC slice + sliceSize); } }, [scrolledToBottom]); React.useEffect(() => { - setSlice(sliceSize); - if (anchor.current?.scrollTo) { + if (!onFetchMore) { + setSlice(sliceSize); + } + if (anchor.current?.scrollTo && !initialized) { anchor.current.scrollTo({ top: 0 }); + setInitialized(true); } }, [choices?.length]); + React.useEffect(() => { + setInitialized(false); + }, [inputValue]); + React.useEffect(() => { if (calledForMore && !loading) { setCalledForMore(false); @@ -183,6 +191,8 @@ const SingleAutocompleteSelectFieldContent: React.FC
0 && (!!add || displayCustomValue) && (
)} - {choices.slice(0, slice).map((suggestion, index) => { + {choicesToDisplay.map((suggestion, index) => { const choiceIndex = getChoiceIndex( index, emptyOption, diff --git a/src/fragments/products.ts b/src/fragments/products.ts index 7857d62b3..b8138c007 100644 --- a/src/fragments/products.ts +++ b/src/fragments/products.ts @@ -246,6 +246,7 @@ export const productFragmentDetails = gql` `; export const variantAttributeFragment = gql` + ${attributeValueListFragment} fragment VariantAttributeFragment on Attribute { id name @@ -254,14 +255,14 @@ export const variantAttributeFragment = gql` entityType valueRequired unit - # values( - # first: $firstValues - # after: $afterValues - # last: $lastValues - # before: $beforeValues - # ) { - # ...AttributeValueListFragment - # } + choices( + first: $firstValues + after: $afterValues + last: $lastValues + before: $beforeValues + ) { + ...AttributeValueListFragment + } } `; diff --git a/src/fragments/types/ProductVariant.ts b/src/fragments/types/ProductVariant.ts index a088dd98c..46d61cd0e 100644 --- a/src/fragments/types/ProductVariant.ts +++ b/src/fragments/types/ProductVariant.ts @@ -21,7 +21,7 @@ export interface ProductVariant_privateMetadata { value: string; } -export interface ProductVariant_selectionAttributes_attribute_values_pageInfo { +export interface ProductVariant_selectionAttributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -29,32 +29,32 @@ export interface ProductVariant_selectionAttributes_attribute_values_pageInfo { startCursor: string | null; } -export interface ProductVariant_selectionAttributes_attribute_values_edges_node_file { +export interface ProductVariant_selectionAttributes_attribute_choices_edges_node_file { __typename: "File"; url: string; contentType: string | null; } -export interface ProductVariant_selectionAttributes_attribute_values_edges_node { +export interface ProductVariant_selectionAttributes_attribute_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface ProductVariant_selectionAttributes_attribute_values_edges { +export interface ProductVariant_selectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: ProductVariant_selectionAttributes_attribute_values_pageInfo; - edges: ProductVariant_selectionAttributes_attribute_values_edges[]; + pageInfo: ProductVariant_selectionAttributes_attribute_choices_pageInfo; + edges: ProductVariant_selectionAttributes_attribute_choices_edges[]; } export interface ProductVariant_selectionAttributes_attribute { @@ -66,7 +66,7 @@ export interface ProductVariant_selectionAttributes_attribute { entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: ProductVariant_selectionAttributes_attribute_values | null; + choices: ProductVariant_selectionAttributes_attribute_choices | null; } export interface ProductVariant_selectionAttributes_values_file { @@ -91,7 +91,7 @@ export interface ProductVariant_selectionAttributes { values: (ProductVariant_selectionAttributes_values | null)[]; } -export interface ProductVariant_nonSelectionAttributes_attribute_values_pageInfo { +export interface ProductVariant_nonSelectionAttributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -99,32 +99,32 @@ export interface ProductVariant_nonSelectionAttributes_attribute_values_pageInfo startCursor: string | null; } -export interface ProductVariant_nonSelectionAttributes_attribute_values_edges_node_file { +export interface ProductVariant_nonSelectionAttributes_attribute_choices_edges_node_file { __typename: "File"; url: string; contentType: string | null; } -export interface ProductVariant_nonSelectionAttributes_attribute_values_edges_node { +export interface ProductVariant_nonSelectionAttributes_attribute_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface ProductVariant_nonSelectionAttributes_attribute_values_edges { +export interface ProductVariant_nonSelectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: ProductVariant_nonSelectionAttributes_attribute_values_pageInfo; - edges: ProductVariant_nonSelectionAttributes_attribute_values_edges[]; + pageInfo: ProductVariant_nonSelectionAttributes_attribute_choices_pageInfo; + edges: ProductVariant_nonSelectionAttributes_attribute_choices_edges[]; } export interface ProductVariant_nonSelectionAttributes_attribute { @@ -136,7 +136,7 @@ export interface ProductVariant_nonSelectionAttributes_attribute { entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: ProductVariant_nonSelectionAttributes_attribute_values | null; + choices: ProductVariant_nonSelectionAttributes_attribute_choices | null; } export interface ProductVariant_nonSelectionAttributes_values_file { diff --git a/src/fragments/types/SelectedVariantAttributeFragment.ts b/src/fragments/types/SelectedVariantAttributeFragment.ts index 7587baae7..0ebf21329 100644 --- a/src/fragments/types/SelectedVariantAttributeFragment.ts +++ b/src/fragments/types/SelectedVariantAttributeFragment.ts @@ -9,7 +9,7 @@ import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } // GraphQL fragment: SelectedVariantAttributeFragment // ==================================================== -export interface SelectedVariantAttributeFragment_attribute_values_pageInfo { +export interface SelectedVariantAttributeFragment_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -17,32 +17,32 @@ export interface SelectedVariantAttributeFragment_attribute_values_pageInfo { startCursor: string | null; } -export interface SelectedVariantAttributeFragment_attribute_values_edges_node_file { +export interface SelectedVariantAttributeFragment_attribute_choices_edges_node_file { __typename: "File"; url: string; contentType: string | null; } -export interface SelectedVariantAttributeFragment_attribute_values_edges_node { +export interface SelectedVariantAttributeFragment_attribute_choices_edges_node { __typename: "AttributeValue"; id: string; name: string | null; slug: string | null; - file: SelectedVariantAttributeFragment_attribute_values_edges_node_file | null; + file: SelectedVariantAttributeFragment_attribute_choices_edges_node_file | null; reference: string | null; richText: any | null; } -export interface SelectedVariantAttributeFragment_attribute_values_edges { +export interface SelectedVariantAttributeFragment_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: SelectedVariantAttributeFragment_attribute_values_pageInfo; - edges: SelectedVariantAttributeFragment_attribute_values_edges[]; + pageInfo: SelectedVariantAttributeFragment_attribute_choices_pageInfo; + edges: SelectedVariantAttributeFragment_attribute_choices_edges[]; } export interface SelectedVariantAttributeFragment_attribute { @@ -54,7 +54,7 @@ export interface SelectedVariantAttributeFragment_attribute { entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: SelectedVariantAttributeFragment_attribute_values | null; + choices: SelectedVariantAttributeFragment_attribute_choices | null; } export interface SelectedVariantAttributeFragment_values_file { diff --git a/src/fragments/types/VariantAttributeFragment.ts b/src/fragments/types/VariantAttributeFragment.ts index 5564a022c..3675ec68d 100644 --- a/src/fragments/types/VariantAttributeFragment.ts +++ b/src/fragments/types/VariantAttributeFragment.ts @@ -9,7 +9,7 @@ import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } // GraphQL fragment: VariantAttributeFragment // ==================================================== -export interface VariantAttributeFragment_values_pageInfo { +export interface VariantAttributeFragment_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -17,32 +17,32 @@ export interface VariantAttributeFragment_values_pageInfo { startCursor: string | null; } -export interface VariantAttributeFragment_values_edges_node_file { +export interface VariantAttributeFragment_choices_edges_node_file { __typename: "File"; url: string; contentType: string | null; } -export interface VariantAttributeFragment_values_edges_node { +export interface VariantAttributeFragment_choices_edges_node { __typename: "AttributeValue"; id: string; name: string | null; slug: string | null; - file: VariantAttributeFragment_values_edges_node_file | null; + file: VariantAttributeFragment_choices_edges_node_file | null; reference: string | null; richText: any | null; } -export interface VariantAttributeFragment_values_edges { +export interface VariantAttributeFragment_choices_edges { __typename: "AttributeValueCountableEdge"; cursor: string; - node: VariantAttributeFragment_values_edges_node; + node: VariantAttributeFragment_choices_edges_node; } -export interface VariantAttributeFragment_values { +export interface VariantAttributeFragment_choices { __typename: "AttributeValueCountableConnection"; - pageInfo: VariantAttributeFragment_values_pageInfo; - edges: VariantAttributeFragment_values_edges[]; + pageInfo: VariantAttributeFragment_choices_pageInfo; + edges: VariantAttributeFragment_choices_edges[]; } export interface VariantAttributeFragment { @@ -54,5 +54,5 @@ export interface VariantAttributeFragment { entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: VariantAttributeFragment_values | null; + choices: VariantAttributeFragment_choices | null; } diff --git a/src/hooks/useLocalPaginator.ts b/src/hooks/useLocalPaginator.ts new file mode 100644 index 000000000..cd81a0244 --- /dev/null +++ b/src/hooks/useLocalPaginator.ts @@ -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({ + 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; diff --git a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx index 9008e4c82..705137222 100644 --- a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx +++ b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx @@ -167,7 +167,7 @@ const PageDetailsPage: React.FC = ({ onReferencesReorder={handlers.reorderAttributeValue} fetchAttributeValues={() => undefined} fetchMoreAttributeValues={undefined} - onAttributeSelect={() => undefined} + onAttributeFocus={() => undefined} /> )} diff --git a/src/products/components/ProductCreatePage/ProductCreatePage.tsx b/src/products/components/ProductCreatePage/ProductCreatePage.tsx index 619a072ed..6634da830 100644 --- a/src/products/components/ProductCreatePage/ProductCreatePage.tsx +++ b/src/products/components/ProductCreatePage/ProductCreatePage.tsx @@ -75,7 +75,7 @@ interface ProductCreatePageProps { fetchCollections: (data: string) => void; fetchProductTypes: (data: string) => void; fetchAttributeValues: (query: string) => void; - onAttributeSelect: (id: string) => void; + onAttributeFocus: (id: string) => void; onWarehouseConfigure: () => void; openChannelsModal: () => void; onChannelsChange: (data: ChannelData[]) => void; @@ -131,7 +131,7 @@ export const ProductCreatePage: React.FC = ({ fetchMoreAttributeValues, onCloseDialog, onSelectProductType, - onAttributeSelect + onAttributeFocus }: ProductCreatePageProps) => { const intl = useIntl(); @@ -243,7 +243,7 @@ export const ProductCreatePage: React.FC = ({ onReferencesReorder={handlers.reorderAttributeValue} fetchAttributeValues={fetchAttributeValues} fetchMoreAttributeValues={fetchMoreAttributeValues} - onAttributeSelect={onAttributeSelect} + onAttributeFocus={onAttributeFocus} /> )} diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx index 125a2aa94..aa02d07da 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx @@ -60,7 +60,7 @@ const props: ProductUpdatePageProps = { onVariantsAdd: () => undefined, onWarehouseConfigure: () => undefined, openChannelsModal: () => undefined, - onAttributeSelect: () => undefined, + onAttributeFocus: () => undefined, placeholderImage, product, referencePages: [], diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx index 96c6a629c..a78845504 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx @@ -102,7 +102,7 @@ export interface ProductUpdatePageProps extends ListActions, ChannelProps { fetchReferencePages?: (data: string) => void; fetchReferenceProducts?: (data: string) => void; fetchAttributeValues: (query: string) => void; - onAttributeSelect: (id: string) => void; + onAttributeFocus: (id: string) => void; onAssignReferencesClick: (attribute: AttributeInput) => void; onCloseDialog: () => void; onVariantsAdd: () => void; @@ -196,7 +196,7 @@ export const ProductUpdatePage: React.FC = ({ onCloseDialog, channelsWithVariantsData, onChannelsChange, - onAttributeSelect + onAttributeFocus }) => { const intl = useIntl(); @@ -319,7 +319,7 @@ export const ProductUpdatePage: React.FC = ({ onReferencesReorder={handlers.reorderAttributeValue} fetchAttributeValues={fetchAttributeValues} fetchMoreAttributeValues={fetchMoreAttributeValues} - onAttributeSelect={onAttributeSelect} + onAttributeFocus={onAttributeFocus} /> )} diff --git a/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx b/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx index 0ece21354..40d5705ea 100644 --- a/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx +++ b/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx @@ -8,8 +8,8 @@ import SingleAutocompleteSelectField, { import Skeleton from "@saleor/components/Skeleton"; import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment"; import { - ProductVariant_nonSelectionAttributes_attribute_values_edges, - ProductVariant_selectionAttributes_attribute_values_edges + ProductVariant_nonSelectionAttributes_attribute_choices_edges, + ProductVariant_selectionAttributes_attribute_choices_edges } from "@saleor/fragments/types/ProductVariant"; import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset"; import { commonMessages } from "@saleor/intl"; @@ -19,8 +19,8 @@ import { useIntl } from "react-intl"; export interface VariantAttributeInputData { values: Array< - | ProductVariant_selectionAttributes_attribute_values_edges - | ProductVariant_nonSelectionAttributes_attribute_values_edges + | ProductVariant_selectionAttributes_attribute_choices_edges + | ProductVariant_nonSelectionAttributes_attribute_choices_edges >; } export type VariantAttributeInput = FormsetAtomicData< diff --git a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx index 7937f781a..1f4989fe7 100644 --- a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx +++ b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx @@ -17,6 +17,7 @@ import Metadata from "@saleor/components/Metadata"; import PageHeader from "@saleor/components/PageHeader"; import SaveButtonBar from "@saleor/components/SaveButtonBar"; 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 { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; @@ -69,6 +70,7 @@ interface ProductVariantCreatePageProps { weightUnit: string; referencePages?: SearchPages_search_edges_node[]; referenceProducts?: SearchProducts_search_edges_node[]; + attributeValues: SearchAttributeValues_attribute_choices_edges_node[]; onBack: () => void; onSubmit: (data: ProductVariantCreateData) => void; onVariantClick: (variantId: string) => void; @@ -76,10 +78,13 @@ interface ProductVariantCreatePageProps { onWarehouseConfigure: () => void; assignReferencesAttributeId?: string; onAssignReferencesClick: (attribute: AttributeInput) => void; + onAttributeFocus: (id: string) => void; fetchReferencePages?: (data: string) => void; fetchReferenceProducts?: (data: string) => void; + fetchAttributeValues: (query: string) => void; fetchMoreReferencePages?: FetchMoreProps; fetchMoreReferenceProducts?: FetchMoreProps; + fetchMoreAttributeValues?: FetchMoreProps; onCloseDialog: () => void; } @@ -94,17 +99,21 @@ const ProductVariantCreatePage: React.FC = ({ weightUnit, referencePages = [], referenceProducts = [], + attributeValues, onBack, onSubmit, onVariantClick, onVariantReorder, onWarehouseConfigure, + onAttributeFocus, assignReferencesAttributeId, onAssignReferencesClick, fetchReferencePages, fetchReferenceProducts, + fetchAttributeValues, fetchMoreReferencePages, fetchMoreReferenceProducts, + fetchMoreAttributeValues, onCloseDialog }) => { const intl = useIntl(); @@ -173,7 +182,7 @@ const ProductVariantCreatePage: React.FC = ({ attribute.data.variantAttributeScope === VariantAttributeScope.NOT_VARIANT_SELECTION )} - attributeValues={[]} + attributeValues={attributeValues} loading={disabled} disabled={disabled} errors={errors} @@ -183,9 +192,9 @@ const ProductVariantCreatePage: React.FC = ({ onReferencesRemove={handlers.selectAttributeReference} onReferencesAddClick={onAssignReferencesClick} onReferencesReorder={handlers.reorderAttributeValue} - fetchAttributeValues={() => undefined} - fetchMoreAttributeValues={undefined} - onAttributeSelect={() => undefined} + fetchAttributeValues={fetchAttributeValues} + fetchMoreAttributeValues={fetchMoreAttributeValues} + onAttributeFocus={onAttributeFocus} /> = ({ attribute.data.variantAttributeScope === VariantAttributeScope.VARIANT_SELECTION )} - attributeValues={[]} + attributeValues={attributeValues} loading={disabled} disabled={disabled} errors={errors} @@ -205,9 +214,9 @@ const ProductVariantCreatePage: React.FC = ({ onReferencesRemove={handlers.selectAttributeReference} onReferencesAddClick={onAssignReferencesClick} onReferencesReorder={handlers.reorderAttributeValue} - fetchAttributeValues={() => undefined} - fetchMoreAttributeValues={undefined} - onAttributeSelect={() => undefined} + fetchAttributeValues={fetchAttributeValues} + fetchMoreAttributeValues={fetchMoreAttributeValues} + onAttributeFocus={onAttributeFocus} /> ({ id: attribute.id, values: attribute.choices.edges - .map(value => value.node.slug) + .map(value => ({ + slug: value.node.slug, + value: value.node + })) .filter((_, valueIndex) => valueIndex % 2 !== 1) })); @@ -89,6 +92,9 @@ const data: ProductVariantCreateFormData = { }; const props: ProductVariantCreatorContentProps = { attributes: [0, 1, 4, 6].map(index => attributes[index]), + attributeValues: [], + fetchAttributeValues: () => undefined, + fetchMoreAttributeValues: fetchMoreProps, channelListings: productChannels.map(listing => ({ currency: listing.pricing?.priceRange?.start?.net.currency, id: listing.channel.id, @@ -103,7 +109,8 @@ const props: ProductVariantCreatorContentProps = { errors: [], variantsLeft: 6, step: ProductVariantCreatorStep.values, - warehouses: warehouseList + warehouses: warehouseList, + onAttributeFocus: () => undefined }; storiesOf("Views / Products / Create multiple variants", module) diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx index be56ed6d2..758699c84 100644 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx @@ -2,6 +2,8 @@ import { ChannelPriceData } from "@saleor/channels/utils"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails"; 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 React from "react"; @@ -17,6 +19,7 @@ import { ProductVariantCreatorStep } from "./types"; export interface ProductVariantCreatorContentProps { attributes: ProductDetails_product_productType_variantAttributes[]; + attributeValues: SearchAttributeValues_attribute_choices_edges_node[]; channelListings: ChannelPriceData[]; data: ProductVariantCreateFormData; dispatchFormDataAction: React.Dispatch; @@ -24,17 +27,24 @@ export interface ProductVariantCreatorContentProps { step: ProductVariantCreatorStep; variantsLeft: number | null; warehouses: WarehouseFragment[]; + fetchAttributeValues: (query: string) => void; + fetchMoreAttributeValues?: FetchMoreProps; + onAttributeFocus: (id: string) => void; } const ProductVariantCreatorContent: React.FC = ({ attributes, + attributeValues, + fetchAttributeValues, + fetchMoreAttributeValues, channelListings, data, dispatchFormDataAction, errors, step, variantsLeft, - warehouses + warehouses, + onAttributeFocus }) => { const selectedAttributes = attributes.filter(attribute => isSelected( @@ -49,17 +59,21 @@ const ProductVariantCreatorContent: React.FC {step === ProductVariantCreatorStep.values && ( + onValueClick={(attributeId, value) => dispatchFormDataAction({ selectValue: { attributeId, - valueId + value }, type: ProductVariantCreateReducerActionType.selectValue }) } + onAttributeFocus={onAttributeFocus} /> )} {step === ProductVariantCreatorStep.prices && ( diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPage.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPage.tsx index 287541f67..4af4c8a81 100644 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPage.tsx +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPage.tsx @@ -1,4 +1,5 @@ import { Button, Typography } from "@material-ui/core"; +import { drawerWidthExpanded } from "@saleor/components/AppLayout/consts"; import Container from "@saleor/components/Container"; import Hr from "@saleor/components/Hr"; import PageHeader from "@saleor/components/PageHeader"; @@ -28,8 +29,13 @@ const useStyles = makeStyles( }, content: { overflowX: "visible", - overflowY: "hidden", - width: 800 + [theme.breakpoints.up("md")]: { + position: "absolute", + width: `calc(100vw - ${drawerWidthExpanded}px + ${theme.spacing(6)}px)`, + maxWidth: `calc(${theme.breakpoints.width("lg")}px - ${theme.spacing( + 6 + )}px)` + } }, description: { marginTop: theme.spacing() @@ -185,7 +191,7 @@ const ProductVariantCreatePage: React.FC = props React.useEffect(reloadForm, [attributes.length, warehouses.length]); - const variantsLeft = limits.allowedUsage.productVariants + const variantsLeft = limits?.allowedUsage.productVariants ? limits.allowedUsage.productVariants - limits.currentUsage.productVariants : null; @@ -237,17 +243,19 @@ const ProductVariantCreatePage: React.FC = props )}
- +
+ +
); }; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorSummary.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorSummary.tsx index 416a6ff51..fe2568404 100644 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorSummary.tsx +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorSummary.tsx @@ -20,7 +20,7 @@ import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { ProductDetails_product_productType_variantAttributes } from "../../types/ProductDetails"; -import { ChannelPrice, ProductVariantCreateFormData } from "./form"; +import { Attribute, ChannelPrice, ProductVariantCreateFormData } from "./form"; export interface ProductVariantCreatorSummaryProps { attributes: ProductDetails_product_productType_variantAttributes[]; @@ -113,18 +113,18 @@ const useStyles = makeStyles( function getVariantName( variant: ProductVariantBulkCreateInput, - attributes: ProductDetails_product_productType_variantAttributes[] + attributes: Attribute[] ): string[] { return attributes.reduce( (acc, attribute) => [ ...acc, - attribute.choices.edges.find( + attribute.values?.find( value => - value.node.slug === + value?.slug === variant.attributes.find( variantAttribute => variantAttribute.id === attribute.id ).values[0] - ).node.name + )?.value?.name ], [] ); @@ -132,7 +132,6 @@ function getVariantName( const ProductVariantCreatorSummary: React.FC = props => { const { - attributes, channelListings, data, errors, @@ -220,7 +219,7 @@ const ProductVariantCreatorSummary: React.FC .join(":")} >
- {getVariantName(variant, attributes).map( + {getVariantName(variant, data.attributes).map( (value, valueIndex) => ( void; +export function getMultiValues( + attributes: Attribute[], + attribute: ProductDetails_product_productType_variantAttributes +) { + return attributes + .find(getById(attribute.id)) + ?.values?.map(value => value.slug); } -const useStyles = makeStyles( - theme => ({ - valueContainer: { - display: "grid", - gridColumnGap: theme.spacing(3), - gridTemplateColumns: "repeat(5, 1fr)" - } - }), - { name: "ProductVariantCreatorValues" } -); +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 { + attributes: ProductDetails_product_productType_variantAttributes[]; + attributeValues: SearchAttributeValues_attribute_choices_edges_node[]; + fetchAttributeValues: (query: string) => void; + fetchMoreAttributeValues?: FetchMoreProps; + data: ProductVariantCreateFormData; + variantsLeft: number | null; + onValueClick: ( + attributeId: string, + value: AttributeValue + ) => void; + onAttributeFocus: (id: string) => void; +} const ProductVariantCreatorValues: React.FC = props => { - const { attributes, data, variantsLeft, onValueClick } = props; - const classes = useStyles(props); + const { + attributes, + attributeValues, + fetchAttributeValues, + fetchMoreAttributeValues, + data, + variantsLeft, + onValueClick, + onAttributeFocus + } = props; const intl = useIntl(); 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 ( <> {variantsLeft !== null && ( @@ -67,32 +114,24 @@ const ProductVariantCreatorValues: React.FC = } /> - - {attribute.choices.edges.map(({ node: value }) => ( - onValueClick(attribute.id, value.slug)} - time={100} - key={value.slug} - > - {change => ( - attribute.id === dataAttribute.id - )?.values || [], - (a, b) => a === b - )} - name={`value:${value.slug}`} - label={value.name} - onChange={change} - /> - )} - - ))} + + + handleValueClick(attribute.id, event.target.value) + } + allowCustomValues={true} + fetchChoices={fetchAttributeValues} + {...fetchMoreAttributeValues} + onFocus={() => onAttributeFocus(attribute.id)} + /> diff --git a/src/products/components/ProductVariantCreatorPage/__snapshots__/reducer.test.ts.snap b/src/products/components/ProductVariantCreatorPage/__snapshots__/reducer.test.ts.snap index 1609ff601..12c22fc2a 100644 --- a/src/products/components/ProductVariantCreatorPage/__snapshots__/reducer.test.ts.snap +++ b/src/products/components/ProductVariantCreatorPage/__snapshots__/reducer.test.ts.snap @@ -6,22 +6,88 @@ Object { Object { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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 { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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 { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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 { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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 { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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 { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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 { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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 { "id": "attr-1", "values": Array [ - "val-1-1", - "val-1-7", + Object { + "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 { "id": "attr-2", "values": Array [ - "val-2-2", - "val-2-4", + Object { + "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 { "id": "attr-4", "values": Array [ - "val-4-1", - "val-4-5", + Object { + "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", + }, + }, ], }, ], diff --git a/src/products/components/ProductVariantCreatorPage/createVariants.test.ts b/src/products/components/ProductVariantCreatorPage/createVariants.test.ts index 6eed8d71d..478e8bfae 100644 --- a/src/products/components/ProductVariantCreatorPage/createVariants.test.ts +++ b/src/products/components/ProductVariantCreatorPage/createVariants.test.ts @@ -63,7 +63,7 @@ describe("Creates variant matrix", () => { attribute: attribute.id, mode: "attribute", values: attribute.values.map((attributeValue, index) => ({ - slug: attributeValue, + slug: attributeValue.slug, value: channels.map(channel => ({ channelId: channel.id, price: (channel.price + index).toString() @@ -97,7 +97,7 @@ describe("Creates variant matrix", () => { variant => variant.attributes.find( variantAttribute => variantAttribute.id === attribute.id - ).values[0] === attributeValue + ).values[0] === attributeValue.slug ) .forEach(variant => { variant.channelListings.map((channel, index) => { @@ -128,7 +128,7 @@ describe("Creates variant matrix", () => { attribute: attribute.id, mode: "attribute", values: attribute.values.map((attributeValue, attributeValueIndex) => ({ - slug: attributeValue, + slug: attributeValue.slug, value: stock.map( (_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1) ) @@ -154,7 +154,7 @@ describe("Creates variant matrix", () => { variant => variant.attributes.find( variantAttribute => variantAttribute.id === attribute.id - ).values[0] === attributeValue + ).values[0] === attributeValue.slug ) .forEach(variant => { variant.stocks.forEach((_, stockIndex) => { @@ -179,7 +179,7 @@ describe("Creates variant matrix", () => { attribute: attribute.id, mode: "attribute", values: attribute.values.map((attributeValue, index) => ({ - slug: attributeValue, + slug: attributeValue.slug, value: channels.map(channel => ({ channelId: channel.id, price: (channel.price + index).toString() @@ -191,7 +191,7 @@ describe("Creates variant matrix", () => { attribute: attribute.id, mode: "attribute", values: attribute.values.map((attributeValue, attributeValueIndex) => ({ - slug: attributeValue, + slug: attributeValue.slug, value: stock.map( (_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1) ) @@ -213,7 +213,7 @@ describe("Creates variant matrix", () => { variant => variant.attributes.find( variantAttribute => variantAttribute.id === attribute.id - ).values[0] === attributeValue + ).values[0] === attributeValue.slug ) .forEach(variant => { variant.channelListings.map((channel, index) => { @@ -230,7 +230,7 @@ describe("Creates variant matrix", () => { variant => variant.attributes.find( variantAttribute => variantAttribute.id === attribute.id - ).values[0] === attributeValue + ).values[0] === attributeValue.slug ) .forEach(variant => { variant.stocks.forEach((_, stockIndex) => { diff --git a/src/products/components/ProductVariantCreatorPage/createVariants.ts b/src/products/components/ProductVariantCreatorPage/createVariants.ts index 5d51db996..9e0ac7cbc 100644 --- a/src/products/components/ProductVariantCreatorPage/createVariants.ts +++ b/src/products/components/ProductVariantCreatorPage/createVariants.ts @@ -112,11 +112,11 @@ function addAttributeToVariant( attribute: Attribute, variant: CreateVariantInput ): CreateVariantInput[] { - return attribute.values.map(attributeValueSlug => [ + return attribute.values.map(attributeValue => [ ...variant, { attributeId: attribute.id, - attributeValueSlug + attributeValueSlug: attributeValue.slug } ]); } diff --git a/src/products/components/ProductVariantCreatorPage/fixtures.ts b/src/products/components/ProductVariantCreatorPage/fixtures.ts index 8dcde4aa9..757dbe37b 100644 --- a/src/products/components/ProductVariantCreatorPage/fixtures.ts +++ b/src/products/components/ProductVariantCreatorPage/fixtures.ts @@ -20,25 +20,69 @@ export const attributes = [ id: "attr-1", values: Array(9) .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", values: Array(6) .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", values: Array(4) .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", values: Array(11) .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", values: [ { - slug: thirdStep.attributes[1].values[0], + slug: thirdStep.attributes[1].values[0].slug, value: [ { channelId: channels[0].id, price: "0" }, { 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: [ { channelId: channels[0].id, price: "0" }, { channelId: channels[1].id, price: "2" }, @@ -139,11 +183,11 @@ const stock: Stock = { value: [], values: [ { - slug: thirdStep.attributes[2].values[0], + slug: thirdStep.attributes[2].values[0].slug, value: [50, 20, 45, 75] }, { - slug: thirdStep.attributes[2].values[1], + slug: thirdStep.attributes[2].values[1].slug, value: [80, 50, 85, 105] } ] diff --git a/src/products/components/ProductVariantCreatorPage/form.ts b/src/products/components/ProductVariantCreatorPage/form.ts index 2e3fbf8a5..5e2974a77 100644 --- a/src/products/components/ProductVariantCreatorPage/form.ts +++ b/src/products/components/ProductVariantCreatorPage/form.ts @@ -1,4 +1,5 @@ import { ChannelPriceData } from "@saleor/channels/utils"; +import { AttributeValueFragment } from "@saleor/fragments/types/AttributeValueFragment"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails"; @@ -28,7 +29,7 @@ export interface Stock { } export interface Attribute { id: string; - values: string[]; + values: Array>; } export interface ProductVariantCreateFormData { attributes: Attribute[]; diff --git a/src/products/components/ProductVariantCreatorPage/reducer.test.ts b/src/products/components/ProductVariantCreatorPage/reducer.test.ts index 42f18d87a..bb1a7f76b 100644 --- a/src/products/components/ProductVariantCreatorPage/reducer.test.ts +++ b/src/products/components/ProductVariantCreatorPage/reducer.test.ts @@ -23,14 +23,14 @@ describe("Reducer is able to", () => { { selectValue: { attributeId: attributes[0].id, - valueId: attributes[0].values[0] + value: attributes[0].values[0] }, type: ProductVariantCreateReducerActionType.selectValue }, { selectValue: { attributeId: attributes[0].id, - valueId: attributes[0].values[6] + value: attributes[0].values[6] }, type: ProductVariantCreateReducerActionType.selectValue @@ -38,28 +38,28 @@ describe("Reducer is able to", () => { { selectValue: { attributeId: attributes[1].id, - valueId: attributes[1].values[1] + value: attributes[1].values[1] }, type: ProductVariantCreateReducerActionType.selectValue }, { selectValue: { attributeId: attributes[1].id, - valueId: attributes[1].values[3] + value: attributes[1].values[3] }, type: ProductVariantCreateReducerActionType.selectValue }, { selectValue: { attributeId: attributes[3].id, - valueId: attributes[3].values[0] + value: attributes[3].values[0] }, type: ProductVariantCreateReducerActionType.selectValue }, { selectValue: { attributeId: attributes[3].id, - valueId: attributes[3].values[4] + value: attributes[3].values[4] }, type: ProductVariantCreateReducerActionType.selectValue } @@ -164,7 +164,7 @@ describe("Reducer is able to", () => { changeAttributeValuePrice: { channelId: channels[0].id, price: value.toString(), - valueId: attribute.values[0] + valueId: attribute.values[0].slug }, type: ProductVariantCreateReducerActionType.changeAttributeValuePrice }, @@ -172,7 +172,7 @@ describe("Reducer is able to", () => { changeAttributeValuePrice: { channelId: channels[1].id, price: (value + 6).toString(), - valueId: attribute.values[1] + valueId: attribute.values[1].slug }, type: ProductVariantCreateReducerActionType.changeAttributeValuePrice }, @@ -209,7 +209,7 @@ describe("Reducer is able to", () => { { changeAttributeValueStock: { quantity, - valueId: attribute.values[0], + valueId: attribute.values[0].slug, warehouseIndex: 0 }, type: ProductVariantCreateReducerActionType.changeAttributeValueStock @@ -217,7 +217,7 @@ describe("Reducer is able to", () => { { changeAttributeValueStock: { quantity: quantity + 6, - valueId: attribute.values[1], + valueId: attribute.values[1].slug, warehouseIndex: 0 }, type: ProductVariantCreateReducerActionType.changeAttributeValueStock diff --git a/src/products/components/ProductVariantCreatorPage/reducer.ts b/src/products/components/ProductVariantCreatorPage/reducer.ts index bc312763f..30147cb39 100644 --- a/src/products/components/ProductVariantCreatorPage/reducer.ts +++ b/src/products/components/ProductVariantCreatorPage/reducer.ts @@ -1,3 +1,4 @@ +import { AttributeValueFragment } from "@saleor/fragments/types/AttributeValueFragment"; import { StockInput } from "@saleor/types/globalTypes"; import { add, @@ -10,6 +11,7 @@ import { import { createVariants } from "./createVariants"; import { + AttributeValue, ProductVariantCreateFormData, VariantCreatorPricesAndSkuMode } from "./form"; @@ -72,19 +74,22 @@ export interface ProductVariantCreateReducerAction { reload?: { data?: ProductVariantCreateFormData; }; - selectValue?: Record<"attributeId" | "valueId", string>; + selectValue?: { + attributeId: string; + value: AttributeValue; + }; type: ProductVariantCreateReducerActionType; } function selectValue( prevState: ProductVariantCreateFormData, attributeId: string, - valueSlug: string + value: AttributeValue ): ProductVariantCreateFormData { const attribute = prevState.attributes.find( 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( { id: attributeId, @@ -97,7 +102,7 @@ function selectValue( prevState.price.attribute === attributeId ? toggle( { - slug: valueSlug, + slug: value.slug, value: [] }, prevState.price.values, @@ -109,7 +114,7 @@ function selectValue( prevState.stock.attribute === attributeId ? toggle( { - slug: valueSlug, + slug: value.slug, value: [] }, prevState.stock.values, @@ -237,8 +242,8 @@ function changeApplyPriceToAttributeId( const attribute = state.attributes.find( attribute => attribute.id === attributeId ); - const values = attribute.values.map(slug => ({ - slug, + const values = attribute.values.map(value => ({ + slug: value.slug, value: [] })); @@ -259,8 +264,8 @@ function changeApplyStockToAttributeId( const attribute = state.attributes.find( attribute => attribute.id === attributeId ); - const values = attribute.values.map(slug => ({ - slug, + const values = attribute.values.map(value => ({ + slug: value.slug, value: [] })); @@ -435,7 +440,7 @@ function reduceProductVariantCreateFormData( return selectValue( prevState, action.selectValue.attributeId, - action.selectValue.valueId + action.selectValue.value ); case ProductVariantCreateReducerActionType.applyPriceToAll: return applyPriceToAll(prevState, action.applyPriceOrStockToAll.mode); diff --git a/src/products/components/ProductVariantCreatorPage/utils.ts b/src/products/components/ProductVariantCreatorPage/utils.ts index 5ba6a1651..51998d192 100644 --- a/src/products/components/ProductVariantCreatorPage/utils.ts +++ b/src/products/components/ProductVariantCreatorPage/utils.ts @@ -17,7 +17,9 @@ export function getPriceAttributeValues( .choices.edges.filter(value => data.attributes .find(attribute => attribute.id === data.price.attribute) - .values.includes(value.node.slug) + .values.some( + attributeValue => attributeValue.slug === value.node.slug + ) ) .map(value => value.node) : []; @@ -35,7 +37,9 @@ export function getStockAttributeValues( .choices.edges.filter(value => data.attributes .find(attribute => attribute.id === data.stock.attribute) - .values.includes(value.node.slug) + .values.some( + attributeValue => attributeValue.slug === value.node.slug + ) ) .map(value => value.node) : []; diff --git a/src/products/components/ProductVariantPage/ProductVariantPage.tsx b/src/products/components/ProductVariantPage/ProductVariantPage.tsx index b7fdcc765..12d6396d6 100644 --- a/src/products/components/ProductVariantPage/ProductVariantPage.tsx +++ b/src/products/components/ProductVariantPage/ProductVariantPage.tsx @@ -22,6 +22,7 @@ import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/Prod import { ProductVariant } from "@saleor/fragments/types/ProductVariant"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; 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 { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { FetchMoreProps, ReorderAction } from "@saleor/types"; @@ -87,11 +88,15 @@ interface ProductVariantPageProps { warehouses: WarehouseFragment[]; referencePages?: SearchPages_search_edges_node[]; referenceProducts?: SearchProducts_search_edges_node[]; + attributeValues: SearchAttributeValues_attribute_choices_edges_node[]; fetchMoreReferencePages?: FetchMoreProps; fetchMoreReferenceProducts?: FetchMoreProps; + fetchMoreAttributeValues?: FetchMoreProps; fetchReferencePages?: (data: string) => void; fetchReferenceProducts?: (data: string) => void; + fetchAttributeValues: (query: string) => void; onAssignReferencesClick: (attribute: AttributeInput) => void; + onAttributeFocus: (id: string) => void; onCloseDialog: () => void; onVariantReorder: ReorderAction; onAdd(); @@ -118,6 +123,7 @@ const ProductVariantPage: React.FC = ({ warehouses, referencePages = [], referenceProducts = [], + attributeValues, onAdd, onBack, onDelete, @@ -127,12 +133,15 @@ const ProductVariantPage: React.FC = ({ onVariantReorder, onSetDefaultVariant, onWarehouseConfigure, + onAttributeFocus, assignReferencesAttributeId, onAssignReferencesClick, fetchReferencePages, fetchReferenceProducts, + fetchAttributeValues, fetchMoreReferencePages, fetchMoreReferenceProducts, + fetchMoreAttributeValues, onCloseDialog }) => { const intl = useIntl(); @@ -226,7 +235,7 @@ const ProductVariantPage: React.FC = ({ attribute.data.variantAttributeScope === VariantAttributeScope.NOT_VARIANT_SELECTION )} - attributeValues={[]} + attributeValues={attributeValues} loading={loading} disabled={loading} errors={errors} @@ -236,9 +245,9 @@ const ProductVariantPage: React.FC = ({ onReferencesRemove={handlers.selectAttributeReference} onReferencesAddClick={onAssignReferencesClick} onReferencesReorder={handlers.reorderAttributeValue} - fetchAttributeValues={() => undefined} - fetchMoreAttributeValues={undefined} - onAttributeSelect={() => undefined} + fetchAttributeValues={fetchAttributeValues} + fetchMoreAttributeValues={fetchMoreAttributeValues} + onAttributeFocus={onAttributeFocus} /> = ({ attribute.data.variantAttributeScope === VariantAttributeScope.VARIANT_SELECTION )} - attributeValues={[]} + attributeValues={attributeValues} loading={loading} disabled={loading} errors={errors} @@ -260,9 +269,9 @@ const ProductVariantPage: React.FC = ({ onReferencesRemove={handlers.selectAttributeReference} onReferencesAddClick={onAssignReferencesClick} onReferencesReorder={handlers.reorderAttributeValue} - fetchAttributeValues={() => undefined} - fetchMoreAttributeValues={undefined} - onAttributeSelect={() => undefined} + fetchAttributeValues={fetchAttributeValues} + fetchMoreAttributeValues={fetchMoreAttributeValues} + onAttributeFocus={onAttributeFocus} /> ({ slug: "attachment", valueRequired: true, unit: null, - values: { + choices: { __typename: "AttributeValueCountableConnection", pageInfo: { endCursor: "WyI4IiwgIjMiXQ==", @@ -3168,7 +3168,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({ slug: "Borders", valueRequired: true, unit: null, - values: { + choices: { __typename: "AttributeValueCountableConnection", pageInfo: { endCursor: "WyI4IiwgIjMiXQ==", @@ -3230,7 +3230,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({ slug: "Legacy", valueRequired: true, unit: null, - values: { + choices: { __typename: "AttributeValueCountableConnection", pageInfo: { endCursor: "WyI4IiwgIjMiXQ==", diff --git a/src/products/mutations.ts b/src/products/mutations.ts index 4724b9d1c..ba3683944 100644 --- a/src/products/mutations.ts +++ b/src/products/mutations.ts @@ -334,7 +334,11 @@ export const variantUpdateMutation = gql` $sku: String $trackInventory: Boolean! $stocks: [StockInput!]! - $weight: WeightScalar # $firstValues: Int # $afterValues: String # $lastValues: Int # $beforeValues: String + $weight: WeightScalar + $firstValues: Int + $afterValues: String + $lastValues: Int + $beforeValues: String ) { productVariantUpdate( id: $id @@ -394,7 +398,11 @@ export const variantCreateMutation = gql` ${fragmentVariant} ${productErrorWithAttributesFragment} 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) { errors { diff --git a/src/products/queries.ts b/src/products/queries.ts index 50e6cc410..906d0a9f2 100644 --- a/src/products/queries.ts +++ b/src/products/queries.ts @@ -282,7 +282,11 @@ export const useProductTypeQuery = makeQuery( const productVariantQuery = gql` ${fragmentVariant} 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 @@ -297,7 +301,11 @@ export const useProductVariantQuery = makeQuery< const productVariantCreateQuery = gql` ${variantAttributeFragment} 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) { id diff --git a/src/products/types/CreateMultipleVariantsData.ts b/src/products/types/CreateMultipleVariantsData.ts index 64454e7b5..f5061c9df 100644 --- a/src/products/types/CreateMultipleVariantsData.ts +++ b/src/products/types/CreateMultipleVariantsData.ts @@ -9,7 +9,7 @@ import { AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum } // GraphQL query operation: CreateMultipleVariantsData // ==================================================== -export interface CreateMultipleVariantsData_product_attributes_attribute_values_pageInfo { +export interface CreateMultipleVariantsData_product_attributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -17,32 +17,32 @@ export interface CreateMultipleVariantsData_product_attributes_attribute_values_ 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"; url: string; contentType: string | null; } -export interface CreateMultipleVariantsData_product_attributes_attribute_values_edges_node { +export interface CreateMultipleVariantsData_product_attributes_attribute_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface CreateMultipleVariantsData_product_attributes_attribute_values_edges { +export interface CreateMultipleVariantsData_product_attributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: CreateMultipleVariantsData_product_attributes_attribute_values_pageInfo; - edges: CreateMultipleVariantsData_product_attributes_attribute_values_edges[]; + pageInfo: CreateMultipleVariantsData_product_attributes_attribute_choices_pageInfo; + edges: CreateMultipleVariantsData_product_attributes_attribute_choices_edges[]; } export interface CreateMultipleVariantsData_product_attributes_attribute { @@ -54,7 +54,7 @@ export interface CreateMultipleVariantsData_product_attributes_attribute { entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: CreateMultipleVariantsData_product_attributes_attribute_values | null; + choices: CreateMultipleVariantsData_product_attributes_attribute_choices | null; } export interface CreateMultipleVariantsData_product_attributes_values_file { @@ -79,7 +79,7 @@ export interface CreateMultipleVariantsData_product_attributes { values: (CreateMultipleVariantsData_product_attributes_values | null)[]; } -export interface CreateMultipleVariantsData_product_productType_variantAttributes_values_pageInfo { +export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -87,39 +87,39 @@ export interface CreateMultipleVariantsData_product_productType_variantAttribute 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"; url: string; contentType: string | null; } -export interface CreateMultipleVariantsData_product_productType_variantAttributes_values_edges_node { +export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface CreateMultipleVariantsData_product_productType_variantAttributes_values_edges { +export interface CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: CreateMultipleVariantsData_product_productType_variantAttributes_values_pageInfo; - edges: CreateMultipleVariantsData_product_productType_variantAttributes_values_edges[]; + pageInfo: CreateMultipleVariantsData_product_productType_variantAttributes_choices_pageInfo; + edges: CreateMultipleVariantsData_product_productType_variantAttributes_choices_edges[]; } export interface CreateMultipleVariantsData_product_productType_variantAttributes { __typename: "Attribute"; id: string; name: string | null; - values: CreateMultipleVariantsData_product_productType_variantAttributes_values | null; + choices: CreateMultipleVariantsData_product_productType_variantAttributes_choices | null; } export interface CreateMultipleVariantsData_product_productType { diff --git a/src/products/types/ProductVariantCreateData.ts b/src/products/types/ProductVariantCreateData.ts index 304fdffdf..afbd6e022 100644 --- a/src/products/types/ProductVariantCreateData.ts +++ b/src/products/types/ProductVariantCreateData.ts @@ -28,7 +28,7 @@ export interface ProductVariantCreateData_product_channelListings { channel: ProductVariantCreateData_product_channelListings_channel; } -export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values_pageInfo { +export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -36,32 +36,32 @@ export interface ProductVariantCreateData_product_productType_selectionVariantAt 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"; url: string; contentType: string | null; } -export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges_node { +export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges { +export interface ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: ProductVariantCreateData_product_productType_selectionVariantAttributes_values_pageInfo; - edges: ProductVariantCreateData_product_productType_selectionVariantAttributes_values_edges[]; + pageInfo: ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_pageInfo; + edges: ProductVariantCreateData_product_productType_selectionVariantAttributes_choices_edges[]; } export interface ProductVariantCreateData_product_productType_selectionVariantAttributes { @@ -73,10 +73,10 @@ export interface ProductVariantCreateData_product_productType_selectionVariantAt entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; 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"; endCursor: string | null; hasNextPage: boolean; @@ -84,32 +84,32 @@ export interface ProductVariantCreateData_product_productType_nonSelectionVarian 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"; url: string; contentType: string | null; } -export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges_node { +export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges { +export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_pageInfo; - edges: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values_edges[]; + pageInfo: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_pageInfo; + edges: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices_edges[]; } export interface ProductVariantCreateData_product_productType_nonSelectionVariantAttributes { @@ -121,7 +121,7 @@ export interface ProductVariantCreateData_product_productType_nonSelectionVarian entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values | null; + choices: ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_choices | null; } export interface ProductVariantCreateData_product_productType { diff --git a/src/products/types/ProductVariantDetails.ts b/src/products/types/ProductVariantDetails.ts index f2a0ebaef..f150dc1f7 100644 --- a/src/products/types/ProductVariantDetails.ts +++ b/src/products/types/ProductVariantDetails.ts @@ -21,7 +21,7 @@ export interface ProductVariantDetails_productVariant_privateMetadata { value: string; } -export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values_pageInfo { +export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -29,32 +29,32 @@ export interface ProductVariantDetails_productVariant_selectionAttributes_attrib 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"; url: string; contentType: string | null; } -export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges_node { +export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges { +export interface ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: ProductVariantDetails_productVariant_selectionAttributes_attribute_values_pageInfo; - edges: ProductVariantDetails_productVariant_selectionAttributes_attribute_values_edges[]; + pageInfo: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_pageInfo; + edges: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices_edges[]; } export interface ProductVariantDetails_productVariant_selectionAttributes_attribute { @@ -66,7 +66,7 @@ export interface ProductVariantDetails_productVariant_selectionAttributes_attrib entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: ProductVariantDetails_productVariant_selectionAttributes_attribute_values | null; + choices: ProductVariantDetails_productVariant_selectionAttributes_attribute_choices | null; } export interface ProductVariantDetails_productVariant_selectionAttributes_values_file { @@ -91,7 +91,7 @@ export interface ProductVariantDetails_productVariant_selectionAttributes { values: (ProductVariantDetails_productVariant_selectionAttributes_values | null)[]; } -export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_pageInfo { +export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -99,32 +99,32 @@ export interface ProductVariantDetails_productVariant_nonSelectionAttributes_att 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"; url: string; contentType: string | null; } -export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges_node { +export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges_node { __typename: "AttributeValue"; id: string; name: 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; richText: any | null; } -export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges { +export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_pageInfo; - edges: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values_edges[]; + pageInfo: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_pageInfo; + edges: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices_edges[]; } export interface ProductVariantDetails_productVariant_nonSelectionAttributes_attribute { @@ -136,7 +136,7 @@ export interface ProductVariantDetails_productVariant_nonSelectionAttributes_att entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; unit: MeasurementUnitsEnum | null; - values: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values | null; + choices: ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_choices | null; } export interface ProductVariantDetails_productVariant_nonSelectionAttributes_values_file { diff --git a/src/products/types/VariantCreate.ts b/src/products/types/VariantCreate.ts index 5a9d092f4..44f791bb1 100644 --- a/src/products/types/VariantCreate.ts +++ b/src/products/types/VariantCreate.ts @@ -28,7 +28,7 @@ export interface VariantCreate_productVariantCreate_productVariant_privateMetada value: string; } -export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_pageInfo { +export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -36,32 +36,32 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr 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"; url: string; 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"; id: string; name: 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; richText: any | null; } -export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges { +export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_pageInfo; - edges: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values_edges[]; + pageInfo: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_pageInfo; + edges: VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_choices_edges[]; } export interface VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute { @@ -73,7 +73,7 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; 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 { @@ -98,7 +98,7 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr 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"; endCursor: string | null; hasNextPage: boolean; @@ -106,32 +106,32 @@ export interface VariantCreate_productVariantCreate_productVariant_nonSelectionA 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"; url: string; 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"; id: string; name: 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; richText: any | null; } -export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges { +export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_pageInfo; - edges: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values_edges[]; + pageInfo: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo; + edges: VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_choices_edges[]; } export interface VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute { @@ -143,7 +143,7 @@ export interface VariantCreate_productVariantCreate_productVariant_nonSelectionA entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; 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 { diff --git a/src/products/types/VariantUpdate.ts b/src/products/types/VariantUpdate.ts index 8b94d2342..395170d3a 100644 --- a/src/products/types/VariantUpdate.ts +++ b/src/products/types/VariantUpdate.ts @@ -28,7 +28,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_privateMetada value: string; } -export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_pageInfo { +export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -36,32 +36,32 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr 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"; url: string; 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"; id: string; name: 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; richText: any | null; } -export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges { +export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_pageInfo; - edges: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values_edges[]; + pageInfo: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo; + edges: VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_choices_edges[]; } export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute { @@ -73,7 +73,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; 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 { @@ -98,7 +98,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr 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"; endCursor: string | null; hasNextPage: boolean; @@ -106,32 +106,32 @@ export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionA 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"; url: string; 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"; id: string; name: 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; richText: any | null; } -export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges { +export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_pageInfo; - edges: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values_edges[]; + pageInfo: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo; + edges: VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges[]; } export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute { @@ -143,7 +143,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionA entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; 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 { @@ -359,7 +359,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_private value: string; } -export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_pageInfo { +export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo { __typename: "PageInfo"; endCursor: string | null; hasNextPage: boolean; @@ -367,32 +367,32 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti 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"; url: string; 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"; id: string; name: 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; richText: any | null; } -export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges { +export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_pageInfo; - edges: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values_edges[]; + pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_pageInfo; + edges: VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_choices_edges[]; } export interface VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute { @@ -404,7 +404,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; 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 { @@ -429,7 +429,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti 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"; endCursor: string | null; hasNextPage: boolean; @@ -437,32 +437,32 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSele 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"; url: string; 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"; id: string; name: 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; richText: any | null; } -export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges { +export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges { __typename: "AttributeValueCountableEdge"; 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"; - pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_pageInfo; - edges: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values_edges[]; + pageInfo: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_pageInfo; + edges: VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_choices_edges[]; } export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute { @@ -474,7 +474,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSele entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; 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 { diff --git a/src/products/utils/data.ts b/src/products/utils/data.ts index acb111438..0d50a7dfc 100644 --- a/src/products/utils/data.ts +++ b/src/products/utils/data.ts @@ -89,7 +89,7 @@ export function getAttributeInputFromAttributes( entityType: attribute.entityType, inputType: attribute.inputType, isRequired: attribute.valueRequired, - values: mapEdgesToItems(attribute.values), + values: mapEdgesToItems(attribute.choices), unit: attribute.unit, variantAttributeScope }, @@ -109,7 +109,7 @@ export function getAttributeInputFromSelectedAttributes( inputType: attribute.attribute.inputType, isRequired: attribute.attribute.valueRequired, selectedValues: attribute.values, - values: mapEdgesToItems(attribute.attribute.values), + values: mapEdgesToItems(attribute.attribute.choices), unit: attribute.attribute.unit, variantAttributeScope }, diff --git a/src/products/views/ProductCreate/ProductCreate.tsx b/src/products/views/ProductCreate/ProductCreate.tsx index bff44125a..a248d39ee 100644 --- a/src/products/views/ProductCreate/ProductCreate.tsx +++ b/src/products/views/ProductCreate/ProductCreate.tsx @@ -103,17 +103,17 @@ export const ProductCreateView: React.FC = ({ params }) => { } = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); - const [selectedAttribute, setSelectedAttribute] = useState(); + const [focusedAttribute, setFocusedAttribute] = useState(); const { loadMore: loadMoreAttributeValues, search: searchAttributeValues, result: searchAttributeValuesOpts } = useAttributeValueSearch({ variables: { - id: selectedAttribute, + id: focusedAttribute, ...DEFAULT_INITIAL_SEARCH_DATA }, - skip: !selectedAttribute + skip: !focusedAttribute }); const warehouses = useWarehouseList({ displayLoader: true, @@ -348,7 +348,7 @@ export const ProductCreateView: React.FC = ({ params }) => { onCloseDialog={() => navigate(productAddUrl())} selectedProductType={selectedProductType?.productType} onSelectProductType={id => setSelectedProductTypeId(id)} - onAttributeSelect={setSelectedAttribute} + onAttributeFocus={setFocusedAttribute} /> ); diff --git a/src/products/views/ProductUpdate/ProductUpdate.tsx b/src/products/views/ProductUpdate/ProductUpdate.tsx index fa6ff6535..295d583f5 100644 --- a/src/products/views/ProductUpdate/ProductUpdate.tsx +++ b/src/products/views/ProductUpdate/ProductUpdate.tsx @@ -141,17 +141,17 @@ export const ProductUpdate: React.FC = ({ id, params }) => { } = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); - const [selectedAttribute, setSelectedAttribute] = useState(); + const [focusedAttribute, setFocusedAttribute] = useState(); const { loadMore: loadMoreAttributeValues, search: searchAttributeValues, result: searchAttributeValuesOpts } = useAttributeValueSearch({ variables: { - id: selectedAttribute, + id: focusedAttribute, ...DEFAULT_INITIAL_SEARCH_DATA }, - skip: !selectedAttribute + skip: !focusedAttribute }); const warehouses = useWarehouseList({ displayLoader: true, @@ -605,7 +605,7 @@ export const ProductUpdate: React.FC = ({ id, params }) => { fetchMoreReferenceProducts={fetchMoreReferenceProducts} fetchMoreAttributeValues={fetchMoreAttributeValues} onCloseDialog={() => navigate(productUrl(id))} - onAttributeSelect={setSelectedAttribute} + onAttributeFocus={setFocusedAttribute} /> = ({ const { data, loading } = useProductVariantQuery({ displayLoader: true, variables: { - id: variantId + id: variantId, + firstValues: 10 } }); const [updateMetadata] = useMetadataUpdate({}); @@ -254,7 +256,8 @@ export const ProductVariant: React.FC = ({ sku: data.sku, stocks: data.updateStocks.map(mapFormsetStockToStockInput), trackInventory: data.trackInventory, - weight: weight(data.weight) + weight: weight(data.weight), + firstValues: 10 } }); await handleSubmitChannels(data, variant); @@ -297,6 +300,18 @@ export const ProductVariant: React.FC = ({ } = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); + const [focusedAttribute, setFocusedAttribute] = useState(); + const { + loadMore: loadMoreAttributeValues, + search: searchAttributeValues, + result: searchAttributeValuesOpts + } = useAttributeValueSearch({ + variables: { + id: focusedAttribute, + ...DEFAULT_INITIAL_SEARCH_DATA + }, + skip: !focusedAttribute + }); const fetchMoreReferencePages = { hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, @@ -308,6 +323,16 @@ export const ProductVariant: React.FC = ({ loading: searchProductsOpts.loading, onFetchMore: loadMoreProducts }; + const fetchMoreAttributeValues = { + hasMore: !!searchAttributeValuesOpts.data?.attribute?.choices?.pageInfo + ?.hasNextPage, + loading: !!searchAttributeValuesOpts.loading, + onFetchMore: loadMoreAttributeValues + }; + + const attributeValues = mapEdgesToItems( + searchAttributeValuesOpts?.data?.attribute.choices + ); return ( <> @@ -316,6 +341,7 @@ export const ProductVariant: React.FC = ({ defaultWeightUnit={shop?.defaultWeightUnit} defaultVariantId={data?.productVariant.product.defaultVariant?.id} errors={errors} + attributeValues={attributeValues} channels={channels} channelErrors={ updateChannelsOpts?.data?.productVariantChannelListingUpdate @@ -351,9 +377,12 @@ export const ProductVariant: React.FC = ({ fetchMoreReferencePages={fetchMoreReferencePages} fetchReferenceProducts={searchProducts} fetchMoreReferenceProducts={fetchMoreReferenceProducts} + fetchAttributeValues={searchAttributeValues} + fetchMoreAttributeValues={fetchMoreAttributeValues} onCloseDialog={() => navigate(productVariantEditUrl(productId, variantId)) } + onAttributeFocus={setFocusedAttribute} /> = ({ const { data, loading: productLoading } = useProductVariantCreateQuery({ displayLoader: true, - variables: { id: productId } + variables: { + id: productId, + firstValues: 10 + } }); const [uploadFile, uploadFileOpts] = useFileUploadMutation({}); @@ -126,7 +130,8 @@ export const ProductVariant: React.FC = ({ })), trackInventory: true, weight: weight(formData.weight) - } + }, + firstValues: 10 } }); const id = result.data?.productVariantCreate?.productVariant?.id; @@ -163,6 +168,18 @@ export const ProductVariant: React.FC = ({ } = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); + const [focusedAttribute, setFocusedAttribute] = useState(); + const { + loadMore: loadMoreAttributeValues, + search: searchAttributeValues, + result: searchAttributeValuesOpts + } = useAttributeValueSearch({ + variables: { + id: focusedAttribute, + ...DEFAULT_INITIAL_SEARCH_DATA + }, + skip: !focusedAttribute + }); const fetchMoreReferencePages = { hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, @@ -174,6 +191,16 @@ export const ProductVariant: React.FC = ({ loading: searchProductsOpts.loading, 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 = productLoading || @@ -198,6 +225,7 @@ export const ProductVariant: React.FC = ({ description: "header" })} product={data?.product} + attributeValues={attributeValues} onBack={handleBack} onSubmit={handleSubmit} onVariantClick={handleVariantClick} @@ -216,7 +244,10 @@ export const ProductVariant: React.FC = ({ fetchMoreReferencePages={fetchMoreReferencePages} fetchReferenceProducts={searchProducts} fetchMoreReferenceProducts={fetchMoreReferenceProducts} + fetchAttributeValues={searchAttributeValues} + fetchMoreAttributeValues={fetchMoreAttributeValues} onCloseDialog={() => navigate(productVariantAddUrl(productId))} + onAttributeFocus={setFocusedAttribute} /> ); diff --git a/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx b/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx index 3e286e315..4e5f801d1 100644 --- a/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx +++ b/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx @@ -1,12 +1,14 @@ import { useShopLimitsQuery } from "@saleor/components/Shop/query"; import { WindowTitle } from "@saleor/components/WindowTitle"; +import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { useProductVariantBulkCreateMutation } from "@saleor/products/mutations"; import { useCreateMultipleVariantsData } from "@saleor/products/queries"; import { productUrl } from "@saleor/products/urls"; +import useAttributeValueSearch from "@saleor/searches/useAttributeValueSearch"; import { mapEdgesToItems } from "@saleor/utils/maps"; -import React from "react"; +import React, { useState } from "react"; import { useIntl } from "react-intl"; import ProductVariantCreatorPage from "../../components/ProductVariantCreatorPage"; @@ -23,7 +25,10 @@ const ProductVariantCreator: React.FC = ({ const intl = useIntl(); const { data } = useCreateMultipleVariantsData({ displayLoader: true, - variables: { id } + variables: { + id, + firstValues: 10 + } }); const [ bulkProductVariantCreate, @@ -48,6 +53,30 @@ const ProductVariantCreator: React.FC = ({ } }); + const [focusedAttribute, setFocusedAttribute] = useState(); + 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 ( <> = ({ name: listing.channel.name, price: "" }))} - attributes={ - data?.product?.productType?.variantAttributes?.map(attr => ({ - ...attr, - choices: attr.values - })) || [] - } + attributes={data?.product?.productType?.variantAttributes || []} + attributeValues={attributeValues} + fetchAttributeValues={searchAttributeValues} + fetchMoreAttributeValues={fetchMoreAttributeValues} limits={limitOpts.data?.shop?.limits} onSubmit={inputs => bulkProductVariantCreate({ @@ -80,6 +107,7 @@ const ProductVariantCreator: React.FC = ({ }) } warehouses={mapEdgesToItems(data?.warehouses)} + onAttributeFocus={setFocusedAttribute} /> ); diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index c269fd502..de8d3982d 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -173222,6 +173222,12 @@ exports[`Storyshots Views / Products / Create multiple variants / summary defaul > Arabica + + Round +
Arabica + + Polo +
Arabica + + Round +
Arabica + + Polo +
Arabica + + Round +
Arabica + + Polo +
Arabica + + Round +
Arabica + + Polo +
- + + +
+
+
+
- - - - - - - + +
+ +
- 250g - - - - + + + + +
+ +
- + + +
+
+ +
- - - - - - - - Robusta - - + Arabica +
+ + + +
- - Author -
-
-
-
-
- - -
-
-
-
-
- - Box Size - +
+
+
-
-
-
-
- - - - -
-
-
-
-
- - Coffee Genre -
+ class="MuiCardContent-root-id" + data-test-id="value-container" + > +
+
+ + +
+
+
+
-
- - -
-
-
-
-
- - Color -
+ + Box Size + +
+
+
+
+
+
+
+ + +
+
+
+
-
- -
+
+
+
- - - - +
+
+
+
+
+
+
+ + Color + +
+
+
+
+
+
+
+ + +
+
+
+
+
+
-
`; diff --git a/src/storybook/stories/products/ProductCreatePage.tsx b/src/storybook/stories/products/ProductCreatePage.tsx index e42f618f4..300729d23 100644 --- a/src/storybook/stories/products/ProductCreatePage.tsx +++ b/src/storybook/stories/products/ProductCreatePage.tsx @@ -56,7 +56,7 @@ storiesOf("Views / Products / Create product", module) onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} onSelectProductType={() => undefined} - onAttributeSelect={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("When loading", () => ( @@ -93,7 +93,7 @@ storiesOf("Views / Products / Create product", module) onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} onSelectProductType={() => undefined} - onAttributeSelect={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("form errors", () => ( @@ -145,6 +145,6 @@ storiesOf("Views / Products / Create product", module) onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} onSelectProductType={() => undefined} - onAttributeSelect={() => undefined} + onAttributeFocus={() => undefined} /> )); diff --git a/src/storybook/stories/products/ProductUpdatePage.tsx b/src/storybook/stories/products/ProductUpdatePage.tsx index 35a3d24e6..e828cea9b 100644 --- a/src/storybook/stories/products/ProductUpdatePage.tsx +++ b/src/storybook/stories/products/ProductUpdatePage.tsx @@ -70,7 +70,7 @@ const props: ProductUpdatePageProps = { onVariantsAdd: () => undefined, onWarehouseConfigure: () => undefined, openChannelsModal: () => undefined, - onAttributeSelect: () => undefined, + onAttributeFocus: () => undefined, placeholderImage, product, referencePages: [], diff --git a/src/storybook/stories/products/ProductVariantCreatePage.tsx b/src/storybook/stories/products/ProductVariantCreatePage.tsx index bf00af7c8..b32542b73 100644 --- a/src/storybook/stories/products/ProductVariantCreatePage.tsx +++ b/src/storybook/stories/products/ProductVariantCreatePage.tsx @@ -36,8 +36,11 @@ storiesOf("Views / Products / Create product variant", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("with errors", () => ( @@ -76,8 +79,11 @@ storiesOf("Views / Products / Create product variant", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("when loading data", () => ( @@ -97,8 +103,11 @@ storiesOf("Views / Products / Create product variant", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("add first variant", () => ( @@ -121,8 +130,11 @@ storiesOf("Views / Products / Create product variant", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("no warehouses", () => ( @@ -142,7 +154,10 @@ storiesOf("Views / Products / Create product variant", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )); diff --git a/src/storybook/stories/products/ProductVariantPage.tsx b/src/storybook/stories/products/ProductVariantPage.tsx index 6c2912e38..b0ba9ea8a 100644 --- a/src/storybook/stories/products/ProductVariantPage.tsx +++ b/src/storybook/stories/products/ProductVariantPage.tsx @@ -35,8 +35,11 @@ storiesOf("Views / Products / Product variant details", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("when loading data", () => ( @@ -61,8 +64,11 @@ storiesOf("Views / Products / Product variant details", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("no warehouses", () => ( @@ -86,8 +92,11 @@ storiesOf("Views / Products / Product variant details", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> )) .add("attribute errors", () => ( @@ -139,7 +148,10 @@ storiesOf("Views / Products / Product variant details", module) onWarehouseConfigure={() => undefined} referencePages={[]} referenceProducts={[]} + attributeValues={[]} + fetchAttributeValues={() => undefined} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} + onAttributeFocus={() => undefined} /> ));