diff --git a/.changeset/large-coins-shout.md b/.changeset/large-coins-shout.md new file mode 100644 index 00000000000..decb9c5f50b --- /dev/null +++ b/.changeset/large-coins-shout.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": patch +--- + +When deleting product type with products the "View products" link now navigates to product list with correctly applied product type filter diff --git a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts index 525b6fd6394..16037fcffc0 100644 --- a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts +++ b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts @@ -14,22 +14,7 @@ import { FetchingParams, OrderFetchingParams, } from "./TokenArray/fetchingParams"; -import { UrlEntry } from "./UrlToken"; - -type Structure = Array; - -const prepareStructure = (filterValue: FilterContainer): Structure => - filterValue.map(f => { - if (typeof f === "string") { - return f; - } - - if (Array.isArray(f)) { - return prepareStructure(f); - } - - return f.asUrlEntry(); - }); +import { prepareStructure } from "./utils"; export const useUrlValueProvider = ( locationSearch: string, diff --git a/src/components/ConditionalFilter/ValueProvider/utils.ts b/src/components/ConditionalFilter/ValueProvider/utils.ts new file mode 100644 index 00000000000..ed504bef8c7 --- /dev/null +++ b/src/components/ConditionalFilter/ValueProvider/utils.ts @@ -0,0 +1,17 @@ +import { FilterContainer } from "../FilterElement"; +import { UrlEntry } from "./UrlToken"; + +type Structure = Array; + +export const prepareStructure = (filterValue: FilterContainer): Structure => + filterValue.map(f => { + if (typeof f === "string") { + return f; + } + + if (Array.isArray(f)) { + return prepareStructure(f); + } + + return f.asUrlEntry(); + }); diff --git a/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx b/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx index 8c0347f77a5..adff4c17350 100644 --- a/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx +++ b/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx @@ -1,21 +1,16 @@ // @ts-strict-ignore import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton"; -import useNavigator from "@dashboard/hooks/useNavigator"; import { buttonMessages } from "@dashboard/intl"; import { getById } from "@dashboard/misc"; import { Box, Spinner } from "@saleor/macaw-ui-next"; import React, { useState } from "react"; import { useIntl } from "react-intl"; +import { Link } from "react-router-dom"; import DeleteButton from "../DeleteButton"; import { DashboardModal } from "../Modal"; import DeleteWarningDialogConsentContent from "./DeleteWarningDialogConsentContent"; -import { CommonTypeDeleteWarningMessages, TypeDeleteWarningMessages } from "./types"; - -export interface TypeBaseData { - id: string; - name: string; -} +import { CommonTypeDeleteWarningMessages, TypeBaseData, TypeDeleteWarningMessages } from "./types"; export interface TypeDeleteMessages { baseMessages: CommonTypeDeleteWarningMessages; @@ -30,13 +25,11 @@ export interface TypeDeleteWarningDialogProps extends Ty deleteButtonState: ConfirmButtonTransitionState; onClose: () => void; onDelete: () => void; - viewAssignedItemsUrl: string; + viewAssignedItemsUrl: string | null; typesToDelete: string[]; assignedItemsCount: number | undefined; - isLoading?: boolean; typesData: T[]; - // temporary, until we add filters to pages list - SALEOR-3279 - showViewAssignedItemsButton?: boolean; + isLoading?: boolean; } function TypeDeleteWarningDialog({ @@ -53,10 +46,8 @@ function TypeDeleteWarningDialog({ viewAssignedItemsUrl, typesToDelete, typesData, - showViewAssignedItemsButton = true, }: TypeDeleteWarningDialogProps) { const intl = useIntl(); - const navigate = useNavigator(); const [isConsentChecked, setIsConsentChecked] = useState(false); const showMultiple = typesToDelete.length > 1; @@ -79,9 +70,10 @@ function TypeDeleteWarningDialog({ }; }; const { description, consentLabel } = selectMessages(); + const singleItemSelectedId = typesToDelete[0]; const singleItemSelectedName = typesData.find(getById(singleItemSelectedId))?.name; - const shouldShowViewAssignedItemsButton = showViewAssignedItemsButton && hasAssignedItems; + const shouldShowViewAssignedItemsButton = hasAssignedItems; return ( @@ -111,12 +103,14 @@ function TypeDeleteWarningDialog({ {shouldShowViewAssignedItemsButton && ( - navigate(viewAssignedItemsUrl)} - transitionState="default" + - {intl.formatMessage(baseMessages.viewAssignedItemsButtonLabel)} - + + {intl.formatMessage(baseMessages.viewAssignedItemsButtonLabel)} + + )} >; + +export interface TypeBaseData { + id: string; + name: string; + slug?: string; +} diff --git a/src/components/TypeDeleteWarningDialog/useViewProducts.test.ts b/src/components/TypeDeleteWarningDialog/useViewProducts.test.ts new file mode 100644 index 00000000000..34882d82875 --- /dev/null +++ b/src/components/TypeDeleteWarningDialog/useViewProducts.test.ts @@ -0,0 +1,52 @@ +import { renderHook } from "@testing-library/react-hooks"; + +import { useViewProducts } from "./useViewProducts"; + +describe("useViewProducts", () => { + const productTypeBaseData = [ + { + id: "123", + name: "Audiobooks", + slug: "audiobooks", + }, + ]; + + it("should return URL with product type filtered", () => { + // Arrange & Act + const { result } = renderHook(() => useViewProducts({ productTypeBaseData })); + + // Assert + expect(result.current).not.toBeNull(); + + const expectedQuery = "0[s0.productType][0]=audiobooks"; + const receivedQuery = decodeURIComponent(result.current!.split("?")[1]); + + expect(receivedQuery).toBe(expectedQuery); + }); + + it("should return URL with product type filtered when multiple product types are selected", () => { + // Arrange + const multipleProductTypeBaseData = [ + ...productTypeBaseData, + { + id: "456", + name: "Shirts", + slug: "shirts", + }, + ]; + + // Act + const { result } = renderHook(() => + useViewProducts({ productTypeBaseData: multipleProductTypeBaseData }), + ); + + // Assert + expect(result.current).not.toBeNull(); + + const expectedQuery = "0[s2.productType][0]=audiobooks&0[s2.productType][1]=shirts"; + + const receivedQuery = decodeURIComponent(result.current!.split("?")[1]); + + expect(receivedQuery).toBe(expectedQuery); + }); +}); diff --git a/src/components/TypeDeleteWarningDialog/useViewProducts.ts b/src/components/TypeDeleteWarningDialog/useViewProducts.ts new file mode 100644 index 00000000000..420636ecf3a --- /dev/null +++ b/src/components/TypeDeleteWarningDialog/useViewProducts.ts @@ -0,0 +1,49 @@ +import { productListPath } from "@dashboard/products/urls"; +import { stringify } from "qs"; +import { useMemo } from "react"; +import urljoin from "url-join"; + +import { FilterElement } from "../ConditionalFilter/FilterElement"; +import { prepareStructure } from "../ConditionalFilter/ValueProvider/utils"; +import { TypeBaseData } from "./types"; + +export interface ProductTypeBaseData extends TypeBaseData { + slug: string; +} + +interface ViewProductsProps { + productTypeBaseData: ProductTypeBaseData[] | undefined; +} + +const baseDataToCondition = (baseData: ProductTypeBaseData) => ({ + label: baseData.name, + slug: baseData.slug, + value: baseData.id, +}); + +export const useViewProducts = ({ productTypeBaseData }: ViewProductsProps) => { + const viewProductsUrl = useMemo(() => { + if (!productTypeBaseData) { + return null; + } + + const productFilterElement = FilterElement.createStaticBySlug("productType"); + + const condition = + productTypeBaseData.length > 1 + ? productFilterElement.condition.options[1] + : productFilterElement.condition.options[0]; // "in" or "is" + + productFilterElement.updateCondition(condition); + + productFilterElement.updateRightOperator(productTypeBaseData.map(baseDataToCondition)); + + const url = stringify({ + ...prepareStructure([productFilterElement]), + }); + + return urljoin(productListPath, `?${url}`); + }, [productTypeBaseData]); + + return viewProductsUrl; +}; diff --git a/src/fragments/productTypes.ts b/src/fragments/productTypes.ts index fdc0c8e1b6c..7cac497a3bf 100644 --- a/src/fragments/productTypes.ts +++ b/src/fragments/productTypes.ts @@ -4,6 +4,7 @@ export const productTypeFragment = gql` fragment ProductType on ProductType { id name + slug kind hasVariants isShippingRequired diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index 9b96831d176..311eed0d480 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -2460,6 +2460,7 @@ export const ProductTypeFragmentDoc = gql` fragment ProductType on ProductType { id name + slug kind hasVariants isShippingRequired diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index a854d7e0f9a..459fa2fe73c 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -10344,9 +10344,9 @@ export type PluginsDetailsFragment = { __typename: 'Plugin', id: string, name: s export type PaymentGatewayFragment = { __typename: 'PaymentGateway', name: string, id: string }; -export type ProductTypeFragment = { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, taxClass: { __typename: 'TaxClass', id: string, name: string } | null }; +export type ProductTypeFragment = { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, taxClass: { __typename: 'TaxClass', id: string, name: string } | null }; -export type ProductTypeDetailsFragment = { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type ProductTypeDetailsFragment = { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; export type StockFragment = { __typename: 'Stock', id: string, quantity: number, quantityAllocated: number, warehouse: { __typename: 'Warehouse', id: string, name: string } }; @@ -11387,7 +11387,7 @@ export type ProductTypeUpdateMutationVariables = Exact<{ }>; -export type ProductTypeUpdateMutation = { __typename: 'Mutation', productTypeUpdate: { __typename: 'ProductTypeUpdate', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type ProductTypeUpdateMutation = { __typename: 'Mutation', productTypeUpdate: { __typename: 'ProductTypeUpdate', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type AssignProductAttributeMutationVariables = Exact<{ id: Scalars['ID']; @@ -11395,7 +11395,7 @@ export type AssignProductAttributeMutationVariables = Exact<{ }>; -export type AssignProductAttributeMutation = { __typename: 'Mutation', productAttributeAssign: { __typename: 'ProductAttributeAssign', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type AssignProductAttributeMutation = { __typename: 'Mutation', productAttributeAssign: { __typename: 'ProductAttributeAssign', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type UnassignProductAttributeMutationVariables = Exact<{ id: Scalars['ID']; @@ -11403,14 +11403,14 @@ export type UnassignProductAttributeMutationVariables = Exact<{ }>; -export type UnassignProductAttributeMutation = { __typename: 'Mutation', productAttributeUnassign: { __typename: 'ProductAttributeUnassign', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type UnassignProductAttributeMutation = { __typename: 'Mutation', productAttributeUnassign: { __typename: 'ProductAttributeUnassign', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type ProductTypeCreateMutationVariables = Exact<{ input: ProductTypeInput; }>; -export type ProductTypeCreateMutation = { __typename: 'Mutation', productTypeCreate: { __typename: 'ProductTypeCreate', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type ProductTypeCreateMutation = { __typename: 'Mutation', productTypeCreate: { __typename: 'ProductTypeCreate', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type ProductTypeAttributeReorderMutationVariables = Exact<{ move: ReorderInput; @@ -11419,7 +11419,7 @@ export type ProductTypeAttributeReorderMutationVariables = Exact<{ }>; -export type ProductTypeAttributeReorderMutation = { __typename: 'Mutation', productTypeReorderAttributes: { __typename: 'ProductTypeReorderAttributes', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type ProductTypeAttributeReorderMutation = { __typename: 'Mutation', productTypeReorderAttributes: { __typename: 'ProductTypeReorderAttributes', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }>, productType: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type ProductAttributeAssignmentUpdateMutationVariables = Exact<{ operations: Array | ProductAttributeAssignmentUpdateInput; @@ -11427,7 +11427,7 @@ export type ProductAttributeAssignmentUpdateMutationVariables = Exact<{ }>; -export type ProductAttributeAssignmentUpdateMutation = { __typename: 'Mutation', productAttributeAssignmentUpdate: { __typename: 'ProductAttributeAssignmentUpdate', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null, attributes: Array | null }>, productType: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type ProductAttributeAssignmentUpdateMutation = { __typename: 'Mutation', productAttributeAssignmentUpdate: { __typename: 'ProductAttributeAssignmentUpdate', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null, attributes: Array | null }>, productType: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type ProductTypeListQueryVariables = Exact<{ after?: InputMaybe; @@ -11439,14 +11439,14 @@ export type ProductTypeListQueryVariables = Exact<{ }>; -export type ProductTypeListQuery = { __typename: 'Query', productTypes: { __typename: 'ProductTypeCountableConnection', edges: Array<{ __typename: 'ProductTypeCountableEdge', node: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, taxClass: { __typename: 'TaxClass', id: string, name: string } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type ProductTypeListQuery = { __typename: 'Query', productTypes: { __typename: 'ProductTypeCountableConnection', edges: Array<{ __typename: 'ProductTypeCountableEdge', node: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, taxClass: { __typename: 'TaxClass', id: string, name: string } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type ProductTypeDetailsQueryVariables = Exact<{ id: Scalars['ID']; }>; -export type ProductTypeDetailsQuery = { __typename: 'Query', productType: { __typename: 'ProductType', id: string, name: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null, shop: { __typename: 'Shop', defaultWeightUnit: WeightUnitsEnum | null } }; +export type ProductTypeDetailsQuery = { __typename: 'Query', productType: { __typename: 'ProductType', id: string, name: string, slug: string, kind: ProductTypeKindEnum, hasVariants: boolean, isShippingRequired: boolean, productAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null }> | null, assignedVariantAttributes: Array<{ __typename: 'AssignedVariantAttribute', variantSelection: boolean, attribute: { __typename: 'Attribute', id: string, name: string | null, slug: string | null, type: AttributeTypeEnum | null, visibleInStorefront: boolean, filterableInDashboard: boolean, filterableInStorefront: boolean, unit: MeasurementUnitsEnum | null, inputType: AttributeInputTypeEnum | null } }> | null, weight: { __typename: 'Weight', unit: WeightUnitsEnum, value: number } | null, taxClass: { __typename: 'TaxClass', id: string, name: string } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null, shop: { __typename: 'Shop', defaultWeightUnit: WeightUnitsEnum | null } }; export type ProductTypeCreateDataQueryVariables = Exact<{ [key: string]: never; }>; diff --git a/src/pageTypes/hooks/usePageTypeDelete/types.ts b/src/pageTypes/hooks/usePageTypeDelete/types.ts index ed4aec49c99..da2ed89e8e9 100644 --- a/src/pageTypes/hooks/usePageTypeDelete/types.ts +++ b/src/pageTypes/hooks/usePageTypeDelete/types.ts @@ -4,7 +4,7 @@ import { Ids } from "@dashboard/types"; export interface UseTypeDeleteData extends TypeDeleteMessages { isOpen: boolean; assignedItemsCount: number | undefined; - viewAssignedItemsUrl: string; + viewAssignedItemsUrl: string | null; isLoading: boolean | undefined; typesToDelete: Ids; } diff --git a/src/pageTypes/views/PageTypeList/PageTypeList.tsx b/src/pageTypes/views/PageTypeList/PageTypeList.tsx index efb6c8ac6d2..5134be2c7c7 100644 --- a/src/pageTypes/views/PageTypeList/PageTypeList.tsx +++ b/src/pageTypes/views/PageTypeList/PageTypeList.tsx @@ -188,7 +188,6 @@ export const PageTypeList: React.FC = ({ params }) => { onClose={closeModal} onDelete={hanldePageTypeBulkDelete} deleteButtonState={pageTypeBulkDeleteOpts.status} - showViewAssignedItemsButton={false} /> )} = - UseTypeDeleteProps; + UseTypeDeleteProps & { typeBaseData: ProductTypeBaseData[] | undefined }; function useProductTypeDelete({ params, singleId, selectedTypes, + typeBaseData, }: UseProductTypeDeleteProps): UseTypeDeleteData { - const productTypes = selectedTypes || [singleId]; + const productTypes = useMemo(() => selectedTypes || [singleId], [selectedTypes, singleId]); + + const filteredTypes = productTypes.filter((type): type is string => !!type); + const isDeleteDialogOpen = params.action === "remove"; - const productsAssignedToSelectedTypesQueryVars = React.useMemo( - () => ({ - filter: { - productTypes, - }, - }), + const productsAssignedToSelectedTypesQueryVars = useMemo( + () => + filteredTypes.length + ? { + filter: { + productTypes: filteredTypes, + }, + } + : {}, [productTypes], ); const shouldSkipProductListQuery = !productTypes.length || !isDeleteDialogOpen; @@ -39,18 +49,24 @@ function useProductTypeDelete({ variables: productsAssignedToSelectedTypesQueryVars, skip: shouldSkipProductListQuery, }); - const selectedProductsAssignedToDeleteUrl = productListUrl({ - productTypes, + + const typesToLink = Array.isArray(typeBaseData) + ? typeBaseData.filter((type: TypeBaseData) => productTypes.includes(type.id)) + : undefined; + + const viewProductsURL = useViewProducts({ + productTypeBaseData: typesToLink, }); + const assignedItemsCount = productsAssignedToSelectedTypesData?.products?.totalCount; return { ...messages, isOpen: isDeleteDialogOpen, - assignedItemsCount, - viewAssignedItemsUrl: selectedProductsAssignedToDeleteUrl, + assignedItemsCount: assignedItemsCount ?? undefined, + viewAssignedItemsUrl: viewProductsURL, isLoading: loadingProductsAssignedToSelectedTypes, - typesToDelete: productTypes, + typesToDelete: filteredTypes, }; } diff --git a/src/productTypes/views/ProductTypeList/ProductTypeList.tsx b/src/productTypes/views/ProductTypeList/ProductTypeList.tsx index 77448cd6265..c9f41c7cc9e 100644 --- a/src/productTypes/views/ProductTypeList/ProductTypeList.tsx +++ b/src/productTypes/views/ProductTypeList/ProductTypeList.tsx @@ -114,11 +114,13 @@ export const ProductTypeList: React.FC = ({ params }) => { queryString: params, }); const handleSort = createSortHandler(navigate, productTypeListUrl, params); + const productTypesData = mapEdgesToItems(data?.productTypes); + const productTypeDeleteData = useProductTypeDelete({ selectedTypes: selectedProductTypes, params, + typeBaseData: productTypesData, }); - const productTypesData = mapEdgesToItems(data?.productTypes); const [productTypeBulkDelete, productTypeBulkDeleteOpts] = useProductTypeBulkDeleteMutation({ onCompleted: data => { if (data.productTypeBulkDelete.errors.length === 0) { diff --git a/src/productTypes/views/ProductTypeUpdate/index.tsx b/src/productTypes/views/ProductTypeUpdate/index.tsx index 49acc4e41a6..cff74d69867 100644 --- a/src/productTypes/views/ProductTypeUpdate/index.tsx +++ b/src/productTypes/views/ProductTypeUpdate/index.tsx @@ -131,16 +131,18 @@ export const ProductTypeUpdate: React.FC = ({ id, params ...productAttributeUpdateResult.data.productAttributeAssignmentUpdate.errors, ]; }; - const productTypeDeleteData = useProductTypeDelete({ - singleId: id, - params, - }); const { data, loading: dataLoading } = useProductTypeDetailsQuery({ displayLoader: true, variables: { id }, }); const { taxClasses, fetchMoreTaxClasses } = useTaxClassFetchMore(); const productType = data?.productType; + + const productTypeDeleteData = useProductTypeDelete({ + singleId: id, + params, + typeBaseData: productType ? [productType] : undefined, + }); const closeModal = () => navigate(productTypeUrl(id), { replace: true }); const handleAttributeAssignSuccess = (data: AssignProductAttributeMutation) => { if (data.productAttributeAssign.errors.length === 0) {