saleor-dashboard/src/customers/views/CustomerDetailsContent.tsx
Magdalena Markusik 3d636f4789
Exit dirty form (#1816)
* Add Exit form prompt component and change some minor styles in other components to match

* Add Exit form prompt provider

* Adjust generic form and useform hook to allow using exit form prompt provider

* Add exit form prompt provider to index

* wip

* Fix types

* Fix styling

* Fix types

* Revert warehouse details refactor

* Add handling of edge cases to exit prompt

* Refactor, add comments, fix some types

* Refactor after exit form dialog name change

* fix types

* Fixes after review

* Add default value for useform prop opts so the app doesn't crash

* Add missing category prop to getting initial data for category details form

* Add exit dialog to everywhere WIP (#1600)

* Add Exit form prompt component and change some minor styles in other components to match

* Add Exit form prompt provider

* Adjust generic form and useform hook to allow using exit form prompt provider

* Add exit form prompt provider to index

* wip

* Fix types

* Fix styling

* Fix types

* Revert warehouse details refactor

* Add handling of edge cases to exit prompt

* Refactor, add comments, fix some types

* Refactor after exit form dialog name change

* fix types

* Add CommonUseFormResultWithHandlers type for later use and refactor handleFormSubmit util

* Refactor login form not to use custom form since it doesn't need to

* Add exit form dialog to order refund page

* Add exit form dialog to order return page

* Add exit form dialog to order order settings  page

* Add exit form dialog to product variant page

* Add exit form dialog to product create page

* Add exit form dialog to product update page

* Add exit form dialog to product variant create page

* Fix confirm leave prop passing in generic Form

* Add util function to handle for submit to extract errors

* Add confirmLeave prop to generic forms

* Move handleChange for custom forms to useForm

* Add exit dialog to more forms

* Add extract mutation errors util function

* Add extracting errors to submit functions that use metadata create handler

* Fix typo

* Add missing category prop to getting initial data for category details form

* Fix types

* wip

* wip

* wip

* wip

* Fix types & refactor

* Fix types & refactor

* Fix typescript

* Fix unmatching tag

* Fixes

* Add handling of multiple forms at once to exit dirty form provider

* Change all usages of ExitFormDialogContext to designated hook

* wip

* wip

* wip

* Fix types wip

* Fix types

* Remove console logs

* Add isSubmitting prop to exit form dialog in order to avoid enabling exit dialog while submit is still in progresS

* Replace handleSubmit global util with a hook to use exit form dialog props inside

* Move useHandleSubmit to general hooks dir, update imports

* Small fixes

* Update snapshots

* Fix types

* Small fixes due to extensive rebase

* Update package lock

* Fixes after rebase

* Remove exit form from customer address dialog

* Fix types and update messages

* Fix types

* Change imports names

* Refactor

* Remove unnecessary console.log

* Update types, snapshots. etc after rebase
2022-02-01 10:58:06 +01:00

149 lines
4.5 KiB
TypeScript

import { DialogContentText } from "@material-ui/core";
import ActionDialog from "@saleor/components/ActionDialog";
import NotFoundPage from "@saleor/components/NotFoundPage";
import { WindowTitle } from "@saleor/components/WindowTitle";
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
import { extractMutationErrors, getStringOrPlaceholder } from "@saleor/misc";
import { MutationResultAdditionalProps } from "@saleor/types";
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
import {
useMetadataUpdate,
usePrivateMetadataUpdate
} from "@saleor/utils/metadata/updateMetadata";
import React, { useContext } from "react";
import { MutationFunction, MutationResult } from "react-apollo";
import { FormattedMessage, useIntl } from "react-intl";
import { orderListUrl, orderUrl } from "../../orders/urls";
import CustomerDetailsPage, {
CustomerDetailsPageFormData
} from "../components/CustomerDetailsPage/CustomerDetailsPage";
import { CustomerDetailsContext } from "../providers/CustomerDetailsProvider";
import {
RemoveCustomer,
RemoveCustomerVariables
} from "../types/RemoveCustomer";
import {
UpdateCustomer,
UpdateCustomerVariables
} from "../types/UpdateCustomer";
import {
customerAddressesUrl,
customerUrl,
CustomerUrlQueryParams
} from "../urls";
export interface CustomerDetailsContentProps {
handleBack: () => void;
updateCustomer: MutationFunction<UpdateCustomer, UpdateCustomerVariables>;
removeCustomer: MutationFunction<RemoveCustomer, RemoveCustomerVariables>;
id: string;
updateCustomerOpts: MutationResult<UpdateCustomer> &
MutationResultAdditionalProps;
removeCustomerOpts: MutationResult<RemoveCustomer> &
MutationResultAdditionalProps;
navigate: UseNavigatorResult;
params: CustomerUrlQueryParams;
}
export const CustomerDetailsContent: React.FC<CustomerDetailsContentProps> = ({
handleBack,
updateCustomer,
id,
updateCustomerOpts,
removeCustomerOpts,
navigate,
removeCustomer,
params
}) => {
const customerDetails = useContext(CustomerDetailsContext);
const user = customerDetails?.customer?.user;
const customerDetailsLoading = customerDetails?.loading;
const intl = useIntl();
if (user === null) {
return <NotFoundPage onBack={handleBack} />;
}
const [updateMetadata] = useMetadataUpdate({});
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
const updateData = async (data: CustomerDetailsPageFormData) =>
extractMutationErrors(
updateCustomer({
variables: {
id,
input: {
email: data.email,
firstName: data.firstName,
isActive: data.isActive,
lastName: data.lastName,
note: data.note
}
}
})
);
const handleSubmit = createMetadataUpdateHandler(
user,
updateData,
variables => updateMetadata({ variables }),
variables => updatePrivateMetadata({ variables })
);
return (
<>
<WindowTitle title={user?.email} />
<CustomerDetailsPage
customer={user}
disabled={
customerDetailsLoading ||
updateCustomerOpts.loading ||
removeCustomerOpts.loading
}
errors={updateCustomerOpts.data?.customerUpdate.errors || []}
saveButtonBar={updateCustomerOpts.status}
onAddressManageClick={() => navigate(customerAddressesUrl(id))}
onBack={handleBack}
onRowClick={id => navigate(orderUrl(id))}
onSubmit={handleSubmit}
onDelete={() =>
navigate(
customerUrl(id, {
action: "remove"
})
)
}
onViewAllOrdersClick={() =>
navigate(
orderListUrl({
customer: user?.email
})
)
}
/>
<ActionDialog
confirmButtonState={removeCustomerOpts.status}
onClose={() => navigate(customerUrl(id), { replace: true })}
onConfirm={() => removeCustomer()}
title={intl.formatMessage({
defaultMessage: "Delete Customer",
description: "dialog header"
})}
variant="delete"
open={params.action === "remove"}
>
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to delete {email}?"
description="delete customer, dialog content"
values={{
email: <strong>{getStringOrPlaceholder(user?.email)}</strong>
}}
/>
</DialogContentText>
</ActionDialog>
</>
);
};