Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.x] Persist dataSourceId across applications under new Nav change (#244) #249

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions public/components/MDSEnabledComponent/MDSEnabledComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from "react";
import React, { useContext, useEffect } from "react";
import { DataSourceMenuContext, DataSourceMenuProperties } from "../../services/DataSourceMenuContext";
import _ from 'lodash'
import { useHistory } from "react-router-dom";
import queryString from "query-string";

export default class MDSEnabledComponent<
Props extends DataSourceMenuProperties,
Expand Down Expand Up @@ -29,6 +31,25 @@ export function isDataSourceChanged(prevProps, currentProps) {
return false;
}

export function isDataSourceError(error) {
export function isDataSourceError(error: { body: { message: string | string[]; }; }) {
return (error.body && error.body.message && error.body.message.includes("Data Source Error"));
}

export function useUpdateUrlWithDataSourceProperties() {
const dataSourceMenuProps = useContext(DataSourceMenuContext);
const { dataSourceId, multiDataSourceEnabled } = dataSourceMenuProps;
const history = useHistory();
const currentSearch = history?.location?.search;
const currentQuery = queryString.parse(currentSearch);
useEffect(() => {
if (multiDataSourceEnabled) {
history.replace({
search: queryString.stringify({
...currentQuery,
dataSourceId,
}),
});
}
}, [dataSourceId, multiDataSourceEnabled]);
}

2 changes: 2 additions & 0 deletions public/components/PageHeader/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
TopNavControlLinkData,
} from '../../../../../src/plugins/navigation/public';
import { getApplication, getNavigationUI, getUseUpdatedUx } from '../../services/utils/constants';
import { useUpdateUrlWithDataSourceProperties } from '../MDSEnabledComponent/MDSEnabledComponent';

export interface PageHeaderProps {
appRightControls?: TopNavControlData[];
Expand All @@ -27,6 +28,7 @@ const PageHeader: React.FC<PageHeaderProps> = ({
}) => {
const { HeaderControl } = getNavigationUI();
const { setAppBadgeControls, setAppRightControls, setAppDescriptionControls, setAppLeftControls } = getApplication();
useUpdateUrlWithDataSourceProperties();

return getUseUpdatedUx() ? (
<>
Expand Down
5 changes: 4 additions & 1 deletion public/pages/Emails/EmailSenders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { SendersTable } from './components/tables/SendersTable';
import { SESSendersTable } from './components/tables/SESSendersTable';
import { NotificationService } from '../../services';
import { getUseUpdatedUx } from '../../services/utils/constants';
import { useUpdateUrlWithDataSourceProperties } from '../../components/MDSEnabledComponent/MDSEnabledComponent';

interface EmailSendersProps extends RouteComponentProps {
notificationService: NotificationService;
Expand All @@ -22,7 +23,9 @@ export function EmailSenders(props: EmailSendersProps) {
const coreContext = useContext(CoreServicesContext)!;
const mainStateContext = useContext(MainContext)!;


// Call the hook to manage URL updates
useUpdateUrlWithDataSourceProperties();

useEffect(() => {
setBreadcrumbs([
BREADCRUMBS.NOTIFICATIONS,
Expand Down
15 changes: 12 additions & 3 deletions public/pages/Main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CoreServicesConsumer, CoreServicesContext } from '../../components/core
import { ModalProvider, ModalRoot } from '../../components/Modal';
import { BrowserServices } from '../../models/interfaces';
import { ServicesConsumer, ServicesContext } from '../../services/services';
import { ROUTES } from '../../utils/constants';
import { ROUTES, dataSourceObservable } from '../../utils/constants';
import { CHANNEL_TYPE } from '../../../common/constants';
import { Channels } from '../Channels/Channels';
import { ChannelDetails } from '../Channels/components/details/ChannelDetails';
Expand Down Expand Up @@ -85,12 +85,20 @@ export default class Main extends Component<MainProps, MainState> {
dataSourceLabel?: string;
};

if (dataSourceId) {
dataSourceObservable.next({ id: dataSourceId, label: dataSourceLabel });
}
this.state = {
...initialState,
dataSourceId: dataSourceId,
dataSourceLabel: dataSourceLabel,
dataSourceReadOnly: false,
dataSourceLoading: props.multiDataSourceEnabled,
/**
* undefined: need data source picker to help to determine which data source to use.
* empty string: using the local cluster.
* string: using the selected data source.
*/
dataSourceLoading: dataSourceId === undefined ? props.multiDataSourceEnabled : false,
};
} else {
this.state = initialState;
Expand Down Expand Up @@ -124,7 +132,7 @@ export default class Main extends Component<MainProps, MainState> {
];

let newState = {
dataSourceId: this.state.dataSourceId || '',
dataSourceId: this.state.dataSourceId,
dataSourceLabel: this.state.dataSourceLabel || '',
dataSourceReadOnly: false,
dataSourceLoading: this.state.dataSourceLoading,
Expand Down Expand Up @@ -153,6 +161,7 @@ export default class Main extends Component<MainProps, MainState> {
dataSourceId: id,
dataSourceLabel: label,
});
dataSourceObservable.next({ id, label });
}
if (this.state.dataSourceLoading) {
this.setState({
Expand Down
23 changes: 21 additions & 2 deletions public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { i18n } from '@osd/i18n';
import {
AppMountParameters,
AppUpdater,
CoreSetup,
CoreStart,
DEFAULT_APP_CATEGORIES,
Expand All @@ -20,8 +21,9 @@ import {
NotificationsDashboardsSetupDeps,
} from './types';
import { PLUGIN_NAME } from '../common';
import { ROUTES } from './utils/constants';
import { ROUTES, dataSourceObservable } from './utils/constants';
import { setApplication, setBreadCrumbsSetter, setNavigationUI, setUISettings } from './services/utils/constants';
import { BehaviorSubject } from "rxjs";

export class notificationsDashboardsPlugin
implements
Expand All @@ -33,6 +35,15 @@ export class notificationsDashboardsPlugin
defaultMessage: 'Notifications',
});

private updateDefaultRouteOfManagementApplications: AppUpdater = () => {
const hash = `#/?dataSourceId=${dataSourceObservable.value?.id || ""}`;
return {
defaultPath: hash,
};
};

private appStateUpdater = new BehaviorSubject<AppUpdater>(this.updateDefaultRouteOfManagementApplications);

public setup(
core: CoreSetup,
{ managementOverview, dataSourceManagement }: NotificationsDashboardsSetupDeps,
Expand Down Expand Up @@ -91,6 +102,7 @@ export class notificationsDashboardsPlugin
title: 'Channels',
order: 9070,
workspaceAvailability: WorkspaceAvailability.outsideWorkspace,
updater$: this.appStateUpdater,
mount: async (params: AppMountParameters) => {
return mountWrapper(params, ROUTES.CHANNELS);
},
Expand All @@ -101,6 +113,7 @@ export class notificationsDashboardsPlugin
title: 'Email senders',
order: 9080,
workspaceAvailability: WorkspaceAvailability.outsideWorkspace,
updater$: this.appStateUpdater,
mount: async (params: AppMountParameters) => {
return mountWrapper(params, ROUTES.EMAIL_SENDERS);
},
Expand All @@ -111,11 +124,18 @@ export class notificationsDashboardsPlugin
title: 'Email recepient groups',
order: 9090,
workspaceAvailability: WorkspaceAvailability.outsideWorkspace,
updater$: this.appStateUpdater,
mount: async (params: AppMountParameters) => {
return mountWrapper(params, ROUTES.EMAIL_GROUPS);
},
});

dataSourceObservable.subscribe((dataSourceOption) => {
if (dataSourceOption) {
this.appStateUpdater.next(this.updateDefaultRouteOfManagementApplications);
}
});

const navlinks = [
{ id: 'channels', parent: PLUGIN_NAME },
{ id: 'email_senders', parent: PLUGIN_NAME },
Expand All @@ -132,7 +152,6 @@ export class notificationsDashboardsPlugin
navLinks
);
}

// Return methods that should be available to other plugins
return {};
}
Expand Down
12 changes: 12 additions & 0 deletions public/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

import { ChromeBreadcrumb } from 'opensearch-dashboards/public';
import { getBreadCrumbsSetter, getUseUpdatedUx } from '../services/utils/constants';
import { DataSourceOption } from 'src/plugins/data_source_management/public';
import { i18n } from "@osd/i18n";
import { BehaviorSubject } from 'rxjs';

export const DOCUMENTATION_LINK = '';
export const ALERTING_DOCUMENTATION_LINK =
Expand Down Expand Up @@ -72,3 +75,12 @@ export const CUSTOM_WEBHOOK_ENDPOINT_TYPE = Object.freeze({
export function setBreadcrumbs(crumbs: ChromeBreadcrumb[]) {
getBreadCrumbsSetter()(getUseUpdatedUx() ? crumbs : [BREADCRUMBS.NOTIFICATIONS, ...crumbs]);
}

const LocalCluster: DataSourceOption = {
label: i18n.translate("dataSource.localCluster", {
defaultMessage: "Local cluster",
}),
id: "",
};

export const dataSourceObservable = new BehaviorSubject<DataSourceOption>(LocalCluster);
Loading