diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsDialogContent.js b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsDialogContent.js
new file mode 100644
index 000000000..655d507fd
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsDialogContent.js
@@ -0,0 +1,15 @@
+import React from 'react';
+
+import UnlockingTransactionsForm from './UnlockingTransactionsForm';
+import { UnlockingTransactionsFormProvider } from './UnlockingTransactionsFormProvider';
+
+export default function UnlockingTransactionsDialogContent({
+ // #ownProps
+ dialogName,
+}) {
+ return (
+
+
+
+ );
+}
diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsForm.js b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsForm.js
new file mode 100644
index 000000000..c99866be1
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsForm.js
@@ -0,0 +1,74 @@
+import React from 'react';
+import { Intent } from '@blueprintjs/core';
+import { Formik } from 'formik';
+import intl from 'react-intl-universal';
+
+import '../../../style/pages/TransactionsLocking/TransactionsLockingDialog.scss';
+
+import { AppToaster } from 'components';
+import { CreateUnlockingTransactionsFormSchema } from './UnlockingTransactionsForm.schema';
+
+import { useUnlockingTransactionsContext } from './UnlockingTransactionsFormProvider';
+import UnlockingTransactionsFormContent from './UnlockingTransactionsFormContent';
+
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import { compose } from 'utils';
+
+const defaultInitialValues = {
+ module: 'all',
+ reason: '',
+};
+
+/**
+ * Unlocking transactions form.
+ */
+function UnlockingTransactionsForm({
+ // #withDialogActions
+ closeDialog,
+}) {
+ const {
+ dialogName,
+ cancelLockingTransactionMutate,
+ cancelUnLockingPartialTransactionMutate,
+ } = useUnlockingTransactionsContext();
+
+ // Initial form values.
+ const initialValues = {
+ ...defaultInitialValues,
+ };
+
+ // Handles the form submit.
+ const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
+ setSubmitting(true);
+
+ // Handle request response success.
+ const onSuccess = (response) => {
+ AppToaster.show({
+ message: intl.get('unlocking_transactions.dialog.success_message'),
+ intent: Intent.SUCCESS,
+ });
+ closeDialog(dialogName);
+ };
+
+ // Handle request response errors.
+ const onError = ({
+ response: {
+ data: { errors },
+ },
+ }) => {
+ setSubmitting(false);
+ };
+
+ cancelLockingTransactionMutate(values).then(onSuccess).catch(onError);
+ };
+
+ return (
+
+ );
+}
+export default compose(withDialogActions)(UnlockingTransactionsForm);
diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsForm.schema.js b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsForm.schema.js
new file mode 100644
index 000000000..3208a4786
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsForm.schema.js
@@ -0,0 +1,13 @@
+import * as Yup from 'yup';
+import intl from 'react-intl-universal';
+import { DATATYPES_LENGTH } from 'common/dataTypes';
+
+const Schema = Yup.object().shape({
+ module: Yup.string().required(),
+ reason: Yup.string()
+ .required()
+ .min(3)
+ .max(DATATYPES_LENGTH.TEXT)
+ .label(intl.get('reason')),
+});
+export const CreateUnlockingTransactionsFormSchema = Schema;
diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormContent.js b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormContent.js
new file mode 100644
index 000000000..351723de2
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormContent.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import { Form } from 'formik';
+
+import UnlockingTransactionsFormFields from './UnlockingTransactionsFormFields';
+import UnlockingTransactionsFormFloatingActions from './UnlockingTransactionsFormFloatingActions';
+
+/**
+ * Unlocking transactions form content.
+ */
+export default function UnlockingTransactionsFormContent() {
+ return (
+
+ );
+}
diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormFields.js b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormFields.js
new file mode 100644
index 000000000..c97398333
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormFields.js
@@ -0,0 +1,34 @@
+import React from 'react';
+import { FastField, ErrorMessage } from 'formik';
+import { Classes, FormGroup, TextArea } from '@blueprintjs/core';
+import { FieldRequiredHint, FormattedMessage as T } from 'components';
+import { inputIntent } from 'utils';
+
+/**
+ * Unlocking transactions form fields.
+ */
+export default function UnlockingTransactionsFormFields() {
+ return (
+
+ {/*------------ Locking Reason -----------*/}
+
+ {({ field, meta: { error, touched } }) => (
+ }
+ labelInfo={}
+ className={'form-group--reason'}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ >
+
+
+ )}
+
+
+ );
+}
diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormFloatingActions.js b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormFloatingActions.js
new file mode 100644
index 000000000..a32c86efd
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormFloatingActions.js
@@ -0,0 +1,48 @@
+import React from 'react';
+import { Intent, Button, Classes } from '@blueprintjs/core';
+import { useFormikContext } from 'formik';
+import { FormattedMessage as T } from 'components';
+
+import { useUnlockingTransactionsContext } from './UnlockingTransactionsFormProvider';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import { compose } from 'utils';
+
+/**
+ * Unlocking transactions form floating actions.
+ */
+function UnlockingTransactionsFormFloatingActions({
+ // #withDialogActions
+ closeDialog,
+}) {
+ // Formik context.
+ const { isSubmitting } = useFormikContext();
+
+ const { dialogName } = useUnlockingTransactionsContext();
+
+ // Handle cancel button click.
+ const handleCancelBtnClick = (event) => {
+ closeDialog(dialogName);
+ };
+
+ return (
+
+ );
+}
+
+export default compose(withDialogActions)(
+ UnlockingTransactionsFormFloatingActions,
+);
diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormProvider.js b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormProvider.js
new file mode 100644
index 000000000..e64526478
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/UnlockingTransactionsFormProvider.js
@@ -0,0 +1,39 @@
+import React from 'react';
+import { DialogContent } from 'components';
+import {
+ useCancelLockingTransaction,
+ useCancelUnlockingPartialTransactions,
+} from 'hooks/query';
+
+const UnlockingTransactionsContext = React.createContext();
+
+/**
+ * Unlocking transactions form provider.
+ */
+function UnlockingTransactionsFormProvider({ dialogName, ...props }) {
+ // Cancle locking transactions mutations.
+ const { mutateAsync: cancelLockingTransactionMutate } =
+ useCancelLockingTransaction();
+
+ // Cancel unlocking partial transactions mutations.
+ const { mutateAsync: cancelUnLockingPartialTransactionMutate } =
+ useCancelUnlockingPartialTransactions();
+
+ // State provider.
+ const provider = {
+ dialogName,
+ cancelLockingTransactionMutate,
+ cancelUnLockingPartialTransactionMutate,
+ };
+
+ return (
+
+
+
+ );
+}
+
+const useUnlockingTransactionsContext = () =>
+ React.useContext(UnlockingTransactionsContext);
+
+export { useUnlockingTransactionsContext, UnlockingTransactionsFormProvider };
diff --git a/src/containers/Dialogs/UnlockingTransactionsDialog/index.js b/src/containers/Dialogs/UnlockingTransactionsDialog/index.js
new file mode 100644
index 000000000..9c400de06
--- /dev/null
+++ b/src/containers/Dialogs/UnlockingTransactionsDialog/index.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import { Dialog, DialogSuspense, FormattedMessage as T } from 'components';
+import withDialogRedux from 'components/DialogReduxConnect';
+import { compose } from 'utils';
+
+const UnlockingTransactionsDialogContent = React.lazy(() =>
+ import('./UnlockingTransactionsDialogContent'),
+);
+
+/**
+ * Unlocking transactions dialog.
+ */
+function UnlockingTransactionsDialog({ dialogName, payload = {}, isOpen }) {
+ return (
+ }
+ canEscapeKeyClose={true}
+ isOpen={isOpen}
+ className={'dialog--transaction--locking'}
+ >
+
+
+
+
+ );
+}
+
+export default compose(withDialogRedux())(UnlockingTransactionsDialog);