Attach metadata to the fulfillments within the orders (#3667)
* Metadata for fulfillment * Metadata for fulfillment * Trigger deploy * Fix removing priv metadata * Remove blinks * tests for adding, deleteing and updating public and prvate metadata for fullfilled orders (#3684) --------- Co-authored-by: wojteknowacki <124166231+wojteknowacki@users.noreply.github.com> Co-authored-by: wojteknowacki <wojciech.nowacki@saleor.io>
This commit is contained in:
parent
ed8b75a9b3
commit
730c96db88
21 changed files with 693 additions and 143 deletions
|
@ -9,41 +9,43 @@ import {
|
|||
ORDERS_SELECTORS,
|
||||
SHARED_ELEMENTS,
|
||||
} from "../../elements/";
|
||||
import { MESSAGES } from "../../fixtures";
|
||||
import { urlList } from "../../fixtures/urlList";
|
||||
import { ONE_PERMISSION_USERS } from "../../fixtures/users";
|
||||
import { MESSAGES, ONE_PERMISSION_USERS, urlList } from "../../fixtures";
|
||||
import {
|
||||
createCustomer,
|
||||
deleteCustomersStartsWith,
|
||||
} from "../../support/api/requests/Customer";
|
||||
import {
|
||||
getOrder,
|
||||
updateMetadata,
|
||||
updateOrdersSettings,
|
||||
} from "../../support/api/requests/Order";
|
||||
import { getDefaultChannel } from "../../support/api/utils/channelsUtils";
|
||||
updatePrivateMetadata,
|
||||
} from "../../support/api/requests/";
|
||||
import {
|
||||
createFulfilledOrder,
|
||||
createOrder,
|
||||
createReadyToFulfillOrder,
|
||||
createUnconfirmedOrder,
|
||||
} from "../../support/api/utils/ordersUtils";
|
||||
import * as productsUtils from "../../support/api/utils/products/productsUtils";
|
||||
import {
|
||||
createShipping,
|
||||
createUnconfirmedOrder,
|
||||
deleteShippingStartsWith,
|
||||
} from "../../support/api/utils/shippingUtils";
|
||||
import {
|
||||
getDefaultChannel,
|
||||
getDefaultTaxClass,
|
||||
productsUtils,
|
||||
updateTaxConfigurationForChannel,
|
||||
} from "../../support/api/utils/taxesUtils";
|
||||
import { selectChannelInPicker } from "../../support/pages/channelsPage";
|
||||
import { finalizeDraftOrder } from "../../support/pages/draftOrderPage";
|
||||
} from "../../support/api/utils/";
|
||||
import {
|
||||
addNewProductToOrder,
|
||||
addPrivateMetadataFieldFulfillmentOrder,
|
||||
addPublicMetadataFieldFulfillmentOrder,
|
||||
applyFixedLineDiscountForProduct,
|
||||
changeQuantityOfProducts,
|
||||
deletePrivateFulfillmentMetadata,
|
||||
deleteProductFromGridTableOnIndex,
|
||||
} from "../../support/pages/ordersOperations";
|
||||
deletePublicFulfillmentMetadata,
|
||||
expandPrivateFulfillmentMetadata,
|
||||
expandPublicFulfillmentMetadata,
|
||||
finalizeDraftOrder,
|
||||
selectChannelInPicker,
|
||||
updatePrivateMetadataFieldFulfillmentOrder,
|
||||
updatePublicMetadataFieldFulfillmentOrder,
|
||||
} from "../../support/pages/";
|
||||
|
||||
describe("Orders", () => {
|
||||
const startsWith = "CyOrders-";
|
||||
|
@ -59,6 +61,16 @@ describe("Orders", () => {
|
|||
|
||||
const shippingPrice = 2;
|
||||
const variantPrice = 1;
|
||||
const metadataName = randomName + "- metadata name";
|
||||
const metadataValue = randomName + "- metadata value";
|
||||
const privateMetadataName = randomName + "- private metadata name";
|
||||
const privateMetadataValue = randomName + "- private metadata value";
|
||||
const updatedMetadataName = metadataName + "- updated metadata name";
|
||||
const updatedMetadataValue = metadataValue + "- updated metadata value";
|
||||
const updatedPrivateMetadataName =
|
||||
privateMetadataName + "- updated private metadata name";
|
||||
const updatedPrivateMetadataValue =
|
||||
privateMetadataValue + "- updated private metadata value";
|
||||
|
||||
before(() => {
|
||||
cy.clearSessionData().loginUserViaRequest();
|
||||
|
@ -335,4 +347,181 @@ describe("Orders", () => {
|
|||
});
|
||||
},
|
||||
);
|
||||
|
||||
it(
|
||||
"should create metadata and private metadata for fulfilled order . TC: SALEOR_2129",
|
||||
{ tags: ["@orders", "@allEnv", "@stable"] },
|
||||
() => {
|
||||
let order;
|
||||
|
||||
cy.addAliasToGraphRequest("UpdateMetadata");
|
||||
cy.addAliasToGraphRequest("UpdatePrivateMetadata");
|
||||
createFulfilledOrder({
|
||||
customerId: customer.id,
|
||||
channelId: defaultChannel.id,
|
||||
shippingMethod,
|
||||
variantsList,
|
||||
address,
|
||||
warehouse: warehouse.id,
|
||||
})
|
||||
.then(({ order: orderResp }) => {
|
||||
order = orderResp;
|
||||
cy.visit(urlList.orders + `${order.id}`);
|
||||
addPublicMetadataFieldFulfillmentOrder(
|
||||
0,
|
||||
metadataName,
|
||||
metadataValue,
|
||||
);
|
||||
addPrivateMetadataFieldFulfillmentOrder(
|
||||
0,
|
||||
privateMetadataName,
|
||||
privateMetadataValue,
|
||||
);
|
||||
})
|
||||
.then(() => {
|
||||
cy.clickConfirmButton()
|
||||
.waitForRequestAndCheckIfNoErrors("@UpdateMetadata")
|
||||
.waitForRequestAndCheckIfNoErrors("@UpdatePrivateMetadata");
|
||||
cy.confirmationMessageShouldAppear();
|
||||
getOrder(order.id).then(orderResponse => {
|
||||
// check to see updated fulfillment metadata and private meta data
|
||||
cy.wrap(orderResponse.fulfillments[0].metadata[0]).should(
|
||||
"deep.equal",
|
||||
{
|
||||
key: metadataName,
|
||||
value: metadataValue,
|
||||
},
|
||||
);
|
||||
cy.wrap(orderResponse.fulfillments[0].privateMetadata[0]).should(
|
||||
"deep.equal",
|
||||
{
|
||||
key: privateMetadataName,
|
||||
value: privateMetadataValue,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
it(
|
||||
"should update metadata and private metadata for fulfilled order . TC: SALEOR_2130",
|
||||
{ tags: ["@orders", "@allEnv", "@stable"] },
|
||||
() => {
|
||||
cy.addAliasToGraphRequest("UpdateMetadata");
|
||||
cy.addAliasToGraphRequest("UpdatePrivateMetadata");
|
||||
createFulfilledOrder({
|
||||
customerId: customer.id,
|
||||
channelId: defaultChannel.id,
|
||||
shippingMethod,
|
||||
variantsList,
|
||||
address,
|
||||
warehouse: warehouse.id,
|
||||
}).then(orderResp => {
|
||||
getOrder(orderResp.order.id).then(orderDetails => {
|
||||
updateMetadata(
|
||||
orderDetails.fulfillments[0].id,
|
||||
metadataName,
|
||||
metadataValue,
|
||||
).then(() => {
|
||||
updatePrivateMetadata(
|
||||
orderDetails.fulfillments[0].id,
|
||||
privateMetadataName,
|
||||
privateMetadataValue,
|
||||
)
|
||||
.then(() => {
|
||||
cy.visit(urlList.orders + `${orderResp.order.id}`);
|
||||
updatePublicMetadataFieldFulfillmentOrder(
|
||||
0,
|
||||
updatedMetadataName,
|
||||
updatedMetadataValue,
|
||||
);
|
||||
updatePrivateMetadataFieldFulfillmentOrder(
|
||||
0,
|
||||
updatedPrivateMetadataName,
|
||||
updatedPrivateMetadataValue,
|
||||
);
|
||||
})
|
||||
.then(() => {
|
||||
cy.clickConfirmButton()
|
||||
.waitForRequestAndCheckIfNoErrors("@UpdateMetadata")
|
||||
.waitForRequestAndCheckIfNoErrors("@UpdatePrivateMetadata");
|
||||
cy.confirmationMessageShouldAppear();
|
||||
getOrder(orderResp.order.id).then(orderResponse => {
|
||||
// check to see updated fulfillment metadata and private meta data
|
||||
cy.wrap(orderResponse.fulfillments[0].metadata[0]).should(
|
||||
"deep.equal",
|
||||
{
|
||||
key: updatedMetadataName,
|
||||
value: updatedMetadataValue,
|
||||
},
|
||||
);
|
||||
cy.wrap(
|
||||
orderResponse.fulfillments[0].privateMetadata[0],
|
||||
).should("deep.equal", {
|
||||
key: updatedPrivateMetadataName,
|
||||
value: updatedPrivateMetadataValue,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
it(
|
||||
"should delete metadata and private metadata for fulfilled order . TC: SALEOR_2131",
|
||||
{ tags: ["@orders", "@allEnv", "@stable"] },
|
||||
() => {
|
||||
cy.addAliasToGraphRequest("UpdateMetadata");
|
||||
cy.addAliasToGraphRequest("UpdatePrivateMetadata");
|
||||
createFulfilledOrder({
|
||||
customerId: customer.id,
|
||||
channelId: defaultChannel.id,
|
||||
shippingMethod,
|
||||
variantsList,
|
||||
address,
|
||||
warehouse: warehouse.id,
|
||||
}).then(orderResp => {
|
||||
getOrder(orderResp.order.id).then(orderDetails => {
|
||||
updateMetadata(
|
||||
orderDetails.fulfillments[0].id,
|
||||
metadataName,
|
||||
metadataValue,
|
||||
).then(() => {
|
||||
updatePrivateMetadata(
|
||||
orderDetails.fulfillments[0].id,
|
||||
privateMetadataName,
|
||||
privateMetadataValue,
|
||||
)
|
||||
.then(() => {
|
||||
cy.visit(urlList.orders + `${orderResp.order.id}`);
|
||||
expandPublicFulfillmentMetadata(0);
|
||||
deletePublicFulfillmentMetadata(0, 0);
|
||||
expandPrivateFulfillmentMetadata(0);
|
||||
deletePrivateFulfillmentMetadata(0, 0);
|
||||
})
|
||||
.then(() => {
|
||||
cy.clickConfirmButton()
|
||||
.waitForRequestAndCheckIfNoErrors("@UpdateMetadata")
|
||||
.waitForRequestAndCheckIfNoErrors("@UpdatePrivateMetadata");
|
||||
cy.confirmationMessageShouldAppear();
|
||||
cy.contains(privateMetadataName).should("not.exist");
|
||||
cy.contains(metadataName).should("not.exist");
|
||||
getOrder(orderResp.order.id).then(orderResponse => {
|
||||
// check to see updated fulfillment metadata and private meta data
|
||||
cy.wrap(orderResponse.fulfillments[0].metadata).should(
|
||||
"deep.equal",
|
||||
[],
|
||||
);
|
||||
cy.wrap(orderResponse.fulfillments[0].privateMetadata).should(
|
||||
"deep.equal",
|
||||
[],
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,5 +5,10 @@ export const METADATA_FORM = {
|
|||
"[data-test-id='metadata-editor'][data-test-is-private='true']",
|
||||
addFieldButton: "[data-test-id='add-field']",
|
||||
nameInput: "[name*='name']",
|
||||
valueField: "[name*='value']"
|
||||
valueField: "[name*='value']",
|
||||
metaExpandButton: "[data-test-id='expand']",
|
||||
metaDeletedButton: "[data-test-id='delete-field-0']",
|
||||
privateMetaSection: "[data-test-is-private='true']",
|
||||
publicMetaSection: "[data-test-is-private='false']",
|
||||
fulfillmentMetaSection: "[data-test-id='fulfilled-order-section']",
|
||||
};
|
||||
|
|
|
@ -155,6 +155,17 @@ export function getOrder(orderId) {
|
|||
countryArea
|
||||
phone
|
||||
}
|
||||
fulfillments{
|
||||
id
|
||||
metadata{
|
||||
key
|
||||
value
|
||||
}
|
||||
privateMetadata{
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy.sendRequestWithQuery(query).its("body.data.order");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export { createChannel, updateChannelOrderSettings } from "./Channels";
|
||||
export { createCustomer, deleteCustomersStartsWith } from "./Customer";
|
||||
export { createDraftOrder, getOrder } from "./Order";
|
||||
export { createDraftOrder, getOrder, updateOrdersSettings } from "./Order";
|
||||
export { updateMetadata, updatePrivateMetadata } from "./Metadata";
|
||||
export { getProductMetadata } from "./storeFront/ProductDetails";
|
||||
export { activatePlugin, updatePlugin } from "./Plugins";
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
export { deleteChannelsStartsWith, getDefaultChannel } from "./channelsUtils";
|
||||
export { createOrder, createReadyToFulfillOrder } from "./ordersUtils";
|
||||
export { createShipping, deleteShippingStartsWith } from "./shippingUtils";
|
||||
export {
|
||||
getDefaultTaxClass,
|
||||
updateTaxConfigurationForChannel,
|
||||
} from "./taxesUtils";
|
||||
export * as productsUtils from "./products/productsUtils";
|
||||
|
||||
export {
|
||||
createFulfilledOrder,
|
||||
createOrder,
|
||||
createReadyToFulfillOrder,
|
||||
createUnconfirmedOrder,
|
||||
} from "./ordersUtils";
|
||||
export {
|
||||
getMailActivationLinkForUser,
|
||||
getMailActivationLinkForUserAndSubject,
|
||||
|
|
|
@ -20,6 +20,9 @@ Cypress.Commands.add("clickPrevPagePaginationButton", () =>
|
|||
Cypress.Commands.add("clickSubmitButton", () =>
|
||||
cy.get(BUTTON_SELECTORS.submit).click(),
|
||||
);
|
||||
Cypress.Commands.add("clickConfirmButton", () =>
|
||||
cy.get(BUTTON_SELECTORS.confirm).click(),
|
||||
);
|
||||
|
||||
Cypress.Commands.add("createNewOption", (selectSelector, newOption) => {
|
||||
cy.get(selectSelector).type(newOption);
|
||||
|
|
|
@ -2,7 +2,7 @@ import { METADATA_FORM } from "../../../elements/shared/metadata/metadata-form";
|
|||
|
||||
export const metadataForms = {
|
||||
private: METADATA_FORM.privateMetadataForm,
|
||||
public: METADATA_FORM.metadataForm
|
||||
public: METADATA_FORM.metadataForm,
|
||||
};
|
||||
|
||||
export function addMetadataField({ metadataForm, name, value }) {
|
||||
|
@ -17,3 +17,123 @@ export function addMetadataField({ metadataForm, name, value }) {
|
|||
.find(METADATA_FORM.valueField)
|
||||
.type(value);
|
||||
}
|
||||
export function addPublicMetadataFieldFulfillmentOrder(
|
||||
fulfillmentIndex,
|
||||
name,
|
||||
value,
|
||||
) {
|
||||
expandPublicFulfillmentMetadata(fulfillmentIndex);
|
||||
cy.get('[data-test-id="fulfilled-order-section"]')
|
||||
.eq(fulfillmentIndex)
|
||||
.find('[data-test-is-private="false"]')
|
||||
.find(METADATA_FORM.addFieldButton)
|
||||
.click();
|
||||
typePublicFulfillmentMetadataName(name, 0);
|
||||
typePublicFulfillmentMetadataValue(value, 0);
|
||||
}
|
||||
export function updatePublicMetadataFieldFulfillmentOrder(
|
||||
fulfillmentIndex,
|
||||
name,
|
||||
value,
|
||||
) {
|
||||
expandPublicFulfillmentMetadata(fulfillmentIndex);
|
||||
typePublicFulfillmentMetadataName(name, 0);
|
||||
typePublicFulfillmentMetadataValue(value, 0);
|
||||
}
|
||||
|
||||
export function typePublicFulfillmentMetadataValue(name, valueIndex) {
|
||||
return cy
|
||||
.get(METADATA_FORM.publicMetaSection)
|
||||
.find(METADATA_FORM.valueField)
|
||||
.eq(valueIndex)
|
||||
.clear()
|
||||
.type(name);
|
||||
}
|
||||
export function typePrivateFulfillmentMetadataValue(name, valueIndex) {
|
||||
return cy
|
||||
.get(METADATA_FORM.privateMetaSection)
|
||||
.find(METADATA_FORM.valueField)
|
||||
.eq(valueIndex)
|
||||
.clear()
|
||||
.type(name);
|
||||
}
|
||||
export function typePublicFulfillmentMetadataName(name, nameIndex) {
|
||||
return cy
|
||||
.get(METADATA_FORM.publicMetaSection)
|
||||
.find(METADATA_FORM.nameInput)
|
||||
.eq(nameIndex)
|
||||
.clear()
|
||||
.type(name);
|
||||
}
|
||||
export function typePrivateFulfillmentMetadataName(name, nameIndex) {
|
||||
return cy
|
||||
.get(METADATA_FORM.privateMetaSection)
|
||||
.find(METADATA_FORM.nameInput)
|
||||
.eq(nameIndex)
|
||||
.clear()
|
||||
.type(name);
|
||||
}
|
||||
export function expandPublicFulfillmentMetadata(fulfillmentIndex) {
|
||||
return cy
|
||||
.get(METADATA_FORM.fulfillmentMetaSection)
|
||||
.eq(fulfillmentIndex)
|
||||
.find(METADATA_FORM.publicMetaSection)
|
||||
.find(METADATA_FORM.metaExpandButton)
|
||||
.click();
|
||||
}
|
||||
export function deletePublicFulfillmentMetadata(
|
||||
fulfillmentIndex,
|
||||
metaDataIndex,
|
||||
) {
|
||||
return cy
|
||||
.get(METADATA_FORM.fulfillmentMetaSection)
|
||||
.eq(fulfillmentIndex)
|
||||
.find(METADATA_FORM.publicMetaSection)
|
||||
.find(METADATA_FORM.metaDeletedButton)
|
||||
.eq(metaDataIndex)
|
||||
.click();
|
||||
}
|
||||
export function deletePrivateFulfillmentMetadata(
|
||||
fulfillmentIndex,
|
||||
metaDataIndex,
|
||||
) {
|
||||
return cy
|
||||
.get(METADATA_FORM.fulfillmentMetaSection)
|
||||
.eq(fulfillmentIndex)
|
||||
.find(METADATA_FORM.privateMetaSection)
|
||||
.find(METADATA_FORM.metaDeletedButton)
|
||||
.eq(metaDataIndex)
|
||||
.click();
|
||||
}
|
||||
export function expandPrivateFulfillmentMetadata(fulfillmentIndex) {
|
||||
return cy
|
||||
.get(METADATA_FORM.fulfillmentMetaSection)
|
||||
.eq(fulfillmentIndex)
|
||||
.find(METADATA_FORM.privateMetaSection)
|
||||
.find(METADATA_FORM.metaExpandButton)
|
||||
.click();
|
||||
}
|
||||
export function addPrivateMetadataFieldFulfillmentOrder(
|
||||
fulfillmentIndex,
|
||||
name,
|
||||
value,
|
||||
) {
|
||||
expandPrivateFulfillmentMetadata(fulfillmentIndex);
|
||||
cy.get(METADATA_FORM.fulfillmentMetaSection)
|
||||
|
||||
.eq(fulfillmentIndex)
|
||||
.find(METADATA_FORM.privateMetaSection)
|
||||
.find(METADATA_FORM.addFieldButton)
|
||||
.click();
|
||||
typePrivateFulfillmentMetadataName(name, 0);
|
||||
typePrivateFulfillmentMetadataValue(value, 0);
|
||||
}
|
||||
export function updatePrivateMetadataFieldFulfillmentOrder(
|
||||
fulfillmentIndex,
|
||||
name,
|
||||
value,
|
||||
) {
|
||||
expandPrivateFulfillmentMetadata(fulfillmentIndex);
|
||||
typePrivateFulfillmentMetadataName(name, 0);
|
||||
typePrivateFulfillmentMetadataValue(value, 0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
export * as ordersOperationsHelpers from "./ordersOperations";
|
||||
export * as transactionsOrderUtils from "./ordersTransactionUtils";
|
||||
export {
|
||||
addMetadataField,
|
||||
addPrivateMetadataFieldFulfillmentOrder,
|
||||
addPublicMetadataFieldFulfillmentOrder,
|
||||
deletePrivateFulfillmentMetadata,
|
||||
deletePublicFulfillmentMetadata,
|
||||
expandPrivateFulfillmentMetadata,
|
||||
expandPublicFulfillmentMetadata,
|
||||
updatePrivateMetadataFieldFulfillmentOrder,
|
||||
updatePublicMetadataFieldFulfillmentOrder,
|
||||
} from "./catalog/metadataComponent";
|
||||
export { selectChannelInPicker } from "./channelsPage";
|
||||
export { finalizeDraftOrder } from "./draftOrderPage";
|
||||
export {
|
||||
addNewProductToOrder,
|
||||
applyFixedLineDiscountForProduct,
|
||||
changeQuantityOfProducts,
|
||||
deleteProductFromGridTableOnIndex,
|
||||
} from "./ordersOperations";
|
||||
export { expectWelcomeMessageIncludes } from "./homePage";
|
||||
export { getDisplayedSelectors } from "./permissionsPage";
|
||||
export {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { MetadataInput } from "@dashboard/graphql";
|
|||
import { ChangeEvent } from "@dashboard/hooks/useForm";
|
||||
import { removeAtIndex, updateAtIndex } from "@dashboard/utils/lists";
|
||||
import { Box } from "@saleor/macaw-ui/next";
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import { MetadataCard, MetadataCardProps } from "./MetadataCard";
|
||||
import { EventDataAction, EventDataField } from "./types";
|
||||
|
@ -11,9 +11,24 @@ import { getDataKey, parseEventData } from "./utils";
|
|||
export interface MetadataProps
|
||||
extends Omit<MetadataCardProps, "data" | "isPrivate"> {
|
||||
data: Record<"metadata" | "privateMetadata", MetadataInput[]>;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export const Metadata: React.FC<MetadataProps> = ({ data, onChange }) => {
|
||||
const propsCompare = (_, newProps: MetadataProps) => {
|
||||
/**
|
||||
If we pass `isLoading` render only when the loading finishes
|
||||
*/
|
||||
if (typeof newProps.isLoading !== "undefined") {
|
||||
return newProps.isLoading;
|
||||
}
|
||||
|
||||
/*
|
||||
If `isLoading` is not present, keep the old behavior
|
||||
*/
|
||||
return false;
|
||||
};
|
||||
|
||||
export const Metadata: React.FC<MetadataProps> = memo(({ data, onChange }) => {
|
||||
const change = (event: ChangeEvent, isPrivate: boolean) => {
|
||||
const { action, field, fieldIndex, value } = parseEventData(event);
|
||||
const key = getDataKey(isPrivate);
|
||||
|
@ -66,4 +81,4 @@ export const Metadata: React.FC<MetadataProps> = ({ data, onChange }) => {
|
|||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
}, propsCompare);
|
||||
|
|
|
@ -19,3 +19,10 @@ export interface MetadataFormData {
|
|||
metadata: MetadataInput[];
|
||||
privateMetadata: MetadataInput[];
|
||||
}
|
||||
|
||||
export interface MetadataIdSchema {
|
||||
[key: string]: {
|
||||
metadata: MetadataInput[];
|
||||
privateMetadata: MetadataInput[];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -156,6 +156,7 @@ export const fragmentRefundOrderLine = gql`
|
|||
|
||||
export const fulfillmentFragment = gql`
|
||||
fragment Fulfillment on Fulfillment {
|
||||
...Metadata
|
||||
id
|
||||
lines {
|
||||
id
|
||||
|
|
|
@ -1603,6 +1603,7 @@ export const OrderLineFragmentDoc = gql`
|
|||
${TaxedMoneyFragmentDoc}`;
|
||||
export const FulfillmentFragmentDoc = gql`
|
||||
fragment Fulfillment on Fulfillment {
|
||||
...Metadata
|
||||
id
|
||||
lines {
|
||||
id
|
||||
|
@ -1619,6 +1620,7 @@ export const FulfillmentFragmentDoc = gql`
|
|||
name
|
||||
}
|
||||
}
|
||||
${MetadataFragmentDoc}
|
||||
${OrderLineFragmentDoc}`;
|
||||
export const InvoiceFragmentDoc = gql`
|
||||
fragment Invoice on Invoice {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -9,7 +9,7 @@ import { CardSpacer } from "@dashboard/components/CardSpacer";
|
|||
import { useDevModeContext } from "@dashboard/components/DevModePanel/hooks";
|
||||
import Form from "@dashboard/components/Form";
|
||||
import { DetailPageLayout } from "@dashboard/components/Layouts";
|
||||
import { Metadata, MetadataFormData } from "@dashboard/components/Metadata";
|
||||
import { Metadata, MetadataIdSchema } from "@dashboard/components/Metadata";
|
||||
import Savebar from "@dashboard/components/Savebar";
|
||||
import {
|
||||
OrderDetailsFragment,
|
||||
|
@ -22,8 +22,6 @@ import { SubmitPromise } from "@dashboard/hooks/useForm";
|
|||
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||
import { defaultGraphiQLQuery } from "@dashboard/orders/queries";
|
||||
import { orderListUrl } from "@dashboard/orders/urls";
|
||||
import { mapMetadataItemToInput } from "@dashboard/utils/maps";
|
||||
import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger";
|
||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
@ -41,7 +39,12 @@ import { OrderPaymentOrTransaction } from "../OrderPaymentOrTransaction/OrderPay
|
|||
import OrderUnfulfilledProductsCard from "../OrderUnfulfilledProductsCard";
|
||||
import { messages } from "./messages";
|
||||
import Title from "./Title";
|
||||
import { filteredConditionalItems, hasAnyItemsReplaceable } from "./utils";
|
||||
import {
|
||||
createMetadataHandler,
|
||||
createOrderMetadataIdSchema,
|
||||
filteredConditionalItems,
|
||||
hasAnyItemsReplaceable,
|
||||
} from "./utils";
|
||||
|
||||
export interface OrderDetailsPageProps {
|
||||
order: OrderDetailsFragment | OrderDetailsFragment;
|
||||
|
@ -80,7 +83,7 @@ export interface OrderDetailsPageProps {
|
|||
onInvoiceSend(invoiceId: string);
|
||||
onTransactionAction(transactionId: string, actionType: TransactionActionEnum);
|
||||
onAddManualTransaction();
|
||||
onSubmit(data: MetadataFormData): SubmitPromise;
|
||||
onSubmit(data: MetadataIdSchema): SubmitPromise;
|
||||
}
|
||||
|
||||
const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
||||
|
@ -118,13 +121,6 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
const navigate = useNavigator();
|
||||
const intl = useIntl();
|
||||
|
||||
const {
|
||||
isMetadataModified,
|
||||
isPrivateMetadataModified,
|
||||
makeChangeHandler: makeMetadataChangeHandler,
|
||||
resetMetadataChanged,
|
||||
} = useMetadataChangeTrigger();
|
||||
|
||||
const isOrderUnconfirmed = order?.status === OrderStatus.UNCONFIRMED;
|
||||
const canCancel = order?.status !== OrderStatus.CANCELED;
|
||||
const canEditAddresses = order?.status !== OrderStatus.CANCELED;
|
||||
|
@ -137,24 +133,12 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
line => line.quantityToFulfill > 0,
|
||||
);
|
||||
|
||||
const handleSubmit = async (data: MetadataFormData) => {
|
||||
const metadata = isMetadataModified ? data.metadata : undefined;
|
||||
const privateMetadata = isPrivateMetadataModified
|
||||
? data.privateMetadata
|
||||
: undefined;
|
||||
|
||||
const result = await onSubmit({
|
||||
metadata,
|
||||
privateMetadata,
|
||||
});
|
||||
resetMetadataChanged();
|
||||
const handleSubmit = async (data: MetadataIdSchema) => {
|
||||
const result = await onSubmit(data);
|
||||
return getMutationErrors(result);
|
||||
};
|
||||
|
||||
const initial: MetadataFormData = {
|
||||
metadata: order?.metadata.map(mapMetadataItemToInput),
|
||||
privateMetadata: order?.privateMetadata.map(mapMetadataItemToInput),
|
||||
};
|
||||
const initial = createOrderMetadataIdSchema(order);
|
||||
|
||||
const saveLabel = isOrderUnconfirmed
|
||||
? { confirm: intl.formatMessage(messages.confirmOrder) }
|
||||
|
@ -204,9 +188,18 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
};
|
||||
|
||||
return (
|
||||
<Form confirmLeave initial={initial} onSubmit={handleSubmit}>
|
||||
{({ change, data, submit }) => {
|
||||
const changeMetadata = makeMetadataChangeHandler(change);
|
||||
<Form
|
||||
confirmLeave
|
||||
initial={initial}
|
||||
onSubmit={handleSubmit}
|
||||
mergeData={false}
|
||||
>
|
||||
{({ set, triggerChange, data, submit }) => {
|
||||
const handleChangeMetadata = createMetadataHandler(
|
||||
data,
|
||||
set,
|
||||
triggerChange,
|
||||
);
|
||||
|
||||
return (
|
||||
<DetailPageLayout>
|
||||
|
@ -248,8 +241,9 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
</>
|
||||
)}
|
||||
{order?.fulfillments?.map(fulfillment => (
|
||||
<React.Fragment key={fulfillment.id}>
|
||||
<OrderFulfilledProductsCard
|
||||
dataTestId="fulfilled-order-section"
|
||||
key={fulfillment.id}
|
||||
fulfillment={fulfillment}
|
||||
fulfillmentAllowUnpaid={shop?.fulfillmentAllowUnpaid}
|
||||
order={order}
|
||||
|
@ -262,8 +256,13 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
onOrderFulfillmentApprove={() =>
|
||||
onFulfillmentApprove(fulfillment.id)
|
||||
}
|
||||
>
|
||||
<Metadata
|
||||
isLoading={loading}
|
||||
data={data[fulfillment.id]}
|
||||
onChange={x => handleChangeMetadata(x, fulfillment.id)}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</OrderFulfilledProductsCard>
|
||||
))}
|
||||
<OrderPaymentOrTransaction
|
||||
order={order}
|
||||
|
@ -275,7 +274,11 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
|
|||
onMarkAsPaid={onMarkAsPaid}
|
||||
onAddManualTransaction={onAddManualTransaction}
|
||||
/>
|
||||
<Metadata data={data} onChange={changeMetadata} />
|
||||
<Metadata
|
||||
isLoading={loading}
|
||||
data={data[order?.id]}
|
||||
onChange={x => handleChangeMetadata(x, order?.id)}
|
||||
/>
|
||||
<OrderHistory
|
||||
history={order?.events}
|
||||
orderCurrency={order?.total?.gross.currency}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import { filteredConditionalItems } from "./utils";
|
||||
import { OrderDetailsFragment } from "@dashboard/graphql";
|
||||
import { ChangeEvent } from "@dashboard/hooks/useForm";
|
||||
|
||||
import {
|
||||
createMetadataHandler,
|
||||
createOrderMetadataIdSchema,
|
||||
filteredConditionalItems,
|
||||
} from "./utils";
|
||||
|
||||
describe("filteredConditionalItems", () => {
|
||||
it("should return empty [] when no items has shouldExist set to true", () => {
|
||||
|
@ -42,3 +49,110 @@ describe("filteredConditionalItems", () => {
|
|||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("createOrderMetadataIdSchema", () => {
|
||||
it("returns order and fulfilment metadata", () => {
|
||||
// Arrange
|
||||
const order = {
|
||||
id: "some-order-id",
|
||||
metadata: [{ key: "mt1", value: "mt1-value" }],
|
||||
privateMetadata: [{ key: "pmt1", value: "pmt1-value" }],
|
||||
fulfillments: [
|
||||
{
|
||||
id: "some-fulfillment-id",
|
||||
metadata: [{ key: "fmt1", value: "fmt1-value" }],
|
||||
privateMetadata: [{ key: "fpmt1", value: "fpmt1-value" }],
|
||||
},
|
||||
{
|
||||
id: "some-fulfillment-id",
|
||||
metadata: [{ key: "fmt1", value: "fmt1-value" }],
|
||||
privateMetadata: [{ key: "fpmt1", value: "fpmt1-value" }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Act
|
||||
const metadata = createOrderMetadataIdSchema(order as OrderDetailsFragment);
|
||||
|
||||
// Assert
|
||||
expect(metadata).toEqual({
|
||||
"some-fulfillment-id": {
|
||||
metadata: [
|
||||
{
|
||||
key: "fmt1",
|
||||
value: "fmt1-value",
|
||||
},
|
||||
],
|
||||
privateMetadata: [
|
||||
{
|
||||
key: "fpmt1",
|
||||
value: "fpmt1-value",
|
||||
},
|
||||
],
|
||||
},
|
||||
"some-order-id": {
|
||||
metadata: [
|
||||
{
|
||||
key: "mt1",
|
||||
value: "mt1-value",
|
||||
},
|
||||
],
|
||||
privateMetadata: [
|
||||
{
|
||||
key: "pmt1",
|
||||
value: "pmt1-value",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("createMetadataHandler", () => {
|
||||
it("handles order metadata change", () => {
|
||||
// Arrange
|
||||
const currentData = {
|
||||
"some-order-id": {
|
||||
metadata: [{ key: "mt1", value: "mt1-value" }],
|
||||
privateMetadata: [{ key: "pmt1", value: "pmt1-value" }],
|
||||
},
|
||||
"some-fulfillment-id": {
|
||||
metadata: [{ key: "fmt1", value: "fmt1-value" }],
|
||||
privateMetadata: [{ key: "fpmt1", value: "fpmt1-value" }],
|
||||
},
|
||||
};
|
||||
const set = jest.fn();
|
||||
const triggerChange = jest.fn();
|
||||
const handler = createMetadataHandler(currentData, set, triggerChange);
|
||||
|
||||
// Act
|
||||
handler(
|
||||
{
|
||||
target: {
|
||||
name: "metadata",
|
||||
value: [{ key: "new-key", value: "new-value" }],
|
||||
},
|
||||
} as ChangeEvent,
|
||||
"some-order-id",
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(set).toHaveBeenCalledWith({
|
||||
"some-order-id": {
|
||||
metadata: [
|
||||
{
|
||||
key: "new-key",
|
||||
value: "new-value",
|
||||
},
|
||||
],
|
||||
privateMetadata: [
|
||||
{
|
||||
key: "pmt1",
|
||||
value: "pmt1-value",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(triggerChange).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import { MetadataIdSchema } from "@dashboard/components/Metadata";
|
||||
import { OrderDetailsFragment } from "@dashboard/graphql";
|
||||
import { ChangeEvent } from "@dashboard/hooks/useForm";
|
||||
import { mapMetadataItemToInput } from "@dashboard/utils/maps";
|
||||
|
||||
import {
|
||||
getFulfilledFulfillemnts,
|
||||
|
@ -29,3 +32,37 @@ export interface ConditionalItem {
|
|||
|
||||
export const filteredConditionalItems = (items: ConditionalItem[]) =>
|
||||
items.filter(({ shouldExist }) => shouldExist).map(({ item }) => item);
|
||||
|
||||
export const createOrderMetadataIdSchema = (
|
||||
order: OrderDetailsFragment,
|
||||
): MetadataIdSchema => ({
|
||||
[order?.id]: {
|
||||
metadata: order?.metadata.map(mapMetadataItemToInput),
|
||||
privateMetadata: order?.privateMetadata.map(mapMetadataItemToInput),
|
||||
},
|
||||
...order?.fulfillments.reduce((p, c) => {
|
||||
p[c.id] = {
|
||||
metadata: c?.metadata.map(mapMetadataItemToInput),
|
||||
privateMetadata: c?.privateMetadata.map(mapMetadataItemToInput),
|
||||
};
|
||||
|
||||
return p;
|
||||
}, {}),
|
||||
});
|
||||
|
||||
export const createMetadataHandler =
|
||||
(
|
||||
currentData: MetadataIdSchema,
|
||||
set: (newData: Partial<MetadataIdSchema>) => void,
|
||||
triggerChange: () => void,
|
||||
) =>
|
||||
(event: ChangeEvent, objectId: string) => {
|
||||
const metadataType = event.target.name;
|
||||
set({
|
||||
[objectId]: {
|
||||
...currentData[objectId],
|
||||
[metadataType]: [...event.target.value],
|
||||
},
|
||||
});
|
||||
triggerChange();
|
||||
};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import CardSpacer from "@dashboard/components/CardSpacer";
|
||||
import { FulfillmentStatus, OrderDetailsFragment } from "@dashboard/graphql";
|
||||
import TrashIcon from "@dashboard/icons/Trash";
|
||||
import { orderHasTransactions } from "@dashboard/orders/types";
|
||||
import { mergeRepeatedOrderLines } from "@dashboard/orders/utils/data";
|
||||
import { Card, CardContent } from "@material-ui/core";
|
||||
import { CardContent } from "@material-ui/core";
|
||||
import { IconButton } from "@saleor/macaw-ui";
|
||||
import { Box, Divider } from "@saleor/macaw-ui/next";
|
||||
import React from "react";
|
||||
|
||||
import OrderCardTitle from "../OrderCardTitle";
|
||||
|
@ -20,6 +20,7 @@ interface OrderFulfilledProductsCardProps {
|
|||
onOrderFulfillmentApprove: () => void;
|
||||
onOrderFulfillmentCancel: () => void;
|
||||
onTrackingCodeAdd: () => void;
|
||||
dataTestId?: string;
|
||||
}
|
||||
|
||||
const statusesToMergeLines = [
|
||||
|
@ -43,6 +44,7 @@ const OrderFulfilledProductsCard: React.FC<
|
|||
onOrderFulfillmentApprove,
|
||||
onOrderFulfillmentCancel,
|
||||
onTrackingCodeAdd,
|
||||
dataTestId,
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
|
@ -61,8 +63,7 @@ const OrderFulfilledProductsCard: React.FC<
|
|||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<Box data-test-id={dataTestId}>
|
||||
<OrderCardTitle
|
||||
withStatus
|
||||
lines={fulfillment?.lines}
|
||||
|
@ -71,7 +72,8 @@ const OrderFulfilledProductsCard: React.FC<
|
|||
warehouseName={fulfillment?.warehouse?.name}
|
||||
orderNumber={order?.number}
|
||||
toolbar={
|
||||
cancelableStatuses.includes(fulfillment?.status) && (
|
||||
<Box display="flex" alignItems="center" gap={6}>
|
||||
{cancelableStatuses.includes(fulfillment?.status) && (
|
||||
<IconButton
|
||||
variant="secondary"
|
||||
className={classes.deleteIcon}
|
||||
|
@ -80,12 +82,7 @@ const OrderFulfilledProductsCard: React.FC<
|
|||
>
|
||||
<TrashIcon />
|
||||
</IconButton>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<CardContent>
|
||||
<OrderDetailsDatagrid lines={getLines()} loading={false} />
|
||||
<ExtraInfoLines fulfillment={fulfillment} />
|
||||
)}
|
||||
<ActionButtons
|
||||
orderId={order?.id}
|
||||
status={fulfillment?.status}
|
||||
|
@ -96,10 +93,16 @@ const OrderFulfilledProductsCard: React.FC<
|
|||
onApprove={onOrderFulfillmentApprove}
|
||||
hasTransactions={orderHasTransactions(order)}
|
||||
/>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<CardContent>
|
||||
<OrderDetailsDatagrid lines={getLines()} loading={false} />
|
||||
<ExtraInfoLines fulfillment={fulfillment} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
<CardSpacer />
|
||||
</>
|
||||
{props.children}
|
||||
<Divider />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1207,6 +1207,8 @@ export const order = (placeholder: string): OrderDetailsFragment => ({
|
|||
__typename: "Fulfillment",
|
||||
fulfillmentOrder: 2,
|
||||
id: "RnVsZmlsbG1lbnQ6MjQ=",
|
||||
metadata: [],
|
||||
privateMetadata: [],
|
||||
lines: [
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
|
@ -1331,6 +1333,8 @@ export const order = (placeholder: string): OrderDetailsFragment => ({
|
|||
__typename: "Fulfillment",
|
||||
fulfillmentOrder: 1,
|
||||
id: "RnVsZmlsbG1lbnQ6OQ==",
|
||||
metadata: [],
|
||||
privateMetadata: [],
|
||||
lines: [
|
||||
{
|
||||
__typename: "FulfillmentLine",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useApolloClient } from "@apollo/client";
|
||||
import { MetadataFormData } from "@dashboard/components/Metadata";
|
||||
import { MetadataIdSchema } from "@dashboard/components/Metadata";
|
||||
import NotFoundPage from "@dashboard/components/NotFoundPage";
|
||||
import { Task } from "@dashboard/containers/BackgroundTasks/types";
|
||||
import {
|
||||
|
@ -15,6 +15,7 @@ import useBackgroundTask from "@dashboard/hooks/useBackgroundTask";
|
|||
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||
import useNotifier from "@dashboard/hooks/useNotifier";
|
||||
import { commonMessages } from "@dashboard/intl";
|
||||
import { createOrderMetadataIdSchema } from "@dashboard/orders/components/OrderDetailsPage/utils";
|
||||
import getOrderErrorMessage from "@dashboard/utils/errors/order";
|
||||
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
|
||||
import createMetadataUpdateHandler from "@dashboard/utils/handlers/metadataUpdateHandler";
|
||||
|
@ -83,21 +84,27 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
const isOrderUnconfirmed = order?.status === OrderStatus.UNCONFIRMED;
|
||||
const isOrderDraft = order?.status === OrderStatus.DRAFT;
|
||||
|
||||
const handleSubmit = async (data: MetadataFormData) => {
|
||||
const handleSubmit = async (data: MetadataIdSchema) => {
|
||||
if (order?.status === OrderStatus.UNCONFIRMED) {
|
||||
await orderConfirm({ variables: { id: order?.id } });
|
||||
}
|
||||
|
||||
const initial = createOrderMetadataIdSchema(order);
|
||||
const metadataPromises = Object.entries(initial).map(([id, metaEntry]) => {
|
||||
const update = createMetadataUpdateHandler(
|
||||
order,
|
||||
{ ...metaEntry, id },
|
||||
() => Promise.resolve([]),
|
||||
variables => updateMetadata({ variables }),
|
||||
variables => updatePrivateMetadata({ variables }),
|
||||
);
|
||||
|
||||
const result = await update(data);
|
||||
return update(data[id]);
|
||||
});
|
||||
|
||||
if (result.length === 0) {
|
||||
const result = await Promise.all(metadataPromises);
|
||||
const errors = result.reduce((p, c) => p.concat(c), []);
|
||||
|
||||
if (errors.length === 0) {
|
||||
notify({
|
||||
status: "success",
|
||||
text: intl.formatMessage(commonMessages.savedChanges),
|
||||
|
@ -182,6 +189,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
<OrderNormalDetails
|
||||
id={id}
|
||||
params={params}
|
||||
loading={loading}
|
||||
data={data}
|
||||
orderAddNote={orderAddNote}
|
||||
orderInvoiceRequest={orderInvoiceRequest}
|
||||
|
|
|
@ -64,6 +64,7 @@ interface OrderNormalDetailsProps {
|
|||
id: string;
|
||||
params: OrderUrlQueryParams;
|
||||
data: OrderDetailsQueryResult["data"];
|
||||
loading: boolean;
|
||||
orderAddNote: any;
|
||||
orderInvoiceRequest: any;
|
||||
handleSubmit: any;
|
||||
|
@ -104,6 +105,7 @@ export const OrderNormalDetails: React.FC<OrderNormalDetailsProps> = ({
|
|||
id,
|
||||
params,
|
||||
data,
|
||||
loading,
|
||||
orderAddNote,
|
||||
orderInvoiceRequest,
|
||||
handleSubmit,
|
||||
|
@ -187,7 +189,9 @@ export const OrderNormalDetails: React.FC<OrderNormalDetailsProps> = ({
|
|||
<OrderDetailsPage
|
||||
onOrderReturn={() => navigate(orderReturnUrl(id))}
|
||||
loading={
|
||||
updateMetadataOpts.loading || updatePrivateMetadataOpts.loading
|
||||
loading ||
|
||||
updateMetadataOpts.loading ||
|
||||
updatePrivateMetadataOpts.loading
|
||||
}
|
||||
errors={errors}
|
||||
onNoteAdd={variables =>
|
||||
|
|
|
@ -52,11 +52,10 @@ function createMetadataUpdateHandler<TData extends MetadataFormData, TError>(
|
|||
if (data.metadata && hasMetadataChanged) {
|
||||
const initialKeys = initial.metadata.map(m => m.key);
|
||||
const modifiedKeys = data.metadata.map(m => m.key);
|
||||
|
||||
const keyDiff = arrayDiff(initialKeys, modifiedKeys);
|
||||
const metadataInput = filterMetadataArray(data.metadata);
|
||||
|
||||
if (metadataInput.length) {
|
||||
if (metadataInput.length || keyDiff.removed.length) {
|
||||
const updateMetaResult = await updateMetadata({
|
||||
id: initial.id,
|
||||
input: metadataInput,
|
||||
|
@ -81,7 +80,7 @@ function createMetadataUpdateHandler<TData extends MetadataFormData, TError>(
|
|||
const keyDiff = arrayDiff(initialKeys, modifiedKeys);
|
||||
const privateMetadataInput = filterMetadataArray(data.privateMetadata);
|
||||
|
||||
if (privateMetadataInput.length) {
|
||||
if (privateMetadataInput.length || keyDiff.removed.length) {
|
||||
const updatePrivateMetaResult = await updatePrivateMetadata({
|
||||
id: initial.id,
|
||||
input: privateMetadataInput,
|
||||
|
|
Loading…
Reference in a new issue