Skip to content

Commit

Permalink
Connect Notifications APIs to Reporting (#131)
Browse files Browse the repository at this point in the history
* call notifications APIs from reporting, saving progress
Signed-off-by: David Cui <[email protected]>

* enable notifications integration, update view in details pages, update tests
Signed-off-by: David Cui <[email protected]>

* address comments, add server APIs to call backend notifications APIs to reduce dependency
Signed-off-by: David Cui <[email protected]>

* add get_event API to confirm test messages are sent successfully and throw error if not
Signed-off-by: David Cui <[email protected]>

* add input validation for delivery subject and message, hide notifications section if opensearch notifications is not installed
Signed-off-by: David Cui <[email protected]>

* renamed constant for notifications to follow API_PREFIX convention
Signed-off-by: David Cui <[email protected]>

* rename notifications constant to reporting_notifications
Signed-off-by: David Cui <[email protected]>

* add list of failed channels on test message failure
Signed-off-by: David Cui <[email protected]>
  • Loading branch information
davidcui1225 authored Jul 30, 2021
1 parent 55ed985 commit b3cf1d4
Show file tree
Hide file tree
Showing 21 changed files with 689 additions and 305 deletions.
14 changes: 14 additions & 0 deletions dashboards-reports/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ export const OPENSEARCH_REPORTS_API = {
LIST_REPORT_DEFINITIONS: `${BASE_REPORTS_URI}/definitions`,
POLL_REPORT_INSTANCE: `${BASE_REPORTS_URI}/poll_instance`,
};

const REPORTING_NOTIFICATIONS_API_PREFIX = '/api/reporting_notifications';
export const REPORTING_NOTIFICATIONS_DASHBOARDS_API = Object.freeze({
GET_CONFIGS: `${REPORTING_NOTIFICATIONS_API_PREFIX}/get_configs`,
GET_EVENT: `${REPORTING_NOTIFICATIONS_API_PREFIX}/get_event`,
SEND_TEST_MESSAGE: `${REPORTING_NOTIFICATIONS_API_PREFIX}/test_message`
});

const NOTIFICATIONS_API_BASE_PATH = '/_plugins/_notifications';
export const NOTIFICATIONS_API = Object.freeze({
CONFIGS: `${NOTIFICATIONS_API_BASE_PATH}/configs`,
EVENTS: `${NOTIFICATIONS_API_BASE_PATH}/events`,
TEST_MESSAGE: `${NOTIFICATIONS_API_BASE_PATH}/feature/test`
});
23 changes: 18 additions & 5 deletions dashboards-reports/public/components/main/main_utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,33 @@
import 'babel-polyfill';
import { i18n } from '@osd/i18n';
import { HttpFetchOptions, HttpSetup } from '../../../../../src/core/public';
import { placeholderChannels } from '../report_definitions/delivery/delivery_constants';

export const displayDeliveryChannels = (configIds: Array<string>) => {
export const displayDeliveryChannels = (configIds: Array<string>, channels: Array<{label: string, id: string}>) => {
let displayChannels = [];
for (let i = 0; i < configIds.length; ++i) {
for (let j = 0; j < placeholderChannels.length; ++j) {
if (configIds[i] === placeholderChannels[j].id) {
displayChannels.push(placeholderChannels[i].label);
for (let j = 0; j < channels.length; ++j) {
if (configIds[i] === channels[j].id) {
displayChannels.push(channels[j].label);
break;
}
}
}
return displayChannels.toString();
}

export const getAvailableNotificationsChannels = (configList: any) => {
let availableChannels = [];
for (let i = 0; i < configList.length; ++i) {
let channelEntry = {};
channelEntry = {
label: configList[i].config.name,
id: configList[i].config_id
}
availableChannels.push(channelEntry);
}
return availableChannels;
}

type fileFormatsOptions = {
[key: string]: string
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ describe('<ReportDefinitionDetails /> panel', () => {

httpClientMock.get = jest.fn().mockResolvedValue({
report_definition,
config_list: []
});

const { container } = render(
Expand Down Expand Up @@ -137,6 +138,7 @@ describe('<ReportDefinitionDetails /> panel', () => {

httpClientMock.get = jest.fn().mockResolvedValue({
report_definition,
config_list: []
});

const { container } = render(
Expand Down Expand Up @@ -191,6 +193,7 @@ describe('<ReportDefinitionDetails /> panel', () => {

httpClientMock.get = jest.fn().mockResolvedValue({
report_definition,
config_list: []
});

const { container } = render(
Expand Down Expand Up @@ -234,6 +237,7 @@ describe('<ReportDefinitionDetails /> panel', () => {

httpClientMock.get = jest.fn().mockResolvedValue({
report_definition,
config_list: []
});

const component = mount(
Expand Down Expand Up @@ -292,6 +296,7 @@ describe('<ReportDefinitionDetails /> panel', () => {

httpClientMock.get = jest.fn().mockResolvedValue({
report_definition,
config_list: []
});

const component = mount(
Expand Down Expand Up @@ -351,6 +356,7 @@ describe('<ReportDefinitionDetails /> panel', () => {

httpClientMock.get = jest.fn().mockResolvedValue({
report_definition,
config_list: []
});

httpClientMock.put = jest.fn().mockResolvedValue({});
Expand Down Expand Up @@ -412,6 +418,7 @@ describe('<ReportDefinitionDetails /> panel', () => {

httpClientMock.get = jest.fn().mockResolvedValue({
report_definition,
config_list: []
});

httpClientMock.put = jest.fn().mockResolvedValue({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
displayDeliveryChannels,
fileFormatsUpper,
generateReportFromDefinitionId,
getAvailableNotificationsChannels,
} from '../main_utils';
import { ReportDefinitionSchemaType } from '../../../../server/model';
import moment from 'moment';
Expand All @@ -62,7 +63,7 @@ import {
permissionsMissingActions,
} from '../../utils/utils';
import { GenerateReportLoadingModal } from '../loading_modal';
import { placeholderChannels } from '../../report_definitions/delivery/delivery_constants';
import { getChannelsQueryObject } from '../../report_definitions/delivery/delivery_constants';

const ON_DEMAND = 'On demand';

Expand Down Expand Up @@ -113,6 +114,7 @@ export function ReportDefinitionDetails(props: { match?: any; setBreadcrumbs?: a
const [toasts, setToasts] = useState([]);
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [showLoading, setShowLoading] = useState(false);
const [channels, setChannels] = useState<Array<{ label: string; id: string; }>>([]);
const reportDefinitionId = props.match['params']['reportDefinitionId'];

const handleLoading = (e: boolean | ((prevState: boolean) => boolean)) => {
Expand Down Expand Up @@ -410,19 +412,10 @@ export function ReportDefinitionDetails(props: { match?: any; setBreadcrumbs?: a
return scheduleDetails;
};

// const displayDeliveryChannels = (configIds: Array<string>) => {
// let displayChannels = [];
// for (let i = 0; i < configIds.length; ++i) {
// for (let j = 0; j < placeholderChannels.length; ++j) {
// if (configIds[i] === placeholderChannels[j].id) {
// displayChannels.push(placeholderChannels[i].label);
// }
// }
// }
// return displayChannels.toString();
// }

const getReportDefinitionDetailsMetadata = (data: ReportDefinitionSchemaType) : ReportDefinitionDetails => {
const getReportDefinitionDetailsMetadata = (
data: ReportDefinitionSchemaType,
availableChannels: Array<{ label: string; id: string; }>
) : ReportDefinitionDetails => {
const reportDefinition: ReportDefinitionSchemaType = data;
const {
report_params: reportParams,
Expand Down Expand Up @@ -485,7 +478,7 @@ export function ReportDefinitionDetails(props: { match?: any; setBreadcrumbs?: a
? humanReadableScheduleDetails(data.trigger)
: `\u2014`,
status: reportDefinition.status,
configIds: (configIds.length > 0) ? displayDeliveryChannels(configIds) : `\u2014`,
configIds: (configIds.length > 0) ? displayDeliveryChannels(configIds, availableChannels) : `\u2014`,
title: (title !== '') ? title : `\u2014`,
textDescription: (textDescription !== '') ? textDescription : `\u2014`,
htmlDescription: (htmlDescription !== '') ? htmlDescription : `\u2014`
Expand All @@ -496,10 +489,20 @@ export function ReportDefinitionDetails(props: { match?: any; setBreadcrumbs?: a
useEffect(() => {
const { httpClient } = props;
httpClient
.get('../api/reporting_notifications/get_configs', {
query: getChannelsQueryObject
})
.then(async (response: any) => {
let availableChannels = getAvailableNotificationsChannels(response.config_list);
setChannels(availableChannels);
return availableChannels;
})
.then((availableChannels: any) => {
httpClient
.get(`../api/reporting/reportDefinitions/${reportDefinitionId}`)
.then((response: {report_definition: ReportDefinitionSchemaType}) => {
handleReportDefinitionRawResponse(response);
handleReportDefinitionDetails(getReportDefinitionDetailsMetadata(response.report_definition));
handleReportDefinitionDetails(getReportDefinitionDetailsMetadata(response.report_definition, availableChannels));
props.setBreadcrumbs([
{
text: i18n.translate(
Expand Down Expand Up @@ -534,6 +537,7 @@ export function ReportDefinitionDetails(props: { match?: any; setBreadcrumbs?: a
);
handleDetailsErrorToast();
});
})
}, []);

const downloadIconDownload = async () => {
Expand Down Expand Up @@ -584,7 +588,7 @@ export function ReportDefinitionDetails(props: { match?: any; setBreadcrumbs?: a
updatedRawResponse.report_definition = updatedReportDefinition;
handleReportDefinitionRawResponse(updatedRawResponse);
setReportDefinitionDetails(
getReportDefinitionDetailsMetadata(updatedReportDefinition)
getReportDefinitionDetailsMetadata(updatedReportDefinition, channels)
);
if (statusChange === 'Enable') {
handleSuccessChangingScheduleStatusToast('enable');
Expand Down
Loading

0 comments on commit b3cf1d4

Please sign in to comment.