feat: Optimize SMS notification module.

This commit is contained in:
a.bouhuolia
2021-11-09 09:51:38 +02:00
parent 6d67d6163d
commit 48221a7af1
24 changed files with 479 additions and 141 deletions

View File

@@ -50,10 +50,12 @@ export default function DialogsContainer() {
<ReceiptPdfPreviewDialog dialogName={'receipt-pdf-preview'} />
<MoneyInDialog dialogName={'money-in'} />
<MoneyOutDialog dialogName={'money-out'} />
<NotifyInvoiceViaSMSDialog dialogName={'notify-invoice-via-sms'} />
<NotifyReceiptViaSMSDialog dialogName={'notify-receipt-via-sms'} />
<NotifyEstimateViaSMSDialog dialogName={'notify-estimate-via-sms'} />
<NotifyPaymentReceiveViaSMSDialog dialogName={'notify-payment-via-sms'} />
<BadDebtDialog dialogName={'write-off-bad-debt'} />
<SMSMessageDialog dialogName={'sms-message-form'} />
</div>

View File

@@ -0,0 +1,46 @@
import React from 'react';
import styled from 'styled-components';
import { Icon } from 'components';
/**
* SMS Message preview.
*/
export function SMSMessagePreview({
message,
iconWidth = '265px',
iconHeight = '287px',
iconColor = '#adadad',
}) {
return (
<SMSMessagePreviewBase>
<Icon
icon={'sms-message-preview'}
width={iconWidth}
height={iconHeight}
color={iconColor}
/>
<SMSMessageText>{message}</SMSMessageText>
</SMSMessagePreviewBase>
);
}
const SMSMessageText = styled.div`
position: absolute;
top: 61px;
padding: 12px;
color: #fff;
border-radius: 12px;
margin-left: 12px;
margin-right: 12px;
overflow-wrap: break-word;
background: #2fa2e4;
font-size: 13px;
line-height: 1.6;
`;
const SMSMessagePreviewBase = styled.div`
position: relative;
width: 265px;
margin: 0 auto;
`;

View File

@@ -87,6 +87,7 @@ export * from './IntersectionObserver';
export * from './Datatable/CellForceWidth';
export * from './Button';
export * from './IntersectionObserver';
export * from './SMSPreview';
const Hint = FieldHint;

View File

@@ -24,6 +24,8 @@ function NotifyEstimateViaSMSForm({
// Handles the form submit.
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
setSubmitting(true);
// Handle request response success.
const onSuccess = (response) => {
AppToaster.show({
@@ -31,8 +33,8 @@ function NotifyEstimateViaSMSForm({
intent: Intent.SUCCESS,
});
closeDialog(dialogName);
setSubmitting(false);
};
// Handle request response errors.
const onError = ({
response: {
@@ -40,6 +42,7 @@ function NotifyEstimateViaSMSForm({
},
}) => {
transformErrors(errors);
setSubmitting(false);
};
createNotifyEstimateBySMSMutate([estimateId, values])
.then(onSuccess)

View File

@@ -11,6 +11,12 @@ import { transformErrors } from '../../../containers/NotifyViaSMS/utils';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
const transformFormValuesToRequest = (values) => {
return {
notification_type: values.notification_key,
};
};
/**
* Notify Invoice Via SMS Form.
*/
@@ -23,16 +29,21 @@ function NotifyInvoiceViaSMSForm({
invoiceId,
invoiceSMSDetail,
dialogName,
notificationType,
setNotificationType,
} = useNotifyInvoiceViaSMSContext();
// Handles the form submit.
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
setSubmitting(true);
// Handle request response success.
const onSuccess = (response) => {
AppToaster.show({
message: intl.get('notify_via_sms.dialog.success_message'),
intent: Intent.SUCCESS,
});
setSubmitting(false);
closeDialog(dialogName);
};
@@ -43,17 +54,37 @@ function NotifyInvoiceViaSMSForm({
},
}) => {
transformErrors(errors);
setSubmitting(false);
};
createNotifyInvoiceBySMSMutate([invoiceId, values])
// Transformes the form values to request.
const requestValues = transformFormValuesToRequest(values);
createNotifyInvoiceBySMSMutate([invoiceId, requestValues])
.then(onSuccess)
.catch(onError);
};
// Handle the form cancel.
const handleFormCancel = React.useCallback(() => {
closeDialog(dialogName);
}, [closeDialog, dialogName]);
const initialValues = {
notification_key: notificationType,
...invoiceSMSDetail,
};
const handleValuesChange = (values) => {
if (values.notification_key !== notificationType) {
setNotificationType(values.notification_key);
}
};
return (
<NotifyViaSMSForm
NotificationDetail={invoiceSMSDetail}
NotificationName={dialogName}
initialValues={initialValues}
onSubmit={handleFormSubmit}
onCancel={handleFormCancel}
onValuesChange={handleValuesChange}
/>
);
}

View File

@@ -5,11 +5,19 @@ import { useCreateNotifyInvoiceBySMS, useInvoiceSMSDetail } from 'hooks/query';
const NotifyInvoiceViaSMSContext = React.createContext();
function NotifyInvoiceViaSMSFormProvider({ invoiceId, dialogName, ...props }) {
const { data: invoiceSMSDetail, isLoading: isInvoiceSMSDetailLoading } =
useInvoiceSMSDetail(invoiceId, {
enabled: !!invoiceId,
});
const [notificationType, setNotificationType] = React.useState('details');
// Retrieve the invoice sms notification message details.
const { data: invoiceSMSDetail, isLoading: isInvoiceSMSDetailLoading } =
useInvoiceSMSDetail(
invoiceId,
{
notification_type: notificationType,
},
{
enabled: !!invoiceId,
},
);
// Create notfiy invoice by sms mutations.
const { mutateAsync: createNotifyInvoiceBySMSMutate } =
useCreateNotifyInvoiceBySMS();
@@ -20,6 +28,9 @@ function NotifyInvoiceViaSMSFormProvider({ invoiceId, dialogName, ...props }) {
invoiceSMSDetail,
dialogName,
createNotifyInvoiceBySMSMutate,
notificationType,
setNotificationType,
};
return (

View File

@@ -32,4 +32,5 @@ function NotifyInvoiceViaSMSDialog({
</Dialog>
);
}
export default compose(withDialogRedux())(NotifyInvoiceViaSMSDialog);

View File

@@ -44,7 +44,6 @@ function SMSMessageForm({
...omit(values, ['is_notification_enabled', 'sms_message']),
notification_key: smsNotification.key,
};
// Handle request response success.
const onSuccess = (response) => {
AppToaster.show({
@@ -53,7 +52,6 @@ function SMSMessageForm({
});
closeDialog(dialogName);
};
// Handle request response errors.
const onError = ({
response: {
@@ -62,7 +60,7 @@ function SMSMessageForm({
}) => {
setSubmitting(false);
};
debugger;
editSMSNotificationMutate(form).then(onSuccess).catch(onError);
};

View File

@@ -1,17 +1,103 @@
import React from 'react';
import { Form } from 'formik';
import { Form, useFormikContext } from 'formik';
import styled from 'styled-components';
import { Classes } from '@blueprintjs/core';
import SMSMessageFormFields from './SMSMessageFormFields';
import SMSMessageFormFloatingActions from './SMSMessageFormFloatingActions';
import { SMSMessagePreview } from 'components';
import { getSMSUnits } from '../../NotifyViaSMS/utils';
const messageVariables = [
{
variable: '{CompanyName}',
description: 'References to the current company name.',
},
];
/**
* SMS message form content.
*/
export default function SMSMessageFormContent() {
return (
<Form>
<SMSMessageFormFields />
<div className={Classes.DIALOG_BODY}>
<FormContent>
<FormFields>
<SMSMessageFormFields />
<SMSMessageVariables>
{messageVariables.map(({ variable, description }) => (
<MessageVariable>
<strong>{variable}</strong> {description}
</MessageVariable>
))}
</SMSMessageVariables>
</FormFields>
<FormPreview>
<SMSMessagePreviewSection />
</FormPreview>
</FormContent>
</div>
<SMSMessageFormFloatingActions />
</Form>
);
}
/**
* SMS Message preview section.
* @returns {JSX}
*/
function SMSMessagePreviewSection() {
const {
values: { message_text: message },
} = useFormikContext();
const messagesUnits = getSMSUnits(message);
return (
<SMSPreviewSectionRoot>
<SMSMessagePreview message={message} />
<SMSPreviewSectionNote>
<strong>Note</strong>: Note: One SMS unit can contain a maximum of 160
characters. <strong>{messagesUnits}</strong> SMS units will be used to
send this SMS notification.
</SMSPreviewSectionNote>
</SMSPreviewSectionRoot>
);
}
const SMSPreviewSectionRoot = styled.div``;
const SMSPreviewSectionNote = styled.div`
font-size: 12px;
opacity: 0.7;
`;
const SMSMessageVariables = styled.div`
list-style: none;
font-size: 12px;
opacity: 0.9;
`;
const MessageVariable = styled.div`
margin-bottom: 8px;
`;
const FormContent = styled.div`
display: flex;
`;
const FormFields = styled.div`
width: 55%;
`;
const FormPreview = styled.div`
display: flex;
flex-direction: column;
width: 45%;
padding-left: 25px;
margin-left: 25px;
border-left: 1px solid #dcdcdd;
`;

View File

@@ -7,7 +7,7 @@ import { inputIntent } from 'utils';
export default function SMSMessageFormFields() {
return (
<div className={Classes.DIALOG_BODY}>
<div>
{/* ----------- Message Text ----------- */}
<FastField name={'message_text'}>
{({ field, meta: { error, touched } }) => (

View File

@@ -1,6 +1,8 @@
import React from 'react';
import { Intent, Button, Classes } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import { useSMSMessageDialogContext } from './SMSMessageDialogProvider';
@@ -27,7 +29,7 @@ function SMSMessageFormFloatingActions({
return (
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<FooterActions className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button onClick={handleCancelBtnClick} style={{ minWidth: '75px' }}>
<T id={'cancel'} />
</Button>
@@ -37,11 +39,15 @@ function SMSMessageFormFloatingActions({
style={{ minWidth: '75px' }}
type="submit"
>
{<T id={'save'} />}
Save SMS Message
</Button>
</div>
</FooterActions>
</div>
);
}
export default compose(withDialogActions)(SMSMessageFormFloatingActions);
const FooterActions = styled.div`
justify-content: flex-start;
`;

View File

@@ -1,28 +1,62 @@
import React from 'react';
import { Formik, Form } from 'formik';
import { Formik, Form, useFormikContext } from 'formik';
import styled from 'styled-components';
import { Classes } from '@blueprintjs/core';
import 'style/pages/NotifyConactViaSMS/NotifyConactViaSMSDialog.scss';
import { CreateNotifyViaSMSFormSchema } from './NotifyViaSMSForm.schema';
import NotifyViaSMSFormFields from './NotifyViaSMSFormFields';
import NotifyViaSMSFormFloatingActions from './NotifyViaSMSFormFloatingActions';
import { FormObserver, SMSMessagePreview } from 'components';
import { transformToForm, saveInvoke } from 'utils';
import { transformToForm, safeInvoke } from 'utils';
import { getSMSUnits } from './utils';
const defaultInitialValues = {
notification_key: '',
customer_name: '',
customer_phone_number: '',
sms_message: '',
};
/**
* Notify via sms - SMS message preview section.
*/
function SMSMessagePreviewSection() {
const {
values: { sms_message },
} = useFormikContext();
// Calculates the SMS units of message.
const messagesUnits = getSMSUnits(sms_message);
return (
<SMSPreviewSectionRoot>
<SMSMessagePreview message={sms_message} />
<SMSPreviewSectionNote>
<strong>Note</strong>: Note: One SMS unit can contain a maximum of 160
characters. <strong>{messagesUnits}</strong> SMS units will be used to
send this SMS notification.
</SMSPreviewSectionNote>
</SMSPreviewSectionRoot>
);
}
/**
* Notify Via SMS Form.
*/
function NotifyViaSMSForm({ onSubmit, NotificationDetail, NotificationName }) {
function NotifyViaSMSForm({
initialValues: initialValuesComponent,
onSubmit,
onCancel,
onValuesChange,
}) {
// Initial form values
const initialValues = {
...defaultInitialValues,
...transformToForm(NotificationDetail, defaultInitialValues),
...transformToForm(initialValuesComponent, defaultInitialValues),
};
return (
@@ -32,11 +66,56 @@ function NotifyViaSMSForm({ onSubmit, NotificationDetail, NotificationName }) {
onSubmit={onSubmit}
>
<Form>
<NotifyViaSMSFormFields />
<NotifyViaSMSFormFloatingActions dialogName={NotificationName} />
<div className={Classes.DIALOG_BODY}>
<NotifyContent>
<NotifyFieldsSection>
<NotifyViaSMSFormFields />
</NotifyFieldsSection>
<SMSMessagePreviewSection />
</NotifyContent>
</div>
<NotifyViaSMSFormFloatingActions onCancel={onCancel} />
<NotifyObserveValuesChange onChange={onValuesChange} />
</Form>
</Formik>
);
}
/**
* Observes the values change of notify form.
*/
function NotifyObserveValuesChange({ onChange }) {
const { values } = useFormikContext();
// Handle the form change observe.
const handleChange = () => {
safeInvoke(onChange, values);
};
return <FormObserver values={values} onChange={handleChange} />;
}
export default NotifyViaSMSForm;
const NotifyContent = styled.div`
display: flex;
`;
const NotifyFieldsSection = styled.div`
flex: 1;
width: 65%;
`;
const SMSPreviewSectionRoot = styled.div`
display: flex;
flex-direction: column;
width: 45%;
padding-left: 25px;
margin-left: 25px;
border-left: 1px solid #dcdcdd;
`;
const SMSPreviewSectionNote = styled.div`
font-size: 12px;
opacity: 0.7;
`;

View File

@@ -1,16 +1,47 @@
import React from 'react';
import { FastField, ErrorMessage } from 'formik';
import { FormattedMessage as T } from 'components';
import { Classes, FormGroup, TextArea, InputGroup } from '@blueprintjs/core';
import { FormGroup, InputGroup } from '@blueprintjs/core';
import classNames from 'classnames';
import {
ListSelect,
FieldRequiredHint,
FormattedMessage as T,
} from 'components';
import { CLASSES } from 'common/classes';
import { inputIntent } from 'utils';
import { FieldRequiredHint } from 'components';
function NotifyViaSMSFormFields() {
const notificationTypes = [
{ key: 'details', label: 'Invoice details' },
{ key: 'reminder', label: 'Invoice reminder' },
];
export default function NotifyViaSMSFormFields() {
return (
<div className={Classes.DIALOG_BODY}>
<div>
<FastField name={'notification_key'}>
{({ form, meta: { error, touched } }) => (
<FormGroup
label={'Notification type'}
className={classNames(CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'customer_name'} />}
>
<ListSelect
items={notificationTypes}
selectedItemProp={'key'}
selectedItem={'details'}
textProp={'label'}
popoverProps={{ minimal: true }}
filterable={false}
onItemSelect={(notification) => {
form.setFieldValue('notification_key', notification.key);
}}
/>
</FormGroup>
)}
</FastField>
{/* ----------- Send Notification to ----------- */}
<FastField name={'customer_name'}>
{({ form, field, meta: { error, touched } }) => (
@@ -51,29 +82,6 @@ function NotifyViaSMSFormFields() {
</FormGroup>
)}
</FastField>
{/* ----------- Message Text ----------- */}
<FastField name={'sms_message'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'notify_via_sms.dialog.message_text'} />}
labelInfo={<FieldRequiredHint />}
className={'form-group--sms_message'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'sms_message'} />}
>
<TextArea
growVertically={true}
large={true}
disabled={true}
intent={inputIntent({ error, touched })}
{...field}
/>
</FormGroup>
)}
</FastField>
</div>
);
}
export default NotifyViaSMSFormFields;

View File

@@ -1,41 +1,47 @@
import React from 'react';
import { useFormikContext } from 'formik';
import { Intent, Button, Classes } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
import { safeCallback } from 'utils';
function NotifyViaSMSFormFloatingActions({
// #withDialogActions
closeDialog,
dialogName,
}) {
/**
*
*/
export default function NotifyViaSMSFormFloatingActions({ onCancel }) {
// Formik context.
const { isSubmitting } = useFormikContext();
// Handle close button click.
const handleCancelBtnClick = () => {
closeDialog(dialogName);
const handleCancelBtnClick = (event) => {
onCancel && onCancel(event);
};
return (
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button onClick={handleCancelBtnClick} style={{ minWidth: '75px' }}>
<T id={'cancel'} />
</Button>
<FooterActions className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button
intent={Intent.PRIMARY}
loading={isSubmitting}
style={{ minWidth: '75px' }}
style={{ minWidth: '110px' }}
type="submit"
>
{<T id={'send'} />}
Send SMS
</Button>
</div>
<Button
disabled={isSubmitting}
onClick={handleCancelBtnClick}
style={{ minWidth: '75px' }}
>
<T id={'cancel'} />
</Button>
</FooterActions>
</div>
);
}
export default compose(withDialogActions)(NotifyViaSMSFormFloatingActions);
const FooterActions = styled.div`
justify-content: flex-start;
`;

View File

@@ -10,3 +10,8 @@ export const transformErrors = (errors) => {
});
}
};
export const getSMSUnits = (message, threshold = 140) => {
return Math.ceil(message.length / threshold);
};

View File

@@ -1,5 +1,7 @@
import React from 'react';
import { DataTableEditable, DataTable } from 'components';
import styled from 'styled-components';
import { DataTable } from 'components';
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
import { useSMSIntegrationTableColumns } from './components';
@@ -23,7 +25,7 @@ function SMSMessagesDataTable({
};
return (
<DataTable
<SMSNotificationsTable
columns={columns}
data={notifications}
loading={isSMSNotificationsLoading}
@@ -38,3 +40,12 @@ function SMSMessagesDataTable({
}
export default compose(withDialogActions)(SMSMessagesDataTable);
const SMSNotificationsTable = styled(DataTable)`
.table .tbody .tr .td {
align-items: flex-start;
}
.table .tbody .td {
padding: 0.8rem;
}
`;

View File

@@ -1,7 +1,10 @@
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import { ButtonLink } from 'components';
import { SwitchFieldCell } from 'components/DataTableCells';
import { safeCallback } from 'utils';
import { safeInvoke } from 'utils';
/**
* Notification accessor.
@@ -9,59 +12,95 @@ import { safeCallback } from 'utils';
export const NotificationAccessor = (row) => {
return (
<span className="notification">
<span className={'notification__label'}>{row.notification_label}</span>
<span className={'notification__desc'}>
<NotificationLabel>{row.notification_label}</NotificationLabel>
<NotificationDescription>
{row.notification_description}
</span>
</NotificationDescription>
</span>
);
};
/**
* SMS notification message cell.
*/
export const SMSMessageCell = ({
payload: { onEditSMSMessage },
row: { original },
}) => (
<div>
{original.sms_message}
<span
className="edit-text"
onClick={safeCallback(onEditSMSMessage, original)}
>
{'Edit'}
</span>
<MessageBox>{original.sms_message}</MessageBox>
<MessageBoxActions>
<ButtonLink onClick={() => safeInvoke(onEditSMSMessage, original)}>
Edit message
</ButtonLink>
</MessageBoxActions>
</div>
);
/**
* Retrieve SMS notifications messages table columns
* @returns
*/
export function useSMSIntegrationTableColumns() {
return React.useMemo(() => [
{
Header: intl.get('sms_message.label_Notification'),
accessor: NotificationAccessor,
className: 'notification',
width: '180',
},
{
Header: intl.get('service'),
accessor: 'module_formatted',
className: 'service',
width: '80',
},
{
Header: intl.get('sms_message.label_mesage'),
accessor: 'sms_message',
Cell: SMSMessageCell,
className: 'sms_message',
clickable: true,
width: '180',
},
{
Header: intl.get('sms_message.label_auto'),
accessor: 'is_notification_enabled',
Cell: SwitchFieldCell,
className: 'is_notification_enabled',
disableSortBy: true,
disableResizing: true,
width: '80',
},
]);
return React.useMemo(
() => [
{
Header: intl.get('sms_message.label_Notification'),
accessor: NotificationAccessor,
className: 'notification',
width: '180',
},
{
Header: intl.get('service'),
accessor: 'module_formatted',
className: 'service',
width: '80',
},
{
Header: intl.get('sms_message.label_mesage'),
accessor: 'sms_message',
Cell: SMSMessageCell,
className: 'sms_message',
clickable: true,
width: '180',
},
{
Header: intl.get('sms_message.label_auto'),
accessor: 'is_notification_enabled',
Cell: SwitchFieldCell,
className: 'is_notification_enabled',
disableSortBy: true,
disableResizing: true,
width: '80',
},
],
[],
);
}
const NotificationLabel = styled.div`
font-weight: 500;
`;
const NotificationDescription = styled.div`
font-size: 14px;
margin-top: 6px;
display: block;
opacity: 0.75;
`;
const MessageBox = styled.div`
padding: 10px;
background-color: #fbfbfb;
border: 1px dashed #dcdcdc;
font-size: 14px;
line-height: 1.45;
`;
const MessageBoxActions = styled.div`
margin-top: 2px;
button {
font-size: 12px;
}
`;

View File

@@ -254,13 +254,13 @@ export function useCreateNotifyInvoiceBySMS(props) {
);
}
export function useInvoiceSMSDetail(invoiceId, props, requestProps) {
export function useInvoiceSMSDetail(invoiceId, query, props) {
return useRequestQuery(
[t.SALE_INVOICE_SMS_DETAIL, invoiceId],
[t.SALE_INVOICE_SMS_DETAIL, invoiceId, query],
{
method: 'get',
url: `sales/invoices/${invoiceId}/sms-details`,
...requestProps,
params: query,
},
{
select: (res) => res.data.data,

View File

@@ -1427,23 +1427,23 @@
"bad_debt.dialog.success_message": "The given sale invoice has been writte-off successfully.",
"bad_debt.cancel_alert.success_message": "The given sale invoice has been canceled write-off successfully.",
"bad_debt.cancel_alert.message": "Are you sure you want to write off this invoice?",
"notify_via_sms.dialog.send_notification_to":"Send notification to",
"notify_via_sms.dialog.message_text":"Message Text",
"notify_via_sms.dialog.notify_via_sms":"Notify vis SMS",
"notify_via_sms.dialog.error_message":"Sms notification cannot be sent, customer personal phone number is invalid, please enter a valid one and try again.",
"notify_invoice_via_sms.dialog.success_message":"The sale invoice sms notification has been sent successfully",
"notify_estimate_via_sms.dialog.success_message":"The sale estimate sms notification has been sent successfully",
"notify_receipt_via_sms.dialog.success_message":"The sale receipt sms notification has been sent successfully",
"notify_payment_receive_via_sms.dialog.success_message":"The payment notification has been sent successfully.",
"notify_via_sms.dialog.send_notification_to": "Send notification to",
"notify_via_sms.dialog.message_text": "Message Text",
"notify_via_sms.dialog.notify_via_sms": "Notify vis SMS",
"notify_via_sms.dialog.success_message": "SMS notification has been sent successfully.",
"notify_via_sms.dialog.error_message": "Sms notification cannot be sent, customer personal phone number is invalid, please enter a valid one and try again.",
"notify_invoice_via_sms.dialog.success_message": "The sale invoice sms notification has been sent successfully",
"notify_estimate_via_sms.dialog.success_message": "The sale estimate sms notification has been sent successfully",
"notify_receipt_via_sms.dialog.success_message": "The sale receipt sms notification has been sent successfully",
"notify_payment_receive_via_sms.dialog.success_message": "The payment notification has been sent successfully.",
"send": "Send",
"sms_integration.label":"SMS Integration",
"sms_integration.label.overview":"Overview",
"sms_integration.label.sms_messages":"SMS Messages",
"sms_message.label.sms_messages_template":"SMS Notifications ",
"sms_message.label_mesage":"Message",
"sms_message.label_Notification":"Notification",
"sms_message.label_auto":"Auto",
"sms_message":"SMS message",
"sms_message.dialog.success_message":"Sms notification settings has been updated successfully."
}
"sms_integration.label": "SMS Integration",
"sms_integration.label.overview": "Overview",
"sms_integration.label.sms_messages": "SMS Messages",
"sms_message.label.sms_messages_template": "SMS Notifications ",
"sms_message.label_mesage": "Message",
"sms_message.label_Notification": "Notification",
"sms_message.label_auto": "Auto",
"sms_message": "SMS message",
"sms_message.dialog.success_message": "Sms notification settings has been updated successfully."
}

View File

@@ -509,4 +509,11 @@ export default {
],
viewBox: '0 0 24 24',
},
"sms-message-preview": {
path: [
'M8.341,375.3573H399.3271v-.0015l-390.9861-.07ZM363.2382,0H44.43A44.4508,44.4508,0,0,0,0,44.371V375.284l8.341.0016V44.371A36.0651,36.0651,0,0,1,44.43,8.33H90.7089a4.6454,4.6454,0,0,1,4.6482,4.6423v1.9718a23.8588,23.8588,0,0,0,23.8742,23.843H288.9146a23.8586,23.8586,0,0,0,23.8741-23.843V12.972A4.6456,4.6456,0,0,1,317.4372,8.33h45.801A36.0651,36.0651,0,0,1,399.3271,44.371V375.3558l8.341.0015V44.371A44.4508,44.4508,0,0,0,363.2382,0Z',
"M1199.9485,803.1623"
],
viewBox: "0 0 407.6681 375.3573",
}
};

View File

@@ -1,6 +1,5 @@
.dialog--notify-vis-sms {
max-width: 350px;
max-height: 450px;
width: 800px;
.bp3-dialog-body {
.bp3-form-group {

View File

@@ -17,8 +17,7 @@
&__inside-content {
display: flex;
flex-direction: column;
height: 100%;
&--tabable {
margin-left: -25px;
margin-right: -25px;

View File

@@ -1,5 +1,5 @@
.dialog--sms-message {
max-width: 350px;
width: 800px;
.bp3-form-group {
margin-bottom: 15px;

View File

@@ -341,7 +341,7 @@ export const saveInvoke = (func, ...rest) => {
};
export const safeInvoke = (func, ...rest) => {
return func && func(...rest);
func && func(...rest);
};
export const transformToForm = (obj, emptyInitialValues) => {