[SALEOR-3965] Extend Sale & Voucher to include Metadata #7653 (#1245)

* Add base logic

* Add missing metadata handlers

* Update changelog

* Cleanup schema

* Add messages
This commit is contained in:
Piotr Grundas 2021-07-29 14:47:22 +02:00 committed by GitHub
parent 6abdc4613a
commit cacf3030a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 1924 additions and 81 deletions

View file

@ -70,6 +70,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Fix list pagination crash on search - #1230 by @orzechdev
- Fix positive float number input validation - #1233 by @orzechdev
- Use MacawUI - #1229 by @dominik-zeglen
- Add Metadata for Sale & Voucher - #7653 by @piotrgrundas
- Add variant create options dialog - #1238 by @orzechdev
# 2.11.1

View file

@ -4839,12 +4839,14 @@ type RequestPasswordReset {
errors: [AccountError!]!
}
type Sale implements Node {
type Sale implements Node & ObjectWithMetadata {
id: ID!
name: String!
type: SaleType!
startDate: DateTime!
endDate: DateTime
privateMetadata: [MetadataItem]!
metadata: [MetadataItem]!
categories(before: String, after: String, first: Int, last: Int): CategoryCountableConnection
collections(before: String, after: String, first: Int, last: Int): CollectionCountableConnection
products(before: String, after: String, first: Int, last: Int): ProductCountableConnection
@ -5757,7 +5759,7 @@ enum VolumeUnitsEnum {
ACRE_FT
}
type Voucher implements Node {
type Voucher implements Node & ObjectWithMetadata {
id: ID!
name: String
type: VoucherTypeEnum!
@ -5771,6 +5773,8 @@ type Voucher implements Node {
onlyForStaff: Boolean!
discountValueType: DiscountValueTypeEnum!
minCheckoutItemsQuantity: Int
privateMetadata: [MetadataItem]!
metadata: [MetadataItem]!
categories(before: String, after: String, first: Int, last: Int): CategoryCountableConnection
collections(before: String, after: String, first: Int, last: Int): CollectionCountableConnection
products(before: String, after: String, first: Int, last: Int): ProductCountableConnection

View file

@ -5,6 +5,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import PageHeader from "@saleor/components/PageHeader";
import Savebar from "@saleor/components/Savebar";
import { createSaleChannelsChangeHandler } from "@saleor/discounts/handlers";
@ -12,6 +13,7 @@ import { DiscountErrorFragment } from "@saleor/fragments/types/DiscountErrorFrag
import { sectionNames } from "@saleor/intl";
import { Backlink } from "@saleor/macaw-ui";
import { validatePrice } from "@saleor/products/utils/validation";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import React from "react";
import { useIntl } from "react-intl";
@ -24,7 +26,7 @@ import SaleInfo from "../SaleInfo";
import SaleType from "../SaleType";
import SaleValue from "../SaleValue";
export interface FormData {
export interface FormData extends MetadataFormData {
channelListings: ChannelSaleData[];
endDate: string;
endTime: string;
@ -60,6 +62,9 @@ const SaleCreatePage: React.FC<SaleCreatePageProps> = ({
onBack
}) => {
const intl = useIntl();
const {
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
const initialForm: FormData = {
channelListings,
@ -70,7 +75,9 @@ const SaleCreatePage: React.FC<SaleCreatePageProps> = ({
startDate: "",
startTime: "",
type: SaleTypeEnum.FIXED,
value: ""
value: "",
metadata: [],
privateMetadata: []
};
return (
<Form initial={initialForm} onSubmit={onSubmit}>
@ -83,6 +90,8 @@ const SaleCreatePage: React.FC<SaleCreatePageProps> = ({
const formDisabled = data.channelListings?.some(channel =>
validatePrice(channel?.discountValue)
);
const changeMetadata = makeMetadataChangeHandler(change);
return (
<Container>
<Backlink onClick={onBack}>
@ -132,6 +141,7 @@ const SaleCreatePage: React.FC<SaleCreatePageProps> = ({
openModal={openChannelsModal}
/>
</div>
<Metadata data={data} onChange={changeMetadata} />
</Grid>
<Savebar
disabled={disabled || formDisabled || !hasChanged}

View file

@ -5,6 +5,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import PageHeader from "@saleor/components/PageHeader";
import Savebar from "@saleor/components/Savebar";
import { Tab, TabContainer } from "@saleor/components/Tab";
@ -13,6 +14,8 @@ import { DiscountErrorFragment } from "@saleor/fragments/types/DiscountErrorFrag
import { sectionNames } from "@saleor/intl";
import { Backlink } from "@saleor/macaw-ui";
import { validatePrice } from "@saleor/products/utils/validation";
import { mapMetadataItemToInput } from "@saleor/utils/maps";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import React from "react";
import { useIntl } from "react-intl";
@ -32,7 +35,7 @@ import SaleSummary from "../SaleSummary";
import SaleType from "../SaleType";
import SaleValue from "../SaleValue";
export interface SaleDetailsPageFormData {
export interface SaleDetailsPageFormData extends MetadataFormData {
channelListings: ChannelSaleData[];
endDate: string;
endTime: string;
@ -127,16 +130,21 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
toggleAll
}) => {
const intl = useIntl();
const {
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
const initialForm: SaleDetailsPageFormData = {
channelListings,
endDate: splitDateTime(maybe(() => sale.endDate, "")).date,
endTime: splitDateTime(maybe(() => sale.endDate, "")).time,
hasEndDate: maybe(() => !!sale.endDate),
name: maybe(() => sale.name, ""),
startDate: splitDateTime(maybe(() => sale.startDate, "")).date,
startTime: splitDateTime(maybe(() => sale.startDate, "")).time,
type: maybe(() => sale.type, SaleTypeEnum.FIXED)
endDate: splitDateTime(sale?.endDate ?? "").date,
endTime: splitDateTime(sale?.endDate ?? "").time,
hasEndDate: !!sale?.endDate,
name: sale?.name ?? "",
startDate: splitDateTime(sale?.startDate ?? "").date,
startTime: splitDateTime(sale?.startDate ?? "").time,
type: sale?.type ?? SaleTypeEnum.FIXED,
metadata: sale?.metadata.map(mapMetadataItemToInput),
privateMetadata: sale?.privateMetadata.map(mapMetadataItemToInput)
};
return (
<Form initial={initialForm} onSubmit={onSubmit}>
@ -149,6 +157,8 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
const formDisabled = data.channelListings?.some(channel =>
validatePrice(channel.discountValue)
);
const changeMetadata = makeMetadataChangeHandler(change);
return (
<Container>
<Backlink onClick={onBack}>
@ -307,6 +317,7 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
openModal={openChannelsModal}
/>
</div>
<Metadata data={data} onChange={changeMetadata} />
</Grid>
<Savebar
disabled={

View file

@ -5,6 +5,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import PageHeader from "@saleor/components/PageHeader";
import Savebar from "@saleor/components/Savebar";
import {
@ -15,6 +16,7 @@ import { DiscountErrorFragment } from "@saleor/fragments/types/DiscountErrorFrag
import { sectionNames } from "@saleor/intl";
import { Backlink } from "@saleor/macaw-ui";
import { validatePrice } from "@saleor/products/utils/validation";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import React from "react";
import { useIntl } from "react-intl";
@ -27,7 +29,7 @@ import VoucherRequirements from "../VoucherRequirements";
import VoucherTypes from "../VoucherTypes";
import VoucherValue from "../VoucherValue";
export interface FormData {
export interface FormData extends MetadataFormData {
applyOncePerCustomer: boolean;
applyOncePerOrder: boolean;
onlyForStaff: boolean;
@ -73,6 +75,9 @@ const VoucherCreatePage: React.FC<VoucherCreatePageProps> = ({
openChannelsModal
}) => {
const intl = useIntl();
const {
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
const initialForm: FormData = {
applyOncePerCustomer: false,
@ -91,7 +96,9 @@ const VoucherCreatePage: React.FC<VoucherCreatePageProps> = ({
startTime: "",
type: VoucherTypeEnum.ENTIRE_ORDER,
usageLimit: "0",
value: 0
value: 0,
metadata: [],
privateMetadata: []
};
return (
@ -113,6 +120,8 @@ const VoucherCreatePage: React.FC<VoucherCreatePageProps> = ({
(data.requirementsPicker === RequirementsPicker.ORDER &&
validatePrice(channel.minSpent))
);
const changeMetadata = makeMetadataChangeHandler(change);
return (
<Container>
<Backlink onClick={onBack}>
@ -189,6 +198,7 @@ const VoucherCreatePage: React.FC<VoucherCreatePageProps> = ({
openModal={openChannelsModal}
/>
</div>
<Metadata data={data} onChange={changeMetadata} />
</Grid>
<Savebar
disabled={

View file

@ -7,6 +7,7 @@ import Container from "@saleor/components/Container";
import CountryList from "@saleor/components/CountryList";
import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import PageHeader from "@saleor/components/PageHeader";
import Savebar from "@saleor/components/Savebar";
import { Tab, TabContainer } from "@saleor/components/Tab";
@ -19,6 +20,8 @@ import { DiscountErrorFragment } from "@saleor/fragments/types/DiscountErrorFrag
import { sectionNames } from "@saleor/intl";
import { Backlink } from "@saleor/macaw-ui";
import { validatePrice } from "@saleor/products/utils/validation";
import { mapMetadataItemToInput } from "@saleor/utils/maps";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@ -55,7 +58,7 @@ export function voucherDetailsPageTab(tab: string): VoucherDetailsPageTab {
: VoucherDetailsPageTab.categories;
}
export interface VoucherDetailsPageFormData {
export interface VoucherDetailsPageFormData extends MetadataFormData {
applyOncePerCustomer: boolean;
applyOncePerOrder: boolean;
onlyForStaff: boolean;
@ -149,6 +152,9 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
productListToolbar
}) => {
const intl = useIntl();
const {
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
const channel = voucher?.channelListings?.find(
listing => listing.channel.id === selectedChannelId
);
@ -175,19 +181,19 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
channelListings,
code: voucher?.code || "",
discountType,
endDate: splitDateTime(maybe(() => voucher.endDate, "")).date,
endTime: splitDateTime(maybe(() => voucher.endDate, "")).time,
hasEndDate: maybe(() => !!voucher.endDate),
hasUsageLimit: maybe(() => !!voucher.usageLimit),
minCheckoutItemsQuantity: maybe(
() => voucher.minCheckoutItemsQuantity.toString(),
"0"
),
endDate: splitDateTime(voucher?.endDate ?? "").date,
endTime: splitDateTime(voucher?.endDate ?? "").time,
hasEndDate: !!voucher?.endDate,
hasUsageLimit: !!voucher?.usageLimit,
minCheckoutItemsQuantity:
voucher?.minCheckoutItemsQuantity?.toString() ?? "0",
requirementsPicker: requirementsPickerInitValue,
startDate: splitDateTime(maybe(() => voucher.startDate, "")).date,
startTime: splitDateTime(maybe(() => voucher.startDate, "")).time,
type: maybe(() => voucher.type, VoucherTypeEnum.ENTIRE_ORDER),
usageLimit: maybe(() => voucher.usageLimit.toString(), "0")
startDate: splitDateTime(voucher?.startDate ?? "").date,
startTime: splitDateTime(voucher?.startDate ?? "").time,
type: voucher?.type ?? VoucherTypeEnum.ENTIRE_ORDER,
usageLimit: voucher?.usageLimit?.toString() ?? "0",
metadata: voucher?.metadata.map(mapMetadataItemToInput),
privateMetadata: voucher?.privateMetadata.map(mapMetadataItemToInput)
};
return (
@ -209,6 +215,8 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
(data.requirementsPicker === RequirementsPicker.ORDER &&
validatePrice(channel.minSpent))
);
const changeMetadata = makeMetadataChangeHandler(change);
return (
<Container>
<Backlink onClick={onBack}>
@ -420,6 +428,7 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
openModal={openChannelsModal}
/>
</div>
<Metadata data={data} onChange={changeMetadata} />
</Grid>
<Savebar
disabled={

View file

@ -13,6 +13,8 @@ import { VoucherList_vouchers_edges_node } from "./types/VoucherList";
export const saleList: SaleList_sales_edges_node[] = [
{
__typename: "Sale" as "Sale",
metadata: [],
privateMetadata: [],
channelListings: [
{
__typename: "SaleChannelListing",
@ -35,6 +37,8 @@ export const saleList: SaleList_sales_edges_node[] = [
},
{
__typename: "Sale" as "Sale",
metadata: [],
privateMetadata: [],
channelListings: [
{
__typename: "SaleChannelListing",
@ -57,6 +61,8 @@ export const saleList: SaleList_sales_edges_node[] = [
},
{
__typename: "Sale" as "Sale",
metadata: [],
privateMetadata: [],
channelListings: [
{
__typename: "SaleChannelListing",
@ -79,6 +85,8 @@ export const saleList: SaleList_sales_edges_node[] = [
},
{
__typename: "Sale" as "Sale",
metadata: [],
privateMetadata: [],
channelListings: [
{
__typename: "SaleChannelListing",
@ -101,6 +109,8 @@ export const saleList: SaleList_sales_edges_node[] = [
},
{
__typename: "Sale" as "Sale",
metadata: [],
privateMetadata: [],
channelListings: [
{
__typename: "SaleChannelListing",
@ -126,6 +136,8 @@ export const saleList: SaleList_sales_edges_node[] = [
export const voucherList: VoucherList_vouchers_edges_node[] = [
{
__typename: "Voucher" as "Voucher",
metadata: [],
privateMetadata: [],
channelListings: [
{
__typename: "VoucherChannelListing",
@ -163,6 +175,8 @@ export const voucherList: VoucherList_vouchers_edges_node[] = [
},
{
__typename: "Voucher" as "Voucher",
metadata: [],
privateMetadata: [],
channelListings: [
{
__typename: "VoucherChannelListing",
@ -196,6 +210,8 @@ export const voucherList: VoucherList_vouchers_edges_node[] = [
export const sale: SaleDetails_sale = {
__typename: "Sale",
metadata: [],
privateMetadata: [],
categories: {
__typename: "CategoryCountableConnection",
edges: [
@ -414,6 +430,8 @@ export const sale: SaleDetails_sale = {
export const voucherDetails: VoucherDetails_voucher = {
__typename: "Voucher",
metadata: [],
privateMetadata: [],
applyOncePerCustomer: false,
applyOncePerOrder: false,
onlyForStaff: false,

View file

@ -16,6 +16,18 @@ export interface SaleCataloguesAdd_saleCataloguesAdd_errors {
channels: string[] | null;
}
export interface SaleCataloguesAdd_saleCataloguesAdd_sale_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleCataloguesAdd_saleCataloguesAdd_sale_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleCataloguesAdd_saleCataloguesAdd_sale_channelListings_channel {
__typename: "Channel";
id: string;
@ -154,6 +166,8 @@ export interface SaleCataloguesAdd_saleCataloguesAdd_sale_collections {
export interface SaleCataloguesAdd_saleCataloguesAdd_sale {
__typename: "Sale";
metadata: (SaleCataloguesAdd_saleCataloguesAdd_sale_metadata | null)[];
privateMetadata: (SaleCataloguesAdd_saleCataloguesAdd_sale_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -16,6 +16,18 @@ export interface SaleCataloguesRemove_saleCataloguesRemove_errors {
channels: string[] | null;
}
export interface SaleCataloguesRemove_saleCataloguesRemove_sale_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleCataloguesRemove_saleCataloguesRemove_sale_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleCataloguesRemove_saleCataloguesRemove_sale_channelListings_channel {
__typename: "Channel";
id: string;
@ -154,6 +166,8 @@ export interface SaleCataloguesRemove_saleCataloguesRemove_sale_collections {
export interface SaleCataloguesRemove_saleCataloguesRemove_sale {
__typename: "Sale";
metadata: (SaleCataloguesRemove_saleCataloguesRemove_sale_metadata | null)[];
privateMetadata: (SaleCataloguesRemove_saleCataloguesRemove_sale_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -16,6 +16,18 @@ export interface SaleChannelListingUpdate_saleChannelListingUpdate_errors {
channels: string[] | null;
}
export interface SaleChannelListingUpdate_saleChannelListingUpdate_sale_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleChannelListingUpdate_saleChannelListingUpdate_sale_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleChannelListingUpdate_saleChannelListingUpdate_sale_channelListings_channel {
__typename: "Channel";
id: string;
@ -33,6 +45,8 @@ export interface SaleChannelListingUpdate_saleChannelListingUpdate_sale_channelL
export interface SaleChannelListingUpdate_saleChannelListingUpdate_sale {
__typename: "Sale";
metadata: (SaleChannelListingUpdate_saleChannelListingUpdate_sale_metadata | null)[];
privateMetadata: (SaleChannelListingUpdate_saleChannelListingUpdate_sale_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -16,6 +16,18 @@ export interface SaleCreate_saleCreate_errors {
channels: string[] | null;
}
export interface SaleCreate_saleCreate_sale_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleCreate_saleCreate_sale_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleCreate_saleCreate_sale_channelListings_channel {
__typename: "Channel";
id: string;
@ -33,6 +45,8 @@ export interface SaleCreate_saleCreate_sale_channelListings {
export interface SaleCreate_saleCreate_sale {
__typename: "Sale";
metadata: (SaleCreate_saleCreate_sale_metadata | null)[];
privateMetadata: (SaleCreate_saleCreate_sale_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -9,6 +9,18 @@ import { SaleType } from "./../../types/globalTypes";
// GraphQL query operation: SaleDetails
// ====================================================
export interface SaleDetails_sale_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleDetails_sale_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleDetails_sale_channelListings_channel {
__typename: "Channel";
id: string;
@ -147,6 +159,8 @@ export interface SaleDetails_sale_collections {
export interface SaleDetails_sale {
__typename: "Sale";
metadata: (SaleDetails_sale_metadata | null)[];
privateMetadata: (SaleDetails_sale_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -9,6 +9,18 @@ import { SaleFilterInput, SaleSortingInput, SaleType } from "./../../types/globa
// GraphQL query operation: SaleList
// ====================================================
export interface SaleList_sales_edges_node_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleList_sales_edges_node_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleList_sales_edges_node_channelListings_channel {
__typename: "Channel";
id: string;
@ -26,6 +38,8 @@ export interface SaleList_sales_edges_node_channelListings {
export interface SaleList_sales_edges_node {
__typename: "Sale";
metadata: (SaleList_sales_edges_node_metadata | null)[];
privateMetadata: (SaleList_sales_edges_node_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -16,6 +16,18 @@ export interface SaleUpdate_saleUpdate_errors {
channels: string[] | null;
}
export interface SaleUpdate_saleUpdate_sale_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleUpdate_saleUpdate_sale_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleUpdate_saleUpdate_sale_channelListings_channel {
__typename: "Channel";
id: string;
@ -33,6 +45,8 @@ export interface SaleUpdate_saleUpdate_sale_channelListings {
export interface SaleUpdate_saleUpdate_sale {
__typename: "Sale";
metadata: (SaleUpdate_saleUpdate_sale_metadata | null)[];
privateMetadata: (SaleUpdate_saleUpdate_sale_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -16,6 +16,18 @@ export interface VoucherCataloguesAdd_voucherCataloguesAdd_errors {
channels: string[] | null;
}
export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher_countries {
__typename: "CountryDisplay";
code: string;
@ -167,6 +179,8 @@ export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher_categories {
export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher {
__typename: "Voucher";
metadata: (VoucherCataloguesAdd_voucherCataloguesAdd_voucher_metadata | null)[];
privateMetadata: (VoucherCataloguesAdd_voucherCataloguesAdd_voucher_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -16,6 +16,18 @@ export interface VoucherCataloguesRemove_voucherCataloguesRemove_errors {
channels: string[] | null;
}
export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher_countries {
__typename: "CountryDisplay";
code: string;
@ -167,6 +179,8 @@ export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher_categor
export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher {
__typename: "Voucher";
metadata: (VoucherCataloguesRemove_voucherCataloguesRemove_voucher_metadata | null)[];
privateMetadata: (VoucherCataloguesRemove_voucherCataloguesRemove_voucher_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -16,6 +16,18 @@ export interface VoucherChannelListingUpdate_voucherChannelListingUpdate_errors
channels: string[] | null;
}
export interface VoucherChannelListingUpdate_voucherChannelListingUpdate_voucher_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherChannelListingUpdate_voucherChannelListingUpdate_voucher_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherChannelListingUpdate_voucherChannelListingUpdate_voucher_countries {
__typename: "CountryDisplay";
code: string;
@ -46,6 +58,8 @@ export interface VoucherChannelListingUpdate_voucherChannelListingUpdate_voucher
export interface VoucherChannelListingUpdate_voucherChannelListingUpdate_voucher {
__typename: "Voucher";
metadata: (VoucherChannelListingUpdate_voucherChannelListingUpdate_voucher_metadata | null)[];
privateMetadata: (VoucherChannelListingUpdate_voucherChannelListingUpdate_voucher_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -16,6 +16,18 @@ export interface VoucherCreate_voucherCreate_errors {
channels: string[] | null;
}
export interface VoucherCreate_voucherCreate_voucher_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherCreate_voucherCreate_voucher_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherCreate_voucherCreate_voucher_countries {
__typename: "CountryDisplay";
code: string;
@ -46,6 +58,8 @@ export interface VoucherCreate_voucherCreate_voucher_channelListings {
export interface VoucherCreate_voucherCreate_voucher {
__typename: "Voucher";
metadata: (VoucherCreate_voucherCreate_voucher_metadata | null)[];
privateMetadata: (VoucherCreate_voucherCreate_voucher_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -9,6 +9,18 @@ import { VoucherTypeEnum, DiscountValueTypeEnum } from "./../../types/globalType
// GraphQL query operation: VoucherDetails
// ====================================================
export interface VoucherDetails_voucher_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherDetails_voucher_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherDetails_voucher_countries {
__typename: "CountryDisplay";
code: string;
@ -160,6 +172,8 @@ export interface VoucherDetails_voucher_categories {
export interface VoucherDetails_voucher {
__typename: "Voucher";
metadata: (VoucherDetails_voucher_metadata | null)[];
privateMetadata: (VoucherDetails_voucher_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -9,6 +9,18 @@ import { VoucherFilterInput, VoucherSortingInput, VoucherTypeEnum, DiscountValue
// GraphQL query operation: VoucherList
// ====================================================
export interface VoucherList_vouchers_edges_node_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherList_vouchers_edges_node_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherList_vouchers_edges_node_countries {
__typename: "CountryDisplay";
code: string;
@ -39,6 +51,8 @@ export interface VoucherList_vouchers_edges_node_channelListings {
export interface VoucherList_vouchers_edges_node {
__typename: "Voucher";
metadata: (VoucherList_vouchers_edges_node_metadata | null)[];
privateMetadata: (VoucherList_vouchers_edges_node_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -16,6 +16,18 @@ export interface VoucherUpdate_voucherUpdate_errors {
channels: string[] | null;
}
export interface VoucherUpdate_voucherUpdate_voucher_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherUpdate_voucherUpdate_voucher_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherUpdate_voucherUpdate_voucher_countries {
__typename: "CountryDisplay";
code: string;
@ -46,6 +58,8 @@ export interface VoucherUpdate_voucherUpdate_voucher_channelListings {
export interface VoucherUpdate_voucherUpdate_voucher {
__typename: "Voucher";
metadata: (VoucherUpdate_voucherUpdate_voucher_metadata | null)[];
privateMetadata: (VoucherUpdate_voucherUpdate_voucher_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -20,6 +20,11 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import { sectionNames } from "@saleor/intl";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
import {
useMetadataUpdate,
usePrivateMetadataUpdate
} from "@saleor/utils/metadata/updateMetadata";
import React from "react";
import { useIntl } from "react-intl";
@ -34,6 +39,8 @@ export const SaleCreateView: React.FC<SaleCreateProps> = ({ params }) => {
const pushMessage = useNotifier();
const intl = useIntl();
const [updateMetadata] = useMetadataUpdate({});
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
const [openModal, closeModal] = createDialogActionHandlers<
ChannelsAction,
SaleCreateUrlQueryParams
@ -92,10 +99,16 @@ export const SaleCreateView: React.FC<SaleCreateProps> = ({ params }) => {
)}
<TypedSaleCreate onCompleted={handleSaleCreate}>
{(saleCreate, saleCreateOpts) => {
const handleSubmit = createHandler(
const handleCreate = createHandler(
variables => saleCreate({ variables }),
updateChannels
);
const handleSubmit = createMetadataCreateHandler(
handleCreate,
updateMetadata,
updatePrivateMetadata
);
return (
<>
<WindowTitle title={intl.formatMessage(sectionNames.sales)} />

View file

@ -39,6 +39,7 @@ export function createHandler(
value: decimal(formData.value)
}
});
if (!response.data.saleCreate.errors.length) {
updateChannels({
variables: getSaleChannelsVariables(
@ -46,6 +47,7 @@ export function createHandler(
formData
)
});
return response.data.saleCreate.sale.id;
}
};
}

View file

@ -50,7 +50,12 @@ import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductSearch from "@saleor/searches/useProductSearch";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
import { mapEdgesToItems } from "@saleor/utils/maps";
import {
useMetadataUpdate,
usePrivateMetadataUpdate
} from "@saleor/utils/metadata/updateMetadata";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@ -62,6 +67,8 @@ interface SaleDetailsProps {
}
export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
const [updateMetadata] = useMetadataUpdate({});
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
const navigate = useNavigator();
const paginate = usePaginator();
const notify = useNotifier();
@ -253,12 +260,19 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
pageInfo
} = paginate(tabPageInfo, paginationState, params);
const handleSubmit = createUpdateHandler(
const handleUpdate = createUpdateHandler(
data?.sale,
saleChannelsChoices,
variables => saleUpdate({ variables }),
updateChannels
);
const handleSubmit = createMetadataUpdateHandler(
data?.sale,
handleUpdate,
variables => updateMetadata({ variables }),
variables => updatePrivateMetadata({ variables })
);
return (
<>
<WindowTitle

View file

@ -30,8 +30,9 @@ export function createUpdateHandler(
variables: SaleChannelListingUpdateVariables;
}) => Promise<MutationFetchResult<SaleChannelListingUpdate>>
) {
return (formData: SaleDetailsPageFormData) => {
return async (formData: SaleDetailsPageFormData) => {
const { id } = sale;
const errors = await Promise.all([
updateSale({
id,
input: {
@ -42,10 +43,13 @@ export function createUpdateHandler(
startDate: joinDateTime(formData.startDate, formData.startTime),
type: discountValueTypeEnum(formData.type)
}
});
}).then(({ data }) => data?.saleUpdate.errors ?? []),
updateChannels({
variables: getSaleChannelsVariables(id, formData, saleChannelsChoices)
});
}).then(({ data }) => data?.saleChannelListingUpdate.errors ?? [])
]);
return errors.flat();
};
}

View file

@ -11,6 +11,11 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import { sectionNames } from "@saleor/intl";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
import {
useMetadataUpdate,
usePrivateMetadataUpdate
} from "@saleor/utils/metadata/updateMetadata";
import React from "react";
import { useIntl } from "react-intl";
@ -37,6 +42,8 @@ export const VoucherCreateView: React.FC<VoucherCreateProps> = ({ params }) => {
const notify = useNotifier();
const intl = useIntl();
const [updateMetadata] = useMetadataUpdate({});
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
const [openModal, closeModal] = createDialogActionHandlers<
ChannelsAction,
VoucherCreateUrlQueryParams
@ -79,10 +86,16 @@ export const VoucherCreateView: React.FC<VoucherCreateProps> = ({ params }) => {
return (
<TypedVoucherCreate onCompleted={handleVoucherCreate}>
{(voucherCreate, voucherCreateOpts) => {
const handleSubmit = createHandler(
const handleCreate = createHandler(
variables => voucherCreate({ variables }),
updateChannels
);
const handleSubmit = createMetadataCreateHandler(
handleCreate,
updateMetadata,
updatePrivateMetadata
);
return (
<>
{!!allChannels?.length && (

View file

@ -63,6 +63,7 @@ export function createHandler(
formData.channelListings
)
});
return response.data.voucherCreate.voucher.id;
}
};
}

View file

@ -47,7 +47,12 @@ import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductSearch from "@saleor/searches/useProductSearch";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
import { mapEdgesToItems } from "@saleor/utils/maps";
import {
useMetadataUpdate,
usePrivateMetadataUpdate
} from "@saleor/utils/metadata/updateMetadata";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@ -95,6 +100,8 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
} = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const [updateMetadata] = useMetadataUpdate({});
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
const paginationState = createPaginationState(PAGINATE_BY, params);
const changeTab = (tab: VoucherDetailsPageTab) => {
@ -218,13 +225,20 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
{(voucherUpdate, voucherUpdateOpts) => (
<TypedVoucherDelete onCompleted={handleVoucherDelete}>
{(voucherDelete, voucherDeleteOpts) => {
const handleSubmit = createUpdateHandler(
const handleUpdate = createUpdateHandler(
data?.voucher,
voucherChannelsChoices,
variables => voucherUpdate({ variables }),
updateChannels
);
const handleSubmit = createMetadataUpdateHandler(
data?.voucher,
handleUpdate,
variables => updateMetadata({ variables }),
variables => updatePrivateMetadata({ variables })
);
const tabPageInfo =
params.activeTab === VoucherDetailsPageTab.categories
? maybe(() => data.voucher.categories.pageInfo)

View file

@ -30,7 +30,9 @@ export function createUpdateHandler(
) {
return async (formData: VoucherDetailsPageFormData) => {
const { id } = voucher;
await updateVoucher({
const errors = await Promise.all([
updateVoucher({
id,
input: {
applyOncePerCustomer: formData.applyOncePerCustomer,
@ -58,10 +60,13 @@ export function createUpdateHandler(
? parseInt(formData.usageLimit, 10)
: null
}
});
}).then(({ data }) => data?.voucherUpdate.errors ?? []),
updateChannels({
variables: getChannelsVariables(id, formData, voucherChannelsChoices)
});
}).then(({ data }) => data?.voucherChannelListingUpdate.errors ?? [])
]);
return errors.flat();
};
}

View file

@ -1,10 +1,13 @@
import { metadataFragment } from "@saleor/fragments/metadata";
import { channelListingProductWithoutPricingFragment } from "@saleor/fragments/products";
import gql from "graphql-tag";
import { pageInfoFragment } from "./pageInfo";
export const saleFragment = gql`
${metadataFragment}
fragment SaleFragment on Sale {
...MetadataFragment
id
name
type
@ -85,7 +88,9 @@ export const saleDetailsFragment = gql`
`;
export const voucherFragment = gql`
${metadataFragment}
fragment VoucherFragment on Voucher {
...MetadataFragment
id
code
startDate

View file

@ -20,7 +20,7 @@ export interface MetadataFragment_privateMetadata {
}
export interface MetadataFragment {
__typename: "App" | "Warehouse" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice";
__typename: "App" | "Warehouse" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "Sale" | "Voucher" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice";
metadata: (MetadataFragment_metadata | null)[];
privateMetadata: (MetadataFragment_privateMetadata | null)[];
}

View file

@ -9,6 +9,18 @@ import { SaleType } from "./../../types/globalTypes";
// GraphQL fragment: SaleDetailsFragment
// ====================================================
export interface SaleDetailsFragment_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleDetailsFragment_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleDetailsFragment_channelListings_channel {
__typename: "Channel";
id: string;
@ -147,6 +159,8 @@ export interface SaleDetailsFragment_collections {
export interface SaleDetailsFragment {
__typename: "Sale";
metadata: (SaleDetailsFragment_metadata | null)[];
privateMetadata: (SaleDetailsFragment_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -9,6 +9,18 @@ import { SaleType } from "./../../types/globalTypes";
// GraphQL fragment: SaleFragment
// ====================================================
export interface SaleFragment_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleFragment_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface SaleFragment_channelListings_channel {
__typename: "Channel";
id: string;
@ -26,6 +38,8 @@ export interface SaleFragment_channelListings {
export interface SaleFragment {
__typename: "Sale";
metadata: (SaleFragment_metadata | null)[];
privateMetadata: (SaleFragment_privateMetadata | null)[];
id: string;
name: string;
type: SaleType;

View file

@ -9,6 +9,18 @@ import { VoucherTypeEnum, DiscountValueTypeEnum } from "./../../types/globalType
// GraphQL fragment: VoucherDetailsFragment
// ====================================================
export interface VoucherDetailsFragment_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherDetailsFragment_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherDetailsFragment_countries {
__typename: "CountryDisplay";
code: string;
@ -160,6 +172,8 @@ export interface VoucherDetailsFragment_categories {
export interface VoucherDetailsFragment {
__typename: "Voucher";
metadata: (VoucherDetailsFragment_metadata | null)[];
privateMetadata: (VoucherDetailsFragment_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

View file

@ -9,6 +9,18 @@ import { VoucherTypeEnum, DiscountValueTypeEnum } from "./../../types/globalType
// GraphQL fragment: VoucherFragment
// ====================================================
export interface VoucherFragment_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherFragment_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}
export interface VoucherFragment_countries {
__typename: "CountryDisplay";
code: string;
@ -39,6 +51,8 @@ export interface VoucherFragment_channelListings {
export interface VoucherFragment {
__typename: "Voucher";
metadata: (VoucherFragment_metadata | null)[];
privateMetadata: (VoucherFragment_privateMetadata | null)[];
id: string;
code: string;
startDate: any;

File diff suppressed because it is too large Load diff

View file

@ -42,6 +42,7 @@ function createMetadataCreateHandler<T extends MetadataFormData>(
return updateMetaErrors;
}
}
if (data.privateMetadata.length > 0) {
const updatePrivateMetaResult = await setPrivateMetadata({
variables: {

View file

@ -60,6 +60,7 @@ function createMetadataUpdateHandler<TData extends MetadataFormData, TError>(
return updateMetaErrors;
}
}
if (data.privateMetadata) {
const privateMetaDiff = diff(
initial.privateMetadata,

View file

@ -39,7 +39,7 @@ export interface UpdateMetadata_deleteMetadata_item_privateMetadata {
}
export interface UpdateMetadata_deleteMetadata_item {
__typename: "App" | "Warehouse" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice";
__typename: "App" | "Warehouse" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "Sale" | "Voucher" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice";
metadata: (UpdateMetadata_deleteMetadata_item_metadata | null)[];
privateMetadata: (UpdateMetadata_deleteMetadata_item_privateMetadata | null)[];
id: string;

View file

@ -39,7 +39,7 @@ export interface UpdatePrivateMetadata_deletePrivateMetadata_item_privateMetadat
}
export interface UpdatePrivateMetadata_deletePrivateMetadata_item {
__typename: "App" | "Warehouse" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice";
__typename: "App" | "Warehouse" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "Sale" | "Voucher" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice";
metadata: (UpdatePrivateMetadata_deletePrivateMetadata_item_metadata | null)[];
privateMetadata: (UpdatePrivateMetadata_deletePrivateMetadata_item_privateMetadata | null)[];
id: string;