Support staff only voucher (#1174)
* Support staff only voucher * Trigger CI * Update messages * Update changelog
This commit is contained in:
parent
a0dce99b5d
commit
4056ac395b
18 changed files with 264 additions and 29 deletions
|
@ -51,6 +51,7 @@ All notable, unreleased changes to this project will be documented in this file.
|
|||
- Paginate attribute values in filters - #1152 by @orzechdev
|
||||
- Fix attribute values input display - #1156 by @orzechdev
|
||||
- Fix product type translations - #1163 by @orzechdev
|
||||
- Support staff only voucher - #1174 by @orzechdev
|
||||
|
||||
# 2.11.1
|
||||
|
||||
|
|
|
@ -3019,21 +3019,26 @@
|
|||
"context": "voucher code, button",
|
||||
"string": "Generate Code"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_2215544659": {
|
||||
"string": "Limit number of times this discount can be used in total"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_3459612469": {
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_applyOncePerCustomer": {
|
||||
"context": "limit voucher",
|
||||
"string": "Limit to one use per customer"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_3751756157": {
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_hasUsageLimit": {
|
||||
"context": "limit voucher",
|
||||
"string": "Limit number of times this discount can be used in total"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_onlyForStaff": {
|
||||
"context": "limit voucher",
|
||||
"string": "Limit to staff only"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_usageLimit": {
|
||||
"context": "limit voucher",
|
||||
"string": "Limit of Uses"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_usageLimitsTitle": {
|
||||
"context": "voucher usage limit, header",
|
||||
"string": "Usage Limit"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherLimits_dot_557552777": {
|
||||
"context": "voucher",
|
||||
"string": "Limit of Uses"
|
||||
},
|
||||
"src_dot_discounts_dot_components_dot_VoucherListPage_dot_1112241061": {
|
||||
"context": "tab name",
|
||||
"string": "All Vouchers"
|
||||
|
|
|
@ -1914,6 +1914,7 @@ type ExportError {
|
|||
}
|
||||
|
||||
enum ExportErrorCode {
|
||||
GRAPHQL_ERROR
|
||||
INVALID
|
||||
NOT_FOUND
|
||||
REQUIRED
|
||||
|
@ -4106,7 +4107,7 @@ type Product implements Node & ObjectWithMetadata {
|
|||
taxType: TaxType
|
||||
attributes: [SelectedAttribute!]!
|
||||
channelListings: [ProductChannelListing!]
|
||||
mediaById(id: ID): ProductMedia!
|
||||
mediaById(id: ID): ProductMedia
|
||||
imageById(id: ID): ProductImage @deprecated(reason: "Will be removed in Saleor 4.0. Use the `mediaById` field instead.")
|
||||
variants: [ProductVariant]
|
||||
media: [ProductMedia!]
|
||||
|
@ -5757,6 +5758,7 @@ type Voucher implements Node {
|
|||
endDate: DateTime
|
||||
applyOncePerOrder: Boolean!
|
||||
applyOncePerCustomer: Boolean!
|
||||
onlyForStaff: Boolean!
|
||||
discountValueType: DiscountValueTypeEnum!
|
||||
minCheckoutItemsQuantity: Int
|
||||
categories(before: String, after: String, first: Int, last: Int): CategoryCountableConnection
|
||||
|
@ -5858,6 +5860,7 @@ input VoucherInput {
|
|||
countries: [String]
|
||||
applyOncePerOrder: Boolean
|
||||
applyOncePerCustomer: Boolean
|
||||
onlyForStaff: Boolean
|
||||
usageLimit: Int
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import VoucherValue from "../VoucherValue";
|
|||
export interface FormData {
|
||||
applyOncePerCustomer: boolean;
|
||||
applyOncePerOrder: boolean;
|
||||
onlyForStaff: boolean;
|
||||
channelListings: ChannelVoucherData[];
|
||||
code: string;
|
||||
discountType: DiscountTypeEnum;
|
||||
|
@ -76,6 +77,7 @@ const VoucherCreatePage: React.FC<VoucherCreatePageProps> = ({
|
|||
const initialForm: FormData = {
|
||||
applyOncePerCustomer: false,
|
||||
applyOncePerOrder: false,
|
||||
onlyForStaff: false,
|
||||
channelListings,
|
||||
code: "",
|
||||
discountType: DiscountTypeEnum.VALUE_FIXED,
|
||||
|
|
|
@ -58,6 +58,7 @@ export function voucherDetailsPageTab(tab: string): VoucherDetailsPageTab {
|
|||
export interface VoucherDetailsPageFormData {
|
||||
applyOncePerCustomer: boolean;
|
||||
applyOncePerOrder: boolean;
|
||||
onlyForStaff: boolean;
|
||||
channelListings: ChannelVoucherData[];
|
||||
code: string;
|
||||
discountType: DiscountTypeEnum;
|
||||
|
@ -170,6 +171,7 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
|
|||
const initialForm: VoucherDetailsPageFormData = {
|
||||
applyOncePerCustomer: voucher?.applyOncePerCustomer || false,
|
||||
applyOncePerOrder: voucher?.applyOncePerOrder || false,
|
||||
onlyForStaff: voucher?.onlyForStaff || false,
|
||||
channelListings,
|
||||
code: voucher?.code || "",
|
||||
discountType,
|
||||
|
|
|
@ -8,6 +8,7 @@ import React from "react";
|
|||
import { useIntl } from "react-intl";
|
||||
|
||||
import { VoucherDetailsPageFormData } from "../VoucherDetailsPage";
|
||||
import messages from "./messages";
|
||||
|
||||
interface VoucherLimitsProps {
|
||||
data: VoucherDetailsPageFormData;
|
||||
|
@ -28,19 +29,11 @@ const VoucherLimits = ({
|
|||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Usage Limit",
|
||||
description: "voucher usage limit, header"
|
||||
})}
|
||||
/>
|
||||
<CardTitle title={intl.formatMessage(messages.usageLimitsTitle)} />
|
||||
<CardContent>
|
||||
<ControlledCheckbox
|
||||
checked={data.hasUsageLimit}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage:
|
||||
"Limit number of times this discount can be used in total"
|
||||
})}
|
||||
label={intl.formatMessage(messages.hasUsageLimit)}
|
||||
name={"hasUsageLimit" as keyof VoucherDetailsPageFormData}
|
||||
onChange={onChange}
|
||||
/>
|
||||
|
@ -49,10 +42,7 @@ const VoucherLimits = ({
|
|||
disabled={disabled}
|
||||
error={!!formErrors.usageLimit}
|
||||
helperText={getDiscountErrorMessage(formErrors.usageLimit, intl)}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Limit of Uses",
|
||||
description: "voucher"
|
||||
})}
|
||||
label={intl.formatMessage(messages.usageLimit)}
|
||||
name={"usageLimit" as keyof VoucherDetailsPageFormData}
|
||||
value={data.usageLimit}
|
||||
onChange={onChange}
|
||||
|
@ -65,13 +55,16 @@ const VoucherLimits = ({
|
|||
)}
|
||||
<ControlledCheckbox
|
||||
checked={data.applyOncePerCustomer}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Limit to one use per customer",
|
||||
description: "limit voucher"
|
||||
})}
|
||||
label={intl.formatMessage(messages.applyOncePerCustomer)}
|
||||
name={"applyOncePerCustomer" as keyof VoucherDetailsPageFormData}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<ControlledCheckbox
|
||||
checked={data.onlyForStaff}
|
||||
label={intl.formatMessage(messages.onlyForStaff)}
|
||||
name={"onlyForStaff" as keyof VoucherDetailsPageFormData}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
|
24
src/discounts/components/VoucherLimits/messages.ts
Normal file
24
src/discounts/components/VoucherLimits/messages.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export default defineMessages({
|
||||
usageLimitsTitle: {
|
||||
defaultMessage: "Usage Limit",
|
||||
description: "voucher usage limit, header"
|
||||
},
|
||||
hasUsageLimit: {
|
||||
defaultMessage: "Limit number of times this discount can be used in total",
|
||||
description: "limit voucher"
|
||||
},
|
||||
usageLimit: {
|
||||
defaultMessage: "Limit of Uses",
|
||||
description: "limit voucher"
|
||||
},
|
||||
applyOncePerCustomer: {
|
||||
defaultMessage: "Limit to one use per customer",
|
||||
description: "limit voucher"
|
||||
},
|
||||
onlyForStaff: {
|
||||
defaultMessage: "Limit to staff only",
|
||||
description: "limit voucher"
|
||||
}
|
||||
});
|
|
@ -416,6 +416,7 @@ export const voucherDetails: VoucherDetails_voucher = {
|
|||
__typename: "Voucher",
|
||||
applyOncePerCustomer: false,
|
||||
applyOncePerOrder: false,
|
||||
onlyForStaff: false,
|
||||
categories: {
|
||||
__typename: "CategoryCountableConnection",
|
||||
edges: [],
|
||||
|
|
|
@ -180,6 +180,7 @@ export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher {
|
|||
used: number;
|
||||
applyOncePerOrder: boolean;
|
||||
applyOncePerCustomer: boolean;
|
||||
onlyForStaff: boolean;
|
||||
products: VoucherCataloguesAdd_voucherCataloguesAdd_voucher_products | null;
|
||||
collections: VoucherCataloguesAdd_voucherCataloguesAdd_voucher_collections | null;
|
||||
categories: VoucherCataloguesAdd_voucherCataloguesAdd_voucher_categories | null;
|
||||
|
|
|
@ -180,6 +180,7 @@ export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher {
|
|||
used: number;
|
||||
applyOncePerOrder: boolean;
|
||||
applyOncePerCustomer: boolean;
|
||||
onlyForStaff: boolean;
|
||||
products: VoucherCataloguesRemove_voucherCataloguesRemove_voucher_products | null;
|
||||
collections: VoucherCataloguesRemove_voucherCataloguesRemove_voucher_collections | null;
|
||||
categories: VoucherCataloguesRemove_voucherCataloguesRemove_voucher_categories | null;
|
||||
|
|
|
@ -173,6 +173,7 @@ export interface VoucherDetails_voucher {
|
|||
used: number;
|
||||
applyOncePerOrder: boolean;
|
||||
applyOncePerCustomer: boolean;
|
||||
onlyForStaff: boolean;
|
||||
products: VoucherDetails_voucher_products | null;
|
||||
collections: VoucherDetails_voucher_collections | null;
|
||||
categories: VoucherDetails_voucher_categories | null;
|
||||
|
|
|
@ -29,6 +29,7 @@ export function createHandler(
|
|||
input: {
|
||||
applyOncePerCustomer: formData.applyOncePerCustomer,
|
||||
applyOncePerOrder: formData.applyOncePerOrder,
|
||||
onlyForStaff: formData.onlyForStaff,
|
||||
code: formData.code,
|
||||
discountValueType:
|
||||
formData.discountType === DiscountTypeEnum.VALUE_PERCENTAGE
|
||||
|
|
|
@ -35,6 +35,7 @@ export function createUpdateHandler(
|
|||
input: {
|
||||
applyOncePerCustomer: formData.applyOncePerCustomer,
|
||||
applyOncePerOrder: formData.applyOncePerOrder,
|
||||
onlyForStaff: formData.onlyForStaff,
|
||||
discountValueType:
|
||||
formData.discountType === DiscountTypeEnum.VALUE_PERCENTAGE
|
||||
? DiscountValueTypeEnum.PERCENTAGE
|
||||
|
|
|
@ -126,6 +126,7 @@ export const voucherDetailsFragment = gql`
|
|||
used
|
||||
applyOncePerOrder
|
||||
applyOncePerCustomer
|
||||
onlyForStaff
|
||||
products(after: $after, before: $before, first: $first, last: $last) {
|
||||
edges {
|
||||
node {
|
||||
|
|
|
@ -173,6 +173,7 @@ export interface VoucherDetailsFragment {
|
|||
used: number;
|
||||
applyOncePerOrder: boolean;
|
||||
applyOncePerCustomer: boolean;
|
||||
onlyForStaff: boolean;
|
||||
products: VoucherDetailsFragment_products | null;
|
||||
collections: VoucherDetailsFragment_collections | null;
|
||||
categories: VoucherDetailsFragment_categories | null;
|
||||
|
|
|
@ -31,7 +31,7 @@ export interface ProductMediaById_product {
|
|||
__typename: "Product";
|
||||
id: string;
|
||||
name: string;
|
||||
mainImage: ProductMediaById_product_mainImage;
|
||||
mainImage: ProductMediaById_product_mainImage | null;
|
||||
media: ProductMediaById_product_media[] | null;
|
||||
}
|
||||
|
||||
|
|
|
@ -95798,6 +95798,45 @@ exports[`Storyshots Views / Discounts / Voucher create default 1`] = `
|
|||
Limit to one use per customer
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="MuiFormControlLabel-root-id"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id MuiIconButton-colorPrimary-id"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-id"
|
||||
data-indeterminate="false"
|
||||
name="onlyForStaff"
|
||||
type="checkbox"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<rect
|
||||
fill="none"
|
||||
height="14"
|
||||
stroke="currentColor"
|
||||
width="14"
|
||||
x="5"
|
||||
y="5"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
Limit to staff only
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -97225,6 +97264,45 @@ exports[`Storyshots Views / Discounts / Voucher create form errors 1`] = `
|
|||
Limit to one use per customer
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="MuiFormControlLabel-root-id"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id MuiIconButton-colorPrimary-id"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-id"
|
||||
data-indeterminate="false"
|
||||
name="onlyForStaff"
|
||||
type="checkbox"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<rect
|
||||
fill="none"
|
||||
height="14"
|
||||
stroke="currentColor"
|
||||
width="14"
|
||||
x="5"
|
||||
y="5"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
Limit to staff only
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -99285,6 +99363,45 @@ exports[`Storyshots Views / Discounts / Voucher details default 1`] = `
|
|||
Limit to one use per customer
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="MuiFormControlLabel-root-id"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id MuiIconButton-colorPrimary-id"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-id"
|
||||
data-indeterminate="false"
|
||||
name="onlyForStaff"
|
||||
type="checkbox"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<rect
|
||||
fill="none"
|
||||
height="14"
|
||||
stroke="currentColor"
|
||||
width="14"
|
||||
x="5"
|
||||
y="5"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
Limit to staff only
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -101495,6 +101612,45 @@ exports[`Storyshots Views / Discounts / Voucher details form errors 1`] = `
|
|||
Limit to one use per customer
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="MuiFormControlLabel-root-id"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id MuiIconButton-colorPrimary-id"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-id"
|
||||
data-indeterminate="false"
|
||||
name="onlyForStaff"
|
||||
type="checkbox"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<rect
|
||||
fill="none"
|
||||
height="14"
|
||||
stroke="currentColor"
|
||||
width="14"
|
||||
x="5"
|
||||
y="5"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
Limit to staff only
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -103268,6 +103424,45 @@ exports[`Storyshots Views / Discounts / Voucher details loading 1`] = `
|
|||
Limit to one use per customer
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="MuiFormControlLabel-root-id"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id MuiIconButton-colorPrimary-id"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-id"
|
||||
data-indeterminate="false"
|
||||
name="onlyForStaff"
|
||||
type="checkbox"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<rect
|
||||
fill="none"
|
||||
height="14"
|
||||
stroke="currentColor"
|
||||
width="14"
|
||||
x="5"
|
||||
y="5"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
Limit to staff only
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -440,6 +440,7 @@ export enum DiscountValueTypeEnum {
|
|||
}
|
||||
|
||||
export enum ExportErrorCode {
|
||||
GRAPHQL_ERROR = "GRAPHQL_ERROR",
|
||||
INVALID = "INVALID",
|
||||
NOT_FOUND = "NOT_FOUND",
|
||||
REQUIRED = "REQUIRED",
|
||||
|
@ -1978,6 +1979,7 @@ export interface VoucherInput {
|
|||
countries?: (string | null)[] | null;
|
||||
applyOncePerOrder?: boolean | null;
|
||||
applyOncePerCustomer?: boolean | null;
|
||||
onlyForStaff?: boolean | null;
|
||||
usageLimit?: number | null;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue