mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
feat: SMS notification module.
This commit is contained in:
@@ -11,6 +11,11 @@ import { transformErrors } from '../../../containers/NotifyViaSMS/utils';
|
|||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const notificationType = {
|
||||||
|
key: 'sale-estimate-details',
|
||||||
|
label: 'Sale estimate details',
|
||||||
|
};
|
||||||
|
|
||||||
function NotifyEstimateViaSMSForm({
|
function NotifyEstimateViaSMSForm({
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
closeDialog,
|
closeDialog,
|
||||||
@@ -51,10 +56,19 @@ function NotifyEstimateViaSMSForm({
|
|||||||
.catch(onError);
|
.catch(onError);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
...estimateSMSDetail,
|
||||||
|
};
|
||||||
|
// Handle the form cancel.
|
||||||
|
const handleFormCancel = () => {
|
||||||
|
closeDialog(dialogName);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotifyViaSMSForm
|
<NotifyViaSMSForm
|
||||||
NotificationDetail={estimateSMSDetail}
|
initialValues={initialValues}
|
||||||
NotificationName={dialogName}
|
notificationTypes={notificationType}
|
||||||
|
onCancel={handleFormCancel}
|
||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -80,10 +80,19 @@ function NotifyInvoiceViaSMSForm({
|
|||||||
setNotificationType(values.notification_key);
|
setNotificationType(values.notification_key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Momerize the notification types.
|
||||||
|
const notificationTypes = React.useMemo(
|
||||||
|
() => [
|
||||||
|
{ key: 'details', label: 'Invoice details' },
|
||||||
|
{ key: 'reminder', label: 'Invoice reminder' },
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotifyViaSMSForm
|
<NotifyViaSMSForm
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
|
notificationTypes={notificationTypes}
|
||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
onCancel={handleFormCancel}
|
onCancel={handleFormCancel}
|
||||||
onValuesChange={handleValuesChange}
|
onValuesChange={handleValuesChange}
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import { transformErrors } from '../../../containers/NotifyViaSMS/utils';
|
|||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const notificationType = {
|
||||||
|
key: 'payment-receive-details',
|
||||||
|
label: 'Payment receive thank you.',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify Payment Recive Via SMS Form.
|
* Notify Payment Recive Via SMS Form.
|
||||||
*/
|
*/
|
||||||
@@ -53,12 +58,23 @@ function NotifyPaymentReceiveViaSMSForm({
|
|||||||
.then(onSuccess)
|
.then(onSuccess)
|
||||||
.catch(onError);
|
.catch(onError);
|
||||||
};
|
};
|
||||||
|
// Handle the form cancel.
|
||||||
|
const handleFormCancel = () => {
|
||||||
|
closeDialog(dialogName);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Form initial values.
|
||||||
|
const initialValues = React.useMemo(
|
||||||
|
() => ({ ...paymentReceiveMSDetail }),
|
||||||
|
[paymentReceiveMSDetail],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotifyViaSMSForm
|
<NotifyViaSMSForm
|
||||||
NotificationDetail={paymentReceiveMSDetail}
|
initialValues={initialValues}
|
||||||
NotificationName={dialogName}
|
notificationTypes={notificationType}
|
||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
|
onCancel={handleFormCancel}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import { transformErrors } from '../../../containers/NotifyViaSMS/utils';
|
|||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const notificationType = {
|
||||||
|
key: 'sale-receipt-details',
|
||||||
|
label: 'Sale receipt details',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify Receipt Via SMS Form.
|
* Notify Receipt Via SMS Form.
|
||||||
*/
|
*/
|
||||||
@@ -51,12 +56,24 @@ function NotifyReceiptViaSMSForm({
|
|||||||
.then(onSuccess)
|
.then(onSuccess)
|
||||||
.catch(onError);
|
.catch(onError);
|
||||||
};
|
};
|
||||||
|
// Handle the form cancel.
|
||||||
|
const handleFormCancel = () => {
|
||||||
|
closeDialog(dialogName);
|
||||||
|
};
|
||||||
|
// Initial values.
|
||||||
|
const initialValues = React.useMemo(
|
||||||
|
() => ({
|
||||||
|
...receiptSMSDetail,
|
||||||
|
}),
|
||||||
|
[receiptSMSDetail],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotifyViaSMSForm
|
<NotifyViaSMSForm
|
||||||
NotificationDetail={receiptSMSDetail}
|
initialValues={initialValues}
|
||||||
NotificationName={dialogName}
|
notificationTypes={notificationType}
|
||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
|
onCancel={handleFormCancel}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,15 @@ import { useCreateNotifyReceiptBySMS, useReceiptSMSDetail } from 'hooks/query';
|
|||||||
|
|
||||||
const NotifyReceiptViaSMSContext = React.createContext();
|
const NotifyReceiptViaSMSContext = React.createContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
function NotifyReceiptViaSMSFormProvider({ receiptId, dialogName, ...props }) {
|
function NotifyReceiptViaSMSFormProvider({ receiptId, dialogName, ...props }) {
|
||||||
// Create notfiy receipt via sms mutations.
|
// Create notfiy receipt via SMS mutations.
|
||||||
const { mutateAsync: createNotifyReceiptBySMSMutate } =
|
const { mutateAsync: createNotifyReceiptBySMSMutate } =
|
||||||
useCreateNotifyReceiptBySMS();
|
useCreateNotifyReceiptBySMS();
|
||||||
|
|
||||||
|
// Retrieve the receipt SMS notification details.
|
||||||
const { data: receiptSMSDetail, isLoading: isReceiptSMSDetailLoading } =
|
const { data: receiptSMSDetail, isLoading: isReceiptSMSDetailLoading } =
|
||||||
useReceiptSMSDetail(receiptId, {
|
useReceiptSMSDetail(receiptId, {
|
||||||
enabled: !!receiptId,
|
enabled: !!receiptId,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { castArray } from 'lodash';
|
||||||
import { Formik, Form, useFormikContext } from 'formik';
|
import { Formik, Form, useFormikContext } from 'formik';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Classes } from '@blueprintjs/core';
|
import { Classes } from '@blueprintjs/core';
|
||||||
@@ -34,7 +35,6 @@ function SMSMessagePreviewSection() {
|
|||||||
return (
|
return (
|
||||||
<SMSPreviewSectionRoot>
|
<SMSPreviewSectionRoot>
|
||||||
<SMSMessagePreview message={sms_message} />
|
<SMSMessagePreview message={sms_message} />
|
||||||
|
|
||||||
<SMSPreviewSectionNote>
|
<SMSPreviewSectionNote>
|
||||||
<strong>Note</strong>: Note: One SMS unit can contain a maximum of 160
|
<strong>Note</strong>: Note: One SMS unit can contain a maximum of 160
|
||||||
characters. <strong>{messagesUnits}</strong> SMS units will be used to
|
characters. <strong>{messagesUnits}</strong> SMS units will be used to
|
||||||
@@ -49,6 +49,7 @@ function SMSMessagePreviewSection() {
|
|||||||
*/
|
*/
|
||||||
function NotifyViaSMSForm({
|
function NotifyViaSMSForm({
|
||||||
initialValues: initialValuesComponent,
|
initialValues: initialValuesComponent,
|
||||||
|
notificationTypes,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
onValuesChange,
|
onValuesChange,
|
||||||
@@ -58,6 +59,11 @@ function NotifyViaSMSForm({
|
|||||||
...defaultInitialValues,
|
...defaultInitialValues,
|
||||||
...transformToForm(initialValuesComponent, defaultInitialValues),
|
...transformToForm(initialValuesComponent, defaultInitialValues),
|
||||||
};
|
};
|
||||||
|
// Ensure always returns array.
|
||||||
|
const formattedNotificationTypes = React.useMemo(
|
||||||
|
() => castArray(notificationTypes),
|
||||||
|
[notificationTypes],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
@@ -69,8 +75,11 @@ function NotifyViaSMSForm({
|
|||||||
<div className={Classes.DIALOG_BODY}>
|
<div className={Classes.DIALOG_BODY}>
|
||||||
<NotifyContent>
|
<NotifyContent>
|
||||||
<NotifyFieldsSection>
|
<NotifyFieldsSection>
|
||||||
<NotifyViaSMSFormFields />
|
<NotifyViaSMSFormFields
|
||||||
|
notificationTypes={formattedNotificationTypes}
|
||||||
|
/>
|
||||||
</NotifyFieldsSection>
|
</NotifyFieldsSection>
|
||||||
|
|
||||||
<SMSMessagePreviewSection />
|
<SMSMessagePreviewSection />
|
||||||
</NotifyContent>
|
</NotifyContent>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { FastField, ErrorMessage } from 'formik';
|
import { FastField, ErrorMessage } from 'formik';
|
||||||
import { FormGroup, InputGroup } from '@blueprintjs/core';
|
import { FormGroup, InputGroup } from '@blueprintjs/core';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ListSelect,
|
ListSelect,
|
||||||
@@ -11,14 +12,9 @@ import {
|
|||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
import { inputIntent } from 'utils';
|
import { inputIntent } from 'utils';
|
||||||
|
|
||||||
const notificationTypes = [
|
export default function NotifyViaSMSFormFields({ notificationTypes }) {
|
||||||
{ key: 'details', label: 'Invoice details' },
|
|
||||||
{ key: 'reminder', label: 'Invoice reminder' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function NotifyViaSMSFormFields() {
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<NotifyViaSMSFormFieldsRoot>
|
||||||
<FastField name={'notification_key'}>
|
<FastField name={'notification_key'}>
|
||||||
{({ form, meta: { error, touched } }) => (
|
{({ form, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
@@ -37,6 +33,7 @@ export default function NotifyViaSMSFormFields() {
|
|||||||
onItemSelect={(notification) => {
|
onItemSelect={(notification) => {
|
||||||
form.setFieldValue('notification_key', notification.key);
|
form.setFieldValue('notification_key', notification.key);
|
||||||
}}
|
}}
|
||||||
|
disabled={notificationTypes.length < 2}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
@@ -82,6 +79,8 @@ export default function NotifyViaSMSFormFields() {
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
</div>
|
</NotifyViaSMSFormFieldsRoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NotifyViaSMSFormFieldsRoot = styled.div``;
|
||||||
|
|||||||
@@ -190,6 +190,9 @@ export function useRefreshEstimates() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
export function useCreateNotifyEstimateBySMS(props) {
|
export function useCreateNotifyEstimateBySMS(props) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
@@ -210,6 +213,13 @@ export function useCreateNotifyEstimateBySMS(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} estimateId
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} requestProps
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function useEstimateSMSDetail(estimateId, props, requestProps) {
|
export function useEstimateSMSDetail(estimateId, props, requestProps) {
|
||||||
return useRequestQuery(
|
return useRequestQuery(
|
||||||
[t.SALE_ESTIMATE_SMS_DETAIL, estimateId],
|
[t.SALE_ESTIMATE_SMS_DETAIL, estimateId],
|
||||||
|
|||||||
@@ -170,8 +170,12 @@ export function useSettingEditSMSNotification(props) {
|
|||||||
(values) => apiRequest.post(`settings/sms-notification`, values),
|
(values) => apiRequest.post(`settings/sms-notification`, values),
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
// Invalidate
|
|
||||||
queryClient.invalidateQueries([t.SETTING_SMS_NOTIFICATIONS]);
|
queryClient.invalidateQueries([t.SETTING_SMS_NOTIFICATIONS]);
|
||||||
|
|
||||||
|
queryClient.invalidateQueries(t.SALE_INVOICE_SMS_DETAIL);
|
||||||
|
queryClient.invalidateQueries(t.SALE_RECEIPT_SMS_DETAIL);
|
||||||
|
queryClient.invalidateQueries(t.PAYMENT_RECEIVE_SMS_DETAIL);
|
||||||
|
queryClient.invalidateQueries(t.SALE_ESTIMATE_SMS_DETAIL);
|
||||||
},
|
},
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user