diff --git a/.changeset/nice-humans-add.md b/.changeset/nice-humans-add.md new file mode 100644 index 00000000000..4e64ab81436 --- /dev/null +++ b/.changeset/nice-humans-add.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": patch +--- + +Gift card details page and customer details page no longer crash when you have only some required permissions. This means that you can now view gift card details page if you have only gift card permissions and customer details page if you have only customer permissions. diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 86568505590..0e6afd6fc7c 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -2605,6 +2605,10 @@ "FTYkgw": { "string": "Delete collections" }, + "FWaL+x": { + "context": "gift card history message", + "string": "Gift card balance was reset" + }, "FWbv/u": { "context": "page header", "string": "Create Discount" diff --git a/src/components/Timeline/TimelineNote.tsx b/src/components/Timeline/TimelineNote.tsx index 87ac4a9b304..2fc6eb760e2 100644 --- a/src/components/Timeline/TimelineNote.tsx +++ b/src/components/Timeline/TimelineNote.tsx @@ -1,4 +1,4 @@ -import { GiftCardEventFragment, OrderEventFragment } from "@dashboard/graphql"; +import { GiftCardEventsQuery, OrderEventFragment } from "@dashboard/graphql"; import { getUserInitials, getUserName } from "@dashboard/misc"; import { makeStyles } from "@saleor/macaw-ui"; import { Text } from "@saleor/macaw-ui-next"; @@ -31,11 +31,15 @@ const useStyles = makeStyles( { name: "TimelineNote" }, ); +type TimelineAppType = + | NonNullable["events"][0]["app"] + | OrderEventFragment["app"]; + interface TimelineNoteProps { date: string; message: string | null; user: OrderEventFragment["user"]; - app: OrderEventFragment["app"] | GiftCardEventFragment["app"]; + app: TimelineAppType; hasPlainDate?: boolean; } @@ -61,7 +65,7 @@ const TimelineAvatar = ({ className, }: { user: OrderEventFragment["user"]; - app: OrderEventFragment["app"] | GiftCardEventFragment["app"]; + app: TimelineAppType; className: string; }) => { if (user) { diff --git a/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx b/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx index 0eb79f48c20..f136b13c012 100644 --- a/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx +++ b/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx @@ -70,7 +70,9 @@ const CustomerDetailsPage: React.FC = ({ lastName: customer?.lastName || "", metadata: customer?.metadata.map(mapMetadataItemToInput), note: customer?.note || "", - privateMetadata: customer?.privateMetadata.map(mapMetadataItemToInput), + privateMetadata: customer?.privateMetadata + ? customer?.privateMetadata.map(mapMetadataItemToInput) + : [], }; const { makeChangeHandler: makeMetadataChangeHandler } = useMetadataChangeTrigger(); const { CUSTOMER_DETAILS_MORE_ACTIONS } = useExtensions(extensionMountPoints.CUSTOMER_DETAILS); diff --git a/src/customers/queries.ts b/src/customers/queries.ts index 92eb6134eb6..62f9ef14d00 100644 --- a/src/customers/queries.ts +++ b/src/customers/queries.ts @@ -37,9 +37,19 @@ export const customerList = gql` `; export const customerDetails = gql` - query CustomerDetails($id: ID!, $PERMISSION_MANAGE_ORDERS: Boolean!) { + query CustomerDetails( + $id: ID! + $PERMISSION_MANAGE_ORDERS: Boolean! + $PERMISSION_MANAGE_STAFF: Boolean! + ) { user(id: $id) { ...CustomerDetails + metadata { + ...MetadataItem + } + privateMetadata @include(if: $PERMISSION_MANAGE_STAFF) { + ...MetadataItem + } orders(last: 5) @include(if: $PERMISSION_MANAGE_ORDERS) { edges { node { diff --git a/src/customers/views/CustomerDetails.tsx b/src/customers/views/CustomerDetails.tsx index c2cf4cfe53a..3969e41c216 100644 --- a/src/customers/views/CustomerDetails.tsx +++ b/src/customers/views/CustomerDetails.tsx @@ -87,7 +87,10 @@ const CustomerDetailsViewInner: React.FC = ({ id, para ); const handleSubmit = createMetadataUpdateHandler( - user, + { + ...user, + privateMetadata: user?.privateMetadata || [], + }, updateData, variables => updateMetadata({ variables }), variables => updatePrivateMetadata({ variables }), diff --git a/src/fragments/customers.ts b/src/fragments/customers.ts index 4705070b15d..20b2da237ba 100644 --- a/src/fragments/customers.ts +++ b/src/fragments/customers.ts @@ -12,7 +12,6 @@ export const customerFragment = gql` export const customerDetailsFragment = gql` fragment CustomerDetails on User { ...Customer - ...Metadata dateJoined lastLogin defaultShippingAddress { diff --git a/src/fragments/giftCards.ts b/src/fragments/giftCards.ts index becbc4455b3..16ddb10a3a4 100644 --- a/src/fragments/giftCards.ts +++ b/src/fragments/giftCards.ts @@ -17,22 +17,6 @@ export const giftCardEventsFragment = gql` id date type - user { - ...UserBase - email - avatar(size: 128) { - url - } - } - app { - id - name - brand { - logo { - default(size: 128) - } - } - } message email orderId @@ -76,10 +60,6 @@ export const giftCardDataFragment = gql` } usedByEmail createdByEmail - app { - id - name - } created expiryDate lastUsedOn @@ -90,7 +70,6 @@ export const giftCardDataFragment = gql` currentBalance { ...Money } - id tags { name diff --git a/src/giftCards/GiftCardUpdate/GiftCardHistory/GiftCardTimelineEvent.tsx b/src/giftCards/GiftCardUpdate/GiftCardHistory/GiftCardTimelineEvent.tsx index 91ad1124e8d..9f1debf023c 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardHistory/GiftCardTimelineEvent.tsx +++ b/src/giftCards/GiftCardUpdate/GiftCardHistory/GiftCardTimelineEvent.tsx @@ -3,7 +3,7 @@ import { AppPaths } from "@dashboard/apps/urls"; import Link from "@dashboard/components/Link"; import { TimelineEvent } from "@dashboard/components/Timeline"; import { customerPath } from "@dashboard/customers/urls"; -import { GiftCardEventFragment, GiftCardEventsEnum } from "@dashboard/graphql"; +import { GiftCardEventsEnum, GiftCardEventsQuery } from "@dashboard/graphql"; import { orderUrl } from "@dashboard/orders/urls"; import { staffMemberDetailsUrl } from "@dashboard/staff/urls"; import React from "react"; @@ -11,7 +11,9 @@ import { IntlShape, useIntl } from "react-intl"; import { giftCardHistoryTimelineMessages as timelineMessages } from "./messages"; -const getUserOrApp = (event: GiftCardEventFragment): string | null => { +type GiftCardEventType = GiftCardEventsQuery["giftCard"]["events"][0]; + +const getUserOrApp = (event: GiftCardEventType): string | null => { if (event.user) { const { firstName, lastName, email } = event.user; @@ -28,7 +30,7 @@ const getUserOrApp = (event: GiftCardEventFragment): string | null => { return null; }; -const getUserOrAppUrl = (event: GiftCardEventFragment): string => { +const getUserOrAppUrl = (event: GiftCardEventType): string => { if (event.user) { return staffMemberDetailsUrl(event.user.id); } @@ -39,7 +41,7 @@ const getUserOrAppUrl = (event: GiftCardEventFragment): string => { return null; }; -const getEventMessage = (event: GiftCardEventFragment, intl: IntlShape) => { +const getEventMessage = (event: GiftCardEventType, intl: IntlShape) => { const user = getUserOrApp(event); const userUrl = getUserOrAppUrl(event); @@ -107,7 +109,7 @@ const getEventMessage = (event: GiftCardEventFragment, intl: IntlShape) => { export interface GiftCardTimelineEventProps { date: string; - event: GiftCardEventFragment; + event: GiftCardEventType; } const GiftCardTimelineEvent: React.FC = ({ date, event }) => { diff --git a/src/giftCards/GiftCardUpdate/GiftCardHistory/hooks/useGiftCardHistoryEvents.test.tsx b/src/giftCards/GiftCardUpdate/GiftCardHistory/hooks/useGiftCardHistoryEvents.test.tsx new file mode 100644 index 00000000000..d4a44b85883 --- /dev/null +++ b/src/giftCards/GiftCardUpdate/GiftCardHistory/hooks/useGiftCardHistoryEvents.test.tsx @@ -0,0 +1,114 @@ +import { renderHook } from "@testing-library/react-hooks"; +import React from "react"; + +import { giftCardsMocks } from "../../../../../testUtils/mocks/giftCards"; +import { useUser } from "../../../../auth"; +import { useGiftCardEventsQuery } from "../../../../graphql"; +import { GiftCardDetailsContext } from "../../providers/GiftCardDetailsProvider"; +import useGiftCardHistoryEvents from "./useGiftCardHistoryEvents"; + +// Mock the dependencies +jest.mock("@dashboard/auth"); +jest.mock("@dashboard/graphql"); + +const mockUseUser = useUser as jest.Mock; +const mockUseGiftCardEventsQuery = useGiftCardEventsQuery as jest.Mock; + +const mockGiftCard = { + ...giftCardsMocks[0], + id: "giftCardId", +}; +const mockUser = { + userPermissions: [{ code: "MANAGE_USERS" }, { code: "MANAGE_APPS" }], +}; + +mockUseUser.mockReturnValue({ user: mockUser }); + +describe("useGiftCardHistoryEvents", () => { + it("should return gift card events", () => { + // Arrange + mockUseGiftCardEventsQuery.mockImplementation(() => ({ + data: { + giftCard: { + events: [ + { id: "event1", app: {}, user: {} }, + { id: "event2", app: {}, user: {} }, + ], + }, + }, + })); + + const wrapper = ({ children }: { children: React.ReactNode }) => ( + + {children} + + ); + + // Act + const { result } = renderHook(() => useGiftCardHistoryEvents(), { wrapper }); + + // Assert + expect(result.current.id).toBe("giftCardId"); + expect(result.current.events).toEqual([ + { id: "event1", app: {}, user: {} }, + { id: "event2", app: {}, user: {} }, + ]); + expect(mockUseGiftCardEventsQuery).toBeCalledWith({ + variables: { id: "giftCardId", canSeeApp: true, canSeeUser: true }, + skip: false, + }); + }); + + it("should return undefined when there is no gift card", () => { + // Arrange + mockUseGiftCardEventsQuery.mockImplementation(() => ({ + data: undefined, + })); + + const wrapper = ({ children }: { children: React.ReactNode }) => ( + + {children} + + ); + + // Act + const { result } = renderHook(() => useGiftCardHistoryEvents(), { wrapper }); + + // Assert + expect(result.current.id).toBeUndefined(); + expect(result.current.events).toBeUndefined(); + expect(mockUseGiftCardEventsQuery).toBeCalledWith({ + variables: undefined, + skip: true, + }); + }); + + it("should not return app and user when user does not have permissions", () => { + // Arrange + mockUseUser.mockReturnValue({ user: { userPermissions: [] } }); + mockUseGiftCardEventsQuery.mockImplementation(() => ({ + data: { + giftCard: { + events: [{ id: "event1" }, { id: "event2" }], + }, + }, + })); + + const wrapper = ({ children }: { children: React.ReactNode }) => ( + + {children} + + ); + + // Act + const { result } = renderHook(() => useGiftCardHistoryEvents(), { wrapper }); + + // Assert + expect(result.current.id).toBe("giftCardId"); + expect(result.current.events).toEqual([{ id: "event1" }, { id: "event2" }]); + expect(mockUseGiftCardEventsQuery).toBeCalledWith({ + variables: { id: "giftCardId", canSeeApp: false, canSeeUser: false }, + skip: false, + }); + }); +}); diff --git a/src/giftCards/GiftCardUpdate/GiftCardHistory/hooks/useGiftCardHistoryEvents.ts b/src/giftCards/GiftCardUpdate/GiftCardHistory/hooks/useGiftCardHistoryEvents.ts index 99448be82e7..a41cc75fd03 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardHistory/hooks/useGiftCardHistoryEvents.ts +++ b/src/giftCards/GiftCardUpdate/GiftCardHistory/hooks/useGiftCardHistoryEvents.ts @@ -1,13 +1,32 @@ +import { useGiftCardPermissions } from "@dashboard/giftCards/hooks/useGiftCardPermissions"; +import { GiftCardEventsQuery, useGiftCardEventsQuery } from "@dashboard/graphql"; import { useContext } from "react"; import { GiftCardDetailsContext } from "../../providers/GiftCardDetailsProvider"; -const useGiftCardHistoryEvents = () => { +interface GiftCardHistoryEvents { + id: string | undefined; + events: NonNullable["events"] | null | undefined; +} + +const useGiftCardHistoryEvents = (): GiftCardHistoryEvents => { + const { canSeeApp, canSeeUser } = useGiftCardPermissions(); + const { giftCard } = useContext(GiftCardDetailsContext); + const { data } = useGiftCardEventsQuery({ + variables: giftCard + ? { + canSeeApp, + canSeeUser, + id: giftCard.id, + } + : undefined, + skip: !giftCard?.id, + }); return { id: giftCard?.id, - events: giftCard?.events, + events: data?.giftCard?.events, }; }; diff --git a/src/giftCards/GiftCardUpdate/GiftCardHistory/messages.ts b/src/giftCards/GiftCardUpdate/GiftCardHistory/messages.ts index 6f19f9c2c54..ec153eb01e8 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardHistory/messages.ts +++ b/src/giftCards/GiftCardUpdate/GiftCardHistory/messages.ts @@ -34,8 +34,8 @@ const giftCardHistoryTimelineMessages = defineMessages({ description: "gift card history message", }, balanceResetAnonymous: { - id: "aEc9Ar", - defaultMessage: "Gift card balance was reset by {resetBy}", + id: "FWaL+x", + defaultMessage: "Gift card balance was reset", description: "gift card history message", }, bought: { diff --git a/src/giftCards/GiftCardUpdate/GiftCardHistory/queries.ts b/src/giftCards/GiftCardUpdate/GiftCardHistory/queries.ts new file mode 100644 index 00000000000..1e97c059d6c --- /dev/null +++ b/src/giftCards/GiftCardUpdate/GiftCardHistory/queries.ts @@ -0,0 +1,27 @@ +import { gql } from "@apollo/client"; + +export const giftCardEvents = gql` + query GiftCardEvents($id: ID!, $canSeeApp: Boolean!, $canSeeUser: Boolean!) { + giftCard(id: $id) { + events { + ...GiftCardEvent + app @include(if: $canSeeApp) { + id + name + brand { + logo { + default(size: 128) + } + } + } + user @include(if: $canSeeUser) { + ...UserBase + email + avatar(size: 128) { + url + } + } + } + } + } +`; diff --git a/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx b/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx index a839098aca0..ea7cb8ee5e8 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx +++ b/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx @@ -4,6 +4,7 @@ import { useChannelsSearch } from "@dashboard/components/ChannelsAvailabilityDia import { Combobox } from "@dashboard/components/Combobox"; import ControlledCheckbox from "@dashboard/components/ControlledCheckbox"; import { IMessage } from "@dashboard/components/messages"; +import { useGiftCardPermissions } from "@dashboard/giftCards/hooks/useGiftCardPermissions"; import { useChannelsQuery, useGiftCardResendMutation } from "@dashboard/graphql"; import useForm from "@dashboard/hooks/useForm"; import useNotifier from "@dashboard/hooks/useNotifier"; @@ -36,8 +37,11 @@ const GiftCardResendCodeDialog: React.FC = ({ open, onClose }) => { const { giftCard: { boughtInChannel: initialChannelSlug }, } = useGiftCardDetails(); + const { canManageChannels } = useGiftCardPermissions(); const [consentSelected, setConsentSelected] = useState(false); - const { data: channelsData, loading: loadingChannels } = useChannelsQuery({}); + const { data: channelsData, loading: loadingChannels } = useChannelsQuery({ + skip: !canManageChannels, + }); const channels = channelsData?.channels; const activeChannels = channels?.filter(({ isActive }) => isActive); const { onQueryChange, filteredChannels } = useChannelsSearch(activeChannels); @@ -118,7 +122,7 @@ const GiftCardResendCodeDialog: React.FC = ({ open, onClose }) => { fetchOptions={onQueryChange} name="channelSlug" value={{ - label: channels.find(getBySlug(data?.channelSlug))?.name, + label: channels?.find(getBySlug(data?.channelSlug))?.name, value: data?.channelSlug, }} onChange={change} diff --git a/src/giftCards/GiftCardUpdate/GiftCardUpdateBalanceDialog/GiftCardUpdateBalanceDialog.tsx b/src/giftCards/GiftCardUpdate/GiftCardUpdateBalanceDialog/GiftCardUpdateBalanceDialog.tsx index 2eaccb624ec..2386f2c9788 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardUpdateBalanceDialog/GiftCardUpdateBalanceDialog.tsx +++ b/src/giftCards/GiftCardUpdate/GiftCardUpdateBalanceDialog/GiftCardUpdateBalanceDialog.tsx @@ -2,6 +2,7 @@ import ActionDialog from "@dashboard/components/ActionDialog"; import CardSpacer from "@dashboard/components/CardSpacer"; import { IMessage } from "@dashboard/components/messages"; +import { useGiftCardPermissions } from "@dashboard/giftCards/hooks/useGiftCardPermissions"; import { useGiftCardUpdateMutation } from "@dashboard/graphql"; import useForm from "@dashboard/hooks/useForm"; import useNotifier from "@dashboard/hooks/useNotifier"; @@ -27,6 +28,7 @@ const GiftCardUpdateBalanceDialog: React.FC = ({ open, onClose }) = const intl = useIntl(); const classes = useStyles({}); const notify = useNotifier(); + const { canSeeCreatedBy } = useGiftCardPermissions(); const { giftCard: { id, @@ -63,6 +65,7 @@ const GiftCardUpdateBalanceDialog: React.FC = ({ open, onClose }) = input: { balanceAmount, }, + showCreatedBy: canSeeCreatedBy, }, }); diff --git a/src/giftCards/GiftCardUpdate/GiftCardUpdateInfoCard/GiftCardUpdateInfoCardContent.tsx b/src/giftCards/GiftCardUpdate/GiftCardUpdateInfoCard/GiftCardUpdateInfoCardContent.tsx index 1039db92b72..14c2aa59492 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardUpdateInfoCard/GiftCardUpdateInfoCardContent.tsx +++ b/src/giftCards/GiftCardUpdate/GiftCardUpdateInfoCard/GiftCardUpdateInfoCardContent.tsx @@ -15,6 +15,7 @@ import { Text } from "@saleor/macaw-ui-next"; import React from "react"; import { MessageDescriptor, useIntl } from "react-intl"; +import useGiftCardHistoryEvents from "../GiftCardHistory/hooks/useGiftCardHistoryEvents"; import useGiftCardDetails from "../providers/GiftCardDetailsProvider/hooks/useGiftCardDetails"; import { PLACEHOLDER } from "../types"; import { giftCardUpdateInfoCardMessages as messages } from "./messages"; @@ -23,9 +24,12 @@ const GiftCardUpdateInfoCardContent: React.FC = () => { const intl = useIntl(); const localizeDate = useDateLocalize(); const { giftCard } = useGiftCardDetails(); - const { created, createdByEmail, createdBy, usedByEmail, usedBy, product, events } = giftCard; - const cardIssuedEvent = events.find(getByType(GiftCardEventsEnum.ISSUED)); - const cardBoughtEvent = events.find(getByType(GiftCardEventsEnum.BOUGHT)); + const { created, createdByEmail, createdBy, usedByEmail, usedBy, product } = giftCard; + + const { events } = useGiftCardHistoryEvents(); + const cardIssuedEvent = events?.find(getByType(GiftCardEventsEnum.ISSUED)); + const cardBoughtEvent = events?.find(getByType(GiftCardEventsEnum.BOUGHT)); + const getBuyerFieldData = (): { label: MessageDescriptor; name: string; diff --git a/src/giftCards/GiftCardUpdate/GiftCardUpdatePageHeader/GiftCardUpdatePageHeader.tsx b/src/giftCards/GiftCardUpdate/GiftCardUpdatePageHeader/GiftCardUpdatePageHeader.tsx index d9610ccd2fa..5f337f1da46 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardUpdatePageHeader/GiftCardUpdatePageHeader.tsx +++ b/src/giftCards/GiftCardUpdate/GiftCardUpdatePageHeader/GiftCardUpdatePageHeader.tsx @@ -2,6 +2,7 @@ import { TopNav } from "@dashboard/components/AppLayout/TopNav"; import { Button } from "@dashboard/components/Button"; import HorizontalSpacer from "@dashboard/components/HorizontalSpacer"; import GiftCardStatusChip from "@dashboard/giftCards/components/GiftCardStatusChip/GiftCardStatusChip"; +import { useGiftCardPermissions } from "@dashboard/giftCards/hooks/useGiftCardPermissions"; import { giftCardsListPath } from "@dashboard/giftCards/urls"; import { getStringOrPlaceholder } from "@dashboard/misc"; import React from "react"; @@ -17,6 +18,7 @@ import useStyles from "./styles"; const GiftCardUpdatePageHeader: React.FC = () => { const classes = useStyles(); const intl = useIntl(); + const { canManageChannels } = useGiftCardPermissions(); const { giftCard } = useGiftCardDetails(); const { openResendCodeDialog } = useGiftCardUpdateDialogs(); @@ -29,6 +31,8 @@ const GiftCardUpdatePageHeader: React.FC = () => { last4CodeChars, }); + const canResendCode = !isExpired && canManageChannels; + return ( <> { > - {!isExpired && ( + {canResendCode && ( diff --git a/src/giftCards/GiftCardUpdate/mutations.ts b/src/giftCards/GiftCardUpdate/mutations.ts index 907a5557a62..bd461dda5e4 100644 --- a/src/giftCards/GiftCardUpdate/mutations.ts +++ b/src/giftCards/GiftCardUpdate/mutations.ts @@ -1,13 +1,16 @@ import { gql } from "@apollo/client"; export const giftCardUpdate = gql` - mutation GiftCardUpdate($id: ID!, $input: GiftCardUpdateInput!) { + mutation GiftCardUpdate($id: ID!, $input: GiftCardUpdateInput!, $showCreatedBy: Boolean!) { giftCardUpdate(id: $id, input: $input) { errors { ...GiftCardError } giftCard { ...GiftCardData + createdBy @include(if: $showCreatedBy) { + ...UserBase + } events { ...GiftCardEvent } diff --git a/src/giftCards/GiftCardUpdate/providers/GiftCardUpdateFormProvider/GiftCardUpdateFormProvider.tsx b/src/giftCards/GiftCardUpdate/providers/GiftCardUpdateFormProvider/GiftCardUpdateFormProvider.tsx index fa2c1852df5..ec0b724247c 100644 --- a/src/giftCards/GiftCardUpdate/providers/GiftCardUpdateFormProvider/GiftCardUpdateFormProvider.tsx +++ b/src/giftCards/GiftCardUpdate/providers/GiftCardUpdateFormProvider/GiftCardUpdateFormProvider.tsx @@ -1,6 +1,7 @@ // @ts-strict-ignore import { MetadataFormData } from "@dashboard/components/Metadata"; import { giftCardUpdateFormMessages } from "@dashboard/giftCards/GiftCardsList/messages"; +import { useGiftCardPermissions } from "@dashboard/giftCards/hooks/useGiftCardPermissions"; import { GiftCardErrorFragment, GiftCardUpdateMutation, @@ -61,6 +62,7 @@ const getGiftCardTagsAddRemoveData = (initTags: string[], changedTags: string[]) const GiftCardUpdateFormProvider: React.FC = ({ children }) => { const notify = useNotifier(); const intl = useIntl(); + const { canSeeCreatedBy } = useGiftCardPermissions(); const [updateMetadata] = useUpdateMetadataMutation({}); const [updatePrivateMetadata] = useUpdatePrivateMetadataMutation({}); const { loading: loadingGiftCard, giftCard } = useGiftCardDetails(); @@ -105,6 +107,7 @@ const GiftCardUpdateFormProvider: React.FC = ({ tags.map(el => el.value), ), }, + showCreatedBy: canSeeCreatedBy, }, }); diff --git a/src/giftCards/GiftCardUpdate/queries.ts b/src/giftCards/GiftCardUpdate/queries.ts index a3c8f64645e..6c6af4bbb6c 100644 --- a/src/giftCards/GiftCardUpdate/queries.ts +++ b/src/giftCards/GiftCardUpdate/queries.ts @@ -6,9 +6,6 @@ export const giftCardDetails = gql` query GiftCardDetails($id: ID!) { giftCard(id: $id) { ...GiftCardData - events { - ...GiftCardEvent - } } } `; diff --git a/src/giftCards/hooks/useGiftCardPermissions.ts b/src/giftCards/hooks/useGiftCardPermissions.ts new file mode 100644 index 00000000000..2a40e38a39c --- /dev/null +++ b/src/giftCards/hooks/useGiftCardPermissions.ts @@ -0,0 +1,31 @@ +import { useUserPermissions } from "@dashboard/auth/hooks/useUserPermissions"; +import { hasOneOfPermissions } from "@dashboard/components/RequirePermissions"; +import { PermissionEnum } from "@dashboard/graphql"; + +interface GiftCardPermissions { + canManageChannels: boolean; + canSeeCreatedBy: boolean; + canSeeUser: boolean; + canSeeApp: boolean; +} + +export const useGiftCardPermissions = (): GiftCardPermissions => { + const userPermissions = useUserPermissions(); + + const canManageChannels = hasOneOfPermissions(userPermissions ?? [], [ + PermissionEnum.MANAGE_CHANNELS, + ]); + const canSeeCreatedBy = hasOneOfPermissions(userPermissions ?? [], [PermissionEnum.MANAGE_USERS]); + const canSeeUser = hasOneOfPermissions(userPermissions ?? [], [ + PermissionEnum.MANAGE_USERS, + PermissionEnum.MANAGE_STAFF, + ]); + const canSeeApp = hasOneOfPermissions(userPermissions ?? [], [PermissionEnum.MANAGE_APPS]); + + return { + canManageChannels, + canSeeCreatedBy, + canSeeUser, + canSeeApp, + }; +}; diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index d19fc81fcfc..3012e634d82 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -367,7 +367,6 @@ export const AddressFragmentDoc = gql` export const CustomerDetailsFragmentDoc = gql` fragment CustomerDetails on User { ...Customer - ...Metadata dateJoined lastLogin defaultShippingAddress { @@ -380,7 +379,6 @@ export const CustomerDetailsFragmentDoc = gql` isActive } ${CustomerFragmentDoc} -${MetadataFragmentDoc} ${AddressFragmentDoc}`; export const CustomerAddressesFragmentDoc = gql` fragment CustomerAddresses on User { @@ -1273,13 +1271,6 @@ export const GiftCardsSettingsFragmentDoc = gql` } } `; -export const UserBaseFragmentDoc = gql` - fragment UserBase on User { - id - firstName - lastName -} - `; export const MoneyFragmentDoc = gql` fragment Money on Money { amount @@ -1293,22 +1284,6 @@ export const GiftCardEventFragmentDoc = gql` id date type - user { - ...UserBase - email - avatar(size: 128) { - url - } - } - app { - id - name - brand { - logo { - default(size: 128) - } - } - } message email orderId @@ -1330,8 +1305,14 @@ export const GiftCardEventFragmentDoc = gql` } } } - ${UserBaseFragmentDoc} -${MoneyFragmentDoc}`; + ${MoneyFragmentDoc}`; +export const UserBaseFragmentDoc = gql` + fragment UserBase on User { + id + firstName + lastName +} + `; export const GiftCardDataFragmentDoc = gql` fragment GiftCardData on GiftCard { ...Metadata @@ -1352,10 +1333,6 @@ export const GiftCardDataFragmentDoc = gql` } usedByEmail createdByEmail - app { - id - name - } created expiryDate lastUsedOn @@ -7250,9 +7227,15 @@ export type ListCustomersQueryHookResult = ReturnType; export type ListCustomersQueryResult = Apollo.QueryResult; export const CustomerDetailsDocument = gql` - query CustomerDetails($id: ID!, $PERMISSION_MANAGE_ORDERS: Boolean!) { + query CustomerDetails($id: ID!, $PERMISSION_MANAGE_ORDERS: Boolean!, $PERMISSION_MANAGE_STAFF: Boolean!) { user(id: $id) { ...CustomerDetails + metadata { + ...MetadataItem + } + privateMetadata @include(if: $PERMISSION_MANAGE_STAFF) { + ...MetadataItem + } orders(last: 5) @include(if: $PERMISSION_MANAGE_ORDERS) { edges { node { @@ -7279,7 +7262,8 @@ export const CustomerDetailsDocument = gql` } } } - ${CustomerDetailsFragmentDoc}`; + ${CustomerDetailsFragmentDoc} +${MetadataItemFragmentDoc}`; /** * __useCustomerDetailsQuery__ @@ -7295,6 +7279,7 @@ export const CustomerDetailsDocument = gql` * variables: { * id: // value for 'id' * PERMISSION_MANAGE_ORDERS: // value for 'PERMISSION_MANAGE_ORDERS' + * PERMISSION_MANAGE_STAFF: // value for 'PERMISSION_MANAGE_STAFF' * }, * }); */ @@ -8974,6 +8959,62 @@ export function useGiftCardSettingsLazyQuery(baseOptions?: ApolloReactHooks.Lazy export type GiftCardSettingsQueryHookResult = ReturnType; export type GiftCardSettingsLazyQueryHookResult = ReturnType; export type GiftCardSettingsQueryResult = Apollo.QueryResult; +export const GiftCardEventsDocument = gql` + query GiftCardEvents($id: ID!, $canSeeApp: Boolean!, $canSeeUser: Boolean!) { + giftCard(id: $id) { + events { + ...GiftCardEvent + app @include(if: $canSeeApp) { + id + name + brand { + logo { + default(size: 128) + } + } + } + user @include(if: $canSeeUser) { + ...UserBase + email + avatar(size: 128) { + url + } + } + } + } +} + ${GiftCardEventFragmentDoc} +${UserBaseFragmentDoc}`; + +/** + * __useGiftCardEventsQuery__ + * + * To run a query within a React component, call `useGiftCardEventsQuery` and pass it any options that fit your needs. + * When your component renders, `useGiftCardEventsQuery` 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 } = useGiftCardEventsQuery({ + * variables: { + * id: // value for 'id' + * canSeeApp: // value for 'canSeeApp' + * canSeeUser: // value for 'canSeeUser' + * }, + * }); + */ +export function useGiftCardEventsQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useQuery(GiftCardEventsDocument, options); + } +export function useGiftCardEventsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useLazyQuery(GiftCardEventsDocument, options); + } +export type GiftCardEventsQueryHookResult = ReturnType; +export type GiftCardEventsLazyQueryHookResult = ReturnType; +export type GiftCardEventsQueryResult = Apollo.QueryResult; export const GiftCardResendDocument = gql` mutation GiftCardResend($input: GiftCardResendInput!) { giftCardResend(input: $input) { @@ -9092,13 +9133,16 @@ export type GiftCardDeactivateMutationHookResult = ReturnType; export type GiftCardDeactivateMutationOptions = Apollo.BaseMutationOptions; export const GiftCardUpdateDocument = gql` - mutation GiftCardUpdate($id: ID!, $input: GiftCardUpdateInput!) { + mutation GiftCardUpdate($id: ID!, $input: GiftCardUpdateInput!, $showCreatedBy: Boolean!) { giftCardUpdate(id: $id, input: $input) { errors { ...GiftCardError } giftCard { ...GiftCardData + createdBy @include(if: $showCreatedBy) { + ...UserBase + } events { ...GiftCardEvent } @@ -9107,6 +9151,7 @@ export const GiftCardUpdateDocument = gql` } ${GiftCardErrorFragmentDoc} ${GiftCardDataFragmentDoc} +${UserBaseFragmentDoc} ${GiftCardEventFragmentDoc}`; export type GiftCardUpdateMutationFn = Apollo.MutationFunction; @@ -9125,6 +9170,7 @@ export type GiftCardUpdateMutationFn = Apollo.MutationFunction; -export type UpdateCustomerMutation = { __typename: 'Mutation', customerUpdate: { __typename: 'CustomerUpdate', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }>, user: { __typename: 'User', dateJoined: any, lastLogin: any | null, note: string | null, isActive: boolean, id: string, email: string, firstName: string, lastName: string, defaultShippingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, defaultBillingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type UpdateCustomerMutation = { __typename: 'Mutation', customerUpdate: { __typename: 'CustomerUpdate', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }>, user: { __typename: 'User', dateJoined: any, lastLogin: any | null, note: string | null, isActive: boolean, id: string, email: string, firstName: string, lastName: string, defaultShippingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, defaultBillingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null } | null } | null }; export type CreateCustomerMutationVariables = Exact<{ input: UserCreateInput; @@ -9621,10 +9621,11 @@ export type ListCustomersQuery = { __typename: 'Query', customers: { __typename: export type CustomerDetailsQueryVariables = Exact<{ id: Scalars['ID']; PERMISSION_MANAGE_ORDERS: Scalars['Boolean']; + PERMISSION_MANAGE_STAFF: Scalars['Boolean']; }>; -export type CustomerDetailsQuery = { __typename: 'Query', user: { __typename: 'User', dateJoined: any, lastLogin: any | null, note: string | null, isActive: boolean, id: string, email: string, firstName: string, lastName: string, orders?: { __typename: 'OrderCountableConnection', edges: Array<{ __typename: 'OrderCountableEdge', node: { __typename: 'Order', id: string, created: any, number: string, paymentStatus: PaymentChargeStatusEnum, total: { __typename: 'TaxedMoney', gross: { __typename: 'Money', currency: string, amount: number } } } }> } | null, lastPlacedOrder: { __typename: 'OrderCountableConnection', edges: Array<{ __typename: 'OrderCountableEdge', node: { __typename: 'Order', id: string, created: any } }> } | null, defaultShippingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, defaultBillingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; +export type CustomerDetailsQuery = { __typename: 'Query', user: { __typename: 'User', dateJoined: any, lastLogin: any | null, note: string | null, isActive: boolean, id: string, email: string, firstName: string, lastName: string, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata?: Array<{ __typename: 'MetadataItem', key: string, value: string }>, orders?: { __typename: 'OrderCountableConnection', edges: Array<{ __typename: 'OrderCountableEdge', node: { __typename: 'Order', id: string, created: any, number: string, paymentStatus: PaymentChargeStatusEnum, total: { __typename: 'TaxedMoney', gross: { __typename: 'Money', currency: string, amount: number } } } }> } | null, lastPlacedOrder: { __typename: 'OrderCountableConnection', edges: Array<{ __typename: 'OrderCountableEdge', node: { __typename: 'Order', id: string, created: any } }> } | null, defaultShippingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, defaultBillingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null } | null }; export type CustomerAddressesQueryVariables = Exact<{ id: Scalars['ID']; @@ -9991,7 +9992,7 @@ export type CollectionProductFragment = { __typename: 'Product', id: string, nam export type CustomerFragment = { __typename: 'User', id: string, email: string, firstName: string, lastName: string }; -export type CustomerDetailsFragment = { __typename: 'User', dateJoined: any, lastLogin: any | null, note: string | null, isActive: boolean, id: string, email: string, firstName: string, lastName: string, defaultShippingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, defaultBillingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type CustomerDetailsFragment = { __typename: 'User', dateJoined: any, lastLogin: any | null, note: string | null, isActive: boolean, id: string, email: string, firstName: string, lastName: string, defaultShippingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null, defaultBillingAddress: { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } } | null }; export type CustomerAddressesFragment = { __typename: 'User', id: string, email: string, firstName: string, lastName: string, addresses: Array<{ __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } }>, defaultBillingAddress: { __typename: 'Address', id: string } | null, defaultShippingAddress: { __typename: 'Address', id: string } | null }; @@ -10169,9 +10170,9 @@ export type FileFragment = { __typename: 'File', url: string, contentType: strin export type GiftCardsSettingsFragment = { __typename: 'GiftCardSettings', expiryType: GiftCardSettingsExpiryTypeEnum, expiryPeriod: { __typename: 'TimePeriod', type: TimePeriodTypeEnum, amount: number } | null }; -export type GiftCardEventFragment = { __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, user: { __typename: 'User', email: string, id: string, firstName: string, lastName: string, avatar: { __typename: 'Image', url: string } | null } | null, app: { __typename: 'App', id: string, name: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null } | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null }; +export type GiftCardEventFragment = { __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null }; -export type GiftCardDataFragment = { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, app: { __typename: 'App', id: string, name: string | null } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; +export type GiftCardDataFragment = { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> }; export type CustomerGiftCardFragment = { __typename: 'GiftCard', id: string, last4CodeChars: string, expiryDate: any | null, isActive: boolean, currentBalance: { __typename: 'Money', amount: number, currency: string } }; @@ -10501,34 +10502,44 @@ export type GiftCardSettingsQueryVariables = Exact<{ [key: string]: never; }>; export type GiftCardSettingsQuery = { __typename: 'Query', giftCardSettings: { __typename: 'GiftCardSettings', expiryType: GiftCardSettingsExpiryTypeEnum, expiryPeriod: { __typename: 'TimePeriod', type: TimePeriodTypeEnum, amount: number } | null } }; +export type GiftCardEventsQueryVariables = Exact<{ + id: Scalars['ID']; + canSeeApp: Scalars['Boolean']; + canSeeUser: Scalars['Boolean']; +}>; + + +export type GiftCardEventsQuery = { __typename: 'Query', giftCard: { __typename: 'GiftCard', events: Array<{ __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, app?: { __typename: 'App', id: string, name: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null } | null, user?: { __typename: 'User', email: string, id: string, firstName: string, lastName: string, avatar: { __typename: 'Image', url: string } | null } | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null }> } | null }; + export type GiftCardResendMutationVariables = Exact<{ input: GiftCardResendInput; }>; -export type GiftCardResendMutation = { __typename: 'Mutation', giftCardResend: { __typename: 'GiftCardResend', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, app: { __typename: 'App', id: string, name: string | null } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type GiftCardResendMutation = { __typename: 'Mutation', giftCardResend: { __typename: 'GiftCardResend', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type GiftCardActivateMutationVariables = Exact<{ id: Scalars['ID']; }>; -export type GiftCardActivateMutation = { __typename: 'Mutation', giftCardActivate: { __typename: 'GiftCardActivate', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, app: { __typename: 'App', id: string, name: string | null } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type GiftCardActivateMutation = { __typename: 'Mutation', giftCardActivate: { __typename: 'GiftCardActivate', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type GiftCardDeactivateMutationVariables = Exact<{ id: Scalars['ID']; }>; -export type GiftCardDeactivateMutation = { __typename: 'Mutation', giftCardDeactivate: { __typename: 'GiftCardDeactivate', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, app: { __typename: 'App', id: string, name: string | null } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type GiftCardDeactivateMutation = { __typename: 'Mutation', giftCardDeactivate: { __typename: 'GiftCardDeactivate', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type GiftCardUpdateMutationVariables = Exact<{ id: Scalars['ID']; input: GiftCardUpdateInput; + showCreatedBy: Scalars['Boolean']; }>; -export type GiftCardUpdateMutation = { __typename: 'Mutation', giftCardUpdate: { __typename: 'GiftCardUpdate', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, events: Array<{ __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, user: { __typename: 'User', email: string, id: string, firstName: string, lastName: string, avatar: { __typename: 'Image', url: string } | null } | null, app: { __typename: 'App', id: string, name: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null } | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null }>, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, app: { __typename: 'App', id: string, name: string | null } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; +export type GiftCardUpdateMutation = { __typename: 'Mutation', giftCardUpdate: { __typename: 'GiftCardUpdate', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy?: { __typename: 'User', id: string, firstName: string, lastName: string } | null, events: Array<{ __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null }>, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null } | null }; export type GiftCardAddNoteMutationVariables = Exact<{ id: Scalars['ID']; @@ -10536,7 +10547,7 @@ export type GiftCardAddNoteMutationVariables = Exact<{ }>; -export type GiftCardAddNoteMutation = { __typename: 'Mutation', giftCardAddNote: { __typename: 'GiftCardAddNote', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, app: { __typename: 'App', id: string, name: string | null } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null, event: { __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, user: { __typename: 'User', email: string, id: string, firstName: string, lastName: string, avatar: { __typename: 'Image', url: string } | null } | null, app: { __typename: 'App', id: string, name: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null } | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null } | null } | null }; +export type GiftCardAddNoteMutation = { __typename: 'Mutation', giftCardAddNote: { __typename: 'GiftCardAddNote', errors: Array<{ __typename: 'GiftCardError', code: GiftCardErrorCode, field: string | null, message: string | null }>, giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null, event: { __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null } | null } | null }; export type GiftCardBulkActivateMutationVariables = Exact<{ ids: Array | Scalars['ID']; @@ -10557,7 +10568,7 @@ export type GiftCardDetailsQueryVariables = Exact<{ }>; -export type GiftCardDetailsQuery = { __typename: 'Query', giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, events: Array<{ __typename: 'GiftCardEvent', expiryDate: any | null, oldExpiryDate: any | null, id: string, date: any | null, type: GiftCardEventsEnum | null, message: string | null, email: string | null, orderId: string | null, orderNumber: string | null, tags: Array | null, oldTags: Array | null, user: { __typename: 'User', email: string, id: string, firstName: string, lastName: string, avatar: { __typename: 'Image', url: string } | null } | null, app: { __typename: 'App', id: string, name: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null } | null, balance: { __typename: 'GiftCardEventBalance', initialBalance: { __typename: 'Money', amount: number, currency: string } | null, currentBalance: { __typename: 'Money', amount: number, currency: string }, oldInitialBalance: { __typename: 'Money', amount: number, currency: string } | null, oldCurrentBalance: { __typename: 'Money', amount: number, currency: string } | null } | null }>, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, app: { __typename: 'App', id: string, name: string | null } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; +export type GiftCardDetailsQuery = { __typename: 'Query', giftCard: { __typename: 'GiftCard', last4CodeChars: string, boughtInChannel: string | null, usedByEmail: string | null, createdByEmail: string | null, created: any, expiryDate: any | null, lastUsedOn: any | null, isActive: boolean, id: string, createdBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, product: { __typename: 'Product', id: string, name: string } | null, usedBy: { __typename: 'User', id: string, firstName: string, lastName: string } | null, initialBalance: { __typename: 'Money', amount: number, currency: string }, currentBalance: { __typename: 'Money', amount: number, currency: string }, tags: Array<{ __typename: 'GiftCardTag', name: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null }; export type GiftCardCurrenciesQueryVariables = Exact<{ [key: string]: never; }>; diff --git a/testUtils/mocks/giftCards.ts b/testUtils/mocks/giftCards.ts new file mode 100644 index 00000000000..8ac7a0e3352 --- /dev/null +++ b/testUtils/mocks/giftCards.ts @@ -0,0 +1,57 @@ +import { ExtendedGiftCard } from "../../src/giftCards/GiftCardUpdate/providers/GiftCardDetailsProvider/types"; +import { GiftCardDetailsQuery } from "../../src/graphql"; + +export const giftCardsMocks: ExtendedGiftCard>[] = [ + { + __typename: "GiftCard", + isExpired: false, + last4CodeChars: "1234", + boughtInChannel: "online", + usedByEmail: "user@example.com", + createdByEmail: "creator@example.com", + created: new Date().toISOString(), + expiryDate: new Date(new Date().setFullYear(new Date().getFullYear() + 1)).toISOString(), + lastUsedOn: new Date().toISOString(), + isActive: true, + id: "giftCardId123", + createdBy: { + __typename: "User", + id: "userId123", + firstName: "John", + lastName: "Doe", + }, + product: { + __typename: "Product", + id: "productId123", + name: "Product Name", + }, + usedBy: { + __typename: "User", + id: "userId456", + firstName: "Jane", + lastName: "Smith", + }, + initialBalance: { + __typename: "Money", + amount: 100, + currency: "USD", + }, + currentBalance: { + __typename: "Money", + amount: 50, + currency: "USD", + }, + tags: [ + { __typename: "GiftCardTag", name: "Birthday" }, + { __typename: "GiftCardTag", name: "Anniversary" }, + ], + metadata: [ + { __typename: "MetadataItem", key: "key1", value: "value1" }, + { __typename: "MetadataItem", key: "key2", value: "value2" }, + ], + privateMetadata: [ + { __typename: "MetadataItem", key: "privateKey1", value: "privateValue1" }, + { __typename: "MetadataItem", key: "privateKey2", value: "privateValue2" }, + ], + }, +];