diff --git a/design-documents/graph-ql/coverage/CategoryFiltering.graphqls b/design-documents/graph-ql/coverage/catalog/CategoryFiltering.graphqls similarity index 100% rename from design-documents/graph-ql/coverage/CategoryFiltering.graphqls rename to design-documents/graph-ql/coverage/catalog/CategoryFiltering.graphqls diff --git a/design-documents/graph-ql/coverage/ProductPrices.graphqls b/design-documents/graph-ql/coverage/catalog/ProductPrices.graphqls similarity index 100% rename from design-documents/graph-ql/coverage/ProductPrices.graphqls rename to design-documents/graph-ql/coverage/catalog/ProductPrices.graphqls diff --git a/design-documents/graph-ql/coverage/catalog/configurable-options-selection.graphqls b/design-documents/graph-ql/coverage/catalog/configurable-options-selection.graphqls new file mode 100644 index 000000000..2131630b7 --- /dev/null +++ b/design-documents/graph-ql/coverage/catalog/configurable-options-selection.graphqls @@ -0,0 +1,21 @@ +type ConfigurableProduct { + configurable_options_selection_metadata(selectedConfigurableOptionValues: [ID!]): ConfigurableOptionsSelectionMetadata @doc(description: "Metadata for the specified configurable options selection") +} + +type ConfigurableOptionsSelectionMetadata @doc(description: "Metadata corresponding to the configurable options selection.") +{ + options_available_for_selection: [ConfigurableOptionAvailableForSelection!] @doc(description: "Configurable options available for further selection based on current selection.") + media_gallery: [MediaGalleryInterface!] @doc(description: "Product images and videos corresponding to the specified configurable options selection.") + variant: SimpleProduct @doc(description: "Variant represented by the specified configurable options selection. It is expected to be null, until selections are made for each configurable option.") +} + +type ConfigurableOptionAvailableForSelection @doc(description: "Configurable option available for further selection based on current selection.") { + available_value_ids: [ID!]! @doc(description: "Configurable option values available for further selection.") + attribute_code: String! @doc(description: "Attribute code that uniquely identifies configurable option.") +} + +# Configurable option value type has to be extended to include ID which can be used to uniquely identify the option value across the system. This is consistent with proposal of single mutation for add-to-cart +type ConfigurableProductOptionsValues { + id: ID! + is_available_for_selection: Boolean! +} diff --git a/design-documents/graph-ql/coverage/catalog/configurable-options-selection.md b/design-documents/graph-ql/coverage/catalog/configurable-options-selection.md new file mode 100644 index 000000000..74b1c5880 --- /dev/null +++ b/design-documents/graph-ql/coverage/catalog/configurable-options-selection.md @@ -0,0 +1,211 @@ +## Use cases + +### Render configurable option values available for selection on the product page + +User navigates to the configurable product page. Option values available for selection are rendered on the page. + +```graphql +{ + products(filter: {sku: {eq: "configurable-sku"}}) { + items { + description { + html + } + name + ... on ConfigurableProduct { + configurable_options { + attribute_code + label + values { + id + is_available_for_selection + value_index + label + swatch_data { + value + } + use_default_value + } + } + configurable_options_selection_metadata { + options_available_for_selection { + attribute_code + available_value_ids + } + media_gallery { + url + label + position + disabled + } + } + } + } + } +} + +``` + +The user makes a selection for the first option and the list of option values available for selection is updated for the remaining options. +The images and videos relevant for the selection are also updated. + +```graphql +{ + products(filter: {sku: {eq: "configurable-sku"}}) { + items { + ... on ConfigurableProduct { + configurable_options_selection_metadata( + selectedConfigurableOptionValues: ["hash from selected option value"] + ) { + options_available_for_selection { + attribute_code + available_value_ids + } + media_gallery { + url + label + position + disabled + } + } + } + } + } +} +``` + +### User opens URL leading to configurable product page and configurable option selections are specified in the URL + +In this case URL will have to be resolved first: + +```graphql +{ + urlResolver(url: "http://magento.instance/configurable_product.html?configurable_options[0]=first-selection-hash&configurable_options[1]=second-selection-hash") { + id + type + } +} +``` + +Then the product data along with available selections can be requested in a single query: + +```graphql +{ + products(filter: {sku: {eq: "resolved-sku"}}) { + items { + description { + html + } + name + ... on ConfigurableProduct { + configurable_options { + attribute_code + label + values { + id + is_available_for_selection + value_index + label + swatch_data { + value + } + use_default_value + } + } + configurable_options_selection_metadata( + selectedConfigurableOptionValues: ["hash from selected option value", "hash from another option value"] + ) { + options_available_for_selection { + attribute_code + available_value_ids + } + media_gallery { + url + label + position + disabled + } + variant { + sku + } + } + } + } + } +} +``` + +### Add to cart + +After the user makes final selection, the corresponding simple product data becomes available and the product can now be added to cart. + +```graphql +{ + products(filter: {sku: {eq: "configurable-sku"}}) { + items { + ... on ConfigurableProduct { + configurable_options_selection_metadata( + selectedConfigurableOptionValues: ["hash from selected option value", "hash from another option value"] + ) { + options_available_for_selection { + attribute_code + available_value_ids + } + media_gallery { + url + label + position + disabled + } + variant { + sku + } + } + } + } + } +} +``` + +Information about variant is taken from previous query result and used to add configurable product to cart. + +### Render configurable option values available for selection on the category page + +In case when the facet filter was used on the category page, for example to search "Red" shorts, it would be a good idea to display available sizes in "Red" for each product on the page. This can be achieved with the following query: + +```graphql +{ + products(filter: {category_id: {eq: "shorts category ID"}}) { + items { + name + sku + ... on ConfigurableProduct { + configurable_options_selection_metadata( + selectedConfigurableOptionValues: ["hash from selected red color option"] + ) { + options_available_for_selection { + attribute_code + available_value_ids + } + media_gallery { + url + label + position + disabled + } + } + } + } + } +} +``` + +### Extension points + +`ConfigurableOptionsSelectionMetadata` type can be extended to support additional use cases, which are not currently supported by Magento like: + - Price range for the variants based on configurable options selection + - Low stock notification based on configurable options selection + +### Long term vision + +In the future all option types will be unified to support additional use cases like conflicting custom options, or price range based on custom + configurable options selection. The new query will be introduced on the top level, and current solution being specific to configurable options only will be deprecated. diff --git a/design-documents/graph-ql/coverage/product-reviews.graphqls b/design-documents/graph-ql/coverage/catalog/product-reviews.graphqls similarity index 100% rename from design-documents/graph-ql/coverage/product-reviews.graphqls rename to design-documents/graph-ql/coverage/catalog/product-reviews.graphqls