in dashboards-reports/public/components/report_definitions/delivery/delivery.tsx [54:358]
export function ReportDelivery(props: ReportDeliveryProps) {
const {
edit,
editDefinitionId,
reportDefinitionRequest,
httpClientProps,
showDeliveryChannelError,
deliveryChannelError,
showDeliverySubjectError,
deliverySubjectError,
showDeliveryTextError,
deliveryTextError,
} = props;
const [isDeliveryHidden, setIsHidden] = useState(false);
const [sendNotification, setSendNotification] = useState(false);
const [channels, setChannels] = useState([]);
const [selectedChannels, setSelectedChannels] = useState([]);
const [notificationSubject, setNotificationSubject] = useState('New report');
const [notificationMessage, setNotificationMessage] = useState(
'New report available to view'
);
const [selectedTab, setSelectedTab] = React.useState<'write' | 'preview'>(
'write'
);
const [testMessageConfirmation, setTestMessageConfirmation] = useState('');
const handleSendNotification = (e: { target: { checked: boolean } }) => {
setSendNotification(e.target.checked);
includeDelivery = e.target.checked;
if (includeDelivery) {
reportDefinitionRequest.delivery.title = 'New report';
reportDefinitionRequest.delivery.textDescription =
'New report available to view';
reportDefinitionRequest.delivery.htmlDescription = converter.makeHtml(
'New report available to view'
);
} else {
reportDefinitionRequest.delivery.title = `\u2014`;
reportDefinitionRequest.delivery.textDescription = `\u2014`;
}
};
const handleSelectedChannels = (e: Array<{ label: string; id: string }>) => {
setSelectedChannels(e);
reportDefinitionRequest.delivery.configIds = [];
for (let i = 0; i < e.length; ++i) {
reportDefinitionRequest.delivery.configIds.push(e[i].id);
}
};
const handleNotificationSubject = (e: { target: { value: string } }) => {
setNotificationSubject(e.target.value);
reportDefinitionRequest.delivery.title = e.target.value;
};
const handleNotificationMessage = (e: string) => {
setNotificationMessage(e);
reportDefinitionRequest.delivery.textDescription = e.toString();
reportDefinitionRequest.delivery.htmlDescription = converter.makeHtml(
e.toString()
);
};
const handleTestMessageConfirmation = (e: JSX.Element) => {
setTestMessageConfirmation(e);
};
const defaultCreateDeliveryParams = () => {
includeDelivery = false;
reportDefinitionRequest.delivery = {
configIds: [],
title: `\u2014`, // default values before any Notifications settings are configured
textDescription: `\u2014`,
htmlDescription: '',
};
};
const isStatusCodeSuccess = (statusCode: string) => {
if (!statusCode) return true;
return /^2\d\d/.test(statusCode);
};
const eventToNotification = (event: any) => {
const success = event.event.status_list.every((status: any) =>
isStatusCodeSuccess(status.delivery_status.status_code)
);
return {
event_source: event.event.event_source,
status_list: event.event.status_list,
event_id: event.event_id,
created_time_ms: event.created_time_ms,
last_updated_time_ms: event.last_updated_time_ms,
success,
};
};
const getNotification = async (id: string) => {
const response = await httpClientProps.get(
`${REPORTING_NOTIFICATIONS_DASHBOARDS_API.GET_EVENT}/${id}`
);
return eventToNotification(response.event_list[0]);
};
const sendTestNotificationsMessage = async () => {
if (selectedChannels.length === 0) {
handleTestMessageConfirmation(noDeliveryChannelsSelectedMessage);
}
let testMessageFailures = false;
let failedChannels: string[] = [];
// for each config ID in the current channels list
for (let i = 0; i < selectedChannels.length; ++i) {
try {
const eventId = await httpClientProps
.get(
`${REPORTING_NOTIFICATIONS_DASHBOARDS_API.SEND_TEST_MESSAGE}/${selectedChannels[i].id}`,
{
query: {
feature: 'reports',
},
}
)
.then((response) => response.event_id);
await getNotification(eventId).then((response) => {
if (!response.success) {
const error = new Error('Failed to send the test message.');
failedChannels.push(response.status_list[0].config_name);
error.stack = JSON.stringify(response.status_list, null, 2);
throw error;
}
});
} catch (error) {
testMessageFailures = true;
}
}
if (testMessageFailures) {
handleTestMessageConfirmation(testMessageFailureMessage(failedChannels));
} else {
handleTestMessageConfirmation(testMessageConfirmationMessage);
}
};
const checkIfNotificationsPluginIsInstalled = () => {
fetch(
'../api/console/proxy?path=%2F_cat%2Fplugins%3Fv%3Dtrue%26s%3Dcomponent%26h%3Dcomponent&method=GET',
{
credentials: 'include',
headers: {
Accept: 'text/plain, */*; q=0.01',
'Accept-Language': 'en-US,en;q=0.5',
'osd-xsrf': 'true',
},
method: 'POST',
mode: 'cors',
}
)
.then((response) => {
return response.text();
})
.then(function (data) {
if (data.includes('opensearch-notifications')) {
setIsHidden(false);
return;
}
setIsHidden(true);
});
};
useEffect(() => {
checkIfNotificationsPluginIsInstalled();
httpClientProps
.get(`${REPORTING_NOTIFICATIONS_DASHBOARDS_API.GET_CONFIGS}`, {
query: getChannelsQueryObject,
})
.then(async (response: any) => {
let availableChannels = getAvailableNotificationsChannels(
response.config_list
);
setChannels(availableChannels);
return availableChannels;
})
.then((availableChannels: any) => {
if (edit) {
httpClientProps
.get(`../api/reporting/reportDefinitions/${editDefinitionId}`)
.then(async (response: any) => {
if (response.report_definition.delivery.configIds.length > 0) {
// add config IDs
handleSendNotification({ target: { checked: true } });
let delivery = response.report_definition.delivery;
let editChannelOptions = [];
for (let i = 0; i < delivery.configIds.length; ++i) {
for (let j = 0; j < availableChannels.length; ++j) {
if (delivery.configIds[i] === availableChannels[j].id) {
let editChannelOption = {
label: availableChannels[j].label,
id: availableChannels[j].id,
};
editChannelOptions.push(editChannelOption);
break;
}
}
}
setSelectedChannels(editChannelOptions);
setNotificationSubject(delivery.title);
setNotificationMessage(delivery.textDescription);
reportDefinitionRequest.delivery = delivery;
}
});
} else {
defaultCreateDeliveryParams();
}
})
.catch((error: string) => {
console.log(
'error: cannot get available channels from Notifications plugin:',
error
);
});
}, []);
const showNotificationsBody = sendNotification ? (
<div>
<EuiSpacer />
<EuiFormRow
label="Channels"
isInvalid={showDeliveryChannelError}
error={deliveryChannelError}
>
<EuiComboBox
id="notificationsChannelSelect"
placeholder={'Select channels'}
options={channels}
selectedOptions={selectedChannels}
onChange={handleSelectedChannels}
isClearable={true}
/>
</EuiFormRow>
<EuiSpacer />
<EuiFormRow
label="Notification subject"
helpText="Required if at least one channel type is Email."
isInvalid={showDeliverySubjectError}
error={deliverySubjectError}
style={styles}
>
<EuiFieldText
placeholder={'Enter notification message subject'}
fullWidth={true}
value={notificationSubject}
onChange={handleNotificationSubject}
/>
</EuiFormRow>
<EuiSpacer />
<EuiFormRow
label="Notification message"
helpText="Embed variables in your message using Markdown."
isInvalid={showDeliveryTextError}
error={deliveryTextError}
style={styles}
>
<ReactMDE
value={notificationMessage}
onChange={handleNotificationMessage}
selectedTab={selectedTab}
onTabChange={setSelectedTab}
toolbarCommands={[
['header', 'bold', 'italic', 'strikethrough'],
['unordered-list', 'ordered-list', 'checked-list'],
]}
generateMarkdownPreview={(markdown) =>
Promise.resolve(converter.makeHtml(markdown))
}
/>
</EuiFormRow>
<EuiSpacer />
<EuiFormRow helpText={testMessageConfirmation} fullWidth={true}>
<EuiButton onClick={sendTestNotificationsMessage}>
Send test message
</EuiButton>
</EuiFormRow>
</div>
) : null;
return (
<EuiPageContent panelPaddingSize={'l'} hidden={isDeliveryHidden}>
<EuiPageHeader>
<EuiTitle>
<h2>Notification settings</h2>
</EuiTitle>
</EuiPageHeader>
<EuiHorizontalRule />
<EuiPageContentBody>
<EuiCheckbox
id="notificationsDeliveryCheckbox"
label="Send notification when report is available"
checked={sendNotification}
onChange={handleSendNotification}
/>
{showNotificationsBody}
</EuiPageContentBody>
</EuiPageContent>
);
}