Merge pull request #189 from mirumee/fix/product-type-search
Fix product type selection
This commit is contained in:
commit
7b0b99fbcd
11 changed files with 123 additions and 96 deletions
|
@ -27,5 +27,6 @@ All notable, unreleased changes to this project will be documented in this file.
|
|||
- Fix navigation - #182 by @benekex2
|
||||
- Add testcafe tags to attributes, categories, collections and product types - #178 by @dominik-zeglen
|
||||
- Fix input error style - #183 by @benekex2
|
||||
- Fix product type selection - #189 by @dominik-zeglen
|
||||
- Fix staff return link - #190 by @dominik-zeglen
|
||||
- Allow sorting products by attribute - #180 by @dominik-zeglen
|
||||
|
|
37
src/containers/SearchProductTypes/index.tsx
Normal file
37
src/containers/SearchProductTypes/index.tsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
import gql from "graphql-tag";
|
||||
|
||||
import BaseSearch from "../BaseSearch";
|
||||
import {
|
||||
SearchProductTypes,
|
||||
SearchProductTypesVariables
|
||||
} from "./types/SearchProductTypes";
|
||||
|
||||
export const searchProductTypes = gql`
|
||||
query SearchProductTypes($after: String, $first: Int!, $query: String!) {
|
||||
productTypes(after: $after, first: $first, filter: { search: $query }) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
hasVariants
|
||||
productAttributes {
|
||||
id
|
||||
inputType
|
||||
slug
|
||||
name
|
||||
valueRequired
|
||||
values {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default BaseSearch<SearchProductTypes, SearchProductTypesVariables>(
|
||||
searchProductTypes
|
||||
);
|
|
@ -0,0 +1,54 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { AttributeInputTypeEnum } from "./../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: SearchProductTypes
|
||||
// ====================================================
|
||||
|
||||
export interface SearchProductTypes_productTypes_edges_node_productAttributes_values {
|
||||
__typename: "AttributeValue";
|
||||
id: string;
|
||||
name: string | null;
|
||||
slug: string | null;
|
||||
}
|
||||
|
||||
export interface SearchProductTypes_productTypes_edges_node_productAttributes {
|
||||
__typename: "Attribute";
|
||||
id: string;
|
||||
inputType: AttributeInputTypeEnum | null;
|
||||
slug: string | null;
|
||||
name: string | null;
|
||||
valueRequired: boolean;
|
||||
values: (SearchProductTypes_productTypes_edges_node_productAttributes_values | null)[] | null;
|
||||
}
|
||||
|
||||
export interface SearchProductTypes_productTypes_edges_node {
|
||||
__typename: "ProductType";
|
||||
id: string;
|
||||
name: string;
|
||||
hasVariants: boolean;
|
||||
productAttributes: (SearchProductTypes_productTypes_edges_node_productAttributes | null)[] | null;
|
||||
}
|
||||
|
||||
export interface SearchProductTypes_productTypes_edges {
|
||||
__typename: "ProductTypeCountableEdge";
|
||||
node: SearchProductTypes_productTypes_edges_node;
|
||||
}
|
||||
|
||||
export interface SearchProductTypes_productTypes {
|
||||
__typename: "ProductTypeCountableConnection";
|
||||
edges: SearchProductTypes_productTypes_edges[];
|
||||
}
|
||||
|
||||
export interface SearchProductTypes {
|
||||
productTypes: SearchProductTypes_productTypes | null;
|
||||
}
|
||||
|
||||
export interface SearchProductTypesVariables {
|
||||
after?: string | null;
|
||||
first: number;
|
||||
query: string;
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
import {
|
||||
ProductCreateData_productTypes_edges_node,
|
||||
ProductCreateData_productTypes_edges_node_productAttributes
|
||||
} from "../products/types/ProductCreateData";
|
||||
SearchProductTypes_productTypes_edges_node,
|
||||
SearchProductTypes_productTypes_edges_node_productAttributes
|
||||
} from "@saleor/containers/SearchProductTypes/types/SearchProductTypes";
|
||||
import { AttributeInputTypeEnum } from "../types/globalTypes";
|
||||
import { ProductTypeDetails_productType } from "./types/ProductTypeDetails";
|
||||
import { ProductTypeList_productTypes_edges_node } from "./types/ProductTypeList";
|
||||
|
||||
export const attributes: ProductCreateData_productTypes_edges_node_productAttributes[] = [
|
||||
export const attributes: SearchProductTypes_productTypes_edges_node_productAttributes[] = [
|
||||
{
|
||||
node: {
|
||||
__typename: "Attribute" as "Attribute",
|
||||
|
@ -469,7 +469,7 @@ export const attributes: ProductCreateData_productTypes_edges_node_productAttrib
|
|||
].map(edge => edge.node);
|
||||
|
||||
export const productTypes: Array<
|
||||
ProductCreateData_productTypes_edges_node &
|
||||
SearchProductTypes_productTypes_edges_node &
|
||||
ProductTypeList_productTypes_edges_node
|
||||
> = [
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ import SeoForm from "@saleor/components/SeoForm";
|
|||
import VisibilityCard from "@saleor/components/VisibilityCard";
|
||||
import { SearchCategories_categories_edges_node } from "@saleor/containers/SearchCategories/types/SearchCategories";
|
||||
import { SearchCollections_collections_edges_node } from "@saleor/containers/SearchCollections/types/SearchCollections";
|
||||
import { SearchProductTypes_productTypes_edges_node_productAttributes } from "@saleor/containers/SearchProductTypes/types/SearchProductTypes";
|
||||
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
||||
import useFormset from "@saleor/hooks/useFormset";
|
||||
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||
|
@ -27,7 +28,6 @@ import {
|
|||
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
|
||||
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
||||
import { UserError } from "../../../types";
|
||||
import { ProductCreateData_productTypes_edges_node_productAttributes } from "../../types/ProductCreateData";
|
||||
import {
|
||||
createAttributeChangeHandler,
|
||||
createAttributeMultiChangeHandler,
|
||||
|
@ -71,12 +71,13 @@ interface ProductCreatePageProps {
|
|||
id: string;
|
||||
name: string;
|
||||
hasVariants: boolean;
|
||||
productAttributes: ProductCreateData_productTypes_edges_node_productAttributes[];
|
||||
productAttributes: SearchProductTypes_productTypes_edges_node_productAttributes[];
|
||||
}>;
|
||||
header: string;
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
fetchCategories: (data: string) => void;
|
||||
fetchCollections: (data: string) => void;
|
||||
fetchProductTypes: (data: string) => void;
|
||||
onAttributesEdit: () => void;
|
||||
onBack?();
|
||||
onSubmit?(data: ProductCreatePageSubmitData);
|
||||
|
@ -96,6 +97,7 @@ export const ProductCreatePage: React.StatelessComponent<
|
|||
productTypes: productTypeChoiceList,
|
||||
saveButtonBarState,
|
||||
onBack,
|
||||
fetchProductTypes,
|
||||
onSubmit
|
||||
}: ProductCreatePageProps) => {
|
||||
const intl = useIntl();
|
||||
|
@ -139,7 +141,7 @@ export const ProductCreatePage: React.StatelessComponent<
|
|||
hasVariants: false,
|
||||
id: "",
|
||||
name: "",
|
||||
productAttributes: [] as ProductCreateData_productTypes_edges_node_productAttributes[]
|
||||
productAttributes: []
|
||||
});
|
||||
|
||||
const categories = getChoices(categoryChoiceList);
|
||||
|
@ -268,6 +270,7 @@ export const ProductCreatePage: React.StatelessComponent<
|
|||
errors={errors}
|
||||
fetchCategories={fetchCategories}
|
||||
fetchCollections={fetchCollections}
|
||||
fetchProductTypes={fetchProductTypes}
|
||||
productType={productType}
|
||||
productTypeInputDisplayValue={productType.name}
|
||||
productTypes={productTypes}
|
||||
|
|
|
@ -62,6 +62,7 @@ interface ProductOrganizationProps extends WithStyles<typeof styles> {
|
|||
productTypes?: SingleAutocompleteChoiceType[];
|
||||
fetchCategories: (query: string) => void;
|
||||
fetchCollections: (query: string) => void;
|
||||
fetchProductTypes?: (data: string) => void;
|
||||
onCategoryChange: (event: ChangeEvent) => void;
|
||||
onCollectionChange: (event: ChangeEvent) => void;
|
||||
onProductTypeChange?: (event: ChangeEvent) => void;
|
||||
|
@ -80,6 +81,7 @@ const ProductOrganization = withStyles(styles, { name: "ProductOrganization" })(
|
|||
errors,
|
||||
fetchCategories,
|
||||
fetchCollections,
|
||||
fetchProductTypes,
|
||||
productType,
|
||||
productTypeInputDisplayValue,
|
||||
productTypes,
|
||||
|
@ -111,6 +113,7 @@ const ProductOrganization = withStyles(styles, { name: "ProductOrganization" })(
|
|||
choices={productTypes}
|
||||
value={data.productType}
|
||||
onChange={onProductTypeChange}
|
||||
fetchChoices={fetchProductTypes}
|
||||
data-tc="product-type"
|
||||
/>
|
||||
) : (
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
AvailableInGridAttributes,
|
||||
AvailableInGridAttributesVariables
|
||||
} from "./types/AvailableInGridAttributes";
|
||||
import { ProductCreateData } from "./types/ProductCreateData";
|
||||
import {
|
||||
ProductDetails,
|
||||
ProductDetailsVariables
|
||||
|
@ -282,35 +281,6 @@ export const TypedProductVariantQuery = TypedQuery<
|
|||
ProductVariantDetailsVariables
|
||||
>(productVariantQuery);
|
||||
|
||||
const productCreateQuery = gql`
|
||||
query ProductCreateData {
|
||||
productTypes(first: 20) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
hasVariants
|
||||
productAttributes {
|
||||
id
|
||||
inputType
|
||||
slug
|
||||
name
|
||||
valueRequired
|
||||
values {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const TypedProductCreateQuery = TypedQuery<ProductCreateData, {}>(
|
||||
productCreateQuery
|
||||
);
|
||||
|
||||
const productVariantCreateQuery = gql`
|
||||
query ProductVariantCreateData($id: ID!) {
|
||||
product(id: $id) {
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { AttributeInputTypeEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: ProductCreateData
|
||||
// ====================================================
|
||||
|
||||
export interface ProductCreateData_productTypes_edges_node_productAttributes_values {
|
||||
__typename: "AttributeValue";
|
||||
id: string;
|
||||
name: string | null;
|
||||
slug: string | null;
|
||||
}
|
||||
|
||||
export interface ProductCreateData_productTypes_edges_node_productAttributes {
|
||||
__typename: "Attribute";
|
||||
id: string;
|
||||
inputType: AttributeInputTypeEnum | null;
|
||||
slug: string | null;
|
||||
name: string | null;
|
||||
valueRequired: boolean;
|
||||
values: (ProductCreateData_productTypes_edges_node_productAttributes_values | null)[] | null;
|
||||
}
|
||||
|
||||
export interface ProductCreateData_productTypes_edges_node {
|
||||
__typename: "ProductType";
|
||||
id: string;
|
||||
name: string;
|
||||
hasVariants: boolean;
|
||||
productAttributes: (ProductCreateData_productTypes_edges_node_productAttributes | null)[] | null;
|
||||
}
|
||||
|
||||
export interface ProductCreateData_productTypes_edges {
|
||||
__typename: "ProductTypeCountableEdge";
|
||||
node: ProductCreateData_productTypes_edges_node;
|
||||
}
|
||||
|
||||
export interface ProductCreateData_productTypes {
|
||||
__typename: "ProductTypeCountableConnection";
|
||||
edges: ProductCreateData_productTypes_edges[];
|
||||
}
|
||||
|
||||
export interface ProductCreateData {
|
||||
productTypes: ProductCreateData_productTypes | null;
|
||||
}
|
|
@ -2,6 +2,7 @@ import { RawDraftContentState } from "draft-js";
|
|||
|
||||
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
|
||||
import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField";
|
||||
import { SearchProductTypes_productTypes_edges_node_productAttributes } from "@saleor/containers/SearchProductTypes/types/SearchProductTypes";
|
||||
import { maybe } from "@saleor/misc";
|
||||
import {
|
||||
ProductDetails_product,
|
||||
|
@ -11,7 +12,6 @@ import {
|
|||
import { UserError } from "@saleor/types";
|
||||
import { ProductAttributeInput } from "../components/ProductAttributes";
|
||||
import { VariantAttributeInput } from "../components/ProductVariantAttributes";
|
||||
import { ProductCreateData_productTypes_edges_node_productAttributes } from "../types/ProductCreateData";
|
||||
import {
|
||||
ProductVariant,
|
||||
ProductVariant_attributes_attribute
|
||||
|
@ -35,7 +35,7 @@ export interface ProductType {
|
|||
hasVariants: boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
productAttributes: ProductCreateData_productTypes_edges_node_productAttributes[];
|
||||
productAttributes: SearchProductTypes_productTypes_edges_node_productAttributes[];
|
||||
}
|
||||
|
||||
export function getAttributeInputFromProduct(
|
||||
|
|
|
@ -2,6 +2,7 @@ import React from "react";
|
|||
import { useIntl } from "react-intl";
|
||||
|
||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||
import SearchProductTypes from "@saleor/containers/SearchProductTypes";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import useShop from "@saleor/hooks/useShop";
|
||||
|
@ -13,7 +14,6 @@ import ProductCreatePage, {
|
|||
ProductCreatePageSubmitData
|
||||
} from "../components/ProductCreatePage";
|
||||
import { TypedProductCreateMutation } from "../mutations";
|
||||
import { TypedProductCreateQuery } from "../queries";
|
||||
import { ProductCreate } from "../types/ProductCreate";
|
||||
import { productListUrl, productUrl } from "../urls";
|
||||
|
||||
|
@ -37,8 +37,11 @@ export const ProductUpdate: React.StatelessComponent<
|
|||
{({ search: searchCategory, result: searchCategoryOpts }) => (
|
||||
<SearchCollections variables={DEFAULT_INITIAL_SEARCH_DATA}>
|
||||
{({ search: searchCollection, result: searchCollectionOpts }) => (
|
||||
<TypedProductCreateQuery displayLoader>
|
||||
{({ data, loading }) => {
|
||||
<SearchProductTypes variables={DEFAULT_INITIAL_SEARCH_DATA}>
|
||||
{({
|
||||
search: searchProductTypes,
|
||||
result: searchProductTypesOpts
|
||||
}) => {
|
||||
const handleSuccess = (data: ProductCreate) => {
|
||||
if (data.productCreate.errors.length === 0) {
|
||||
notify({
|
||||
|
@ -103,8 +106,6 @@ export const ProductUpdate: React.StatelessComponent<
|
|||
});
|
||||
};
|
||||
|
||||
const disabled = loading || productCreateDataLoading;
|
||||
|
||||
const formTransitionState = getMutationState(
|
||||
productCreateCalled,
|
||||
productCreateDataLoading,
|
||||
|
@ -128,19 +129,22 @@ export const ProductUpdate: React.StatelessComponent<
|
|||
() => searchCollectionOpts.data.collections.edges,
|
||||
[]
|
||||
).map(edge => edge.node)}
|
||||
disabled={disabled}
|
||||
disabled={productCreateDataLoading}
|
||||
errors={maybe(
|
||||
() => productCreateData.productCreate.errors,
|
||||
[]
|
||||
)}
|
||||
fetchCategories={searchCategory}
|
||||
fetchCollections={searchCollection}
|
||||
fetchProductTypes={searchProductTypes}
|
||||
header={intl.formatMessage({
|
||||
defaultMessage: "New Product",
|
||||
description: "page header"
|
||||
})}
|
||||
productTypes={maybe(() =>
|
||||
data.productTypes.edges.map(edge => edge.node)
|
||||
searchProductTypesOpts.data.productTypes.edges.map(
|
||||
edge => edge.node
|
||||
)
|
||||
)}
|
||||
onAttributesEdit={handleAttributesEdit}
|
||||
onBack={handleBack}
|
||||
|
@ -153,7 +157,7 @@ export const ProductUpdate: React.StatelessComponent<
|
|||
</TypedProductCreateMutation>
|
||||
);
|
||||
}}
|
||||
</TypedProductCreateQuery>
|
||||
</SearchProductTypes>
|
||||
)}
|
||||
</SearchCollections>
|
||||
)}
|
||||
|
|
|
@ -24,6 +24,7 @@ storiesOf("Views / Products / Create product", module)
|
|||
collections={product.collections}
|
||||
fetchCategories={() => undefined}
|
||||
fetchCollections={() => undefined}
|
||||
fetchProductTypes={() => undefined}
|
||||
productTypes={productTypes}
|
||||
categories={[product.category]}
|
||||
onAttributesEdit={undefined}
|
||||
|
@ -41,6 +42,7 @@ storiesOf("Views / Products / Create product", module)
|
|||
collections={product.collections}
|
||||
fetchCategories={() => undefined}
|
||||
fetchCollections={() => undefined}
|
||||
fetchProductTypes={() => undefined}
|
||||
productTypes={productTypes}
|
||||
categories={[product.category]}
|
||||
onAttributesEdit={undefined}
|
||||
|
@ -60,6 +62,7 @@ storiesOf("Views / Products / Create product", module)
|
|||
collections={product.collections}
|
||||
fetchCategories={() => undefined}
|
||||
fetchCollections={() => undefined}
|
||||
fetchProductTypes={() => undefined}
|
||||
productTypes={productTypes}
|
||||
categories={[product.category]}
|
||||
onAttributesEdit={undefined}
|
||||
|
|
Loading…
Reference in a new issue