mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
feat: Optimize SMS notification module.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -32,4 +32,5 @@ function NotifyInvoiceViaSMSDialog({
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withDialogRedux())(NotifyInvoiceViaSMSDialog);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
`;
|
||||
|
||||
@@ -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 } }) => (
|
||||
|
||||
@@ -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;
|
||||
`;
|
||||
|
||||
@@ -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;
|
||||
`;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
`;
|
||||
|
||||
@@ -10,3 +10,8 @@ export const transformErrors = (errors) => {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const getSMSUnits = (message, threshold = 140) => {
|
||||
return Math.ceil(message.length / threshold);
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user