From 123631fd0d269a07b798750e06eadbbc55c16aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 12 Sep 2023 14:04:41 +0200 Subject: [PATCH 01/67] Init voucher codes datagrid --- .../VoucherCodesDatagrid.tsx | 79 +++++++++++++++++++ .../VoucherCodesDatagrid/datagrid.ts | 47 +++++++++++ .../components/VoucherCodesDatagrid/index.ts | 1 + .../VoucherCodesDatagrid/messages.ts | 23 ++++++ .../components/VoucherCodesDatagrid/types.ts | 5 ++ .../VoucherDetailsPage/VoucherDetailsPage.tsx | 10 +++ 6 files changed, 165 insertions(+) create mode 100644 src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx create mode 100644 src/discounts/components/VoucherCodesDatagrid/datagrid.ts create mode 100644 src/discounts/components/VoucherCodesDatagrid/index.ts create mode 100644 src/discounts/components/VoucherCodesDatagrid/messages.ts create mode 100644 src/discounts/components/VoucherCodesDatagrid/types.ts diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx new file mode 100644 index 00000000000..eeefc2e5165 --- /dev/null +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -0,0 +1,79 @@ +import { useColumns } from "@dashboard/components/Datagrid/ColumnPicker/useColumns"; +import Datagrid from "@dashboard/components/Datagrid/Datagrid"; +import { + DatagridChangeStateContext, + useDatagridChangeState, +} from "@dashboard/components/Datagrid/hooks/useDatagridChange"; +import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; +import { Box } from "@saleor/macaw-ui/next"; +import React, { useCallback, useMemo } from "react"; +import { useIntl } from "react-intl"; + +import { + createGetCellContent, + voucherCodesStaticColumnsAdapter, +} from "./datagrid"; +import { messages } from "./messages"; +import { VoucherCode } from "./types"; + +interface VoucherCodesDatagridProps { + codes: VoucherCode[]; + loading: boolean; + disabled?: boolean; +} + +export const VoucherCodesDatagrid = ({ + codes, + loading, + disabled, +}: VoucherCodesDatagridProps) => { + const intl = useIntl(); + const datagrid = useDatagridChangeState(); + + const voucherCodesStaticColumns = useMemo( + () => voucherCodesStaticColumnsAdapter(intl), + [intl], + ); + + const { handlers, visibleColumns } = useColumns({ + staticColumns: voucherCodesStaticColumns, + selectedColumns: ["code", "usage", "limit"], + onSave: () => {}, + }); + + const getCellContent = useCallback( + createGetCellContent(codes, visibleColumns), + [codes, visibleColumns], + ); + + return ( + + col > 0} + rows={codes?.length ?? 0} + availableColumns={visibleColumns} + emptyText={intl.formatMessage(messages.empty)} + getCellContent={getCellContent} + getCellError={() => false} + selectionActions={() => null} + menuItems={() => []} + /> + + + {}} + /> + + + ); +}; diff --git a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts new file mode 100644 index 00000000000..8e77b096641 --- /dev/null +++ b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts @@ -0,0 +1,47 @@ +import { readonlyTextCell } from "@dashboard/components/Datagrid/customCells/cells"; +import { AvailableColumn } from "@dashboard/components/Datagrid/types"; +import { GridCell, Item } from "@glideapps/glide-data-grid"; +import { IntlShape } from "react-intl"; + +import { columnsMessages } from "./messages"; +import { VoucherCode } from "./types"; + +export const voucherCodesStaticColumnsAdapter = (intl: IntlShape) => [ + { + id: "code", + title: intl.formatMessage(columnsMessages.code), + width: 300, + }, + { + id: "usage", + title: intl.formatMessage(columnsMessages.usage), + width: 150, + }, + { + id: "limit", + title: intl.formatMessage(columnsMessages.limit), + width: 150, + }, +]; + +export const createGetCellContent = + (voucherCodes: VoucherCode[], columns: AvailableColumn[]) => + ([column, row]: Item): GridCell => { + const columnId = columns[column]?.id; + const rowData: VoucherCode | undefined = voucherCodes[row]; + + if (!columnId || !rowData) { + return readonlyTextCell(""); + } + + switch (columnId) { + case "code": + return readonlyTextCell(rowData?.code ?? ""); + case "usage": + return readonlyTextCell(rowData?.usage ?? ""); + case "limit": + return readonlyTextCell(rowData?.limit ?? ""); + default: + return readonlyTextCell("", false); + } + }; diff --git a/src/discounts/components/VoucherCodesDatagrid/index.ts b/src/discounts/components/VoucherCodesDatagrid/index.ts new file mode 100644 index 00000000000..1e4764f0d52 --- /dev/null +++ b/src/discounts/components/VoucherCodesDatagrid/index.ts @@ -0,0 +1 @@ +export * from "./VoucherCodesDatagrid"; diff --git a/src/discounts/components/VoucherCodesDatagrid/messages.ts b/src/discounts/components/VoucherCodesDatagrid/messages.ts new file mode 100644 index 00000000000..f04acaad45b --- /dev/null +++ b/src/discounts/components/VoucherCodesDatagrid/messages.ts @@ -0,0 +1,23 @@ +import { defineMessages } from "react-intl"; + +export const columnsMessages = defineMessages({ + code: { + defaultMessage: "Code", + id: "h2vipu", + }, + usage: { + defaultMessage: "Usage", + id: "wbsq7O", + }, + limit: { + defaultMessage: "Limit", + id: "YH6meO", + }, +}); + +export const messages = defineMessages({ + empty: { + defaultMessage: "No voucher codes found", + id: "KkufwD", + }, +}); diff --git a/src/discounts/components/VoucherCodesDatagrid/types.ts b/src/discounts/components/VoucherCodesDatagrid/types.ts new file mode 100644 index 00000000000..42ea2777600 --- /dev/null +++ b/src/discounts/components/VoucherCodesDatagrid/types.ts @@ -0,0 +1,5 @@ +export interface VoucherCode { + code: string; + usage: string; + limit: string; +} diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 7e10057e958..49359692aad 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -41,6 +41,7 @@ import DiscountCategories from "../DiscountCategories"; import DiscountCollections from "../DiscountCollections"; import DiscountDates from "../DiscountDates"; import DiscountProducts from "../DiscountProducts"; +import { VoucherCodesDatagrid } from "../VoucherCodesDatagrid"; import VoucherInfo from "../VoucherInfo"; import VoucherLimits from "../VoucherLimits"; import VoucherRequirements from "../VoucherRequirements"; @@ -219,6 +220,15 @@ const VoucherDetailsPage: React.FC = ({ onChange={change} variant="update" /> + Date: Tue, 12 Sep 2023 16:07:12 +0200 Subject: [PATCH 02/67] Submenu --- src/components/SubMenu/SubMenu.tsx | 43 ++++++++++++++++ src/components/SubMenu/index.ts | 1 + .../VoucherCodesDatagrid.tsx | 50 ++++++++++++++++++- 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/components/SubMenu/SubMenu.tsx create mode 100644 src/components/SubMenu/index.ts diff --git a/src/components/SubMenu/SubMenu.tsx b/src/components/SubMenu/SubMenu.tsx new file mode 100644 index 00000000000..55d857bd414 --- /dev/null +++ b/src/components/SubMenu/SubMenu.tsx @@ -0,0 +1,43 @@ +import { List, Text } from "@saleor/macaw-ui/next"; +import React, { ReactNode } from "react"; + +export interface MenuItem { + id: string; + title: ReactNode; + description: ReactNode; + onClick: () => void; +} + +interface SubMenuProps { + menuItems: MenuItem[]; +} + +export const SubMenu = ({ menuItems }: SubMenuProps) => { + return ( + + {menuItems.map(({ id, title, description, onClick }, idx) => { + const isLastItem = idx === menuItems.length - 1; + + return ( + + {title} + {description} + + ); + })} + + ); +}; diff --git a/src/components/SubMenu/index.ts b/src/components/SubMenu/index.ts new file mode 100644 index 00000000000..6536d21bfa5 --- /dev/null +++ b/src/components/SubMenu/index.ts @@ -0,0 +1 @@ +export * from "./SubMenu"; diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index eeefc2e5165..30d4bf91569 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -4,9 +4,16 @@ import { DatagridChangeStateContext, useDatagridChangeState, } from "@dashboard/components/Datagrid/hooks/useDatagridChange"; +import { SubMenu } from "@dashboard/components/SubMenu"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; -import { Box } from "@saleor/macaw-ui/next"; -import React, { useCallback, useMemo } from "react"; +import { + Box, + DropdownButton, + PlusIcon, + Popover, + Text, +} from "@saleor/macaw-ui/next"; +import React, { useCallback, useMemo, useState } from "react"; import { useIntl } from "react-intl"; import { @@ -29,6 +36,7 @@ export const VoucherCodesDatagrid = ({ }: VoucherCodesDatagridProps) => { const intl = useIntl(); const datagrid = useDatagridChangeState(); + const [isSubMenuOpen, setSubMenuOpen] = useState(false); const voucherCodesStaticColumns = useMemo( () => voucherCodesStaticColumnsAdapter(intl), @@ -46,8 +54,46 @@ export const VoucherCodesDatagrid = ({ [codes, visibleColumns], ); + const handleAutoGenerateCodes = useCallback(() => { + setSubMenuOpen(false); + }, []); + + const subMenuItems = useMemo( + () => [ + { + id: "auto-generate-codes", + title: "Auto-generate codes", + description: "Generate multiple codes at once", + onClick: handleAutoGenerateCodes, + }, + ], + [handleAutoGenerateCodes], + ); + return ( + + Voucher codes + + + + + Add code + + + + + + + + + Date: Wed, 13 Sep 2023 12:35:10 +0200 Subject: [PATCH 03/67] Change dropdown button --- .../VoucherCodesDatagrid/VoucherCodesDatagrid.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 30d4bf91569..1356bc09ec4 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -7,8 +7,9 @@ import { import { SubMenu } from "@dashboard/components/SubMenu"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; import { + ArrowDownIcon, Box, - DropdownButton, + Button, PlusIcon, Popover, Text, @@ -82,10 +83,15 @@ export const VoucherCodesDatagrid = ({ Voucher codes - + From b9870ef10d69737024c734257223c7182b177400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 13 Sep 2023 13:05:30 +0200 Subject: [PATCH 04/67] Delete voucher codes dialog --- .../VoucherCodesDatagrid.tsx | 14 ++++- .../VoucherCodesDeleteDialog.tsx | 57 +++++++++++++++++++ .../VoucherCodesDeleteDialog/index.ts | 1 + .../VoucherDetailsPage/VoucherDetailsPage.tsx | 5 ++ src/discounts/urls.ts | 2 + .../views/VoucherDetails/VoucherDetails.tsx | 7 +++ 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx create mode 100644 src/discounts/components/VoucherCodesDeleteDialog/index.ts diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 1356bc09ec4..7a127bbf21c 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -6,6 +6,7 @@ import { } from "@dashboard/components/Datagrid/hooks/useDatagridChange"; import { SubMenu } from "@dashboard/components/SubMenu"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; +import { buttonMessages } from "@dashboard/intl"; import { ArrowDownIcon, Box, @@ -13,6 +14,7 @@ import { PlusIcon, Popover, Text, + TrashBinIcon, } from "@saleor/macaw-ui/next"; import React, { useCallback, useMemo, useState } from "react"; import { useIntl } from "react-intl"; @@ -28,12 +30,14 @@ interface VoucherCodesDatagridProps { codes: VoucherCode[]; loading: boolean; disabled?: boolean; + onVoucherCodeDelete: (code: string) => void; } export const VoucherCodesDatagrid = ({ codes, loading, disabled, + onVoucherCodeDelete, }: VoucherCodesDatagridProps) => { const intl = useIntl(); const datagrid = useDatagridChangeState(); @@ -115,7 +119,15 @@ export const VoucherCodesDatagrid = ({ getCellContent={getCellContent} getCellError={() => false} selectionActions={() => null} - menuItems={() => []} + menuItems={index => [ + { + label: intl.formatMessage(buttonMessages.delete), + onSelect: () => { + onVoucherCodeDelete(codes[index].code); + }, + Icon: , + }, + ]} /> diff --git a/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx new file mode 100644 index 00000000000..7428b033709 --- /dev/null +++ b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx @@ -0,0 +1,57 @@ +import { DashboardCard } from "@dashboard/components/Card"; +import { buttonMessages } from "@dashboard/intl"; +import { Box, Button, Modal, Text } from "@saleor/macaw-ui/next"; +import React from "react"; +import { useIntl } from "react-intl"; + +interface VoucherCodesDeleteDialogProps { + open: boolean; + onClose: () => void; + onDelete: () => void; +} + +export const VoucherCodesDeleteDialog = ({ + open, + onClose, + onDelete, +}: VoucherCodesDeleteDialogProps) => { + const intl = useIntl(); + + return ( + + + + + Delete voucher code + + + Are you sure you want to delete this voucher code? + + + + + + + + + + + ); +}; diff --git a/src/discounts/components/VoucherCodesDeleteDialog/index.ts b/src/discounts/components/VoucherCodesDeleteDialog/index.ts new file mode 100644 index 00000000000..388916b8597 --- /dev/null +++ b/src/discounts/components/VoucherCodesDeleteDialog/index.ts @@ -0,0 +1 @@ +export * from "./VoucherCodesDeleteDialog"; diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 49359692aad..b197a2854e6 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -105,6 +105,7 @@ export interface VoucherDetailsPageProps onTabClick: (index: VoucherDetailsPageTab) => void; onChannelsChange: (data: ChannelVoucherData[]) => void; openChannelsModal: () => void; + onDeleteVoucherCodes: () => void; } const CategoriesTab = Tab(VoucherDetailsPageTab.categories); @@ -132,6 +133,7 @@ const VoucherDetailsPage: React.FC = ({ onTabClick, openChannelsModal, onRemove, + onDeleteVoucherCodes, onSubmit, toggle, toggleAll, @@ -222,6 +224,9 @@ const VoucherDetailsPage: React.FC = ({ /> { + onDeleteVoucherCodes(); + }} disabled={disabled} codes={[ { code: "Code 1", usage: "1", limit: "1" }, diff --git a/src/discounts/urls.ts b/src/discounts/urls.ts index 87dc61754f0..b867bc70929 100644 --- a/src/discounts/urls.ts +++ b/src/discounts/urls.ts @@ -111,6 +111,8 @@ export type VoucherUrlDialog = | "unassign-collection" | "unassign-product" | "remove" + | "delete-codes" + | "generate-codes" | ChannelsAction; export type VoucherUrlQueryParams = BulkAction & Dialog; export type VoucherCreateUrlQueryParams = Dialog; diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 74482eba43e..503a48a9957 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -14,6 +14,7 @@ import ChannelsAvailabilityDialog from "@dashboard/components/ChannelsAvailabili import { WindowTitle } from "@dashboard/components/WindowTitle"; import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@dashboard/config"; import DiscountCountrySelectDialog from "@dashboard/discounts/components/DiscountCountrySelectDialog"; +import { VoucherCodesDeleteDialog } from "@dashboard/discounts/components/VoucherCodesDeleteDialog"; import VoucherDetailsPage, { VoucherDetailsPageTab, VoucherTabItemsCount, @@ -353,6 +354,7 @@ export const VoucherDetails: React.FC = ({ ids: [productId], }) } + onDeleteVoucherCodes={() => openModal("delete-codes")} activeTab={activeTab} tabItemsCount={tabItemsCount} onTabClick={changeTab} @@ -411,6 +413,11 @@ export const VoucherDetails: React.FC = ({ toggle={toggle} toggleAll={toggleAll} /> + {}} + /> suggestedCategory.id, From 5425cf02699f377151f6f0dfa6a93edef963a951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 13 Sep 2023 13:50:00 +0200 Subject: [PATCH 05/67] Generate voucher codes dialog --- .../VoucherCodesDatagrid.tsx | 3 + .../VoucherCodesDeleteDialog.tsx | 2 +- .../VoucherCodesGenerateDialog.tsx | 81 +++++++++++++++++++ .../VoucherCodesGenerateDialog/index.ts | 1 + .../VoucherDetailsPage/VoucherDetailsPage.tsx | 3 + .../views/VoucherDetails/VoucherDetails.tsx | 7 ++ 6 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx create mode 100644 src/discounts/components/VoucherCodesGenerateDialog/index.ts diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 7a127bbf21c..2e8ae2d8114 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -31,12 +31,14 @@ interface VoucherCodesDatagridProps { loading: boolean; disabled?: boolean; onVoucherCodeDelete: (code: string) => void; + onGenerateVoucherCodes: () => void; } export const VoucherCodesDatagrid = ({ codes, loading, disabled, + onGenerateVoucherCodes, onVoucherCodeDelete, }: VoucherCodesDatagridProps) => { const intl = useIntl(); @@ -60,6 +62,7 @@ export const VoucherCodesDatagrid = ({ ); const handleAutoGenerateCodes = useCallback(() => { + onGenerateVoucherCodes(); setSubMenuOpen(false); }, []); diff --git a/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx index 7428b033709..e44446d7253 100644 --- a/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx +++ b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx @@ -42,7 +42,7 @@ export const VoucherCodesDeleteDialog = ({ paddingBottom={6} > + + + + + + + + ); +}; diff --git a/src/discounts/components/VoucherCodesGenerateDialog/index.ts b/src/discounts/components/VoucherCodesGenerateDialog/index.ts new file mode 100644 index 00000000000..9510a4efd70 --- /dev/null +++ b/src/discounts/components/VoucherCodesGenerateDialog/index.ts @@ -0,0 +1 @@ +export * from "./VoucherCodesGenerateDialog"; diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index b197a2854e6..57f7889df8a 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -106,6 +106,7 @@ export interface VoucherDetailsPageProps onChannelsChange: (data: ChannelVoucherData[]) => void; openChannelsModal: () => void; onDeleteVoucherCodes: () => void; + onGenerateVoucherCodes: () => void; } const CategoriesTab = Tab(VoucherDetailsPageTab.categories); @@ -134,6 +135,7 @@ const VoucherDetailsPage: React.FC = ({ openChannelsModal, onRemove, onDeleteVoucherCodes, + onGenerateVoucherCodes, onSubmit, toggle, toggleAll, @@ -224,6 +226,7 @@ const VoucherDetailsPage: React.FC = ({ /> { onDeleteVoucherCodes(); }} diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 503a48a9957..d4a145f4204 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -15,6 +15,7 @@ import { WindowTitle } from "@dashboard/components/WindowTitle"; import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@dashboard/config"; import DiscountCountrySelectDialog from "@dashboard/discounts/components/DiscountCountrySelectDialog"; import { VoucherCodesDeleteDialog } from "@dashboard/discounts/components/VoucherCodesDeleteDialog"; +import { VoucherCodesGenerateDialog } from "@dashboard/discounts/components/VoucherCodesGenerateDialog"; import VoucherDetailsPage, { VoucherDetailsPageTab, VoucherTabItemsCount, @@ -355,6 +356,7 @@ export const VoucherDetails: React.FC = ({ }) } onDeleteVoucherCodes={() => openModal("delete-codes")} + onGenerateVoucherCodes={() => openModal("generate-codes")} activeTab={activeTab} tabItemsCount={tabItemsCount} onTabClick={changeTab} @@ -418,6 +420,11 @@ export const VoucherDetails: React.FC = ({ onClose={closeModal} onDelete={() => {}} /> + {}} + /> suggestedCategory.id, From c69b6f7065226773fd73b840af8b200ba69d37e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 14 Sep 2023 11:02:43 +0200 Subject: [PATCH 06/67] Allow only dgits in voucher generate modal quantity field --- .../VoucherCodesGenerateDialog.tsx | 34 ++++++++++++++----- .../VoucherDetailsPage/VoucherDetailsPage.tsx | 4 +-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx index 68fb52649b1..f4d6a5eee20 100644 --- a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx +++ b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx @@ -25,14 +25,28 @@ export const VoucherCodesGenerateDialog = ({ onSubmit, ); + const handleKeyDown = (e: React.KeyboardEvent) => { + if ( + /\D/.test(e.key) && + ![ + "Backspace", + "ArrowDown", + "ArrowUp", + "ArrowLeft", + "ArrowRight", + ].includes(e.key) + ) { + e.preventDefault(); + } + }; + + const handleModalClose = () => { + onClose(); + reset(); + }; + return ( - { - onClose(); - reset(); - }} - > + @@ -65,7 +83,7 @@ export const VoucherCodesGenerateDialog = ({ gap={3} paddingBottom={6} > - - - - - + + + Generate voucher codes + + + - - + + + + + + ); }; diff --git a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx new file mode 100644 index 00000000000..6a1905c736e --- /dev/null +++ b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx @@ -0,0 +1,57 @@ +import { DashboardModal } from "@dashboard/components/Modal"; +import useForm from "@dashboard/hooks/useForm"; +import { buttonMessages } from "@dashboard/intl"; +import { Box, Button, Input } from "@saleor/macaw-ui/next"; +import React from "react"; +import { useIntl } from "react-intl"; + +interface VoucherCodesManualDialogProps { + open: boolean; + onClose: () => void; + onSubmit: () => void; +} + +export const VoucherCodesManualDialog = ({ + open, + onClose, + onSubmit, +}: VoucherCodesManualDialogProps) => { + const intl = useIntl(); + const { change, submit, data, reset } = useForm( + { + quantity: "", + prefix: "", + }, + onSubmit, + ); + + const handleModalClose = () => { + onClose(); + reset(); + }; + + return ( + + + Enter Voucher Code + + + + + + + + + + ); +}; diff --git a/src/discounts/components/VoucherCodesManualDialog/index.ts b/src/discounts/components/VoucherCodesManualDialog/index.ts new file mode 100644 index 00000000000..05132380172 --- /dev/null +++ b/src/discounts/components/VoucherCodesManualDialog/index.ts @@ -0,0 +1 @@ +export * from "./VoucherCodesManualDialog"; diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 919b4c524e2..66b62e5bc60 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -106,7 +106,8 @@ export interface VoucherDetailsPageProps onChannelsChange: (data: ChannelVoucherData[]) => void; openChannelsModal: () => void; onDeleteVoucherCodes: () => void; - onGenerateVoucherCodes: () => void; + onAutoVoucheCodesGenerate: () => void; + onManualVoucherCodeGenerate: () => void; } const CategoriesTab = Tab(VoucherDetailsPageTab.categories); @@ -135,7 +136,8 @@ const VoucherDetailsPage: React.FC = ({ openChannelsModal, onRemove, onDeleteVoucherCodes, - onGenerateVoucherCodes, + onAutoVoucheCodesGenerate, + onManualVoucherCodeGenerate, onSubmit, toggle, toggleAll, @@ -226,7 +228,8 @@ const VoucherDetailsPage: React.FC = ({ /> ; export type VoucherCreateUrlQueryParams = Dialog; diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index d4a145f4204..9a080595723 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -16,6 +16,7 @@ import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@dashboard/config"; import DiscountCountrySelectDialog from "@dashboard/discounts/components/DiscountCountrySelectDialog"; import { VoucherCodesDeleteDialog } from "@dashboard/discounts/components/VoucherCodesDeleteDialog"; import { VoucherCodesGenerateDialog } from "@dashboard/discounts/components/VoucherCodesGenerateDialog"; +import { VoucherCodesManualDialog } from "@dashboard/discounts/components/VoucherCodesManualDialog"; import VoucherDetailsPage, { VoucherDetailsPageTab, VoucherTabItemsCount, @@ -356,7 +357,8 @@ export const VoucherDetails: React.FC = ({ }) } onDeleteVoucherCodes={() => openModal("delete-codes")} - onGenerateVoucherCodes={() => openModal("generate-codes")} + onAutoVoucheCodesGenerate={() => openModal("generate-codes")} + onManualVoucherCodeGenerate={() => openModal("manual-codes")} activeTab={activeTab} tabItemsCount={tabItemsCount} onTabClick={changeTab} @@ -425,6 +427,11 @@ export const VoucherDetails: React.FC = ({ onClose={closeModal} onSubmit={() => {}} /> + {}} + /> suggestedCategory.id, From e3f55a157c1d708363f948859b1049d7aac7205b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 20 Sep 2023 15:22:43 +0200 Subject: [PATCH 12/67] Add manual voucher code --- .../VoucherCodesManualDialog.tsx | 54 ++++++++++++++----- .../VoucherDetailsPage/VoucherDetailsPage.tsx | 3 ++ .../views/VoucherDetails/VoucherDetails.tsx | 17 ++++-- .../views/VoucherDetails/handlers.ts | 1 - 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx index 6a1905c736e..0adecdaed70 100644 --- a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx +++ b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx @@ -1,5 +1,9 @@ +import { + ConfirmButton, + ConfirmButtonTransitionState, +} from "@dashboard/components/ConfirmButton"; import { DashboardModal } from "@dashboard/components/Modal"; -import useForm from "@dashboard/hooks/useForm"; +import { VoucherInput } from "@dashboard/graphql"; import { buttonMessages } from "@dashboard/intl"; import { Box, Button, Input } from "@saleor/macaw-ui/next"; import React from "react"; @@ -7,49 +11,71 @@ import { useIntl } from "react-intl"; interface VoucherCodesManualDialogProps { open: boolean; + confirmButtonTransitionState: ConfirmButtonTransitionState; onClose: () => void; - onSubmit: () => void; + onSubmit: (codes: VoucherInput["codes"]) => void; } export const VoucherCodesManualDialog = ({ open, + confirmButtonTransitionState, onClose, onSubmit, }: VoucherCodesManualDialogProps) => { const intl = useIntl(); - const { change, submit, data, reset } = useForm( - { - quantity: "", - prefix: "", - }, - onSubmit, - ); + + const [quantity, setQuantity] = React.useState(""); + const [usage, setUsage] = React.useState(""); + + const reset = () => { + setQuantity(""); + setUsage(""); + }; const handleModalClose = () => { onClose(); reset(); }; + const handleSubmit = () => { + onClose(); + onSubmit([{ code: quantity, usageLimit: Number(usage) }]); + reset(); + }; + return ( Enter Voucher Code - + setQuantity(e.target.value)} + /> + + setUsage(e.target.value)} /> - + diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 66b62e5bc60..0292678a600 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -25,6 +25,7 @@ import { DiscountErrorFragment, DiscountValueTypeEnum, PermissionEnum, + VoucherCodeFragment, VoucherDetailsFragment, VoucherTypeEnum, } from "@dashboard/graphql"; @@ -65,6 +66,7 @@ export interface VoucherDetailsPageFormData extends MetadataFormData { onlyForStaff: boolean; channelListings: ChannelVoucherData[]; code: string; + codes: VoucherCodeFragment[]; discountType: DiscountTypeEnum; endDate: string; endTime: string; @@ -182,6 +184,7 @@ const VoucherDetailsPage: React.FC = ({ onlyForStaff: voucher?.onlyForStaff || false, channelListings, code: voucher?.code || "", + codes: mapEdgesToItems(voucher?.codes) ?? [], discountType, endDate: splitDateTime(voucher?.endDate ?? "").date, endTime: splitDateTime(voucher?.endDate ?? "").time, diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 9a080595723..7226acb3d79 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -420,17 +420,28 @@ export const VoucherDetails: React.FC = ({ {}} + onDelete={closeModal} /> {}} + onSubmit={closeModal} /> {}} + onSubmit={codes => + voucherUpdate({ + variables: { + ...paginationState, + id, + input: { + codes, + }, + }, + }) + } /> data?.voucherUpdate.errors ?? []), From 81291aa5f3da541ce512042866da99e2b347dac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 20 Sep 2023 15:27:19 +0200 Subject: [PATCH 13/67] Update prosp and fixtures --- .../VoucherDetailsPage/VoucherDetailsPage.stories.tsx | 3 ++- .../components/VoucherDetailsPage/VoucherDetailsPage.tsx | 3 --- src/discounts/fixtures.ts | 4 ++++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx index 83f09a7cb12..69d0a625413 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx @@ -21,7 +21,8 @@ const channels = createChannelsDataWithDiscountPrice( const props: VoucherDetailsPageProps = { ...listActionsProps, ...pageListProps.default, - onGenerateVoucherCodes: () => undefined, + onAutoVoucheCodesGenerate: () => undefined, + onManualVoucherCodeGenerate: () => undefined, onDeleteVoucherCodes: () => undefined, activeTab: VoucherDetailsPageTab.products, tabItemsCount: { diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 0292678a600..66b62e5bc60 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -25,7 +25,6 @@ import { DiscountErrorFragment, DiscountValueTypeEnum, PermissionEnum, - VoucherCodeFragment, VoucherDetailsFragment, VoucherTypeEnum, } from "@dashboard/graphql"; @@ -66,7 +65,6 @@ export interface VoucherDetailsPageFormData extends MetadataFormData { onlyForStaff: boolean; channelListings: ChannelVoucherData[]; code: string; - codes: VoucherCodeFragment[]; discountType: DiscountTypeEnum; endDate: string; endTime: string; @@ -184,7 +182,6 @@ const VoucherDetailsPage: React.FC = ({ onlyForStaff: voucher?.onlyForStaff || false, channelListings, code: voucher?.code || "", - codes: mapEdgesToItems(voucher?.codes) ?? [], discountType, endDate: splitDateTime(voucher?.endDate ?? "").date, endTime: splitDateTime(voucher?.endDate ?? "").time, diff --git a/src/discounts/fixtures.ts b/src/discounts/fixtures.ts index 4c0b88c7c31..6c555cf4fcd 100644 --- a/src/discounts/fixtures.ts +++ b/src/discounts/fixtures.ts @@ -583,6 +583,10 @@ export const sale: SaleDetailsFragment = { export const voucherDetails: VoucherDetailsFragment = { __typename: "Voucher", metadata: [], + codes: { + __typename: "VoucherCodeCountableConnection", + edges: [], + }, privateMetadata: [], applyOncePerCustomer: false, applyOncePerOrder: false, From c5c8720672858d86f03bab84c77947a0160380e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 20 Sep 2023 15:28:54 +0200 Subject: [PATCH 14/67] Remove delete codes from datgrid menu item --- .../VoucherCodesDatagrid/VoucherCodesDatagrid.tsx | 14 +------------- .../VoucherDetailsPage.stories.tsx | 1 - .../VoucherDetailsPage/VoucherDetailsPage.tsx | 3 --- .../views/VoucherDetails/VoucherDetails.tsx | 1 - 4 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 77ca071e8ab..d9c4878c672 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -7,7 +7,6 @@ import { import { SubMenu } from "@dashboard/components/SubMenu"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; import { VoucherCodeFragment } from "@dashboard/graphql"; -import { buttonMessages } from "@dashboard/intl"; import { ArrowDownIcon, Box, @@ -15,7 +14,6 @@ import { PlusIcon, Popover, Text, - TrashBinIcon, } from "@saleor/macaw-ui/next"; import React, { useCallback, useMemo, useState } from "react"; import { useIntl } from "react-intl"; @@ -30,7 +28,6 @@ interface VoucherCodesDatagridProps { codes: VoucherCodeFragment[]; loading: boolean; disabled?: boolean; - onVoucherCodeDelete: (code: string) => void; onAutoVoucheCodesGenerate: () => void; onManualVoucherCodeGenerate: () => void; } @@ -41,7 +38,6 @@ export const VoucherCodesDatagrid = ({ disabled, onAutoVoucheCodesGenerate, onManualVoucherCodeGenerate, - onVoucherCodeDelete, }: VoucherCodesDatagridProps) => { const intl = useIntl(); const datagrid = useDatagridChangeState(); @@ -135,15 +131,7 @@ export const VoucherCodesDatagrid = ({ getCellContent={getCellContent} getCellError={() => false} selectionActions={() => null} - menuItems={index => [ - { - label: intl.formatMessage(buttonMessages.delete), - onSelect: () => { - onVoucherCodeDelete(codes[index].code); - }, - Icon: , - }, - ]} + menuItems={() => []} /> diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx index 69d0a625413..ba93993c255 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx @@ -23,7 +23,6 @@ const props: VoucherDetailsPageProps = { ...pageListProps.default, onAutoVoucheCodesGenerate: () => undefined, onManualVoucherCodeGenerate: () => undefined, - onDeleteVoucherCodes: () => undefined, activeTab: VoucherDetailsPageTab.products, tabItemsCount: { [VoucherDetailsPageTab.categories]: diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 66b62e5bc60..096e519dd3a 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -105,7 +105,6 @@ export interface VoucherDetailsPageProps onTabClick: (index: VoucherDetailsPageTab) => void; onChannelsChange: (data: ChannelVoucherData[]) => void; openChannelsModal: () => void; - onDeleteVoucherCodes: () => void; onAutoVoucheCodesGenerate: () => void; onManualVoucherCodeGenerate: () => void; } @@ -135,7 +134,6 @@ const VoucherDetailsPage: React.FC = ({ onTabClick, openChannelsModal, onRemove, - onDeleteVoucherCodes, onAutoVoucheCodesGenerate, onManualVoucherCodeGenerate, onSubmit, @@ -230,7 +228,6 @@ const VoucherDetailsPage: React.FC = ({ loading={false} onAutoVoucheCodesGenerate={onAutoVoucheCodesGenerate} onManualVoucherCodeGenerate={onManualVoucherCodeGenerate} - onVoucherCodeDelete={onDeleteVoucherCodes} disabled={disabled} codes={mapEdgesToItems(voucher?.codes)} /> diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 7226acb3d79..38c09b16418 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -356,7 +356,6 @@ export const VoucherDetails: React.FC = ({ ids: [productId], }) } - onDeleteVoucherCodes={() => openModal("delete-codes")} onAutoVoucheCodesGenerate={() => openModal("generate-codes")} onManualVoucherCodeGenerate={() => openModal("manual-codes")} activeTab={activeTab} From 453895cf12b93427eccb8f67aa078e2e097f8d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 20 Sep 2023 23:11:36 +0200 Subject: [PATCH 15/67] Refactor components --- .../components/VoucherCodes/VoucherCodes.tsx | 44 +++++++++++ .../components/VoucherCodes/index.ts | 1 + .../VoucherCodesAddButton.tsx | 74 +++++++++++++++++++ .../components/VoucherCodesAddButton/index.ts | 1 + .../VoucherCodesAddButton/messages.ts | 24 ++++++ .../VoucherCodesDatagrid.tsx | 74 +------------------ .../VoucherDetailsPage/VoucherDetailsPage.tsx | 8 +- 7 files changed, 151 insertions(+), 75 deletions(-) create mode 100644 src/discounts/components/VoucherCodes/VoucherCodes.tsx create mode 100644 src/discounts/components/VoucherCodes/index.ts create mode 100644 src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx create mode 100644 src/discounts/components/VoucherCodesAddButton/index.ts create mode 100644 src/discounts/components/VoucherCodesAddButton/messages.ts diff --git a/src/discounts/components/VoucherCodes/VoucherCodes.tsx b/src/discounts/components/VoucherCodes/VoucherCodes.tsx new file mode 100644 index 00000000000..22fccb4e7e8 --- /dev/null +++ b/src/discounts/components/VoucherCodes/VoucherCodes.tsx @@ -0,0 +1,44 @@ +import { Box, Text } from "@saleor/macaw-ui/next"; +import React from "react"; +import { FormattedMessage } from "react-intl"; + +import { + VoucherCodesAddButton, + VoucherCodesAddButtonProps, +} from "../VoucherCodesAddButton/VoucherCodesAddButton"; +import { + VoucherCodesDatagrid, + VoucherCodesDatagridProps, +} from "../VoucherCodesDatagrid"; + +interface VoucherCodesProps + extends VoucherCodesAddButtonProps, + VoucherCodesDatagridProps {} + +export const VoucherCodes = ({ + onMultiCodesGenerate, + onSingleCodesGenerate, + ...datagridProps +}: VoucherCodesProps) => { + return ( + + + + + + + + + + + ); +}; diff --git a/src/discounts/components/VoucherCodes/index.ts b/src/discounts/components/VoucherCodes/index.ts new file mode 100644 index 00000000000..ba49cb01b36 --- /dev/null +++ b/src/discounts/components/VoucherCodes/index.ts @@ -0,0 +1 @@ +export * from "./VoucherCodes"; diff --git a/src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx b/src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx new file mode 100644 index 00000000000..9eadd198756 --- /dev/null +++ b/src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx @@ -0,0 +1,74 @@ +import { SubMenu } from "@dashboard/components/SubMenu"; +import { + ArrowDownIcon, + Box, + Button, + PlusIcon, + Popover, +} from "@saleor/macaw-ui/next"; +import React, { useCallback, useMemo, useState } from "react"; +import { useIntl } from "react-intl"; + +import { messages } from "./messages"; + +export interface VoucherCodesAddButtonProps { + onMultiCodesGenerate: () => void; + onSingleCodesGenerate: () => void; +} + +export const VoucherCodesAddButton = ({ + onMultiCodesGenerate, + onSingleCodesGenerate, +}: VoucherCodesAddButtonProps) => { + const [isSubMenuOpen, setSubMenuOpen] = useState(false); + const intl = useIntl(); + + const handleMultupleCodesGenerate = useCallback(() => { + onMultiCodesGenerate(); + setSubMenuOpen(false); + }, []); + + const handleManualCodeGenerate = useCallback(() => { + onSingleCodesGenerate(); + setSubMenuOpen(false); + }, []); + + const subMenuItems = useMemo( + () => [ + { + id: "manual", + title: intl.formatMessage(messages.manual), + description: intl.formatMessage(messages.manualDescription), + onClick: handleManualCodeGenerate, + }, + { + id: "auto-generate-codes", + title: intl.formatMessage(messages.autoGenerate), + description: intl.formatMessage(messages.autoGenerateDescription), + onClick: handleMultupleCodesGenerate, + }, + ], + [handleMultupleCodesGenerate, handleManualCodeGenerate], + ); + + return ( + + + + + + + + + + + ); +}; diff --git a/src/discounts/components/VoucherCodesAddButton/index.ts b/src/discounts/components/VoucherCodesAddButton/index.ts new file mode 100644 index 00000000000..cf1bce0bfd7 --- /dev/null +++ b/src/discounts/components/VoucherCodesAddButton/index.ts @@ -0,0 +1 @@ +export * from "./VoucherCodesAddButton"; diff --git a/src/discounts/components/VoucherCodesAddButton/messages.ts b/src/discounts/components/VoucherCodesAddButton/messages.ts new file mode 100644 index 00000000000..cb49eb10ffc --- /dev/null +++ b/src/discounts/components/VoucherCodesAddButton/messages.ts @@ -0,0 +1,24 @@ +import { defineMessages } from "react-intl"; + +export const messages = defineMessages({ + manual: { + id: "M59JhX", + defaultMessage: "Manual", + }, + manualDescription: { + id: "83egc7", + defaultMessage: "Manually enter the voucher code.", + }, + autoGenerate: { + id: "awNXI/", + defaultMessage: "Auto-generate codes", + }, + autoGenerateDescription: { + id: "DJatYh", + defaultMessage: "Generate multiple codes at once", + }, + addCode: { + id: "6xNl6V", + defaultMessage: "Add code", + }, +}); diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index d9c4878c672..623bcd9f135 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -4,18 +4,10 @@ import { DatagridChangeStateContext, useDatagridChangeState, } from "@dashboard/components/Datagrid/hooks/useDatagridChange"; -import { SubMenu } from "@dashboard/components/SubMenu"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; import { VoucherCodeFragment } from "@dashboard/graphql"; -import { - ArrowDownIcon, - Box, - Button, - PlusIcon, - Popover, - Text, -} from "@saleor/macaw-ui/next"; -import React, { useCallback, useMemo, useState } from "react"; +import { Box } from "@saleor/macaw-ui/next"; +import React, { useCallback, useMemo } from "react"; import { useIntl } from "react-intl"; import { @@ -24,24 +16,19 @@ import { } from "./datagrid"; import { messages } from "./messages"; -interface VoucherCodesDatagridProps { +export interface VoucherCodesDatagridProps { codes: VoucherCodeFragment[]; loading: boolean; disabled?: boolean; - onAutoVoucheCodesGenerate: () => void; - onManualVoucherCodeGenerate: () => void; } export const VoucherCodesDatagrid = ({ codes, loading, disabled, - onAutoVoucheCodesGenerate, - onManualVoucherCodeGenerate, }: VoucherCodesDatagridProps) => { const intl = useIntl(); const datagrid = useDatagridChangeState(); - const [isSubMenuOpen, setSubMenuOpen] = useState(false); const voucherCodesStaticColumns = useMemo( () => voucherCodesStaticColumnsAdapter(intl), @@ -59,63 +46,8 @@ export const VoucherCodesDatagrid = ({ [codes, visibleColumns], ); - const handleMultupleCodesGenerate = useCallback(() => { - onAutoVoucheCodesGenerate(); - setSubMenuOpen(false); - }, []); - - const handleManualCodeGenerate = useCallback(() => { - onManualVoucherCodeGenerate(); - setSubMenuOpen(false); - }, []); - - const subMenuItems = useMemo( - () => [ - { - id: "manual", - title: "Manual", - description: "Manually enter the voucher code.", - onClick: handleManualCodeGenerate, - }, - { - id: "auto-generate-codes", - title: "Auto-generate codes", - description: "Generate multiple codes at once", - onClick: handleMultupleCodesGenerate, - }, - ], - [handleMultupleCodesGenerate, handleManualCodeGenerate], - ); - return ( - - Voucher codes - - - - - - - - - - - = ({ onChange={change} variant="update" /> - From be939f05d9f81f6c0bd70e035582fc76a6ffb01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 20 Sep 2023 23:49:34 +0200 Subject: [PATCH 16/67] Bulk voucher delete by row selection --- .../components/VoucherCodes/VoucherCodes.tsx | 24 ++++++++-- .../VoucherCodesDatagrid.tsx | 3 ++ .../VoucherDetailsPage.stories.tsx | 7 ++- .../VoucherDetailsPage/VoucherDetailsPage.tsx | 21 ++++++--- src/discounts/urls.ts | 4 +- .../views/VoucherDetails/VoucherDetails.tsx | 46 +++++++++++++++++-- 6 files changed, 85 insertions(+), 20 deletions(-) diff --git a/src/discounts/components/VoucherCodes/VoucherCodes.tsx b/src/discounts/components/VoucherCodes/VoucherCodes.tsx index 22fccb4e7e8..64f70822b9f 100644 --- a/src/discounts/components/VoucherCodes/VoucherCodes.tsx +++ b/src/discounts/components/VoucherCodes/VoucherCodes.tsx @@ -1,3 +1,4 @@ +import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton"; import { Box, Text } from "@saleor/macaw-ui/next"; import React from "react"; import { FormattedMessage } from "react-intl"; @@ -13,11 +14,17 @@ import { interface VoucherCodesProps extends VoucherCodesAddButtonProps, - VoucherCodesDatagridProps {} + VoucherCodesDatagridProps { + selectedCodesIds: string[]; + onDeleteCodes: () => void; + onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; +} export const VoucherCodes = ({ + selectedCodesIds, onMultiCodesGenerate, onSingleCodesGenerate, + onDeleteCodes, ...datagridProps }: VoucherCodesProps) => { return ( @@ -32,10 +39,17 @@ export const VoucherCodes = ({ - + + {selectedCodesIds.length > 0 && ( + + + + )} + + diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 623bcd9f135..a4a197eadd8 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -20,12 +20,14 @@ export interface VoucherCodesDatagridProps { codes: VoucherCodeFragment[]; loading: boolean; disabled?: boolean; + onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; } export const VoucherCodesDatagrid = ({ codes, loading, disabled, + onSelectVoucherCodesIds, }: VoucherCodesDatagridProps) => { const intl = useIntl(); const datagrid = useDatagridChangeState(); @@ -63,6 +65,7 @@ export const VoucherCodesDatagrid = ({ getCellContent={getCellContent} getCellError={() => false} selectionActions={() => null} + onRowSelectionChange={onSelectVoucherCodesIds} menuItems={() => []} /> diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx index ba93993c255..0c8678baf41 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx @@ -21,8 +21,11 @@ const channels = createChannelsDataWithDiscountPrice( const props: VoucherDetailsPageProps = { ...listActionsProps, ...pageListProps.default, - onAutoVoucheCodesGenerate: () => undefined, - onManualVoucherCodeGenerate: () => undefined, + selectedVoucherCodesIds: [], + onMultipleVoucheCodesGenerate: () => undefined, + onSingleVoucherCodeGenerate: () => undefined, + onSelectVoucherCodesIds: () => undefined, + onDeleteVoucherCodes: () => undefined, activeTab: VoucherDetailsPageTab.products, tabItemsCount: { [VoucherDetailsPageTab.categories]: diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index ee52c5ef63f..ac89ea97d9a 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -92,6 +92,8 @@ export interface VoucherDetailsPageProps voucher: VoucherDetailsFragment; allChannelsCount: number; channelListings: ChannelVoucherData[]; + selectedVoucherCodesIds: string[]; + onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; onCategoryAssign: () => void; onCategoryUnassign: (id: string) => void; onCollectionAssign: () => void; @@ -105,8 +107,9 @@ export interface VoucherDetailsPageProps onTabClick: (index: VoucherDetailsPageTab) => void; onChannelsChange: (data: ChannelVoucherData[]) => void; openChannelsModal: () => void; - onAutoVoucheCodesGenerate: () => void; - onManualVoucherCodeGenerate: () => void; + onMultipleVoucheCodesGenerate: () => void; + onSingleVoucherCodeGenerate: () => void; + onDeleteVoucherCodes: () => void; } const CategoriesTab = Tab(VoucherDetailsPageTab.categories); @@ -134,8 +137,9 @@ const VoucherDetailsPage: React.FC = ({ onTabClick, openChannelsModal, onRemove, - onAutoVoucheCodesGenerate, - onManualVoucherCodeGenerate, + onMultipleVoucheCodesGenerate, + onSingleVoucherCodeGenerate, + onDeleteVoucherCodes, onSubmit, toggle, toggleAll, @@ -145,6 +149,8 @@ const VoucherDetailsPage: React.FC = ({ categoryListToolbar, collectionListToolbar, productListToolbar, + selectedVoucherCodesIds, + onSelectVoucherCodesIds, }) => { const intl = useIntl(); const navigate = useNavigator(); @@ -225,9 +231,12 @@ const VoucherDetailsPage: React.FC = ({ variant="update" /> diff --git a/src/discounts/urls.ts b/src/discounts/urls.ts index 285aecab575..84e6f264c41 100644 --- a/src/discounts/urls.ts +++ b/src/discounts/urls.ts @@ -112,8 +112,8 @@ export type VoucherUrlDialog = | "unassign-product" | "remove" | "delete-codes" - | "generate-codes" - | "manual-codes" + | "multiple-codes" + | "single-codes" | ChannelsAction; export type VoucherUrlQueryParams = BulkAction & Dialog; export type VoucherCreateUrlQueryParams = Dialog; diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 38c09b16418..db6bb1dcad4 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -46,6 +46,7 @@ import useLocalPaginator, { import useNavigator from "@dashboard/hooks/useNavigator"; import useNotifier from "@dashboard/hooks/useNotifier"; import { PaginatorContext } from "@dashboard/hooks/usePaginator"; +import { useRowSelection } from "@dashboard/hooks/useRowSelection"; import useShop from "@dashboard/hooks/useShop"; import { commonMessages, sectionNames } from "@dashboard/intl"; import useCategorySearch from "@dashboard/searches/useCategorySearch"; @@ -55,7 +56,8 @@ import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHa import createMetadataUpdateHandler from "@dashboard/utils/handlers/metadataUpdateHandler"; import { mapEdgesToItems } from "@dashboard/utils/maps"; import { DialogContentText } from "@material-ui/core"; -import React, { useMemo, useState } from "react"; +import isEqual from "lodash/isEqual"; +import React, { useCallback, useMemo, useState } from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { maybe } from "../../../misc"; @@ -133,6 +135,37 @@ export const VoucherDetails: React.FC = ({ }, }); + const { + selectedRowIds, + setClearDatagridRowSelectionCallback, + setSelectedRowIds, + } = useRowSelection(); + + const voucherCodes = mapEdgesToItems(data?.voucher?.codes); + + const handleSetSelectedVoucherCodesIds = useCallback( + (rows: number[], clearSelection: () => void) => { + if (!voucherCodes) { + return; + } + + const rowsIds = rows.map(row => voucherCodes[row].code); + const haveSaveValues = isEqual(rowsIds, selectedRowIds); + + if (!haveSaveValues) { + setSelectedRowIds(rowsIds); + } + + setClearDatagridRowSelectionCallback(clearSelection); + }, + [ + voucherCodes, + selectedRowIds, + setClearDatagridRowSelectionCallback, + setSelectedRowIds, + ], + ); + const [openModal, closeModal] = createDialogActionHandlers< VoucherUrlDialog, VoucherUrlQueryParams @@ -356,8 +389,11 @@ export const VoucherDetails: React.FC = ({ ids: [productId], }) } - onAutoVoucheCodesGenerate={() => openModal("generate-codes")} - onManualVoucherCodeGenerate={() => openModal("manual-codes")} + onMultipleVoucheCodesGenerate={() => openModal("multiple-codes")} + onSingleVoucherCodeGenerate={() => openModal("single-codes")} + onDeleteVoucherCodes={() => openModal("delete-codes")} + onSelectVoucherCodesIds={handleSetSelectedVoucherCodesIds} + selectedVoucherCodesIds={selectedRowIds} activeTab={activeTab} tabItemsCount={tabItemsCount} onTabClick={changeTab} @@ -422,12 +458,12 @@ export const VoucherDetails: React.FC = ({ onDelete={closeModal} /> From b8255bbcf227f9211083267777cbb5e028acc5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 09:54:10 +0200 Subject: [PATCH 17/67] Handle add manual voucher code form data --- .../VoucherCodesManualDialog.tsx | 56 +++++++++++-------- .../VoucherCodesManualDialog/messages.ts | 12 ++++ .../views/VoucherDetails/VoucherDetails.tsx | 1 - 3 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 src/discounts/components/VoucherCodesManualDialog/messages.ts diff --git a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx index 0adecdaed70..0619b825dcb 100644 --- a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx +++ b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx @@ -4,10 +4,13 @@ import { } from "@dashboard/components/ConfirmButton"; import { DashboardModal } from "@dashboard/components/Modal"; import { VoucherInput } from "@dashboard/graphql"; +import useForm, { SubmitPromise } from "@dashboard/hooks/useForm"; import { buttonMessages } from "@dashboard/intl"; import { Box, Button, Input } from "@saleor/macaw-ui/next"; import React from "react"; -import { useIntl } from "react-intl"; +import { FormattedMessage, useIntl } from "react-intl"; + +import { messages } from "./messages"; interface VoucherCodesManualDialogProps { open: boolean; @@ -16,6 +19,11 @@ interface VoucherCodesManualDialogProps { onSubmit: (codes: VoucherInput["codes"]) => void; } +interface FormData { + code: string; + usageLimit: string; +} + export const VoucherCodesManualDialog = ({ open, confirmButtonTransitionState, @@ -23,47 +31,49 @@ export const VoucherCodesManualDialog = ({ onSubmit, }: VoucherCodesManualDialogProps) => { const intl = useIntl(); - - const [quantity, setQuantity] = React.useState(""); - const [usage, setUsage] = React.useState(""); - - const reset = () => { - setQuantity(""); - setUsage(""); + const intialData: FormData = { + code: "", + usageLimit: "", }; - const handleModalClose = () => { + const handleSubmit = async ({ + code, + usageLimit, + }: FormData): SubmitPromise => { + await onSubmit([{ code, usageLimit: Number(usageLimit) }]); onClose(); - reset(); }; - const handleSubmit = () => { + const { data, change, submit, reset } = useForm(intialData, handleSubmit); + + const handleModalClose = () => { onClose(); - onSubmit([{ code: quantity, usageLimit: Number(usage) }]); reset(); }; return ( - Enter Voucher Code + + + setQuantity(e.target.value)} + label={intl.formatMessage(messages.enterCode)} + value={data.code} + onChange={change} /> setUsage(e.target.value)} + label={intl.formatMessage(messages.enterUsage)} + value={data.usageLimit} + onChange={change} /> @@ -72,7 +82,7 @@ export const VoucherCodesManualDialog = ({ {intl.formatMessage(buttonMessages.confirm)} diff --git a/src/discounts/components/VoucherCodesManualDialog/messages.ts b/src/discounts/components/VoucherCodesManualDialog/messages.ts new file mode 100644 index 00000000000..acaa779c8b6 --- /dev/null +++ b/src/discounts/components/VoucherCodesManualDialog/messages.ts @@ -0,0 +1,12 @@ +import { defineMessages } from "react-intl"; + +export const messages = defineMessages({ + enterCode: { + defaultMessage: "Enter code", + id: "SGdcJD", + }, + enterUsage: { + defaultMessage: "Enter usage", + id: "qPSWmL", + }, +}); diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index db6bb1dcad4..214240b5705 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -469,7 +469,6 @@ export const VoucherDetails: React.FC = ({ onSubmit={codes => voucherUpdate({ variables: { - ...paginationState, id, input: { codes, From 6683265aebe853aebb2b9694cef07f80d99198f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 12:33:54 +0200 Subject: [PATCH 18/67] Use separate query to fetch codes --- .../VoucherDetailsPage/VoucherDetailsPage.tsx | 9 +++- src/discounts/queries.ts | 20 +++++++ .../views/VoucherDetails/VoucherDetails.tsx | 13 ++++- src/fragments/discounts.ts | 9 ---- src/graphql/hooks.generated.ts | 54 +++++++++++++++---- src/graphql/types.generated.ts | 19 +++++-- 6 files changed, 99 insertions(+), 25 deletions(-) diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index ac89ea97d9a..d11328f1635 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -25,6 +25,7 @@ import { DiscountErrorFragment, DiscountValueTypeEnum, PermissionEnum, + VoucherCodeFragment, VoucherDetailsFragment, VoucherTypeEnum, } from "@dashboard/graphql"; @@ -93,6 +94,8 @@ export interface VoucherDetailsPageProps allChannelsCount: number; channelListings: ChannelVoucherData[]; selectedVoucherCodesIds: string[]; + voucherCodes: VoucherCodeFragment[]; + voucherCodesLoading: boolean; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; onCategoryAssign: () => void; onCategoryUnassign: (id: string) => void; @@ -151,6 +154,8 @@ const VoucherDetailsPage: React.FC = ({ productListToolbar, selectedVoucherCodesIds, onSelectVoucherCodesIds, + voucherCodes, + voucherCodesLoading, }) => { const intl = useIntl(); const navigate = useNavigator(); @@ -234,11 +239,11 @@ const VoucherDetailsPage: React.FC = ({ selectedCodesIds={selectedVoucherCodesIds} onSelectVoucherCodesIds={onSelectVoucherCodesIds} onDeleteCodes={onDeleteVoucherCodes} - loading={false} + loading={voucherCodesLoading} onMultiCodesGenerate={onMultipleVoucheCodesGenerate} onSingleCodesGenerate={onSingleVoucherCodeGenerate} disabled={disabled} - codes={mapEdgesToItems(voucher?.codes)} + codes={voucherCodes} /> = ({ }, }); + const { data: voucherCodesData, loading: voucherCodesLoading } = + useVoucherCodesQuery({ + variables: { + id, + first: 10, + }, + }); + const { selectedRowIds, setClearDatagridRowSelectionCallback, setSelectedRowIds, } = useRowSelection(); - const voucherCodes = mapEdgesToItems(data?.voucher?.codes); + const voucherCodes = mapEdgesToItems(voucherCodesData?.voucher?.codes); const handleSetSelectedVoucherCodesIds = useCallback( (rows: number[], clearSelection: () => void) => { @@ -344,6 +353,8 @@ export const VoucherDetails: React.FC = ({ )} ; export type VoucherDetailsLazyQueryHookResult = ReturnType; export type VoucherDetailsQueryResult = Apollo.QueryResult; +export const VoucherCodesDocument = gql` + query VoucherCodes($id: ID!, $after: String, $before: String, $first: Int, $last: Int) { + voucher(id: $id) { + codes(first: $first, last: $last, before: $before, after: $after) { + edges { + node { + ...VoucherCode + } + } + } + } +} + ${VoucherCodeFragmentDoc}`; + +/** + * __useVoucherCodesQuery__ + * + * To run a query within a React component, call `useVoucherCodesQuery` and pass it any options that fit your needs. + * When your component renders, `useVoucherCodesQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useVoucherCodesQuery({ + * variables: { + * id: // value for 'id' + * after: // value for 'after' + * before: // value for 'before' + * first: // value for 'first' + * last: // value for 'last' + * }, + * }); + */ +export function useVoucherCodesQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useQuery(VoucherCodesDocument, options); + } +export function useVoucherCodesLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useLazyQuery(VoucherCodesDocument, options); + } +export type VoucherCodesQueryHookResult = ReturnType; +export type VoucherCodesLazyQueryHookResult = ReturnType; +export type VoucherCodesQueryResult = Apollo.QueryResult; export const FileUploadDocument = gql` mutation FileUpload($file: Upload!) { fileUpload(file: $file) { diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 32d249a8b10..5e548e38105 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -9105,7 +9105,7 @@ export type VoucherCataloguesAddMutationVariables = Exact<{ }>; -export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }> } | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCataloguesRemoveMutationVariables = Exact<{ input: CatalogueInput; @@ -9120,7 +9120,7 @@ export type VoucherCataloguesRemoveMutationVariables = Exact<{ }>; -export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }> } | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCreateMutationVariables = Exact<{ input: VoucherInput; @@ -9196,7 +9196,18 @@ export type VoucherDetailsQueryVariables = Exact<{ }>; -export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }> } | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; +export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; + +export type VoucherCodesQueryVariables = Exact<{ + id: Scalars['ID']; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}>; + + +export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }> } | null } | null }; export type FileUploadMutationVariables = Exact<{ file: Scalars['Upload']; @@ -9271,7 +9282,7 @@ export type VoucherFragment = { __typename: 'Voucher', id: string, code: string export type VoucherCodeFragment = { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null }; -export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }> } | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; export type AttributeErrorFragment = { __typename: 'AttributeError', code: AttributeErrorCode, field: string | null, message: string | null }; From f85e74f41a698211606053ca83491c950adbf164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 13:49:51 +0200 Subject: [PATCH 19/67] Pagination wip --- src/config.ts | 4 ++++ .../components/VoucherCodes/VoucherCodes.tsx | 11 +++++++-- .../VoucherCodesDatagrid.tsx | 8 +++++-- .../VoucherDetailsPage/VoucherDetailsPage.tsx | 9 +++++++ src/discounts/queries.ts | 3 +++ .../views/VoucherDetails/VoucherDetails.tsx | 24 ++++++++++++++++++- src/graphql/hooks.generated.ts | 6 ++++- src/graphql/types.generated.ts | 2 +- src/types.ts | 1 + 9 files changed, 61 insertions(+), 7 deletions(-) diff --git a/src/config.ts b/src/config.ts index 2ddca3bd3ed..a09f68b7ef2 100644 --- a/src/config.ts +++ b/src/config.ts @@ -57,6 +57,7 @@ export interface AppListViewSettings { [ListViews.STAFF_MEMBERS_LIST]: ListSettings; [ListViews.PERMISSION_GROUP_LIST]: ListSettings; [ListViews.VOUCHER_LIST]: ListSettings; + [ListViews.VOUCHER_CODDES_LIST]: ListSettings; [ListViews.WAREHOUSE_LIST]: ListSettings; [ListViews.WEBHOOK_LIST]: ListSettings; [ListViews.TRANSLATION_ATTRIBUTE_VALUE_LIST]: ListSettings; @@ -136,6 +137,9 @@ export const defaultListSettings: AppListViewSettings = { rowNumber: PAGINATE_BY, columns: ["code", "min-spent", "start-date", "end-date", "value", "limit"], }, + [ListViews.VOUCHER_CODDES_LIST]: { + rowNumber: PAGINATE_BY, + }, [ListViews.WAREHOUSE_LIST]: { rowNumber: PAGINATE_BY, }, diff --git a/src/discounts/components/VoucherCodes/VoucherCodes.tsx b/src/discounts/components/VoucherCodes/VoucherCodes.tsx index 64f70822b9f..7ca1876c20d 100644 --- a/src/discounts/components/VoucherCodes/VoucherCodes.tsx +++ b/src/discounts/components/VoucherCodes/VoucherCodes.tsx @@ -1,4 +1,5 @@ import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton"; +import { PaginatorContext } from "@dashboard/hooks/usePaginator"; import { Box, Text } from "@saleor/macaw-ui/next"; import React from "react"; import { FormattedMessage } from "react-intl"; @@ -18,6 +19,9 @@ interface VoucherCodesProps selectedCodesIds: string[]; onDeleteCodes: () => void; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; + voucherCodesPagination: any; + onSettingsChange: any; + settings: any; } export const VoucherCodes = ({ @@ -25,10 +29,13 @@ export const VoucherCodes = ({ onMultiCodesGenerate, onSingleCodesGenerate, onDeleteCodes, + voucherCodesPagination, ...datagridProps }: VoucherCodesProps) => { + const { pageInfo, ...paginationValues } = voucherCodesPagination; + return ( - + - + ); }; diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index a4a197eadd8..39f108b60ca 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -21,6 +21,8 @@ export interface VoucherCodesDatagridProps { loading: boolean; disabled?: boolean; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; + settings: any; + onSettingsChange: any; } export const VoucherCodesDatagrid = ({ @@ -28,6 +30,8 @@ export const VoucherCodesDatagrid = ({ loading, disabled, onSelectVoucherCodesIds, + onSettingsChange, + settings, }: VoucherCodesDatagridProps) => { const intl = useIntl(); const datagrid = useDatagridChangeState(); @@ -72,9 +76,9 @@ export const VoucherCodesDatagrid = ({ {}} + onUpdateListSettings={onSettingsChange} /> diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index d11328f1635..950bacea481 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -113,6 +113,9 @@ export interface VoucherDetailsPageProps onMultipleVoucheCodesGenerate: () => void; onSingleVoucherCodeGenerate: () => void; onDeleteVoucherCodes: () => void; + voucherCodesPagination: any; + onVoucherCodesSettingsChange: any; + voucherCodesSettings: any; } const CategoriesTab = Tab(VoucherDetailsPageTab.categories); @@ -156,6 +159,9 @@ const VoucherDetailsPage: React.FC = ({ onSelectVoucherCodesIds, voucherCodes, voucherCodesLoading, + voucherCodesPagination, + onVoucherCodesSettingsChange, + voucherCodesSettings, }) => { const intl = useIntl(); const navigate = useNavigator(); @@ -244,6 +250,9 @@ const VoucherDetailsPage: React.FC = ({ onSingleCodesGenerate={onSingleVoucherCodeGenerate} disabled={disabled} codes={voucherCodes} + voucherCodesPagination={voucherCodesPagination} + onSettingsChange={onVoucherCodesSettingsChange} + settings={voucherCodesSettings} /> = ({ }, }); + const { + settings: voucherCodesSettings, + updateListSettings: updateVoucherCodesListSettings, + } = useListSettings(ListViews.VOUCHER_CODDES_LIST); + + const [voucherCodesPaginationState, setVoucherCodesPaginationState] = + useLocalPaginationState(voucherCodesSettings.rowNumber); + const voucherCodesPaginate = useLocalPaginator( + setVoucherCodesPaginationState, + ); + const { data: voucherCodesData, loading: voucherCodesLoading } = useVoucherCodesQuery({ variables: { id, - first: 10, + ...voucherCodesPaginationState, }, }); + const voucherCodesPagination = voucherCodesPaginate( + voucherCodesData?.voucher?.codes?.pageInfo, + paginationState, + ); + const { selectedRowIds, setClearDatagridRowSelectionCallback, @@ -354,7 +373,10 @@ export const VoucherDetails: React.FC = ({ ; -export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }> } | null } | null }; +export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null } | null }; export type FileUploadMutationVariables = Exact<{ file: Scalars['Upload']; diff --git a/src/types.ts b/src/types.ts index 3421f77b65f..870062a30d8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -42,6 +42,7 @@ export enum ListViews { SHIPPING_METHODS_LIST = "SHIPPING_METHODS_LIST", STAFF_MEMBERS_LIST = "STAFF_MEMBERS_LIST", VOUCHER_LIST = "VOUCHER_LIST", + VOUCHER_CODDES_LIST = "VOUCHER_CODES_LIST", WAREHOUSE_LIST = "WAREHOUSE_LIST", WEBHOOK_LIST = "WEBHOOK_LIST", TRANSLATION_ATTRIBUTE_VALUE_LIST = "TRANSLATION_ATTRIBUTE_VALUE_LIST", From 858246d613266a332038f8b1c3f5ec689f0a89a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 15:26:02 +0200 Subject: [PATCH 20/67] Clear add manual code after submit --- .../VoucherCodesManualDialog.tsx | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx index 0619b825dcb..2483a160cb2 100644 --- a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx +++ b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx @@ -4,7 +4,7 @@ import { } from "@dashboard/components/ConfirmButton"; import { DashboardModal } from "@dashboard/components/Modal"; import { VoucherInput } from "@dashboard/graphql"; -import useForm, { SubmitPromise } from "@dashboard/hooks/useForm"; +import useForm from "@dashboard/hooks/useForm"; import { buttonMessages } from "@dashboard/intl"; import { Box, Button, Input } from "@saleor/macaw-ui/next"; import React from "react"; @@ -24,6 +24,11 @@ interface FormData { usageLimit: string; } +const intialData: FormData = { + code: "", + usageLimit: "", +}; + export const VoucherCodesManualDialog = ({ open, confirmButtonTransitionState, @@ -31,22 +36,20 @@ export const VoucherCodesManualDialog = ({ onSubmit, }: VoucherCodesManualDialogProps) => { const intl = useIntl(); - const intialData: FormData = { - code: "", - usageLimit: "", - }; - const handleSubmit = async ({ - code, - usageLimit, - }: FormData): SubmitPromise => { - await onSubmit([{ code, usageLimit: Number(usageLimit) }]); + const { data, change, submit, reset } = useForm( + intialData, + ({ code, usageLimit }: FormData) => + onSubmit([{ code, usageLimit: Number(usageLimit) }]), + ); + + const handleModalClose = () => { onClose(); + reset(); }; - const { data, change, submit, reset } = useForm(intialData, handleSubmit); - - const handleModalClose = () => { + const handleSubmit = async () => { + await submit(); onClose(); reset(); }; @@ -82,7 +85,7 @@ export const VoucherCodesManualDialog = ({ {intl.formatMessage(buttonMessages.confirm)} From 0a921b0652425839ced389b196efc5b30560417c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 20:28:42 +0200 Subject: [PATCH 21/67] Block dots in usage input --- .../VoucherCodesManualDialog/VoucherCodesManualDialog.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx index 2483a160cb2..e71f87d2e57 100644 --- a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx +++ b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx @@ -73,6 +73,11 @@ export const VoucherCodesManualDialog = ({ { + if ([",", "."].includes(e.key)) { + e.preventDefault(); + } + }} size="small" label={intl.formatMessage(messages.enterUsage)} value={data.usageLimit} From e8def68f4ded81451cdd4acbd95794181ec55a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 20:29:05 +0200 Subject: [PATCH 22/67] Refetch voucher codes when update --- .../views/VoucherDetails/VoucherDetails.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 03af7e59a78..96b1a456f1c 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -150,13 +150,16 @@ export const VoucherDetails: React.FC = ({ setVoucherCodesPaginationState, ); - const { data: voucherCodesData, loading: voucherCodesLoading } = - useVoucherCodesQuery({ - variables: { - id, - ...voucherCodesPaginationState, - }, - }); + const { + data: voucherCodesData, + loading: voucherCodesLoading, + refetch: voucherCodesRefetch, + } = useVoucherCodesQuery({ + variables: { + id, + ...voucherCodesPaginationState, + }, + }); const voucherCodesPagination = voucherCodesPaginate( voucherCodesData?.voucher?.codes?.pageInfo, @@ -245,6 +248,7 @@ export const VoucherDetails: React.FC = ({ if (data.voucherUpdate.errors.length === 0) { closeModal(); notifySaved(); + voucherCodesRefetch(); } }, }); From 403d2988a0d05089f3b665feaf32bef741f51d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 21:25:28 +0200 Subject: [PATCH 23/67] Code refactor, replace any types --- .../components/VoucherCodes/VoucherCodes.tsx | 8 +- .../VoucherDetailsPage.stories.tsx | 15 ++++ .../VoucherDetailsPage/VoucherDetailsPage.tsx | 8 +- .../views/VoucherDetails/VoucherDetails.tsx | 84 ++++--------------- .../views/VoucherDetails/useVoucherCodes.ts | 82 ++++++++++++++++++ src/hooks/useLocalPaginator.ts | 9 +- 6 files changed, 131 insertions(+), 75 deletions(-) create mode 100644 src/discounts/views/VoucherDetails/useVoucherCodes.ts diff --git a/src/discounts/components/VoucherCodes/VoucherCodes.tsx b/src/discounts/components/VoucherCodes/VoucherCodes.tsx index 7ca1876c20d..8c2ee091d62 100644 --- a/src/discounts/components/VoucherCodes/VoucherCodes.tsx +++ b/src/discounts/components/VoucherCodes/VoucherCodes.tsx @@ -1,4 +1,6 @@ import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton"; +import { UseListSettings } from "@dashboard/hooks/useListSettings"; +import { LocalPagination } from "@dashboard/hooks/useLocalPaginator"; import { PaginatorContext } from "@dashboard/hooks/usePaginator"; import { Box, Text } from "@saleor/macaw-ui/next"; import React from "react"; @@ -19,9 +21,9 @@ interface VoucherCodesProps selectedCodesIds: string[]; onDeleteCodes: () => void; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; - voucherCodesPagination: any; - onSettingsChange: any; - settings: any; + voucherCodesPagination: LocalPagination; + onSettingsChange: UseListSettings["updateListSettings"]; + settings: UseListSettings["settings"]; } export const VoucherCodes = ({ diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx index 0c8678baf41..a9c160d1bb8 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx @@ -21,7 +21,22 @@ const channels = createChannelsDataWithDiscountPrice( const props: VoucherDetailsPageProps = { ...listActionsProps, ...pageListProps.default, + voucherCodes: [], + onVoucherCodesSettingsChange: () => undefined, selectedVoucherCodesIds: [], + voucherCodesLoading: false, + voucherCodesPagination: { + loadNextPage: () => undefined, + loadPreviousPage: () => undefined, + paginatorType: "click", + pageInfo: { + endCursor: "", + hasNextPage: false, + hasPreviousPage: false, + startCursor: "", + }, + }, + voucherCodesSettings: undefined, onMultipleVoucheCodesGenerate: () => undefined, onSingleVoucherCodeGenerate: () => undefined, onSelectVoucherCodesIds: () => undefined, diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 950bacea481..d896a5e21b1 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -29,6 +29,8 @@ import { VoucherDetailsFragment, VoucherTypeEnum, } from "@dashboard/graphql"; +import { UseListSettings } from "@dashboard/hooks/useListSettings"; +import { LocalPagination } from "@dashboard/hooks/useLocalPaginator"; import useNavigator from "@dashboard/hooks/useNavigator"; import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps"; import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger"; @@ -113,9 +115,9 @@ export interface VoucherDetailsPageProps onMultipleVoucheCodesGenerate: () => void; onSingleVoucherCodeGenerate: () => void; onDeleteVoucherCodes: () => void; - voucherCodesPagination: any; - onVoucherCodesSettingsChange: any; - voucherCodesSettings: any; + voucherCodesPagination: LocalPagination; + onVoucherCodesSettingsChange: UseListSettings["updateListSettings"]; + voucherCodesSettings: UseListSettings["settings"]; } const CategoriesTab = Tab(VoucherDetailsPageTab.categories); diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 96b1a456f1c..426a3bafa6b 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -33,7 +33,6 @@ import { useVoucherCataloguesAddMutation, useVoucherCataloguesRemoveMutation, useVoucherChannelListingUpdateMutation, - useVoucherCodesQuery, useVoucherDeleteMutation, useVoucherDetailsQuery, useVoucherUpdateMutation, @@ -41,32 +40,28 @@ import { } from "@dashboard/graphql"; import useBulkActions from "@dashboard/hooks/useBulkActions"; import useChannels from "@dashboard/hooks/useChannels"; -import useListSettings from "@dashboard/hooks/useListSettings"; import useLocalPaginator, { - useLocalPaginationState, useSectionLocalPaginationState, } from "@dashboard/hooks/useLocalPaginator"; import useNavigator from "@dashboard/hooks/useNavigator"; import useNotifier from "@dashboard/hooks/useNotifier"; import { PaginatorContext } from "@dashboard/hooks/usePaginator"; -import { useRowSelection } from "@dashboard/hooks/useRowSelection"; import useShop from "@dashboard/hooks/useShop"; import { commonMessages, sectionNames } from "@dashboard/intl"; import useCategorySearch from "@dashboard/searches/useCategorySearch"; import useCollectionSearch from "@dashboard/searches/useCollectionSearch"; import useProductSearch from "@dashboard/searches/useProductSearch"; -import { ListViews } from "@dashboard/types"; import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers"; import createMetadataUpdateHandler from "@dashboard/utils/handlers/metadataUpdateHandler"; import { mapEdgesToItems } from "@dashboard/utils/maps"; import { DialogContentText } from "@material-ui/core"; -import isEqual from "lodash/isEqual"; -import React, { useCallback, useMemo, useState } from "react"; +import React, { useMemo, useState } from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { maybe } from "../../../misc"; import { createUpdateHandler } from "./handlers"; import { VOUCHER_UPDATE_FORM_ID } from "./types"; +import { useVoucherCodes } from "./useVoucherCodes"; interface VoucherDetailsProps { id: string; @@ -140,62 +135,15 @@ export const VoucherDetails: React.FC = ({ }); const { - settings: voucherCodesSettings, - updateListSettings: updateVoucherCodesListSettings, - } = useListSettings(ListViews.VOUCHER_CODDES_LIST); - - const [voucherCodesPaginationState, setVoucherCodesPaginationState] = - useLocalPaginationState(voucherCodesSettings.rowNumber); - const voucherCodesPaginate = useLocalPaginator( - setVoucherCodesPaginationState, - ); - - const { - data: voucherCodesData, - loading: voucherCodesLoading, - refetch: voucherCodesRefetch, - } = useVoucherCodesQuery({ - variables: { - id, - ...voucherCodesPaginationState, - }, - }); - - const voucherCodesPagination = voucherCodesPaginate( - voucherCodesData?.voucher?.codes?.pageInfo, - paginationState, - ); - - const { - selectedRowIds, - setClearDatagridRowSelectionCallback, - setSelectedRowIds, - } = useRowSelection(); - - const voucherCodes = mapEdgesToItems(voucherCodesData?.voucher?.codes); - - const handleSetSelectedVoucherCodesIds = useCallback( - (rows: number[], clearSelection: () => void) => { - if (!voucherCodes) { - return; - } - - const rowsIds = rows.map(row => voucherCodes[row].code); - const haveSaveValues = isEqual(rowsIds, selectedRowIds); - - if (!haveSaveValues) { - setSelectedRowIds(rowsIds); - } - - setClearDatagridRowSelectionCallback(clearSelection); - }, - [ - voucherCodes, - selectedRowIds, - setClearDatagridRowSelectionCallback, - setSelectedRowIds, - ], - ); + voucherCodes, + voucherCodesLoading, + voucherCodesPagination, + voucherCodesSettings, + selectedVoucherCodesIds, + voucherCodesRefetch, + handleSetSelectedVoucherCodesIds, + updateVoucherCodesListSettings, + } = useVoucherCodes({ id }); const [openModal, closeModal] = createDialogActionHandlers< VoucherUrlDialog, @@ -381,6 +329,11 @@ export const VoucherDetails: React.FC = ({ voucherCodesLoading={voucherCodesLoading} voucherCodesSettings={voucherCodesSettings} onVoucherCodesSettingsChange={updateVoucherCodesListSettings} + onMultipleVoucheCodesGenerate={() => openModal("multiple-codes")} + onSingleVoucherCodeGenerate={() => openModal("single-codes")} + onDeleteVoucherCodes={() => openModal("delete-codes")} + onSelectVoucherCodesIds={handleSetSelectedVoucherCodesIds} + selectedVoucherCodesIds={selectedVoucherCodesIds} allChannelsCount={allChannels?.length} channelListings={currentChannels} disabled={ @@ -426,11 +379,6 @@ export const VoucherDetails: React.FC = ({ ids: [productId], }) } - onMultipleVoucheCodesGenerate={() => openModal("multiple-codes")} - onSingleVoucherCodeGenerate={() => openModal("single-codes")} - onDeleteVoucherCodes={() => openModal("delete-codes")} - onSelectVoucherCodesIds={handleSetSelectedVoucherCodesIds} - selectedVoucherCodesIds={selectedRowIds} activeTab={activeTab} tabItemsCount={tabItemsCount} onTabClick={changeTab} diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts new file mode 100644 index 00000000000..c7f6d238607 --- /dev/null +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.ts @@ -0,0 +1,82 @@ +import { useVoucherCodesQuery } from "@dashboard/graphql"; +import useListSettings from "@dashboard/hooks/useListSettings"; +import useLocalPaginator, { + useLocalPaginationState, +} from "@dashboard/hooks/useLocalPaginator"; +import { useRowSelection } from "@dashboard/hooks/useRowSelection"; +import { ListViews } from "@dashboard/types"; +import { mapEdgesToItems } from "@dashboard/utils/maps"; +import isEqual from "lodash/isEqual"; +import { useCallback } from "react"; + +export const useVoucherCodes = ({ id }: { id: string }) => { + const { + settings: voucherCodesSettings, + updateListSettings: updateVoucherCodesListSettings, + } = useListSettings(ListViews.VOUCHER_CODDES_LIST); + + const [voucherCodesPaginationState, setVoucherCodesPaginationState] = + useLocalPaginationState(voucherCodesSettings.rowNumber); + + const voucherCodesPaginate = useLocalPaginator( + setVoucherCodesPaginationState, + ); + + const { + data: voucherCodesData, + loading: voucherCodesLoading, + refetch: voucherCodesRefetch, + } = useVoucherCodesQuery({ + variables: { + id, + ...voucherCodesPaginationState, + }, + }); + + const voucherCodesPagination = voucherCodesPaginate( + voucherCodesData?.voucher?.codes?.pageInfo, + voucherCodesPaginationState, + ); + + const { + selectedRowIds, + setClearDatagridRowSelectionCallback, + setSelectedRowIds, + } = useRowSelection(); + + const voucherCodes = mapEdgesToItems(voucherCodesData?.voucher?.codes); + + const handleSetSelectedVoucherCodesIds = useCallback( + (rows: number[], clearSelection: () => void) => { + if (!voucherCodes) { + return; + } + + const rowsIds = rows.map(row => voucherCodes[row].code); + const haveSaveValues = isEqual(rowsIds, selectedRowIds); + + if (!haveSaveValues) { + setSelectedRowIds(rowsIds); + } + + setClearDatagridRowSelectionCallback(clearSelection); + }, + [ + voucherCodes, + selectedRowIds, + setClearDatagridRowSelectionCallback, + setSelectedRowIds, + ], + ); + + return { + voucherCodes, + voucherCodesLoading, + voucherCodesPagination, + voucherCodesRefetch, + voucherCodesSettings, + updateVoucherCodesListSettings, + selectedVoucherCodesIds: selectedRowIds, + handleSetSelectedVoucherCodesIds, + }; +}; diff --git a/src/hooks/useLocalPaginator.ts b/src/hooks/useLocalPaginator.ts index acd52e28346..20b44336697 100644 --- a/src/hooks/useLocalPaginator.ts +++ b/src/hooks/useLocalPaginator.ts @@ -88,13 +88,20 @@ export function useSectionLocalPaginationState( ]; } +export interface LocalPagination { + loadNextPage: () => void; + loadPreviousPage: () => void; + paginatorType: "click"; + pageInfo?: PageInfo; +} + function useLocalPaginator( setPaginationState: (paginationState: PaginationState) => void, ) { function paginate( pageInfo: PageInfo | undefined, paginationState: PaginationState, - ) { + ): LocalPagination { const loadNextPage = () => setPaginationState({ ...paginationState, From cc99b154aff935e9ca653f70c573e2cb4e0b0712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 21 Sep 2023 21:27:55 +0200 Subject: [PATCH 24/67] Update fixture --- src/discounts/fixtures.ts | 4 ---- src/discounts/views/VoucherDetails/useVoucherCodes.ts | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/discounts/fixtures.ts b/src/discounts/fixtures.ts index 6c555cf4fcd..4c0b88c7c31 100644 --- a/src/discounts/fixtures.ts +++ b/src/discounts/fixtures.ts @@ -583,10 +583,6 @@ export const sale: SaleDetailsFragment = { export const voucherDetails: VoucherDetailsFragment = { __typename: "Voucher", metadata: [], - codes: { - __typename: "VoucherCodeCountableConnection", - edges: [], - }, privateMetadata: [], applyOncePerCustomer: false, applyOncePerOrder: false, diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts index c7f6d238607..21b27119f8c 100644 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.ts @@ -52,11 +52,11 @@ export const useVoucherCodes = ({ id }: { id: string }) => { return; } - const rowsIds = rows.map(row => voucherCodes[row].code); + const rowsIds = rows.map(row => voucherCodes[row].code).filter(Boolean); const haveSaveValues = isEqual(rowsIds, selectedRowIds); if (!haveSaveValues) { - setSelectedRowIds(rowsIds); + setSelectedRowIds(rowsIds as string[]); } setClearDatagridRowSelectionCallback(clearSelection); From eaba340a8b6664a4c4c968ce2311934c6cc8a98e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Fri, 22 Sep 2023 09:41:02 +0200 Subject: [PATCH 25/67] Add changeset --- .changeset/lovely-walls-shake.md | 5 +++++ src/graphql/types.generated.ts | 11 ----------- 2 files changed, 5 insertions(+), 11 deletions(-) create mode 100644 .changeset/lovely-walls-shake.md diff --git a/.changeset/lovely-walls-shake.md b/.changeset/lovely-walls-shake.md new file mode 100644 index 00000000000..337a36f01b3 --- /dev/null +++ b/.changeset/lovely-walls-shake.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": minor +--- + +Introduce voucher codes datagrid diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 58922b6dd82..c2129578c23 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -4666,17 +4666,6 @@ export type PaymentInput = { token?: InputMaybe; }; -export type PaymentSettingsInput = { - /** - * Determine the transaction flow strategy to be used. Include the selected option in the payload sent to the payment app, as a requested action for the transaction. - * - * Added in Saleor 3.16. - * - * Note: this API is currently in Feature Preview and can be subject to changes at later point. - */ - defaultTransactionFlowStrategy?: InputMaybe; -}; - /** An enumeration. */ export enum PaymentMethodInitializeTokenizationErrorCode { CHANNEL_INACTIVE = 'CHANNEL_INACTIVE', From edf8b450274136fec1a1ba775e6e5f7983dc2100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 25 Sep 2023 15:06:36 +0200 Subject: [PATCH 26/67] Remove VoucherLimit from details page --- .../VoucherCreatePage/VoucherCreatePage.tsx | 10 ++++++---- .../VoucherDetailsPage/VoucherDetailsPage.tsx | 16 +--------------- .../components/VoucherLimits/VoucherLimits.tsx | 5 +++-- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx index bdcaf0591a5..cd246fbe4ad 100644 --- a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx +++ b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx @@ -33,8 +33,10 @@ import VoucherRequirements from "../VoucherRequirements"; import VoucherTypes from "../VoucherTypes"; import VoucherValue from "../VoucherValue"; -export interface FormData extends VoucherDetailsPageFormData { +export interface VoucherCreatePageFormData extends VoucherDetailsPageFormData { value: number; + usageLimit: number; + used: number; } export interface VoucherCreatePageProps { @@ -45,7 +47,7 @@ export interface VoucherCreatePageProps { saveButtonBarState: ConfirmButtonTransitionState; onChannelsChange: (data: ChannelVoucherData[]) => void; openChannelsModal: () => void; - onSubmit: (data: FormData) => SubmitPromise; + onSubmit: (data: VoucherCreatePageFormData) => SubmitPromise; } const VoucherCreatePage: React.FC = ({ @@ -64,7 +66,7 @@ const VoucherCreatePage: React.FC = ({ const { makeChangeHandler: makeMetadataChangeHandler } = useMetadataChangeTrigger(); - const initialForm: FormData = { + const initialForm: VoucherCreatePageFormData = { applyOncePerCustomer: false, applyOncePerOrder: false, onlyForStaff: false, @@ -87,7 +89,7 @@ const VoucherCreatePage: React.FC = ({ privateMetadata: [], }; - const checkIfSaveIsDisabled = (data: FormData) => + const checkIfSaveIsDisabled = (data: VoucherCreatePageFormData) => (data.discountType.toString() !== "SHIPPING" && data.channelListings?.some( channel => diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index d896a5e21b1..75f6d596967 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -46,7 +46,6 @@ import DiscountDates from "../DiscountDates"; import DiscountProducts from "../DiscountProducts"; import { VoucherCodes } from "../VoucherCodes"; import VoucherInfo from "../VoucherInfo"; -import VoucherLimits from "../VoucherLimits"; import VoucherRequirements from "../VoucherRequirements"; import VoucherSummary from "../VoucherSummary"; import VoucherTypes from "../VoucherTypes"; @@ -78,8 +77,6 @@ export interface VoucherDetailsPageFormData extends MetadataFormData { startDate: string; startTime: string; type: VoucherTypeEnum; - usageLimit: number; - used: number; } export interface VoucherDetailsPageProps @@ -210,15 +207,13 @@ const VoucherDetailsPage: React.FC = ({ startDate: splitDateTime(voucher?.startDate ?? "").date, startTime: splitDateTime(voucher?.startDate ?? "").time, type: voucher?.type ?? VoucherTypeEnum.ENTIRE_ORDER, - usageLimit: voucher?.usageLimit ?? 1, - used: voucher?.used ?? 0, metadata: voucher?.metadata.map(mapMetadataItemToInput), privateMetadata: voucher?.privateMetadata.map(mapMetadataItemToInput), }; return (
- {({ change, data, submit, triggerChange, set }) => { + {({ change, data, submit, triggerChange }) => { const handleDiscountTypeChange = createDiscountTypeChangeHandler(change); const handleChannelChange = createChannelsChangeHandler( @@ -375,15 +370,6 @@ const VoucherDetailsPage: React.FC = ({ onChange={change} onChannelChange={handleChannelChange} /> - ) => void; - setData: (data: Partial) => void; + setData: (data: Partial) => void; isNewVoucher: boolean; } From 6afdeeb2e3d72daf9262d0ba07b4b408710a00dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 25 Sep 2023 15:08:54 +0200 Subject: [PATCH 27/67] No poiner in ddatagrid, add placeholder in case of no data --- .../components/VoucherCodesDatagrid/datagrid.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts index 799e2ffcc7b..6eb54caf3f0 100644 --- a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts +++ b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts @@ -1,3 +1,4 @@ +import { PLACEHOLDER } from "@dashboard/components/Datagrid/const"; import { readonlyTextCell } from "@dashboard/components/Datagrid/customCells/cells"; import { AvailableColumn } from "@dashboard/components/Datagrid/types"; import { VoucherCodeFragment } from "@dashboard/graphql"; @@ -36,11 +37,17 @@ export const createGetCellContent = switch (columnId) { case "code": - return readonlyTextCell(rowData?.code ?? ""); + return readonlyTextCell(rowData?.code ?? "", false); case "usage": - return readonlyTextCell(rowData?.used?.toString() ?? ""); + return readonlyTextCell( + rowData?.used?.toString() ?? PLACEHOLDER, + false, + ); case "limit": - return readonlyTextCell(rowData?.usageLimit?.toString() ?? ""); + return readonlyTextCell( + rowData?.usageLimit?.toString() ?? PLACEHOLDER, + false, + ); default: return readonlyTextCell("", false); } From 88bc81b4e63e2e07635e5bda0974a5084093eab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 25 Sep 2023 15:28:23 +0200 Subject: [PATCH 28/67] Revert "Remove VoucherLimit from details page" This reverts commit edf8b450274136fec1a1ba775e6e5f7983dc2100. --- .../VoucherCreatePage/VoucherCreatePage.tsx | 10 ++++------ .../VoucherDetailsPage/VoucherDetailsPage.tsx | 16 +++++++++++++++- .../components/VoucherLimits/VoucherLimits.tsx | 5 ++--- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx index cd246fbe4ad..bdcaf0591a5 100644 --- a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx +++ b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx @@ -33,10 +33,8 @@ import VoucherRequirements from "../VoucherRequirements"; import VoucherTypes from "../VoucherTypes"; import VoucherValue from "../VoucherValue"; -export interface VoucherCreatePageFormData extends VoucherDetailsPageFormData { +export interface FormData extends VoucherDetailsPageFormData { value: number; - usageLimit: number; - used: number; } export interface VoucherCreatePageProps { @@ -47,7 +45,7 @@ export interface VoucherCreatePageProps { saveButtonBarState: ConfirmButtonTransitionState; onChannelsChange: (data: ChannelVoucherData[]) => void; openChannelsModal: () => void; - onSubmit: (data: VoucherCreatePageFormData) => SubmitPromise; + onSubmit: (data: FormData) => SubmitPromise; } const VoucherCreatePage: React.FC = ({ @@ -66,7 +64,7 @@ const VoucherCreatePage: React.FC = ({ const { makeChangeHandler: makeMetadataChangeHandler } = useMetadataChangeTrigger(); - const initialForm: VoucherCreatePageFormData = { + const initialForm: FormData = { applyOncePerCustomer: false, applyOncePerOrder: false, onlyForStaff: false, @@ -89,7 +87,7 @@ const VoucherCreatePage: React.FC = ({ privateMetadata: [], }; - const checkIfSaveIsDisabled = (data: VoucherCreatePageFormData) => + const checkIfSaveIsDisabled = (data: FormData) => (data.discountType.toString() !== "SHIPPING" && data.channelListings?.some( channel => diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 75f6d596967..d896a5e21b1 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -46,6 +46,7 @@ import DiscountDates from "../DiscountDates"; import DiscountProducts from "../DiscountProducts"; import { VoucherCodes } from "../VoucherCodes"; import VoucherInfo from "../VoucherInfo"; +import VoucherLimits from "../VoucherLimits"; import VoucherRequirements from "../VoucherRequirements"; import VoucherSummary from "../VoucherSummary"; import VoucherTypes from "../VoucherTypes"; @@ -77,6 +78,8 @@ export interface VoucherDetailsPageFormData extends MetadataFormData { startDate: string; startTime: string; type: VoucherTypeEnum; + usageLimit: number; + used: number; } export interface VoucherDetailsPageProps @@ -207,13 +210,15 @@ const VoucherDetailsPage: React.FC = ({ startDate: splitDateTime(voucher?.startDate ?? "").date, startTime: splitDateTime(voucher?.startDate ?? "").time, type: voucher?.type ?? VoucherTypeEnum.ENTIRE_ORDER, + usageLimit: voucher?.usageLimit ?? 1, + used: voucher?.used ?? 0, metadata: voucher?.metadata.map(mapMetadataItemToInput), privateMetadata: voucher?.privateMetadata.map(mapMetadataItemToInput), }; return ( - {({ change, data, submit, triggerChange }) => { + {({ change, data, submit, triggerChange, set }) => { const handleDiscountTypeChange = createDiscountTypeChangeHandler(change); const handleChannelChange = createChannelsChangeHandler( @@ -370,6 +375,15 @@ const VoucherDetailsPage: React.FC = ({ onChange={change} onChannelChange={handleChannelChange} /> + ) => void; - setData: (data: Partial) => void; + setData: (data: Partial) => void; isNewVoucher: boolean; } From c9699d7e169e2594a60a47e30fcc667a0a332a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 25 Sep 2023 15:37:22 +0200 Subject: [PATCH 29/67] Show limit only for create voucher form --- .../VoucherLimits/VoucherLimits.tsx | 88 +++++++------------ 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/src/discounts/components/VoucherLimits/VoucherLimits.tsx b/src/discounts/components/VoucherLimits/VoucherLimits.tsx index 44a1411d3b5..410cf241ec7 100644 --- a/src/discounts/components/VoucherLimits/VoucherLimits.tsx +++ b/src/discounts/components/VoucherLimits/VoucherLimits.tsx @@ -1,10 +1,9 @@ import CardTitle from "@dashboard/components/CardTitle"; import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox"; -import { Grid } from "@dashboard/components/Grid"; import { DiscountErrorFragment } from "@dashboard/graphql"; import { getFormErrors } from "@dashboard/utils/errors"; import getDiscountErrorMessage from "@dashboard/utils/errors/discounts"; -import { Card, CardContent, TextField, Typography } from "@material-ui/core"; +import { Card, CardContent, TextField } from "@material-ui/core"; import React from "react"; import { useIntl } from "react-intl"; @@ -36,66 +35,39 @@ const VoucherLimits = ({ const formErrors = getFormErrors(["usageLimit"], errors); - const usesLeft = data.usageLimit - data.used; - return ( - { - onChange(evt); - setData({ usageLimit: initialUsageLimit }); - }} - /> - {data.hasUsageLimit && - (isNewVoucher ? ( - - ) : ( - - -
- - {intl.formatMessage(messages.usesLeftCaption)} - - {usesLeft >= 0 ? usesLeft : 0} -
-
- ))} + {isNewVoucher && ( + { + onChange(evt); + setData({ usageLimit: initialUsageLimit }); + }} + /> + )} + {data.hasUsageLimit && isNewVoucher && ( + + )} Date: Tue, 26 Sep 2023 14:44:07 +0200 Subject: [PATCH 30/67] Restore usage limit --- .../VoucherLimits/VoucherLimits.tsx | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/discounts/components/VoucherLimits/VoucherLimits.tsx b/src/discounts/components/VoucherLimits/VoucherLimits.tsx index 410cf241ec7..66b4f41248b 100644 --- a/src/discounts/components/VoucherLimits/VoucherLimits.tsx +++ b/src/discounts/components/VoucherLimits/VoucherLimits.tsx @@ -1,9 +1,10 @@ import CardTitle from "@dashboard/components/CardTitle"; import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox"; +import { Grid } from "@dashboard/components/Grid"; import { DiscountErrorFragment } from "@dashboard/graphql"; import { getFormErrors } from "@dashboard/utils/errors"; import getDiscountErrorMessage from "@dashboard/utils/errors/discounts"; -import { Card, CardContent, TextField } from "@material-ui/core"; +import { Card, CardContent, TextField, Typography } from "@material-ui/core"; import React from "react"; import { useIntl } from "react-intl"; @@ -35,10 +36,66 @@ const VoucherLimits = ({ const formErrors = getFormErrors(["usageLimit"], errors); + const usesLeft = data.usageLimit - data.used; + return ( + { + onChange(evt); + setData({ usageLimit: initialUsageLimit }); + }} + /> + {data.hasUsageLimit && + (isNewVoucher ? ( + + ) : ( + + +
+ + {intl.formatMessage(messages.usesLeftCaption)} + + {usesLeft >= 0 ? usesLeft : 0} +
+
+ ))} {isNewVoucher && ( Date: Wed, 27 Sep 2023 12:51:12 +0200 Subject: [PATCH 31/67] Create voucher codes --- .../VoucherCodesDatagrid.tsx | 4 +- .../VoucherCodesDatagrid/datagrid.ts | 16 +--- .../components/VoucherCodesDatagrid/types.ts | 4 + .../VoucherCodesManualDialog.tsx | 22 +---- .../VoucherCreatePage/VoucherCreatePage.tsx | 92 ++++++++++++++++++- .../VoucherDetailsPage/VoucherDetailsPage.tsx | 7 +- .../components/VoucherInfo/VoucherInfo.tsx | 59 ++++-------- .../VoucherLimits/VoucherLimits.tsx | 29 ------ .../VoucherListDatagrid/datagrid.ts | 2 +- src/discounts/urls.ts | 2 +- .../views/VoucherCreate/VoucherCreate.tsx | 9 +- src/discounts/views/VoucherCreate/handlers.ts | 3 +- .../views/VoucherDetails/VoucherDetails.tsx | 2 +- src/fragments/discounts.ts | 2 +- src/graphql/hooks.generated.ts | 2 +- src/graphql/types.generated.ts | 22 ++--- 16 files changed, 149 insertions(+), 128 deletions(-) create mode 100644 src/discounts/components/VoucherCodesDatagrid/types.ts diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 39f108b60ca..b2fe457dd79 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -5,7 +5,6 @@ import { useDatagridChangeState, } from "@dashboard/components/Datagrid/hooks/useDatagridChange"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; -import { VoucherCodeFragment } from "@dashboard/graphql"; import { Box } from "@saleor/macaw-ui/next"; import React, { useCallback, useMemo } from "react"; import { useIntl } from "react-intl"; @@ -15,9 +14,10 @@ import { voucherCodesStaticColumnsAdapter, } from "./datagrid"; import { messages } from "./messages"; +import { VoucherCode } from "./types"; export interface VoucherCodesDatagridProps { - codes: VoucherCodeFragment[]; + codes: VoucherCode[]; loading: boolean; disabled?: boolean; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; diff --git a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts index 6eb54caf3f0..2c82157095c 100644 --- a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts +++ b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts @@ -1,11 +1,11 @@ import { PLACEHOLDER } from "@dashboard/components/Datagrid/const"; import { readonlyTextCell } from "@dashboard/components/Datagrid/customCells/cells"; import { AvailableColumn } from "@dashboard/components/Datagrid/types"; -import { VoucherCodeFragment } from "@dashboard/graphql"; import { GridCell, Item } from "@glideapps/glide-data-grid"; import { IntlShape } from "react-intl"; import { columnsMessages } from "./messages"; +import { VoucherCode } from "./types"; export const voucherCodesStaticColumnsAdapter = (intl: IntlShape) => [ { @@ -18,18 +18,13 @@ export const voucherCodesStaticColumnsAdapter = (intl: IntlShape) => [ title: intl.formatMessage(columnsMessages.usage), width: 150, }, - { - id: "limit", - title: intl.formatMessage(columnsMessages.limit), - width: 150, - }, ]; export const createGetCellContent = - (voucherCodes: VoucherCodeFragment[], columns: AvailableColumn[]) => + (voucherCodes: VoucherCode[], columns: AvailableColumn[]) => ([column, row]: Item): GridCell => { const columnId = columns[column]?.id; - const rowData: VoucherCodeFragment | undefined = voucherCodes[row]; + const rowData: VoucherCode | undefined = voucherCodes[row]; if (!columnId || !rowData) { return readonlyTextCell(""); @@ -43,11 +38,6 @@ export const createGetCellContent = rowData?.used?.toString() ?? PLACEHOLDER, false, ); - case "limit": - return readonlyTextCell( - rowData?.usageLimit?.toString() ?? PLACEHOLDER, - false, - ); default: return readonlyTextCell("", false); } diff --git a/src/discounts/components/VoucherCodesDatagrid/types.ts b/src/discounts/components/VoucherCodesDatagrid/types.ts new file mode 100644 index 00000000000..367023dd27c --- /dev/null +++ b/src/discounts/components/VoucherCodesDatagrid/types.ts @@ -0,0 +1,4 @@ +export interface VoucherCode { + code: string; + used?: number; +} diff --git a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx index e71f87d2e57..01079ea2ccd 100644 --- a/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx +++ b/src/discounts/components/VoucherCodesManualDialog/VoucherCodesManualDialog.tsx @@ -3,7 +3,6 @@ import { ConfirmButtonTransitionState, } from "@dashboard/components/ConfirmButton"; import { DashboardModal } from "@dashboard/components/Modal"; -import { VoucherInput } from "@dashboard/graphql"; import useForm from "@dashboard/hooks/useForm"; import { buttonMessages } from "@dashboard/intl"; import { Box, Button, Input } from "@saleor/macaw-ui/next"; @@ -16,17 +15,15 @@ interface VoucherCodesManualDialogProps { open: boolean; confirmButtonTransitionState: ConfirmButtonTransitionState; onClose: () => void; - onSubmit: (codes: VoucherInput["codes"]) => void; + onSubmit: (code: string) => void; } interface FormData { code: string; - usageLimit: string; } const intialData: FormData = { code: "", - usageLimit: "", }; export const VoucherCodesManualDialog = ({ @@ -39,8 +36,7 @@ export const VoucherCodesManualDialog = ({ const { data, change, submit, reset } = useForm( intialData, - ({ code, usageLimit }: FormData) => - onSubmit([{ code, usageLimit: Number(usageLimit) }]), + ({ code }: FormData) => onSubmit(code), ); const handleModalClose = () => { @@ -69,20 +65,6 @@ export const VoucherCodesManualDialog = ({ value={data.code} onChange={change} /> - - { - if ([",", "."].includes(e.key)) { - e.preventDefault(); - } - }} - size="small" - label={intl.formatMessage(messages.enterUsage)} - value={data.usageLimit} - onChange={change} - /> - ) - } - /> - - + + {intl.formatMessage(commonMessages.generalInformations)} + + + - -
+ + ); }; export default VoucherInfo; diff --git a/src/discounts/components/VoucherLimits/VoucherLimits.tsx b/src/discounts/components/VoucherLimits/VoucherLimits.tsx index 66b4f41248b..44a1411d3b5 100644 --- a/src/discounts/components/VoucherLimits/VoucherLimits.tsx +++ b/src/discounts/components/VoucherLimits/VoucherLimits.tsx @@ -96,35 +96,6 @@ const VoucherLimits = ({ ))} - {isNewVoucher && ( - { - onChange(evt); - setData({ usageLimit: initialUsageLimit }); - }} - /> - )} - {data.hasUsageLimit && isNewVoucher && ( - - )} ; -export type VoucherCreateUrlQueryParams = Dialog; +export type VoucherCreateUrlQueryParams = Dialog; export const voucherUrl = (id: string, params?: VoucherUrlQueryParams) => voucherPath(encodeURIComponent(id)) + "?" + stringifyQs(params); export const voucherAddPath = urlJoin(voucherSection, "add"); diff --git a/src/discounts/views/VoucherCreate/VoucherCreate.tsx b/src/discounts/views/VoucherCreate/VoucherCreate.tsx index b488eb975d3..b526bdc44ed 100644 --- a/src/discounts/views/VoucherCreate/VoucherCreate.tsx +++ b/src/discounts/views/VoucherCreate/VoucherCreate.tsx @@ -1,5 +1,4 @@ // @ts-strict-ignore -import { ChannelsAction } from "@dashboard/channels/urls"; import { ChannelVoucherData, createSortedVoucherData, @@ -27,6 +26,7 @@ import { voucherAddUrl, VoucherCreateUrlQueryParams, voucherUrl, + VoucherUrlDialog, } from "../../urls"; import { createHandler } from "./handlers"; import { VOUCHER_CREATE_FORM_ID } from "./types"; @@ -43,7 +43,7 @@ export const VoucherCreateView: React.FC = ({ params }) => { const [updateMetadata] = useUpdateMetadataMutation({}); const [updatePrivateMetadata] = useUpdatePrivateMetadataMutation({}); const [openModal, closeModal] = createDialogActionHandlers< - ChannelsAction, + VoucherUrlDialog, VoucherCreateUrlQueryParams >(navigate, params => voucherAddUrl(params), params); @@ -131,6 +131,11 @@ export const VoucherCreateView: React.FC = ({ params }) => { saveButtonBarState={voucherCreateOpts.status} openChannelsModal={handleChannelsModalOpen} onChannelsChange={setCurrentChannels} + onMultipleVoucheCodesGenerate={() => openModal("multiple-codes")} + onSingleVoucherCodeGenerate={() => openModal("single-codes")} + onVoucherCodesDelete={() => openModal("delete-codes")} + onModalClose={closeModal} + isModalOpen={modalName => params.action === modalName} /> ); diff --git a/src/discounts/views/VoucherCreate/handlers.ts b/src/discounts/views/VoucherCreate/handlers.ts index 1f24361fc6c..2e909b3c3ba 100644 --- a/src/discounts/views/VoucherCreate/handlers.ts +++ b/src/discounts/views/VoucherCreate/handlers.ts @@ -31,10 +31,11 @@ export function createHandler( return async (formData: VoucherDetailsPageFormData) => { const response = await voucherCreate({ input: { + name: formData.name, applyOncePerCustomer: formData.applyOncePerCustomer, applyOncePerOrder: formData.applyOncePerOrder, onlyForStaff: formData.onlyForStaff, - code: formData.code, + codes: formData.codes.map(code => ({ code, usageLimit: 0 })), discountValueType: formData.discountType === DiscountTypeEnum.VALUE_PERCENTAGE ? DiscountValueTypeEnum.PERCENTAGE diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 426a3bafa6b..7dc6b4cbb70 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -456,7 +456,7 @@ export const VoucherDetails: React.FC = ({ variables: { id, input: { - codes, + codes: [], }, }, }) diff --git a/src/fragments/discounts.ts b/src/fragments/discounts.ts index 29b9b844aa2..c1336525dc6 100644 --- a/src/fragments/discounts.ts +++ b/src/fragments/discounts.ts @@ -122,6 +122,7 @@ export const voucherFragment = gql` ...Metadata id code + name startDate endDate usageLimit @@ -153,7 +154,6 @@ export const voucherCodeFragment = gql` fragment VoucherCode on VoucherCode { code used - usageLimit } `; diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index 62bfce8a9ff..e31441df673 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -523,7 +523,6 @@ export const VoucherCodeFragmentDoc = gql` fragment VoucherCode on VoucherCode { code used - usageLimit } `; export const VoucherFragmentDoc = gql` @@ -531,6 +530,7 @@ export const VoucherFragmentDoc = gql` ...Metadata id code + name startDate endDate usageLimit diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index c2129578c23..60187034fb0 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -9157,7 +9157,7 @@ export type VoucherChannelListingUpdateMutationVariables = Exact<{ }>; -export type VoucherChannelListingUpdateMutation = { __typename: 'Mutation', voucherChannelListingUpdate: { __typename: 'VoucherChannelListingUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherChannelListingUpdateMutation = { __typename: 'Mutation', voucherChannelListingUpdate: { __typename: 'VoucherChannelListingUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherUpdateMutationVariables = Exact<{ input: VoucherInput; @@ -9165,7 +9165,7 @@ export type VoucherUpdateMutationVariables = Exact<{ }>; -export type VoucherUpdateMutation = { __typename: 'Mutation', voucherUpdate: { __typename: 'VoucherUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherUpdateMutation = { __typename: 'Mutation', voucherUpdate: { __typename: 'VoucherUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCataloguesAddMutationVariables = Exact<{ input: CatalogueInput; @@ -9180,7 +9180,7 @@ export type VoucherCataloguesAddMutationVariables = Exact<{ }>; -export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCataloguesRemoveMutationVariables = Exact<{ input: CatalogueInput; @@ -9195,14 +9195,14 @@ export type VoucherCataloguesRemoveMutationVariables = Exact<{ }>; -export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCreateMutationVariables = Exact<{ input: VoucherInput; }>; -export type VoucherCreateMutation = { __typename: 'Mutation', voucherCreate: { __typename: 'VoucherCreate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCreateMutation = { __typename: 'Mutation', voucherCreate: { __typename: 'VoucherCreate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherDeleteMutationVariables = Exact<{ id: Scalars['ID']; @@ -9242,7 +9242,7 @@ export type VoucherListQueryVariables = Exact<{ }>; -export type VoucherListQuery = { __typename: 'Query', vouchers: { __typename: 'VoucherCountableConnection', edges: Array<{ __typename: 'VoucherCountableEdge', node: { __typename: 'Voucher', id: string, code: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type VoucherListQuery = { __typename: 'Query', vouchers: { __typename: 'VoucherCountableConnection', edges: Array<{ __typename: 'VoucherCountableEdge', node: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type SaleDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -9271,7 +9271,7 @@ export type VoucherDetailsQueryVariables = Exact<{ }>; -export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; +export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; export type VoucherCodesQueryVariables = Exact<{ id: Scalars['ID']; @@ -9282,7 +9282,7 @@ export type VoucherCodesQueryVariables = Exact<{ }>; -export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null } | null }; +export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null } | null }; export type FileUploadMutationVariables = Exact<{ file: Scalars['Upload']; @@ -9353,11 +9353,11 @@ export type SaleFragment = { __typename: 'Sale', id: string, name: string, type: export type SaleDetailsFragment = { __typename: 'Sale', id: string, name: string, type: SaleType, startDate: any, endDate: any | null, variantsCount: { __typename: 'ProductVariantCountableConnection', totalCount: number | null } | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, variants?: { __typename: 'ProductVariantCountableConnection', edges: Array<{ __typename: 'ProductVariantCountableEdge', node: { __typename: 'ProductVariant', id: string, name: string, product: { __typename: 'Product', id: string, name: string, thumbnail: { __typename: 'Image', url: string } | null, productType: { __typename: 'ProductType', id: string, name: string }, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, channelListings: Array<{ __typename: 'SaleChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; -export type VoucherFragment = { __typename: 'Voucher', id: string, code: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type VoucherFragment = { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; -export type VoucherCodeFragment = { __typename: 'VoucherCode', code: string | null, used: number | null, usageLimit: number | null }; +export type VoucherCodeFragment = { __typename: 'VoucherCode', code: string | null, used: number | null }; -export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; export type AttributeErrorFragment = { __typename: 'AttributeError', code: AttributeErrorCode, field: string | null, message: string | null }; From 1d8eeebbadda8a7b86c54137d701e71021735fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 27 Sep 2023 13:09:44 +0200 Subject: [PATCH 32/67] Genrate multipe codes --- package-lock.json | 53 ++++++++++--------- package.json | 3 +- .../VoucherCodesGenerateDialog.tsx | 20 ++++--- .../VoucherCreatePage/VoucherCreatePage.tsx | 27 ++++++++-- 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 11ca710c271..90fd0c1e5a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -88,7 +88,8 @@ "slugify": "^1.4.6", "tslib": "^2.4.1", "url-join": "^4.0.1", - "use-react-router": "^1.0.7" + "use-react-router": "^1.0.7", + "uuid": "^9.0.1" }, "devDependencies": { "@babel/cli": "^7.5.5", @@ -8884,15 +8885,6 @@ } } }, - "node_modules/@storybook/addon-actions/node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@storybook/addon-backgrounds": { "version": "7.0.8", "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.8.tgz", @@ -33595,6 +33587,16 @@ "node": ">= 6.0.0" } }, + "node_modules/teeny-request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/telejson": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", @@ -34977,11 +34979,15 @@ } }, "node_modules/uuid": { - "version": "3.4.0", - "dev": true, - "license": "MIT", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/uvu": { @@ -42472,14 +42478,6 @@ "telejson": "^7.0.3", "ts-dedent": "^2.0.0", "uuid": "^9.0.0" - }, - "dependencies": { - "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "optional": true - } } }, "@storybook/addon-backgrounds": { @@ -59909,6 +59907,12 @@ "agent-base": "5", "debug": "4" } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, @@ -60841,8 +60845,9 @@ "optional": true }, "uuid": { - "version": "3.4.0", - "dev": true + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, "uvu": { "version": "0.5.6", diff --git a/package.json b/package.json index 2fa77fd0ac0..01e2dad4e1c 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,8 @@ "slugify": "^1.4.6", "tslib": "^2.4.1", "url-join": "^4.0.1", - "use-react-router": "^1.0.7" + "use-react-router": "^1.0.7", + "uuid": "^9.0.1" }, "devDependencies": { "@babel/cli": "^7.5.5", diff --git a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx index 49289e51390..7e535d4a069 100644 --- a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx +++ b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx @@ -8,22 +8,26 @@ import { useIntl } from "react-intl"; interface VoucherCodesGenerateDialogProps { open: boolean; onClose: () => void; - onSubmit: () => void; + onSubmit: (data: GenerateMultipleVoucherCodeFormData) => void; } +export interface GenerateMultipleVoucherCodeFormData { + quantity: string; + prefix: string; +} + +const initialData: GenerateMultipleVoucherCodeFormData = { + quantity: "", + prefix: "", +}; + export const VoucherCodesGenerateDialog = ({ open, onClose, onSubmit, }: VoucherCodesGenerateDialogProps) => { const intl = useIntl(); - const { change, submit, data, reset } = useForm( - { - quantity: "", - prefix: "", - }, - onSubmit, - ); + const { change, submit, data, reset } = useForm(initialData, onSubmit); const handleKeyDown = (e: React.KeyboardEvent) => { if ( diff --git a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx index 4ecd8874462..edd3732d990 100644 --- a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx +++ b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx @@ -26,11 +26,15 @@ import { Box } from "@saleor/macaw-ui/next"; import isEqual from "lodash/isEqual"; import React from "react"; import { useIntl } from "react-intl"; +import { v4 as uuidv4 } from "uuid"; import { DiscountTypeEnum, RequirementsPicker } from "../../types"; import { VoucherCodes } from "../VoucherCodes"; import { VoucherCodesDeleteDialog } from "../VoucherCodesDeleteDialog"; -import { VoucherCodesGenerateDialog } from "../VoucherCodesGenerateDialog"; +import { + GenerateMultipleVoucherCodeFormData, + VoucherCodesGenerateDialog, +} from "../VoucherCodesGenerateDialog"; import { VoucherCodesManualDialog } from "../VoucherCodesManualDialog"; import VoucherDates from "../VoucherDates"; import { VoucherDetailsPageFormData } from "../VoucherDetailsPage"; @@ -122,6 +126,12 @@ const VoucherCreatePage: React.FC = ({ clearRowSelection, } = useRowSelection(); + const generateMultipleIds = (quantity: string, prefix?: string) => { + return Array.from({ length: Number(quantity) }).map(() => ({ + code: prefix ? `${prefix}-${uuidv4()}` : uuidv4(), + })); + }; + return ( = ({ setClearDatagridRowSelectionCallback(clearSelection); }; + const handleGenerateMultipeCodes = ({ + quantity, + prefix, + }: GenerateMultipleVoucherCodeFormData) => { + onModalClose(); + clearRowSelection(); + set({ + codes: [...data.codes, ...generateMultipleIds(quantity, prefix)], + }); + }; + return ( = ({ onChange={event => handleDiscountTypeChange(data, event)} variant="create" /> - + = ({ {}} + onSubmit={handleGenerateMultipeCodes} /> Date: Thu, 28 Sep 2023 14:54:58 +0200 Subject: [PATCH 33/67] Create voucher with codes generating --- .../VoucherCodesDatagrid/datagrid.ts | 2 +- .../VoucherCreatePage.stories.tsx | 5 + .../VoucherCreatePage/VoucherCreatePage.tsx | 372 ++++++++---------- .../components/VoucherCreatePage/const.ts | 31 ++ .../hooks/useVoucherCodesPagination.ts | 44 +++ .../hooks/useVoucherCodesSelection.ts | 37 ++ .../components/VoucherCreatePage/types.ts | 5 + .../components/VoucherCreatePage/utils.ts | 7 + src/discounts/fixtures.ts | 3 + src/discounts/views/VoucherCreate/handlers.ts | 2 +- .../views/VoucherDetails/VoucherDetails.tsx | 2 +- 11 files changed, 293 insertions(+), 217 deletions(-) create mode 100644 src/discounts/components/VoucherCreatePage/const.ts create mode 100644 src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts create mode 100644 src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesSelection.ts create mode 100644 src/discounts/components/VoucherCreatePage/types.ts create mode 100644 src/discounts/components/VoucherCreatePage/utils.ts diff --git a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts index 2c82157095c..184bd969123 100644 --- a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts +++ b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts @@ -11,7 +11,7 @@ export const voucherCodesStaticColumnsAdapter = (intl: IntlShape) => [ { id: "code", title: intl.formatMessage(columnsMessages.code), - width: 300, + width: 400, }, { id: "usage", diff --git a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.stories.tsx b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.stories.tsx index 4ba4436fe49..63326dd260b 100644 --- a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.stories.tsx +++ b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.stories.tsx @@ -13,6 +13,11 @@ const channels = createVoucherChannels(channelsList); const props: VoucherCreatePageProps = { allChannelsCount: channels.length, + onMultipleVoucheCodesGenerate: () => undefined, + onSingleVoucherCodeGenerate: () => undefined, + onModalClose: () => undefined, + isModalOpen: () => false, + onVoucherCodesDelete: () => undefined, channelListings: channels, disabled: false, errors: [], diff --git a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx index edd3732d990..70b3920b140 100644 --- a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx +++ b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx @@ -2,7 +2,6 @@ import { ChannelVoucherData } from "@dashboard/channels/utils"; import { TopNav } from "@dashboard/components/AppLayout/TopNav"; import ChannelsAvailabilityCard from "@dashboard/components/ChannelsAvailabilityCard"; import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton"; -import Form from "@dashboard/components/Form"; import { DetailPageLayout } from "@dashboard/components/Layouts"; import { Metadata } from "@dashboard/components/Metadata"; import Savebar from "@dashboard/components/Savebar"; @@ -12,23 +11,16 @@ import { } from "@dashboard/discounts/handlers"; import { voucherListUrl, VoucherUrlDialog } from "@dashboard/discounts/urls"; import { VOUCHER_CREATE_FORM_ID } from "@dashboard/discounts/views/VoucherCreate/types"; -import { - DiscountErrorFragment, - PermissionEnum, - VoucherTypeEnum, -} from "@dashboard/graphql"; -import { SubmitPromise } from "@dashboard/hooks/useForm"; +import { DiscountErrorFragment, PermissionEnum } from "@dashboard/graphql"; +import useForm, { SubmitPromise } from "@dashboard/hooks/useForm"; import useNavigator from "@dashboard/hooks/useNavigator"; -import { useRowSelection } from "@dashboard/hooks/useRowSelection"; import { validatePrice } from "@dashboard/products/utils/validation"; import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger"; import { Box } from "@saleor/macaw-ui/next"; -import isEqual from "lodash/isEqual"; import React from "react"; import { useIntl } from "react-intl"; -import { v4 as uuidv4 } from "uuid"; -import { DiscountTypeEnum, RequirementsPicker } from "../../types"; +import { RequirementsPicker } from "../../types"; import { VoucherCodes } from "../VoucherCodes"; import { VoucherCodesDeleteDialog } from "../VoucherCodesDeleteDialog"; import { @@ -43,6 +35,10 @@ import VoucherLimits from "../VoucherLimits"; import VoucherRequirements from "../VoucherRequirements"; import VoucherTypes from "../VoucherTypes"; import VoucherValue from "../VoucherValue"; +import { initialForm } from "./const"; +import { useVoucherCodesPagination } from "./hooks/useVoucherCodesPagination"; +import { useVoucherCodesSelection } from "./hooks/useVoucherCodesSelection"; +import { generateMultipleIds } from "./utils"; export interface FormData extends VoucherDetailsPageFormData { value: number; @@ -85,30 +81,6 @@ const VoucherCreatePage: React.FC = ({ const { makeChangeHandler: makeMetadataChangeHandler } = useMetadataChangeTrigger(); - const initialForm: FormData = { - applyOncePerCustomer: false, - applyOncePerOrder: false, - onlyForStaff: false, - channelListings, - name: "", - discountType: DiscountTypeEnum.VALUE_FIXED, - endDate: "", - endTime: "", - hasEndDate: false, - hasUsageLimit: false, - minCheckoutItemsQuantity: "0", - requirementsPicker: RequirementsPicker.NONE, - startDate: "", - startTime: "", - type: VoucherTypeEnum.ENTIRE_ORDER, - used: 1, - usageLimit: 1, - codes: [], - value: 0, - metadata: [], - privateMetadata: [], - }; - const checkIfSaveIsDisabled = (data: FormData) => (data.discountType.toString() !== "SHIPPING" && data.channelListings?.some( @@ -119,192 +91,164 @@ const VoucherCreatePage: React.FC = ({ )) || disabled; - const { - selectedRowIds, - setClearDatagridRowSelectionCallback, - setSelectedRowIds, - clearRowSelection, - } = useRowSelection(); - - const generateMultipleIds = (quantity: string, prefix?: string) => { - return Array.from({ length: Number(quantity) }).map(() => ({ - code: prefix ? `${prefix}-${uuidv4()}` : uuidv4(), - })); + const { change, data, triggerChange, set, submit } = useForm< + FormData, + unknown + >({ ...initialForm, channelListings }, onSubmit, { + confirmLeave: true, + formId: VOUCHER_CREATE_FORM_ID, + checkIfSaveIsDisabled, + }); + + const { clearRowSelection, setSelectedVoucherCodesIds, selectedRowIds } = + useVoucherCodesSelection(data.codes); + + const handleDiscountTypeChange = createDiscountTypeChangeHandler(change); + const handleChannelChange = createChannelsChangeHandler( + data.channelListings, + onChannelsChange, + triggerChange, + ); + const changeMetadata = makeMetadataChangeHandler(change); + + const handleGenerateMultipeCodes = ({ + quantity, + prefix, + }: GenerateMultipleVoucherCodeFormData) => { + onModalClose(); + clearRowSelection(); + set({ + codes: [...data.codes, ...generateMultipleIds(quantity, prefix)], + }); }; - return ( - - {({ change, data, submit, triggerChange, set }) => { - const handleDiscountTypeChange = - createDiscountTypeChangeHandler(change); - const handleChannelChange = createChannelsChangeHandler( - data.channelListings, - onChannelsChange, - triggerChange, - ); - const changeMetadata = makeMetadataChangeHandler(change); - - const handleSetSelectedVoucherCodesIds = ( - rows: number[], - clearSelection: () => void, - ) => { - if (!data.codes) { - return; - } - - const rowsIds = rows.map(row => data.codes[row].code).filter(Boolean); - const haveSaveValues = isEqual(rowsIds, selectedRowIds); - - if (!haveSaveValues) { - setSelectedRowIds(rowsIds as string[]); - } + const { pagination, paginatedCodes, settings, onSettingsChange } = + useVoucherCodesPagination(data.codes); - setClearDatagridRowSelectionCallback(clearSelection); - }; - - const handleGenerateMultipeCodes = ({ - quantity, - prefix, - }: GenerateMultipleVoucherCodeFormData) => { - onModalClose(); - clearRowSelection(); - set({ - codes: [...data.codes, ...generateMultipleIds(quantity, prefix)], - }); - }; - - return ( - - + + + + handleDiscountTypeChange(data, event)} + variant="create" + /> + + - - handleDiscountTypeChange(data, event)} - variant="create" - /> - - {}} - onSingleCodesGenerate={onSingleVoucherCodeGenerate} - selectedCodesIds={selectedRowIds} - settings={{ rowNumber: 10 }} - voucherCodesPagination={{} as any} - /> - - - {data.discountType.toString() !== "SHIPPING" ? ( - <> - - - ) : null} - - - - - - - ({ - id: channel.id, - name: channel.name, - }))} - disabled={disabled} - openModal={openChannelsModal} - /> - - + + {data.discountType.toString() !== "SHIPPING" ? ( + navigate(voucherListUrl())} - onSubmit={submit} - state={saveButtonBarState} - /> - - { - set({ - codes: [...data.codes, { code }], - }); - }} - /> - - { - onModalClose(); - clearRowSelection(); - set({ - codes: data.codes.filter( - ({ code }) => !selectedRowIds.includes(code), - ), - }); - }} - /> - - ); - }} - + ) : null} + + + + + + + ({ + id: channel.id, + name: channel.name, + }))} + disabled={disabled} + openModal={openChannelsModal} + /> + + navigate(voucherListUrl())} + onSubmit={submit} + state={saveButtonBarState} + /> + + { + set({ + codes: [...data.codes, { code }], + }); + }} + /> + + { + onModalClose(); + clearRowSelection(); + set({ + codes: data.codes.filter( + ({ code }) => !selectedRowIds.includes(code), + ), + }); + }} + /> + + ); }; + VoucherCreatePage.displayName = "VoucherCreatePage"; export default VoucherCreatePage; diff --git a/src/discounts/components/VoucherCreatePage/const.ts b/src/discounts/components/VoucherCreatePage/const.ts new file mode 100644 index 00000000000..ce219e69b97 --- /dev/null +++ b/src/discounts/components/VoucherCreatePage/const.ts @@ -0,0 +1,31 @@ +import { + DiscountTypeEnum, + RequirementsPicker, +} from "@dashboard/discounts/types"; +import { VoucherTypeEnum } from "@dashboard/graphql"; + +import { FormData } from "./types"; + +export const initialForm: FormData = { + applyOncePerCustomer: false, + applyOncePerOrder: false, + onlyForStaff: false, + channelListings: [], + name: "", + discountType: DiscountTypeEnum.VALUE_FIXED, + endDate: "", + endTime: "", + hasEndDate: false, + hasUsageLimit: false, + minCheckoutItemsQuantity: "0", + requirementsPicker: RequirementsPicker.NONE, + startDate: "", + startTime: "", + type: VoucherTypeEnum.ENTIRE_ORDER, + used: 1, + usageLimit: 1, + codes: [], + value: 0, + metadata: [], + privateMetadata: [], +}; diff --git a/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts new file mode 100644 index 00000000000..a053e447726 --- /dev/null +++ b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts @@ -0,0 +1,44 @@ +import { PAGINATE_BY } from "@dashboard/config"; +import { UseListSettings } from "@dashboard/hooks/useListSettings"; +import useLocalPageInfo from "@dashboard/hooks/useLocalPageInfo"; +import { LocalPagination } from "@dashboard/hooks/useLocalPaginator"; +import { useState } from "react"; + +import { VoucherCode } from "../../VoucherCodesDatagrid/types"; + +export interface UseVoucherCodesPagination { + pagination: LocalPagination; + paginatedCodes: VoucherCode[]; + onSettingsChange: UseListSettings["updateListSettings"]; + settings: UseListSettings["settings"]; +} + +export const useVoucherCodesPagination = ( + voucherCodes: VoucherCode[], +): UseVoucherCodesPagination => { + const [codesPaginatedBy, setCodesPaginatedBy] = useState(PAGINATE_BY); + const { loadNextPage, loadPreviousPage, pageInfo, pageValues } = + useLocalPageInfo(voucherCodes, codesPaginatedBy); + + return { + paginatedCodes: pageValues, + settings: { + rowNumber: codesPaginatedBy, + }, + onSettingsChange: (key, value) => { + if (key === "rowNumber") { + setCodesPaginatedBy(value as number); + } + }, + pagination: { + loadNextPage, + loadPreviousPage, + paginatorType: "click", + pageInfo: { + ...pageInfo, + endCursor: pageInfo.endCursor.toString(), + startCursor: pageInfo.startCursor.toString(), + }, + }, + }; +}; diff --git a/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesSelection.ts b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesSelection.ts new file mode 100644 index 00000000000..8c3bb1a10a6 --- /dev/null +++ b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesSelection.ts @@ -0,0 +1,37 @@ +import { useRowSelection } from "@dashboard/hooks/useRowSelection"; +import isEqual from "lodash/isEqual"; + +import { VoucherCode } from "../../VoucherCodesDatagrid/types"; + +export const useVoucherCodesSelection = (codes: VoucherCode[]) => { + const { + selectedRowIds, + setClearDatagridRowSelectionCallback, + setSelectedRowIds, + clearRowSelection, + } = useRowSelection(); + + const setSelectedVoucherCodesIds = ( + rows: number[], + clearSelection: () => void, + ) => { + if (!codes) { + return; + } + + const rowsIds = rows.map(row => codes[row].code).filter(Boolean); + const haveSaveValues = isEqual(rowsIds, selectedRowIds); + + if (!haveSaveValues) { + setSelectedRowIds(rowsIds as string[]); + } + + setClearDatagridRowSelectionCallback(clearSelection); + }; + + return { + selectedRowIds, + setSelectedVoucherCodesIds, + clearRowSelection, + }; +}; diff --git a/src/discounts/components/VoucherCreatePage/types.ts b/src/discounts/components/VoucherCreatePage/types.ts new file mode 100644 index 00000000000..5345ee89ff9 --- /dev/null +++ b/src/discounts/components/VoucherCreatePage/types.ts @@ -0,0 +1,5 @@ +import { VoucherDetailsPageFormData } from "../VoucherDetailsPage"; + +export interface FormData extends VoucherDetailsPageFormData { + value: number; +} diff --git a/src/discounts/components/VoucherCreatePage/utils.ts b/src/discounts/components/VoucherCreatePage/utils.ts new file mode 100644 index 00000000000..9e09180e7f2 --- /dev/null +++ b/src/discounts/components/VoucherCreatePage/utils.ts @@ -0,0 +1,7 @@ +import { v4 as uuidv4 } from "uuid"; + +export const generateMultipleIds = (quantity: string, prefix?: string) => { + return Array.from({ length: Number(quantity) }).map(() => ({ + code: prefix ? `${prefix}-${uuidv4()}` : uuidv4(), + })); +}; diff --git a/src/discounts/fixtures.ts b/src/discounts/fixtures.ts index 4c0b88c7c31..a2195c129f8 100644 --- a/src/discounts/fixtures.ts +++ b/src/discounts/fixtures.ts @@ -135,6 +135,7 @@ export const saleList: SaleFragment[] = [ export const voucherList: VoucherFragment[] = [ { __typename: "Voucher" as "Voucher", + name: "Free shipping", metadata: [], privateMetadata: [], channelListings: [ @@ -174,6 +175,7 @@ export const voucherList: VoucherFragment[] = [ }, { __typename: "Voucher" as "Voucher", + name: "Free 2019", metadata: [], privateMetadata: [], channelListings: [ @@ -582,6 +584,7 @@ export const sale: SaleDetailsFragment = { export const voucherDetails: VoucherDetailsFragment = { __typename: "Voucher", + name: "VFree2020", metadata: [], privateMetadata: [], applyOncePerCustomer: false, diff --git a/src/discounts/views/VoucherCreate/handlers.ts b/src/discounts/views/VoucherCreate/handlers.ts index 2e909b3c3ba..6dc23096d3f 100644 --- a/src/discounts/views/VoucherCreate/handlers.ts +++ b/src/discounts/views/VoucherCreate/handlers.ts @@ -35,7 +35,7 @@ export function createHandler( applyOncePerCustomer: formData.applyOncePerCustomer, applyOncePerOrder: formData.applyOncePerOrder, onlyForStaff: formData.onlyForStaff, - codes: formData.codes.map(code => ({ code, usageLimit: 0 })), + codes: formData.codes.map(({ code }) => ({ code, usageLimit: 0 })), discountValueType: formData.discountType === DiscountTypeEnum.VALUE_PERCENTAGE ? DiscountValueTypeEnum.PERCENTAGE diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 7dc6b4cbb70..0e712c49647 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -451,7 +451,7 @@ export const VoucherDetails: React.FC = ({ open={params.action === "single-codes"} confirmButtonTransitionState={voucherUpdateOpts.status} onClose={closeModal} - onSubmit={codes => + onSubmit={() => voucherUpdate({ variables: { id, From a96cd8772f183067abef455eef45f17ec285e6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 28 Sep 2023 15:14:39 +0200 Subject: [PATCH 34/67] Add uuid types --- package-lock.json | 13 +++++++++++++ package.json | 1 + 2 files changed, 14 insertions(+) diff --git a/package-lock.json b/package-lock.json index 90fd0c1e5a7..5b5bd27b0f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -138,6 +138,7 @@ "@types/react-sortable-hoc": "^0.7.1", "@types/react-sortable-tree": "^0.3.15", "@types/url-join": "^4.0.1", + "@types/uuid": "^9.0.4", "@types/webappsec-credential-management": "^0.5.1", "@typescript-eslint/eslint-plugin": "^5.60.0", "@typescript-eslint/parser": "^5.41.0", @@ -12685,6 +12686,12 @@ "integrity": "sha512-wDXw9LEEUHyV+7UWy7U315nrJGJ7p1BzaCxDpEoLr789Dk1WDVMMlf3iBfbG2F8NdWnYyFbtTxUn2ZNbm1Q4LQ==", "dev": true }, + "node_modules/@types/uuid": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.4.tgz", + "integrity": "sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==", + "dev": true + }, "node_modules/@types/webappsec-credential-management": { "version": "0.5.1", "dev": true, @@ -45289,6 +45296,12 @@ "integrity": "sha512-wDXw9LEEUHyV+7UWy7U315nrJGJ7p1BzaCxDpEoLr789Dk1WDVMMlf3iBfbG2F8NdWnYyFbtTxUn2ZNbm1Q4LQ==", "dev": true }, + "@types/uuid": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.4.tgz", + "integrity": "sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==", + "dev": true + }, "@types/webappsec-credential-management": { "version": "0.5.1", "dev": true diff --git a/package.json b/package.json index 01e2dad4e1c..845d38f49de 100644 --- a/package.json +++ b/package.json @@ -145,6 +145,7 @@ "@types/react-sortable-hoc": "^0.7.1", "@types/react-sortable-tree": "^0.3.15", "@types/url-join": "^4.0.1", + "@types/uuid": "^9.0.4", "@types/webappsec-credential-management": "^0.5.1", "@typescript-eslint/eslint-plugin": "^5.60.0", "@typescript-eslint/parser": "^5.41.0", From 0e9bc2db633a819cbee5e3df5a341c7ae57913e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 28 Sep 2023 15:57:00 +0200 Subject: [PATCH 35/67] Prevent provide qunatity greater than limit --- .../VoucherCodesGenerateDialog.tsx | 29 +++++++++++++++---- .../VoucherCodesGenerateDialog/messages.ts | 16 ++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 src/discounts/components/VoucherCodesGenerateDialog/messages.ts diff --git a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx index 7e535d4a069..34fd21aefd6 100644 --- a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx +++ b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx @@ -2,9 +2,11 @@ import { DashboardModal } from "@dashboard/components/Modal"; import useForm from "@dashboard/hooks/useForm"; import { buttonMessages } from "@dashboard/intl"; import { Box, Button, Input } from "@saleor/macaw-ui/next"; -import React from "react"; +import React, { ChangeEvent } from "react"; import { useIntl } from "react-intl"; +import { messages } from "./messages"; + interface VoucherCodesGenerateDialogProps { open: boolean; onClose: () => void; @@ -21,6 +23,8 @@ const initialData: GenerateMultipleVoucherCodeFormData = { prefix: "", }; +const MAX_VOUCHER_CODES = 50; + export const VoucherCodesGenerateDialog = ({ open, onClose, @@ -44,6 +48,17 @@ export const VoucherCodesGenerateDialog = ({ } }; + const handleChange = (e: ChangeEvent) => { + const value = Number(e.currentTarget.value); + + if (Number.isNaN(value) || value > MAX_VOUCHER_CODES) { + e.preventDefault(); + return; + } + + change(e); + }; + const handleModalClose = () => { onClose(); reset(); @@ -52,21 +67,25 @@ export const VoucherCodesGenerateDialog = ({ return ( - Generate voucher codes + + {intl.formatMessage(messages.title)} + diff --git a/src/discounts/components/VoucherCodesGenerateDialog/messages.ts b/src/discounts/components/VoucherCodesGenerateDialog/messages.ts new file mode 100644 index 00000000000..236acf11863 --- /dev/null +++ b/src/discounts/components/VoucherCodesGenerateDialog/messages.ts @@ -0,0 +1,16 @@ +import { defineMessages } from "react-intl"; + +export const messages = defineMessages({ + title: { + id: "qgQeVW", + defaultMessage: "Generate Voucher Codes", + }, + codeQuantity: { + id: "vTPu1s", + defaultMessage: "Code Quantity (max {maxCodes})", + }, + codePrefix: { + id: "1UQ9Qy", + defaultMessage: "Code Prefix (Optional)", + }, +}); From 54ae988015ae6a8572aff61c95012380d21f30a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 28 Sep 2023 16:50:29 +0200 Subject: [PATCH 36/67] Use list settings --- src/config.ts | 9 +++---- .../hooks/useVoucherCodesPagination.ts | 24 +++++++++---------- .../views/VoucherDetails/useVoucherCodes.ts | 2 +- src/types.ts | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/config.ts b/src/config.ts index 1f777c2b89d..6f8c6298373 100644 --- a/src/config.ts +++ b/src/config.ts @@ -57,7 +57,6 @@ export interface AppListViewSettings { [ListViews.STAFF_MEMBERS_LIST]: ListSettings; [ListViews.PERMISSION_GROUP_LIST]: ListSettings; [ListViews.VOUCHER_LIST]: ListSettings; - [ListViews.VOUCHER_CODDES_LIST]: ListSettings; [ListViews.WAREHOUSE_LIST]: ListSettings; [ListViews.WEBHOOK_LIST]: ListSettings; [ListViews.TRANSLATION_ATTRIBUTE_VALUE_LIST]: ListSettings; @@ -65,6 +64,7 @@ export interface AppListViewSettings { [ListViews.ORDER_DETAILS_LIST]: ListSettings; [ListViews.ORDER_DRAFT_DETAILS_LIST]: ListSettings; [ListViews.PRODUCT_DETAILS]: ListSettings; + [ListViews.VOUCHER_CODES]: ListSettings; } export const defaultListSettings: AppListViewSettings = { @@ -139,9 +139,7 @@ export const defaultListSettings: AppListViewSettings = { rowNumber: PAGINATE_BY, columns: ["code", "min-spent", "start-date", "end-date", "value", "limit"], }, - [ListViews.VOUCHER_CODDES_LIST]: { - rowNumber: PAGINATE_BY, - }, + [ListViews.WAREHOUSE_LIST]: { rowNumber: PAGINATE_BY, }, @@ -184,6 +182,9 @@ export const defaultListSettings: AppListViewSettings = { rowNumber: PAGINATE_BY, columns: ["name", "sku"], }, + [ListViews.VOUCHER_CODES]: { + rowNumber: PAGINATE_BY, + }, }; export const APP_VERSION = diff --git a/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts index a053e447726..f5bcf4c34d2 100644 --- a/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts +++ b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts @@ -1,8 +1,9 @@ -import { PAGINATE_BY } from "@dashboard/config"; -import { UseListSettings } from "@dashboard/hooks/useListSettings"; +import useListSettings, { + UseListSettings, +} from "@dashboard/hooks/useListSettings"; import useLocalPageInfo from "@dashboard/hooks/useLocalPageInfo"; import { LocalPagination } from "@dashboard/hooks/useLocalPaginator"; -import { useState } from "react"; +import { ListViews } from "@dashboard/types"; import { VoucherCode } from "../../VoucherCodesDatagrid/types"; @@ -16,20 +17,17 @@ export interface UseVoucherCodesPagination { export const useVoucherCodesPagination = ( voucherCodes: VoucherCode[], ): UseVoucherCodesPagination => { - const [codesPaginatedBy, setCodesPaginatedBy] = useState(PAGINATE_BY); + const { settings, updateListSettings } = useListSettings( + ListViews.VOUCHER_CODES, + ); + const { loadNextPage, loadPreviousPage, pageInfo, pageValues } = - useLocalPageInfo(voucherCodes, codesPaginatedBy); + useLocalPageInfo(voucherCodes, settings.rowNumber); return { paginatedCodes: pageValues, - settings: { - rowNumber: codesPaginatedBy, - }, - onSettingsChange: (key, value) => { - if (key === "rowNumber") { - setCodesPaginatedBy(value as number); - } - }, + settings, + onSettingsChange: updateListSettings, pagination: { loadNextPage, loadPreviousPage, diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts index 21b27119f8c..f8109d9184e 100644 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.ts @@ -13,7 +13,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { const { settings: voucherCodesSettings, updateListSettings: updateVoucherCodesListSettings, - } = useListSettings(ListViews.VOUCHER_CODDES_LIST); + } = useListSettings(ListViews.VOUCHER_CODES); const [voucherCodesPaginationState, setVoucherCodesPaginationState] = useLocalPaginationState(voucherCodesSettings.rowNumber); diff --git a/src/types.ts b/src/types.ts index ad28f71f711..8b7371e4c9f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -42,13 +42,13 @@ export enum ListViews { SHIPPING_METHODS_LIST = "SHIPPING_METHODS_LIST", STAFF_MEMBERS_LIST = "STAFF_MEMBERS_LIST", VOUCHER_LIST = "VOUCHER_LIST", - VOUCHER_CODDES_LIST = "VOUCHER_CODES_LIST", WAREHOUSE_LIST = "WAREHOUSE_LIST", WEBHOOK_LIST = "WEBHOOK_LIST", TRANSLATION_ATTRIBUTE_VALUE_LIST = "TRANSLATION_ATTRIBUTE_VALUE_LIST", GIFT_CARD_LIST = "GIFT_CARD_LIST", // Not strictly a list view, but there's a list of variants PRODUCT_DETAILS = "PRODUCT_DETAILS", + VOUCHER_CODES = "VOUCHER_CODES", } export interface ListProps { From ad4fc5953e4d25b843446f2beb552eb18c54b797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 3 Oct 2023 15:47:57 +0200 Subject: [PATCH 37/67] edit pagination wip --- .../components/VoucherCodes/VoucherCodes.tsx | 1 + .../VoucherCodesGenerateDialog.tsx | 8 +- .../VoucherCreatePage/VoucherCreatePage.tsx | 27 +++--- .../views/VoucherDetails/VoucherDetails.tsx | 15 +--- .../views/VoucherDetails/useVoucherCodes.ts | 90 ++++++++++++++++++- 5 files changed, 110 insertions(+), 31 deletions(-) diff --git a/src/discounts/components/VoucherCodes/VoucherCodes.tsx b/src/discounts/components/VoucherCodes/VoucherCodes.tsx index 8c2ee091d62..2f4a501fa52 100644 --- a/src/discounts/components/VoucherCodes/VoucherCodes.tsx +++ b/src/discounts/components/VoucherCodes/VoucherCodes.tsx @@ -43,6 +43,7 @@ export const VoucherCodes = ({ justifyContent="space-between" alignItems="center" marginBottom={4} + marginTop={8} paddingX={6} > diff --git a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx index 34fd21aefd6..1c299617ef0 100644 --- a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx +++ b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx @@ -64,6 +64,12 @@ export const VoucherCodesGenerateDialog = ({ reset(); }; + const handleSubmit = async () => { + await submit(); + onClose(); + reset(); + }; + return ( @@ -94,7 +100,7 @@ export const VoucherCodesGenerateDialog = ({ - diff --git a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx index 70b3920b140..58fa7cfc4fa 100644 --- a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx +++ b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx @@ -16,7 +16,6 @@ import useForm, { SubmitPromise } from "@dashboard/hooks/useForm"; import useNavigator from "@dashboard/hooks/useNavigator"; import { validatePrice } from "@dashboard/products/utils/validation"; import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger"; -import { Box } from "@saleor/macaw-ui/next"; import React from "react"; import { useIntl } from "react-intl"; @@ -144,20 +143,18 @@ const VoucherCreatePage: React.FC = ({ onChange={event => handleDiscountTypeChange(data, event)} variant="create" /> - - - + = ({ voucherCodesRefetch, handleSetSelectedVoucherCodesIds, updateVoucherCodesListSettings, + handleAddVoucherCode, + handleGenerateMultipeCodes, } = useVoucherCodes({ id }); const [openModal, closeModal] = createDialogActionHandlers< @@ -445,22 +447,13 @@ export const VoucherDetails: React.FC = ({ - voucherUpdate({ - variables: { - id, - input: { - codes: [], - }, - }, - }) - } + onSubmit={handleAddVoucherCode} /> { const { @@ -15,6 +19,24 @@ export const useVoucherCodes = ({ id }: { id: string }) => { updateListSettings: updateVoucherCodesListSettings, } = useListSettings(ListViews.VOUCHER_CODES); + const [addedVoucherCodes, setAddedVoucherCodes] = useState([]); + const [serverPagination, setServerPagination] = useState(true); + + const handleAddVoucherCode = (code: string) => [ + setAddedVoucherCodes(codes => [...codes, { code }]), + ]; + + const handleGenerateMultipeCodes = ({ + quantity, + prefix, + }: GenerateMultipleVoucherCodeFormData) => { + setAddedVoucherCodes(codes => [ + ...codes, + ...generateMultipleIds(quantity, prefix), + ]); + setServerPagination(false); + }; + const [voucherCodesPaginationState, setVoucherCodesPaginationState] = useLocalPaginationState(voucherCodesSettings.rowNumber); @@ -33,7 +55,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { }, }); - const voucherCodesPagination = voucherCodesPaginate( + let voucherCodesPagination = voucherCodesPaginate( voucherCodesData?.voucher?.codes?.pageInfo, voucherCodesPaginationState, ); @@ -44,7 +66,23 @@ export const useVoucherCodes = ({ id }: { id: string }) => { setSelectedRowIds, } = useRowSelection(); - const voucherCodes = mapEdgesToItems(voucherCodesData?.voucher?.codes); + const serverVoucherCodes = + mapEdgesToItems(voucherCodesData?.voucher?.codes) ?? []; + + const { paginatedCodes, pagination: clientPagination } = + useVoucherCodesPagination(addedVoucherCodes); + + let voucherCodes = []; + + if (serverPagination) { + voucherCodes = serverVoucherCodes; + } else { + voucherCodes = paginatedCodes; + } + + if (!serverPagination) { + voucherCodesPagination = clientPagination; + } const handleSetSelectedVoucherCodesIds = useCallback( (rows: number[], clearSelection: () => void) => { @@ -69,14 +107,58 @@ export const useVoucherCodes = ({ id }: { id: string }) => { ], ); + const finalPagination = serverPagination + ? voucherCodesPagination + : clientPagination; + return { voucherCodes, voucherCodesLoading, - voucherCodesPagination, + voucherCodesPagination: { + ...finalPagination, + pageInfo: { + ...finalPagination.pageInfo, + hasNextPage: serverPagination + ? voucherCodesPagination?.pageInfo?.hasNextPage + : clientPagination?.pageInfo?.hasNextPage || + voucherCodesData?.voucher?.codes?.edges.length > 0, + hasPreviousPage: !serverPagination + ? clientPagination.pageInfo?.hasPreviousPage + : voucherCodesPagination?.pageInfo?.hasPreviousPage || + addedVoucherCodes.length > 0, + }, + loadNextPage: () => { + if (serverPagination) { + voucherCodesPagination.loadNextPage(); + } else { + if (voucherCodes.length < voucherCodesSettings.rowNumber) { + setServerPagination(true); + } else { + clientPagination.loadNextPage(); + } + } + }, + loadPreviousPage: () => { + if (serverPagination) { + if ( + !voucherCodesPagination?.pageInfo?.hasPreviousPage && + addedVoucherCodes.length > 0 + ) { + setServerPagination(false); + } else { + voucherCodesPagination.loadPreviousPage(); + } + } else { + clientPagination.loadPreviousPage(); + } + }, + }, voucherCodesRefetch, voucherCodesSettings, updateVoucherCodesListSettings, selectedVoucherCodesIds: selectedRowIds, handleSetSelectedVoucherCodesIds, + handleAddVoucherCode, + handleGenerateMultipeCodes, }; }; From 4aeca9c01e4d8b86f3261ed0741b7e137e67357b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 3 Oct 2023 15:54:34 +0200 Subject: [PATCH 38/67] Add status column --- .../VoucherCodesDatagrid/VoucherCodesDatagrid.tsx | 2 +- src/discounts/components/VoucherCodesDatagrid/datagrid.ts | 7 +++++++ src/discounts/components/VoucherCodesDatagrid/messages.ts | 6 +++--- src/discounts/components/VoucherCodesDatagrid/types.ts | 1 + src/discounts/components/VoucherCreatePage/utils.ts | 1 + 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index b2fe457dd79..58be698221b 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -43,7 +43,7 @@ export const VoucherCodesDatagrid = ({ const { handlers, visibleColumns } = useColumns({ staticColumns: voucherCodesStaticColumns, - selectedColumns: ["code", "usage", "limit"], + selectedColumns: ["code", "usage", "status"], onSave: () => {}, }); diff --git a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts index 184bd969123..44b15a8f8b2 100644 --- a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts +++ b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts @@ -18,6 +18,11 @@ export const voucherCodesStaticColumnsAdapter = (intl: IntlShape) => [ title: intl.formatMessage(columnsMessages.usage), width: 150, }, + { + id: "status", + title: intl.formatMessage(columnsMessages.status), + width: 150, + }, ]; export const createGetCellContent = @@ -38,6 +43,8 @@ export const createGetCellContent = rowData?.used?.toString() ?? PLACEHOLDER, false, ); + case "status": + return readonlyTextCell(rowData?.status ?? "Active", false); default: return readonlyTextCell("", false); } diff --git a/src/discounts/components/VoucherCodesDatagrid/messages.ts b/src/discounts/components/VoucherCodesDatagrid/messages.ts index f04acaad45b..12c20605661 100644 --- a/src/discounts/components/VoucherCodesDatagrid/messages.ts +++ b/src/discounts/components/VoucherCodesDatagrid/messages.ts @@ -9,9 +9,9 @@ export const columnsMessages = defineMessages({ defaultMessage: "Usage", id: "wbsq7O", }, - limit: { - defaultMessage: "Limit", - id: "YH6meO", + status: { + defaultMessage: "Status", + id: "tzMNF3", }, }); diff --git a/src/discounts/components/VoucherCodesDatagrid/types.ts b/src/discounts/components/VoucherCodesDatagrid/types.ts index 367023dd27c..4406acac35c 100644 --- a/src/discounts/components/VoucherCodesDatagrid/types.ts +++ b/src/discounts/components/VoucherCodesDatagrid/types.ts @@ -1,4 +1,5 @@ export interface VoucherCode { code: string; used?: number; + status?: string; } diff --git a/src/discounts/components/VoucherCreatePage/utils.ts b/src/discounts/components/VoucherCreatePage/utils.ts index 9e09180e7f2..36373bd3e54 100644 --- a/src/discounts/components/VoucherCreatePage/utils.ts +++ b/src/discounts/components/VoucherCreatePage/utils.ts @@ -3,5 +3,6 @@ import { v4 as uuidv4 } from "uuid"; export const generateMultipleIds = (quantity: string, prefix?: string) => { return Array.from({ length: Number(quantity) }).map(() => ({ code: prefix ? `${prefix}-${uuidv4()}` : uuidv4(), + status: "Draft", })); }; From 7572946dd055c50c221e3b13f1aa9eca4fac6e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Wed, 4 Oct 2023 09:13:11 +0200 Subject: [PATCH 39/67] refactor useVoucherCodes --- .../views/VoucherDetails/useVoucherCodes.ts | 110 +++++++++++------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts index df0af70800c..f7e3a838a3a 100644 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.ts @@ -5,6 +5,7 @@ import { generateMultipleIds } from "@dashboard/discounts/components/VoucherCrea import { useVoucherCodesQuery } from "@dashboard/graphql"; import useListSettings from "@dashboard/hooks/useListSettings"; import useLocalPaginator, { + LocalPagination, useLocalPaginationState, } from "@dashboard/hooks/useLocalPaginator"; import { useRowSelection } from "@dashboard/hooks/useRowSelection"; @@ -20,7 +21,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { } = useListSettings(ListViews.VOUCHER_CODES); const [addedVoucherCodes, setAddedVoucherCodes] = useState([]); - const [serverPagination, setServerPagination] = useState(true); + const [isServerPagination, setIsServerPagination] = useState(true); const handleAddVoucherCode = (code: string) => [ setAddedVoucherCodes(codes => [...codes, { code }]), @@ -34,16 +35,32 @@ export const useVoucherCodes = ({ id }: { id: string }) => { ...codes, ...generateMultipleIds(quantity, prefix), ]); - setServerPagination(false); + setIsServerPagination(false); }; - const [voucherCodesPaginationState, setVoucherCodesPaginationState] = - useLocalPaginationState(voucherCodesSettings.rowNumber); + const [ + serverVoucherCodesPaginationState, + setServerVoucherCodesPaginationState, + ] = useLocalPaginationState(voucherCodesSettings.rowNumber); - const voucherCodesPaginate = useLocalPaginator( - setVoucherCodesPaginationState, + const serverVoucherCodesPaginate = useLocalPaginator( + setServerVoucherCodesPaginationState, ); + const { + paginatedCodes: clientVoucherCodes, + pagination: clientVoucherCodesPagination, + onSettingsChange, + } = useVoucherCodesPagination(addedVoucherCodes); + + const hasClientPaginationNextPage = + clientVoucherCodesPagination?.pageInfo?.hasNextPage; + const hasClientPaginationPrevPage = + clientVoucherCodesPagination.pageInfo?.hasPreviousPage; + + const freeSlotsInClientPagianationPage = + voucherCodesSettings.rowNumber - clientVoucherCodes.length; + const { data: voucherCodesData, loading: voucherCodesLoading, @@ -51,15 +68,26 @@ export const useVoucherCodes = ({ id }: { id: string }) => { } = useVoucherCodesQuery({ variables: { id, - ...voucherCodesPaginationState, + ...(isServerPagination && serverVoucherCodesPaginationState), + first: + !isServerPagination && + !hasClientPaginationNextPage && + freeSlotsInClientPagianationPage > 0 + ? freeSlotsInClientPagianationPage + : serverVoucherCodesPaginationState.first, }, }); - let voucherCodesPagination = voucherCodesPaginate( + const serverVoucherCodesPagination = serverVoucherCodesPaginate( voucherCodesData?.voucher?.codes?.pageInfo, - voucherCodesPaginationState, + serverVoucherCodesPaginationState, ); + const hasServerPaginationNextPage = + serverVoucherCodesPagination?.pageInfo?.hasNextPage; + const hasServerPaginationPrevPage = + serverVoucherCodesPagination?.pageInfo?.hasPreviousPage; + const { selectedRowIds, setClearDatagridRowSelectionCallback, @@ -69,19 +97,25 @@ export const useVoucherCodes = ({ id }: { id: string }) => { const serverVoucherCodes = mapEdgesToItems(voucherCodesData?.voucher?.codes) ?? []; - const { paginatedCodes, pagination: clientPagination } = - useVoucherCodesPagination(addedVoucherCodes); - let voucherCodes = []; - if (serverPagination) { + if (isServerPagination) { voucherCodes = serverVoucherCodes; } else { - voucherCodes = paginatedCodes; + voucherCodes = [ + ...clientVoucherCodes, + ...(!hasClientPaginationNextPage && freeSlotsInClientPagianationPage > 0 + ? [...serverVoucherCodes] + : []), + ]; } - if (!serverPagination) { - voucherCodesPagination = clientPagination; + let voucherCodesPagination: LocalPagination; + + if (!isServerPagination) { + voucherCodesPagination = clientVoucherCodesPagination; + } else { + voucherCodesPagination = serverVoucherCodesPagination; } const handleSetSelectedVoucherCodesIds = useCallback( @@ -107,55 +141,49 @@ export const useVoucherCodes = ({ id }: { id: string }) => { ], ); - const finalPagination = serverPagination - ? voucherCodesPagination - : clientPagination; - return { voucherCodes, voucherCodesLoading, voucherCodesPagination: { - ...finalPagination, + ...voucherCodesPagination, pageInfo: { - ...finalPagination.pageInfo, - hasNextPage: serverPagination - ? voucherCodesPagination?.pageInfo?.hasNextPage - : clientPagination?.pageInfo?.hasNextPage || - voucherCodesData?.voucher?.codes?.edges.length > 0, - hasPreviousPage: !serverPagination - ? clientPagination.pageInfo?.hasPreviousPage - : voucherCodesPagination?.pageInfo?.hasPreviousPage || - addedVoucherCodes.length > 0, + ...voucherCodesPagination.pageInfo, + hasNextPage: isServerPagination + ? hasServerPaginationNextPage + : hasClientPaginationNextPage || serverVoucherCodes.length > 0, + hasPreviousPage: !isServerPagination + ? clientVoucherCodesPagination.pageInfo?.hasPreviousPage + : hasClientPaginationPrevPage || addedVoucherCodes.length > 0, }, loadNextPage: () => { - if (serverPagination) { + if (isServerPagination) { voucherCodesPagination.loadNextPage(); } else { if (voucherCodes.length < voucherCodesSettings.rowNumber) { - setServerPagination(true); + setIsServerPagination(true); } else { - clientPagination.loadNextPage(); + clientVoucherCodesPagination.loadNextPage(); } } }, loadPreviousPage: () => { - if (serverPagination) { - if ( - !voucherCodesPagination?.pageInfo?.hasPreviousPage && - addedVoucherCodes.length > 0 - ) { - setServerPagination(false); + if (isServerPagination) { + if (!hasServerPaginationPrevPage && addedVoucherCodes.length > 0) { + setIsServerPagination(false); } else { voucherCodesPagination.loadPreviousPage(); } } else { - clientPagination.loadPreviousPage(); + clientVoucherCodesPagination.loadPreviousPage(); } }, }, voucherCodesRefetch, voucherCodesSettings, - updateVoucherCodesListSettings, + updateVoucherCodesListSettings: (key: any, value: any) => { + updateVoucherCodesListSettings(key, value); + onSettingsChange(key, value); + }, selectedVoucherCodesIds: selectedRowIds, handleSetSelectedVoucherCodesIds, handleAddVoucherCode, From 2b60d8cb480bf47ce0dd8d7ea0b3849c189f85a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 5 Oct 2023 10:44:51 +0200 Subject: [PATCH 40/67] Fix type checks --- .../components/VoucherDetailsPage/VoucherDetailsPage.tsx | 3 +-- src/discounts/views/VoucherDetails/useVoucherCodes.ts | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 9c63aeea563..09a39855b52 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -25,7 +25,6 @@ import { DiscountErrorFragment, DiscountValueTypeEnum, PermissionEnum, - VoucherCodeFragment, VoucherDetailsFragment, VoucherTypeEnum, } from "@dashboard/graphql"; @@ -98,7 +97,7 @@ export interface VoucherDetailsPageProps allChannelsCount: number; channelListings: ChannelVoucherData[]; selectedVoucherCodesIds: string[]; - voucherCodes: VoucherCodeFragment[]; + voucherCodes: VoucherCode[]; voucherCodesLoading: boolean; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; onCategoryAssign: () => void; diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts index f7e3a838a3a..6b0997dfcc6 100644 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.ts @@ -94,10 +94,11 @@ export const useVoucherCodes = ({ id }: { id: string }) => { setSelectedRowIds, } = useRowSelection(); - const serverVoucherCodes = - mapEdgesToItems(voucherCodesData?.voucher?.codes) ?? []; + const serverVoucherCodes = (mapEdgesToItems( + voucherCodesData?.voucher?.codes, + ) ?? []) as VoucherCode[]; - let voucherCodes = []; + let voucherCodes: VoucherCode[] = []; if (isServerPagination) { voucherCodes = serverVoucherCodes; From 76716215f824c8d335117cd210e956dad87d9766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 5 Oct 2023 16:10:39 +0200 Subject: [PATCH 41/67] Finish voucher codes pagination --- .../views/VoucherDetails/useVoucherCodes.ts | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts index 6b0997dfcc6..6a7cdf120c6 100644 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.ts @@ -66,15 +66,16 @@ export const useVoucherCodes = ({ id }: { id: string }) => { loading: voucherCodesLoading, refetch: voucherCodesRefetch, } = useVoucherCodesQuery({ + skip: !isServerPagination && hasClientPaginationNextPage, variables: { id, - ...(isServerPagination && serverVoucherCodesPaginationState), first: !isServerPagination && !hasClientPaginationNextPage && freeSlotsInClientPagianationPage > 0 ? freeSlotsInClientPagianationPage - : serverVoucherCodesPaginationState.first, + : undefined, + ...(isServerPagination && serverVoucherCodesPaginationState), }, }); @@ -98,10 +99,19 @@ export const useVoucherCodes = ({ id }: { id: string }) => { voucherCodesData?.voucher?.codes, ) ?? []) as VoucherCode[]; + const freeSlotsInServerPagianationPage = + voucherCodesSettings.rowNumber - serverVoucherCodes.length; + let voucherCodes: VoucherCode[] = []; if (isServerPagination) { - voucherCodes = serverVoucherCodes; + voucherCodes = [ + ...(freeSlotsInServerPagianationPage > 0 && + !serverVoucherCodesPagination.pageInfo?.hasPreviousPage + ? addedVoucherCodes.slice(-freeSlotsInServerPagianationPage) + : []), + ...serverVoucherCodes, + ]; } else { voucherCodes = [ ...clientVoucherCodes, @@ -151,31 +161,33 @@ export const useVoucherCodes = ({ id }: { id: string }) => { ...voucherCodesPagination.pageInfo, hasNextPage: isServerPagination ? hasServerPaginationNextPage - : hasClientPaginationNextPage || serverVoucherCodes.length > 0, + : hasClientPaginationNextPage || hasServerPaginationNextPage, hasPreviousPage: !isServerPagination - ? clientVoucherCodesPagination.pageInfo?.hasPreviousPage - : hasClientPaginationPrevPage || addedVoucherCodes.length > 0, + ? hasClientPaginationPrevPage + : hasServerPaginationPrevPage || hasClientPaginationPrevPage, }, loadNextPage: () => { if (isServerPagination) { voucherCodesPagination.loadNextPage(); } else { - if (voucherCodes.length < voucherCodesSettings.rowNumber) { + if (clientVoucherCodes.length < voucherCodesSettings.rowNumber) { setIsServerPagination(true); + serverVoucherCodesPagination.loadNextPage(); } else { clientVoucherCodesPagination.loadNextPage(); } } }, loadPreviousPage: () => { - if (isServerPagination) { + if (!isServerPagination) { + clientVoucherCodesPagination.loadPreviousPage(); + } else { if (!hasServerPaginationPrevPage && addedVoucherCodes.length > 0) { + clientVoucherCodesPagination.loadPreviousPage(); setIsServerPagination(false); } else { voucherCodesPagination.loadPreviousPage(); } - } else { - clientVoucherCodesPagination.loadPreviousPage(); } }, }, From ceccd9c03cf724f591fab74e6acd76effb8330d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 5 Oct 2023 21:33:45 +0200 Subject: [PATCH 42/67] Restart local pagiation page to 0 when change row numbers --- src/hooks/useLocalPageInfo.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hooks/useLocalPageInfo.ts b/src/hooks/useLocalPageInfo.ts index 652187f713e..9c3e6db8793 100644 --- a/src/hooks/useLocalPageInfo.ts +++ b/src/hooks/useLocalPageInfo.ts @@ -17,10 +17,8 @@ function useLocalPageInfo(values: T[], paginateBy: number) { const maxPage = getMaxPage(values.length, paginateBy); useEffect(() => { - if (page > maxPage) { - setPage(maxPage); - } - }, [values.length, paginateBy]); + setPage(0); + }, [paginateBy]); const hasPreviousPage = page > 0; const hasNextPage = page < maxPage; From 514768d8e0f00795d59826f049769555486d7046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Fri, 6 Oct 2023 14:56:31 +0200 Subject: [PATCH 43/67] useVoucherCodes tests poc --- .../useVoucherCodes.test.ts.snap | 37 ++ .../VoucherDetails/useVoucherCodes.test.ts | 473 ++++++++++++++++++ .../views/VoucherDetails/useVoucherCodes.ts | 2 +- 3 files changed, 511 insertions(+), 1 deletion(-) create mode 100644 src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap create mode 100644 src/discounts/views/VoucherDetails/useVoucherCodes.test.ts diff --git a/src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap b/src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap new file mode 100644 index 00000000000..2d7bb05db27 --- /dev/null +++ b/src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`useVoucherCodes should return correct data 1`] = ` +Object { + "handleAddVoucherCode": [Function], + "handleGenerateMultipeCodes": [Function], + "handleSetSelectedVoucherCodesIds": [Function], + "selectedVoucherCodesIds": Array [], + "updateVoucherCodesListSettings": [Function], + "voucherCodes": Array [ + Object { + "code": "code 1", + "used": 0, + }, + Object { + "code": "code 2", + "used": 0, + }, + ], + "voucherCodesLoading": false, + "voucherCodesPagination": Object { + "loadNextPage": [Function], + "loadPreviousPage": [Function], + "pageInfo": Object { + "endCursor": "curson", + "hasNextPage": true, + "hasPreviousPage": false, + "startCursor": "cursor", + }, + "paginatorType": "click", + }, + "voucherCodesRefetch": [MockFunction], + "voucherCodesSettings": Object { + "rowNumber": 20, + }, +} +`; diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts new file mode 100644 index 00000000000..1447c3bd21d --- /dev/null +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts @@ -0,0 +1,473 @@ +import { useVoucherCodesQuery } from "@dashboard/graphql"; +import { act } from "@testing-library/react"; +import { renderHook } from "@testing-library/react-hooks"; + +import { useVoucherCodes } from "./useVoucherCodes"; + +jest.mock("uuid", () => ({ v4: () => "123456789" })); +jest.mock("@dashboard/graphql", () => ({ + useVoucherCodesQuery: jest.fn(() => ({ + data: { + voucher: { + codes: { + edges: [ + { + node: { + code: "code 1", + used: 0, + }, + }, + { + node: { + code: "code 2", + used: 0, + }, + }, + ], + pageInfo: { + hasNextPage: true, + hasPreviousPage: false, + endCursor: "curson", + startCursor: "cursor", + }, + }, + }, + }, + loading: false, + refetch: jest.fn(), + })), +})); + +describe("useVoucherCodes", () => { + it("should return correct data", () => { + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + + expect(result.current).toMatchSnapshot(); + }); + + it("should return manually generated voucher coded", () => { + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + + act(() => { + result.current.handleAddVoucherCode("code 3"); + result.current.handleAddVoucherCode("code 4"); + }); + + expect(result.current.voucherCodes).toEqual([ + { code: "code 3", status: "Draft" }, + { code: "code 4", status: "Draft" }, + { code: "code 1", used: 0 }, + { code: "code 2", used: 0 }, + ]); + }); + + it("should return automatictlly genereted voucher codes", () => { + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + + act(() => { + result.current.handleGenerateMultipeCodes({ + quantity: "5", + prefix: "code", + }); + }); + + expect(result.current.voucherCodes).toEqual([ + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code 1", used: 0 }, + { code: "code 2", used: 0 }, + ]); + }); + + it("should allow to paginate voucher codes comes from server", () => { + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + + act(() => { + result.current.updateVoucherCodesListSettings("rowNumber", 2); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + false, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + + expect(result.current.voucherCodes).toEqual([ + { code: "code 1", used: 0 }, + { code: "code 2", used: 0 }, + ]); + + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: [ + { + node: { + code: "code 3", + used: 0, + }, + }, + { + node: { + code: "code 4", + used: 0, + }, + }, + ], + pageInfo: { + hasNextPage: false, + hasPreviousPage: true, + endCursor: "curson", + startCursor: "cursor", + }, + }, + }, + }, + loading: false, + })); + + act(() => { + result.current.voucherCodesPagination.loadNextPage(); + }); + + expect(result.current.voucherCodes).toEqual([ + { code: "code 3", used: 0 }, + { code: "code 4", used: 0 }, + ]); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + false, + ); + + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + true, + ); + + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: [ + { + node: { + code: "code 1", + used: 0, + }, + }, + { + node: { + code: "code 2", + used: 0, + }, + }, + ], + pageInfo: { + hasNextPage: true, + hasPreviousPage: false, + endCursor: "curson", + startCursor: "cursor", + }, + }, + }, + }, + loading: false, + })); + + act(() => { + result.current.voucherCodesPagination.loadPreviousPage(); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodes).toEqual([ + { code: "code 1", used: 0 }, + { code: "code 2", used: 0 }, + ]); + }); + + it("should allow to paginate voucher codes comes from client", () => { + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: null, + loading: false, + })); + + const generatedCodes = [ + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + ]; + + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + + act(() => { + result.current.updateVoucherCodesListSettings("rowNumber", 5); + result.current.handleGenerateMultipeCodes({ + quantity: "10", + prefix: "code", + }); + result.current.handleAddVoucherCode("code 1"); + result.current.handleAddVoucherCode("code 2"); + }); + + expect(result.current.voucherCodes).toEqual(generatedCodes.slice(5)); + + act(() => { + result.current.voucherCodesPagination.loadNextPage(); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + true, + ); + expect(result.current.voucherCodes).toEqual(generatedCodes.slice(5)); + + act(() => { + result.current.voucherCodesPagination.loadNextPage(); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + undefined, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + true, + ); + expect(result.current.voucherCodes).toEqual([ + { code: "code 1", status: "Draft" }, + { code: "code 2", status: "Draft" }, + ]); + + act(() => { + result.current.voucherCodesPagination.loadPreviousPage(); + }); + act(() => { + result.current.voucherCodesPagination.loadPreviousPage(); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + false, + ); + expect(result.current.voucherCodes).toEqual(generatedCodes.slice(5)); + + act(() => { + result.current.voucherCodesPagination.loadNextPage(); + result.current.updateVoucherCodesListSettings("rowNumber", 20); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + undefined, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + false, + ); + expect(result.current.voucherCodes).toEqual([ + ...generatedCodes, + { code: "code 1", status: "Draft" }, + { code: "code 2", status: "Draft" }, + ]); + }); + + it("should allow to paginate voucher codes comes from client and server", () => { + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: [ + { + node: { + code: "code 1", + used: 0, + }, + }, + { + node: { + code: "code 2", + used: 0, + }, + }, + ], + pageInfo: { + hasNextPage: false, + hasPreviousPage: true, + endCursor: "curson", + startCursor: "cursor", + }, + }, + }, + }, + loading: false, + })); + + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + + const generatedCodes = [ + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + { code: "code-123456789", status: "Draft" }, + ]; + + act(() => { + result.current.updateVoucherCodesListSettings("rowNumber", 2); + result.current.handleGenerateMultipeCodes({ + quantity: "3", + prefix: "code", + }); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + false, + ); + expect(result.current.voucherCodes).toEqual(generatedCodes.slice(1)); + + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: [ + { + node: { + code: "code 1", + used: 0, + }, + }, + ], + pageInfo: { + hasNextPage: true, + hasPreviousPage: false, + endCursor: "cursor", + startCursor: "cursor", + }, + }, + }, + }, + loading: false, + })); + + act(() => { + result.current.voucherCodesPagination.loadNextPage(); + }); + + expect(useVoucherCodesQuery).toHaveBeenCalledWith({ + skip: false, + variables: { first: 1, id: "1" }, + }); + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + true, + ); + expect(result.current.voucherCodes).toEqual([ + ...generatedCodes.slice(2), + { code: "code 1", used: 0 }, + ]); + + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: [ + { + node: { + code: "code 2", + used: 0, + }, + }, + ], + pageInfo: { + hasNextPage: false, + hasPreviousPage: true, + endCursor: "cursor", + startCursor: "cursor", + }, + }, + }, + }, + loading: false, + })); + + act(() => { + result.current.voucherCodesPagination.loadNextPage(); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + false, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + true, + ); + expect(result.current.voucherCodes).toEqual([{ code: "code 2", used: 0 }]); + + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: [ + { + node: { + code: "code 1", + used: 0, + }, + }, + ], + pageInfo: { + hasNextPage: true, + hasPreviousPage: false, + endCursor: "cursor", + startCursor: "cursor", + }, + }, + }, + }, + loading: false, + })); + + act(() => { + result.current.voucherCodesPagination.loadPreviousPage(); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + true, + ); + + expect(result.current.voucherCodes).toEqual([ + ...generatedCodes.slice(2), + { code: "code 1", used: 0 }, + ]); + + act(() => { + result.current.voucherCodesPagination.loadPreviousPage(); + }); + + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + false, + ); + expect(result.current.voucherCodes).toEqual(generatedCodes.slice(1)); + }); +}); diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts index 6a7cdf120c6..f4671ee70c4 100644 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.ts @@ -24,7 +24,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { const [isServerPagination, setIsServerPagination] = useState(true); const handleAddVoucherCode = (code: string) => [ - setAddedVoucherCodes(codes => [...codes, { code }]), + setAddedVoucherCodes(codes => [...codes, { code, status: "Draft" }]), ]; const handleGenerateMultipeCodes = ({ From 5ce41322a5701048930f7416e956546b1b1cbf58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Fri, 6 Oct 2023 15:45:52 +0200 Subject: [PATCH 44/67] Tests refactor --- .../useVoucherCodes.test.ts.snap | 37 --- .../VoucherDetails/useVoucherCodes.test.ts | 230 +++++++----------- 2 files changed, 88 insertions(+), 179 deletions(-) delete mode 100644 src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap diff --git a/src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap b/src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap deleted file mode 100644 index 2d7bb05db27..00000000000 --- a/src/discounts/views/VoucherDetails/__snapshots__/useVoucherCodes.test.ts.snap +++ /dev/null @@ -1,37 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`useVoucherCodes should return correct data 1`] = ` -Object { - "handleAddVoucherCode": [Function], - "handleGenerateMultipeCodes": [Function], - "handleSetSelectedVoucherCodesIds": [Function], - "selectedVoucherCodesIds": Array [], - "updateVoucherCodesListSettings": [Function], - "voucherCodes": Array [ - Object { - "code": "code 1", - "used": 0, - }, - Object { - "code": "code 2", - "used": 0, - }, - ], - "voucherCodesLoading": false, - "voucherCodesPagination": Object { - "loadNextPage": [Function], - "loadPreviousPage": [Function], - "pageInfo": Object { - "endCursor": "curson", - "hasNextPage": true, - "hasPreviousPage": false, - "startCursor": "cursor", - }, - "paginatorType": "click", - }, - "voucherCodesRefetch": [MockFunction], - "voucherCodesSettings": Object { - "rowNumber": 20, - }, -} -`; diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts index 1447c3bd21d..ac9017f66e3 100644 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts +++ b/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts @@ -4,55 +4,49 @@ import { renderHook } from "@testing-library/react-hooks"; import { useVoucherCodes } from "./useVoucherCodes"; +const apiVoucherCodes = Array.from({ length: 10 }, (_, i) => ({ + node: { + code: `code ${i + 1}`, + used: 0, + }, +})); + +const autoGeneratedVoucherCodes = Array.from({ length: 5 }, () => ({ + code: "code-123456789", + status: "Draft", +})); + jest.mock("uuid", () => ({ v4: () => "123456789" })); jest.mock("@dashboard/graphql", () => ({ useVoucherCodesQuery: jest.fn(() => ({ data: { voucher: { codes: { - edges: [ - { - node: { - code: "code 1", - used: 0, - }, - }, - { - node: { - code: "code 2", - used: 0, - }, - }, - ], + edges: apiVoucherCodes.slice(0, 2), pageInfo: { hasNextPage: true, hasPreviousPage: false, - endCursor: "curson", - startCursor: "cursor", }, }, }, }, - loading: false, + refetch: jest.fn(), })), })); describe("useVoucherCodes", () => { - it("should return correct data", () => { - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); - - expect(result.current).toMatchSnapshot(); - }); - it("should return manually generated voucher coded", () => { + // Arrange const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + // Act act(() => { result.current.handleAddVoucherCode("code 3"); result.current.handleAddVoucherCode("code 4"); }); + // Assert expect(result.current.voucherCodes).toEqual([ { code: "code 3", status: "Draft" }, { code: "code 4", status: "Draft" }, @@ -62,8 +56,10 @@ describe("useVoucherCodes", () => { }); it("should return automatictlly genereted voucher codes", () => { + // Arrange const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + // Act act(() => { result.current.handleGenerateMultipeCodes({ quantity: "5", @@ -71,24 +67,38 @@ describe("useVoucherCodes", () => { }); }); + // Assert expect(result.current.voucherCodes).toEqual([ - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, + ...autoGeneratedVoucherCodes, { code: "code 1", used: 0 }, { code: "code 2", used: 0 }, ]); }); it("should allow to paginate voucher codes comes from server", () => { + // Arrange + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: apiVoucherCodes.slice(0, 2), + pageInfo: { + hasNextPage: true, + hasPreviousPage: false, + }, + }, + }, + }, + })); + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + // Act act(() => { result.current.updateVoucherCodesListSettings("rowNumber", 2); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( false, ); @@ -101,87 +111,59 @@ describe("useVoucherCodes", () => { { code: "code 2", used: 0 }, ]); + // Arrange (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ data: { voucher: { codes: { - edges: [ - { - node: { - code: "code 3", - used: 0, - }, - }, - { - node: { - code: "code 4", - used: 0, - }, - }, - ], + edges: apiVoucherCodes.slice(2, 4), pageInfo: { hasNextPage: false, hasPreviousPage: true, - endCursor: "curson", - startCursor: "cursor", }, }, }, }, - loading: false, })); + // Act act(() => { result.current.voucherCodesPagination.loadNextPage(); }); + // Assert expect(result.current.voucherCodes).toEqual([ { code: "code 3", used: 0 }, { code: "code 4", used: 0 }, ]); - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( false, ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( true, ); + // Arrange (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ data: { voucher: { codes: { - edges: [ - { - node: { - code: "code 1", - used: 0, - }, - }, - { - node: { - code: "code 2", - used: 0, - }, - }, - ], + edges: apiVoucherCodes.slice(0, 2), pageInfo: { hasNextPage: true, hasPreviousPage: false, - endCursor: "curson", - startCursor: "cursor", }, }, }, }, - loading: false, })); + // Act act(() => { result.current.voucherCodesPagination.loadPreviousPage(); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( true, ); @@ -192,26 +174,14 @@ describe("useVoucherCodes", () => { }); it("should allow to paginate voucher codes comes from client", () => { + // Arrange (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ data: null, - loading: false, })); - const generatedCodes = [ - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - ]; - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + // Act act(() => { result.current.updateVoucherCodesListSettings("rowNumber", 5); result.current.handleGenerateMultipeCodes({ @@ -222,24 +192,29 @@ describe("useVoucherCodes", () => { result.current.handleAddVoucherCode("code 2"); }); - expect(result.current.voucherCodes).toEqual(generatedCodes.slice(5)); + // Assert + expect(result.current.voucherCodes).toEqual(autoGeneratedVoucherCodes); + // Act act(() => { result.current.voucherCodesPagination.loadNextPage(); }); + // Asssert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( true, ); expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( true, ); - expect(result.current.voucherCodes).toEqual(generatedCodes.slice(5)); + expect(result.current.voucherCodes).toEqual(autoGeneratedVoucherCodes); + // Act act(() => { result.current.voucherCodesPagination.loadNextPage(); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( undefined, ); @@ -251,6 +226,7 @@ describe("useVoucherCodes", () => { { code: "code 2", status: "Draft" }, ]); + // Act act(() => { result.current.voucherCodesPagination.loadPreviousPage(); }); @@ -258,19 +234,22 @@ describe("useVoucherCodes", () => { result.current.voucherCodesPagination.loadPreviousPage(); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( true, ); expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( false, ); - expect(result.current.voucherCodes).toEqual(generatedCodes.slice(5)); + expect(result.current.voucherCodes).toEqual(autoGeneratedVoucherCodes); + // Act act(() => { result.current.voucherCodesPagination.loadNextPage(); result.current.updateVoucherCodesListSettings("rowNumber", 20); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( undefined, ); @@ -278,51 +257,32 @@ describe("useVoucherCodes", () => { false, ); expect(result.current.voucherCodes).toEqual([ - ...generatedCodes, + ...autoGeneratedVoucherCodes, + ...autoGeneratedVoucherCodes, { code: "code 1", status: "Draft" }, { code: "code 2", status: "Draft" }, ]); }); it("should allow to paginate voucher codes comes from client and server", () => { + // Arrange (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ data: { voucher: { codes: { - edges: [ - { - node: { - code: "code 1", - used: 0, - }, - }, - { - node: { - code: "code 2", - used: 0, - }, - }, - ], + edges: apiVoucherCodes.slice(0, 2), pageInfo: { hasNextPage: false, hasPreviousPage: true, - endCursor: "curson", - startCursor: "cursor", }, }, }, }, - loading: false, })); const { result } = renderHook(() => useVoucherCodes({ id: "1" })); - const generatedCodes = [ - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - { code: "code-123456789", status: "Draft" }, - ]; - + // Act act(() => { result.current.updateVoucherCodesListSettings("rowNumber", 2); result.current.handleGenerateMultipeCodes({ @@ -331,42 +291,38 @@ describe("useVoucherCodes", () => { }); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( true, ); expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( false, ); - expect(result.current.voucherCodes).toEqual(generatedCodes.slice(1)); + expect(result.current.voucherCodes).toEqual( + autoGeneratedVoucherCodes.slice(3), + ); + // Arrange (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ data: { voucher: { codes: { - edges: [ - { - node: { - code: "code 1", - used: 0, - }, - }, - ], + edges: [apiVoucherCodes[0]], pageInfo: { hasNextPage: true, hasPreviousPage: false, - endCursor: "cursor", - startCursor: "cursor", }, }, }, }, - loading: false, })); + // Act act(() => { result.current.voucherCodesPagination.loadNextPage(); }); + // Assert expect(useVoucherCodesQuery).toHaveBeenCalledWith({ skip: false, variables: { first: 1, id: "1" }, @@ -378,38 +334,31 @@ describe("useVoucherCodes", () => { true, ); expect(result.current.voucherCodes).toEqual([ - ...generatedCodes.slice(2), + ...autoGeneratedVoucherCodes.slice(0, 1), { code: "code 1", used: 0 }, ]); + // Arrange (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ data: { voucher: { codes: { - edges: [ - { - node: { - code: "code 2", - used: 0, - }, - }, - ], + edges: [apiVoucherCodes[1]], pageInfo: { hasNextPage: false, hasPreviousPage: true, - endCursor: "cursor", - startCursor: "cursor", }, }, }, }, - loading: false, })); + // Act act(() => { result.current.voucherCodesPagination.loadNextPage(); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( false, ); @@ -418,34 +367,27 @@ describe("useVoucherCodes", () => { ); expect(result.current.voucherCodes).toEqual([{ code: "code 2", used: 0 }]); + // Arrange (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ data: { voucher: { codes: { - edges: [ - { - node: { - code: "code 1", - used: 0, - }, - }, - ], + edges: [apiVoucherCodes[0]], pageInfo: { hasNextPage: true, hasPreviousPage: false, - endCursor: "cursor", - startCursor: "cursor", }, }, }, }, - loading: false, })); + // Act act(() => { result.current.voucherCodesPagination.loadPreviousPage(); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( true, ); @@ -454,20 +396,24 @@ describe("useVoucherCodes", () => { ); expect(result.current.voucherCodes).toEqual([ - ...generatedCodes.slice(2), + ...autoGeneratedVoucherCodes.slice(0, 1), { code: "code 1", used: 0 }, ]); + // Act act(() => { result.current.voucherCodesPagination.loadPreviousPage(); }); + // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( true, ); expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( false, ); - expect(result.current.voucherCodes).toEqual(generatedCodes.slice(1)); + expect(result.current.voucherCodes).toEqual( + autoGeneratedVoucherCodes.slice(0, 2), + ); }); }); From a0131d9c1d36a6d9dd2151c843ece531796433e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 09:22:33 +0200 Subject: [PATCH 45/67] useVoucherCodes refactor --- .../views/VoucherDetails/VoucherDetails.tsx | 2 +- .../{ => hooks}/useVoucherCodes.test.ts | 0 .../VoucherDetails/hooks/useVoucherCodes.ts | 129 +++++++++++ .../hooks/useVoucherCodesClient.ts | 54 +++++ .../hooks/useVoucherCodesRowSelection.ts | 50 +++++ .../hooks/useVoucherCodesServer.tsx | 84 +++++++ .../views/VoucherDetails/useVoucherCodes.ts | 205 ------------------ src/discounts/views/VoucherDetails/utils.ts | 37 ++++ 8 files changed, 355 insertions(+), 206 deletions(-) rename src/discounts/views/VoucherDetails/{ => hooks}/useVoucherCodes.test.ts (100%) create mode 100644 src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts create mode 100644 src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts create mode 100644 src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts create mode 100644 src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx delete mode 100644 src/discounts/views/VoucherDetails/useVoucherCodes.ts create mode 100644 src/discounts/views/VoucherDetails/utils.ts diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 98b8ef84e43..09185e42a20 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -60,8 +60,8 @@ import { FormattedMessage, useIntl } from "react-intl"; import { maybe } from "../../../misc"; import { createUpdateHandler } from "./handlers"; +import { useVoucherCodes } from "./hooks/useVoucherCodes"; import { VOUCHER_UPDATE_FORM_ID } from "./types"; -import { useVoucherCodes } from "./useVoucherCodes"; interface VoucherDetailsProps { id: string; diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.test.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts similarity index 100% rename from src/discounts/views/VoucherDetails/useVoucherCodes.test.ts rename to src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts new file mode 100644 index 00000000000..0308a019769 --- /dev/null +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts @@ -0,0 +1,129 @@ +import useListSettings from "@dashboard/hooks/useListSettings"; +import { ListViews } from "@dashboard/types"; +import { useState } from "react"; + +import { getVoucherCodesToDisplay } from "../utils"; +import { useVoucherCodesClient } from "./useVoucherCodesClient"; +import { useVoucherCodesRowSelection } from "./useVoucherCodesRowSelection"; +import { useVoucherCodesServer } from "./useVoucherCodesServer"; + +export const useVoucherCodes = ({ id }: { id: string }) => { + const { + settings: voucherCodesSettings, + updateListSettings: updateVoucherCodesListSettings, + } = useListSettings(ListViews.VOUCHER_CODES); + + const [isServerPagination, setIsServerPagination] = useState(true); + + const { + addedVoucherCodes, + clientVoucherCodes, + clientVoucherCodesPagination, + freeSlotsInClientPagianationPage, + handleAddVoucherCode, + handleGenerateMultipeCodes, + hasClientPaginationNextPage, + hasClientPaginationPrevPage, + onSettingsChange, + } = useVoucherCodesClient(voucherCodesSettings, () => { + setIsServerPagination(false); + }); + + const { + freeSlotsInServerPagianationPage, + hasServerPaginationNextPage, + hasServerPaginationPrevPage, + serverVoucherCodesPagination, + serverVoucherCodes, + voucherCodesLoading, + voucherCodesRefetch, + } = useVoucherCodesServer({ + id, + skipFetch: !isServerPagination && hasClientPaginationNextPage, + settings: voucherCodesSettings, + isServerPagination, + paginationState: { + first: + !isServerPagination && + !hasClientPaginationNextPage && + freeSlotsInClientPagianationPage > 0 + ? freeSlotsInClientPagianationPage + : undefined, + }, + }); + + const voucherCodes = getVoucherCodesToDisplay({ + addedVoucherCodes, + clientVoucherCodes, + freeSlotsInClientPagianationPage, + hasClientPaginationNextPage, + freeSlotsInServerPagianationPage, + hasServerPaginationPrevPage, + isServerPagination, + serverVoucherCodes, + }); + + const voucherCodesPagination = isServerPagination + ? serverVoucherCodesPagination + : clientVoucherCodesPagination; + + const { selectedVoucherCodesIds, handleSetSelectedVoucherCodesIds } = + useVoucherCodesRowSelection(voucherCodes); + + const handleLoadNextPage = () => { + if (isServerPagination) { + voucherCodesPagination.loadNextPage(); + } else { + // Switch to server pagination + if (clientVoucherCodes.length < voucherCodesSettings.rowNumber) { + setIsServerPagination(true); + serverVoucherCodesPagination.loadNextPage(); + } else { + clientVoucherCodesPagination.loadNextPage(); + } + } + }; + + const handleLoadPrevousPage = () => { + if (!isServerPagination) { + clientVoucherCodesPagination.loadPreviousPage(); + } else { + // Switch to client pagination + if (!hasServerPaginationPrevPage && addedVoucherCodes.length > 0) { + clientVoucherCodesPagination.loadPreviousPage(); + setIsServerPagination(false); + } else { + voucherCodesPagination.loadPreviousPage(); + } + } + }; + + return { + voucherCodes, + voucherCodesLoading, + voucherCodesPagination: { + ...voucherCodesPagination, + pageInfo: { + ...voucherCodesPagination.pageInfo, + hasNextPage: isServerPagination + ? hasServerPaginationNextPage + : hasClientPaginationNextPage || hasServerPaginationNextPage, + hasPreviousPage: !isServerPagination + ? hasClientPaginationPrevPage + : hasServerPaginationPrevPage || hasClientPaginationPrevPage, + }, + loadNextPage: handleLoadNextPage, + loadPreviousPage: handleLoadPrevousPage, + }, + voucherCodesRefetch, + voucherCodesSettings, + updateVoucherCodesListSettings: (key: any, value: any) => { + updateVoucherCodesListSettings(key, value); + onSettingsChange(key, value); + }, + selectedVoucherCodesIds, + handleSetSelectedVoucherCodesIds, + handleAddVoucherCode, + handleGenerateMultipeCodes, + }; +}; diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts new file mode 100644 index 00000000000..3647a7f30be --- /dev/null +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts @@ -0,0 +1,54 @@ +import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagrid/types"; +import { GenerateMultipleVoucherCodeFormData } from "@dashboard/discounts/components/VoucherCodesGenerateDialog"; +import { useVoucherCodesPagination } from "@dashboard/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination"; +import { generateMultipleIds } from "@dashboard/discounts/components/VoucherCreatePage/utils"; +import { ListSettings } from "@dashboard/types"; +import { useState } from "react"; + +export const useVoucherCodesClient = ( + settings: ListSettings, + resetPagination: () => void, +) => { + const [addedVoucherCodes, setAddedVoucherCodes] = useState([]); + + const { + paginatedCodes: clientVoucherCodes, + pagination: clientVoucherCodesPagination, + onSettingsChange, + } = useVoucherCodesPagination(addedVoucherCodes); + + const hasClientPaginationNextPage = + clientVoucherCodesPagination?.pageInfo?.hasNextPage; + const hasClientPaginationPrevPage = + clientVoucherCodesPagination.pageInfo?.hasPreviousPage; + + const freeSlotsInClientPagianationPage = + settings.rowNumber - clientVoucherCodes.length; + + const handleAddVoucherCode = (code: string) => [ + setAddedVoucherCodes(codes => [...codes, { code, status: "Draft" }]), + ]; + + const handleGenerateMultipeCodes = ({ + quantity, + prefix, + }: GenerateMultipleVoucherCodeFormData) => { + setAddedVoucherCodes(codes => [ + ...codes, + ...generateMultipleIds(quantity, prefix), + ]); + resetPagination(); + }; + + return { + addedVoucherCodes, + clientVoucherCodes, + clientVoucherCodesPagination, + onSettingsChange, + hasClientPaginationNextPage, + hasClientPaginationPrevPage, + freeSlotsInClientPagianationPage, + handleAddVoucherCode, + handleGenerateMultipeCodes, + }; +}; diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts new file mode 100644 index 00000000000..18a886b5b31 --- /dev/null +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts @@ -0,0 +1,50 @@ +import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagrid/types"; +import { useRowSelection } from "@dashboard/hooks/useRowSelection"; +import isEqual from "lodash/isEqual"; +import { useCallback } from "react"; + +interface VoucherCodesRowSelection { + selectedVoucherCodesIds: string[]; + handleSetSelectedVoucherCodesIds: ( + rows: number[], + clearSelection: () => void, + ) => void; +} + +export const useVoucherCodesRowSelection = ( + voucherCodes: VoucherCode[], +): VoucherCodesRowSelection => { + const { + selectedRowIds, + setClearDatagridRowSelectionCallback, + setSelectedRowIds, + } = useRowSelection(); + + const handleSetSelectedVoucherCodesIds = useCallback( + (rows: number[], clearSelection: () => void) => { + if (!voucherCodes) { + return; + } + + const rowsIds = rows.map(row => voucherCodes[row].code).filter(Boolean); + const haveSaveValues = isEqual(rowsIds, selectedRowIds); + + if (!haveSaveValues) { + setSelectedRowIds(rowsIds as string[]); + } + + setClearDatagridRowSelectionCallback(clearSelection); + }, + [ + voucherCodes, + selectedRowIds, + setClearDatagridRowSelectionCallback, + setSelectedRowIds, + ], + ); + + return { + selectedVoucherCodesIds: selectedRowIds, + handleSetSelectedVoucherCodesIds, + }; +}; diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx new file mode 100644 index 00000000000..b6e4cec62e3 --- /dev/null +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx @@ -0,0 +1,84 @@ +import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagrid/types"; +import { useVoucherCodesQuery } from "@dashboard/graphql"; +import useLocalPaginator, { + LocalPagination, + PaginationState, + useLocalPaginationState, +} from "@dashboard/hooks/useLocalPaginator"; +import { ListSettings } from "@dashboard/types"; +import { mapEdgesToItems } from "@dashboard/utils/maps"; + +interface UseVoucherCodesServerProps { + settings: ListSettings; + id: string; + skipFetch?: boolean; + isServerPagination?: boolean; + paginationState?: PaginationState; +} + +interface VoucherCodesServer { + voucherCodesLoading: boolean; + voucherCodesRefetch: () => void; + serverVoucherCodesPagination: LocalPagination; + hasServerPaginationNextPage: boolean; + hasServerPaginationPrevPage: boolean; + freeSlotsInServerPagianationPage: number; + serverVoucherCodes: VoucherCode[]; +} + +export const useVoucherCodesServer = ({ + settings, + skipFetch, + id, + isServerPagination, + paginationState = {}, +}: UseVoucherCodesServerProps): VoucherCodesServer => { + const [ + serverVoucherCodesPaginationState, + setServerVoucherCodesPaginationState, + ] = useLocalPaginationState(settings.rowNumber); + + const serverVoucherCodesPaginate = useLocalPaginator( + setServerVoucherCodesPaginationState, + ); + + const { + data: voucherCodesData, + loading: voucherCodesLoading, + refetch: voucherCodesRefetch, + } = useVoucherCodesQuery({ + skip: skipFetch, + variables: { + id, + ...paginationState, + ...(isServerPagination && serverVoucherCodesPaginationState), + }, + }); + + const serverVoucherCodesPagination = serverVoucherCodesPaginate( + voucherCodesData?.voucher?.codes?.pageInfo, + serverVoucherCodesPaginationState, + ); + + const hasServerPaginationNextPage = + serverVoucherCodesPagination?.pageInfo?.hasNextPage; + const hasServerPaginationPrevPage = + serverVoucherCodesPagination?.pageInfo?.hasPreviousPage; + + const serverVoucherCodes = (mapEdgesToItems( + voucherCodesData?.voucher?.codes, + ) ?? []) as VoucherCode[]; + + const freeSlotsInServerPagianationPage = + settings.rowNumber - serverVoucherCodes.length; + + return { + voucherCodesLoading, + voucherCodesRefetch, + serverVoucherCodes, + serverVoucherCodesPagination, + hasServerPaginationNextPage, + hasServerPaginationPrevPage, + freeSlotsInServerPagianationPage, + }; +}; diff --git a/src/discounts/views/VoucherDetails/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/useVoucherCodes.ts deleted file mode 100644 index f4671ee70c4..00000000000 --- a/src/discounts/views/VoucherDetails/useVoucherCodes.ts +++ /dev/null @@ -1,205 +0,0 @@ -import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagrid/types"; -import { GenerateMultipleVoucherCodeFormData } from "@dashboard/discounts/components/VoucherCodesGenerateDialog"; -import { useVoucherCodesPagination } from "@dashboard/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination"; -import { generateMultipleIds } from "@dashboard/discounts/components/VoucherCreatePage/utils"; -import { useVoucherCodesQuery } from "@dashboard/graphql"; -import useListSettings from "@dashboard/hooks/useListSettings"; -import useLocalPaginator, { - LocalPagination, - useLocalPaginationState, -} from "@dashboard/hooks/useLocalPaginator"; -import { useRowSelection } from "@dashboard/hooks/useRowSelection"; -import { ListViews } from "@dashboard/types"; -import { mapEdgesToItems } from "@dashboard/utils/maps"; -import isEqual from "lodash/isEqual"; -import { useCallback, useState } from "react"; - -export const useVoucherCodes = ({ id }: { id: string }) => { - const { - settings: voucherCodesSettings, - updateListSettings: updateVoucherCodesListSettings, - } = useListSettings(ListViews.VOUCHER_CODES); - - const [addedVoucherCodes, setAddedVoucherCodes] = useState([]); - const [isServerPagination, setIsServerPagination] = useState(true); - - const handleAddVoucherCode = (code: string) => [ - setAddedVoucherCodes(codes => [...codes, { code, status: "Draft" }]), - ]; - - const handleGenerateMultipeCodes = ({ - quantity, - prefix, - }: GenerateMultipleVoucherCodeFormData) => { - setAddedVoucherCodes(codes => [ - ...codes, - ...generateMultipleIds(quantity, prefix), - ]); - setIsServerPagination(false); - }; - - const [ - serverVoucherCodesPaginationState, - setServerVoucherCodesPaginationState, - ] = useLocalPaginationState(voucherCodesSettings.rowNumber); - - const serverVoucherCodesPaginate = useLocalPaginator( - setServerVoucherCodesPaginationState, - ); - - const { - paginatedCodes: clientVoucherCodes, - pagination: clientVoucherCodesPagination, - onSettingsChange, - } = useVoucherCodesPagination(addedVoucherCodes); - - const hasClientPaginationNextPage = - clientVoucherCodesPagination?.pageInfo?.hasNextPage; - const hasClientPaginationPrevPage = - clientVoucherCodesPagination.pageInfo?.hasPreviousPage; - - const freeSlotsInClientPagianationPage = - voucherCodesSettings.rowNumber - clientVoucherCodes.length; - - const { - data: voucherCodesData, - loading: voucherCodesLoading, - refetch: voucherCodesRefetch, - } = useVoucherCodesQuery({ - skip: !isServerPagination && hasClientPaginationNextPage, - variables: { - id, - first: - !isServerPagination && - !hasClientPaginationNextPage && - freeSlotsInClientPagianationPage > 0 - ? freeSlotsInClientPagianationPage - : undefined, - ...(isServerPagination && serverVoucherCodesPaginationState), - }, - }); - - const serverVoucherCodesPagination = serverVoucherCodesPaginate( - voucherCodesData?.voucher?.codes?.pageInfo, - serverVoucherCodesPaginationState, - ); - - const hasServerPaginationNextPage = - serverVoucherCodesPagination?.pageInfo?.hasNextPage; - const hasServerPaginationPrevPage = - serverVoucherCodesPagination?.pageInfo?.hasPreviousPage; - - const { - selectedRowIds, - setClearDatagridRowSelectionCallback, - setSelectedRowIds, - } = useRowSelection(); - - const serverVoucherCodes = (mapEdgesToItems( - voucherCodesData?.voucher?.codes, - ) ?? []) as VoucherCode[]; - - const freeSlotsInServerPagianationPage = - voucherCodesSettings.rowNumber - serverVoucherCodes.length; - - let voucherCodes: VoucherCode[] = []; - - if (isServerPagination) { - voucherCodes = [ - ...(freeSlotsInServerPagianationPage > 0 && - !serverVoucherCodesPagination.pageInfo?.hasPreviousPage - ? addedVoucherCodes.slice(-freeSlotsInServerPagianationPage) - : []), - ...serverVoucherCodes, - ]; - } else { - voucherCodes = [ - ...clientVoucherCodes, - ...(!hasClientPaginationNextPage && freeSlotsInClientPagianationPage > 0 - ? [...serverVoucherCodes] - : []), - ]; - } - - let voucherCodesPagination: LocalPagination; - - if (!isServerPagination) { - voucherCodesPagination = clientVoucherCodesPagination; - } else { - voucherCodesPagination = serverVoucherCodesPagination; - } - - const handleSetSelectedVoucherCodesIds = useCallback( - (rows: number[], clearSelection: () => void) => { - if (!voucherCodes) { - return; - } - - const rowsIds = rows.map(row => voucherCodes[row].code).filter(Boolean); - const haveSaveValues = isEqual(rowsIds, selectedRowIds); - - if (!haveSaveValues) { - setSelectedRowIds(rowsIds as string[]); - } - - setClearDatagridRowSelectionCallback(clearSelection); - }, - [ - voucherCodes, - selectedRowIds, - setClearDatagridRowSelectionCallback, - setSelectedRowIds, - ], - ); - - return { - voucherCodes, - voucherCodesLoading, - voucherCodesPagination: { - ...voucherCodesPagination, - pageInfo: { - ...voucherCodesPagination.pageInfo, - hasNextPage: isServerPagination - ? hasServerPaginationNextPage - : hasClientPaginationNextPage || hasServerPaginationNextPage, - hasPreviousPage: !isServerPagination - ? hasClientPaginationPrevPage - : hasServerPaginationPrevPage || hasClientPaginationPrevPage, - }, - loadNextPage: () => { - if (isServerPagination) { - voucherCodesPagination.loadNextPage(); - } else { - if (clientVoucherCodes.length < voucherCodesSettings.rowNumber) { - setIsServerPagination(true); - serverVoucherCodesPagination.loadNextPage(); - } else { - clientVoucherCodesPagination.loadNextPage(); - } - } - }, - loadPreviousPage: () => { - if (!isServerPagination) { - clientVoucherCodesPagination.loadPreviousPage(); - } else { - if (!hasServerPaginationPrevPage && addedVoucherCodes.length > 0) { - clientVoucherCodesPagination.loadPreviousPage(); - setIsServerPagination(false); - } else { - voucherCodesPagination.loadPreviousPage(); - } - } - }, - }, - voucherCodesRefetch, - voucherCodesSettings, - updateVoucherCodesListSettings: (key: any, value: any) => { - updateVoucherCodesListSettings(key, value); - onSettingsChange(key, value); - }, - selectedVoucherCodesIds: selectedRowIds, - handleSetSelectedVoucherCodesIds, - handleAddVoucherCode, - handleGenerateMultipeCodes, - }; -}; diff --git a/src/discounts/views/VoucherDetails/utils.ts b/src/discounts/views/VoucherDetails/utils.ts new file mode 100644 index 00000000000..f3d64e38a94 --- /dev/null +++ b/src/discounts/views/VoucherDetails/utils.ts @@ -0,0 +1,37 @@ +import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagrid/types"; + +export const getVoucherCodesToDisplay = ({ + clientVoucherCodes, + serverVoucherCodes, + isServerPagination, + freeSlotsInServerPagianationPage, + hasServerPaginationPrevPage, + addedVoucherCodes, + hasClientPaginationNextPage, + freeSlotsInClientPagianationPage, +}: { + isServerPagination: boolean; + clientVoucherCodes: VoucherCode[]; + serverVoucherCodes: VoucherCode[]; + freeSlotsInServerPagianationPage: number; + hasServerPaginationPrevPage: boolean; + addedVoucherCodes: VoucherCode[]; + hasClientPaginationNextPage: boolean; + freeSlotsInClientPagianationPage: number; +}) => { + if (isServerPagination) { + return [ + ...(freeSlotsInServerPagianationPage > 0 && !hasServerPaginationPrevPage + ? addedVoucherCodes.slice(-freeSlotsInServerPagianationPage) + : []), + ...serverVoucherCodes, + ]; + } + + return [ + ...clientVoucherCodes, + ...(!hasClientPaginationNextPage && freeSlotsInClientPagianationPage > 0 + ? [...serverVoucherCodes] + : []), + ]; +}; From 0d03d0222112e61588ba0cf88286b4d00c18160d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 12:03:56 +0200 Subject: [PATCH 46/67] New generated codes always at top --- .../hooks/useVoucherCodes.test.ts | 25 ++++++++++++------- .../hooks/useVoucherCodesClient.ts | 4 +-- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts index ac9017f66e3..484d1fdee63 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts @@ -48,8 +48,8 @@ describe("useVoucherCodes", () => { // Assert expect(result.current.voucherCodes).toEqual([ - { code: "code 3", status: "Draft" }, { code: "code 4", status: "Draft" }, + { code: "code 3", status: "Draft" }, { code: "code 1", used: 0 }, { code: "code 2", used: 0 }, ]); @@ -193,7 +193,11 @@ describe("useVoucherCodes", () => { }); // Assert - expect(result.current.voucherCodes).toEqual(autoGeneratedVoucherCodes); + expect(result.current.voucherCodes).toEqual([ + { code: "code 2", status: "Draft" }, + { code: "code 1", status: "Draft" }, + ...autoGeneratedVoucherCodes.slice(2), + ]); // Act act(() => { @@ -221,10 +225,9 @@ describe("useVoucherCodes", () => { expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( true, ); - expect(result.current.voucherCodes).toEqual([ - { code: "code 1", status: "Draft" }, - { code: "code 2", status: "Draft" }, - ]); + expect(result.current.voucherCodes).toEqual( + autoGeneratedVoucherCodes.slice(0, 2), + ); // Act act(() => { @@ -241,7 +244,11 @@ describe("useVoucherCodes", () => { expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( false, ); - expect(result.current.voucherCodes).toEqual(autoGeneratedVoucherCodes); + expect(result.current.voucherCodes).toEqual([ + { code: "code 2", status: "Draft" }, + { code: "code 1", status: "Draft" }, + ...autoGeneratedVoucherCodes.slice(2), + ]); // Act act(() => { @@ -257,10 +264,10 @@ describe("useVoucherCodes", () => { false, ); expect(result.current.voucherCodes).toEqual([ + { code: "code 2", status: "Draft" }, + { code: "code 1", status: "Draft" }, ...autoGeneratedVoucherCodes, ...autoGeneratedVoucherCodes, - { code: "code 1", status: "Draft" }, - { code: "code 2", status: "Draft" }, ]); }); diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts index 3647a7f30be..e63dad81d85 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts @@ -26,7 +26,7 @@ export const useVoucherCodesClient = ( settings.rowNumber - clientVoucherCodes.length; const handleAddVoucherCode = (code: string) => [ - setAddedVoucherCodes(codes => [...codes, { code, status: "Draft" }]), + setAddedVoucherCodes(codes => [{ code, status: "Draft" }, ...codes]), ]; const handleGenerateMultipeCodes = ({ @@ -34,8 +34,8 @@ export const useVoucherCodesClient = ( prefix, }: GenerateMultipleVoucherCodeFormData) => { setAddedVoucherCodes(codes => [ - ...codes, ...generateMultipleIds(quantity, prefix), + ...codes, ]); resetPagination(); }; From e76a289d53bc275d04a2a9ed427d27945f3fadde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 12:05:37 +0200 Subject: [PATCH 47/67] Update schema --- fetch-schema.yml | 2 +- introspection.json | 6572 +++++++++++++++-- schema.graphql | 1754 ++++- src/discounts/views/VoucherCreate/handlers.ts | 2 +- src/graphql/fragmentTypes.generated.ts | 49 + src/graphql/typePolicies.generated.ts | 484 +- src/graphql/types.generated.ts | 350 +- 7 files changed, 8488 insertions(+), 725 deletions(-) diff --git a/fetch-schema.yml b/fetch-schema.yml index 00228d15603..ce4af5f8755 100644 --- a/fetch-schema.yml +++ b/fetch-schema.yml @@ -1,4 +1,4 @@ -schema: ${API_URI} +schema: https://multiple-codes-for-voucher-feature.api.saleor.rocks/graphql/ generates: ./introspection.json: plugins: diff --git a/introspection.json b/introspection.json index 11b5ff3312c..24f71604c8f 100644 --- a/introspection.json +++ b/introspection.json @@ -9938,7 +9938,7 @@ { "kind": "OBJECT", "name": "AttributeTranslatableContent", - "description": null, + "description": "Represents attribute's original translatable fields and related translations.", "fields": [ { "name": "attribute", @@ -10134,7 +10134,7 @@ { "kind": "OBJECT", "name": "AttributeTranslation", - "description": null, + "description": "Represents attribute translations.", "fields": [ { "name": "id", @@ -11963,7 +11963,7 @@ { "kind": "OBJECT", "name": "AttributeValueTranslatableContent", - "description": null, + "description": "Represents attribute value's original translatable fields and related translations.", "fields": [ { "name": "attribute", @@ -12195,7 +12195,7 @@ { "kind": "OBJECT", "name": "AttributeValueTranslation", - "description": null, + "description": "Represents attribute value translations.", "fields": [ { "name": "id", @@ -13516,6 +13516,105 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "CataloguePredicateInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "AND", + "description": "List of conditions that must be met.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CataloguePredicateInput", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OR", + "description": "A list of conditions of which at least one must be met.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CataloguePredicateInput", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "categoryPredicate", + "description": "Defines the category conditions to be met.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CategoryWhereInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "collectionPredicate", + "description": "Defines the collection conditions to be met.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CollectionWhereInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productPredicate", + "description": "Defines the product conditions to be met.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProductWhereInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "variantPredicate", + "description": "Defines the product variant conditions to be met.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProductVariantWhereInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "Category", @@ -14929,7 +15028,7 @@ { "kind": "OBJECT", "name": "CategoryTranslatableContent", - "description": null, + "description": "Represents category original translatable fields and related translations.", "fields": [ { "name": "category", @@ -15138,7 +15237,7 @@ { "kind": "OBJECT", "name": "CategoryTranslation", - "description": null, + "description": "Represents category translations.", "fields": [ { "name": "description", @@ -24076,7 +24175,7 @@ { "kind": "OBJECT", "name": "CollectionTranslatableContent", - "description": null, + "description": "Represents collection's original translatable fields and related translations.", "fields": [ { "name": "collection", @@ -24285,7 +24384,7 @@ { "kind": "OBJECT", "name": "CollectionTranslation", - "description": null, + "description": "Represents collection translations.", "fields": [ { "name": "description", @@ -28174,6 +28273,61 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "DateTimeFilterInput", + "description": "Define the filtering options for date time fields.\n\nAdded in Saleor 3.11.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": null, + "inputFields": [ + { + "name": "eq", + "description": "The value equal to.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "oneOf", + "description": "The value included in.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "range", + "description": "The value in range.", + "type": { + "kind": "INPUT_OBJECT", + "name": "DateTimeRangeInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "DateTimeRangeInput", @@ -31599,6 +31753,46 @@ "name": "ProductVariantUpdated", "ofType": null }, + { + "kind": "OBJECT", + "name": "PromotionCreated", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionDeleted", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionEnded", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreated", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeleted", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdated", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionStarted", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdated", + "ofType": null + }, { "kind": "OBJECT", "name": "SaleCreated", @@ -39765,8 +39959,8 @@ "name": "String", "ofType": null }, - "isDeprecated": false, - "deprecationReason": null + "isDeprecated": true, + "deprecationReason": "This field will be removed in Saleor 4.0. Use `url` field.This field will be removed in 4.0" }, { "name": "id", @@ -40026,7 +40220,7 @@ }, { "name": "url", - "description": "URL to download an invoice.", + "description": "URL to view/download an invoice. This can be an internal URL if the Invoicing Plugin was used or an external URL if it has been provided.", "args": [], "type": { "kind": "SCALAR", @@ -49069,7 +49263,7 @@ { "kind": "OBJECT", "name": "MenuItemTranslatableContent", - "description": null, + "description": "Represents menu item's original translatable fields and related translations.", "fields": [ { "name": "id", @@ -49230,7 +49424,7 @@ { "kind": "OBJECT", "name": "MenuItemTranslation", - "description": null, + "description": "Represents menu item translations.", "fields": [ { "name": "id", @@ -51362,7 +51556,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update attribute translations.", "type": { "kind": "NON_NULL", "name": null, @@ -51644,7 +51838,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update attribute value translations.", "type": { "kind": "NON_NULL", "name": null, @@ -51865,7 +52059,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update category translations.", "type": { "kind": "NON_NULL", "name": null, @@ -53634,7 +53828,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update collection translations.", "type": { "kind": "NON_NULL", "name": null, @@ -55828,7 +56022,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update menu item translations.", "type": { "kind": "NON_NULL", "name": null, @@ -57645,7 +57839,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update page translations.", "type": { "kind": "NON_NULL", "name": null, @@ -59249,7 +59443,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update product translations.", "type": { "kind": "NON_NULL", "name": null, @@ -60310,7 +60504,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update product variant translations.", "type": { "kind": "NON_NULL", "name": null, @@ -60415,142 +60609,12 @@ "deprecationReason": null }, { - "name": "requestEmailChange", - "description": "Request email change of the logged in user. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- NOTIFY_USER (async): A notification for account email change.\n- ACCOUNT_CHANGE_EMAIL_REQUESTED (async): An account email change was requested.", - "args": [ - { - "name": "channel", - "description": "Slug of a channel which will be used to notify users. Optional when only one channel exists.", - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "newEmail", - "description": "New user email.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "password", - "description": "User password.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "redirectUrl", - "description": "URL of a view where users should be redirected to update the email address. URL in RFC 1808 format.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "RequestEmailChange", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "requestPasswordReset", - "description": "Sends an email with the account password modification link.\n\nTriggers the following webhook events:\n- NOTIFY_USER (async): A notification for password reset.\n- ACCOUNT_SET_PASSWORD_REQUESTED (async): Setting a new password for the account is requested.\n- STAFF_SET_PASSWORD_REQUESTED (async): Setting a new password for the staff account is requested.", - "args": [ - { - "name": "channel", - "description": "Slug of a channel which will be used for notify user. Optional when only one channel exists.", - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "email", - "description": "Email of the user that will be used for password recovery.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "redirectUrl", - "description": "URL of a view where users should be redirected to reset the password. URL in RFC 1808 format.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "RequestPasswordReset", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "saleBulkDelete", - "description": "Deletes sales. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_DELETED (async): A sale was deleted.", + "name": "promotionBulkDelete", + "description": "Deletes promotions.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_DELETED (async): A promotion was deleted.", "args": [ { "name": "ids", - "description": "List of sale IDs to delete.", + "description": "List of promotion IDs to delete.", "type": { "kind": "NON_NULL", "name": null, @@ -60575,41 +60639,54 @@ ], "type": { "kind": "OBJECT", - "name": "SaleBulkDelete", + "name": "PromotionBulkDelete", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "saleCataloguesAdd", - "description": "Adds products, categories, collections to a voucher. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", + "name": "promotionCreate", + "description": "Creates a new promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_CREATED (async): A promotion was created.\n- PROMOTION_STARTED (async): Optionally called if promotion was started.", "args": [ { - "name": "id", - "description": "ID of a sale.", + "name": "input", + "description": "Fields requires to create a promotion.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "SCALAR", - "name": "ID", + "kind": "INPUT_OBJECT", + "name": "PromotionCreateInput", "ofType": null } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - }, + } + ], + "type": { + "kind": "OBJECT", + "name": "PromotionCreate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionDelete", + "description": "Deletes a promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_DELETED (async): A promotion was deleted.", + "args": [ { - "name": "input", - "description": "Fields required to modify catalogue IDs of sale.", + "name": "id", + "description": "The ID of the promotion to remove.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "INPUT_OBJECT", - "name": "CatalogueInput", + "kind": "SCALAR", + "name": "ID", "ofType": null } }, @@ -60620,41 +60697,54 @@ ], "type": { "kind": "OBJECT", - "name": "SaleAddCatalogues", + "name": "PromotionDelete", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "saleCataloguesRemove", - "description": "Removes products, categories, collections from a sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", + "name": "promotionRuleCreate", + "description": "Creates a new promotion rule.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_RULE_CREATED (async): A promotion rule was created.", "args": [ { - "name": "id", - "description": "ID of a sale.", + "name": "input", + "description": "Fields required to create a promotion rule.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "SCALAR", - "name": "ID", + "kind": "INPUT_OBJECT", + "name": "PromotionRuleCreateInput", "ofType": null } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - }, + } + ], + "type": { + "kind": "OBJECT", + "name": "PromotionRuleCreate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRuleDelete", + "description": "Deletes a promotion rule.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_RULE_DELETED (async): A promotion rule was deleted.", + "args": [ { - "name": "input", - "description": "Fields required to modify catalogue IDs of sale.", + "name": "id", + "description": "The ID of the promotion to remove.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "INPUT_OBJECT", - "name": "CatalogueInput", + "kind": "SCALAR", + "name": "ID", "ofType": null } }, @@ -60665,19 +60755,19 @@ ], "type": { "kind": "OBJECT", - "name": "SaleRemoveCatalogues", + "name": "PromotionRuleDelete", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "saleChannelListingUpdate", - "description": "Manage sale's availability in channels. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.", + "name": "promotionRuleTranslate", + "description": "Creates/updates translations for a promotion rule.\n\nAdded in Saleor 3.17. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", "args": [ { "name": "id", - "description": "ID of a sale to update.", + "description": "PromotionRule ID or PromotionRuleTranslatableContent ID.", "type": { "kind": "NON_NULL", "name": null, @@ -60693,42 +60783,29 @@ }, { "name": "input", - "description": "Fields required to update sale channel listings.", + "description": "Fields required to update promotion rule translations.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "SaleChannelListingInput", + "name": "PromotionRuleTranslationInput", "ofType": null } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "SaleChannelListingUpdate", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "saleCreate", - "description": "Creates a new sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_CREATED (async): A sale was created.", - "args": [ + }, { - "name": "input", - "description": "Fields required to create a sale.", + "name": "languageCode", + "description": "Translation language code.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "INPUT_OBJECT", - "name": "SaleInput", + "kind": "ENUM", + "name": "LanguageCodeEnum", "ofType": null } }, @@ -60739,19 +60816,19 @@ ], "type": { "kind": "OBJECT", - "name": "SaleCreate", + "name": "PromotionRuleTranslate", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "saleDelete", - "description": "Deletes a sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_DELETED (async): A sale was deleted.", + "name": "promotionRuleUpdate", + "description": "Updates an existing promotion rule.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_RULE_UPDATED (async): A promotion rule was updated.", "args": [ { "name": "id", - "description": "ID of a sale to delete.", + "description": "ID of the promotion rule to update.", "type": { "kind": "NON_NULL", "name": null, @@ -60764,23 +60841,39 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "input", + "description": "Fields required to create a promotion rule.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "PromotionRuleUpdateInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "type": { "kind": "OBJECT", - "name": "SaleDelete", + "name": "PromotionRuleUpdate", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "saleTranslate", - "description": "Creates/updates translations for a sale. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", + "name": "promotionTranslate", + "description": "Creates/updates translations for a promotion.\n\nAdded in Saleor 3.17. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", "args": [ { "name": "id", - "description": "Sale ID or SaleTranslatableContent ID.", + "description": "Promotion ID or PromotionTranslatableContent ID.", "type": { "kind": "NON_NULL", "name": null, @@ -60796,13 +60889,13 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update promotion translations.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "NameTranslationInput", + "name": "PromotionTranslationInput", "ofType": null } }, @@ -60829,19 +60922,19 @@ ], "type": { "kind": "OBJECT", - "name": "SaleTranslate", + "name": "PromotionTranslate", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "saleUpdate", - "description": "Updates a sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.\n- SALE_TOGGLE (async): Optionally triggered when a sale is started or stopped.", + "name": "promotionUpdate", + "description": "Updates an existing promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_UPDATED (async): A promotion was updated.\n- PROMOTION_STARTED (async): Optionally called if promotion was started.\n- PROMOTION_ENDED (async): Optionally called if promotion was ended.", "args": [ { "name": "id", - "description": "ID of a sale to update.", + "description": "ID of the promotion to update.", "type": { "kind": "NON_NULL", "name": null, @@ -60857,13 +60950,13 @@ }, { "name": "input", - "description": "Fields required to update a sale.", + "description": "Fields required to update a promotion.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "SaleInput", + "name": "PromotionUpdateInput", "ofType": null } }, @@ -60874,64 +60967,31 @@ ], "type": { "kind": "OBJECT", - "name": "SaleUpdate", + "name": "PromotionUpdate", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "sendConfirmationEmail", - "description": "Sends a notification confirmation.\n\nAdded in Saleor 3.15.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- NOTIFY_USER (async): A notification for account confirmation.\n- ACCOUNT_CONFIRMATION_REQUESTED (async): An account confirmation was requested. This event is always sent regardless of settings.", + "name": "requestEmailChange", + "description": "Request email change of the logged in user. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- NOTIFY_USER (async): A notification for account email change.\n- ACCOUNT_CHANGE_EMAIL_REQUESTED (async): An account email change was requested.", "args": [ { "name": "channel", - "description": "Slug of a channel which will be used for notify user.", + "description": "Slug of a channel which will be used to notify users. Optional when only one channel exists.", "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } + "kind": "SCALAR", + "name": "String", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "redirectUrl", - "description": "Base of frontend URL that will be needed to create confirmation URL.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "SendConfirmationEmail", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "setPassword", - "description": "Sets the user's password from the token sent by email using the RequestPasswordReset mutation.", - "args": [ - { - "name": "email", - "description": "Email of a user.", + "name": "newEmail", + "description": "New user email.", "type": { "kind": "NON_NULL", "name": null, @@ -60947,7 +61007,7 @@ }, { "name": "password", - "description": "Password of a user.", + "description": "User password.", "type": { "kind": "NON_NULL", "name": null, @@ -60962,8 +61022,8 @@ "deprecationReason": null }, { - "name": "token", - "description": "A one-time token required to set the password.", + "name": "redirectUrl", + "description": "URL of a view where users should be redirected to update the email address. URL in RFC 1808 format.", "type": { "kind": "NON_NULL", "name": null, @@ -60980,25 +61040,37 @@ ], "type": { "kind": "OBJECT", - "name": "SetPassword", + "name": "RequestEmailChange", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "shippingMethodChannelListingUpdate", - "description": "Manage shipping method's availability in channels. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "name": "requestPasswordReset", + "description": "Sends an email with the account password modification link.\n\nTriggers the following webhook events:\n- NOTIFY_USER (async): A notification for password reset.\n- ACCOUNT_SET_PASSWORD_REQUESTED (async): Setting a new password for the account is requested.\n- STAFF_SET_PASSWORD_REQUESTED (async): Setting a new password for the staff account is requested.", "args": [ { - "name": "id", - "description": "ID of a shipping method to update.", + "name": "channel", + "description": "Slug of a channel which will be used for notify user. Optional when only one channel exists.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "email", + "description": "Email of the user that will be used for password recovery.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "SCALAR", - "name": "ID", + "name": "String", "ofType": null } }, @@ -61007,14 +61079,14 @@ "deprecationReason": null }, { - "name": "input", - "description": "Fields required to update shipping method channel listings.", + "name": "redirectUrl", + "description": "URL of a view where users should be redirected to reset the password. URL in RFC 1808 format.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "INPUT_OBJECT", - "name": "ShippingMethodChannelListingInput", + "kind": "SCALAR", + "name": "String", "ofType": null } }, @@ -61025,19 +61097,19 @@ ], "type": { "kind": "OBJECT", - "name": "ShippingMethodChannelListingUpdate", + "name": "RequestPasswordReset", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "shippingPriceBulkDelete", - "description": "Deletes shipping prices. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "name": "saleBulkDelete", + "description": "Deletes sales. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_DELETED (async): A sale was deleted.", "args": [ { "name": "ids", - "description": "List of shipping price IDs to delete.", + "description": "List of sale IDs to delete.", "type": { "kind": "NON_NULL", "name": null, @@ -61062,25 +61134,41 @@ ], "type": { "kind": "OBJECT", - "name": "ShippingPriceBulkDelete", + "name": "SaleBulkDelete", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "shippingPriceCreate", - "description": "Creates a new shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "name": "saleCataloguesAdd", + "description": "Adds products, categories, collections to a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", "args": [ + { + "name": "id", + "description": "ID of a sale.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "input", - "description": "Fields required to create a shipping price.", + "description": "Fields required to modify catalogue IDs of sale.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "ShippingPriceInput", + "name": "CatalogueInput", "ofType": null } }, @@ -61091,19 +61179,19 @@ ], "type": { "kind": "OBJECT", - "name": "ShippingPriceCreate", + "name": "SaleAddCatalogues", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "shippingPriceDelete", - "description": "Deletes a shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "name": "saleCataloguesRemove", + "description": "Removes products, categories, collections from a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleUpdate` or `promotionRuleDelete` mutations instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", "args": [ { "name": "id", - "description": "ID of a shipping price to delete.", + "description": "ID of a sale.", "type": { "kind": "NON_NULL", "name": null, @@ -61116,23 +61204,39 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "input", + "description": "Fields required to modify catalogue IDs of sale.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CatalogueInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "type": { "kind": "OBJECT", - "name": "ShippingPriceDelete", + "name": "SaleRemoveCatalogues", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "shippingPriceExcludeProducts", - "description": "Exclude products from shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "name": "saleChannelListingUpdate", + "description": "Manage sale's availability in channels.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` or `promotionRuleUpdate` mutations instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.", "args": [ { "name": "id", - "description": "ID of a shipping price.", + "description": "ID of a sale to update.", "type": { "kind": "NON_NULL", "name": null, @@ -61148,13 +61252,13 @@ }, { "name": "input", - "description": "Exclude products input.", + "description": "Fields required to update sale channel listings.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "ShippingPriceExcludeProductsInput", + "name": "SaleChannelListingInput", "ofType": null } }, @@ -61165,50 +61269,55 @@ ], "type": { "kind": "OBJECT", - "name": "ShippingPriceExcludeProducts", + "name": "SaleChannelListingUpdate", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "shippingPriceRemoveProductFromExclude", - "description": "Remove product from excluded list for shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "name": "saleCreate", + "description": "Creates a new sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionCreate` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_CREATED (async): A sale was created.", "args": [ { - "name": "id", - "description": "ID of a shipping price.", + "name": "input", + "description": "Fields required to create a sale.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "SCALAR", - "name": "ID", + "kind": "INPUT_OBJECT", + "name": "SaleInput", "ofType": null } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - }, + } + ], + "type": { + "kind": "OBJECT", + "name": "SaleCreate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "saleDelete", + "description": "Deletes a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionDelete` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_DELETED (async): A sale was deleted.", + "args": [ { - "name": "products", - "description": "List of products which will be removed from excluded list.", + "name": "id", + "description": "ID of a sale to delete.", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - } + "kind": "SCALAR", + "name": "ID", + "ofType": null } }, "defaultValue": null, @@ -61218,19 +61327,19 @@ ], "type": { "kind": "OBJECT", - "name": "ShippingPriceRemoveProductFromExclude", + "name": "SaleDelete", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "shippingPriceTranslate", - "description": "Creates/updates translations for a shipping method. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", + "name": "saleTranslate", + "description": "Creates/updates translations for a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `PromotionTranslate` mutation instead. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", "args": [ { "name": "id", - "description": "ShippingMethodType ID or ShippingMethodTranslatableContent ID.", + "description": "Sale ID or SaleTranslatableContent ID.", "type": { "kind": "NON_NULL", "name": null, @@ -61246,13 +61355,463 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update sale translations.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "ShippingPriceTranslationInput", + "name": "NameTranslationInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "languageCode", + "description": "Translation language code.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "LanguageCodeEnum", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "SaleTranslate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "saleUpdate", + "description": "Updates a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionUpdate` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.\n- SALE_TOGGLE (async): Optionally triggered when a sale is started or stopped.", + "args": [ + { + "name": "id", + "description": "ID of a sale to update.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "input", + "description": "Fields required to update a sale.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "SaleInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "SaleUpdate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sendConfirmationEmail", + "description": "Sends a notification confirmation.\n\nAdded in Saleor 3.15.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- NOTIFY_USER (async): A notification for account confirmation.\n- ACCOUNT_CONFIRMATION_REQUESTED (async): An account confirmation was requested. This event is always sent regardless of settings.", + "args": [ + { + "name": "channel", + "description": "Slug of a channel which will be used for notify user.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "redirectUrl", + "description": "Base of frontend URL that will be needed to create confirmation URL.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "SendConfirmationEmail", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "setPassword", + "description": "Sets the user's password from the token sent by email using the RequestPasswordReset mutation.", + "args": [ + { + "name": "email", + "description": "Email of a user.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "password", + "description": "Password of a user.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "token", + "description": "A one-time token required to set the password.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "SetPassword", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingMethodChannelListingUpdate", + "description": "Manage shipping method's availability in channels. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "args": [ + { + "name": "id", + "description": "ID of a shipping method to update.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "input", + "description": "Fields required to update shipping method channel listings.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ShippingMethodChannelListingInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ShippingMethodChannelListingUpdate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingPriceBulkDelete", + "description": "Deletes shipping prices. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "args": [ + { + "name": "ids", + "description": "List of shipping price IDs to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ShippingPriceBulkDelete", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingPriceCreate", + "description": "Creates a new shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "args": [ + { + "name": "input", + "description": "Fields required to create a shipping price.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ShippingPriceInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ShippingPriceCreate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingPriceDelete", + "description": "Deletes a shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "args": [ + { + "name": "id", + "description": "ID of a shipping price to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ShippingPriceDelete", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingPriceExcludeProducts", + "description": "Exclude products from shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "args": [ + { + "name": "id", + "description": "ID of a shipping price.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "input", + "description": "Exclude products input.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ShippingPriceExcludeProductsInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ShippingPriceExcludeProducts", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingPriceRemoveProductFromExclude", + "description": "Remove product from excluded list for shipping price. \n\nRequires one of the following permissions: MANAGE_SHIPPING.", + "args": [ + { + "name": "id", + "description": "ID of a shipping price.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "products", + "description": "List of products which will be removed from excluded list.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ShippingPriceRemoveProductFromExclude", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingPriceTranslate", + "description": "Creates/updates translations for a shipping method. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", + "args": [ + { + "name": "id", + "description": "ShippingMethodType ID or ShippingMethodTranslatableContent ID.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "input", + "description": "Fields required to update shipping price translations.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ShippingPriceTranslationInput", "ofType": null } }, @@ -63400,6 +63959,43 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "voucherCodeBulkDelete", + "description": "Deletes voucher codes.\n\nAdded in Saleor 3.18. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- VOUCHER_UPDATED (async): A voucher was updated.", + "args": [ + { + "name": "ids", + "description": "List of voucher codes IDs to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "VoucherCodeBulkDelete", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "voucherCreate", "description": "Creates a new voucher. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- VOUCHER_CREATED (async): A voucher was created.", @@ -63480,7 +64076,7 @@ }, { "name": "input", - "description": null, + "description": "Fields required to update voucher translations.", "type": { "kind": "NON_NULL", "name": null, @@ -64130,6 +64726,71 @@ "name": "ProductVariantTranslation", "ofType": null }, + { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionCreatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionEndedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleTranslatableContent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleTranslation", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionStartedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionTranslatableContent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionTranslation", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdatedEvent", + "ofType": null + }, { "kind": "OBJECT", "name": "Sale", @@ -64559,6 +65220,11 @@ "name": "ProductVariant", "ofType": null }, + { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, { "kind": "OBJECT", "name": "Sale", @@ -69081,6 +69747,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "PROMOTION", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "SALE", "description": null, @@ -77604,7 +78276,7 @@ { "kind": "OBJECT", "name": "PageTranslatableContent", - "description": null, + "description": "Represents page's original translatable fields and related translations.", "fields": [ { "name": "attributeValues", @@ -77837,7 +78509,7 @@ { "kind": "OBJECT", "name": "PageTranslation", - "description": null, + "description": "Represents page translations.", "fields": [ { "name": "content", @@ -91284,7 +91956,7 @@ { "kind": "OBJECT", "name": "ProductTranslatableContent", - "description": null, + "description": "Represents product's original translatable fields and related translations.", "fields": [ { "name": "attributeValues", @@ -91552,7 +92224,7 @@ { "kind": "OBJECT", "name": "ProductTranslation", - "description": null, + "description": "Represents product translations.", "fields": [ { "name": "description", @@ -97343,7 +98015,7 @@ { "kind": "OBJECT", "name": "ProductVariantTranslatableContent", - "description": null, + "description": "Represents product variant's original translatable fields and related translations.", "fields": [ { "name": "attributeValues", @@ -97563,7 +98235,7 @@ { "kind": "OBJECT", "name": "ProductVariantTranslation", - "description": null, + "description": "Represents product variant translations.", "fields": [ { "name": "id", @@ -98036,32 +98708,4282 @@ "deprecationReason": null }, { - "name": "isAvailable", - "description": "Filter by availability for purchase.", - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isPublished", - "description": "Filter by public visibility.", - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isVisibleInListing", - "description": "Filter by visibility on the channel.", + "name": "isAvailable", + "description": "Filter by availability for purchase.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPublished", + "description": "Filter by public visibility.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isVisibleInListing", + "description": "Filter by visibility on the channel.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "metadata", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "MetadataFilter", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "minimalPrice", + "description": "Filter by the lowest variant price after discounts.", + "type": { + "kind": "INPUT_OBJECT", + "name": "DecimalFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Filter by product name.", + "type": { + "kind": "INPUT_OBJECT", + "name": "StringFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "price", + "description": "Filter by product variant price.", + "type": { + "kind": "INPUT_OBJECT", + "name": "DecimalFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productType", + "description": "Filter by product type.", + "type": { + "kind": "INPUT_OBJECT", + "name": "GlobalIDFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedFrom", + "description": "Filter by the publication date.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "slug", + "description": "Filter by product slug.", + "type": { + "kind": "INPUT_OBJECT", + "name": "StringFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stockAvailability", + "description": "Filter by variants having specific stock status.", + "type": { + "kind": "ENUM", + "name": "StockAvailability", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stocks", + "description": "Filter by stock of the product variant.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProductStockFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Filter by when was the most recent update.", + "type": { + "kind": "INPUT_OBJECT", + "name": "DateTimeFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Promotion", + "description": "Represents the promotion that allow creating discounts based on given conditions, and is visible to all the customers.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdAt", + "description": "Date time of promotion creation.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Description of the promotion.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endDate", + "description": "End date of the promotion.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "events", + "description": "The list of events associated with the promotion.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "PromotionEvent", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "metadata", + "description": "List of public metadata items. Can be accessed without permissions.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MetadataItem", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "metafield", + "description": "A single key from public metadata.\n\nTip: Use GraphQL aliases to fetch multiple keys.\n\nAdded in Saleor 3.3.", + "args": [ + { + "name": "key", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "metafields", + "description": "Public metadata. Use `keys` to control which fields you want to include. The default is to include everything.\n\nAdded in Saleor 3.3.", + "args": [ + { + "name": "keys", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "SCALAR", + "name": "Metadata", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Name of the promotion.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "privateMetadata", + "description": "List of private metadata items. Requires staff permissions to access.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MetadataItem", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "privateMetafield", + "description": "A single key from private metadata. Requires staff permissions to access.\n\nTip: Use GraphQL aliases to fetch multiple keys.\n\nAdded in Saleor 3.3.", + "args": [ + { + "name": "key", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "privateMetafields", + "description": "Private metadata. Requires staff permissions to access. Use `keys` to control which fields you want to include. The default is to include everything.\n\nAdded in Saleor 3.3.", + "args": [ + { + "name": "keys", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "SCALAR", + "name": "Metadata", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rules", + "description": "The list of promotion rules.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "startDate", + "description": "Start date of the promotion.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "translation", + "description": "Returns translated promotion fields for the given language code.", + "args": [ + { + "name": "languageCode", + "description": "A language code to return the translation for promotion.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "LanguageCodeEnum", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "PromotionTranslation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Date time of last update of promotion.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "ObjectWithMetadata", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionBulkDelete", + "description": "Deletes promotions.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_DELETED (async): A promotion was deleted.", + "fields": [ + { + "name": "count", + "description": "Returns how many objects were affected.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DiscountError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionCountableConnection", + "description": null, + "fields": [ + { + "name": "edges", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionCountableEdge", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Pagination data for this connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "A total count of items in the collection.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionCountableEdge", + "description": null, + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionCreate", + "description": "Creates a new promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_CREATED (async): A promotion was created.\n- PROMOTION_STARTED (async): Optionally called if promotion was started.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionCreateError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionCreateError", + "description": null, + "fields": [ + { + "name": "code", + "description": "The error code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionCreateErrorCode", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "field", + "description": "Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "index", + "description": "Index of an input list item that caused the error.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The error message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PromotionCreateErrorCode", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "GRAPHQL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID_PRECISION", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MULTIPLE_CURRENCIES_NOT_ALLOWED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_FOUND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REQUIRED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionCreateInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "description", + "description": "Promotion description.", + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endDate", + "description": "The end date of the promotion in ISO 8601 format.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Promotion name.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rules", + "description": "List of promotion rules.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "PromotionRuleInput", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "startDate", + "description": "The start date of the promotion in ISO 8601 format.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionCreated", + "description": "Event sent when new promotion is created.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": "The promotion the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionCreatedEvent", + "description": "History log of the promotion created event.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionDelete", + "description": "Deletes a promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_DELETED (async): A promotion was deleted.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionDeleteError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionDeleteError", + "description": null, + "fields": [ + { + "name": "code", + "description": "The error code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionDeleteErrorCode", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "field", + "description": "Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The error message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PromotionDeleteErrorCode", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "GRAPHQL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_FOUND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionDeleted", + "description": "Event sent when promotion is deleted.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": "The promotion the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionEnded", + "description": "The event informs about the end of the promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": "The promotion the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionEndedEvent", + "description": "History log of the promotion ended event.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "PromotionEvent", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "PromotionCreatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionEndedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionStartedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdatedEvent", + "ofType": null + } + ] + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "description": null, + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "PromotionCreatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionEndedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionStartedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdatedEvent", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PROMOTION_CREATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_ENDED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_STARTED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_UPDATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RULE_CREATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RULE_DELETED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RULE_UPDATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRule", + "description": "Represents the promotion rule that specifies the conditions that must be met to apply the promotion discount.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "cataloguePredicate", + "description": "The catalogue predicate that must be met to apply the rule reward.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "channels", + "description": "List of channels where the rule applies.\n\nRequires one of the following permissions: AUTHENTICATED_APP, AUTHENTICATED_STAFF_USER.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Channel", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Description of the promotion rule.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Name of the promotion rule.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": "Promotion to which the rule belongs.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValue", + "description": "The reward value of the promotion rule. Defines the discount value applied when the rule conditions are met.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "PositiveDecimal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValueType", + "description": "The type of reward value of the promotion rule.", + "args": [], + "type": { + "kind": "ENUM", + "name": "RewardValueTypeEnum", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "translation", + "description": "Returns translated promotion rule fields for the given language code.", + "args": [ + { + "name": "languageCode", + "description": "A language code to return the translation for promotion rule.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "LanguageCodeEnum", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "PromotionRuleTranslation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreate", + "description": "Creates a new promotion rule.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_RULE_CREATED (async): A promotion rule was created.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionRuleCreateError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRule", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreateError", + "description": null, + "fields": [ + { + "name": "code", + "description": "The error code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionRuleCreateErrorCode", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "field", + "description": "Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The error message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PromotionRuleCreateErrorCode", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "GRAPHQL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID_PRECISION", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MULTIPLE_CURRENCIES_NOT_ALLOWED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_FOUND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REQUIRED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionRuleCreateInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "cataloguePredicate", + "description": "Defines the conditions on the catalogue level that must be met for the reward to be applied.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CataloguePredicateInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "channels", + "description": "List of channel ids to which the rule should apply to.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Promotion rule description.", + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Promotion rule name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": "The ID of the promotion that rule belongs to.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValue", + "description": "Defines the discount value. Required when catalogue predicate is provided.", + "type": { + "kind": "SCALAR", + "name": "PositiveDecimal", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValueType", + "description": "Defines the promotion rule reward value type. Must be provided together with reward value.", + "type": { + "kind": "ENUM", + "name": "RewardValueTypeEnum", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreated", + "description": "Event sent when new promotion rule is created.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRule", + "description": "The promotion rule the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleCreatedEvent", + "description": "History log of the promotion rule created event.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ruleId", + "description": "The rule ID associated with the promotion event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionRuleEventInterface", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDelete", + "description": "Deletes a promotion rule.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_RULE_DELETED (async): A promotion rule was deleted.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionRuleDeleteError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRule", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeleteError", + "description": null, + "fields": [ + { + "name": "code", + "description": "The error code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionRuleDeleteErrorCode", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "field", + "description": "Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The error message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PromotionRuleDeleteErrorCode", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "GRAPHQL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_FOUND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeleted", + "description": "Event sent when new promotion rule is deleted.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRule", + "description": "The promotion rule the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeletedEvent", + "description": "History log of the promotion rule created event.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ruleId", + "description": "The rule ID associated with the promotion event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionRuleEventInterface", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "PromotionRuleEventInterface", + "description": "History log of the promotion event related to rule.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "ruleId", + "description": "The rule ID associated with the promotion event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "PromotionRuleCreatedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdatedEvent", + "ofType": null + } + ] + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionRuleInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "cataloguePredicate", + "description": "Defines the conditions on the catalogue level that must be met for the reward to be applied.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CataloguePredicateInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "channels", + "description": "List of channel ids to which the rule should apply to.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Promotion rule description.", + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Promotion rule name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValue", + "description": "Defines the discount value. Required when catalogue predicate is provided.", + "type": { + "kind": "SCALAR", + "name": "PositiveDecimal", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValueType", + "description": "Defines the promotion rule reward value type. Must be provided together with reward value.", + "type": { + "kind": "ENUM", + "name": "RewardValueTypeEnum", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleTranslatableContent", + "description": "Represents promotion rule's original translatable fields and related translations.\n\nAdded in Saleor 3.17.", + "fields": [ + { + "name": "description", + "description": "Description of the promotion rule.\n\nRich text format. For reference see https://editorjs.io/", + "args": [], + "type": { + "kind": "SCALAR", + "name": "JSONString", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "ID of the promotion rule translatable content.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Name of the promotion rule.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "translation", + "description": "Returns translated promotion rule fields for the given language code.", + "args": [ + { + "name": "languageCode", + "description": "A language code to return the translation for promotion rule.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "LanguageCodeEnum", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "PromotionRuleTranslation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleTranslate", + "description": "Creates/updates translations for a promotion rule.\n\nAdded in Saleor 3.17. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TranslationError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRule", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleTranslation", + "description": "Represents promotion rule translations.\n\nAdded in Saleor 3.17.", + "fields": [ + { + "name": "description", + "description": "Translated description of the promotion rule.\n\nRich text format. For reference see https://editorjs.io/", + "args": [], + "type": { + "kind": "SCALAR", + "name": "JSONString", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "ID of the promotion rule translation.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "language", + "description": "Translation language.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LanguageDisplay", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Translated name of the promotion rule.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionRuleTranslationInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "description", + "description": "Translated promotion description.\n\nRich text format. For reference see https://editorjs.io/", + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdate", + "description": "Updates an existing promotion rule.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_RULE_UPDATED (async): A promotion rule was updated.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionRuleUpdateError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRule", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdateError", + "description": null, + "fields": [ + { + "name": "channels", + "description": "List of channel IDs which causes the error.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "code", + "description": "The error code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionRuleUpdateErrorCode", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "field", + "description": "Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The error message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PromotionRuleUpdateErrorCode", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "DUPLICATED_INPUT_ITEM", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "GRAPHQL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID_PRECISION", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MISSING_CHANNELS", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MULTIPLE_CURRENCIES_NOT_ALLOWED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_FOUND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionRuleUpdateInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "addChannels", + "description": "List of channel ids to remove.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "cataloguePredicate", + "description": "Defines the conditions on the catalogue level that must be met for the reward to be applied.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CataloguePredicateInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Promotion rule description.", + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Promotion rule name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "removeChannels", + "description": "List of channel ids to remove.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValue", + "description": "Defines the discount value. Required when catalogue predicate is provided.", + "type": { + "kind": "SCALAR", + "name": "PositiveDecimal", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rewardValueType", + "description": "Defines the promotion rule reward value type. Must be provided together with reward value.", + "type": { + "kind": "ENUM", + "name": "RewardValueTypeEnum", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdated", + "description": "Event sent when new promotion rule is updated.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotionRule", + "description": "The promotion rule the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PromotionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionRuleUpdatedEvent", + "description": "History log of the promotion rule created event.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ruleId", + "description": "The rule ID associated with the promotion event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionRuleEventInterface", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PromotionSortField", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Sort promotions by created at.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "END_DATE", + "description": "Sort promotions by end date.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NAME", + "description": "Sort promotions by name.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "START_DATE", + "description": "Sort promotions by start date.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionSortingInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "direction", + "description": "Specifies the direction in which to sort promotions.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "field", + "description": "Sort promotions by the selected field.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionSortField", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionStarted", + "description": "The event informs about the start of the promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": "The promotion the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionStartedEvent", + "description": "History log of the promotion started event.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionTranslatableContent", + "description": "Represents promotion's original translatable fields and related translations.\n\nAdded in Saleor 3.17.", + "fields": [ + { + "name": "description", + "description": "Description of the promotion.\n\nRich text format. For reference see https://editorjs.io/", + "args": [], + "type": { + "kind": "SCALAR", + "name": "JSONString", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "ID of the promotion translatable content.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Name of the promotion.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "translation", + "description": "Returns translated promotion fields for the given language code.", + "args": [ + { + "name": "languageCode", + "description": "A language code to return the translation for promotion.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "LanguageCodeEnum", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "PromotionTranslation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionTranslate", + "description": "Creates/updates translations for a promotion.\n\nAdded in Saleor 3.17. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TranslationError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionTranslation", + "description": "Represents promotion translations.\n\nAdded in Saleor 3.17.", + "fields": [ + { + "name": "description", + "description": "Translated description of the promotion.\n\nRich text format. For reference see https://editorjs.io/", + "args": [], + "type": { + "kind": "SCALAR", + "name": "JSONString", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "ID of the promotion translation.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "language", + "description": "Translation language.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LanguageDisplay", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Translated name of the promotion.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionTranslationInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "description", + "description": "Translated promotion description.\n\nRich text format. For reference see https://editorjs.io/", + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdate", + "description": "Updates an existing promotion.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- PROMOTION_UPDATED (async): A promotion was updated.\n- PROMOTION_STARTED (async): Optionally called if promotion was started.\n- PROMOTION_ENDED (async): Optionally called if promotion was ended.", + "fields": [ + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PromotionUpdateError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdateError", + "description": null, + "fields": [ + { + "name": "code", + "description": "The error code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionUpdateErrorCode", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "field", + "description": "Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The error message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PromotionUpdateErrorCode", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "GRAPHQL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_FOUND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REQUIRED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionUpdateInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "description", + "description": "Promotion description.", + "type": { + "kind": "SCALAR", + "name": "JSON", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endDate", + "description": "The end date of the promotion in ISO 8601 format.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Promotion name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "startDate", + "description": "The start date of the promotion in ISO 8601 format.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdated", + "description": "Event sent when promotion is updated.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotion", + "description": "The promotion the event relates to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PromotionUpdatedEvent", + "description": "History log of the promotion updated event.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "createdBy", + "description": "User or App that created the promotion event. \n\nRequires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER.", + "args": [], + "type": { + "kind": "UNION", + "name": "UserOrApp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "Date when event happened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Promotion event type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PromotionEventsEnum", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "PromotionEventInterface", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PromotionWhereInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "AND", + "description": "List of conditions that must be met.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "PromotionWhereInput", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OR", + "description": "A list of conditions of which at least one must be met.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "PromotionWhereInput", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endDate", + "description": "Filter promotions by end date.", + "type": { + "kind": "INPUT_OBJECT", + "name": "DateTimeFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ids", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isOldSale", + "description": null, "type": { "kind": "SCALAR", "name": "Boolean", @@ -98091,21 +103013,9 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "minimalPrice", - "description": "Filter by the lowest variant price after discounts.", - "type": { - "kind": "INPUT_OBJECT", - "name": "DecimalFilterInput", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "name", - "description": "Filter by product name.", + "description": "Filter by promotion name.", "type": { "kind": "INPUT_OBJECT", "name": "StringFilterInput", @@ -98116,83 +103026,11 @@ "deprecationReason": null }, { - "name": "price", - "description": "Filter by product variant price.", - "type": { - "kind": "INPUT_OBJECT", - "name": "DecimalFilterInput", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "productType", - "description": "Filter by product type.", - "type": { - "kind": "INPUT_OBJECT", - "name": "GlobalIDFilterInput", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "publishedFrom", - "description": "Filter by the publication date.", - "type": { - "kind": "SCALAR", - "name": "DateTime", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "slug", - "description": "Filter by product slug.", - "type": { - "kind": "INPUT_OBJECT", - "name": "StringFilterInput", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "stockAvailability", - "description": "Filter by variants having specific stock status.", - "type": { - "kind": "ENUM", - "name": "StockAvailability", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "stocks", - "description": "Filter by stock of the product variant.", - "type": { - "kind": "INPUT_OBJECT", - "name": "ProductStockFilterInput", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "updatedAt", - "description": "Filter by when was the most recent update.", + "name": "startDate", + "description": "Filter promotions by start date.", "type": { "kind": "INPUT_OBJECT", - "name": "DateTimeRangeInput", + "name": "DateTimeFilterInput", "ofType": null }, "defaultValue": null, @@ -101252,11 +106090,157 @@ "deprecationReason": null }, { - "name": "filter", - "description": "Filtering options for product types.", + "name": "filter", + "description": "Filtering options for product types.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProductTypeFilterInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "first", + "description": "Retrieve the first n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "last", + "description": "Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sortBy", + "description": "Sort product types.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProductTypeSortingInput", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ProductTypeCountableConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productVariant", + "description": "Look up a product variant by ID or SKU. Requires one of the following permissions to include the unpublished items: MANAGE_ORDERS, MANAGE_DISCOUNTS, MANAGE_PRODUCTS.", + "args": [ + { + "name": "channel", + "description": "Slug of a channel for which the data should be returned.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "externalReference", + "description": "External ID of the product. \n\nAdded in Saleor 3.10.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "ID of the product variant.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sku", + "description": "SKU of the product variant.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ProductVariant", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productVariants", + "description": "List of product variants. Requires one of the following permissions to include the unpublished items: MANAGE_ORDERS, MANAGE_DISCOUNTS, MANAGE_PRODUCTS.", + "args": [ + { + "name": "after", + "description": "Return the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "before", + "description": "Return the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "channel", + "description": "Slug of a channel for which the data should be returned.", "type": { - "kind": "INPUT_OBJECT", - "name": "ProductTypeFilterInput", + "kind": "SCALAR", + "name": "String", "ofType": null }, "defaultValue": null, @@ -101264,11 +106248,11 @@ "deprecationReason": null }, { - "name": "first", - "description": "Retrieve the first n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", + "name": "filter", + "description": "Filtering options for product variant.", "type": { - "kind": "SCALAR", - "name": "Int", + "kind": "INPUT_OBJECT", + "name": "ProductVariantFilterInput", "ofType": null }, "defaultValue": null, @@ -101276,8 +106260,8 @@ "deprecationReason": null }, { - "name": "last", - "description": "Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", + "name": "first", + "description": "Retrieve the first n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", "type": { "kind": "SCALAR", "name": "Int", @@ -101288,48 +106272,31 @@ "deprecationReason": null }, { - "name": "sortBy", - "description": "Sort product types.", - "type": { - "kind": "INPUT_OBJECT", - "name": "ProductTypeSortingInput", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "ProductTypeCountableConnection", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "productVariant", - "description": "Look up a product variant by ID or SKU. Requires one of the following permissions to include the unpublished items: MANAGE_ORDERS, MANAGE_DISCOUNTS, MANAGE_PRODUCTS.", - "args": [ - { - "name": "channel", - "description": "Slug of a channel for which the data should be returned.", + "name": "ids", + "description": "Filter product variants by given IDs.", "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "externalReference", - "description": "External ID of the product. \n\nAdded in Saleor 3.10.", + "name": "last", + "description": "Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", "type": { "kind": "SCALAR", - "name": "String", + "name": "Int", "ofType": null }, "defaultValue": null, @@ -101337,11 +106304,11 @@ "deprecationReason": null }, { - "name": "id", - "description": "ID of the product variant.", + "name": "sortBy", + "description": "Sort products variants.", "type": { - "kind": "SCALAR", - "name": "ID", + "kind": "INPUT_OBJECT", + "name": "ProductVariantSortingInput", "ofType": null }, "defaultValue": null, @@ -101349,11 +106316,11 @@ "deprecationReason": null }, { - "name": "sku", - "description": "SKU of the product variant.", + "name": "where", + "description": "Where filtering options.\n\nAdded in Saleor 3.14.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", "type": { - "kind": "SCALAR", - "name": "String", + "kind": "INPUT_OBJECT", + "name": "ProductVariantWhereInput", "ofType": null }, "defaultValue": null, @@ -101363,15 +106330,15 @@ ], "type": { "kind": "OBJECT", - "name": "ProductVariant", + "name": "ProductVariantCountableConnection", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "productVariants", - "description": "List of product variants. Requires one of the following permissions to include the unpublished items: MANAGE_ORDERS, MANAGE_DISCOUNTS, MANAGE_PRODUCTS.", + "name": "products", + "description": "List of the shop's products. Requires one of the following permissions to include the unpublished items: MANAGE_ORDERS, MANAGE_DISCOUNTS, MANAGE_PRODUCTS.", "args": [ { "name": "after", @@ -101411,10 +106378,10 @@ }, { "name": "filter", - "description": "Filtering options for product variant.", + "description": "Filtering options for products.", "type": { "kind": "INPUT_OBJECT", - "name": "ProductVariantFilterInput", + "name": "ProductFilterInput", "ofType": null }, "defaultValue": null, @@ -101434,31 +106401,23 @@ "deprecationReason": null }, { - "name": "ids", - "description": "Filter product variants by given IDs.", + "name": "last", + "description": "Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - } + "kind": "SCALAR", + "name": "Int", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "last", - "description": "Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", + "name": "search", + "description": "Search products.\n\nAdded in Saleor 3.14.", "type": { "kind": "SCALAR", - "name": "Int", + "name": "String", "ofType": null }, "defaultValue": null, @@ -101467,10 +106426,10 @@ }, { "name": "sortBy", - "description": "Sort products variants.", + "description": "Sort products.", "type": { "kind": "INPUT_OBJECT", - "name": "ProductVariantSortingInput", + "name": "ProductOrder", "ofType": null }, "defaultValue": null, @@ -101482,7 +106441,7 @@ "description": "Where filtering options.\n\nAdded in Saleor 3.14.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", "type": { "kind": "INPUT_OBJECT", - "name": "ProductVariantWhereInput", + "name": "ProductWhereInput", "ofType": null }, "defaultValue": null, @@ -101492,31 +106451,48 @@ ], "type": { "kind": "OBJECT", - "name": "ProductVariantCountableConnection", + "name": "ProductCountableConnection", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, { - "name": "products", - "description": "List of the shop's products. Requires one of the following permissions to include the unpublished items: MANAGE_ORDERS, MANAGE_DISCOUNTS, MANAGE_PRODUCTS.", + "name": "promotion", + "description": "Look up a promotion by ID.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.\n\nRequires one of the following permissions: MANAGE_DISCOUNTS.", "args": [ { - "name": "after", - "description": "Return the elements in the list that come after the specified cursor.", + "name": "id", + "description": "ID of the promotion.", "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null - }, + } + ], + "type": { + "kind": "OBJECT", + "name": "Promotion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "promotions", + "description": "List of the promotions.\n\nAdded in Saleor 3.17.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.\n\nRequires one of the following permissions: MANAGE_DISCOUNTS.", + "args": [ { - "name": "before", - "description": "Return the elements in the list that come before the specified cursor.", + "name": "after", + "description": "Return the elements in the list that come after the specified cursor.", "type": { "kind": "SCALAR", "name": "String", @@ -101527,8 +106503,8 @@ "deprecationReason": null }, { - "name": "channel", - "description": "Slug of a channel for which the data should be returned.", + "name": "before", + "description": "Return the elements in the list that come before the specified cursor.", "type": { "kind": "SCALAR", "name": "String", @@ -101538,18 +106514,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "filter", - "description": "Filtering options for products.", - "type": { - "kind": "INPUT_OBJECT", - "name": "ProductFilterInput", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "first", "description": "Retrieve the first n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.", @@ -101574,24 +106538,12 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "search", - "description": "Search products.\n\nAdded in Saleor 3.14.", - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "sortBy", - "description": "Sort products.", + "description": "Sort promotions.", "type": { "kind": "INPUT_OBJECT", - "name": "ProductOrder", + "name": "PromotionSortingInput", "ofType": null }, "defaultValue": null, @@ -101600,10 +106552,10 @@ }, { "name": "where", - "description": "Where filtering options.\n\nAdded in Saleor 3.14.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "description": "Where filtering options.", "type": { "kind": "INPUT_OBJECT", - "name": "ProductWhereInput", + "name": "PromotionWhereInput", "ofType": null }, "defaultValue": null, @@ -101613,7 +106565,7 @@ ], "type": { "kind": "OBJECT", - "name": "ProductCountableConnection", + "name": "PromotionCountableConnection", "ofType": null }, "isDeprecated": false, @@ -101750,8 +106702,8 @@ "name": "Sale", "ofType": null }, - "isDeprecated": false, - "deprecationReason": null + "isDeprecated": true, + "deprecationReason": "This field will be removed in Saleor 4.0. Use the `promotion` query instead." }, { "name": "sales", @@ -101859,8 +106811,8 @@ "name": "SaleCountableConnection", "ofType": null }, - "isDeprecated": false, - "deprecationReason": null + "isDeprecated": true, + "deprecationReason": "This field will be removed in Saleor 4.0. Use the `promotions` query instead." }, { "name": "shippingZone", @@ -103350,10 +108302,33 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "ENUM", + "name": "RewardValueTypeEnum", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "FIXED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PERCENTAGE", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, { "kind": "OBJECT", "name": "Sale", - "description": "Sales allow creating discounts for categories, collections or products and are visible to all the customers.", + "description": "Sales allow creating discounts for categories, collections or products and are visible to all the customers.\n\nDEPRECATED: this type will be removed in Saleor 4.0. Use `Promotion` type instead.", "fields": [ { "name": "categories", @@ -103972,7 +108947,7 @@ { "kind": "OBJECT", "name": "SaleAddCatalogues", - "description": "Adds products, categories, collections to a voucher. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", + "description": "Adds products, categories, collections to a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", "fields": [ { "name": "discountErrors", @@ -104118,7 +109093,7 @@ { "kind": "OBJECT", "name": "SaleChannelListing", - "description": "Represents sale channel listing.", + "description": "Represents sale channel listing.\n\nDEPRECATED: this type will be removed in Saleor 4.0. Use `PromotionRule` type instead.", "fields": [ { "name": "channel", @@ -104293,7 +109268,7 @@ { "kind": "OBJECT", "name": "SaleChannelListingUpdate", - "description": "Manage sale's availability in channels. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.", + "description": "Manage sale's availability in channels.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` or `promotionRuleUpdate` mutations instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.", "fields": [ { "name": "discountErrors", @@ -104470,7 +109445,7 @@ { "kind": "OBJECT", "name": "SaleCreate", - "description": "Creates a new sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_CREATED (async): A sale was created.", + "description": "Creates a new sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionCreate` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_CREATED (async): A sale was created.", "fields": [ { "name": "discountErrors", @@ -104541,7 +109516,7 @@ { "kind": "OBJECT", "name": "SaleCreated", - "description": "Event sent when new sale is created.\n\nAdded in Saleor 3.2.", + "description": "Event sent when new sale is created.\n\nAdded in Saleor 3.2.\n\nDEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionCreated` event instead.", "fields": [ { "name": "issuedAt", @@ -104631,7 +109606,7 @@ { "kind": "OBJECT", "name": "SaleDelete", - "description": "Deletes a sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_DELETED (async): A sale was deleted.", + "description": "Deletes a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionDelete` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_DELETED (async): A sale was deleted.", "fields": [ { "name": "discountErrors", @@ -104702,7 +109677,7 @@ { "kind": "OBJECT", "name": "SaleDeleted", - "description": "Event sent when sale is deleted.\n\nAdded in Saleor 3.2.", + "description": "Event sent when sale is deleted.\n\nAdded in Saleor 3.2.\n\nDEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionDeleted` event instead.", "fields": [ { "name": "issuedAt", @@ -105042,7 +110017,7 @@ { "kind": "OBJECT", "name": "SaleRemoveCatalogues", - "description": "Removes products, categories, collections from a sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", + "description": "Removes products, categories, collections from a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleUpdate` or `promotionRuleDelete` mutations instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.", "fields": [ { "name": "discountErrors", @@ -105221,7 +110196,7 @@ { "kind": "OBJECT", "name": "SaleToggle", - "description": "The event informs about the start or end of the sale.\n\nAdded in Saleor 3.5.", + "description": "The event informs about the start or end of the sale.\n\nAdded in Saleor 3.5.\n\nDEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionStarted` and `PromotionEnded` events instead.", "fields": [ { "name": "issuedAt", @@ -105311,7 +110286,7 @@ { "kind": "OBJECT", "name": "SaleTranslatableContent", - "description": null, + "description": "Represents sale's original translatable fields and related translations.\n\nDEPRECATED: this type will be removed in Saleor 4.0. Use `PromotionTranslatableContent` instead.", "fields": [ { "name": "id", @@ -105401,7 +110376,7 @@ { "kind": "OBJECT", "name": "SaleTranslate", - "description": "Creates/updates translations for a sale. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", + "description": "Creates/updates translations for a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `PromotionTranslate` mutation instead. \n\nRequires one of the following permissions: MANAGE_TRANSLATIONS.", "fields": [ { "name": "errors", @@ -105472,7 +110447,7 @@ { "kind": "OBJECT", "name": "SaleTranslation", - "description": null, + "description": "Represents sale translations.\n\nDEPRECATED: this type will be removed in Saleor 4.0. Use `PromotionTranslation` instead.", "fields": [ { "name": "id", @@ -105556,7 +110531,7 @@ { "kind": "OBJECT", "name": "SaleUpdate", - "description": "Updates a sale. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.\n- SALE_TOGGLE (async): Optionally triggered when a sale is started or stopped.", + "description": "Updates a sale.\n\nDEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionUpdate` mutation instead. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- SALE_UPDATED (async): A sale was updated.\n- SALE_TOGGLE (async): Optionally triggered when a sale is started or stopped.", "fields": [ { "name": "discountErrors", @@ -105627,7 +110602,7 @@ { "kind": "OBJECT", "name": "SaleUpdated", - "description": "Event sent when sale is updated.\n\nAdded in Saleor 3.2.", + "description": "Event sent when sale is updated.\n\nAdded in Saleor 3.2.\n\nDEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionUpdated` event instead.", "fields": [ { "name": "issuedAt", @@ -107012,7 +111987,7 @@ { "kind": "OBJECT", "name": "ShippingMethodTranslatableContent", - "description": null, + "description": "Represents shipping method's original translatable fields and related translations.", "fields": [ { "name": "description", @@ -107114,7 +112089,7 @@ { "kind": "OBJECT", "name": "ShippingMethodTranslation", - "description": null, + "description": "Represents shipping method translations.", "fields": [ { "name": "description", @@ -112043,7 +117018,7 @@ { "kind": "OBJECT", "name": "ShopTranslation", - "description": null, + "description": "Represents shop translations.", "fields": [ { "name": "description", @@ -121519,6 +126494,16 @@ "name": "ProductVariantTranslatableContent", "ofType": null }, + { + "kind": "OBJECT", + "name": "PromotionRuleTranslatableContent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionTranslatableContent", + "ofType": null + }, { "kind": "OBJECT", "name": "SaleTranslatableContent", @@ -121692,6 +126677,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "PROMOTION", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "SALE", "description": null, @@ -121990,6 +126987,16 @@ "name": "ProductVariantTranslation", "ofType": null }, + { + "kind": "OBJECT", + "name": "PromotionRuleTranslation", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PromotionTranslation", + "ofType": null + }, { "kind": "OBJECT", "name": "SaleTranslation", @@ -124693,7 +129700,7 @@ }, { "name": "codes", - "description": "List of codes available for this voucher.\n\nAdded in Saleor 3.16.", + "description": "List of codes available for this voucher.\n\nAdded in Saleor 3.18.", "args": [ { "name": "after", @@ -125186,6 +130193,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "singleUse", + "description": "Determine if the voucher is limited to a single use or unlimited use.\n\nAdded in Saleor 3.18.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "startDate", "description": "The start date and time of voucher.", @@ -125249,7 +130272,7 @@ }, { "name": "usageLimit", - "description": "The number of times a voucher can be used.This field will be removed in Saleor 4.0.", + "description": "The number of times a voucher can be used.", "args": [], "type": { "kind": "SCALAR", @@ -125768,7 +130791,7 @@ { "kind": "OBJECT", "name": "VoucherCode", - "description": "Represents voucher code.\n\nAdded in Saleor 3.16.", + "description": "Represents voucher code.\n\nAdded in Saleor 3.18.", "fields": [ { "name": "code", @@ -125783,12 +130806,28 @@ "deprecationReason": null }, { - "name": "usageLimit", - "description": "The number of times a voucher code can be used.", + "name": "id", + "description": "The ID of the voucher code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isActive", + "description": "Whether a code is active or not.", "args": [], "type": { "kind": "SCALAR", - "name": "Int", + "name": "Boolean", "ofType": null }, "isDeprecated": false, @@ -125812,6 +130851,157 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "VoucherCodeBulkDelete", + "description": "Deletes voucher codes.\n\nAdded in Saleor 3.18. \n\nRequires one of the following permissions: MANAGE_DISCOUNTS.\n\nTriggers the following webhook events:\n- VOUCHER_UPDATED (async): A voucher was updated.", + "fields": [ + { + "name": "count", + "description": "Returns how many codes were deleted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "errors", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "VoucherCodeBulkDeleteError", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "VoucherCodeBulkDeleteError", + "description": null, + "fields": [ + { + "name": "code", + "description": "The error code.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "VoucherCodeBulkDeleteErrorCode", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The error message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "path", + "description": "Path to field that caused the error. A value of `null` indicates that the error isn't associated with a particular field.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "voucherCodes", + "description": "List of voucher codes which causes the error.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "VoucherCodeBulkDeleteErrorCode", + "description": "An enumeration.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "GRAPHQL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_FOUND", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, { "kind": "OBJECT", "name": "VoucherCodeCountableConnection", @@ -125921,7 +131111,7 @@ { "kind": "INPUT_OBJECT", "name": "VoucherCodeInput", - "description": "Represents voucher code data.\n\nAdded in Saleor 3.16.", + "description": "Represents voucher code data.\n\nAdded in Saleor 3.18.", "fields": null, "inputFields": [ { @@ -125935,18 +131125,6 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "usageLimit", - "description": "Code usage limit.", - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null } ], "interfaces": null, @@ -126601,7 +131779,7 @@ }, { "name": "codes", - "description": "Codes to use the voucher.\n\nAdded in Saleor 3.16.", + "description": "Codes to use the voucher.\n\nAdded in Saleor 3.18.", "type": { "kind": "LIST", "name": null, @@ -126739,6 +131917,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "singleUse", + "description": "When set to 'True', each voucher is limited to a single use; otherwise, usage remains unrestricted.\n\nAdded in Saleor 3.18.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "startDate", "description": "Start date of the voucher in ISO 8601 format.", @@ -126765,7 +131955,7 @@ }, { "name": "usageLimit", - "description": "Limit number of times this voucher can be used in total.This field will be removed in Saleor 4.0.", + "description": "Limit number of times this voucher can be used in total.", "type": { "kind": "SCALAR", "name": "Int", @@ -126971,7 +132161,7 @@ "enumValues": [ { "name": "CODE", - "description": "Sort vouchers by code.", + "description": "Sort vouchers by code.\n\nDEPRECATED: this field will be removed in Saleor 4.0.", "isDeprecated": false, "deprecationReason": null }, @@ -126987,6 +132177,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "NAME", + "description": "Sort vouchers by name.\n\nAdded in Saleor 3.18.", + "isDeprecated": false, + "deprecationReason": null + }, { "name": "START_DATE", "description": "Sort vouchers by start date.", @@ -127072,7 +132268,7 @@ { "kind": "OBJECT", "name": "VoucherTranslatableContent", - "description": null, + "description": "Represents voucher's original translatable fields and related translations.", "fields": [ { "name": "id", @@ -127229,7 +132425,7 @@ { "kind": "OBJECT", "name": "VoucherTranslation", - "description": null, + "description": "Represents voucher translations.", "fields": [ { "name": "id", @@ -130808,6 +136004,54 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "PROMOTION_CREATED", + "description": "A promotion is created.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_DELETED", + "description": "A promotion is deleted.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_ENDED", + "description": "A promotion is deactivated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_CREATED", + "description": "A promotion rule is created.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_DELETED", + "description": "A promotion rule is deleted.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_UPDATED", + "description": "A promotion rule is updated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_STARTED", + "description": "A promotion is activated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_UPDATED", + "description": "A promotion is updated.", + "isDeprecated": false, + "deprecationReason": null + }, { "name": "SALE_CREATED", "description": "A sale is created.", @@ -131701,6 +136945,54 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "PROMOTION_CREATED", + "description": "A promotion is created.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_DELETED", + "description": "A promotion is deleted.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_ENDED", + "description": "A promotion is deactivated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_CREATED", + "description": "A promotion rule is created.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_DELETED", + "description": "A promotion rule is deleted.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_UPDATED", + "description": "A promotion rule is updated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_STARTED", + "description": "A promotion is activated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_UPDATED", + "description": "A promotion is updated.", + "isDeprecated": false, + "deprecationReason": null + }, { "name": "SALE_CREATED", "description": "A sale is created.", @@ -132683,6 +137975,54 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "PROMOTION_CREATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_DELETED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_ENDED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_CREATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_DELETED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_RULE_UPDATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_STARTED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PROMOTION_UPDATED", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "SALE_CREATED", "description": null, @@ -134347,7 +139687,10 @@ "name": "deprecated", "description": "Marks an element of a GraphQL schema as no longer supported.", "isRepeatable": false, - "locations": ["ENUM_VALUE", "FIELD_DEFINITION"], + "locations": [ + "ENUM_VALUE", + "FIELD_DEFINITION" + ], "args": [ { "name": "reason", @@ -134397,7 +139740,11 @@ "name": "include", "description": "Directs the executor to include this field or fragment only when the `if` argument is true.", "isRepeatable": false, - "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], "args": [ { "name": "if", @@ -134421,7 +139768,11 @@ "name": "skip", "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", "isRepeatable": false, - "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], "args": [ { "name": "if", @@ -134445,7 +139796,12 @@ "name": "webhookEventsInfo", "description": "Webhook events triggered by a specific location.", "isRepeatable": false, - "locations": ["FIELD", "FIELD_DEFINITION", "INPUT_OBJECT", "OBJECT"], + "locations": [ + "FIELD", + "FIELD_DEFINITION", + "INPUT_OBJECT", + "OBJECT" + ], "args": [ { "name": "asyncEvents", @@ -134499,4 +139855,4 @@ } ] } -} +} \ No newline at end of file diff --git a/schema.graphql b/schema.graphql index 72dfa444567..aed768d6fe2 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2398,6 +2398,9 @@ input AttributeSortingInput { field: AttributeSortField! } +""" +Represents attribute's original translatable fields and related translations. +""" type AttributeTranslatableContent implements Node { """Custom attribute of a product.""" attribute: Attribute @deprecated(reason: "This field will be removed in Saleor 4.0. Get model fields from the root level queries.") @@ -2434,6 +2437,7 @@ enum AttributeTranslateErrorCode { REQUIRED } +"""Represents attribute translations.""" type AttributeTranslation implements Node { """The ID of the attribute translation.""" id: ID! @@ -2923,6 +2927,9 @@ input AttributeValueSelectableTypeInput { value: String } +""" +Represents attribute value's original translatable fields and related translations. +""" type AttributeValueTranslatableContent implements Node { """ Associated attribute that can be translated. @@ -2976,6 +2983,7 @@ enum AttributeValueTranslateErrorCode { REQUIRED } +"""Represents attribute value translations.""" type AttributeValueTranslation implements Node { """The ID of the attribute value translation.""" id: ID! @@ -3318,6 +3326,26 @@ input CatalogueInput { variants: [ID!] } +input CataloguePredicateInput { + """List of conditions that must be met.""" + AND: [CataloguePredicateInput!] + + """A list of conditions of which at least one must be met.""" + OR: [CataloguePredicateInput!] + + """Defines the category conditions to be met.""" + categoryPredicate: CategoryWhereInput + + """Defines the collection conditions to be met.""" + collectionPredicate: CollectionWhereInput + + """Defines the product conditions to be met.""" + productPredicate: ProductWhereInput + + """Defines the product variant conditions to be met.""" + variantPredicate: ProductVariantWhereInput +} + """ Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. """ @@ -3683,6 +3711,9 @@ input CategorySortingInput { field: CategorySortField! } +""" +Represents category original translatable fields and related translations. +""" type CategoryTranslatableContent implements Node { """Represents a single category of products.""" category: Category @deprecated(reason: "This field will be removed in Saleor 4.0. Get model fields from the root level queries.") @@ -3731,6 +3762,7 @@ type CategoryTranslate { translationErrors: [TranslationError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.") } +"""Represents category translations.""" type CategoryTranslation implements Node { """ Translated description of the category. @@ -6084,6 +6116,9 @@ input CollectionSortingInput { field: CollectionSortField! } +""" +Represents collection's original translatable fields and related translations. +""" type CollectionTranslatableContent implements Node { """Represents a collection of products.""" collection: Collection @deprecated(reason: "This field will be removed in Saleor 4.0. Get model fields from the root level queries.") @@ -6132,6 +6167,7 @@ type CollectionTranslate { translationErrors: [TranslationError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.") } +"""Represents collection translations.""" type CollectionTranslation implements Node { """ Translated description of the collection. @@ -6940,6 +6976,24 @@ value as specified by """ scalar DateTime +""" +Define the filtering options for date time fields. + +Added in Saleor 3.11. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +input DateTimeFilterInput { + """The value equal to.""" + eq: DateTime + + """The value included in.""" + oneOf: [DateTime!] + + """The value in range.""" + range: DateTimeRangeInput +} + input DateTimeRangeInput { """Start date.""" gte: DateTime @@ -9418,7 +9472,7 @@ type Invoice implements Job & Node & ObjectWithMetadata { createdAt: DateTime! """URL to view an invoice.""" - externalUrl: String + externalUrl: String @deprecated(reason: "This field will be removed in Saleor 4.0. Use `url` field.This field will be removed in 4.0") """The ID of the object.""" id: ID! @@ -9480,7 +9534,9 @@ type Invoice implements Job & Node & ObjectWithMetadata { """Date and time at which invoice was updated.""" updatedAt: DateTime! - """URL to download an invoice.""" + """ + URL to view/download an invoice. This can be an internal URL if the Invoicing Plugin was used or an external URL if it has been provided. + """ url: String } @@ -11247,6 +11303,9 @@ input MenuItemSortingInput { field: MenuItemsSortField! } +""" +Represents menu item's original translatable fields and related translations. +""" type MenuItemTranslatableContent implements Node { """The ID of the menu item translatable content.""" id: ID! @@ -11277,6 +11336,7 @@ type MenuItemTranslate { translationErrors: [TranslationError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.") } +"""Represents menu item translations.""" type MenuItemTranslation implements Node { """The ID of the menu item translation.""" id: ID! @@ -11961,6 +12021,8 @@ type Mutation { attributeTranslate( """Attribute ID or AttributeTranslatableContent ID.""" id: ID! + + """Fields required to update attribute translations.""" input: NameTranslationInput! """Translation language code.""" @@ -12067,6 +12129,8 @@ type Mutation { attributeValueTranslate( """AttributeValue ID or AttributeValueTranslatableContent ID.""" id: ID! + + """Fields required to update attribute value translations.""" input: AttributeValueTranslationInput! """Translation language code.""" @@ -12140,6 +12204,8 @@ type Mutation { categoryTranslate( """Category ID or CategoryTranslatableContent ID.""" id: ID! + + """Fields required to update category translations.""" input: TranslationInput! """Translation language code.""" @@ -12911,6 +12977,8 @@ type Mutation { collectionTranslate( """Collection ID or CollectionTranslatableContent ID.""" id: ID! + + """Fields required to update collection translations.""" input: TranslationInput! """Translation language code.""" @@ -13694,6 +13762,8 @@ type Mutation { menuItemTranslate( """MenuItem ID or MenuItemTranslatableContent ID.""" id: ID! + + """Fields required to update menu item translations.""" input: NameTranslationInput! """Translation language code.""" @@ -14285,6 +14355,8 @@ type Mutation { pageTranslate( """Page ID or PageTranslatableContent ID.""" id: ID! + + """Fields required to update page translations.""" input: PageTranslationInput! """Translation language code.""" @@ -14790,6 +14862,8 @@ type Mutation { productTranslate( """Product ID or ProductTranslatableContent ID.""" id: ID! + + """Fields required to update product translations.""" input: TranslationInput! """Translation language code.""" @@ -15118,6 +15192,8 @@ type Mutation { productVariantTranslate( """ProductVariant ID or ProductVariantTranslatableContent ID.""" id: ID! + + """Fields required to update product variant translations.""" input: NameTranslationInput! """Translation language code.""" @@ -15151,6 +15227,170 @@ type Mutation { sku: String ): ProductVariantUpdate + """ + Deletes promotions. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - PROMOTION_DELETED (async): A promotion was deleted. + """ + promotionBulkDelete( + """List of promotion IDs to delete.""" + ids: [ID!]! + ): PromotionBulkDelete + + """ + Creates a new promotion. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - PROMOTION_CREATED (async): A promotion was created. + - PROMOTION_STARTED (async): Optionally called if promotion was started. + """ + promotionCreate( + """Fields requires to create a promotion.""" + input: PromotionCreateInput! + ): PromotionCreate + + """ + Deletes a promotion. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - PROMOTION_DELETED (async): A promotion was deleted. + """ + promotionDelete( + """The ID of the promotion to remove.""" + id: ID! + ): PromotionDelete + + """ + Creates a new promotion rule. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - PROMOTION_RULE_CREATED (async): A promotion rule was created. + """ + promotionRuleCreate( + """Fields required to create a promotion rule.""" + input: PromotionRuleCreateInput! + ): PromotionRuleCreate + + """ + Deletes a promotion rule. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - PROMOTION_RULE_DELETED (async): A promotion rule was deleted. + """ + promotionRuleDelete( + """The ID of the promotion to remove.""" + id: ID! + ): PromotionRuleDelete + + """ + Creates/updates translations for a promotion rule. + + Added in Saleor 3.17. + + Requires one of the following permissions: MANAGE_TRANSLATIONS. + """ + promotionRuleTranslate( + """PromotionRule ID or PromotionRuleTranslatableContent ID.""" + id: ID! + + """Fields required to update promotion rule translations.""" + input: PromotionRuleTranslationInput! + + """Translation language code.""" + languageCode: LanguageCodeEnum! + ): PromotionRuleTranslate + + """ + Updates an existing promotion rule. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - PROMOTION_RULE_UPDATED (async): A promotion rule was updated. + """ + promotionRuleUpdate( + """ID of the promotion rule to update.""" + id: ID! + + """Fields required to create a promotion rule.""" + input: PromotionRuleUpdateInput! + ): PromotionRuleUpdate + + """ + Creates/updates translations for a promotion. + + Added in Saleor 3.17. + + Requires one of the following permissions: MANAGE_TRANSLATIONS. + """ + promotionTranslate( + """Promotion ID or PromotionTranslatableContent ID.""" + id: ID! + + """Fields required to update promotion translations.""" + input: PromotionTranslationInput! + + """Translation language code.""" + languageCode: LanguageCodeEnum! + ): PromotionTranslate + + """ + Updates an existing promotion. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - PROMOTION_UPDATED (async): A promotion was updated. + - PROMOTION_STARTED (async): Optionally called if promotion was started. + - PROMOTION_ENDED (async): Optionally called if promotion was ended. + """ + promotionUpdate( + """ID of the promotion to update.""" + id: ID! + + """Fields required to update a promotion.""" + input: PromotionUpdateInput! + ): PromotionUpdate + """ Request email change of the logged in user. @@ -15215,7 +15455,9 @@ type Mutation { ): SaleBulkDelete """ - Adds products, categories, collections to a voucher. + Adds products, categories, collections to a sale. + + DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -15231,7 +15473,9 @@ type Mutation { ): SaleAddCatalogues """ - Removes products, categories, collections from a sale. + Removes products, categories, collections from a sale. + + DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleUpdate` or `promotionRuleDelete` mutations instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -15247,7 +15491,9 @@ type Mutation { ): SaleRemoveCatalogues """ - Manage sale's availability in channels. + Manage sale's availability in channels. + + DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` or `promotionRuleUpdate` mutations instead. Requires one of the following permissions: MANAGE_DISCOUNTS. """ @@ -15260,7 +15506,9 @@ type Mutation { ): SaleChannelListingUpdate """ - Creates a new sale. + Creates a new sale. + + DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionCreate` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -15273,7 +15521,9 @@ type Mutation { ): SaleCreate """ - Deletes a sale. + Deletes a sale. + + DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionDelete` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -15286,13 +15536,17 @@ type Mutation { ): SaleDelete """ - Creates/updates translations for a sale. + Creates/updates translations for a sale. + + DEPRECATED: this mutation will be removed in Saleor 4.0. Use `PromotionTranslate` mutation instead. Requires one of the following permissions: MANAGE_TRANSLATIONS. """ saleTranslate( """Sale ID or SaleTranslatableContent ID.""" id: ID! + + """Fields required to update sale translations.""" input: NameTranslationInput! """Translation language code.""" @@ -15300,7 +15554,9 @@ type Mutation { ): SaleTranslate """ - Updates a sale. + Updates a sale. + + DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionUpdate` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -15428,6 +15684,8 @@ type Mutation { shippingPriceTranslate( """ShippingMethodType ID or ShippingMethodTranslatableContent ID.""" id: ID! + + """Fields required to update shipping price translations.""" input: ShippingPriceTranslationInput! """Translation language code.""" @@ -16156,6 +16414,21 @@ type Mutation { input: VoucherChannelListingInput! ): VoucherChannelListingUpdate + """ + Deletes voucher codes. + + Added in Saleor 3.18. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + + Triggers the following webhook events: + - VOUCHER_UPDATED (async): A voucher was updated. + """ + voucherCodeBulkDelete( + """List of voucher codes IDs to delete.""" + ids: [ID!]! + ): VoucherCodeBulkDelete + """ Creates a new voucher. @@ -16190,6 +16463,8 @@ type Mutation { voucherTranslate( """Voucher ID or VoucherTranslatableContent ID.""" id: ID! + + """Fields required to update voucher translations.""" input: NameTranslationInput! """Translation language code.""" @@ -17412,6 +17687,7 @@ type OrderDiscountDelete { """An enumeration.""" enum OrderDiscountType { MANUAL + PROMOTION SALE VOUCHER } @@ -19470,6 +19746,9 @@ input PageSortingInput { field: PageSortField! } +""" +Represents page's original translatable fields and related translations. +""" type PageTranslatableContent implements Node { """List of page content attribute values that can be translated.""" attributeValues: [AttributeValueTranslatableContent!]! @@ -19523,6 +19802,7 @@ type PageTranslate { translationErrors: [TranslationError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.") } +"""Represents page translations.""" type PageTranslation implements Node { """ Translated content of the page. @@ -20466,19 +20746,6 @@ type PaymentListGateways implements Event { version: String } -type PaymentMethodRequestDeleteError { - """The error code.""" - code: StoredPaymentMethodRequestDeleteErrorCode! - - """ - Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. - """ - field: String - - """The error message.""" - message: String -} - """ Tokenize payment method. @@ -22796,6 +23063,9 @@ input ProductStockFilterInput { warehouseIds: [ID!] } +""" +Represents product's original translatable fields and related translations. +""" type ProductTranslatableContent implements Node { """List of product attribute values that can be translated.""" attributeValues: [AttributeValueTranslatableContent!]! @@ -22855,6 +23125,7 @@ enum ProductTranslateErrorCode { REQUIRED } +"""Represents product translations.""" type ProductTranslation implements Node { """ Translated description of the product. @@ -24244,6 +24515,9 @@ input ProductVariantStocksUpdateInput { update: [StockUpdateInput!] } +""" +Represents product variant's original translatable fields and related translations. +""" type ProductVariantTranslatableContent implements Node { """List of product variant attribute values that can be translated.""" attributeValues: [AttributeValueTranslatableContent!]! @@ -24283,6 +24557,7 @@ enum ProductVariantTranslateErrorCode { REQUIRED } +"""Represents product variant translations.""" type ProductVariantTranslation implements Node { """The ID of the product variant translation.""" id: ID! @@ -24404,58 +24679,1157 @@ input ProductWhereInput { stocks: ProductStockFilterInput """Filter by when was the most recent update.""" - updatedAt: DateTimeRangeInput + updatedAt: DateTimeFilterInput } -input PublishableChannelListingInput { - """ID of a channel.""" - channelId: ID! +""" +Represents the promotion that allow creating discounts based on given conditions, and is visible to all the customers. - """Determines if object is visible to customers.""" - isPublished: Boolean +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type Promotion implements Node & ObjectWithMetadata { + """Date time of promotion creation.""" + createdAt: DateTime! + + """Description of the promotion.""" + description: JSON + + """End date of the promotion.""" + endDate: DateTime + + """The list of events associated with the promotion.""" + events: [PromotionEvent!] + id: ID! + + """List of public metadata items. Can be accessed without permissions.""" + metadata: [MetadataItem!]! """ - Publication date. ISO 8601 standard. + A single key from public metadata. - DEPRECATED: this field will be removed in Saleor 4.0. Use `publishedAt` field instead. + Tip: Use GraphQL aliases to fetch multiple keys. + + Added in Saleor 3.3. """ - publicationDate: Date + metafield(key: String!): String """ - Publication date time. ISO 8601 standard. + Public metadata. Use `keys` to control which fields you want to include. The default is to include everything. Added in Saleor 3.3. """ - publishedAt: DateTime -} + metafields(keys: [String!]): Metadata -type Query { - _entities(representations: [_Any]): [_Entity] - _service: _Service + """Name of the promotion.""" + name: String! + + """List of private metadata items. Requires staff permissions to access.""" + privateMetadata: [MetadataItem!]! """ - Look up an address by ID. + A single key from private metadata. Requires staff permissions to access. - Requires one of the following permissions: MANAGE_USERS, OWNER. + Tip: Use GraphQL aliases to fetch multiple keys. + + Added in Saleor 3.3. """ - address( - """ID of an address.""" - id: ID! - ): Address + privateMetafield(key: String!): String - """Returns address validation rules.""" - addressValidationRules( - """City or a town name.""" - city: String + """ + Private metadata. Requires staff permissions to access. Use `keys` to control which fields you want to include. The default is to include everything. + + Added in Saleor 3.3. + """ + privateMetafields(keys: [String!]): Metadata - """Sublocality like a district.""" - cityArea: String + """The list of promotion rules.""" + rules: [PromotionRule!] - """Designation of a region, province or state.""" - countryArea: String + """Start date of the promotion.""" + startDate: DateTime! - """Two-letter ISO 3166-1 country code.""" - countryCode: CountryCode! + """Returns translated promotion fields for the given language code.""" + translation( + """A language code to return the translation for promotion.""" + languageCode: LanguageCodeEnum! + ): PromotionTranslation + + """Date time of last update of promotion.""" + updatedAt: DateTime! +} + +""" +Deletes promotions. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- PROMOTION_DELETED (async): A promotion was deleted. +""" +type PromotionBulkDelete { + """Returns how many objects were affected.""" + count: Int! + errors: [DiscountError!]! +} + +type PromotionCountableConnection { + edges: [PromotionCountableEdge!]! + + """Pagination data for this connection.""" + pageInfo: PageInfo! + + """A total count of items in the collection.""" + totalCount: Int +} + +type PromotionCountableEdge { + """A cursor for use in pagination.""" + cursor: String! + + """The item at the end of the edge.""" + node: Promotion! +} + +""" +Creates a new promotion. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- PROMOTION_CREATED (async): A promotion was created. +- PROMOTION_STARTED (async): Optionally called if promotion was started. +""" +type PromotionCreate { + errors: [PromotionCreateError!]! + promotion: Promotion +} + +type PromotionCreateError { + """The error code.""" + code: PromotionCreateErrorCode! + + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """Index of an input list item that caused the error.""" + index: Int + + """The error message.""" + message: String +} + +"""An enumeration.""" +enum PromotionCreateErrorCode { + GRAPHQL_ERROR + INVALID + INVALID_PRECISION + MULTIPLE_CURRENCIES_NOT_ALLOWED + NOT_FOUND + REQUIRED +} + +input PromotionCreateInput { + """Promotion description.""" + description: JSON + + """The end date of the promotion in ISO 8601 format.""" + endDate: DateTime + + """Promotion name.""" + name: String! + + """List of promotion rules.""" + rules: [PromotionRuleInput!] + + """The start date of the promotion in ISO 8601 format.""" + startDate: DateTime +} + +""" +Event sent when new promotion is created. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionCreated implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion the event relates to.""" + promotion: Promotion + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +History log of the promotion created event. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionCreatedEvent implements Node & PromotionEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +""" +Deletes a promotion. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- PROMOTION_DELETED (async): A promotion was deleted. +""" +type PromotionDelete { + errors: [PromotionDeleteError!]! + promotion: Promotion +} + +type PromotionDeleteError { + """The error code.""" + code: PromotionDeleteErrorCode! + + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """The error message.""" + message: String +} + +"""An enumeration.""" +enum PromotionDeleteErrorCode { + GRAPHQL_ERROR + NOT_FOUND +} + +""" +Event sent when promotion is deleted. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionDeleted implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion the event relates to.""" + promotion: Promotion + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +The event informs about the end of the promotion. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionEnded implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion the event relates to.""" + promotion: Promotion + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +History log of the promotion ended event. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionEndedEvent implements Node & PromotionEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +union PromotionEvent = PromotionCreatedEvent | PromotionEndedEvent | PromotionRuleCreatedEvent | PromotionRuleDeletedEvent | PromotionRuleUpdatedEvent | PromotionStartedEvent | PromotionUpdatedEvent + +interface PromotionEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +"""An enumeration.""" +enum PromotionEventsEnum { + PROMOTION_CREATED + PROMOTION_ENDED + PROMOTION_STARTED + PROMOTION_UPDATED + RULE_CREATED + RULE_DELETED + RULE_UPDATED +} + +""" +Represents the promotion rule that specifies the conditions that must be met to apply the promotion discount. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionRule implements Node { + """The catalogue predicate that must be met to apply the rule reward.""" + cataloguePredicate: JSON + + """ + List of channels where the rule applies. + + Requires one of the following permissions: AUTHENTICATED_APP, AUTHENTICATED_STAFF_USER. + """ + channels: [Channel!] + + """Description of the promotion rule.""" + description: JSON + id: ID! + + """Name of the promotion rule.""" + name: String + + """Promotion to which the rule belongs.""" + promotion: Promotion + + """ + The reward value of the promotion rule. Defines the discount value applied when the rule conditions are met. + """ + rewardValue: PositiveDecimal + + """The type of reward value of the promotion rule.""" + rewardValueType: RewardValueTypeEnum + + """Returns translated promotion rule fields for the given language code.""" + translation( + """A language code to return the translation for promotion rule.""" + languageCode: LanguageCodeEnum! + ): PromotionRuleTranslation +} + +""" +Creates a new promotion rule. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- PROMOTION_RULE_CREATED (async): A promotion rule was created. +""" +type PromotionRuleCreate { + errors: [PromotionRuleCreateError!]! + promotionRule: PromotionRule +} + +type PromotionRuleCreateError { + """The error code.""" + code: PromotionRuleCreateErrorCode! + + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """The error message.""" + message: String +} + +"""An enumeration.""" +enum PromotionRuleCreateErrorCode { + GRAPHQL_ERROR + INVALID + INVALID_PRECISION + MULTIPLE_CURRENCIES_NOT_ALLOWED + NOT_FOUND + REQUIRED +} + +input PromotionRuleCreateInput { + """ + Defines the conditions on the catalogue level that must be met for the reward to be applied. + """ + cataloguePredicate: CataloguePredicateInput + + """List of channel ids to which the rule should apply to.""" + channels: [ID!] + + """Promotion rule description.""" + description: JSON + + """Promotion rule name.""" + name: String + + """The ID of the promotion that rule belongs to.""" + promotion: ID! + + """ + Defines the discount value. Required when catalogue predicate is provided. + """ + rewardValue: PositiveDecimal + + """ + Defines the promotion rule reward value type. Must be provided together with reward value. + """ + rewardValueType: RewardValueTypeEnum +} + +""" +Event sent when new promotion rule is created. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionRuleCreated implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion rule the event relates to.""" + promotionRule: PromotionRule + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +History log of the promotion rule created event. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionRuleCreatedEvent implements Node & PromotionEventInterface & PromotionRuleEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """The rule ID associated with the promotion event.""" + ruleId: String + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +""" +Deletes a promotion rule. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- PROMOTION_RULE_DELETED (async): A promotion rule was deleted. +""" +type PromotionRuleDelete { + errors: [PromotionRuleDeleteError!]! + promotionRule: PromotionRule +} + +type PromotionRuleDeleteError { + """The error code.""" + code: PromotionRuleDeleteErrorCode! + + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """The error message.""" + message: String +} + +"""An enumeration.""" +enum PromotionRuleDeleteErrorCode { + GRAPHQL_ERROR + NOT_FOUND +} + +""" +Event sent when new promotion rule is deleted. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionRuleDeleted implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion rule the event relates to.""" + promotionRule: PromotionRule + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +History log of the promotion rule created event. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionRuleDeletedEvent implements Node & PromotionEventInterface & PromotionRuleEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """The rule ID associated with the promotion event.""" + ruleId: String + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +""" +History log of the promotion event related to rule. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +interface PromotionRuleEventInterface { + """The rule ID associated with the promotion event.""" + ruleId: String +} + +input PromotionRuleInput { + """ + Defines the conditions on the catalogue level that must be met for the reward to be applied. + """ + cataloguePredicate: CataloguePredicateInput + + """List of channel ids to which the rule should apply to.""" + channels: [ID!] + + """Promotion rule description.""" + description: JSON + + """Promotion rule name.""" + name: String + + """ + Defines the discount value. Required when catalogue predicate is provided. + """ + rewardValue: PositiveDecimal + + """ + Defines the promotion rule reward value type. Must be provided together with reward value. + """ + rewardValueType: RewardValueTypeEnum +} + +""" +Represents promotion rule's original translatable fields and related translations. + +Added in Saleor 3.17. +""" +type PromotionRuleTranslatableContent implements Node { + """ + Description of the promotion rule. + + Rich text format. For reference see https://editorjs.io/ + """ + description: JSONString + + """ID of the promotion rule translatable content.""" + id: ID! + + """Name of the promotion rule.""" + name: String + + """Returns translated promotion rule fields for the given language code.""" + translation( + """A language code to return the translation for promotion rule.""" + languageCode: LanguageCodeEnum! + ): PromotionRuleTranslation +} + +""" +Creates/updates translations for a promotion rule. + +Added in Saleor 3.17. + +Requires one of the following permissions: MANAGE_TRANSLATIONS. +""" +type PromotionRuleTranslate { + errors: [TranslationError!]! + promotionRule: PromotionRule +} + +""" +Represents promotion rule translations. + +Added in Saleor 3.17. +""" +type PromotionRuleTranslation implements Node { + """ + Translated description of the promotion rule. + + Rich text format. For reference see https://editorjs.io/ + """ + description: JSONString + + """ID of the promotion rule translation.""" + id: ID! + + """Translation language.""" + language: LanguageDisplay! + + """Translated name of the promotion rule.""" + name: String +} + +input PromotionRuleTranslationInput { + """ + Translated promotion description. + + Rich text format. For reference see https://editorjs.io/ + """ + description: JSON + name: String +} + +""" +Updates an existing promotion rule. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- PROMOTION_RULE_UPDATED (async): A promotion rule was updated. +""" +type PromotionRuleUpdate { + errors: [PromotionRuleUpdateError!]! + promotionRule: PromotionRule +} + +type PromotionRuleUpdateError { + """List of channel IDs which causes the error.""" + channels: [ID!] + + """The error code.""" + code: PromotionRuleUpdateErrorCode! + + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """The error message.""" + message: String +} + +"""An enumeration.""" +enum PromotionRuleUpdateErrorCode { + DUPLICATED_INPUT_ITEM + GRAPHQL_ERROR + INVALID + INVALID_PRECISION + MISSING_CHANNELS + MULTIPLE_CURRENCIES_NOT_ALLOWED + NOT_FOUND +} + +input PromotionRuleUpdateInput { + """List of channel ids to remove.""" + addChannels: [ID!] + + """ + Defines the conditions on the catalogue level that must be met for the reward to be applied. + """ + cataloguePredicate: CataloguePredicateInput + + """Promotion rule description.""" + description: JSON + + """Promotion rule name.""" + name: String + + """List of channel ids to remove.""" + removeChannels: [ID!] + + """ + Defines the discount value. Required when catalogue predicate is provided. + """ + rewardValue: PositiveDecimal + + """ + Defines the promotion rule reward value type. Must be provided together with reward value. + """ + rewardValueType: RewardValueTypeEnum +} + +""" +Event sent when new promotion rule is updated. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionRuleUpdated implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion rule the event relates to.""" + promotionRule: PromotionRule + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +History log of the promotion rule created event. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionRuleUpdatedEvent implements Node & PromotionEventInterface & PromotionRuleEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """The rule ID associated with the promotion event.""" + ruleId: String + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +enum PromotionSortField { + """Sort promotions by created at.""" + CREATED_AT + + """Sort promotions by end date.""" + END_DATE + + """Sort promotions by name.""" + NAME + + """Sort promotions by start date.""" + START_DATE +} + +input PromotionSortingInput { + """Specifies the direction in which to sort promotions.""" + direction: OrderDirection! + + """Sort promotions by the selected field.""" + field: PromotionSortField! +} + +""" +The event informs about the start of the promotion. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionStarted implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion the event relates to.""" + promotion: Promotion + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +History log of the promotion started event. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionStartedEvent implements Node & PromotionEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +""" +Represents promotion's original translatable fields and related translations. + +Added in Saleor 3.17. +""" +type PromotionTranslatableContent implements Node { + """ + Description of the promotion. + + Rich text format. For reference see https://editorjs.io/ + """ + description: JSONString + + """ID of the promotion translatable content.""" + id: ID! + + """Name of the promotion.""" + name: String! + + """Returns translated promotion fields for the given language code.""" + translation( + """A language code to return the translation for promotion.""" + languageCode: LanguageCodeEnum! + ): PromotionTranslation +} + +""" +Creates/updates translations for a promotion. + +Added in Saleor 3.17. + +Requires one of the following permissions: MANAGE_TRANSLATIONS. +""" +type PromotionTranslate { + errors: [TranslationError!]! + promotion: Promotion +} + +""" +Represents promotion translations. + +Added in Saleor 3.17. +""" +type PromotionTranslation implements Node { + """ + Translated description of the promotion. + + Rich text format. For reference see https://editorjs.io/ + """ + description: JSONString + + """ID of the promotion translation.""" + id: ID! + + """Translation language.""" + language: LanguageDisplay! + + """Translated name of the promotion.""" + name: String +} + +input PromotionTranslationInput { + """ + Translated promotion description. + + Rich text format. For reference see https://editorjs.io/ + """ + description: JSON + name: String +} + +""" +Updates an existing promotion. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- PROMOTION_UPDATED (async): A promotion was updated. +- PROMOTION_STARTED (async): Optionally called if promotion was started. +- PROMOTION_ENDED (async): Optionally called if promotion was ended. +""" +type PromotionUpdate { + errors: [PromotionUpdateError!]! + promotion: Promotion +} + +type PromotionUpdateError { + """The error code.""" + code: PromotionUpdateErrorCode! + + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """The error message.""" + message: String +} + +"""An enumeration.""" +enum PromotionUpdateErrorCode { + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED +} + +input PromotionUpdateInput { + """Promotion description.""" + description: JSON + + """The end date of the promotion in ISO 8601 format.""" + endDate: DateTime + + """Promotion name.""" + name: String + + """The start date of the promotion in ISO 8601 format.""" + startDate: DateTime +} + +""" +Event sent when promotion is updated. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionUpdated implements Event { + """Time of the event.""" + issuedAt: DateTime + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The promotion the event relates to.""" + promotion: Promotion + + """The application receiving the webhook.""" + recipient: App + + """Saleor version that triggered the event.""" + version: String +} + +""" +History log of the promotion updated event. + +Added in Saleor 3.17. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type PromotionUpdatedEvent implements Node & PromotionEventInterface { + """ + User or App that created the promotion event. + + Requires one of the following permissions: MANAGE_STAFF, MANAGE_APPS, OWNER. + """ + createdBy: UserOrApp + + """Date when event happened.""" + date: DateTime! + id: ID! + + """Promotion event type.""" + type: PromotionEventsEnum! +} + +input PromotionWhereInput { + """List of conditions that must be met.""" + AND: [PromotionWhereInput!] + + """A list of conditions of which at least one must be met.""" + OR: [PromotionWhereInput!] + + """Filter promotions by end date.""" + endDate: DateTimeFilterInput + ids: [ID!] + isOldSale: Boolean + metadata: [MetadataFilter!] + + """Filter by promotion name.""" + name: StringFilterInput + + """Filter promotions by start date.""" + startDate: DateTimeFilterInput +} + +input PublishableChannelListingInput { + """ID of a channel.""" + channelId: ID! + + """Determines if object is visible to customers.""" + isPublished: Boolean + + """ + Publication date. ISO 8601 standard. + + DEPRECATED: this field will be removed in Saleor 4.0. Use `publishedAt` field instead. + """ + publicationDate: Date + + """ + Publication date time. ISO 8601 standard. + + Added in Saleor 3.3. + """ + publishedAt: DateTime +} + +type Query { + _entities(representations: [_Any]): [_Entity] + _service: _Service + + """ + Look up an address by ID. + + Requires one of the following permissions: MANAGE_USERS, OWNER. + """ + address( + """ID of an address.""" + id: ID! + ): Address + + """Returns address validation rules.""" + addressValidationRules( + """City or a town name.""" + city: String + + """Sublocality like a district.""" + cityArea: String + + """Designation of a region, province or state.""" + countryArea: String + + """Two-letter ISO 3166-1 country code.""" + countryCode: CountryCode! ): AddressValidationData """ @@ -25558,6 +26932,53 @@ type Query { where: ProductWhereInput ): ProductCountableConnection + """ + Look up a promotion by ID. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + """ + promotion( + """ID of the promotion.""" + id: ID! + ): Promotion + + """ + List of the promotions. + + Added in Saleor 3.17. + + Note: this API is currently in Feature Preview and can be subject to changes at later point. + + Requires one of the following permissions: MANAGE_DISCOUNTS. + """ + promotions( + """Return the elements in the list that come after the specified cursor.""" + after: String + + """Return the elements in the list that come before the specified cursor.""" + before: String + + """ + Retrieve the first n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query. + """ + first: Int + + """ + Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query. + """ + last: Int + + """Sort promotions.""" + sortBy: PromotionSortingInput + + """Where filtering options.""" + where: PromotionWhereInput + ): PromotionCountableConnection + """ List of top selling products. @@ -25598,7 +27019,7 @@ type Query { """ID of the sale.""" id: ID! - ): Sale + ): Sale @deprecated(reason: "This field will be removed in Saleor 4.0. Use the `promotion` query instead.") """ List of the shop's sales. @@ -25637,7 +27058,7 @@ type Query { """Sort sales.""" sortBy: SaleSortingInput - ): SaleCountableConnection + ): SaleCountableConnection @deprecated(reason: "This field will be removed in Saleor 4.0. Use the `promotions` query instead.") """ Look up a shipping zone by ID. @@ -26109,8 +27530,16 @@ type RequestPasswordReset { errors: [AccountError!]! } +"""An enumeration.""" +enum RewardValueTypeEnum { + FIXED + PERCENTAGE +} + """ Sales allow creating discounts for categories, collections or products and are visible to all the customers. + +DEPRECATED: this type will be removed in Saleor 4.0. Use `Promotion` type instead. """ type Sale implements Node & ObjectWithMetadata { """List of categories this sale applies to.""" @@ -26283,7 +27712,9 @@ type Sale implements Node & ObjectWithMetadata { } """ -Adds products, categories, collections to a voucher. +Adds products, categories, collections to a sale. + +DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -26313,7 +27744,11 @@ type SaleBulkDelete { errors: [DiscountError!]! } -"""Represents sale channel listing.""" +""" +Represents sale channel listing. + +DEPRECATED: this type will be removed in Saleor 4.0. Use `PromotionRule` type instead. +""" type SaleChannelListing implements Node { """The channel in which the sale is available.""" channel: Channel! @@ -26345,7 +27780,9 @@ input SaleChannelListingInput { } """ -Manage sale's availability in channels. +Manage sale's availability in channels. + +DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleCreate` or `promotionRuleUpdate` mutations instead. Requires one of the following permissions: MANAGE_DISCOUNTS. """ @@ -26376,7 +27813,9 @@ type SaleCountableEdge { } """ -Creates a new sale. +Creates a new sale. + +DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionCreate` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -26393,6 +27832,8 @@ type SaleCreate { Event sent when new sale is created. Added in Saleor 3.2. + +DEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionCreated` event instead. """ type SaleCreated implements Event { """Time of the event.""" @@ -26415,7 +27856,9 @@ type SaleCreated implements Event { } """ -Deletes a sale. +Deletes a sale. + +DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionDelete` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -26432,6 +27875,8 @@ type SaleDelete { Event sent when sale is deleted. Added in Saleor 3.2. + +DEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionDeleted` event instead. """ type SaleDeleted implements Event { """Time of the event.""" @@ -26490,7 +27935,9 @@ input SaleInput { } """ -Removes products, categories, collections from a sale. +Removes products, categories, collections from a sale. + +DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionRuleUpdate` or `promotionRuleDelete` mutations instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -26551,6 +27998,8 @@ input SaleSortingInput { The event informs about the start or end of the sale. Added in Saleor 3.5. + +DEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionStarted` and `PromotionEnded` events instead. """ type SaleToggle implements Event { """Time of the event.""" @@ -26576,6 +28025,11 @@ type SaleToggle implements Event { version: String } +""" +Represents sale's original translatable fields and related translations. + +DEPRECATED: this type will be removed in Saleor 4.0. Use `PromotionTranslatableContent` instead. +""" type SaleTranslatableContent implements Node { """The ID of the sale translatable content.""" id: ID! @@ -26598,7 +28052,9 @@ type SaleTranslatableContent implements Node { } """ -Creates/updates translations for a sale. +Creates/updates translations for a sale. + +DEPRECATED: this mutation will be removed in Saleor 4.0. Use `PromotionTranslate` mutation instead. Requires one of the following permissions: MANAGE_TRANSLATIONS. """ @@ -26608,6 +28064,11 @@ type SaleTranslate { translationErrors: [TranslationError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.") } +""" +Represents sale translations. + +DEPRECATED: this type will be removed in Saleor 4.0. Use `PromotionTranslation` instead. +""" type SaleTranslation implements Node { """The ID of the sale translation.""" id: ID! @@ -26625,7 +28086,9 @@ enum SaleType { } """ -Updates a sale. +Updates a sale. + +DEPRECATED: this mutation will be removed in Saleor 4.0. Use `promotionUpdate` mutation instead. Requires one of the following permissions: MANAGE_DISCOUNTS. @@ -26643,6 +28106,8 @@ type SaleUpdate { Event sent when sale is updated. Added in Saleor 3.2. + +DEPRECATED: this event will be removed in Saleor 4.0. Use `PromotionUpdated` event instead. """ type SaleUpdated implements Event { """Time of the event.""" @@ -26951,6 +28416,9 @@ type ShippingMethodPostalCodeRule implements Node { start: String } +""" +Represents shipping method's original translatable fields and related translations. +""" type ShippingMethodTranslatableContent implements Node { """ Shipping method description to translate. @@ -26979,6 +28447,7 @@ type ShippingMethodTranslatableContent implements Node { ): ShippingMethodTranslation } +"""Represents shipping method translations.""" type ShippingMethodTranslation implements Node { """ Translated description of the shipping method. @@ -28179,6 +29648,7 @@ type ShopSettingsUpdate { shopErrors: [ShopError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.") } +"""Represents shop translations.""" type ShopTranslation implements Node { """Translated description of sale.""" description: String! @@ -30587,7 +32057,7 @@ input TransactionUpdateInput { pspReference: String } -union TranslatableItem = AttributeTranslatableContent | AttributeValueTranslatableContent | CategoryTranslatableContent | CollectionTranslatableContent | MenuItemTranslatableContent | PageTranslatableContent | ProductTranslatableContent | ProductVariantTranslatableContent | SaleTranslatableContent | ShippingMethodTranslatableContent | VoucherTranslatableContent +union TranslatableItem = AttributeTranslatableContent | AttributeValueTranslatableContent | CategoryTranslatableContent | CollectionTranslatableContent | MenuItemTranslatableContent | PageTranslatableContent | ProductTranslatableContent | ProductVariantTranslatableContent | PromotionRuleTranslatableContent | PromotionTranslatableContent | SaleTranslatableContent | ShippingMethodTranslatableContent | VoucherTranslatableContent type TranslatableItemConnection { edges: [TranslatableItemEdge!]! @@ -30615,6 +32085,8 @@ enum TranslatableKinds { MENU_ITEM PAGE PRODUCT + PROMOTION + PROMOTION_RULE SALE SHIPPING_METHOD VARIANT @@ -30676,7 +32148,7 @@ input TranslationInput { seoTitle: String } -union TranslationTypes = AttributeTranslation | AttributeValueTranslation | CategoryTranslation | CollectionTranslation | MenuItemTranslation | PageTranslation | ProductTranslation | ProductVariantTranslation | SaleTranslation | ShippingMethodTranslation | VoucherTranslation +union TranslationTypes = AttributeTranslation | AttributeValueTranslation | CategoryTranslation | CollectionTranslation | MenuItemTranslation | PageTranslation | ProductTranslation | ProductVariantTranslation | PromotionRuleTranslation | PromotionTranslation | SaleTranslation | ShippingMethodTranslation | VoucherTranslation """ Event sent when translation is updated. @@ -31323,7 +32795,7 @@ type Voucher implements Node & ObjectWithMetadata { """ List of codes available for this voucher. - Added in Saleor 3.16. + Added in Saleor 3.18. """ codes( """Return the elements in the list that come after the specified cursor.""" @@ -31457,6 +32929,13 @@ type Voucher implements Node & ObjectWithMetadata { last: Int ): ProductCountableConnection + """ + Determine if the voucher is limited to a single use or unlimited use. + + Added in Saleor 3.18. + """ + singleUse: Boolean! + """The start date and time of voucher.""" startDate: DateTime! @@ -31469,9 +32948,7 @@ type Voucher implements Node & ObjectWithMetadata { """Determines a type of voucher.""" type: VoucherTypeEnum! - """ - The number of times a voucher can be used.This field will be removed in Saleor 4.0. - """ + """The number of times a voucher can be used.""" usageLimit: Int """Usage count of the voucher.This field will be removed in Saleor 4.0.""" @@ -31590,19 +33067,61 @@ type VoucherChannelListingUpdate { """ Represents voucher code. -Added in Saleor 3.16. +Added in Saleor 3.18. """ type VoucherCode { """Code to use the voucher.""" code: String - """The number of times a voucher code can be used.""" - usageLimit: Int + """The ID of the voucher code.""" + id: ID! + + """Whether a code is active or not.""" + isActive: Boolean """Number of times a code has been used.""" used: Int } +""" +Deletes voucher codes. + +Added in Saleor 3.18. + +Requires one of the following permissions: MANAGE_DISCOUNTS. + +Triggers the following webhook events: +- VOUCHER_UPDATED (async): A voucher was updated. +""" +type VoucherCodeBulkDelete { + """Returns how many codes were deleted.""" + count: Int! + errors: [VoucherCodeBulkDeleteError!]! +} + +type VoucherCodeBulkDeleteError { + """The error code.""" + code: VoucherCodeBulkDeleteErrorCode! + + """The error message.""" + message: String + + """ + Path to field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + path: String + + """List of voucher codes which causes the error.""" + voucherCodes: [ID!] +} + +"""An enumeration.""" +enum VoucherCodeBulkDeleteErrorCode { + GRAPHQL_ERROR + INVALID + NOT_FOUND +} + type VoucherCodeCountableConnection { edges: [VoucherCodeCountableEdge!]! @@ -31624,14 +33143,11 @@ type VoucherCodeCountableEdge { """ Represents voucher code data. -Added in Saleor 3.16. +Added in Saleor 3.18. """ input VoucherCodeInput { """Code to use the voucher.""" code: String - - """Code usage limit.""" - usageLimit: Int } type VoucherCountableConnection { @@ -31762,7 +33278,7 @@ input VoucherInput { """ Codes to use the voucher. - Added in Saleor 3.16. + Added in Saleor 3.18. """ codes: [VoucherCodeInput!] @@ -31790,15 +33306,20 @@ input VoucherInput { """Products discounted by the voucher.""" products: [ID!] + """ + When set to 'True', each voucher is limited to a single use; otherwise, usage remains unrestricted. + + Added in Saleor 3.18. + """ + singleUse: Boolean + """Start date of the voucher in ISO 8601 format.""" startDate: DateTime """Voucher type: PRODUCT, CATEGORY SHIPPING or ENTIRE_ORDER.""" type: VoucherTypeEnum - """ - Limit number of times this voucher can be used in total.This field will be removed in Saleor 4.0. - """ + """Limit number of times this voucher can be used in total.""" usageLimit: Int """ @@ -31851,7 +33372,11 @@ type VoucherRemoveCatalogues { } enum VoucherSortField { - """Sort vouchers by code.""" + """ + Sort vouchers by code. + + DEPRECATED: this field will be removed in Saleor 4.0. + """ CODE """Sort vouchers by end date.""" @@ -31864,6 +33389,13 @@ enum VoucherSortField { """ MINIMUM_SPENT_AMOUNT + """ + Sort vouchers by name. + + Added in Saleor 3.18. + """ + NAME + """Sort vouchers by start date.""" START_DATE @@ -31896,6 +33428,9 @@ input VoucherSortingInput { field: VoucherSortField! } +""" +Represents voucher's original translatable fields and related translations. +""" type VoucherTranslatableContent implements Node { """The ID of the voucher translatable content.""" id: ID! @@ -31928,6 +33463,7 @@ type VoucherTranslate { voucher: Voucher } +"""Represents voucher translations.""" type VoucherTranslation implements Node { """The ID of the voucher translation.""" id: ID! @@ -32999,6 +34535,30 @@ enum WebhookEventTypeAsyncEnum { """A product variant is updated.""" PRODUCT_VARIANT_UPDATED + """A promotion is created.""" + PROMOTION_CREATED + + """A promotion is deleted.""" + PROMOTION_DELETED + + """A promotion is deactivated.""" + PROMOTION_ENDED + + """A promotion rule is created.""" + PROMOTION_RULE_CREATED + + """A promotion rule is deleted.""" + PROMOTION_RULE_DELETED + + """A promotion rule is updated.""" + PROMOTION_RULE_UPDATED + + """A promotion is activated.""" + PROMOTION_STARTED + + """A promotion is updated.""" + PROMOTION_UPDATED + """A sale is created.""" SALE_CREATED @@ -33557,6 +35117,30 @@ enum WebhookEventTypeEnum { """A product variant is updated.""" PRODUCT_VARIANT_UPDATED + """A promotion is created.""" + PROMOTION_CREATED + + """A promotion is deleted.""" + PROMOTION_DELETED + + """A promotion is deactivated.""" + PROMOTION_ENDED + + """A promotion rule is created.""" + PROMOTION_RULE_CREATED + + """A promotion rule is deleted.""" + PROMOTION_RULE_DELETED + + """A promotion rule is updated.""" + PROMOTION_RULE_UPDATED + + """A promotion is activated.""" + PROMOTION_STARTED + + """A promotion is updated.""" + PROMOTION_UPDATED + """A sale is created.""" SALE_CREATED @@ -33885,6 +35469,14 @@ enum WebhookSampleEventTypeEnum { PRODUCT_VARIANT_OUT_OF_STOCK PRODUCT_VARIANT_STOCK_UPDATED PRODUCT_VARIANT_UPDATED + PROMOTION_CREATED + PROMOTION_DELETED + PROMOTION_ENDED + PROMOTION_RULE_CREATED + PROMOTION_RULE_DELETED + PROMOTION_RULE_UPDATED + PROMOTION_STARTED + PROMOTION_UPDATED SALE_CREATED SALE_DELETED SALE_TOGGLE diff --git a/src/discounts/views/VoucherCreate/handlers.ts b/src/discounts/views/VoucherCreate/handlers.ts index 6dc23096d3f..52bf243096c 100644 --- a/src/discounts/views/VoucherCreate/handlers.ts +++ b/src/discounts/views/VoucherCreate/handlers.ts @@ -35,7 +35,7 @@ export function createHandler( applyOncePerCustomer: formData.applyOncePerCustomer, applyOncePerOrder: formData.applyOncePerOrder, onlyForStaff: formData.onlyForStaff, - codes: formData.codes.map(({ code }) => ({ code, usageLimit: 0 })), + codes: formData.codes.map(({ code }) => ({ code })), discountValueType: formData.discountType === DiscountTypeEnum.VALUE_PERCENTAGE ? DiscountValueTypeEnum.PERCENTAGE diff --git a/src/graphql/fragmentTypes.generated.ts b/src/graphql/fragmentTypes.generated.ts index feb9447dd60..798d00b2664 100644 --- a/src/graphql/fragmentTypes.generated.ts +++ b/src/graphql/fragmentTypes.generated.ts @@ -134,6 +134,14 @@ "ProductVariantOutOfStock", "ProductVariantStockUpdated", "ProductVariantUpdated", + "PromotionCreated", + "PromotionDeleted", + "PromotionEnded", + "PromotionRuleCreated", + "PromotionRuleDeleted", + "PromotionRuleUpdated", + "PromotionStarted", + "PromotionUpdated", "SaleCreated", "SaleDeleted", "SaleToggle", @@ -239,6 +247,19 @@ "ProductVariantChannelListing", "ProductVariantTranslatableContent", "ProductVariantTranslation", + "Promotion", + "PromotionCreatedEvent", + "PromotionEndedEvent", + "PromotionRule", + "PromotionRuleCreatedEvent", + "PromotionRuleDeletedEvent", + "PromotionRuleTranslatableContent", + "PromotionRuleTranslation", + "PromotionRuleUpdatedEvent", + "PromotionStartedEvent", + "PromotionTranslatableContent", + "PromotionTranslation", + "PromotionUpdatedEvent", "Sale", "SaleChannelListing", "SaleTranslatableContent", @@ -290,6 +311,7 @@ "ProductMedia", "ProductType", "ProductVariant", + "Promotion", "Sale", "ShippingMethod", "ShippingMethodType", @@ -306,6 +328,29 @@ "Checkout", "Order" ], + "PromotionEvent": [ + "PromotionCreatedEvent", + "PromotionEndedEvent", + "PromotionRuleCreatedEvent", + "PromotionRuleDeletedEvent", + "PromotionRuleUpdatedEvent", + "PromotionStartedEvent", + "PromotionUpdatedEvent" + ], + "PromotionEventInterface": [ + "PromotionCreatedEvent", + "PromotionEndedEvent", + "PromotionRuleCreatedEvent", + "PromotionRuleDeletedEvent", + "PromotionRuleUpdatedEvent", + "PromotionStartedEvent", + "PromotionUpdatedEvent" + ], + "PromotionRuleEventInterface": [ + "PromotionRuleCreatedEvent", + "PromotionRuleDeletedEvent", + "PromotionRuleUpdatedEvent" + ], "TaxSourceLine": [ "CheckoutLine", "OrderLine" @@ -323,6 +368,8 @@ "PageTranslatableContent", "ProductTranslatableContent", "ProductVariantTranslatableContent", + "PromotionRuleTranslatableContent", + "PromotionTranslatableContent", "SaleTranslatableContent", "ShippingMethodTranslatableContent", "VoucherTranslatableContent" @@ -336,6 +383,8 @@ "PageTranslation", "ProductTranslation", "ProductVariantTranslation", + "PromotionRuleTranslation", + "PromotionTranslation", "SaleTranslation", "ShippingMethodTranslation", "VoucherTranslation" diff --git a/src/graphql/typePolicies.generated.ts b/src/graphql/typePolicies.generated.ts index 881b00a61c1..fa4228b4037 100644 --- a/src/graphql/typePolicies.generated.ts +++ b/src/graphql/typePolicies.generated.ts @@ -2617,7 +2617,7 @@ export type MoneyRangeFieldPolicy = { start?: FieldPolicy | FieldReadFunction, stop?: FieldPolicy | FieldReadFunction }; -export type MutationKeySpecifier = ('accountAddressCreate' | 'accountAddressDelete' | 'accountAddressUpdate' | 'accountDelete' | 'accountRegister' | 'accountRequestDeletion' | 'accountSetDefaultAddress' | 'accountUpdate' | 'addressCreate' | 'addressDelete' | 'addressSetDefault' | 'addressUpdate' | 'appActivate' | 'appCreate' | 'appDeactivate' | 'appDelete' | 'appDeleteFailedInstallation' | 'appFetchManifest' | 'appInstall' | 'appRetryInstall' | 'appTokenCreate' | 'appTokenDelete' | 'appTokenVerify' | 'appUpdate' | 'assignNavigation' | 'assignWarehouseShippingZone' | 'attributeBulkCreate' | 'attributeBulkDelete' | 'attributeBulkTranslate' | 'attributeBulkUpdate' | 'attributeCreate' | 'attributeDelete' | 'attributeReorderValues' | 'attributeTranslate' | 'attributeUpdate' | 'attributeValueBulkDelete' | 'attributeValueBulkTranslate' | 'attributeValueCreate' | 'attributeValueDelete' | 'attributeValueTranslate' | 'attributeValueUpdate' | 'categoryBulkDelete' | 'categoryCreate' | 'categoryDelete' | 'categoryTranslate' | 'categoryUpdate' | 'channelActivate' | 'channelCreate' | 'channelDeactivate' | 'channelDelete' | 'channelReorderWarehouses' | 'channelUpdate' | 'checkoutAddPromoCode' | 'checkoutBillingAddressUpdate' | 'checkoutComplete' | 'checkoutCreate' | 'checkoutCreateFromOrder' | 'checkoutCustomerAttach' | 'checkoutCustomerDetach' | 'checkoutDeliveryMethodUpdate' | 'checkoutEmailUpdate' | 'checkoutLanguageCodeUpdate' | 'checkoutLineDelete' | 'checkoutLinesAdd' | 'checkoutLinesDelete' | 'checkoutLinesUpdate' | 'checkoutPaymentCreate' | 'checkoutRemovePromoCode' | 'checkoutShippingAddressUpdate' | 'checkoutShippingMethodUpdate' | 'collectionAddProducts' | 'collectionBulkDelete' | 'collectionChannelListingUpdate' | 'collectionCreate' | 'collectionDelete' | 'collectionRemoveProducts' | 'collectionReorderProducts' | 'collectionTranslate' | 'collectionUpdate' | 'confirmAccount' | 'confirmEmailChange' | 'createWarehouse' | 'customerBulkDelete' | 'customerBulkUpdate' | 'customerCreate' | 'customerDelete' | 'customerUpdate' | 'deleteMetadata' | 'deletePrivateMetadata' | 'deleteWarehouse' | 'digitalContentCreate' | 'digitalContentDelete' | 'digitalContentUpdate' | 'digitalContentUrlCreate' | 'draftOrderBulkDelete' | 'draftOrderComplete' | 'draftOrderCreate' | 'draftOrderDelete' | 'draftOrderLinesBulkDelete' | 'draftOrderUpdate' | 'eventDeliveryRetry' | 'exportGiftCards' | 'exportProducts' | 'externalAuthenticationUrl' | 'externalLogout' | 'externalNotificationTrigger' | 'externalObtainAccessTokens' | 'externalRefresh' | 'externalVerify' | 'fileUpload' | 'giftCardActivate' | 'giftCardAddNote' | 'giftCardBulkActivate' | 'giftCardBulkCreate' | 'giftCardBulkDeactivate' | 'giftCardBulkDelete' | 'giftCardCreate' | 'giftCardDeactivate' | 'giftCardDelete' | 'giftCardResend' | 'giftCardSettingsUpdate' | 'giftCardUpdate' | 'invoiceCreate' | 'invoiceDelete' | 'invoiceRequest' | 'invoiceRequestDelete' | 'invoiceSendNotification' | 'invoiceUpdate' | 'menuBulkDelete' | 'menuCreate' | 'menuDelete' | 'menuItemBulkDelete' | 'menuItemCreate' | 'menuItemDelete' | 'menuItemMove' | 'menuItemTranslate' | 'menuItemUpdate' | 'menuUpdate' | 'orderAddNote' | 'orderBulkCancel' | 'orderBulkCreate' | 'orderCancel' | 'orderCapture' | 'orderConfirm' | 'orderCreateFromCheckout' | 'orderDiscountAdd' | 'orderDiscountDelete' | 'orderDiscountUpdate' | 'orderFulfill' | 'orderFulfillmentApprove' | 'orderFulfillmentCancel' | 'orderFulfillmentRefundProducts' | 'orderFulfillmentReturnProducts' | 'orderFulfillmentUpdateTracking' | 'orderGrantRefundCreate' | 'orderGrantRefundUpdate' | 'orderLineDelete' | 'orderLineDiscountRemove' | 'orderLineDiscountUpdate' | 'orderLineUpdate' | 'orderLinesCreate' | 'orderMarkAsPaid' | 'orderNoteAdd' | 'orderNoteUpdate' | 'orderRefund' | 'orderSettingsUpdate' | 'orderUpdate' | 'orderUpdateShipping' | 'orderVoid' | 'pageAttributeAssign' | 'pageAttributeUnassign' | 'pageBulkDelete' | 'pageBulkPublish' | 'pageCreate' | 'pageDelete' | 'pageReorderAttributeValues' | 'pageTranslate' | 'pageTypeBulkDelete' | 'pageTypeCreate' | 'pageTypeDelete' | 'pageTypeReorderAttributes' | 'pageTypeUpdate' | 'pageUpdate' | 'passwordChange' | 'paymentCapture' | 'paymentCheckBalance' | 'paymentGatewayInitialize' | 'paymentGatewayInitializeTokenization' | 'paymentInitialize' | 'paymentMethodInitializeTokenization' | 'paymentMethodProcessTokenization' | 'paymentRefund' | 'paymentVoid' | 'permissionGroupCreate' | 'permissionGroupDelete' | 'permissionGroupUpdate' | 'pluginUpdate' | 'productAttributeAssign' | 'productAttributeAssignmentUpdate' | 'productAttributeUnassign' | 'productBulkCreate' | 'productBulkDelete' | 'productBulkTranslate' | 'productChannelListingUpdate' | 'productCreate' | 'productDelete' | 'productMediaBulkDelete' | 'productMediaCreate' | 'productMediaDelete' | 'productMediaReorder' | 'productMediaUpdate' | 'productReorderAttributeValues' | 'productTranslate' | 'productTypeBulkDelete' | 'productTypeCreate' | 'productTypeDelete' | 'productTypeReorderAttributes' | 'productTypeUpdate' | 'productUpdate' | 'productVariantBulkCreate' | 'productVariantBulkDelete' | 'productVariantBulkTranslate' | 'productVariantBulkUpdate' | 'productVariantChannelListingUpdate' | 'productVariantCreate' | 'productVariantDelete' | 'productVariantPreorderDeactivate' | 'productVariantReorder' | 'productVariantReorderAttributeValues' | 'productVariantSetDefault' | 'productVariantStocksCreate' | 'productVariantStocksDelete' | 'productVariantStocksUpdate' | 'productVariantTranslate' | 'productVariantUpdate' | 'requestEmailChange' | 'requestPasswordReset' | 'saleBulkDelete' | 'saleCataloguesAdd' | 'saleCataloguesRemove' | 'saleChannelListingUpdate' | 'saleCreate' | 'saleDelete' | 'saleTranslate' | 'saleUpdate' | 'sendConfirmationEmail' | 'setPassword' | 'shippingMethodChannelListingUpdate' | 'shippingPriceBulkDelete' | 'shippingPriceCreate' | 'shippingPriceDelete' | 'shippingPriceExcludeProducts' | 'shippingPriceRemoveProductFromExclude' | 'shippingPriceTranslate' | 'shippingPriceUpdate' | 'shippingZoneBulkDelete' | 'shippingZoneCreate' | 'shippingZoneDelete' | 'shippingZoneUpdate' | 'shopAddressUpdate' | 'shopDomainUpdate' | 'shopFetchTaxRates' | 'shopSettingsTranslate' | 'shopSettingsUpdate' | 'staffBulkDelete' | 'staffCreate' | 'staffDelete' | 'staffNotificationRecipientCreate' | 'staffNotificationRecipientDelete' | 'staffNotificationRecipientUpdate' | 'staffUpdate' | 'stockBulkUpdate' | 'storedPaymentMethodRequestDelete' | 'taxClassCreate' | 'taxClassDelete' | 'taxClassUpdate' | 'taxConfigurationUpdate' | 'taxCountryConfigurationDelete' | 'taxCountryConfigurationUpdate' | 'taxExemptionManage' | 'tokenCreate' | 'tokenRefresh' | 'tokenVerify' | 'tokensDeactivateAll' | 'transactionCreate' | 'transactionEventReport' | 'transactionInitialize' | 'transactionProcess' | 'transactionRequestAction' | 'transactionRequestRefundForGrantedRefund' | 'transactionUpdate' | 'unassignWarehouseShippingZone' | 'updateMetadata' | 'updatePrivateMetadata' | 'updateWarehouse' | 'userAvatarDelete' | 'userAvatarUpdate' | 'userBulkSetActive' | 'variantMediaAssign' | 'variantMediaUnassign' | 'voucherBulkDelete' | 'voucherCataloguesAdd' | 'voucherCataloguesRemove' | 'voucherChannelListingUpdate' | 'voucherCreate' | 'voucherDelete' | 'voucherTranslate' | 'voucherUpdate' | 'webhookCreate' | 'webhookDelete' | 'webhookDryRun' | 'webhookTrigger' | 'webhookUpdate' | MutationKeySpecifier)[]; +export type MutationKeySpecifier = ('accountAddressCreate' | 'accountAddressDelete' | 'accountAddressUpdate' | 'accountDelete' | 'accountRegister' | 'accountRequestDeletion' | 'accountSetDefaultAddress' | 'accountUpdate' | 'addressCreate' | 'addressDelete' | 'addressSetDefault' | 'addressUpdate' | 'appActivate' | 'appCreate' | 'appDeactivate' | 'appDelete' | 'appDeleteFailedInstallation' | 'appFetchManifest' | 'appInstall' | 'appRetryInstall' | 'appTokenCreate' | 'appTokenDelete' | 'appTokenVerify' | 'appUpdate' | 'assignNavigation' | 'assignWarehouseShippingZone' | 'attributeBulkCreate' | 'attributeBulkDelete' | 'attributeBulkTranslate' | 'attributeBulkUpdate' | 'attributeCreate' | 'attributeDelete' | 'attributeReorderValues' | 'attributeTranslate' | 'attributeUpdate' | 'attributeValueBulkDelete' | 'attributeValueBulkTranslate' | 'attributeValueCreate' | 'attributeValueDelete' | 'attributeValueTranslate' | 'attributeValueUpdate' | 'categoryBulkDelete' | 'categoryCreate' | 'categoryDelete' | 'categoryTranslate' | 'categoryUpdate' | 'channelActivate' | 'channelCreate' | 'channelDeactivate' | 'channelDelete' | 'channelReorderWarehouses' | 'channelUpdate' | 'checkoutAddPromoCode' | 'checkoutBillingAddressUpdate' | 'checkoutComplete' | 'checkoutCreate' | 'checkoutCreateFromOrder' | 'checkoutCustomerAttach' | 'checkoutCustomerDetach' | 'checkoutDeliveryMethodUpdate' | 'checkoutEmailUpdate' | 'checkoutLanguageCodeUpdate' | 'checkoutLineDelete' | 'checkoutLinesAdd' | 'checkoutLinesDelete' | 'checkoutLinesUpdate' | 'checkoutPaymentCreate' | 'checkoutRemovePromoCode' | 'checkoutShippingAddressUpdate' | 'checkoutShippingMethodUpdate' | 'collectionAddProducts' | 'collectionBulkDelete' | 'collectionChannelListingUpdate' | 'collectionCreate' | 'collectionDelete' | 'collectionRemoveProducts' | 'collectionReorderProducts' | 'collectionTranslate' | 'collectionUpdate' | 'confirmAccount' | 'confirmEmailChange' | 'createWarehouse' | 'customerBulkDelete' | 'customerBulkUpdate' | 'customerCreate' | 'customerDelete' | 'customerUpdate' | 'deleteMetadata' | 'deletePrivateMetadata' | 'deleteWarehouse' | 'digitalContentCreate' | 'digitalContentDelete' | 'digitalContentUpdate' | 'digitalContentUrlCreate' | 'draftOrderBulkDelete' | 'draftOrderComplete' | 'draftOrderCreate' | 'draftOrderDelete' | 'draftOrderLinesBulkDelete' | 'draftOrderUpdate' | 'eventDeliveryRetry' | 'exportGiftCards' | 'exportProducts' | 'externalAuthenticationUrl' | 'externalLogout' | 'externalNotificationTrigger' | 'externalObtainAccessTokens' | 'externalRefresh' | 'externalVerify' | 'fileUpload' | 'giftCardActivate' | 'giftCardAddNote' | 'giftCardBulkActivate' | 'giftCardBulkCreate' | 'giftCardBulkDeactivate' | 'giftCardBulkDelete' | 'giftCardCreate' | 'giftCardDeactivate' | 'giftCardDelete' | 'giftCardResend' | 'giftCardSettingsUpdate' | 'giftCardUpdate' | 'invoiceCreate' | 'invoiceDelete' | 'invoiceRequest' | 'invoiceRequestDelete' | 'invoiceSendNotification' | 'invoiceUpdate' | 'menuBulkDelete' | 'menuCreate' | 'menuDelete' | 'menuItemBulkDelete' | 'menuItemCreate' | 'menuItemDelete' | 'menuItemMove' | 'menuItemTranslate' | 'menuItemUpdate' | 'menuUpdate' | 'orderAddNote' | 'orderBulkCancel' | 'orderBulkCreate' | 'orderCancel' | 'orderCapture' | 'orderConfirm' | 'orderCreateFromCheckout' | 'orderDiscountAdd' | 'orderDiscountDelete' | 'orderDiscountUpdate' | 'orderFulfill' | 'orderFulfillmentApprove' | 'orderFulfillmentCancel' | 'orderFulfillmentRefundProducts' | 'orderFulfillmentReturnProducts' | 'orderFulfillmentUpdateTracking' | 'orderGrantRefundCreate' | 'orderGrantRefundUpdate' | 'orderLineDelete' | 'orderLineDiscountRemove' | 'orderLineDiscountUpdate' | 'orderLineUpdate' | 'orderLinesCreate' | 'orderMarkAsPaid' | 'orderNoteAdd' | 'orderNoteUpdate' | 'orderRefund' | 'orderSettingsUpdate' | 'orderUpdate' | 'orderUpdateShipping' | 'orderVoid' | 'pageAttributeAssign' | 'pageAttributeUnassign' | 'pageBulkDelete' | 'pageBulkPublish' | 'pageCreate' | 'pageDelete' | 'pageReorderAttributeValues' | 'pageTranslate' | 'pageTypeBulkDelete' | 'pageTypeCreate' | 'pageTypeDelete' | 'pageTypeReorderAttributes' | 'pageTypeUpdate' | 'pageUpdate' | 'passwordChange' | 'paymentCapture' | 'paymentCheckBalance' | 'paymentGatewayInitialize' | 'paymentGatewayInitializeTokenization' | 'paymentInitialize' | 'paymentMethodInitializeTokenization' | 'paymentMethodProcessTokenization' | 'paymentRefund' | 'paymentVoid' | 'permissionGroupCreate' | 'permissionGroupDelete' | 'permissionGroupUpdate' | 'pluginUpdate' | 'productAttributeAssign' | 'productAttributeAssignmentUpdate' | 'productAttributeUnassign' | 'productBulkCreate' | 'productBulkDelete' | 'productBulkTranslate' | 'productChannelListingUpdate' | 'productCreate' | 'productDelete' | 'productMediaBulkDelete' | 'productMediaCreate' | 'productMediaDelete' | 'productMediaReorder' | 'productMediaUpdate' | 'productReorderAttributeValues' | 'productTranslate' | 'productTypeBulkDelete' | 'productTypeCreate' | 'productTypeDelete' | 'productTypeReorderAttributes' | 'productTypeUpdate' | 'productUpdate' | 'productVariantBulkCreate' | 'productVariantBulkDelete' | 'productVariantBulkTranslate' | 'productVariantBulkUpdate' | 'productVariantChannelListingUpdate' | 'productVariantCreate' | 'productVariantDelete' | 'productVariantPreorderDeactivate' | 'productVariantReorder' | 'productVariantReorderAttributeValues' | 'productVariantSetDefault' | 'productVariantStocksCreate' | 'productVariantStocksDelete' | 'productVariantStocksUpdate' | 'productVariantTranslate' | 'productVariantUpdate' | 'promotionBulkDelete' | 'promotionCreate' | 'promotionDelete' | 'promotionRuleCreate' | 'promotionRuleDelete' | 'promotionRuleTranslate' | 'promotionRuleUpdate' | 'promotionTranslate' | 'promotionUpdate' | 'requestEmailChange' | 'requestPasswordReset' | 'saleBulkDelete' | 'saleCataloguesAdd' | 'saleCataloguesRemove' | 'saleChannelListingUpdate' | 'saleCreate' | 'saleDelete' | 'saleTranslate' | 'saleUpdate' | 'sendConfirmationEmail' | 'setPassword' | 'shippingMethodChannelListingUpdate' | 'shippingPriceBulkDelete' | 'shippingPriceCreate' | 'shippingPriceDelete' | 'shippingPriceExcludeProducts' | 'shippingPriceRemoveProductFromExclude' | 'shippingPriceTranslate' | 'shippingPriceUpdate' | 'shippingZoneBulkDelete' | 'shippingZoneCreate' | 'shippingZoneDelete' | 'shippingZoneUpdate' | 'shopAddressUpdate' | 'shopDomainUpdate' | 'shopFetchTaxRates' | 'shopSettingsTranslate' | 'shopSettingsUpdate' | 'staffBulkDelete' | 'staffCreate' | 'staffDelete' | 'staffNotificationRecipientCreate' | 'staffNotificationRecipientDelete' | 'staffNotificationRecipientUpdate' | 'staffUpdate' | 'stockBulkUpdate' | 'storedPaymentMethodRequestDelete' | 'taxClassCreate' | 'taxClassDelete' | 'taxClassUpdate' | 'taxConfigurationUpdate' | 'taxCountryConfigurationDelete' | 'taxCountryConfigurationUpdate' | 'taxExemptionManage' | 'tokenCreate' | 'tokenRefresh' | 'tokenVerify' | 'tokensDeactivateAll' | 'transactionCreate' | 'transactionEventReport' | 'transactionInitialize' | 'transactionProcess' | 'transactionRequestAction' | 'transactionRequestRefundForGrantedRefund' | 'transactionUpdate' | 'unassignWarehouseShippingZone' | 'updateMetadata' | 'updatePrivateMetadata' | 'updateWarehouse' | 'userAvatarDelete' | 'userAvatarUpdate' | 'userBulkSetActive' | 'variantMediaAssign' | 'variantMediaUnassign' | 'voucherBulkDelete' | 'voucherCataloguesAdd' | 'voucherCataloguesRemove' | 'voucherChannelListingUpdate' | 'voucherCodeBulkDelete' | 'voucherCreate' | 'voucherDelete' | 'voucherTranslate' | 'voucherUpdate' | 'webhookCreate' | 'webhookDelete' | 'webhookDryRun' | 'webhookTrigger' | 'webhookUpdate' | MutationKeySpecifier)[]; export type MutationFieldPolicy = { accountAddressCreate?: FieldPolicy | FieldReadFunction, accountAddressDelete?: FieldPolicy | FieldReadFunction, @@ -2854,6 +2854,15 @@ export type MutationFieldPolicy = { productVariantStocksUpdate?: FieldPolicy | FieldReadFunction, productVariantTranslate?: FieldPolicy | FieldReadFunction, productVariantUpdate?: FieldPolicy | FieldReadFunction, + promotionBulkDelete?: FieldPolicy | FieldReadFunction, + promotionCreate?: FieldPolicy | FieldReadFunction, + promotionDelete?: FieldPolicy | FieldReadFunction, + promotionRuleCreate?: FieldPolicy | FieldReadFunction, + promotionRuleDelete?: FieldPolicy | FieldReadFunction, + promotionRuleTranslate?: FieldPolicy | FieldReadFunction, + promotionRuleUpdate?: FieldPolicy | FieldReadFunction, + promotionTranslate?: FieldPolicy | FieldReadFunction, + promotionUpdate?: FieldPolicy | FieldReadFunction, requestEmailChange?: FieldPolicy | FieldReadFunction, requestPasswordReset?: FieldPolicy | FieldReadFunction, saleBulkDelete?: FieldPolicy | FieldReadFunction, @@ -2923,6 +2932,7 @@ export type MutationFieldPolicy = { voucherCataloguesAdd?: FieldPolicy | FieldReadFunction, voucherCataloguesRemove?: FieldPolicy | FieldReadFunction, voucherChannelListingUpdate?: FieldPolicy | FieldReadFunction, + voucherCodeBulkDelete?: FieldPolicy | FieldReadFunction, voucherCreate?: FieldPolicy | FieldReadFunction, voucherDelete?: FieldPolicy | FieldReadFunction, voucherTranslate?: FieldPolicy | FieldReadFunction, @@ -4781,7 +4791,287 @@ export type ProductVariantUpdatedFieldPolicy = { recipient?: FieldPolicy | FieldReadFunction, version?: FieldPolicy | FieldReadFunction }; -export type QueryKeySpecifier = ('_entities' | '_service' | 'address' | 'addressValidationRules' | 'app' | 'appExtension' | 'appExtensions' | 'apps' | 'appsInstallations' | 'attribute' | 'attributes' | 'categories' | 'category' | 'channel' | 'channels' | 'checkout' | 'checkoutLines' | 'checkouts' | 'collection' | 'collections' | 'customers' | 'digitalContent' | 'digitalContents' | 'draftOrders' | 'exportFile' | 'exportFiles' | 'giftCard' | 'giftCardCurrencies' | 'giftCardSettings' | 'giftCardTags' | 'giftCards' | 'homepageEvents' | 'me' | 'menu' | 'menuItem' | 'menuItems' | 'menus' | 'order' | 'orderByToken' | 'orderSettings' | 'orders' | 'ordersTotal' | 'page' | 'pageType' | 'pageTypes' | 'pages' | 'payment' | 'payments' | 'permissionGroup' | 'permissionGroups' | 'plugin' | 'plugins' | 'product' | 'productType' | 'productTypes' | 'productVariant' | 'productVariants' | 'products' | 'reportProductSales' | 'sale' | 'sales' | 'shippingZone' | 'shippingZones' | 'shop' | 'staffUsers' | 'stock' | 'stocks' | 'taxClass' | 'taxClasses' | 'taxConfiguration' | 'taxConfigurations' | 'taxCountryConfiguration' | 'taxCountryConfigurations' | 'taxTypes' | 'transaction' | 'translation' | 'translations' | 'user' | 'voucher' | 'vouchers' | 'warehouse' | 'warehouses' | 'webhook' | 'webhookEvents' | 'webhookSamplePayload' | QueryKeySpecifier)[]; +export type PromotionKeySpecifier = ('createdAt' | 'description' | 'endDate' | 'events' | 'id' | 'metadata' | 'metafield' | 'metafields' | 'name' | 'privateMetadata' | 'privateMetafield' | 'privateMetafields' | 'rules' | 'startDate' | 'translation' | 'updatedAt' | PromotionKeySpecifier)[]; +export type PromotionFieldPolicy = { + createdAt?: FieldPolicy | FieldReadFunction, + description?: FieldPolicy | FieldReadFunction, + endDate?: FieldPolicy | FieldReadFunction, + events?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + metadata?: FieldPolicy | FieldReadFunction, + metafield?: FieldPolicy | FieldReadFunction, + metafields?: FieldPolicy | FieldReadFunction, + name?: FieldPolicy | FieldReadFunction, + privateMetadata?: FieldPolicy | FieldReadFunction, + privateMetafield?: FieldPolicy | FieldReadFunction, + privateMetafields?: FieldPolicy | FieldReadFunction, + rules?: FieldPolicy | FieldReadFunction, + startDate?: FieldPolicy | FieldReadFunction, + translation?: FieldPolicy | FieldReadFunction, + updatedAt?: FieldPolicy | FieldReadFunction +}; +export type PromotionBulkDeleteKeySpecifier = ('count' | 'errors' | PromotionBulkDeleteKeySpecifier)[]; +export type PromotionBulkDeleteFieldPolicy = { + count?: FieldPolicy | FieldReadFunction, + errors?: FieldPolicy | FieldReadFunction +}; +export type PromotionCountableConnectionKeySpecifier = ('edges' | 'pageInfo' | 'totalCount' | PromotionCountableConnectionKeySpecifier)[]; +export type PromotionCountableConnectionFieldPolicy = { + edges?: FieldPolicy | FieldReadFunction, + pageInfo?: FieldPolicy | FieldReadFunction, + totalCount?: FieldPolicy | FieldReadFunction +}; +export type PromotionCountableEdgeKeySpecifier = ('cursor' | 'node' | PromotionCountableEdgeKeySpecifier)[]; +export type PromotionCountableEdgeFieldPolicy = { + cursor?: FieldPolicy | FieldReadFunction, + node?: FieldPolicy | FieldReadFunction +}; +export type PromotionCreateKeySpecifier = ('errors' | 'promotion' | PromotionCreateKeySpecifier)[]; +export type PromotionCreateFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction +}; +export type PromotionCreateErrorKeySpecifier = ('code' | 'field' | 'index' | 'message' | PromotionCreateErrorKeySpecifier)[]; +export type PromotionCreateErrorFieldPolicy = { + code?: FieldPolicy | FieldReadFunction, + field?: FieldPolicy | FieldReadFunction, + index?: FieldPolicy | FieldReadFunction, + message?: FieldPolicy | FieldReadFunction +}; +export type PromotionCreatedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotion' | 'recipient' | 'version' | PromotionCreatedKeySpecifier)[]; +export type PromotionCreatedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionCreatedEventKeySpecifier = ('createdBy' | 'date' | 'id' | 'type' | PromotionCreatedEventKeySpecifier)[]; +export type PromotionCreatedEventFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type PromotionDeleteKeySpecifier = ('errors' | 'promotion' | PromotionDeleteKeySpecifier)[]; +export type PromotionDeleteFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction +}; +export type PromotionDeleteErrorKeySpecifier = ('code' | 'field' | 'message' | PromotionDeleteErrorKeySpecifier)[]; +export type PromotionDeleteErrorFieldPolicy = { + code?: FieldPolicy | FieldReadFunction, + field?: FieldPolicy | FieldReadFunction, + message?: FieldPolicy | FieldReadFunction +}; +export type PromotionDeletedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotion' | 'recipient' | 'version' | PromotionDeletedKeySpecifier)[]; +export type PromotionDeletedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionEndedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotion' | 'recipient' | 'version' | PromotionEndedKeySpecifier)[]; +export type PromotionEndedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionEndedEventKeySpecifier = ('createdBy' | 'date' | 'id' | 'type' | PromotionEndedEventKeySpecifier)[]; +export type PromotionEndedEventFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type PromotionEventInterfaceKeySpecifier = ('createdBy' | 'date' | 'id' | 'type' | PromotionEventInterfaceKeySpecifier)[]; +export type PromotionEventInterfaceFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleKeySpecifier = ('cataloguePredicate' | 'channels' | 'description' | 'id' | 'name' | 'promotion' | 'rewardValue' | 'rewardValueType' | 'translation' | PromotionRuleKeySpecifier)[]; +export type PromotionRuleFieldPolicy = { + cataloguePredicate?: FieldPolicy | FieldReadFunction, + channels?: FieldPolicy | FieldReadFunction, + description?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + name?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction, + rewardValue?: FieldPolicy | FieldReadFunction, + rewardValueType?: FieldPolicy | FieldReadFunction, + translation?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleCreateKeySpecifier = ('errors' | 'promotionRule' | PromotionRuleCreateKeySpecifier)[]; +export type PromotionRuleCreateFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotionRule?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleCreateErrorKeySpecifier = ('code' | 'field' | 'message' | PromotionRuleCreateErrorKeySpecifier)[]; +export type PromotionRuleCreateErrorFieldPolicy = { + code?: FieldPolicy | FieldReadFunction, + field?: FieldPolicy | FieldReadFunction, + message?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleCreatedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotionRule' | 'recipient' | 'version' | PromotionRuleCreatedKeySpecifier)[]; +export type PromotionRuleCreatedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotionRule?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleCreatedEventKeySpecifier = ('createdBy' | 'date' | 'id' | 'ruleId' | 'type' | PromotionRuleCreatedEventKeySpecifier)[]; +export type PromotionRuleCreatedEventFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + ruleId?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleDeleteKeySpecifier = ('errors' | 'promotionRule' | PromotionRuleDeleteKeySpecifier)[]; +export type PromotionRuleDeleteFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotionRule?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleDeleteErrorKeySpecifier = ('code' | 'field' | 'message' | PromotionRuleDeleteErrorKeySpecifier)[]; +export type PromotionRuleDeleteErrorFieldPolicy = { + code?: FieldPolicy | FieldReadFunction, + field?: FieldPolicy | FieldReadFunction, + message?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleDeletedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotionRule' | 'recipient' | 'version' | PromotionRuleDeletedKeySpecifier)[]; +export type PromotionRuleDeletedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotionRule?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleDeletedEventKeySpecifier = ('createdBy' | 'date' | 'id' | 'ruleId' | 'type' | PromotionRuleDeletedEventKeySpecifier)[]; +export type PromotionRuleDeletedEventFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + ruleId?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleEventInterfaceKeySpecifier = ('ruleId' | PromotionRuleEventInterfaceKeySpecifier)[]; +export type PromotionRuleEventInterfaceFieldPolicy = { + ruleId?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleTranslatableContentKeySpecifier = ('description' | 'id' | 'name' | 'translation' | PromotionRuleTranslatableContentKeySpecifier)[]; +export type PromotionRuleTranslatableContentFieldPolicy = { + description?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + name?: FieldPolicy | FieldReadFunction, + translation?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleTranslateKeySpecifier = ('errors' | 'promotionRule' | PromotionRuleTranslateKeySpecifier)[]; +export type PromotionRuleTranslateFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotionRule?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleTranslationKeySpecifier = ('description' | 'id' | 'language' | 'name' | PromotionRuleTranslationKeySpecifier)[]; +export type PromotionRuleTranslationFieldPolicy = { + description?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + language?: FieldPolicy | FieldReadFunction, + name?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleUpdateKeySpecifier = ('errors' | 'promotionRule' | PromotionRuleUpdateKeySpecifier)[]; +export type PromotionRuleUpdateFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotionRule?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleUpdateErrorKeySpecifier = ('channels' | 'code' | 'field' | 'message' | PromotionRuleUpdateErrorKeySpecifier)[]; +export type PromotionRuleUpdateErrorFieldPolicy = { + channels?: FieldPolicy | FieldReadFunction, + code?: FieldPolicy | FieldReadFunction, + field?: FieldPolicy | FieldReadFunction, + message?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleUpdatedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotionRule' | 'recipient' | 'version' | PromotionRuleUpdatedKeySpecifier)[]; +export type PromotionRuleUpdatedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotionRule?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionRuleUpdatedEventKeySpecifier = ('createdBy' | 'date' | 'id' | 'ruleId' | 'type' | PromotionRuleUpdatedEventKeySpecifier)[]; +export type PromotionRuleUpdatedEventFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + ruleId?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type PromotionStartedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotion' | 'recipient' | 'version' | PromotionStartedKeySpecifier)[]; +export type PromotionStartedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionStartedEventKeySpecifier = ('createdBy' | 'date' | 'id' | 'type' | PromotionStartedEventKeySpecifier)[]; +export type PromotionStartedEventFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type PromotionTranslatableContentKeySpecifier = ('description' | 'id' | 'name' | 'translation' | PromotionTranslatableContentKeySpecifier)[]; +export type PromotionTranslatableContentFieldPolicy = { + description?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + name?: FieldPolicy | FieldReadFunction, + translation?: FieldPolicy | FieldReadFunction +}; +export type PromotionTranslateKeySpecifier = ('errors' | 'promotion' | PromotionTranslateKeySpecifier)[]; +export type PromotionTranslateFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction +}; +export type PromotionTranslationKeySpecifier = ('description' | 'id' | 'language' | 'name' | PromotionTranslationKeySpecifier)[]; +export type PromotionTranslationFieldPolicy = { + description?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + language?: FieldPolicy | FieldReadFunction, + name?: FieldPolicy | FieldReadFunction +}; +export type PromotionUpdateKeySpecifier = ('errors' | 'promotion' | PromotionUpdateKeySpecifier)[]; +export type PromotionUpdateFieldPolicy = { + errors?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction +}; +export type PromotionUpdateErrorKeySpecifier = ('code' | 'field' | 'message' | PromotionUpdateErrorKeySpecifier)[]; +export type PromotionUpdateErrorFieldPolicy = { + code?: FieldPolicy | FieldReadFunction, + field?: FieldPolicy | FieldReadFunction, + message?: FieldPolicy | FieldReadFunction +}; +export type PromotionUpdatedKeySpecifier = ('issuedAt' | 'issuingPrincipal' | 'promotion' | 'recipient' | 'version' | PromotionUpdatedKeySpecifier)[]; +export type PromotionUpdatedFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction +}; +export type PromotionUpdatedEventKeySpecifier = ('createdBy' | 'date' | 'id' | 'type' | PromotionUpdatedEventKeySpecifier)[]; +export type PromotionUpdatedEventFieldPolicy = { + createdBy?: FieldPolicy | FieldReadFunction, + date?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + type?: FieldPolicy | FieldReadFunction +}; +export type QueryKeySpecifier = ('_entities' | '_service' | 'address' | 'addressValidationRules' | 'app' | 'appExtension' | 'appExtensions' | 'apps' | 'appsInstallations' | 'attribute' | 'attributes' | 'categories' | 'category' | 'channel' | 'channels' | 'checkout' | 'checkoutLines' | 'checkouts' | 'collection' | 'collections' | 'customers' | 'digitalContent' | 'digitalContents' | 'draftOrders' | 'exportFile' | 'exportFiles' | 'giftCard' | 'giftCardCurrencies' | 'giftCardSettings' | 'giftCardTags' | 'giftCards' | 'homepageEvents' | 'me' | 'menu' | 'menuItem' | 'menuItems' | 'menus' | 'order' | 'orderByToken' | 'orderSettings' | 'orders' | 'ordersTotal' | 'page' | 'pageType' | 'pageTypes' | 'pages' | 'payment' | 'payments' | 'permissionGroup' | 'permissionGroups' | 'plugin' | 'plugins' | 'product' | 'productType' | 'productTypes' | 'productVariant' | 'productVariants' | 'products' | 'promotion' | 'promotions' | 'reportProductSales' | 'sale' | 'sales' | 'shippingZone' | 'shippingZones' | 'shop' | 'staffUsers' | 'stock' | 'stocks' | 'taxClass' | 'taxClasses' | 'taxConfiguration' | 'taxConfigurations' | 'taxCountryConfiguration' | 'taxCountryConfigurations' | 'taxTypes' | 'transaction' | 'translation' | 'translations' | 'user' | 'voucher' | 'vouchers' | 'warehouse' | 'warehouses' | 'webhook' | 'webhookEvents' | 'webhookSamplePayload' | QueryKeySpecifier)[]; export type QueryFieldPolicy = { _entities?: FieldPolicy | FieldReadFunction, _service?: FieldPolicy | FieldReadFunction, @@ -4841,6 +5131,8 @@ export type QueryFieldPolicy = { productVariant?: FieldPolicy | FieldReadFunction, productVariants?: FieldPolicy | FieldReadFunction, products?: FieldPolicy | FieldReadFunction, + promotion?: FieldPolicy | FieldReadFunction, + promotions?: FieldPolicy | FieldReadFunction, reportProductSales?: FieldPolicy | FieldReadFunction, sale?: FieldPolicy | FieldReadFunction, sales?: FieldPolicy | FieldReadFunction, @@ -6163,7 +6455,7 @@ export type VerifyTokenFieldPolicy = { payload?: FieldPolicy | FieldReadFunction, user?: FieldPolicy | FieldReadFunction }; -export type VoucherKeySpecifier = ('applyOncePerCustomer' | 'applyOncePerOrder' | 'categories' | 'channelListings' | 'code' | 'codes' | 'collections' | 'countries' | 'currency' | 'discountValue' | 'discountValueType' | 'endDate' | 'id' | 'metadata' | 'metafield' | 'metafields' | 'minCheckoutItemsQuantity' | 'minSpent' | 'name' | 'onlyForStaff' | 'privateMetadata' | 'privateMetafield' | 'privateMetafields' | 'products' | 'startDate' | 'translation' | 'type' | 'usageLimit' | 'used' | 'variants' | VoucherKeySpecifier)[]; +export type VoucherKeySpecifier = ('applyOncePerCustomer' | 'applyOncePerOrder' | 'categories' | 'channelListings' | 'code' | 'codes' | 'collections' | 'countries' | 'currency' | 'discountValue' | 'discountValueType' | 'endDate' | 'id' | 'metadata' | 'metafield' | 'metafields' | 'minCheckoutItemsQuantity' | 'minSpent' | 'name' | 'onlyForStaff' | 'privateMetadata' | 'privateMetafield' | 'privateMetafields' | 'products' | 'singleUse' | 'startDate' | 'translation' | 'type' | 'usageLimit' | 'used' | 'variants' | VoucherKeySpecifier)[]; export type VoucherFieldPolicy = { applyOncePerCustomer?: FieldPolicy | FieldReadFunction, applyOncePerOrder?: FieldPolicy | FieldReadFunction, @@ -6189,6 +6481,7 @@ export type VoucherFieldPolicy = { privateMetafield?: FieldPolicy | FieldReadFunction, privateMetafields?: FieldPolicy | FieldReadFunction, products?: FieldPolicy | FieldReadFunction, + singleUse?: FieldPolicy | FieldReadFunction, startDate?: FieldPolicy | FieldReadFunction, translation?: FieldPolicy | FieldReadFunction, type?: FieldPolicy | FieldReadFunction, @@ -6222,12 +6515,25 @@ export type VoucherChannelListingUpdateFieldPolicy = { errors?: FieldPolicy | FieldReadFunction, voucher?: FieldPolicy | FieldReadFunction }; -export type VoucherCodeKeySpecifier = ('code' | 'usageLimit' | 'used' | VoucherCodeKeySpecifier)[]; +export type VoucherCodeKeySpecifier = ('code' | 'id' | 'isActive' | 'used' | VoucherCodeKeySpecifier)[]; export type VoucherCodeFieldPolicy = { code?: FieldPolicy | FieldReadFunction, - usageLimit?: FieldPolicy | FieldReadFunction, + id?: FieldPolicy | FieldReadFunction, + isActive?: FieldPolicy | FieldReadFunction, used?: FieldPolicy | FieldReadFunction }; +export type VoucherCodeBulkDeleteKeySpecifier = ('count' | 'errors' | VoucherCodeBulkDeleteKeySpecifier)[]; +export type VoucherCodeBulkDeleteFieldPolicy = { + count?: FieldPolicy | FieldReadFunction, + errors?: FieldPolicy | FieldReadFunction +}; +export type VoucherCodeBulkDeleteErrorKeySpecifier = ('code' | 'message' | 'path' | 'voucherCodes' | VoucherCodeBulkDeleteErrorKeySpecifier)[]; +export type VoucherCodeBulkDeleteErrorFieldPolicy = { + code?: FieldPolicy | FieldReadFunction, + message?: FieldPolicy | FieldReadFunction, + path?: FieldPolicy | FieldReadFunction, + voucherCodes?: FieldPolicy | FieldReadFunction +}; export type VoucherCodeCountableConnectionKeySpecifier = ('edges' | 'pageInfo' | 'totalCount' | VoucherCodeCountableConnectionKeySpecifier)[]; export type VoucherCodeCountableConnectionFieldPolicy = { edges?: FieldPolicy | FieldReadFunction, @@ -8802,6 +9108,166 @@ export type StrictTypedTypePolicies = { keyFields?: false | ProductVariantUpdatedKeySpecifier | (() => undefined | ProductVariantUpdatedKeySpecifier), fields?: ProductVariantUpdatedFieldPolicy, }, + Promotion?: Omit & { + keyFields?: false | PromotionKeySpecifier | (() => undefined | PromotionKeySpecifier), + fields?: PromotionFieldPolicy, + }, + PromotionBulkDelete?: Omit & { + keyFields?: false | PromotionBulkDeleteKeySpecifier | (() => undefined | PromotionBulkDeleteKeySpecifier), + fields?: PromotionBulkDeleteFieldPolicy, + }, + PromotionCountableConnection?: Omit & { + keyFields?: false | PromotionCountableConnectionKeySpecifier | (() => undefined | PromotionCountableConnectionKeySpecifier), + fields?: PromotionCountableConnectionFieldPolicy, + }, + PromotionCountableEdge?: Omit & { + keyFields?: false | PromotionCountableEdgeKeySpecifier | (() => undefined | PromotionCountableEdgeKeySpecifier), + fields?: PromotionCountableEdgeFieldPolicy, + }, + PromotionCreate?: Omit & { + keyFields?: false | PromotionCreateKeySpecifier | (() => undefined | PromotionCreateKeySpecifier), + fields?: PromotionCreateFieldPolicy, + }, + PromotionCreateError?: Omit & { + keyFields?: false | PromotionCreateErrorKeySpecifier | (() => undefined | PromotionCreateErrorKeySpecifier), + fields?: PromotionCreateErrorFieldPolicy, + }, + PromotionCreated?: Omit & { + keyFields?: false | PromotionCreatedKeySpecifier | (() => undefined | PromotionCreatedKeySpecifier), + fields?: PromotionCreatedFieldPolicy, + }, + PromotionCreatedEvent?: Omit & { + keyFields?: false | PromotionCreatedEventKeySpecifier | (() => undefined | PromotionCreatedEventKeySpecifier), + fields?: PromotionCreatedEventFieldPolicy, + }, + PromotionDelete?: Omit & { + keyFields?: false | PromotionDeleteKeySpecifier | (() => undefined | PromotionDeleteKeySpecifier), + fields?: PromotionDeleteFieldPolicy, + }, + PromotionDeleteError?: Omit & { + keyFields?: false | PromotionDeleteErrorKeySpecifier | (() => undefined | PromotionDeleteErrorKeySpecifier), + fields?: PromotionDeleteErrorFieldPolicy, + }, + PromotionDeleted?: Omit & { + keyFields?: false | PromotionDeletedKeySpecifier | (() => undefined | PromotionDeletedKeySpecifier), + fields?: PromotionDeletedFieldPolicy, + }, + PromotionEnded?: Omit & { + keyFields?: false | PromotionEndedKeySpecifier | (() => undefined | PromotionEndedKeySpecifier), + fields?: PromotionEndedFieldPolicy, + }, + PromotionEndedEvent?: Omit & { + keyFields?: false | PromotionEndedEventKeySpecifier | (() => undefined | PromotionEndedEventKeySpecifier), + fields?: PromotionEndedEventFieldPolicy, + }, + PromotionEventInterface?: Omit & { + keyFields?: false | PromotionEventInterfaceKeySpecifier | (() => undefined | PromotionEventInterfaceKeySpecifier), + fields?: PromotionEventInterfaceFieldPolicy, + }, + PromotionRule?: Omit & { + keyFields?: false | PromotionRuleKeySpecifier | (() => undefined | PromotionRuleKeySpecifier), + fields?: PromotionRuleFieldPolicy, + }, + PromotionRuleCreate?: Omit & { + keyFields?: false | PromotionRuleCreateKeySpecifier | (() => undefined | PromotionRuleCreateKeySpecifier), + fields?: PromotionRuleCreateFieldPolicy, + }, + PromotionRuleCreateError?: Omit & { + keyFields?: false | PromotionRuleCreateErrorKeySpecifier | (() => undefined | PromotionRuleCreateErrorKeySpecifier), + fields?: PromotionRuleCreateErrorFieldPolicy, + }, + PromotionRuleCreated?: Omit & { + keyFields?: false | PromotionRuleCreatedKeySpecifier | (() => undefined | PromotionRuleCreatedKeySpecifier), + fields?: PromotionRuleCreatedFieldPolicy, + }, + PromotionRuleCreatedEvent?: Omit & { + keyFields?: false | PromotionRuleCreatedEventKeySpecifier | (() => undefined | PromotionRuleCreatedEventKeySpecifier), + fields?: PromotionRuleCreatedEventFieldPolicy, + }, + PromotionRuleDelete?: Omit & { + keyFields?: false | PromotionRuleDeleteKeySpecifier | (() => undefined | PromotionRuleDeleteKeySpecifier), + fields?: PromotionRuleDeleteFieldPolicy, + }, + PromotionRuleDeleteError?: Omit & { + keyFields?: false | PromotionRuleDeleteErrorKeySpecifier | (() => undefined | PromotionRuleDeleteErrorKeySpecifier), + fields?: PromotionRuleDeleteErrorFieldPolicy, + }, + PromotionRuleDeleted?: Omit & { + keyFields?: false | PromotionRuleDeletedKeySpecifier | (() => undefined | PromotionRuleDeletedKeySpecifier), + fields?: PromotionRuleDeletedFieldPolicy, + }, + PromotionRuleDeletedEvent?: Omit & { + keyFields?: false | PromotionRuleDeletedEventKeySpecifier | (() => undefined | PromotionRuleDeletedEventKeySpecifier), + fields?: PromotionRuleDeletedEventFieldPolicy, + }, + PromotionRuleEventInterface?: Omit & { + keyFields?: false | PromotionRuleEventInterfaceKeySpecifier | (() => undefined | PromotionRuleEventInterfaceKeySpecifier), + fields?: PromotionRuleEventInterfaceFieldPolicy, + }, + PromotionRuleTranslatableContent?: Omit & { + keyFields?: false | PromotionRuleTranslatableContentKeySpecifier | (() => undefined | PromotionRuleTranslatableContentKeySpecifier), + fields?: PromotionRuleTranslatableContentFieldPolicy, + }, + PromotionRuleTranslate?: Omit & { + keyFields?: false | PromotionRuleTranslateKeySpecifier | (() => undefined | PromotionRuleTranslateKeySpecifier), + fields?: PromotionRuleTranslateFieldPolicy, + }, + PromotionRuleTranslation?: Omit & { + keyFields?: false | PromotionRuleTranslationKeySpecifier | (() => undefined | PromotionRuleTranslationKeySpecifier), + fields?: PromotionRuleTranslationFieldPolicy, + }, + PromotionRuleUpdate?: Omit & { + keyFields?: false | PromotionRuleUpdateKeySpecifier | (() => undefined | PromotionRuleUpdateKeySpecifier), + fields?: PromotionRuleUpdateFieldPolicy, + }, + PromotionRuleUpdateError?: Omit & { + keyFields?: false | PromotionRuleUpdateErrorKeySpecifier | (() => undefined | PromotionRuleUpdateErrorKeySpecifier), + fields?: PromotionRuleUpdateErrorFieldPolicy, + }, + PromotionRuleUpdated?: Omit & { + keyFields?: false | PromotionRuleUpdatedKeySpecifier | (() => undefined | PromotionRuleUpdatedKeySpecifier), + fields?: PromotionRuleUpdatedFieldPolicy, + }, + PromotionRuleUpdatedEvent?: Omit & { + keyFields?: false | PromotionRuleUpdatedEventKeySpecifier | (() => undefined | PromotionRuleUpdatedEventKeySpecifier), + fields?: PromotionRuleUpdatedEventFieldPolicy, + }, + PromotionStarted?: Omit & { + keyFields?: false | PromotionStartedKeySpecifier | (() => undefined | PromotionStartedKeySpecifier), + fields?: PromotionStartedFieldPolicy, + }, + PromotionStartedEvent?: Omit & { + keyFields?: false | PromotionStartedEventKeySpecifier | (() => undefined | PromotionStartedEventKeySpecifier), + fields?: PromotionStartedEventFieldPolicy, + }, + PromotionTranslatableContent?: Omit & { + keyFields?: false | PromotionTranslatableContentKeySpecifier | (() => undefined | PromotionTranslatableContentKeySpecifier), + fields?: PromotionTranslatableContentFieldPolicy, + }, + PromotionTranslate?: Omit & { + keyFields?: false | PromotionTranslateKeySpecifier | (() => undefined | PromotionTranslateKeySpecifier), + fields?: PromotionTranslateFieldPolicy, + }, + PromotionTranslation?: Omit & { + keyFields?: false | PromotionTranslationKeySpecifier | (() => undefined | PromotionTranslationKeySpecifier), + fields?: PromotionTranslationFieldPolicy, + }, + PromotionUpdate?: Omit & { + keyFields?: false | PromotionUpdateKeySpecifier | (() => undefined | PromotionUpdateKeySpecifier), + fields?: PromotionUpdateFieldPolicy, + }, + PromotionUpdateError?: Omit & { + keyFields?: false | PromotionUpdateErrorKeySpecifier | (() => undefined | PromotionUpdateErrorKeySpecifier), + fields?: PromotionUpdateErrorFieldPolicy, + }, + PromotionUpdated?: Omit & { + keyFields?: false | PromotionUpdatedKeySpecifier | (() => undefined | PromotionUpdatedKeySpecifier), + fields?: PromotionUpdatedFieldPolicy, + }, + PromotionUpdatedEvent?: Omit & { + keyFields?: false | PromotionUpdatedEventKeySpecifier | (() => undefined | PromotionUpdatedEventKeySpecifier), + fields?: PromotionUpdatedEventFieldPolicy, + }, Query?: Omit & { keyFields?: false | QueryKeySpecifier | (() => undefined | QueryKeySpecifier), fields?: QueryFieldPolicy, @@ -9498,6 +9964,14 @@ export type StrictTypedTypePolicies = { keyFields?: false | VoucherCodeKeySpecifier | (() => undefined | VoucherCodeKeySpecifier), fields?: VoucherCodeFieldPolicy, }, + VoucherCodeBulkDelete?: Omit & { + keyFields?: false | VoucherCodeBulkDeleteKeySpecifier | (() => undefined | VoucherCodeBulkDeleteKeySpecifier), + fields?: VoucherCodeBulkDeleteFieldPolicy, + }, + VoucherCodeBulkDeleteError?: Omit & { + keyFields?: false | VoucherCodeBulkDeleteErrorKeySpecifier | (() => undefined | VoucherCodeBulkDeleteErrorKeySpecifier), + fields?: VoucherCodeBulkDeleteErrorFieldPolicy, + }, VoucherCodeCountableConnection?: Omit & { keyFields?: false | VoucherCodeCountableConnectionKeySpecifier | (() => undefined | VoucherCodeCountableConnectionKeySpecifier), fields?: VoucherCodeCountableConnectionFieldPolicy, diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index aa99181bfd4..ef79119da6a 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -883,6 +883,21 @@ export type CatalogueInput = { variants?: InputMaybe>; }; +export type CataloguePredicateInput = { + /** List of conditions that must be met. */ + AND?: InputMaybe>; + /** A list of conditions of which at least one must be met. */ + OR?: InputMaybe>; + /** Defines the category conditions to be met. */ + categoryPredicate?: InputMaybe; + /** Defines the collection conditions to be met. */ + collectionPredicate?: InputMaybe; + /** Defines the product conditions to be met. */ + productPredicate?: InputMaybe; + /** Defines the product variant conditions to be met. */ + variantPredicate?: InputMaybe; +}; + export type CategoryFilterInput = { ids?: InputMaybe>; metadata?: InputMaybe>; @@ -1902,6 +1917,22 @@ export type DateRangeInput = { lte?: InputMaybe; }; +/** + * Define the filtering options for date time fields. + * + * Added in Saleor 3.11. + * + * Note: this API is currently in Feature Preview and can be subject to changes at later point. + */ +export type DateTimeFilterInput = { + /** The value equal to. */ + eq?: InputMaybe; + /** The value included in. */ + oneOf?: InputMaybe>; + /** The value in range. */ + range?: InputMaybe; +}; + export type DateTimeRangeInput = { /** Start date. */ gte?: InputMaybe; @@ -3861,6 +3892,7 @@ export type OrderDiscountCommonInput = { /** An enumeration. */ export enum OrderDiscountType { MANUAL = 'MANUAL', + PROMOTION = 'PROMOTION', SALE = 'SALE', VOUCHER = 'VOUCHER' } @@ -5822,7 +5854,196 @@ export type ProductWhereInput = { /** Filter by stock of the product variant. */ stocks?: InputMaybe; /** Filter by when was the most recent update. */ - updatedAt?: InputMaybe; + updatedAt?: InputMaybe; +}; + +/** An enumeration. */ +export enum PromotionCreateErrorCode { + GRAPHQL_ERROR = 'GRAPHQL_ERROR', + INVALID = 'INVALID', + INVALID_PRECISION = 'INVALID_PRECISION', + MULTIPLE_CURRENCIES_NOT_ALLOWED = 'MULTIPLE_CURRENCIES_NOT_ALLOWED', + NOT_FOUND = 'NOT_FOUND', + REQUIRED = 'REQUIRED' +} + +export type PromotionCreateInput = { + /** Promotion description. */ + description?: InputMaybe; + /** The end date of the promotion in ISO 8601 format. */ + endDate?: InputMaybe; + /** Promotion name. */ + name: Scalars['String']; + /** List of promotion rules. */ + rules?: InputMaybe>; + /** The start date of the promotion in ISO 8601 format. */ + startDate?: InputMaybe; +}; + +/** An enumeration. */ +export enum PromotionDeleteErrorCode { + GRAPHQL_ERROR = 'GRAPHQL_ERROR', + NOT_FOUND = 'NOT_FOUND' +} + +/** An enumeration. */ +export enum PromotionEventsEnum { + PROMOTION_CREATED = 'PROMOTION_CREATED', + PROMOTION_ENDED = 'PROMOTION_ENDED', + PROMOTION_STARTED = 'PROMOTION_STARTED', + PROMOTION_UPDATED = 'PROMOTION_UPDATED', + RULE_CREATED = 'RULE_CREATED', + RULE_DELETED = 'RULE_DELETED', + RULE_UPDATED = 'RULE_UPDATED' +} + +/** An enumeration. */ +export enum PromotionRuleCreateErrorCode { + GRAPHQL_ERROR = 'GRAPHQL_ERROR', + INVALID = 'INVALID', + INVALID_PRECISION = 'INVALID_PRECISION', + MULTIPLE_CURRENCIES_NOT_ALLOWED = 'MULTIPLE_CURRENCIES_NOT_ALLOWED', + NOT_FOUND = 'NOT_FOUND', + REQUIRED = 'REQUIRED' +} + +export type PromotionRuleCreateInput = { + /** Defines the conditions on the catalogue level that must be met for the reward to be applied. */ + cataloguePredicate?: InputMaybe; + /** List of channel ids to which the rule should apply to. */ + channels?: InputMaybe>; + /** Promotion rule description. */ + description?: InputMaybe; + /** Promotion rule name. */ + name?: InputMaybe; + /** The ID of the promotion that rule belongs to. */ + promotion: Scalars['ID']; + /** Defines the discount value. Required when catalogue predicate is provided. */ + rewardValue?: InputMaybe; + /** Defines the promotion rule reward value type. Must be provided together with reward value. */ + rewardValueType?: InputMaybe; +}; + +/** An enumeration. */ +export enum PromotionRuleDeleteErrorCode { + GRAPHQL_ERROR = 'GRAPHQL_ERROR', + NOT_FOUND = 'NOT_FOUND' +} + +export type PromotionRuleInput = { + /** Defines the conditions on the catalogue level that must be met for the reward to be applied. */ + cataloguePredicate?: InputMaybe; + /** List of channel ids to which the rule should apply to. */ + channels?: InputMaybe>; + /** Promotion rule description. */ + description?: InputMaybe; + /** Promotion rule name. */ + name?: InputMaybe; + /** Defines the discount value. Required when catalogue predicate is provided. */ + rewardValue?: InputMaybe; + /** Defines the promotion rule reward value type. Must be provided together with reward value. */ + rewardValueType?: InputMaybe; +}; + +export type PromotionRuleTranslationInput = { + /** + * Translated promotion description. + * + * Rich text format. For reference see https://editorjs.io/ + */ + description?: InputMaybe; + name?: InputMaybe; +}; + +/** An enumeration. */ +export enum PromotionRuleUpdateErrorCode { + DUPLICATED_INPUT_ITEM = 'DUPLICATED_INPUT_ITEM', + GRAPHQL_ERROR = 'GRAPHQL_ERROR', + INVALID = 'INVALID', + INVALID_PRECISION = 'INVALID_PRECISION', + MISSING_CHANNELS = 'MISSING_CHANNELS', + MULTIPLE_CURRENCIES_NOT_ALLOWED = 'MULTIPLE_CURRENCIES_NOT_ALLOWED', + NOT_FOUND = 'NOT_FOUND' +} + +export type PromotionRuleUpdateInput = { + /** List of channel ids to remove. */ + addChannels?: InputMaybe>; + /** Defines the conditions on the catalogue level that must be met for the reward to be applied. */ + cataloguePredicate?: InputMaybe; + /** Promotion rule description. */ + description?: InputMaybe; + /** Promotion rule name. */ + name?: InputMaybe; + /** List of channel ids to remove. */ + removeChannels?: InputMaybe>; + /** Defines the discount value. Required when catalogue predicate is provided. */ + rewardValue?: InputMaybe; + /** Defines the promotion rule reward value type. Must be provided together with reward value. */ + rewardValueType?: InputMaybe; +}; + +export enum PromotionSortField { + /** Sort promotions by created at. */ + CREATED_AT = 'CREATED_AT', + /** Sort promotions by end date. */ + END_DATE = 'END_DATE', + /** Sort promotions by name. */ + NAME = 'NAME', + /** Sort promotions by start date. */ + START_DATE = 'START_DATE' +} + +export type PromotionSortingInput = { + /** Specifies the direction in which to sort promotions. */ + direction: OrderDirection; + /** Sort promotions by the selected field. */ + field: PromotionSortField; +}; + +export type PromotionTranslationInput = { + /** + * Translated promotion description. + * + * Rich text format. For reference see https://editorjs.io/ + */ + description?: InputMaybe; + name?: InputMaybe; +}; + +/** An enumeration. */ +export enum PromotionUpdateErrorCode { + GRAPHQL_ERROR = 'GRAPHQL_ERROR', + INVALID = 'INVALID', + NOT_FOUND = 'NOT_FOUND', + REQUIRED = 'REQUIRED' +} + +export type PromotionUpdateInput = { + /** Promotion description. */ + description?: InputMaybe; + /** The end date of the promotion in ISO 8601 format. */ + endDate?: InputMaybe; + /** Promotion name. */ + name?: InputMaybe; + /** The start date of the promotion in ISO 8601 format. */ + startDate?: InputMaybe; +}; + +export type PromotionWhereInput = { + /** List of conditions that must be met. */ + AND?: InputMaybe>; + /** A list of conditions of which at least one must be met. */ + OR?: InputMaybe>; + /** Filter promotions by end date. */ + endDate?: InputMaybe; + ids?: InputMaybe>; + isOldSale?: InputMaybe; + metadata?: InputMaybe>; + /** Filter by promotion name. */ + name?: InputMaybe; + /** Filter promotions by start date. */ + startDate?: InputMaybe; }; export type PublishableChannelListingInput = { @@ -5856,6 +6077,12 @@ export enum ReportingPeriod { TODAY = 'TODAY' } +/** An enumeration. */ +export enum RewardValueTypeEnum { + FIXED = 'FIXED', + PERCENTAGE = 'PERCENTAGE' +} + export type SaleChannelListingAddInput = { /** ID of a channel. */ channelId: Scalars['ID']; @@ -6838,6 +7065,8 @@ export enum TranslatableKinds { MENU_ITEM = 'MENU_ITEM', PAGE = 'PAGE', PRODUCT = 'PRODUCT', + PROMOTION = 'PROMOTION', + PROMOTION_RULE = 'PROMOTION_RULE', SALE = 'SALE', SHIPPING_METHOD = 'SHIPPING_METHOD', VARIANT = 'VARIANT', @@ -6996,16 +7225,21 @@ export type VoucherChannelListingInput = { removeChannels?: InputMaybe>; }; +/** An enumeration. */ +export enum VoucherCodeBulkDeleteErrorCode { + GRAPHQL_ERROR = 'GRAPHQL_ERROR', + INVALID = 'INVALID', + NOT_FOUND = 'NOT_FOUND' +} + /** * Represents voucher code data. * - * Added in Saleor 3.16. + * Added in Saleor 3.18. */ export type VoucherCodeInput = { /** Code to use the voucher. */ code?: InputMaybe; - /** Code usage limit. */ - usageLimit?: InputMaybe; }; export enum VoucherDiscountType { @@ -7036,7 +7270,7 @@ export type VoucherInput = { /** * Codes to use the voucher. * - * Added in Saleor 3.16. + * Added in Saleor 3.18. */ codes?: InputMaybe>; /** Collections discounted by the voucher. */ @@ -7055,11 +7289,17 @@ export type VoucherInput = { onlyForStaff?: InputMaybe; /** Products discounted by the voucher. */ products?: InputMaybe>; + /** + * When set to 'True', each voucher is limited to a single use; otherwise, usage remains unrestricted. + * + * Added in Saleor 3.18. + */ + singleUse?: InputMaybe; /** Start date of the voucher in ISO 8601 format. */ startDate?: InputMaybe; /** Voucher type: PRODUCT, CATEGORY SHIPPING or ENTIRE_ORDER. */ type?: InputMaybe; - /** Limit number of times this voucher can be used in total.This field will be removed in Saleor 4.0. */ + /** Limit number of times this voucher can be used in total. */ usageLimit?: InputMaybe; /** * Variants discounted by the voucher. @@ -7070,7 +7310,11 @@ export type VoucherInput = { }; export enum VoucherSortField { - /** Sort vouchers by code. */ + /** + * Sort vouchers by code. + * + * DEPRECATED: this field will be removed in Saleor 4.0. + */ CODE = 'CODE', /** Sort vouchers by end date. */ END_DATE = 'END_DATE', @@ -7080,6 +7324,12 @@ export enum VoucherSortField { * This option requires a channel filter to work as the values can vary between channels. */ MINIMUM_SPENT_AMOUNT = 'MINIMUM_SPENT_AMOUNT', + /** + * Sort vouchers by name. + * + * Added in Saleor 3.18. + */ + NAME = 'NAME', /** Sort vouchers by start date. */ START_DATE = 'START_DATE', /** Sort vouchers by type. */ @@ -7570,6 +7820,22 @@ export enum WebhookEventTypeAsyncEnum { PRODUCT_VARIANT_STOCK_UPDATED = 'PRODUCT_VARIANT_STOCK_UPDATED', /** A product variant is updated. */ PRODUCT_VARIANT_UPDATED = 'PRODUCT_VARIANT_UPDATED', + /** A promotion is created. */ + PROMOTION_CREATED = 'PROMOTION_CREATED', + /** A promotion is deleted. */ + PROMOTION_DELETED = 'PROMOTION_DELETED', + /** A promotion is deactivated. */ + PROMOTION_ENDED = 'PROMOTION_ENDED', + /** A promotion rule is created. */ + PROMOTION_RULE_CREATED = 'PROMOTION_RULE_CREATED', + /** A promotion rule is deleted. */ + PROMOTION_RULE_DELETED = 'PROMOTION_RULE_DELETED', + /** A promotion rule is updated. */ + PROMOTION_RULE_UPDATED = 'PROMOTION_RULE_UPDATED', + /** A promotion is activated. */ + PROMOTION_STARTED = 'PROMOTION_STARTED', + /** A promotion is updated. */ + PROMOTION_UPDATED = 'PROMOTION_UPDATED', /** A sale is created. */ SALE_CREATED = 'SALE_CREATED', /** A sale is deleted. */ @@ -7983,6 +8249,22 @@ export enum WebhookEventTypeEnum { PRODUCT_VARIANT_STOCK_UPDATED = 'PRODUCT_VARIANT_STOCK_UPDATED', /** A product variant is updated. */ PRODUCT_VARIANT_UPDATED = 'PRODUCT_VARIANT_UPDATED', + /** A promotion is created. */ + PROMOTION_CREATED = 'PROMOTION_CREATED', + /** A promotion is deleted. */ + PROMOTION_DELETED = 'PROMOTION_DELETED', + /** A promotion is deactivated. */ + PROMOTION_ENDED = 'PROMOTION_ENDED', + /** A promotion rule is created. */ + PROMOTION_RULE_CREATED = 'PROMOTION_RULE_CREATED', + /** A promotion rule is deleted. */ + PROMOTION_RULE_DELETED = 'PROMOTION_RULE_DELETED', + /** A promotion rule is updated. */ + PROMOTION_RULE_UPDATED = 'PROMOTION_RULE_UPDATED', + /** A promotion is activated. */ + PROMOTION_STARTED = 'PROMOTION_STARTED', + /** A promotion is updated. */ + PROMOTION_UPDATED = 'PROMOTION_UPDATED', /** A sale is created. */ SALE_CREATED = 'SALE_CREATED', /** A sale is deleted. */ @@ -8266,6 +8548,14 @@ export enum WebhookSampleEventTypeEnum { PRODUCT_VARIANT_OUT_OF_STOCK = 'PRODUCT_VARIANT_OUT_OF_STOCK', PRODUCT_VARIANT_STOCK_UPDATED = 'PRODUCT_VARIANT_STOCK_UPDATED', PRODUCT_VARIANT_UPDATED = 'PRODUCT_VARIANT_UPDATED', + PROMOTION_CREATED = 'PROMOTION_CREATED', + PROMOTION_DELETED = 'PROMOTION_DELETED', + PROMOTION_ENDED = 'PROMOTION_ENDED', + PROMOTION_RULE_CREATED = 'PROMOTION_RULE_CREATED', + PROMOTION_RULE_DELETED = 'PROMOTION_RULE_DELETED', + PROMOTION_RULE_UPDATED = 'PROMOTION_RULE_UPDATED', + PROMOTION_STARTED = 'PROMOTION_STARTED', + PROMOTION_UPDATED = 'PROMOTION_UPDATED', SALE_CREATED = 'SALE_CREATED', SALE_DELETED = 'SALE_DELETED', SALE_TOGGLE = 'SALE_TOGGLE', @@ -9563,6 +9853,8 @@ type Metadata_ProductType_Fragment = { __typename: 'ProductType', metadata: Arra type Metadata_ProductVariant_Fragment = { __typename: 'ProductVariant', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +type Metadata_Promotion_Fragment = { __typename: 'Promotion', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; + type Metadata_Sale_Fragment = { __typename: 'Sale', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; type Metadata_ShippingMethod_Fragment = { __typename: 'ShippingMethod', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; @@ -9585,7 +9877,7 @@ type Metadata_Voucher_Fragment = { __typename: 'Voucher', metadata: Array<{ __ty type Metadata_Warehouse_Fragment = { __typename: 'Warehouse', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; -export type MetadataFragment = Metadata_Address_Fragment | Metadata_App_Fragment | Metadata_Attribute_Fragment | Metadata_Category_Fragment | Metadata_Channel_Fragment | Metadata_Checkout_Fragment | Metadata_CheckoutLine_Fragment | Metadata_Collection_Fragment | Metadata_DigitalContent_Fragment | Metadata_Fulfillment_Fragment | Metadata_GiftCard_Fragment | Metadata_Invoice_Fragment | Metadata_Menu_Fragment | Metadata_MenuItem_Fragment | Metadata_Order_Fragment | Metadata_OrderLine_Fragment | Metadata_Page_Fragment | Metadata_PageType_Fragment | Metadata_Payment_Fragment | Metadata_Product_Fragment | Metadata_ProductMedia_Fragment | Metadata_ProductType_Fragment | Metadata_ProductVariant_Fragment | Metadata_Sale_Fragment | Metadata_ShippingMethod_Fragment | Metadata_ShippingMethodType_Fragment | Metadata_ShippingZone_Fragment | Metadata_Shop_Fragment | Metadata_TaxClass_Fragment | Metadata_TaxConfiguration_Fragment | Metadata_TransactionItem_Fragment | Metadata_User_Fragment | Metadata_Voucher_Fragment | Metadata_Warehouse_Fragment; +export type MetadataFragment = Metadata_Address_Fragment | Metadata_App_Fragment | Metadata_Attribute_Fragment | Metadata_Category_Fragment | Metadata_Channel_Fragment | Metadata_Checkout_Fragment | Metadata_CheckoutLine_Fragment | Metadata_Collection_Fragment | Metadata_DigitalContent_Fragment | Metadata_Fulfillment_Fragment | Metadata_GiftCard_Fragment | Metadata_Invoice_Fragment | Metadata_Menu_Fragment | Metadata_MenuItem_Fragment | Metadata_Order_Fragment | Metadata_OrderLine_Fragment | Metadata_Page_Fragment | Metadata_PageType_Fragment | Metadata_Payment_Fragment | Metadata_Product_Fragment | Metadata_ProductMedia_Fragment | Metadata_ProductType_Fragment | Metadata_ProductVariant_Fragment | Metadata_Promotion_Fragment | Metadata_Sale_Fragment | Metadata_ShippingMethod_Fragment | Metadata_ShippingMethodType_Fragment | Metadata_ShippingZone_Fragment | Metadata_Shop_Fragment | Metadata_TaxClass_Fragment | Metadata_TaxConfiguration_Fragment | Metadata_TransactionItem_Fragment | Metadata_User_Fragment | Metadata_Voucher_Fragment | Metadata_Warehouse_Fragment; export type MenuFragment = { __typename: 'Menu', id: string, name: string, items: Array<{ __typename: 'MenuItem', id: string }> | null }; @@ -11615,7 +11907,7 @@ export type CategoryTranslationsQueryVariables = Exact<{ }>; -export type CategoryTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent', translation: { __typename: 'CategoryTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null, category: { __typename: 'Category', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type CategoryTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent', translation: { __typename: 'CategoryTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null, category: { __typename: 'Category', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type CollectionTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11626,7 +11918,7 @@ export type CollectionTranslationsQueryVariables = Exact<{ }>; -export type CollectionTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent', collection: { __typename: 'Collection', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'CollectionTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type CollectionTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent', collection: { __typename: 'Collection', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'CollectionTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type ProductTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11637,7 +11929,7 @@ export type ProductTranslationsQueryVariables = Exact<{ }>; -export type ProductTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent', product: { __typename: 'Product', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'ProductTranslation', id: string, seoTitle: string | null, seoDescription: string | null, name: string | null, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type ProductTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent', product: { __typename: 'Product', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'ProductTranslation', id: string, seoTitle: string | null, seoDescription: string | null, name: string | null, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type PageTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11648,7 +11940,7 @@ export type PageTranslationsQueryVariables = Exact<{ }>; -export type PageTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent', page: { __typename: 'Page', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string } | null, translation: { __typename: 'PageTranslation', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type PageTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent', page: { __typename: 'Page', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string } | null, translation: { __typename: 'PageTranslation', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type VoucherTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11659,7 +11951,7 @@ export type VoucherTranslationsQueryVariables = Exact<{ }>; -export type VoucherTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent', name: string | null, voucher: { __typename: 'Voucher', id: string, name: string | null } | null, translation: { __typename: 'VoucherTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type VoucherTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent', name: string | null, voucher: { __typename: 'Voucher', id: string, name: string | null } | null, translation: { __typename: 'VoucherTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type SaleTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11670,7 +11962,7 @@ export type SaleTranslationsQueryVariables = Exact<{ }>; -export type SaleTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent', sale: { __typename: 'Sale', id: string, name: string } | null, translation: { __typename: 'SaleTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type SaleTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent', sale: { __typename: 'Sale', id: string, name: string } | null, translation: { __typename: 'SaleTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type AttributeTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11681,7 +11973,7 @@ export type AttributeTranslationsQueryVariables = Exact<{ }>; -export type AttributeTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent', id: string, name: string, translation: { __typename: 'AttributeTranslation', id: string, name: string } | null, attribute: { __typename: 'Attribute', id: string, name: string | null, inputType: AttributeInputTypeEnum | null } | null } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type AttributeTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent', id: string, name: string, translation: { __typename: 'AttributeTranslation', id: string, name: string } | null, attribute: { __typename: 'Attribute', id: string, name: string | null, inputType: AttributeInputTypeEnum | null } | null } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type ShippingMethodTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11692,7 +11984,7 @@ export type ShippingMethodTranslationsQueryVariables = Exact<{ }>; -export type ShippingMethodTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent', id: string, name: string, description: any | null, shippingMethod: { __typename: 'ShippingMethodType', id: string } | null, translation: { __typename: 'ShippingMethodTranslation', id: string, name: string, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type ShippingMethodTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent', id: string, name: string, description: any | null, shippingMethod: { __typename: 'ShippingMethodType', id: string } | null, translation: { __typename: 'ShippingMethodTranslation', id: string, name: string, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type MenuItemTranslationsQueryVariables = Exact<{ language: LanguageCodeEnum; @@ -11703,7 +11995,7 @@ export type MenuItemTranslationsQueryVariables = Exact<{ }>; -export type MenuItemTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent', translation: { __typename: 'MenuItemTranslation', id: string, name: string, language: { __typename: 'LanguageDisplay', language: string } } | null, menuItem: { __typename: 'MenuItem', id: string, name: string } | null } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type MenuItemTranslationsQuery = { __typename: 'Query', translations: { __typename: 'TranslatableItemConnection', edges: Array<{ __typename: 'TranslatableItemEdge', node: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent', translation: { __typename: 'MenuItemTranslation', id: string, name: string, language: { __typename: 'LanguageDisplay', language: string } } | null, menuItem: { __typename: 'MenuItem', id: string, name: string } | null } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type ProductTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11711,7 +12003,7 @@ export type ProductTranslationDetailsQueryVariables = Exact<{ }>; -export type ProductTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent', product: { __typename: 'Product', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'ProductTranslation', id: string, seoTitle: string | null, seoDescription: string | null, name: string | null, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type ProductTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent', product: { __typename: 'Product', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'ProductTranslation', id: string, seoTitle: string | null, seoDescription: string | null, name: string | null, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type ProductVariantListQueryVariables = Exact<{ id: Scalars['ID']; @@ -11726,7 +12018,7 @@ export type ProductVariantTranslationDetailsQueryVariables = Exact<{ }>; -export type ProductVariantTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent', name: string, productVariant: { __typename: 'ProductVariant', id: string } | null, translation: { __typename: 'ProductVariantTranslation', id: string, name: string, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type ProductVariantTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent', name: string, productVariant: { __typename: 'ProductVariant', id: string } | null, translation: { __typename: 'ProductVariantTranslation', id: string, name: string, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type CategoryTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11734,7 +12026,7 @@ export type CategoryTranslationDetailsQueryVariables = Exact<{ }>; -export type CategoryTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent', translation: { __typename: 'CategoryTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null, category: { __typename: 'Category', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type CategoryTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent', translation: { __typename: 'CategoryTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null, category: { __typename: 'Category', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type CollectionTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11742,7 +12034,7 @@ export type CollectionTranslationDetailsQueryVariables = Exact<{ }>; -export type CollectionTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent', collection: { __typename: 'Collection', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'CollectionTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type CollectionTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent', collection: { __typename: 'Collection', id: string, name: string, description: any | null, seoDescription: string | null, seoTitle: string | null } | null, translation: { __typename: 'CollectionTranslation', id: string, description: any | null, name: string | null, seoDescription: string | null, seoTitle: string | null, language: { __typename: 'LanguageDisplay', language: string } } | null } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type PageTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11750,7 +12042,7 @@ export type PageTranslationDetailsQueryVariables = Exact<{ }>; -export type PageTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent', page: { __typename: 'Page', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string } | null, translation: { __typename: 'PageTranslation', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type PageTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent', page: { __typename: 'Page', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string } | null, translation: { __typename: 'PageTranslation', id: string, content: any | null, seoDescription: string | null, seoTitle: string | null, title: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null, attributeValues: Array<{ __typename: 'AttributeValueTranslatableContent', id: string, name: string, plainText: string | null, richText: any | null, attributeValue: { __typename: 'AttributeValue', id: string } | null, attribute: { __typename: 'AttributeTranslatableContent', id: string, name: string } | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null }> } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type SaleTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11758,7 +12050,7 @@ export type SaleTranslationDetailsQueryVariables = Exact<{ }>; -export type SaleTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent', sale: { __typename: 'Sale', id: string, name: string } | null, translation: { __typename: 'SaleTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type SaleTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent', sale: { __typename: 'Sale', id: string, name: string } | null, translation: { __typename: 'SaleTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type VoucherTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11766,7 +12058,7 @@ export type VoucherTranslationDetailsQueryVariables = Exact<{ }>; -export type VoucherTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent', name: string | null, voucher: { __typename: 'Voucher', id: string, name: string | null } | null, translation: { __typename: 'VoucherTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | null }; +export type VoucherTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent', name: string | null, voucher: { __typename: 'Voucher', id: string, name: string | null } | null, translation: { __typename: 'VoucherTranslation', id: string, name: string | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | null }; export type AttributeTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11778,7 +12070,7 @@ export type AttributeTranslationDetailsQueryVariables = Exact<{ }>; -export type AttributeTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent', translation: { __typename: 'AttributeTranslation', id: string, name: string } | null, attribute: { __typename: 'Attribute', id: string, name: string | null, inputType: AttributeInputTypeEnum | null, withChoices: boolean, choices: { __typename: 'AttributeValueCountableConnection', pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null }, edges: Array<{ __typename: 'AttributeValueCountableEdge', cursor: string, node: { __typename: 'AttributeValue', id: string, name: string | null, plainText: string | null, richText: any | null, inputType: AttributeInputTypeEnum | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null } | null } }> } | null } | null } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type AttributeTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent', translation: { __typename: 'AttributeTranslation', id: string, name: string } | null, attribute: { __typename: 'Attribute', id: string, name: string | null, inputType: AttributeInputTypeEnum | null, withChoices: boolean, choices: { __typename: 'AttributeValueCountableConnection', pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null }, edges: Array<{ __typename: 'AttributeValueCountableEdge', cursor: string, node: { __typename: 'AttributeValue', id: string, name: string | null, plainText: string | null, richText: any | null, inputType: AttributeInputTypeEnum | null, translation: { __typename: 'AttributeValueTranslation', id: string, name: string, plainText: string | null, richText: any | null } | null } }> } | null } | null } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type ShippingMethodTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11786,7 +12078,7 @@ export type ShippingMethodTranslationDetailsQueryVariables = Exact<{ }>; -export type ShippingMethodTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent', id: string, name: string, description: any | null, shippingMethod: { __typename: 'ShippingMethodType', id: string } | null, translation: { __typename: 'ShippingMethodTranslation', id: string, name: string, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'VoucherTranslatableContent' } | null }; +export type ShippingMethodTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent' } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent', id: string, name: string, description: any | null, shippingMethod: { __typename: 'ShippingMethodType', id: string } | null, translation: { __typename: 'ShippingMethodTranslation', id: string, name: string, description: any | null, language: { __typename: 'LanguageDisplay', code: LanguageCodeEnum, language: string } } | null } | { __typename: 'VoucherTranslatableContent' } | null }; export type MenuItemTranslationDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -11794,7 +12086,7 @@ export type MenuItemTranslationDetailsQueryVariables = Exact<{ }>; -export type MenuItemTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent', translation: { __typename: 'MenuItemTranslation', id: string, name: string, language: { __typename: 'LanguageDisplay', language: string } } | null, menuItem: { __typename: 'MenuItem', id: string, name: string } | null } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; +export type MenuItemTranslationDetailsQuery = { __typename: 'Query', translation: { __typename: 'AttributeTranslatableContent' } | { __typename: 'AttributeValueTranslatableContent' } | { __typename: 'CategoryTranslatableContent' } | { __typename: 'CollectionTranslatableContent' } | { __typename: 'MenuItemTranslatableContent', translation: { __typename: 'MenuItemTranslation', id: string, name: string, language: { __typename: 'LanguageDisplay', language: string } } | null, menuItem: { __typename: 'MenuItem', id: string, name: string } | null } | { __typename: 'PageTranslatableContent' } | { __typename: 'ProductTranslatableContent' } | { __typename: 'ProductVariantTranslatableContent' } | { __typename: 'PromotionRuleTranslatableContent' } | { __typename: 'PromotionTranslatableContent' } | { __typename: 'SaleTranslatableContent' } | { __typename: 'ShippingMethodTranslatableContent' } | { __typename: 'VoucherTranslatableContent' } | null }; export type UpdateMetadataMutationVariables = Exact<{ id: Scalars['ID']; @@ -11803,7 +12095,7 @@ export type UpdateMetadataMutationVariables = Exact<{ }>; -export type UpdateMetadataMutation = { __typename: 'Mutation', updateMetadata: { __typename: 'UpdateMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null, deleteMetadata: { __typename: 'DeleteMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type UpdateMetadataMutation = { __typename: 'Mutation', updateMetadata: { __typename: 'UpdateMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Promotion', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null, deleteMetadata: { __typename: 'DeleteMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Promotion', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type UpdatePrivateMetadataMutationVariables = Exact<{ id: Scalars['ID']; @@ -11812,7 +12104,7 @@ export type UpdatePrivateMetadataMutationVariables = Exact<{ }>; -export type UpdatePrivateMetadataMutation = { __typename: 'Mutation', updatePrivateMetadata: { __typename: 'UpdatePrivateMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null, deletePrivateMetadata: { __typename: 'DeletePrivateMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type UpdatePrivateMetadataMutation = { __typename: 'Mutation', updatePrivateMetadata: { __typename: 'UpdatePrivateMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Promotion', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null, deletePrivateMetadata: { __typename: 'DeletePrivateMetadata', errors: Array<{ __typename: 'MetadataError', code: MetadataErrorCode, field: string | null, message: string | null }>, item: { __typename: 'Address', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'App', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Attribute', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Category', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Channel', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Checkout', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'CheckoutLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Collection', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'DigitalContent', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Fulfillment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'GiftCard', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Invoice', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Menu', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'MenuItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Order', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'OrderLine', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Page', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'PageType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Payment', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Product', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductMedia', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ProductVariant', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Promotion', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Sale', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethod', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingMethodType', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'ShippingZone', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Shop', metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxClass', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TaxConfiguration', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'TransactionItem', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'User', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Voucher', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | { __typename: 'Warehouse', id: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type WarehouseDeleteMutationVariables = Exact<{ id: Scalars['ID']; From af5852da755cdc6d5b40a954b5540d368c0e5315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 16:59:40 +0200 Subject: [PATCH 48/67] Improve pagination, restart to first page when add voucher --- .../hooks/useVoucherCodesPagination.ts | 4 +- .../hooks/useVoucherCodes.test.ts | 78 ++++++++++++++++++- .../VoucherDetails/hooks/useVoucherCodes.ts | 76 ++++++++++-------- .../hooks/useVoucherCodesClient.test.ts | 70 +++++++++++++++++ .../hooks/useVoucherCodesClient.ts | 32 ++++++-- .../hooks/useVoucherCodesServer.tsx | 7 +- src/discounts/views/VoucherDetails/utils.ts | 7 +- src/hooks/useLocalPageInfo.ts | 3 + 8 files changed, 227 insertions(+), 50 deletions(-) create mode 100644 src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.test.ts diff --git a/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts index f5bcf4c34d2..334c49892fb 100644 --- a/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts +++ b/src/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination.ts @@ -12,6 +12,7 @@ export interface UseVoucherCodesPagination { paginatedCodes: VoucherCode[]; onSettingsChange: UseListSettings["updateListSettings"]; settings: UseListSettings["settings"]; + resetPage: () => void; } export const useVoucherCodesPagination = ( @@ -21,13 +22,14 @@ export const useVoucherCodesPagination = ( ListViews.VOUCHER_CODES, ); - const { loadNextPage, loadPreviousPage, pageInfo, pageValues } = + const { loadNextPage, loadPreviousPage, pageInfo, pageValues, resetPage } = useLocalPageInfo(voucherCodes, settings.rowNumber); return { paginatedCodes: pageValues, settings, onSettingsChange: updateListSettings, + resetPage, pagination: { loadNextPage, loadPreviousPage, diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts index 484d1fdee63..427df62664c 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts @@ -330,10 +330,6 @@ describe("useVoucherCodes", () => { }); // Assert - expect(useVoucherCodesQuery).toHaveBeenCalledWith({ - skip: false, - variables: { first: 1, id: "1" }, - }); expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( true, ); @@ -423,4 +419,78 @@ describe("useVoucherCodes", () => { autoGeneratedVoucherCodes.slice(0, 2), ); }); + + it("should allow to handle client and server pagination when client generate whole page", () => { + // Arrange + (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ + data: { + voucher: { + codes: { + edges: apiVoucherCodes.slice(0, 2), + pageInfo: { + hasNextPage: false, + hasPreviousPage: false, + }, + }, + }, + }, + })); + + const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + + // Act + act(() => { + result.current.updateVoucherCodesListSettings("rowNumber", 10); + result.current.handleGenerateMultipeCodes({ + quantity: "10", + prefix: "code", + }); + }); + + // Assert + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + false, + ); + expect(result.current.voucherCodes).toEqual([ + ...autoGeneratedVoucherCodes, + ...autoGeneratedVoucherCodes, + ]); + + // Act + act(() => { + result.current.voucherCodesPagination.loadNextPage(); + }); + + // Assert + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + false, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + true, + ); + expect(result.current.voucherCodes).toEqual([ + { code: "code 1", used: 0 }, + { code: "code 2", used: 0 }, + ]); + + // Act + act(() => { + result.current.voucherCodesPagination.loadPreviousPage(); + }); + + // Assert + expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( + true, + ); + expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( + false, + ); + expect(result.current.voucherCodes).toEqual([ + ...autoGeneratedVoucherCodes, + ...autoGeneratedVoucherCodes, + ]); + }); }); diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts index 0308a019769..008d6bd0162 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts @@ -16,7 +16,6 @@ export const useVoucherCodes = ({ id }: { id: string }) => { const [isServerPagination, setIsServerPagination] = useState(true); const { - addedVoucherCodes, clientVoucherCodes, clientVoucherCodesPagination, freeSlotsInClientPagianationPage, @@ -39,21 +38,17 @@ export const useVoucherCodes = ({ id }: { id: string }) => { voucherCodesRefetch, } = useVoucherCodesServer({ id, - skipFetch: !isServerPagination && hasClientPaginationNextPage, settings: voucherCodesSettings, isServerPagination, paginationState: { first: - !isServerPagination && - !hasClientPaginationNextPage && - freeSlotsInClientPagianationPage > 0 + !isServerPagination && freeSlotsInClientPagianationPage > 0 ? freeSlotsInClientPagianationPage - : undefined, + : voucherCodesSettings.rowNumber, }, }); const voucherCodes = getVoucherCodesToDisplay({ - addedVoucherCodes, clientVoucherCodes, freeSlotsInClientPagianationPage, hasClientPaginationNextPage, @@ -71,31 +66,52 @@ export const useVoucherCodes = ({ id }: { id: string }) => { useVoucherCodesRowSelection(voucherCodes); const handleLoadNextPage = () => { + if (!hasClientPaginationNextPage) { + setIsServerPagination(true); + } + if (isServerPagination) { - voucherCodesPagination.loadNextPage(); - } else { - // Switch to server pagination - if (clientVoucherCodes.length < voucherCodesSettings.rowNumber) { - setIsServerPagination(true); - serverVoucherCodesPagination.loadNextPage(); - } else { - clientVoucherCodesPagination.loadNextPage(); - } + serverVoucherCodesPagination.loadNextPage(); + } else if (!isServerPagination && freeSlotsInClientPagianationPage > 0) { + serverVoucherCodesPagination.loadNextPage(); } + + clientVoucherCodesPagination.loadNextPage(); }; const handleLoadPrevousPage = () => { - if (!isServerPagination) { - clientVoucherCodesPagination.loadPreviousPage(); - } else { - // Switch to client pagination - if (!hasServerPaginationPrevPage && addedVoucherCodes.length > 0) { - clientVoucherCodesPagination.loadPreviousPage(); - setIsServerPagination(false); - } else { - voucherCodesPagination.loadPreviousPage(); - } + if (!hasServerPaginationPrevPage) { + setIsServerPagination(false); + } + + if (isServerPagination && hasServerPaginationPrevPage) { + serverVoucherCodesPagination.loadPreviousPage(); } + + clientVoucherCodesPagination.loadPreviousPage(); + }; + + const calculateHasNextPage = () => { + // In case when client voucher codes takes all slots + // on page and there are some server voucher codes to display + if ( + !isServerPagination && + !hasClientPaginationNextPage && + freeSlotsInClientPagianationPage === 0 && + serverVoucherCodes.length > 0 + ) { + return true; + } + + return hasClientPaginationNextPage || hasServerPaginationNextPage; + }; + + const calculateHasPrevPage = () => { + if (isServerPagination) { + return hasServerPaginationPrevPage || hasClientPaginationPrevPage; + } + + return hasClientPaginationPrevPage; }; return { @@ -105,12 +121,8 @@ export const useVoucherCodes = ({ id }: { id: string }) => { ...voucherCodesPagination, pageInfo: { ...voucherCodesPagination.pageInfo, - hasNextPage: isServerPagination - ? hasServerPaginationNextPage - : hasClientPaginationNextPage || hasServerPaginationNextPage, - hasPreviousPage: !isServerPagination - ? hasClientPaginationPrevPage - : hasServerPaginationPrevPage || hasClientPaginationPrevPage, + hasNextPage: calculateHasNextPage(), + hasPreviousPage: calculateHasPrevPage(), }, loadNextPage: handleLoadNextPage, loadPreviousPage: handleLoadPrevousPage, diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.test.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.test.ts new file mode 100644 index 00000000000..9ef0597b086 --- /dev/null +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.test.ts @@ -0,0 +1,70 @@ +import { act } from "@testing-library/react"; +import { renderHook } from "@testing-library/react-hooks"; + +import { useVoucherCodesClient } from "./useVoucherCodesClient"; + +jest.mock("uuid", () => ({ v4: () => "123456789" })); + +describe("useVoucherCodesClient", () => { + it("should add voucher code manually", () => { + // Arrange + const settings = { + rowNumber: 10, + updateListSettings: jest.fn(), + }; + const switchToClientPagination = jest.fn(); + + const { result } = renderHook(() => + useVoucherCodesClient(settings, switchToClientPagination), + ); + + // Act + act(() => { + result.current.handleAddVoucherCode("code 1"); + result.current.handleAddVoucherCode("code 2"); + }); + + // Assert + expect(switchToClientPagination).toHaveBeenCalled(); + expect(result.current.addedVoucherCodes).toEqual([ + { code: "code 2", status: "Draft" }, + { code: "code 1", status: "Draft" }, + ]); + }); + + it("should add multiple voucher codes", () => { + // Arrange + const settings = { + rowNumber: 10, + updateListSettings: jest.fn(), + }; + const switchToClientPagination = jest.fn(); + + const { result } = renderHook(() => + useVoucherCodesClient(settings, switchToClientPagination), + ); + + // Act + act(() => { + result.current.handleGenerateMultipeCodes({ + quantity: "10", + prefix: "prefix", + }); + }); + + // Assert + expect(switchToClientPagination).toHaveBeenCalled(); + expect(result.current.addedVoucherCodes).toEqual([ + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + { code: "prefix-123456789", status: "Draft" }, + ]); + }); +}); diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts index e63dad81d85..8c8699e6e6a 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts @@ -2,19 +2,36 @@ import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagri import { GenerateMultipleVoucherCodeFormData } from "@dashboard/discounts/components/VoucherCodesGenerateDialog"; import { useVoucherCodesPagination } from "@dashboard/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination"; import { generateMultipleIds } from "@dashboard/discounts/components/VoucherCreatePage/utils"; +import { UseListSettings } from "@dashboard/hooks/useListSettings"; import { ListSettings } from "@dashboard/types"; import { useState } from "react"; +interface UseVoucherCodesClient { + hasClientPaginationNextPage: boolean; + hasClientPaginationPrevPage: boolean; + addedVoucherCodes: VoucherCode[]; + clientVoucherCodes: VoucherCode[]; + clientVoucherCodesPagination: any; + freeSlotsInClientPagianationPage: number; + onSettingsChange: UseListSettings["updateListSettings"]; + handleAddVoucherCode: (code: string) => void; + handleGenerateMultipeCodes: ({ + quantity, + prefix, + }: GenerateMultipleVoucherCodeFormData) => void; +} + export const useVoucherCodesClient = ( settings: ListSettings, - resetPagination: () => void, -) => { + switchToClientPagination: () => void, +): UseVoucherCodesClient => { const [addedVoucherCodes, setAddedVoucherCodes] = useState([]); const { paginatedCodes: clientVoucherCodes, pagination: clientVoucherCodesPagination, onSettingsChange, + resetPage, } = useVoucherCodesPagination(addedVoucherCodes); const hasClientPaginationNextPage = @@ -25,9 +42,11 @@ export const useVoucherCodesClient = ( const freeSlotsInClientPagianationPage = settings.rowNumber - clientVoucherCodes.length; - const handleAddVoucherCode = (code: string) => [ - setAddedVoucherCodes(codes => [{ code, status: "Draft" }, ...codes]), - ]; + const handleAddVoucherCode = (code: string) => { + setAddedVoucherCodes(codes => [{ code, status: "Draft" }, ...codes]); + switchToClientPagination(); + resetPage(); + }; const handleGenerateMultipeCodes = ({ quantity, @@ -37,7 +56,8 @@ export const useVoucherCodesClient = ( ...generateMultipleIds(quantity, prefix), ...codes, ]); - resetPagination(); + switchToClientPagination(); + resetPage(); }; return { diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx index b6e4cec62e3..9ad5fca45b3 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx @@ -28,7 +28,6 @@ interface VoucherCodesServer { export const useVoucherCodesServer = ({ settings, - skipFetch, id, isServerPagination, paginationState = {}, @@ -47,11 +46,11 @@ export const useVoucherCodesServer = ({ loading: voucherCodesLoading, refetch: voucherCodesRefetch, } = useVoucherCodesQuery({ - skip: skipFetch, variables: { id, - ...paginationState, - ...(isServerPagination && serverVoucherCodesPaginationState), + ...(!isServerPagination + ? paginationState + : serverVoucherCodesPaginationState), }, }); diff --git a/src/discounts/views/VoucherDetails/utils.ts b/src/discounts/views/VoucherDetails/utils.ts index f3d64e38a94..cea37c19cfd 100644 --- a/src/discounts/views/VoucherDetails/utils.ts +++ b/src/discounts/views/VoucherDetails/utils.ts @@ -6,7 +6,6 @@ export const getVoucherCodesToDisplay = ({ isServerPagination, freeSlotsInServerPagianationPage, hasServerPaginationPrevPage, - addedVoucherCodes, hasClientPaginationNextPage, freeSlotsInClientPagianationPage, }: { @@ -15,19 +14,21 @@ export const getVoucherCodesToDisplay = ({ serverVoucherCodes: VoucherCode[]; freeSlotsInServerPagianationPage: number; hasServerPaginationPrevPage: boolean; - addedVoucherCodes: VoucherCode[]; hasClientPaginationNextPage: boolean; freeSlotsInClientPagianationPage: number; }) => { if (isServerPagination) { + // Fill missing slots using client voucher codes when there are no more server voucher codes + // Happend when user is on navigating back and reach begining of server pagination return [ ...(freeSlotsInServerPagianationPage > 0 && !hasServerPaginationPrevPage - ? addedVoucherCodes.slice(-freeSlotsInServerPagianationPage) + ? clientVoucherCodes : []), ...serverVoucherCodes, ]; } + // Fill missing slots in clinet navigation with server voucher codes return [ ...clientVoucherCodes, ...(!hasClientPaginationNextPage && freeSlotsInClientPagianationPage > 0 diff --git a/src/hooks/useLocalPageInfo.ts b/src/hooks/useLocalPageInfo.ts index 9c3e6db8793..e0a5464500c 100644 --- a/src/hooks/useLocalPageInfo.ts +++ b/src/hooks/useLocalPageInfo.ts @@ -33,6 +33,8 @@ function useLocalPageInfo(values: T[], paginateBy: number) { const loadPreviousPage = () => setPage(page - 1); const loadNextPage = () => setPage(page + 1); + const resetPage = () => setPage(0); + return { pageInfo: { hasNextPage, @@ -41,6 +43,7 @@ function useLocalPageInfo(values: T[], paginateBy: number) { startCursor, }, pageValues, + resetPage, loadNextPage, loadPreviousPage, loadPage: setPage, From 137f573e3a7c3d0338aec976081b5de283467e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 17:03:10 +0200 Subject: [PATCH 49/67] Fix types --- .../views/VoucherDetails/hooks/useVoucherCodes.test.ts | 4 ++-- .../views/VoucherDetails/hooks/useVoucherCodesClient.ts | 4 ++-- .../views/VoucherDetails/hooks/useVoucherCodesServer.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts index 427df62664c..74f12bcc4bd 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts @@ -220,7 +220,7 @@ describe("useVoucherCodes", () => { // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - undefined, + false, ); expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( true, @@ -258,7 +258,7 @@ describe("useVoucherCodes", () => { // Assert expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - undefined, + false, ); expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( false, diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts index 8c8699e6e6a..48ccbfeac37 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts @@ -35,9 +35,9 @@ export const useVoucherCodesClient = ( } = useVoucherCodesPagination(addedVoucherCodes); const hasClientPaginationNextPage = - clientVoucherCodesPagination?.pageInfo?.hasNextPage; + clientVoucherCodesPagination?.pageInfo?.hasNextPage ?? false; const hasClientPaginationPrevPage = - clientVoucherCodesPagination.pageInfo?.hasPreviousPage; + clientVoucherCodesPagination.pageInfo?.hasPreviousPage ?? false; const freeSlotsInClientPagianationPage = settings.rowNumber - clientVoucherCodes.length; diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx index 9ad5fca45b3..23dd1476f55 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx @@ -60,9 +60,9 @@ export const useVoucherCodesServer = ({ ); const hasServerPaginationNextPage = - serverVoucherCodesPagination?.pageInfo?.hasNextPage; + serverVoucherCodesPagination?.pageInfo?.hasNextPage ?? false; const hasServerPaginationPrevPage = - serverVoucherCodesPagination?.pageInfo?.hasPreviousPage; + serverVoucherCodesPagination?.pageInfo?.hasPreviousPage ?? false; const serverVoucherCodes = (mapEdgesToItems( voucherCodesData?.voucher?.codes, From 0e35f71556d79d0926e8687518c605e46553758e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 17:10:33 +0200 Subject: [PATCH 50/67] Send voucher codes on update --- src/discounts/views/VoucherDetails/handlers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/discounts/views/VoucherDetails/handlers.ts b/src/discounts/views/VoucherDetails/handlers.ts index 32580c87043..0e98fce8afc 100644 --- a/src/discounts/views/VoucherDetails/handlers.ts +++ b/src/discounts/views/VoucherDetails/handlers.ts @@ -57,6 +57,7 @@ export function createUpdateHandler( ? VoucherTypeEnum.SHIPPING : formData.type, usageLimit: formData.hasUsageLimit ? formData.usageLimit : null, + codes: formData.codes.map(({ code }) => ({ code })), }, }).then(({ data }) => data?.voucherUpdate.errors ?? []), From 018562fee25ec36e16e7a69e0e3a9a5ecb71b90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 17:18:35 +0200 Subject: [PATCH 51/67] Display isActive voucher code --- .../VoucherCodesDatagrid.tsx | 2 +- .../components/VoucherCodesDatagrid/datagrid.ts | 16 +++++++++++++--- .../components/VoucherCodesDatagrid/messages.ts | 12 ++++++++++++ .../components/VoucherCodesDatagrid/types.ts | 1 + src/fragments/discounts.ts | 1 + src/graphql/hooks.generated.ts | 1 + src/graphql/types.generated.ts | 4 ++-- 7 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 58be698221b..4df923dae84 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -48,7 +48,7 @@ export const VoucherCodesDatagrid = ({ }); const getCellContent = useCallback( - createGetCellContent(codes, visibleColumns), + createGetCellContent(codes, visibleColumns, intl), [codes, visibleColumns], ); diff --git a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts index 44b15a8f8b2..0640b87bd31 100644 --- a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts +++ b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts @@ -4,7 +4,7 @@ import { AvailableColumn } from "@dashboard/components/Datagrid/types"; import { GridCell, Item } from "@glideapps/glide-data-grid"; import { IntlShape } from "react-intl"; -import { columnsMessages } from "./messages"; +import { columnsMessages, messages } from "./messages"; import { VoucherCode } from "./types"; export const voucherCodesStaticColumnsAdapter = (intl: IntlShape) => [ @@ -26,7 +26,7 @@ export const voucherCodesStaticColumnsAdapter = (intl: IntlShape) => [ ]; export const createGetCellContent = - (voucherCodes: VoucherCode[], columns: AvailableColumn[]) => + (voucherCodes: VoucherCode[], columns: AvailableColumn[], intl: IntlShape) => ([column, row]: Item): GridCell => { const columnId = columns[column]?.id; const rowData: VoucherCode | undefined = voucherCodes[row]; @@ -44,8 +44,18 @@ export const createGetCellContent = false, ); case "status": - return readonlyTextCell(rowData?.status ?? "Active", false); + return readonlyTextCell(getStatus(rowData?.isActive, intl), false); default: return readonlyTextCell("", false); } }; + +function getStatus(isActive: boolean | undefined, intl: IntlShape) { + if (isActive === undefined) { + return intl.formatMessage(messages.draft); + } + + return isActive + ? intl.formatMessage(messages.active) + : intl.formatMessage(messages.inactive); +} diff --git a/src/discounts/components/VoucherCodesDatagrid/messages.ts b/src/discounts/components/VoucherCodesDatagrid/messages.ts index 12c20605661..93d3306aa95 100644 --- a/src/discounts/components/VoucherCodesDatagrid/messages.ts +++ b/src/discounts/components/VoucherCodesDatagrid/messages.ts @@ -20,4 +20,16 @@ export const messages = defineMessages({ defaultMessage: "No voucher codes found", id: "KkufwD", }, + draft: { + id: "W6nwjo", + defaultMessage: "Draft", + }, + active: { + id: "3a5wL8", + defaultMessage: "Active", + }, + inactive: { + id: "6Tps09", + defaultMessage: "Inactive", + }, }); diff --git a/src/discounts/components/VoucherCodesDatagrid/types.ts b/src/discounts/components/VoucherCodesDatagrid/types.ts index 4406acac35c..fba54e8fd3b 100644 --- a/src/discounts/components/VoucherCodesDatagrid/types.ts +++ b/src/discounts/components/VoucherCodesDatagrid/types.ts @@ -2,4 +2,5 @@ export interface VoucherCode { code: string; used?: number; status?: string; + isActive?: boolean; } diff --git a/src/fragments/discounts.ts b/src/fragments/discounts.ts index c1336525dc6..85b689d7ec2 100644 --- a/src/fragments/discounts.ts +++ b/src/fragments/discounts.ts @@ -154,6 +154,7 @@ export const voucherCodeFragment = gql` fragment VoucherCode on VoucherCode { code used + isActive } `; diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index 8953f654b01..41b912f2ad3 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -525,6 +525,7 @@ export const VoucherCodeFragmentDoc = gql` fragment VoucherCode on VoucherCode { code used + isActive } `; export const VoucherFragmentDoc = gql` diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index ef79119da6a..1c7ea49bf21 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -9578,7 +9578,7 @@ export type VoucherCodesQueryVariables = Exact<{ }>; -export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null } | null }; +export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, isActive: boolean | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null } | null }; export type FileUploadMutationVariables = Exact<{ file: Scalars['Upload']; @@ -9651,7 +9651,7 @@ export type SaleDetailsFragment = { __typename: 'Sale', id: string, name: string export type VoucherFragment = { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; -export type VoucherCodeFragment = { __typename: 'VoucherCode', code: string | null, used: number | null }; +export type VoucherCodeFragment = { __typename: 'VoucherCode', code: string | null, used: number | null, isActive: boolean | null }; export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; From 9f9963add72225910fd8f5d578b736f38fa04e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 9 Oct 2023 17:43:27 +0200 Subject: [PATCH 52/67] Single use support --- src/discounts/components/VoucherCreatePage/const.ts | 1 + .../components/VoucherDetailsPage/VoucherDetailsPage.tsx | 2 ++ src/discounts/components/VoucherLimits/VoucherLimits.tsx | 8 ++++++++ src/discounts/components/VoucherLimits/messages.ts | 4 ++++ src/discounts/fixtures.ts | 1 + src/discounts/views/VoucherCreate/handlers.ts | 1 + src/discounts/views/VoucherDetails/handlers.ts | 5 ++++- src/fragments/discounts.ts | 1 + src/graphql/hooks.generated.ts | 1 + src/graphql/types.generated.ts | 8 ++++---- 10 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/discounts/components/VoucherCreatePage/const.ts b/src/discounts/components/VoucherCreatePage/const.ts index ce219e69b97..532483d5ee6 100644 --- a/src/discounts/components/VoucherCreatePage/const.ts +++ b/src/discounts/components/VoucherCreatePage/const.ts @@ -24,6 +24,7 @@ export const initialForm: FormData = { type: VoucherTypeEnum.ENTIRE_ORDER, used: 1, usageLimit: 1, + singleUse: false, codes: [], value: 0, metadata: [], diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 09a39855b52..79e4de4c224 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -81,6 +81,7 @@ export interface VoucherDetailsPageFormData extends MetadataFormData { codes: VoucherCode[]; usageLimit: number; used: number; + singleUse: boolean; } export interface VoucherDetailsPageProps @@ -214,6 +215,7 @@ const VoucherDetailsPage: React.FC = ({ type: voucher?.type ?? VoucherTypeEnum.ENTIRE_ORDER, usageLimit: voucher?.usageLimit ?? 1, used: voucher?.used ?? 0, + singleUse: voucher?.singleUse ?? false, metadata: voucher?.metadata.map(mapMetadataItemToInput), privateMetadata: voucher?.privateMetadata.map(mapMetadataItemToInput), }; diff --git a/src/discounts/components/VoucherLimits/VoucherLimits.tsx b/src/discounts/components/VoucherLimits/VoucherLimits.tsx index 44a1411d3b5..e2203606185 100644 --- a/src/discounts/components/VoucherLimits/VoucherLimits.tsx +++ b/src/discounts/components/VoucherLimits/VoucherLimits.tsx @@ -110,6 +110,14 @@ const VoucherLimits = ({ name={"onlyForStaff" as keyof VoucherDetailsPageFormData} onChange={onChange} /> + +
); diff --git a/src/discounts/components/VoucherLimits/messages.ts b/src/discounts/components/VoucherLimits/messages.ts index d4141dd36e1..8d1cab697da 100644 --- a/src/discounts/components/VoucherLimits/messages.ts +++ b/src/discounts/components/VoucherLimits/messages.ts @@ -31,4 +31,8 @@ export default defineMessages({ defaultMessage: "Limit to staff only", description: "limit voucher", }, + singleUse: { + defaultMessage: "Limit to voucher code use once", + id: "ZCSOaS", + }, }); diff --git a/src/discounts/fixtures.ts b/src/discounts/fixtures.ts index a2195c129f8..fe8bda7a97c 100644 --- a/src/discounts/fixtures.ts +++ b/src/discounts/fixtures.ts @@ -589,6 +589,7 @@ export const voucherDetails: VoucherDetailsFragment = { privateMetadata: [], applyOncePerCustomer: false, applyOncePerOrder: false, + singleUse: false, onlyForStaff: false, categoriesCount: { __typename: "CategoryCountableConnection", diff --git a/src/discounts/views/VoucherCreate/handlers.ts b/src/discounts/views/VoucherCreate/handlers.ts index 52bf243096c..fc198d2c0ec 100644 --- a/src/discounts/views/VoucherCreate/handlers.ts +++ b/src/discounts/views/VoucherCreate/handlers.ts @@ -55,6 +55,7 @@ export function createHandler( ? VoucherTypeEnum.SHIPPING : formData.type, usageLimit: formData.hasUsageLimit ? formData.usageLimit : null, + singleUse: formData.singleUse, }, }); diff --git a/src/discounts/views/VoucherDetails/handlers.ts b/src/discounts/views/VoucherDetails/handlers.ts index 0e98fce8afc..2cb1ec4407c 100644 --- a/src/discounts/views/VoucherDetails/handlers.ts +++ b/src/discounts/views/VoucherDetails/handlers.ts @@ -57,7 +57,10 @@ export function createUpdateHandler( ? VoucherTypeEnum.SHIPPING : formData.type, usageLimit: formData.hasUsageLimit ? formData.usageLimit : null, - codes: formData.codes.map(({ code }) => ({ code })), + singleUse: formData.singleUse, + // TODO: implement updating codes + codes: [], + // codes: formData.codes.map(({ code }) => ({ code })), }, }).then(({ data }) => data?.voucherUpdate.errors ?? []), diff --git a/src/fragments/discounts.ts b/src/fragments/discounts.ts index 85b689d7ec2..a6171902bf8 100644 --- a/src/fragments/discounts.ts +++ b/src/fragments/discounts.ts @@ -167,6 +167,7 @@ export const voucherDetailsFragment = gql` applyOncePerOrder applyOncePerCustomer onlyForStaff + singleUse productsCount: products { totalCount } diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index 41b912f2ad3..3b7379b5af1 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -569,6 +569,7 @@ export const VoucherDetailsFragmentDoc = gql` applyOncePerOrder applyOncePerCustomer onlyForStaff + singleUse productsCount: products { totalCount } diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 1c7ea49bf21..39d9bee7d80 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -9476,7 +9476,7 @@ export type VoucherCataloguesAddMutationVariables = Exact<{ }>; -export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCataloguesRemoveMutationVariables = Exact<{ input: CatalogueInput; @@ -9491,7 +9491,7 @@ export type VoucherCataloguesRemoveMutationVariables = Exact<{ }>; -export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCreateMutationVariables = Exact<{ input: VoucherInput; @@ -9567,7 +9567,7 @@ export type VoucherDetailsQueryVariables = Exact<{ }>; -export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; +export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; export type VoucherCodesQueryVariables = Exact<{ id: Scalars['ID']; @@ -9653,7 +9653,7 @@ export type VoucherFragment = { __typename: 'Voucher', id: string, code: string export type VoucherCodeFragment = { __typename: 'VoucherCode', code: string | null, used: number | null, isActive: boolean | null }; -export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; export type AttributeErrorFragment = { __typename: 'AttributeError', code: AttributeErrorCode, field: string | null, message: string | null }; From ce061dd07f799858c64fe35c6206bdb3cfa99d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 09:25:38 +0200 Subject: [PATCH 53/67] Send only added voucher codes on update --- .../components/VoucherDetailsPage/VoucherDetailsPage.tsx | 4 +++- src/discounts/views/VoucherDetails/VoucherDetails.tsx | 2 ++ src/discounts/views/VoucherDetails/handlers.ts | 4 +--- src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts | 2 ++ 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 79e4de4c224..3068016ccc1 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -99,6 +99,7 @@ export interface VoucherDetailsPageProps channelListings: ChannelVoucherData[]; selectedVoucherCodesIds: string[]; voucherCodes: VoucherCode[]; + addedVoucherCodes: VoucherCode[]; voucherCodesLoading: boolean; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; onCategoryAssign: () => void; @@ -162,6 +163,7 @@ const VoucherDetailsPage: React.FC = ({ selectedVoucherCodesIds, onSelectVoucherCodesIds, voucherCodes, + addedVoucherCodes, voucherCodesLoading, voucherCodesPagination, onVoucherCodesSettingsChange, @@ -202,7 +204,7 @@ const VoucherDetailsPage: React.FC = ({ channelListings, name: voucher?.name || "", discountType, - codes: voucherCodes, + codes: addedVoucherCodes, endDate: splitDateTime(voucher?.endDate ?? "").date, endTime: splitDateTime(voucher?.endDate ?? "").time, hasEndDate: !!voucher?.endDate, diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 09185e42a20..f421eff9c7b 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -140,6 +140,7 @@ export const VoucherDetails: React.FC = ({ voucherCodesPagination, voucherCodesSettings, selectedVoucherCodesIds, + addedVoucherCodes, voucherCodesRefetch, handleSetSelectedVoucherCodesIds, updateVoucherCodesListSettings, @@ -327,6 +328,7 @@ export const VoucherDetails: React.FC = ({ ({ code })), + codes: formData.codes.map(({ code }) => ({ code })), }, }).then(({ data }) => data?.voucherUpdate.errors ?? []), diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts index 008d6bd0162..db7d875a75a 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts @@ -16,6 +16,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { const [isServerPagination, setIsServerPagination] = useState(true); const { + addedVoucherCodes, clientVoucherCodes, clientVoucherCodesPagination, freeSlotsInClientPagianationPage, @@ -116,6 +117,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { return { voucherCodes, + addedVoucherCodes, voucherCodesLoading, voucherCodesPagination: { ...voucherCodesPagination, From 1cabf3dad0ba580f083d8533cdc06f99dd6b9d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 09:29:01 +0200 Subject: [PATCH 54/67] Extract messages --- locale/defaultMessages.json | 64 +++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 3ec32a0d571..e24b2cc3460 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -542,6 +542,9 @@ "context": "header", "string": "Translation ShippingMethod \"{shippingMethodName}\" - {languageCode}" }, + "1UQ9Qy": { + "string": "Code Prefix (Optional)" + }, "1Uj0Wd": { "context": "order draft total price", "string": "Total" @@ -1222,6 +1225,9 @@ "6SL46U": { "string": "by {author}" }, + "6Tps09": { + "string": "Inactive" + }, "6WRFp2": { "context": "order history message", "string": "Note was added to the order" @@ -1275,6 +1281,9 @@ "context": "informations about product seo, header", "string": "SEO Information" }, + "6xNl6V": { + "string": "Add code" + }, "6y+k8V": { "context": "product field", "string": "Product Images" @@ -1394,6 +1403,9 @@ "context": "section header", "string": "User Status" }, + "83egc7": { + "string": "Manually enter the voucher code." + }, "86pLaG": { "context": "WarehouseSettings public stock label", "string": "Public Stock" @@ -2123,6 +2135,9 @@ "context": "button", "string": "Confirm" }, + "DJatYh": { + "string": "Generate multiple codes at once" + }, "DK+8PB": { "string": "This channel has already been created" }, @@ -3199,6 +3214,9 @@ "context": "order", "string": "Paid with Gift Card" }, + "KkufwD": { + "string": "No voucher codes found" + }, "KmPicj": { "string": "Note successfully added" }, @@ -3353,6 +3371,9 @@ "context": "collection", "string": "Not Published" }, + "M59JhX": { + "string": "Manual" + }, "M6s/9e": { "context": "unassign country, dialog header", "string": "Remove from Shipping Zone" @@ -4248,6 +4269,9 @@ "context": "Payment card title", "string": "Payment status" }, + "SGdcJD": { + "string": "Enter code" + }, "SHm7ee": { "string": "Search by product name, attribute, product type etc..." }, @@ -4530,6 +4554,9 @@ "context": "searchbar placeholder", "string": "Country" }, + "UJ97Lb": { + "string": "Delete codes" + }, "UJnqdm": { "context": "dialog header", "string": "Unassign Attribute From Product Type" @@ -4810,6 +4837,9 @@ "context": "warehouse input", "string": "Warehouse" }, + "W6nwjo": { + "string": "Draft" + }, "W8i2Ez": { "context": "product field", "string": "Name" @@ -5289,6 +5319,9 @@ "context": "Taxes section title", "string": "Countries" }, + "ZCSOaS": { + "string": "Limit to voucher code use once" + }, "ZDJEat": { "context": "button", "string": "Load More" @@ -5524,6 +5557,9 @@ "context": "ChannelsSection subtitle", "string": "Assign channels to this shipping zone so we know which orders will be supported" }, + "awNXI/": { + "string": "Auto-generate codes" + }, "axFFaD": { "context": "range input label", "string": "Postal codes (end)" @@ -6279,6 +6315,9 @@ "context": "sale end date", "string": "Ends" }, + "giVGCH": { + "string": "Enter Voucher Code" + }, "gj3MUg": { "context": "gift card history message", "string": "Gift card was resent" @@ -6337,6 +6376,9 @@ "context": "search gift card placeholder", "string": "Search gift cards, e.g {exampleGiftCardCode}" }, + "h2vipu": { + "string": "Code" + }, "h65vZI": { "context": "times voucher used", "string": "Used" @@ -6687,9 +6729,6 @@ "context": "dialog header", "string": "Assign product" }, - "jvKNMP": { - "string": "Discount Code" - }, "jvo0vs": { "string": "Save" }, @@ -6809,6 +6848,9 @@ "context": "order expiration card title", "string": "Order expiration" }, + "kVL3LM": { + "string": "Voucher codes" + }, "kVOslW": { "context": "reason for discount label", "string": "Reason for discount" @@ -7073,10 +7115,6 @@ "context": "Webhook details asynchronous events", "string": "Asynchronous" }, - "mSLr9d": { - "context": "voucher code, button", - "string": "Generate Code" - }, "mTEqYL": { "context": "NoChannels content", "string": "No channels to assign. Please first assign them for the product." @@ -7610,6 +7648,9 @@ "context": "User registration", "string": "User registration" }, + "qPSWmL": { + "string": "Enter usage" + }, "qT6YYk": { "context": "order line total price", "string": "Total" @@ -7638,6 +7679,9 @@ "context": "order history message", "string": "Invoice was sent to customer by {sentBy}" }, + "qgQeVW": { + "string": "Generate Voucher Codes" + }, "qkRuT0": { "context": "attribute type", "string": "Product Attribute" @@ -8306,6 +8350,9 @@ "context": "button", "string": "Discard" }, + "vTPu1s": { + "string": "Code Quantity (max {maxCodes})" + }, "vTgRTZ": { "context": "limit voucher", "string": "Limit to one use per customer" @@ -8474,6 +8521,9 @@ "wWTUrM": { "string": "No activities found" }, + "wbsq7O": { + "string": "Usage" + }, "wgA48T": { "context": "country selection", "string": "Countries A to Z" From 21f6c4e31f21eb48f4717428b77d4445c14627c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 10:02:30 +0200 Subject: [PATCH 55/67] Handle delete added vouche codes --- .../views/VoucherDetails/VoucherDetails.tsx | 6 +++++- .../views/VoucherDetails/hooks/useVoucherCodes.ts | 14 ++++++++++++-- .../VoucherDetails/hooks/useVoucherCodesClient.ts | 8 ++++++++ .../hooks/useVoucherCodesRowSelection.ts | 3 +++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index f421eff9c7b..d16e33d8f9b 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -146,6 +146,7 @@ export const VoucherDetails: React.FC = ({ updateVoucherCodesListSettings, handleAddVoucherCode, handleGenerateMultipeCodes, + handleDeleteVoucherCodes, } = useVoucherCodes({ id }); const [openModal, closeModal] = createDialogActionHandlers< @@ -444,7 +445,10 @@ export const VoucherDetails: React.FC = ({ { + handleDeleteVoucherCodes(); + closeModal(); + }} /> { freeSlotsInClientPagianationPage, handleAddVoucherCode, handleGenerateMultipeCodes, + handleDeleteAddedVoucherCodes, hasClientPaginationNextPage, hasClientPaginationPrevPage, onSettingsChange, @@ -63,8 +64,16 @@ export const useVoucherCodes = ({ id }: { id: string }) => { ? serverVoucherCodesPagination : clientVoucherCodesPagination; - const { selectedVoucherCodesIds, handleSetSelectedVoucherCodesIds } = - useVoucherCodesRowSelection(voucherCodes); + const { + selectedVoucherCodesIds, + handleSetSelectedVoucherCodesIds, + clearRowSelection, + } = useVoucherCodesRowSelection(voucherCodes); + + const handleDeleteVoucherCodes = () => { + clearRowSelection(); + handleDeleteAddedVoucherCodes(selectedVoucherCodesIds); + }; const handleLoadNextPage = () => { if (!hasClientPaginationNextPage) { @@ -139,5 +148,6 @@ export const useVoucherCodes = ({ id }: { id: string }) => { handleSetSelectedVoucherCodesIds, handleAddVoucherCode, handleGenerateMultipeCodes, + handleDeleteVoucherCodes, }; }; diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts index 48ccbfeac37..165451dcfbd 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts @@ -14,6 +14,7 @@ interface UseVoucherCodesClient { clientVoucherCodesPagination: any; freeSlotsInClientPagianationPage: number; onSettingsChange: UseListSettings["updateListSettings"]; + handleDeleteAddedVoucherCodes: (idsToDelete: string[]) => void; handleAddVoucherCode: (code: string) => void; handleGenerateMultipeCodes: ({ quantity, @@ -60,6 +61,12 @@ export const useVoucherCodesClient = ( resetPage(); }; + const handleDeleteAddedVoucherCodes = (idsToDelete: string[]) => { + setAddedVoucherCodes(codes => + codes.filter(({ code }) => !idsToDelete.includes(code)), + ); + }; + return { addedVoucherCodes, clientVoucherCodes, @@ -70,5 +77,6 @@ export const useVoucherCodesClient = ( freeSlotsInClientPagianationPage, handleAddVoucherCode, handleGenerateMultipeCodes, + handleDeleteAddedVoucherCodes, }; }; diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts index 18a886b5b31..75a0dbbf97f 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts @@ -5,6 +5,7 @@ import { useCallback } from "react"; interface VoucherCodesRowSelection { selectedVoucherCodesIds: string[]; + clearRowSelection: () => void; handleSetSelectedVoucherCodesIds: ( rows: number[], clearSelection: () => void, @@ -17,6 +18,7 @@ export const useVoucherCodesRowSelection = ( const { selectedRowIds, setClearDatagridRowSelectionCallback, + clearRowSelection, setSelectedRowIds, } = useRowSelection(); @@ -46,5 +48,6 @@ export const useVoucherCodesRowSelection = ( return { selectedVoucherCodesIds: selectedRowIds, handleSetSelectedVoucherCodesIds, + clearRowSelection, }; }; From bd2e401b5336992cb76b247311d7e135e2ba7b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 10:03:15 +0200 Subject: [PATCH 56/67] Add missing prop to storybook --- .../components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx index a9c160d1bb8..d9a08a2257b 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.stories.tsx @@ -22,6 +22,7 @@ const props: VoucherDetailsPageProps = { ...listActionsProps, ...pageListProps.default, voucherCodes: [], + addedVoucherCodes: [], onVoucherCodesSettingsChange: () => undefined, selectedVoucherCodesIds: [], voucherCodesLoading: false, From 3081a2ef238e308bde1341b9e51cc4e18ac3f3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 10:39:01 +0200 Subject: [PATCH 57/67] New voucher codes at begining in create page --- .../components/VoucherCreatePage/VoucherCreatePage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx index 58fa7cfc4fa..41280fbcef3 100644 --- a/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx +++ b/src/discounts/components/VoucherCreatePage/VoucherCreatePage.tsx @@ -117,7 +117,7 @@ const VoucherCreatePage: React.FC = ({ onModalClose(); clearRowSelection(); set({ - codes: [...data.codes, ...generateMultipleIds(quantity, prefix)], + codes: [...generateMultipleIds(quantity, prefix), ...data.codes], }); }; @@ -220,7 +220,7 @@ const VoucherCreatePage: React.FC = ({ onClose={onModalClose} onSubmit={code => { set({ - codes: [...data.codes, { code }], + codes: [{ code }, ...data.codes], }); }} /> From 0828f4457d53ed592a9640957b04dde7d66098ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 10:39:28 +0200 Subject: [PATCH 58/67] Display voucher name in topbar --- .../components/VoucherDetailsPage/VoucherDetailsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index 3068016ccc1..bbcc256ec92 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -240,7 +240,7 @@ const VoucherDetailsPage: React.FC = ({ return ( - + Date: Tue, 10 Oct 2023 11:20:33 +0200 Subject: [PATCH 59/67] Clear row selection --- src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts | 3 +++ .../views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts index fc8231c051b..d8096fdb50d 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts @@ -27,6 +27,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { hasClientPaginationPrevPage, onSettingsChange, } = useVoucherCodesClient(voucherCodesSettings, () => { + clearRowSelection(); setIsServerPagination(false); }); @@ -76,6 +77,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { }; const handleLoadNextPage = () => { + clearRowSelection(); if (!hasClientPaginationNextPage) { setIsServerPagination(true); } @@ -90,6 +92,7 @@ export const useVoucherCodes = ({ id }: { id: string }) => { }; const handleLoadPrevousPage = () => { + clearRowSelection(); if (!hasServerPaginationPrevPage) { setIsServerPagination(false); } diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts index 75a0dbbf97f..8e2b4172032 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesRowSelection.ts @@ -28,7 +28,7 @@ export const useVoucherCodesRowSelection = ( return; } - const rowsIds = rows.map(row => voucherCodes[row].code).filter(Boolean); + const rowsIds = rows.map(row => voucherCodes[row]?.code).filter(Boolean); const haveSaveValues = isEqual(rowsIds, selectedRowIds); if (!haveSaveValues) { From 07a45eaf0afd51b48bd9c6f9f3f2d42570ab9977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 11:24:13 +0200 Subject: [PATCH 60/67] Make voucher codes datagrid checkbox visible --- .../components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 4df923dae84..69933330c20 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -57,7 +57,7 @@ export const VoucherCodesDatagrid = ({ Date: Tue, 10 Oct 2023 13:40:35 +0200 Subject: [PATCH 61/67] Fix tabing in dialog --- .../VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx index 1c299617ef0..44e31344dba 100644 --- a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx +++ b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx @@ -42,6 +42,7 @@ export const VoucherCodesGenerateDialog = ({ "ArrowUp", "ArrowLeft", "ArrowRight", + "Tab", ].includes(e.key) ) { e.preventDefault(); @@ -95,6 +96,7 @@ export const VoucherCodesGenerateDialog = ({ value={data.prefix} onChange={change} /> + + ) + } + /> + + - - + + ); }; export default VoucherInfo; diff --git a/src/discounts/components/VoucherLimits/VoucherLimits.tsx b/src/discounts/components/VoucherLimits/VoucherLimits.tsx index e2203606185..045a4f6d6e9 100644 --- a/src/discounts/components/VoucherLimits/VoucherLimits.tsx +++ b/src/discounts/components/VoucherLimits/VoucherLimits.tsx @@ -1,6 +1,7 @@ import CardTitle from "@dashboard/components/CardTitle"; import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox"; import { Grid } from "@dashboard/components/Grid"; +import { useFlag } from "@dashboard/featureFlags"; import { DiscountErrorFragment } from "@dashboard/graphql"; import { getFormErrors } from "@dashboard/utils/errors"; import getDiscountErrorMessage from "@dashboard/utils/errors/discounts"; @@ -34,6 +35,8 @@ const VoucherLimits = ({ const intl = useIntl(); const classes = useStyles(); + const voucherCodesFlag = useFlag("voucher_codes"); + const formErrors = getFormErrors(["usageLimit"], errors); const usesLeft = data.usageLimit - data.used; @@ -110,14 +113,15 @@ const VoucherLimits = ({ name={"onlyForStaff" as keyof VoucherDetailsPageFormData} onChange={onChange} /> - - + {voucherCodesFlag.enabled && ( + + )} ); diff --git a/src/discounts/fixtures.ts b/src/discounts/fixtures.ts index fe8bda7a97c..a2195c129f8 100644 --- a/src/discounts/fixtures.ts +++ b/src/discounts/fixtures.ts @@ -589,7 +589,6 @@ export const voucherDetails: VoucherDetailsFragment = { privateMetadata: [], applyOncePerCustomer: false, applyOncePerOrder: false, - singleUse: false, onlyForStaff: false, categoriesCount: { __typename: "CategoryCountableConnection", diff --git a/src/discounts/queries.ts b/src/discounts/queries.ts index 47dd5f41ddc..fa5fb44eb4c 100644 --- a/src/discounts/queries.ts +++ b/src/discounts/queries.ts @@ -96,26 +96,3 @@ export const voucherDetails = gql` } } `; - -export const voucherCodes = gql` - query VoucherCodes( - $id: ID! - $after: String - $before: String - $first: Int - $last: Int - ) { - voucher(id: $id) { - codes(first: $first, last: $last, before: $before, after: $after) { - edges { - node { - ...VoucherCode - } - } - pageInfo { - ...PageInfo - } - } - } - } -`; diff --git a/src/discounts/views/VoucherCreate/handlers.ts b/src/discounts/views/VoucherCreate/handlers.ts index fc198d2c0ec..1f24361fc6c 100644 --- a/src/discounts/views/VoucherCreate/handlers.ts +++ b/src/discounts/views/VoucherCreate/handlers.ts @@ -31,11 +31,10 @@ export function createHandler( return async (formData: VoucherDetailsPageFormData) => { const response = await voucherCreate({ input: { - name: formData.name, applyOncePerCustomer: formData.applyOncePerCustomer, applyOncePerOrder: formData.applyOncePerOrder, onlyForStaff: formData.onlyForStaff, - codes: formData.codes.map(({ code }) => ({ code })), + code: formData.code, discountValueType: formData.discountType === DiscountTypeEnum.VALUE_PERCENTAGE ? DiscountValueTypeEnum.PERCENTAGE @@ -55,7 +54,6 @@ export function createHandler( ? VoucherTypeEnum.SHIPPING : formData.type, usageLimit: formData.hasUsageLimit ? formData.usageLimit : null, - singleUse: formData.singleUse, }, }); diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index b73ecc16542..0c9c34639c1 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -138,13 +138,12 @@ export const VoucherDetails: React.FC = ({ voucherCodesSettings, selectedVoucherCodesIds, addedVoucherCodes, - voucherCodesRefetch, handleSetSelectedVoucherCodesIds, updateVoucherCodesListSettings, handleAddVoucherCode, handleGenerateMultipeCodes, handleDeleteVoucherCodes, - } = useVoucherCodes({ id }); + } = useVoucherCodes(); const [openModal, closeModal] = createDialogActionHandlers< VoucherUrlDialog, @@ -197,7 +196,6 @@ export const VoucherDetails: React.FC = ({ if (data.voucherUpdate.errors.length === 0) { closeModal(); notifySaved(); - voucherCodesRefetch(); } }, }); diff --git a/src/discounts/views/VoucherDetails/handlers.ts b/src/discounts/views/VoucherDetails/handlers.ts index e2db58c181d..32580c87043 100644 --- a/src/discounts/views/VoucherDetails/handlers.ts +++ b/src/discounts/views/VoucherDetails/handlers.ts @@ -57,8 +57,6 @@ export function createUpdateHandler( ? VoucherTypeEnum.SHIPPING : formData.type, usageLimit: formData.hasUsageLimit ? formData.usageLimit : null, - singleUse: formData.singleUse, - codes: formData.codes.map(({ code }) => ({ code })), }, }).then(({ data }) => data?.voucherUpdate.errors ?? []), diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts index 74f12bcc4bd..7426af17aae 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.test.ts @@ -1,44 +1,19 @@ -import { useVoucherCodesQuery } from "@dashboard/graphql"; import { act } from "@testing-library/react"; import { renderHook } from "@testing-library/react-hooks"; import { useVoucherCodes } from "./useVoucherCodes"; -const apiVoucherCodes = Array.from({ length: 10 }, (_, i) => ({ - node: { - code: `code ${i + 1}`, - used: 0, - }, -})); - const autoGeneratedVoucherCodes = Array.from({ length: 5 }, () => ({ code: "code-123456789", status: "Draft", })); jest.mock("uuid", () => ({ v4: () => "123456789" })); -jest.mock("@dashboard/graphql", () => ({ - useVoucherCodesQuery: jest.fn(() => ({ - data: { - voucher: { - codes: { - edges: apiVoucherCodes.slice(0, 2), - pageInfo: { - hasNextPage: true, - hasPreviousPage: false, - }, - }, - }, - }, - - refetch: jest.fn(), - })), -})); describe("useVoucherCodes", () => { it("should return manually generated voucher coded", () => { // Arrange - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + const { result } = renderHook(() => useVoucherCodes()); // Act act(() => { @@ -50,14 +25,12 @@ describe("useVoucherCodes", () => { expect(result.current.voucherCodes).toEqual([ { code: "code 4", status: "Draft" }, { code: "code 3", status: "Draft" }, - { code: "code 1", used: 0 }, - { code: "code 2", used: 0 }, ]); }); it("should return automatictlly genereted voucher codes", () => { // Arrange - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + const { result } = renderHook(() => useVoucherCodes()); // Act act(() => { @@ -68,118 +41,12 @@ describe("useVoucherCodes", () => { }); // Assert - expect(result.current.voucherCodes).toEqual([ - ...autoGeneratedVoucherCodes, - { code: "code 1", used: 0 }, - { code: "code 2", used: 0 }, - ]); - }); - - it("should allow to paginate voucher codes comes from server", () => { - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: apiVoucherCodes.slice(0, 2), - pageInfo: { - hasNextPage: true, - hasPreviousPage: false, - }, - }, - }, - }, - })); - - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); - - // Act - act(() => { - result.current.updateVoucherCodesListSettings("rowNumber", 2); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - false, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - - expect(result.current.voucherCodes).toEqual([ - { code: "code 1", used: 0 }, - { code: "code 2", used: 0 }, - ]); - - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: apiVoucherCodes.slice(2, 4), - pageInfo: { - hasNextPage: false, - hasPreviousPage: true, - }, - }, - }, - }, - })); - - // Act - act(() => { - result.current.voucherCodesPagination.loadNextPage(); - }); - - // Assert - expect(result.current.voucherCodes).toEqual([ - { code: "code 3", used: 0 }, - { code: "code 4", used: 0 }, - ]); - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - false, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - true, - ); - - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: apiVoucherCodes.slice(0, 2), - pageInfo: { - hasNextPage: true, - hasPreviousPage: false, - }, - }, - }, - }, - })); - - // Act - act(() => { - result.current.voucherCodesPagination.loadPreviousPage(); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - expect(result.current.voucherCodes).toEqual([ - { code: "code 1", used: 0 }, - { code: "code 2", used: 0 }, - ]); + expect(result.current.voucherCodes).toEqual([...autoGeneratedVoucherCodes]); }); it("should allow to paginate voucher codes comes from client", () => { // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: null, - })); - - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); + const { result } = renderHook(() => useVoucherCodes()); // Act act(() => { @@ -270,227 +137,4 @@ describe("useVoucherCodes", () => { ...autoGeneratedVoucherCodes, ]); }); - - it("should allow to paginate voucher codes comes from client and server", () => { - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: apiVoucherCodes.slice(0, 2), - pageInfo: { - hasNextPage: false, - hasPreviousPage: true, - }, - }, - }, - }, - })); - - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); - - // Act - act(() => { - result.current.updateVoucherCodesListSettings("rowNumber", 2); - result.current.handleGenerateMultipeCodes({ - quantity: "3", - prefix: "code", - }); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - false, - ); - expect(result.current.voucherCodes).toEqual( - autoGeneratedVoucherCodes.slice(3), - ); - - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: [apiVoucherCodes[0]], - pageInfo: { - hasNextPage: true, - hasPreviousPage: false, - }, - }, - }, - }, - })); - - // Act - act(() => { - result.current.voucherCodesPagination.loadNextPage(); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - true, - ); - expect(result.current.voucherCodes).toEqual([ - ...autoGeneratedVoucherCodes.slice(0, 1), - { code: "code 1", used: 0 }, - ]); - - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: [apiVoucherCodes[1]], - pageInfo: { - hasNextPage: false, - hasPreviousPage: true, - }, - }, - }, - }, - })); - - // Act - act(() => { - result.current.voucherCodesPagination.loadNextPage(); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - false, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - true, - ); - expect(result.current.voucherCodes).toEqual([{ code: "code 2", used: 0 }]); - - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: [apiVoucherCodes[0]], - pageInfo: { - hasNextPage: true, - hasPreviousPage: false, - }, - }, - }, - }, - })); - - // Act - act(() => { - result.current.voucherCodesPagination.loadPreviousPage(); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - true, - ); - - expect(result.current.voucherCodes).toEqual([ - ...autoGeneratedVoucherCodes.slice(0, 1), - { code: "code 1", used: 0 }, - ]); - - // Act - act(() => { - result.current.voucherCodesPagination.loadPreviousPage(); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - false, - ); - expect(result.current.voucherCodes).toEqual( - autoGeneratedVoucherCodes.slice(0, 2), - ); - }); - - it("should allow to handle client and server pagination when client generate whole page", () => { - // Arrange - (useVoucherCodesQuery as jest.Mock).mockImplementation(() => ({ - data: { - voucher: { - codes: { - edges: apiVoucherCodes.slice(0, 2), - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - }, - }, - }, - }, - })); - - const { result } = renderHook(() => useVoucherCodes({ id: "1" })); - - // Act - act(() => { - result.current.updateVoucherCodesListSettings("rowNumber", 10); - result.current.handleGenerateMultipeCodes({ - quantity: "10", - prefix: "code", - }); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - false, - ); - expect(result.current.voucherCodes).toEqual([ - ...autoGeneratedVoucherCodes, - ...autoGeneratedVoucherCodes, - ]); - - // Act - act(() => { - result.current.voucherCodesPagination.loadNextPage(); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - false, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - true, - ); - expect(result.current.voucherCodes).toEqual([ - { code: "code 1", used: 0 }, - { code: "code 2", used: 0 }, - ]); - - // Act - act(() => { - result.current.voucherCodesPagination.loadPreviousPage(); - }); - - // Assert - expect(result.current.voucherCodesPagination.pageInfo.hasNextPage).toBe( - true, - ); - expect(result.current.voucherCodesPagination.pageInfo.hasPreviousPage).toBe( - false, - ); - expect(result.current.voucherCodes).toEqual([ - ...autoGeneratedVoucherCodes, - ...autoGeneratedVoucherCodes, - ]); - }); }); diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts index d8096fdb50d..9211bb7a9ad 100644 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts +++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodes.ts @@ -1,147 +1,43 @@ import useListSettings from "@dashboard/hooks/useListSettings"; import { ListViews } from "@dashboard/types"; -import { useState } from "react"; -import { getVoucherCodesToDisplay } from "../utils"; import { useVoucherCodesClient } from "./useVoucherCodesClient"; import { useVoucherCodesRowSelection } from "./useVoucherCodesRowSelection"; -import { useVoucherCodesServer } from "./useVoucherCodesServer"; -export const useVoucherCodes = ({ id }: { id: string }) => { +export const useVoucherCodes = () => { const { settings: voucherCodesSettings, updateListSettings: updateVoucherCodesListSettings, } = useListSettings(ListViews.VOUCHER_CODES); - const [isServerPagination, setIsServerPagination] = useState(true); - const { addedVoucherCodes, clientVoucherCodes, clientVoucherCodesPagination, - freeSlotsInClientPagianationPage, handleAddVoucherCode, handleGenerateMultipeCodes, handleDeleteAddedVoucherCodes, - hasClientPaginationNextPage, - hasClientPaginationPrevPage, onSettingsChange, } = useVoucherCodesClient(voucherCodesSettings, () => { clearRowSelection(); - setIsServerPagination(false); - }); - - const { - freeSlotsInServerPagianationPage, - hasServerPaginationNextPage, - hasServerPaginationPrevPage, - serverVoucherCodesPagination, - serverVoucherCodes, - voucherCodesLoading, - voucherCodesRefetch, - } = useVoucherCodesServer({ - id, - settings: voucherCodesSettings, - isServerPagination, - paginationState: { - first: - !isServerPagination && freeSlotsInClientPagianationPage > 0 - ? freeSlotsInClientPagianationPage - : voucherCodesSettings.rowNumber, - }, - }); - - const voucherCodes = getVoucherCodesToDisplay({ - clientVoucherCodes, - freeSlotsInClientPagianationPage, - hasClientPaginationNextPage, - freeSlotsInServerPagianationPage, - hasServerPaginationPrevPage, - isServerPagination, - serverVoucherCodes, }); - const voucherCodesPagination = isServerPagination - ? serverVoucherCodesPagination - : clientVoucherCodesPagination; - const { selectedVoucherCodesIds, handleSetSelectedVoucherCodesIds, clearRowSelection, - } = useVoucherCodesRowSelection(voucherCodes); + } = useVoucherCodesRowSelection(clientVoucherCodes); const handleDeleteVoucherCodes = () => { clearRowSelection(); handleDeleteAddedVoucherCodes(selectedVoucherCodesIds); }; - const handleLoadNextPage = () => { - clearRowSelection(); - if (!hasClientPaginationNextPage) { - setIsServerPagination(true); - } - - if (isServerPagination) { - serverVoucherCodesPagination.loadNextPage(); - } else if (!isServerPagination && freeSlotsInClientPagianationPage > 0) { - serverVoucherCodesPagination.loadNextPage(); - } - - clientVoucherCodesPagination.loadNextPage(); - }; - - const handleLoadPrevousPage = () => { - clearRowSelection(); - if (!hasServerPaginationPrevPage) { - setIsServerPagination(false); - } - - if (isServerPagination && hasServerPaginationPrevPage) { - serverVoucherCodesPagination.loadPreviousPage(); - } - - clientVoucherCodesPagination.loadPreviousPage(); - }; - - const calculateHasNextPage = () => { - // In case when client voucher codes takes all slots - // on page and there are some server voucher codes to display - if ( - !isServerPagination && - !hasClientPaginationNextPage && - freeSlotsInClientPagianationPage === 0 && - serverVoucherCodes.length > 0 - ) { - return true; - } - - return hasClientPaginationNextPage || hasServerPaginationNextPage; - }; - - const calculateHasPrevPage = () => { - if (isServerPagination) { - return hasServerPaginationPrevPage || hasClientPaginationPrevPage; - } - - return hasClientPaginationPrevPage; - }; - return { - voucherCodes, + voucherCodes: clientVoucherCodes, addedVoucherCodes, - voucherCodesLoading, - voucherCodesPagination: { - ...voucherCodesPagination, - pageInfo: { - ...voucherCodesPagination.pageInfo, - hasNextPage: calculateHasNextPage(), - hasPreviousPage: calculateHasPrevPage(), - }, - loadNextPage: handleLoadNextPage, - loadPreviousPage: handleLoadPrevousPage, - }, - voucherCodesRefetch, + voucherCodesLoading: false, + voucherCodesPagination: clientVoucherCodesPagination, voucherCodesSettings, updateVoucherCodesListSettings: (key: any, value: any) => { updateVoucherCodesListSettings(key, value); diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx deleted file mode 100644 index 23dd1476f55..00000000000 --- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesServer.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagrid/types"; -import { useVoucherCodesQuery } from "@dashboard/graphql"; -import useLocalPaginator, { - LocalPagination, - PaginationState, - useLocalPaginationState, -} from "@dashboard/hooks/useLocalPaginator"; -import { ListSettings } from "@dashboard/types"; -import { mapEdgesToItems } from "@dashboard/utils/maps"; - -interface UseVoucherCodesServerProps { - settings: ListSettings; - id: string; - skipFetch?: boolean; - isServerPagination?: boolean; - paginationState?: PaginationState; -} - -interface VoucherCodesServer { - voucherCodesLoading: boolean; - voucherCodesRefetch: () => void; - serverVoucherCodesPagination: LocalPagination; - hasServerPaginationNextPage: boolean; - hasServerPaginationPrevPage: boolean; - freeSlotsInServerPagianationPage: number; - serverVoucherCodes: VoucherCode[]; -} - -export const useVoucherCodesServer = ({ - settings, - id, - isServerPagination, - paginationState = {}, -}: UseVoucherCodesServerProps): VoucherCodesServer => { - const [ - serverVoucherCodesPaginationState, - setServerVoucherCodesPaginationState, - ] = useLocalPaginationState(settings.rowNumber); - - const serverVoucherCodesPaginate = useLocalPaginator( - setServerVoucherCodesPaginationState, - ); - - const { - data: voucherCodesData, - loading: voucherCodesLoading, - refetch: voucherCodesRefetch, - } = useVoucherCodesQuery({ - variables: { - id, - ...(!isServerPagination - ? paginationState - : serverVoucherCodesPaginationState), - }, - }); - - const serverVoucherCodesPagination = serverVoucherCodesPaginate( - voucherCodesData?.voucher?.codes?.pageInfo, - serverVoucherCodesPaginationState, - ); - - const hasServerPaginationNextPage = - serverVoucherCodesPagination?.pageInfo?.hasNextPage ?? false; - const hasServerPaginationPrevPage = - serverVoucherCodesPagination?.pageInfo?.hasPreviousPage ?? false; - - const serverVoucherCodes = (mapEdgesToItems( - voucherCodesData?.voucher?.codes, - ) ?? []) as VoucherCode[]; - - const freeSlotsInServerPagianationPage = - settings.rowNumber - serverVoucherCodes.length; - - return { - voucherCodesLoading, - voucherCodesRefetch, - serverVoucherCodes, - serverVoucherCodesPagination, - hasServerPaginationNextPage, - hasServerPaginationPrevPage, - freeSlotsInServerPagianationPage, - }; -}; diff --git a/src/fragments/discounts.ts b/src/fragments/discounts.ts index a6171902bf8..d830cc424a2 100644 --- a/src/fragments/discounts.ts +++ b/src/fragments/discounts.ts @@ -150,14 +150,6 @@ export const voucherFragment = gql` } `; -export const voucherCodeFragment = gql` - fragment VoucherCode on VoucherCode { - code - used - isActive - } -`; - export const voucherDetailsFragment = gql` fragment VoucherDetails on Voucher { ...Voucher @@ -167,7 +159,6 @@ export const voucherDetailsFragment = gql` applyOncePerOrder applyOncePerCustomer onlyForStaff - singleUse productsCount: products { totalCount } diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index 3b7379b5af1..7f476947647 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -521,13 +521,6 @@ export const SaleDetailsFragmentDoc = gql` ${SaleFragmentDoc} ${ChannelListingProductWithoutPricingFragmentDoc} ${PageInfoFragmentDoc}`; -export const VoucherCodeFragmentDoc = gql` - fragment VoucherCode on VoucherCode { - code - used - isActive -} - `; export const VoucherFragmentDoc = gql` fragment Voucher on Voucher { ...Metadata @@ -569,7 +562,6 @@ export const VoucherDetailsFragmentDoc = gql` applyOncePerOrder applyOncePerCustomer onlyForStaff - singleUse productsCount: products { totalCount } @@ -7898,55 +7890,6 @@ export function useVoucherDetailsLazyQuery(baseOptions?: ApolloReactHooks.LazyQu export type VoucherDetailsQueryHookResult = ReturnType; export type VoucherDetailsLazyQueryHookResult = ReturnType; export type VoucherDetailsQueryResult = Apollo.QueryResult; -export const VoucherCodesDocument = gql` - query VoucherCodes($id: ID!, $after: String, $before: String, $first: Int, $last: Int) { - voucher(id: $id) { - codes(first: $first, last: $last, before: $before, after: $after) { - edges { - node { - ...VoucherCode - } - } - pageInfo { - ...PageInfo - } - } - } -} - ${VoucherCodeFragmentDoc} -${PageInfoFragmentDoc}`; - -/** - * __useVoucherCodesQuery__ - * - * To run a query within a React component, call `useVoucherCodesQuery` and pass it any options that fit your needs. - * When your component renders, `useVoucherCodesQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useVoucherCodesQuery({ - * variables: { - * id: // value for 'id' - * after: // value for 'after' - * before: // value for 'before' - * first: // value for 'first' - * last: // value for 'last' - * }, - * }); - */ -export function useVoucherCodesQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useQuery(VoucherCodesDocument, options); - } -export function useVoucherCodesLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useLazyQuery(VoucherCodesDocument, options); - } -export type VoucherCodesQueryHookResult = ReturnType; -export type VoucherCodesLazyQueryHookResult = ReturnType; -export type VoucherCodesQueryResult = Apollo.QueryResult; export const FileUploadDocument = gql` mutation FileUpload($file: Upload!) { fileUpload(file: $file) { diff --git a/src/graphql/typePolicies.generated.ts b/src/graphql/typePolicies.generated.ts index fa4228b4037..d76661976b5 100644 --- a/src/graphql/typePolicies.generated.ts +++ b/src/graphql/typePolicies.generated.ts @@ -1660,14 +1660,13 @@ export type DigitalContentUrlCreateFieldPolicy = { errors?: FieldPolicy | FieldReadFunction, productErrors?: FieldPolicy | FieldReadFunction }; -export type DiscountErrorKeySpecifier = ('channels' | 'code' | 'field' | 'message' | 'products' | 'voucherCodes' | DiscountErrorKeySpecifier)[]; +export type DiscountErrorKeySpecifier = ('channels' | 'code' | 'field' | 'message' | 'products' | DiscountErrorKeySpecifier)[]; export type DiscountErrorFieldPolicy = { channels?: FieldPolicy | FieldReadFunction, code?: FieldPolicy | FieldReadFunction, field?: FieldPolicy | FieldReadFunction, message?: FieldPolicy | FieldReadFunction, - products?: FieldPolicy | FieldReadFunction, - voucherCodes?: FieldPolicy | FieldReadFunction + products?: FieldPolicy | FieldReadFunction }; export type DomainKeySpecifier = ('host' | 'sslEnabled' | 'url' | DomainKeySpecifier)[]; export type DomainFieldPolicy = { @@ -2617,7 +2616,7 @@ export type MoneyRangeFieldPolicy = { start?: FieldPolicy | FieldReadFunction, stop?: FieldPolicy | FieldReadFunction }; -export type MutationKeySpecifier = ('accountAddressCreate' | 'accountAddressDelete' | 'accountAddressUpdate' | 'accountDelete' | 'accountRegister' | 'accountRequestDeletion' | 'accountSetDefaultAddress' | 'accountUpdate' | 'addressCreate' | 'addressDelete' | 'addressSetDefault' | 'addressUpdate' | 'appActivate' | 'appCreate' | 'appDeactivate' | 'appDelete' | 'appDeleteFailedInstallation' | 'appFetchManifest' | 'appInstall' | 'appRetryInstall' | 'appTokenCreate' | 'appTokenDelete' | 'appTokenVerify' | 'appUpdate' | 'assignNavigation' | 'assignWarehouseShippingZone' | 'attributeBulkCreate' | 'attributeBulkDelete' | 'attributeBulkTranslate' | 'attributeBulkUpdate' | 'attributeCreate' | 'attributeDelete' | 'attributeReorderValues' | 'attributeTranslate' | 'attributeUpdate' | 'attributeValueBulkDelete' | 'attributeValueBulkTranslate' | 'attributeValueCreate' | 'attributeValueDelete' | 'attributeValueTranslate' | 'attributeValueUpdate' | 'categoryBulkDelete' | 'categoryCreate' | 'categoryDelete' | 'categoryTranslate' | 'categoryUpdate' | 'channelActivate' | 'channelCreate' | 'channelDeactivate' | 'channelDelete' | 'channelReorderWarehouses' | 'channelUpdate' | 'checkoutAddPromoCode' | 'checkoutBillingAddressUpdate' | 'checkoutComplete' | 'checkoutCreate' | 'checkoutCreateFromOrder' | 'checkoutCustomerAttach' | 'checkoutCustomerDetach' | 'checkoutDeliveryMethodUpdate' | 'checkoutEmailUpdate' | 'checkoutLanguageCodeUpdate' | 'checkoutLineDelete' | 'checkoutLinesAdd' | 'checkoutLinesDelete' | 'checkoutLinesUpdate' | 'checkoutPaymentCreate' | 'checkoutRemovePromoCode' | 'checkoutShippingAddressUpdate' | 'checkoutShippingMethodUpdate' | 'collectionAddProducts' | 'collectionBulkDelete' | 'collectionChannelListingUpdate' | 'collectionCreate' | 'collectionDelete' | 'collectionRemoveProducts' | 'collectionReorderProducts' | 'collectionTranslate' | 'collectionUpdate' | 'confirmAccount' | 'confirmEmailChange' | 'createWarehouse' | 'customerBulkDelete' | 'customerBulkUpdate' | 'customerCreate' | 'customerDelete' | 'customerUpdate' | 'deleteMetadata' | 'deletePrivateMetadata' | 'deleteWarehouse' | 'digitalContentCreate' | 'digitalContentDelete' | 'digitalContentUpdate' | 'digitalContentUrlCreate' | 'draftOrderBulkDelete' | 'draftOrderComplete' | 'draftOrderCreate' | 'draftOrderDelete' | 'draftOrderLinesBulkDelete' | 'draftOrderUpdate' | 'eventDeliveryRetry' | 'exportGiftCards' | 'exportProducts' | 'externalAuthenticationUrl' | 'externalLogout' | 'externalNotificationTrigger' | 'externalObtainAccessTokens' | 'externalRefresh' | 'externalVerify' | 'fileUpload' | 'giftCardActivate' | 'giftCardAddNote' | 'giftCardBulkActivate' | 'giftCardBulkCreate' | 'giftCardBulkDeactivate' | 'giftCardBulkDelete' | 'giftCardCreate' | 'giftCardDeactivate' | 'giftCardDelete' | 'giftCardResend' | 'giftCardSettingsUpdate' | 'giftCardUpdate' | 'invoiceCreate' | 'invoiceDelete' | 'invoiceRequest' | 'invoiceRequestDelete' | 'invoiceSendNotification' | 'invoiceUpdate' | 'menuBulkDelete' | 'menuCreate' | 'menuDelete' | 'menuItemBulkDelete' | 'menuItemCreate' | 'menuItemDelete' | 'menuItemMove' | 'menuItemTranslate' | 'menuItemUpdate' | 'menuUpdate' | 'orderAddNote' | 'orderBulkCancel' | 'orderBulkCreate' | 'orderCancel' | 'orderCapture' | 'orderConfirm' | 'orderCreateFromCheckout' | 'orderDiscountAdd' | 'orderDiscountDelete' | 'orderDiscountUpdate' | 'orderFulfill' | 'orderFulfillmentApprove' | 'orderFulfillmentCancel' | 'orderFulfillmentRefundProducts' | 'orderFulfillmentReturnProducts' | 'orderFulfillmentUpdateTracking' | 'orderGrantRefundCreate' | 'orderGrantRefundUpdate' | 'orderLineDelete' | 'orderLineDiscountRemove' | 'orderLineDiscountUpdate' | 'orderLineUpdate' | 'orderLinesCreate' | 'orderMarkAsPaid' | 'orderNoteAdd' | 'orderNoteUpdate' | 'orderRefund' | 'orderSettingsUpdate' | 'orderUpdate' | 'orderUpdateShipping' | 'orderVoid' | 'pageAttributeAssign' | 'pageAttributeUnassign' | 'pageBulkDelete' | 'pageBulkPublish' | 'pageCreate' | 'pageDelete' | 'pageReorderAttributeValues' | 'pageTranslate' | 'pageTypeBulkDelete' | 'pageTypeCreate' | 'pageTypeDelete' | 'pageTypeReorderAttributes' | 'pageTypeUpdate' | 'pageUpdate' | 'passwordChange' | 'paymentCapture' | 'paymentCheckBalance' | 'paymentGatewayInitialize' | 'paymentGatewayInitializeTokenization' | 'paymentInitialize' | 'paymentMethodInitializeTokenization' | 'paymentMethodProcessTokenization' | 'paymentRefund' | 'paymentVoid' | 'permissionGroupCreate' | 'permissionGroupDelete' | 'permissionGroupUpdate' | 'pluginUpdate' | 'productAttributeAssign' | 'productAttributeAssignmentUpdate' | 'productAttributeUnassign' | 'productBulkCreate' | 'productBulkDelete' | 'productBulkTranslate' | 'productChannelListingUpdate' | 'productCreate' | 'productDelete' | 'productMediaBulkDelete' | 'productMediaCreate' | 'productMediaDelete' | 'productMediaReorder' | 'productMediaUpdate' | 'productReorderAttributeValues' | 'productTranslate' | 'productTypeBulkDelete' | 'productTypeCreate' | 'productTypeDelete' | 'productTypeReorderAttributes' | 'productTypeUpdate' | 'productUpdate' | 'productVariantBulkCreate' | 'productVariantBulkDelete' | 'productVariantBulkTranslate' | 'productVariantBulkUpdate' | 'productVariantChannelListingUpdate' | 'productVariantCreate' | 'productVariantDelete' | 'productVariantPreorderDeactivate' | 'productVariantReorder' | 'productVariantReorderAttributeValues' | 'productVariantSetDefault' | 'productVariantStocksCreate' | 'productVariantStocksDelete' | 'productVariantStocksUpdate' | 'productVariantTranslate' | 'productVariantUpdate' | 'promotionBulkDelete' | 'promotionCreate' | 'promotionDelete' | 'promotionRuleCreate' | 'promotionRuleDelete' | 'promotionRuleTranslate' | 'promotionRuleUpdate' | 'promotionTranslate' | 'promotionUpdate' | 'requestEmailChange' | 'requestPasswordReset' | 'saleBulkDelete' | 'saleCataloguesAdd' | 'saleCataloguesRemove' | 'saleChannelListingUpdate' | 'saleCreate' | 'saleDelete' | 'saleTranslate' | 'saleUpdate' | 'sendConfirmationEmail' | 'setPassword' | 'shippingMethodChannelListingUpdate' | 'shippingPriceBulkDelete' | 'shippingPriceCreate' | 'shippingPriceDelete' | 'shippingPriceExcludeProducts' | 'shippingPriceRemoveProductFromExclude' | 'shippingPriceTranslate' | 'shippingPriceUpdate' | 'shippingZoneBulkDelete' | 'shippingZoneCreate' | 'shippingZoneDelete' | 'shippingZoneUpdate' | 'shopAddressUpdate' | 'shopDomainUpdate' | 'shopFetchTaxRates' | 'shopSettingsTranslate' | 'shopSettingsUpdate' | 'staffBulkDelete' | 'staffCreate' | 'staffDelete' | 'staffNotificationRecipientCreate' | 'staffNotificationRecipientDelete' | 'staffNotificationRecipientUpdate' | 'staffUpdate' | 'stockBulkUpdate' | 'storedPaymentMethodRequestDelete' | 'taxClassCreate' | 'taxClassDelete' | 'taxClassUpdate' | 'taxConfigurationUpdate' | 'taxCountryConfigurationDelete' | 'taxCountryConfigurationUpdate' | 'taxExemptionManage' | 'tokenCreate' | 'tokenRefresh' | 'tokenVerify' | 'tokensDeactivateAll' | 'transactionCreate' | 'transactionEventReport' | 'transactionInitialize' | 'transactionProcess' | 'transactionRequestAction' | 'transactionRequestRefundForGrantedRefund' | 'transactionUpdate' | 'unassignWarehouseShippingZone' | 'updateMetadata' | 'updatePrivateMetadata' | 'updateWarehouse' | 'userAvatarDelete' | 'userAvatarUpdate' | 'userBulkSetActive' | 'variantMediaAssign' | 'variantMediaUnassign' | 'voucherBulkDelete' | 'voucherCataloguesAdd' | 'voucherCataloguesRemove' | 'voucherChannelListingUpdate' | 'voucherCodeBulkDelete' | 'voucherCreate' | 'voucherDelete' | 'voucherTranslate' | 'voucherUpdate' | 'webhookCreate' | 'webhookDelete' | 'webhookDryRun' | 'webhookTrigger' | 'webhookUpdate' | MutationKeySpecifier)[]; +export type MutationKeySpecifier = ('accountAddressCreate' | 'accountAddressDelete' | 'accountAddressUpdate' | 'accountDelete' | 'accountRegister' | 'accountRequestDeletion' | 'accountSetDefaultAddress' | 'accountUpdate' | 'addressCreate' | 'addressDelete' | 'addressSetDefault' | 'addressUpdate' | 'appActivate' | 'appCreate' | 'appDeactivate' | 'appDelete' | 'appDeleteFailedInstallation' | 'appFetchManifest' | 'appInstall' | 'appRetryInstall' | 'appTokenCreate' | 'appTokenDelete' | 'appTokenVerify' | 'appUpdate' | 'assignNavigation' | 'assignWarehouseShippingZone' | 'attributeBulkCreate' | 'attributeBulkDelete' | 'attributeBulkTranslate' | 'attributeBulkUpdate' | 'attributeCreate' | 'attributeDelete' | 'attributeReorderValues' | 'attributeTranslate' | 'attributeUpdate' | 'attributeValueBulkDelete' | 'attributeValueBulkTranslate' | 'attributeValueCreate' | 'attributeValueDelete' | 'attributeValueTranslate' | 'attributeValueUpdate' | 'categoryBulkDelete' | 'categoryCreate' | 'categoryDelete' | 'categoryTranslate' | 'categoryUpdate' | 'channelActivate' | 'channelCreate' | 'channelDeactivate' | 'channelDelete' | 'channelReorderWarehouses' | 'channelUpdate' | 'checkoutAddPromoCode' | 'checkoutBillingAddressUpdate' | 'checkoutComplete' | 'checkoutCreate' | 'checkoutCreateFromOrder' | 'checkoutCustomerAttach' | 'checkoutCustomerDetach' | 'checkoutDeliveryMethodUpdate' | 'checkoutEmailUpdate' | 'checkoutLanguageCodeUpdate' | 'checkoutLineDelete' | 'checkoutLinesAdd' | 'checkoutLinesDelete' | 'checkoutLinesUpdate' | 'checkoutPaymentCreate' | 'checkoutRemovePromoCode' | 'checkoutShippingAddressUpdate' | 'checkoutShippingMethodUpdate' | 'collectionAddProducts' | 'collectionBulkDelete' | 'collectionChannelListingUpdate' | 'collectionCreate' | 'collectionDelete' | 'collectionRemoveProducts' | 'collectionReorderProducts' | 'collectionTranslate' | 'collectionUpdate' | 'confirmAccount' | 'confirmEmailChange' | 'createWarehouse' | 'customerBulkDelete' | 'customerBulkUpdate' | 'customerCreate' | 'customerDelete' | 'customerUpdate' | 'deleteMetadata' | 'deletePrivateMetadata' | 'deleteWarehouse' | 'digitalContentCreate' | 'digitalContentDelete' | 'digitalContentUpdate' | 'digitalContentUrlCreate' | 'draftOrderBulkDelete' | 'draftOrderComplete' | 'draftOrderCreate' | 'draftOrderDelete' | 'draftOrderLinesBulkDelete' | 'draftOrderUpdate' | 'eventDeliveryRetry' | 'exportGiftCards' | 'exportProducts' | 'externalAuthenticationUrl' | 'externalLogout' | 'externalNotificationTrigger' | 'externalObtainAccessTokens' | 'externalRefresh' | 'externalVerify' | 'fileUpload' | 'giftCardActivate' | 'giftCardAddNote' | 'giftCardBulkActivate' | 'giftCardBulkCreate' | 'giftCardBulkDeactivate' | 'giftCardBulkDelete' | 'giftCardCreate' | 'giftCardDeactivate' | 'giftCardDelete' | 'giftCardResend' | 'giftCardSettingsUpdate' | 'giftCardUpdate' | 'invoiceCreate' | 'invoiceDelete' | 'invoiceRequest' | 'invoiceRequestDelete' | 'invoiceSendNotification' | 'invoiceUpdate' | 'menuBulkDelete' | 'menuCreate' | 'menuDelete' | 'menuItemBulkDelete' | 'menuItemCreate' | 'menuItemDelete' | 'menuItemMove' | 'menuItemTranslate' | 'menuItemUpdate' | 'menuUpdate' | 'orderAddNote' | 'orderBulkCancel' | 'orderBulkCreate' | 'orderCancel' | 'orderCapture' | 'orderConfirm' | 'orderCreateFromCheckout' | 'orderDiscountAdd' | 'orderDiscountDelete' | 'orderDiscountUpdate' | 'orderFulfill' | 'orderFulfillmentApprove' | 'orderFulfillmentCancel' | 'orderFulfillmentRefundProducts' | 'orderFulfillmentReturnProducts' | 'orderFulfillmentUpdateTracking' | 'orderGrantRefundCreate' | 'orderGrantRefundUpdate' | 'orderLineDelete' | 'orderLineDiscountRemove' | 'orderLineDiscountUpdate' | 'orderLineUpdate' | 'orderLinesCreate' | 'orderMarkAsPaid' | 'orderNoteAdd' | 'orderNoteUpdate' | 'orderRefund' | 'orderSettingsUpdate' | 'orderUpdate' | 'orderUpdateShipping' | 'orderVoid' | 'pageAttributeAssign' | 'pageAttributeUnassign' | 'pageBulkDelete' | 'pageBulkPublish' | 'pageCreate' | 'pageDelete' | 'pageReorderAttributeValues' | 'pageTranslate' | 'pageTypeBulkDelete' | 'pageTypeCreate' | 'pageTypeDelete' | 'pageTypeReorderAttributes' | 'pageTypeUpdate' | 'pageUpdate' | 'passwordChange' | 'paymentCapture' | 'paymentCheckBalance' | 'paymentGatewayInitialize' | 'paymentGatewayInitializeTokenization' | 'paymentInitialize' | 'paymentMethodInitializeTokenization' | 'paymentMethodProcessTokenization' | 'paymentRefund' | 'paymentVoid' | 'permissionGroupCreate' | 'permissionGroupDelete' | 'permissionGroupUpdate' | 'pluginUpdate' | 'productAttributeAssign' | 'productAttributeAssignmentUpdate' | 'productAttributeUnassign' | 'productBulkCreate' | 'productBulkDelete' | 'productBulkTranslate' | 'productChannelListingUpdate' | 'productCreate' | 'productDelete' | 'productMediaBulkDelete' | 'productMediaCreate' | 'productMediaDelete' | 'productMediaReorder' | 'productMediaUpdate' | 'productReorderAttributeValues' | 'productTranslate' | 'productTypeBulkDelete' | 'productTypeCreate' | 'productTypeDelete' | 'productTypeReorderAttributes' | 'productTypeUpdate' | 'productUpdate' | 'productVariantBulkCreate' | 'productVariantBulkDelete' | 'productVariantBulkTranslate' | 'productVariantBulkUpdate' | 'productVariantChannelListingUpdate' | 'productVariantCreate' | 'productVariantDelete' | 'productVariantPreorderDeactivate' | 'productVariantReorder' | 'productVariantReorderAttributeValues' | 'productVariantSetDefault' | 'productVariantStocksCreate' | 'productVariantStocksDelete' | 'productVariantStocksUpdate' | 'productVariantTranslate' | 'productVariantUpdate' | 'promotionBulkDelete' | 'promotionCreate' | 'promotionDelete' | 'promotionRuleCreate' | 'promotionRuleDelete' | 'promotionRuleTranslate' | 'promotionRuleUpdate' | 'promotionTranslate' | 'promotionUpdate' | 'requestEmailChange' | 'requestPasswordReset' | 'saleBulkDelete' | 'saleCataloguesAdd' | 'saleCataloguesRemove' | 'saleChannelListingUpdate' | 'saleCreate' | 'saleDelete' | 'saleTranslate' | 'saleUpdate' | 'sendConfirmationEmail' | 'setPassword' | 'shippingMethodChannelListingUpdate' | 'shippingPriceBulkDelete' | 'shippingPriceCreate' | 'shippingPriceDelete' | 'shippingPriceExcludeProducts' | 'shippingPriceRemoveProductFromExclude' | 'shippingPriceTranslate' | 'shippingPriceUpdate' | 'shippingZoneBulkDelete' | 'shippingZoneCreate' | 'shippingZoneDelete' | 'shippingZoneUpdate' | 'shopAddressUpdate' | 'shopDomainUpdate' | 'shopFetchTaxRates' | 'shopSettingsTranslate' | 'shopSettingsUpdate' | 'staffBulkDelete' | 'staffCreate' | 'staffDelete' | 'staffNotificationRecipientCreate' | 'staffNotificationRecipientDelete' | 'staffNotificationRecipientUpdate' | 'staffUpdate' | 'stockBulkUpdate' | 'storedPaymentMethodRequestDelete' | 'taxClassCreate' | 'taxClassDelete' | 'taxClassUpdate' | 'taxConfigurationUpdate' | 'taxCountryConfigurationDelete' | 'taxCountryConfigurationUpdate' | 'taxExemptionManage' | 'tokenCreate' | 'tokenRefresh' | 'tokenVerify' | 'tokensDeactivateAll' | 'transactionCreate' | 'transactionEventReport' | 'transactionInitialize' | 'transactionProcess' | 'transactionRequestAction' | 'transactionRequestRefundForGrantedRefund' | 'transactionUpdate' | 'unassignWarehouseShippingZone' | 'updateMetadata' | 'updatePrivateMetadata' | 'updateWarehouse' | 'userAvatarDelete' | 'userAvatarUpdate' | 'userBulkSetActive' | 'variantMediaAssign' | 'variantMediaUnassign' | 'voucherBulkDelete' | 'voucherCataloguesAdd' | 'voucherCataloguesRemove' | 'voucherChannelListingUpdate' | 'voucherCreate' | 'voucherDelete' | 'voucherTranslate' | 'voucherUpdate' | 'webhookCreate' | 'webhookDelete' | 'webhookDryRun' | 'webhookTrigger' | 'webhookUpdate' | MutationKeySpecifier)[]; export type MutationFieldPolicy = { accountAddressCreate?: FieldPolicy | FieldReadFunction, accountAddressDelete?: FieldPolicy | FieldReadFunction, @@ -2932,7 +2931,6 @@ export type MutationFieldPolicy = { voucherCataloguesAdd?: FieldPolicy | FieldReadFunction, voucherCataloguesRemove?: FieldPolicy | FieldReadFunction, voucherChannelListingUpdate?: FieldPolicy | FieldReadFunction, - voucherCodeBulkDelete?: FieldPolicy | FieldReadFunction, voucherCreate?: FieldPolicy | FieldReadFunction, voucherDelete?: FieldPolicy | FieldReadFunction, voucherTranslate?: FieldPolicy | FieldReadFunction, @@ -6455,14 +6453,13 @@ export type VerifyTokenFieldPolicy = { payload?: FieldPolicy | FieldReadFunction, user?: FieldPolicy | FieldReadFunction }; -export type VoucherKeySpecifier = ('applyOncePerCustomer' | 'applyOncePerOrder' | 'categories' | 'channelListings' | 'code' | 'codes' | 'collections' | 'countries' | 'currency' | 'discountValue' | 'discountValueType' | 'endDate' | 'id' | 'metadata' | 'metafield' | 'metafields' | 'minCheckoutItemsQuantity' | 'minSpent' | 'name' | 'onlyForStaff' | 'privateMetadata' | 'privateMetafield' | 'privateMetafields' | 'products' | 'singleUse' | 'startDate' | 'translation' | 'type' | 'usageLimit' | 'used' | 'variants' | VoucherKeySpecifier)[]; +export type VoucherKeySpecifier = ('applyOncePerCustomer' | 'applyOncePerOrder' | 'categories' | 'channelListings' | 'code' | 'collections' | 'countries' | 'currency' | 'discountValue' | 'discountValueType' | 'endDate' | 'id' | 'metadata' | 'metafield' | 'metafields' | 'minCheckoutItemsQuantity' | 'minSpent' | 'name' | 'onlyForStaff' | 'privateMetadata' | 'privateMetafield' | 'privateMetafields' | 'products' | 'startDate' | 'translation' | 'type' | 'usageLimit' | 'used' | 'variants' | VoucherKeySpecifier)[]; export type VoucherFieldPolicy = { applyOncePerCustomer?: FieldPolicy | FieldReadFunction, applyOncePerOrder?: FieldPolicy | FieldReadFunction, categories?: FieldPolicy | FieldReadFunction, channelListings?: FieldPolicy | FieldReadFunction, code?: FieldPolicy | FieldReadFunction, - codes?: FieldPolicy | FieldReadFunction, collections?: FieldPolicy | FieldReadFunction, countries?: FieldPolicy | FieldReadFunction, currency?: FieldPolicy | FieldReadFunction, @@ -6481,7 +6478,6 @@ export type VoucherFieldPolicy = { privateMetafield?: FieldPolicy | FieldReadFunction, privateMetafields?: FieldPolicy | FieldReadFunction, products?: FieldPolicy | FieldReadFunction, - singleUse?: FieldPolicy | FieldReadFunction, startDate?: FieldPolicy | FieldReadFunction, translation?: FieldPolicy | FieldReadFunction, type?: FieldPolicy | FieldReadFunction, @@ -6515,36 +6511,6 @@ export type VoucherChannelListingUpdateFieldPolicy = { errors?: FieldPolicy | FieldReadFunction, voucher?: FieldPolicy | FieldReadFunction }; -export type VoucherCodeKeySpecifier = ('code' | 'id' | 'isActive' | 'used' | VoucherCodeKeySpecifier)[]; -export type VoucherCodeFieldPolicy = { - code?: FieldPolicy | FieldReadFunction, - id?: FieldPolicy | FieldReadFunction, - isActive?: FieldPolicy | FieldReadFunction, - used?: FieldPolicy | FieldReadFunction -}; -export type VoucherCodeBulkDeleteKeySpecifier = ('count' | 'errors' | VoucherCodeBulkDeleteKeySpecifier)[]; -export type VoucherCodeBulkDeleteFieldPolicy = { - count?: FieldPolicy | FieldReadFunction, - errors?: FieldPolicy | FieldReadFunction -}; -export type VoucherCodeBulkDeleteErrorKeySpecifier = ('code' | 'message' | 'path' | 'voucherCodes' | VoucherCodeBulkDeleteErrorKeySpecifier)[]; -export type VoucherCodeBulkDeleteErrorFieldPolicy = { - code?: FieldPolicy | FieldReadFunction, - message?: FieldPolicy | FieldReadFunction, - path?: FieldPolicy | FieldReadFunction, - voucherCodes?: FieldPolicy | FieldReadFunction -}; -export type VoucherCodeCountableConnectionKeySpecifier = ('edges' | 'pageInfo' | 'totalCount' | VoucherCodeCountableConnectionKeySpecifier)[]; -export type VoucherCodeCountableConnectionFieldPolicy = { - edges?: FieldPolicy | FieldReadFunction, - pageInfo?: FieldPolicy | FieldReadFunction, - totalCount?: FieldPolicy | FieldReadFunction -}; -export type VoucherCodeCountableEdgeKeySpecifier = ('cursor' | 'node' | VoucherCodeCountableEdgeKeySpecifier)[]; -export type VoucherCodeCountableEdgeFieldPolicy = { - cursor?: FieldPolicy | FieldReadFunction, - node?: FieldPolicy | FieldReadFunction -}; export type VoucherCountableConnectionKeySpecifier = ('edges' | 'pageInfo' | 'totalCount' | VoucherCountableConnectionKeySpecifier)[]; export type VoucherCountableConnectionFieldPolicy = { edges?: FieldPolicy | FieldReadFunction, @@ -9960,26 +9926,6 @@ export type StrictTypedTypePolicies = { keyFields?: false | VoucherChannelListingUpdateKeySpecifier | (() => undefined | VoucherChannelListingUpdateKeySpecifier), fields?: VoucherChannelListingUpdateFieldPolicy, }, - VoucherCode?: Omit & { - keyFields?: false | VoucherCodeKeySpecifier | (() => undefined | VoucherCodeKeySpecifier), - fields?: VoucherCodeFieldPolicy, - }, - VoucherCodeBulkDelete?: Omit & { - keyFields?: false | VoucherCodeBulkDeleteKeySpecifier | (() => undefined | VoucherCodeBulkDeleteKeySpecifier), - fields?: VoucherCodeBulkDeleteFieldPolicy, - }, - VoucherCodeBulkDeleteError?: Omit & { - keyFields?: false | VoucherCodeBulkDeleteErrorKeySpecifier | (() => undefined | VoucherCodeBulkDeleteErrorKeySpecifier), - fields?: VoucherCodeBulkDeleteErrorFieldPolicy, - }, - VoucherCodeCountableConnection?: Omit & { - keyFields?: false | VoucherCodeCountableConnectionKeySpecifier | (() => undefined | VoucherCodeCountableConnectionKeySpecifier), - fields?: VoucherCodeCountableConnectionFieldPolicy, - }, - VoucherCodeCountableEdge?: Omit & { - keyFields?: false | VoucherCodeCountableEdgeKeySpecifier | (() => undefined | VoucherCodeCountableEdgeKeySpecifier), - fields?: VoucherCodeCountableEdgeFieldPolicy, - }, VoucherCountableConnection?: Omit & { keyFields?: false | VoucherCountableConnectionKeySpecifier | (() => undefined | VoucherCountableConnectionKeySpecifier), fields?: VoucherCountableConnectionFieldPolicy, diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 39d9bee7d80..269d323efa1 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -7225,23 +7225,6 @@ export type VoucherChannelListingInput = { removeChannels?: InputMaybe>; }; -/** An enumeration. */ -export enum VoucherCodeBulkDeleteErrorCode { - GRAPHQL_ERROR = 'GRAPHQL_ERROR', - INVALID = 'INVALID', - NOT_FOUND = 'NOT_FOUND' -} - -/** - * Represents voucher code data. - * - * Added in Saleor 3.18. - */ -export type VoucherCodeInput = { - /** Code to use the voucher. */ - code?: InputMaybe; -}; - export enum VoucherDiscountType { FIXED = 'FIXED', PERCENTAGE = 'PERCENTAGE', @@ -7265,14 +7248,8 @@ export type VoucherInput = { applyOncePerOrder?: InputMaybe; /** Categories discounted by the voucher. */ categories?: InputMaybe>; - /** Code to use the voucher.This field will be removed in Saleor 4.0. */ + /** Code to use the voucher. */ code?: InputMaybe; - /** - * Codes to use the voucher. - * - * Added in Saleor 3.18. - */ - codes?: InputMaybe>; /** Collections discounted by the voucher. */ collections?: InputMaybe>; /** Country codes that can be used with the shipping voucher. */ @@ -7289,12 +7266,6 @@ export type VoucherInput = { onlyForStaff?: InputMaybe; /** Products discounted by the voucher. */ products?: InputMaybe>; - /** - * When set to 'True', each voucher is limited to a single use; otherwise, usage remains unrestricted. - * - * Added in Saleor 3.18. - */ - singleUse?: InputMaybe; /** Start date of the voucher in ISO 8601 format. */ startDate?: InputMaybe; /** Voucher type: PRODUCT, CATEGORY SHIPPING or ENTIRE_ORDER. */ @@ -7310,11 +7281,7 @@ export type VoucherInput = { }; export enum VoucherSortField { - /** - * Sort vouchers by code. - * - * DEPRECATED: this field will be removed in Saleor 4.0. - */ + /** Sort vouchers by code. */ CODE = 'CODE', /** Sort vouchers by end date. */ END_DATE = 'END_DATE', @@ -7324,12 +7291,6 @@ export enum VoucherSortField { * This option requires a channel filter to work as the values can vary between channels. */ MINIMUM_SPENT_AMOUNT = 'MINIMUM_SPENT_AMOUNT', - /** - * Sort vouchers by name. - * - * Added in Saleor 3.18. - */ - NAME = 'NAME', /** Sort vouchers by start date. */ START_DATE = 'START_DATE', /** Sort vouchers by type. */ @@ -9453,7 +9414,7 @@ export type VoucherChannelListingUpdateMutationVariables = Exact<{ }>; -export type VoucherChannelListingUpdateMutation = { __typename: 'Mutation', voucherChannelListingUpdate: { __typename: 'VoucherChannelListingUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherChannelListingUpdateMutation = { __typename: 'Mutation', voucherChannelListingUpdate: { __typename: 'VoucherChannelListingUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherUpdateMutationVariables = Exact<{ input: VoucherInput; @@ -9461,7 +9422,7 @@ export type VoucherUpdateMutationVariables = Exact<{ }>; -export type VoucherUpdateMutation = { __typename: 'Mutation', voucherUpdate: { __typename: 'VoucherUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherUpdateMutation = { __typename: 'Mutation', voucherUpdate: { __typename: 'VoucherUpdate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCataloguesAddMutationVariables = Exact<{ input: CatalogueInput; @@ -9476,7 +9437,7 @@ export type VoucherCataloguesAddMutationVariables = Exact<{ }>; -export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesAddMutation = { __typename: 'Mutation', voucherCataloguesAdd: { __typename: 'VoucherAddCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCataloguesRemoveMutationVariables = Exact<{ input: CatalogueInput; @@ -9491,14 +9452,14 @@ export type VoucherCataloguesRemoveMutationVariables = Exact<{ }>; -export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCataloguesRemoveMutation = { __typename: 'Mutation', voucherCataloguesRemove: { __typename: 'VoucherRemoveCatalogues', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', code: string, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherCreateMutationVariables = Exact<{ input: VoucherInput; }>; -export type VoucherCreateMutation = { __typename: 'Mutation', voucherCreate: { __typename: 'VoucherCreate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type VoucherCreateMutation = { __typename: 'Mutation', voucherCreate: { __typename: 'VoucherCreate', errors: Array<{ __typename: 'DiscountError', code: DiscountErrorCode, field: string | null, channels: Array | null, message: string | null }>, voucher: { __typename: 'Voucher', id: string, code: string, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type VoucherDeleteMutationVariables = Exact<{ id: Scalars['ID']; @@ -9538,7 +9499,7 @@ export type VoucherListQueryVariables = Exact<{ }>; -export type VoucherListQuery = { __typename: 'Query', vouchers: { __typename: 'VoucherCountableConnection', edges: Array<{ __typename: 'VoucherCountableEdge', node: { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; +export type VoucherListQuery = { __typename: 'Query', vouchers: { __typename: 'VoucherCountableConnection', edges: Array<{ __typename: 'VoucherCountableEdge', node: { __typename: 'Voucher', id: string, code: string, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null }; export type SaleDetailsQueryVariables = Exact<{ id: Scalars['ID']; @@ -9567,18 +9528,7 @@ export type VoucherDetailsQueryVariables = Exact<{ }>; -export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; - -export type VoucherCodesQueryVariables = Exact<{ - id: Scalars['ID']; - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}>; - - -export type VoucherCodesQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', codes: { __typename: 'VoucherCodeCountableConnection', edges: Array<{ __typename: 'VoucherCodeCountableEdge', node: { __typename: 'VoucherCode', code: string | null, used: number | null, isActive: boolean | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null } | null }; +export type VoucherDetailsQuery = { __typename: 'Query', voucher: { __typename: 'Voucher', code: string, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; export type FileUploadMutationVariables = Exact<{ file: Scalars['Upload']; @@ -9649,11 +9599,9 @@ export type SaleFragment = { __typename: 'Sale', id: string, name: string, type: export type SaleDetailsFragment = { __typename: 'Sale', id: string, name: string, type: SaleType, startDate: any, endDate: any | null, variantsCount: { __typename: 'ProductVariantCountableConnection', totalCount: number | null } | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, variants?: { __typename: 'ProductVariantCountableConnection', edges: Array<{ __typename: 'ProductVariantCountableEdge', node: { __typename: 'ProductVariant', id: string, name: string, product: { __typename: 'Product', id: string, name: string, thumbnail: { __typename: 'Image', url: string } | null, productType: { __typename: 'ProductType', id: string, name: string }, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, channelListings: Array<{ __typename: 'SaleChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; -export type VoucherFragment = { __typename: 'Voucher', id: string, code: string | null, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; - -export type VoucherCodeFragment = { __typename: 'VoucherCode', code: string | null, used: number | null, isActive: boolean | null }; +export type VoucherFragment = { __typename: 'Voucher', id: string, code: string, name: string | null, startDate: any, endDate: any | null, usageLimit: number | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; -export type VoucherDetailsFragment = { __typename: 'Voucher', code: string | null, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, singleUse: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type VoucherDetailsFragment = { __typename: 'Voucher', code: string, usageLimit: number | null, used: number, applyOncePerOrder: boolean, applyOncePerCustomer: boolean, onlyForStaff: boolean, id: string, name: string | null, startDate: any, endDate: any | null, type: VoucherTypeEnum, discountValueType: DiscountValueTypeEnum, minCheckoutItemsQuantity: number | null, productsCount: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, collectionsCount: { __typename: 'CollectionCountableConnection', totalCount: number | null } | null, categoriesCount: { __typename: 'CategoryCountableConnection', totalCount: number | null } | null, products?: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, collections?: { __typename: 'CollectionCountableConnection', edges: Array<{ __typename: 'CollectionCountableEdge', node: { __typename: 'Collection', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, categories?: { __typename: 'CategoryCountableConnection', edges: Array<{ __typename: 'CategoryCountableEdge', node: { __typename: 'Category', id: string, name: string, products: { __typename: 'ProductCountableConnection', totalCount: number | null } | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, countries: Array<{ __typename: 'CountryDisplay', code: string, country: string }> | null, channelListings: Array<{ __typename: 'VoucherChannelListing', id: string, discountValue: number, currency: string, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string }, minSpent: { __typename: 'Money', amount: number, currency: string } | null }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; export type AttributeErrorFragment = { __typename: 'AttributeError', code: AttributeErrorCode, field: string | null, message: string | null }; From e48a20dd0bd076091e9ab34d24300aec35cd078a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 10 Oct 2023 20:52:53 +0200 Subject: [PATCH 64/67] Extract messages --- locale/defaultMessages.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index e24b2cc3460..9eae3bebd73 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -6729,6 +6729,9 @@ "context": "dialog header", "string": "Assign product" }, + "jvKNMP": { + "string": "Discount Code" + }, "jvo0vs": { "string": "Save" }, @@ -7115,6 +7118,10 @@ "context": "Webhook details asynchronous events", "string": "Asynchronous" }, + "mSLr9d": { + "context": "voucher code, button", + "string": "Generate Code" + }, "mTEqYL": { "context": "NoChannels content", "string": "No channels to assign. Please first assign them for the product." From bdd04e8aadb922b4c2e95701a7bbaafe1517f78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 12 Oct 2023 12:48:54 +0200 Subject: [PATCH 65/67] Fix cr comments --- .../components/VoucherCodes/VoucherCodes.tsx | 12 ++-- .../VoucherCodesAddButton.tsx | 4 +- .../VoucherCodesDatagrid.tsx | 9 +-- .../VoucherCodesDatagrid/datagrid.ts | 20 +++++- .../VoucherCodesDeleteDialog.tsx | 70 +++++++++---------- .../VoucherCodesGenerateDialog.tsx | 1 - .../VoucherCreatePage/VoucherCreatePage.tsx | 5 +- .../VoucherLimits/VoucherLimits.tsx | 2 +- .../views/VoucherDetails/VoucherDetails.tsx | 4 +- .../hooks/useVoucherCodes.test.ts | 42 +++++------ .../VoucherDetails/hooks/useVoucherCodes.ts | 19 +++-- .../hooks/useVoucherCodesClient.test.ts | 24 +++---- .../hooks/useVoucherCodesClient.ts | 9 +-- 13 files changed, 116 insertions(+), 105 deletions(-) diff --git a/src/discounts/components/VoucherCodes/VoucherCodes.tsx b/src/discounts/components/VoucherCodes/VoucherCodes.tsx index 498ecc89f99..3ea23218da9 100644 --- a/src/discounts/components/VoucherCodes/VoucherCodes.tsx +++ b/src/discounts/components/VoucherCodes/VoucherCodes.tsx @@ -17,6 +17,7 @@ import { VoucherCodesGenerateDialog, } from "../VoucherCodesGenerateDialog"; import { VoucherCodesManualDialog } from "../VoucherCodesManualDialog"; +import { VoucherCodesUrlDialog } from "./types"; interface VoucherCodesProps extends VoucherCodesDatagridProps { selectedCodesIds: string[]; @@ -38,9 +39,9 @@ export const VoucherCodes = ({ ...datagridProps }: VoucherCodesProps) => { const { pageInfo, ...paginationValues } = voucherCodesPagination; - const [openModal, setOpenModal] = useState< - "single-codes" | "multiple-codes" | "delete-codes" | null - >(null); + const [openModal, setOpenModal] = useState( + null, + ); const closeModal = () => { setOpenModal(null); @@ -90,10 +91,7 @@ export const VoucherCodes = ({ { - closeModal(); - onDeleteCodes(); - }} + onDelete={onDeleteCodes} /> ); diff --git a/src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx b/src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx index 9eadd198756..298585a03a0 100644 --- a/src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx +++ b/src/discounts/components/VoucherCodesAddButton/VoucherCodesAddButton.tsx @@ -1,4 +1,4 @@ -import { SubMenu } from "@dashboard/components/SubMenu"; +import { MenuItem, SubMenu } from "@dashboard/components/SubMenu"; import { ArrowDownIcon, Box, @@ -33,7 +33,7 @@ export const VoucherCodesAddButton = ({ setSubMenuOpen(false); }, []); - const subMenuItems = useMemo( + const subMenuItems = useMemo( () => [ { id: "manual", diff --git a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx index 69933330c20..9200a2e680f 100644 --- a/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx +++ b/src/discounts/components/VoucherCodesDatagrid/VoucherCodesDatagrid.tsx @@ -5,6 +5,7 @@ import { useDatagridChangeState, } from "@dashboard/components/Datagrid/hooks/useDatagridChange"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; +import { UseListSettings } from "@dashboard/hooks/useListSettings"; import { Box } from "@saleor/macaw-ui/next"; import React, { useCallback, useMemo } from "react"; import { useIntl } from "react-intl"; @@ -18,16 +19,16 @@ import { VoucherCode } from "./types"; export interface VoucherCodesDatagridProps { codes: VoucherCode[]; - loading: boolean; + loading?: boolean; disabled?: boolean; onSelectVoucherCodesIds: (rows: number[], clearSelection: () => void) => void; - settings: any; - onSettingsChange: any; + settings: UseListSettings["settings"]; + onSettingsChange: UseListSettings["updateListSettings"]; } export const VoucherCodesDatagrid = ({ codes, - loading, + loading = false, disabled, onSelectVoucherCodesIds, onSettingsChange, diff --git a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts index 0640b87bd31..8a6fc3d27c5 100644 --- a/src/discounts/components/VoucherCodesDatagrid/datagrid.ts +++ b/src/discounts/components/VoucherCodesDatagrid/datagrid.ts @@ -1,6 +1,10 @@ import { PLACEHOLDER } from "@dashboard/components/Datagrid/const"; -import { readonlyTextCell } from "@dashboard/components/Datagrid/customCells/cells"; +import { + readonlyTextCell, + statusCell, +} from "@dashboard/components/Datagrid/customCells/cells"; import { AvailableColumn } from "@dashboard/components/Datagrid/types"; +import { DotStatus } from "@dashboard/components/StatusDot/StatusDot"; import { GridCell, Item } from "@glideapps/glide-data-grid"; import { IntlShape } from "react-intl"; @@ -44,13 +48,23 @@ export const createGetCellContent = false, ); case "status": - return readonlyTextCell(getStatus(rowData?.isActive, intl), false); + return statusCell( + getStatus(rowData?.isActive), + getStatusMessage(rowData?.isActive, intl), + ); default: return readonlyTextCell("", false); } }; -function getStatus(isActive: boolean | undefined, intl: IntlShape) { +function getStatus(isActive: boolean | undefined): DotStatus { + if (isActive === undefined) { + return "warning"; + } + return isActive ? "success" : "error"; +} + +function getStatusMessage(isActive: boolean | undefined, intl: IntlShape) { if (isActive === undefined) { return intl.formatMessage(messages.draft); } diff --git a/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx index e44446d7253..f89e27f9525 100644 --- a/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx +++ b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx @@ -1,8 +1,8 @@ -import { DashboardCard } from "@dashboard/components/Card"; +import { DashboardModal } from "@dashboard/components/Modal"; import { buttonMessages } from "@dashboard/intl"; -import { Box, Button, Modal, Text } from "@saleor/macaw-ui/next"; +import { Button, Text } from "@saleor/macaw-ui/next"; import React from "react"; -import { useIntl } from "react-intl"; +import { FormattedMessage, useIntl } from "react-intl"; interface VoucherCodesDeleteDialogProps { open: boolean; @@ -17,41 +17,35 @@ export const VoucherCodesDeleteDialog = ({ }: VoucherCodesDeleteDialogProps) => { const intl = useIntl(); + const handleSubmit = async () => { + onDelete(); + onClose(); + }; + return ( - - - - - Delete voucher code - - - Are you sure you want to delete this voucher code? - - - - - - - - - - + + + + + + + + + + + + + + + + + ); }; diff --git a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx index 44e31344dba..1376c55e259 100644 --- a/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx +++ b/src/discounts/components/VoucherCodesGenerateDialog/VoucherCodesGenerateDialog.tsx @@ -96,7 +96,6 @@ export const VoucherCodesGenerateDialog = ({ value={data.prefix} onChange={change} /> -