Skip to content

Commit

Permalink
[FEATURE] Create global state object for async requests opensearch-pr…
Browse files Browse the repository at this point in the history
…oject#491

Signed-off-by: Jovan Cvetkovic <[email protected]>
  • Loading branch information
jovancvetkovic3006 committed Mar 27, 2023
1 parent ee8afd9 commit dea7ddc
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ export class DetectorDetails extends React.Component<DetectorDetailsProps, Detec
this.getDetector();
}
);
} else {
this.setState({ createFailed: true });
}
}
this.setState({ loading: false });
Expand Down
16 changes: 15 additions & 1 deletion public/pages/Main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
EuiSideNavItemType,
EuiTitle,
EuiSpacer,
EuiGlobalToastList,
} from '@elastic/eui';
import { Toast } from '@opensearch-project/oui/src/eui_components/toast/global_toast_list';
import { CoreStart } from 'opensearch-dashboards/public';
import { ServicesConsumer } from '../../services';
import { BrowserServices } from '../../models/interfaces';
Expand Down Expand Up @@ -71,6 +73,7 @@ interface MainState {
selectedNavItemIndex: number;
dateTimeFilter: DateTimeFilter;
callout?: ICalloutProps;
toasts?: Toast[];
}

const navItemIndexByRoute: { [route: string]: number } = {
Expand All @@ -93,7 +96,7 @@ export default class Main extends Component<MainProps, MainState> {
},
};

DataStore.detectors.setCalloutHandler(this.showCallout);
DataStore.detectors.setHandlers(this.showCallout, this.showToast);
}

showCallout = (callout?: ICalloutProps) => {
Expand All @@ -102,6 +105,12 @@ export default class Main extends Component<MainProps, MainState> {
});
};

showToast = (toasts?: any[]) => {
this.setState({
toasts,
});
};

componentDidMount(): void {
this.updateSelectedNavItem();
}
Expand Down Expand Up @@ -426,6 +435,11 @@ export default class Main extends Component<MainProps, MainState> {
<Redirect from={'/'} to={landingPage} />
</Switch>
</EuiPageBody>
<EuiGlobalToastList
toasts={this.state.toasts}
dismissToast={DataStore.detectors.hideToast}
toastLifeTimeMs={6000}
/>
</EuiPage>
)
}
Expand Down
54 changes: 27 additions & 27 deletions public/pages/Main/components/Callout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ export interface ICalloutProps {
closeHandler?: (callout?: ICalloutProps) => void;
}

export const toastTypes: {
[Key in TCalloutColor]: TCalloutIcon;
} = {
primary: 'iInCircle',
success: 'check',
warning: 'help',
danger: 'alert',
};

export const resolveType = (type?: ICalloutType | TCalloutColor): ICalloutType => {
if (type === undefined) {
return {
color: 'primary',
iconType: 'iInCircle',
};
} else {
if (typeof type === 'string') {
return {
color: type,
iconType: toastTypes[type],
};
} else {
return type;
}
}
};

export const CallOut = ({
title,
message,
Expand All @@ -38,33 +65,6 @@ export const CallOut = ({
loading = false,
closeHandler,
}: ICalloutProps) => {
const toastTypes: {
[Key in TCalloutColor]: TCalloutIcon;
} = {
primary: 'iInCircle',
success: 'check',
warning: 'help',
danger: 'alert',
};

const resolveType = (type?: ICalloutType | TCalloutColor): ICalloutType => {
if (type === undefined) {
return {
color: 'primary',
iconType: 'iInCircle',
};
} else {
if (typeof type === 'string') {
return {
color: type,
iconType: toastTypes[type],
};
} else {
return type;
}
}
};

const closeCallout = () => closeHandler && closeHandler(undefined);

const getTitle = (): JSX.Element => {
Expand Down
72 changes: 33 additions & 39 deletions public/store/DetectorsStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
*/

import React from 'react';
import ReactDOM from 'react-dom';
import { DetectorsService } from '../services';
import { NotificationsStart } from 'opensearch-dashboards/public';
import { CreateDetectorState } from '../pages/CreateDetector/containers/CreateDetector';
import { ICalloutProps, TCalloutColor } from '../pages/Main/components/Callout';
import { ICalloutProps, resolveType, TCalloutColor } from '../pages/Main/components/Callout';
import { CreateDetectorResponse, ISavedObjectsService, ServerResponse } from '../../types';
import { CreateMappingsResponse } from '../../server/models/interfaces';
import { logTypesWithDashboards, ROUTES } from '../utils/constants';
import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { Toast } from '@opensearch-project/oui/src/eui_components/toast/global_toast_list';
import { RouteComponentProps } from 'react-router-dom';
import { DataStore } from './DataStore';
import { v4 as uuidv4 } from 'uuid';

export interface IDetectorsStore {
readonly service: DetectorsService;
Expand All @@ -29,7 +30,10 @@ export interface IDetectorsStore {
dashboardId?: string;
ok: boolean;
}>;
setCalloutHandler: (calloutHandler: (callout?: ICalloutProps) => void) => void;
setHandlers: (
calloutHandler: (callout?: ICalloutProps) => void,
toastHandler: (toasts?: Toast[]) => void
) => void;
}

export interface IDetectorsCache {}
Expand Down Expand Up @@ -95,7 +99,7 @@ export class DetectorsStore implements IDetectorsStore {
* List of all shown toasts
* @private
*/
private toasts: any[] = [];
private toasts: Toast[] = [];

constructor(
service: DetectorsService,
Expand Down Expand Up @@ -138,12 +142,9 @@ export class DetectorsStore implements IDetectorsStore {
): void => {
if (!type) type = 'primary';

const closeToasts = () => {
while (this.toasts.length) {
const toast = this.toasts.pop();
this.notifications?.toasts.remove(toast);
closeToasts();
}
const closeAllToasts = () => {
this.toasts = [];
this.showToast(this.toasts);
};

const btn = btnText && (
Expand All @@ -152,7 +153,7 @@ export class DetectorsStore implements IDetectorsStore {
onClick={(e: any) => {
btnHandler && btnHandler(e);
this.hideCallout();
closeToasts();
closeAllToasts();
}}
size="s"
>
Expand All @@ -174,33 +175,15 @@ export class DetectorsStore implements IDetectorsStore {
closeHandler: this.hideCallout,
});

let toastGenerator;
switch (type) {
case 'danger':
toastGenerator = this.notifications?.toasts.addDanger;
break;
case 'warning':
toastGenerator = this.notifications?.toasts.addWarning;
break;
case 'success':
toastGenerator = this.notifications?.toasts.addSuccess;
break;
default:
toastGenerator = this.notifications?.toasts.addInfo;
break;
}

this.toasts.push(
toastGenerator.bind(this.notifications?.toasts)({
title: title,
text: this.mountToaster(messageBody),
})
);
};

private mountToaster = (component: React.ReactElement) => (container: HTMLElement) => {
ReactDOM.render(component, container);
return () => ReactDOM.unmountComponentAtNode(container);
const { color, iconType } = resolveType(type);
this.toasts.push({
title,
color,
iconType,
id: `toastsKey_${uuidv4()}`,
text: messageBody,
});
this.showToast(this.toasts);
};

private viewDetectorConfiguration = (): void => {
Expand Down Expand Up @@ -329,7 +312,18 @@ export class DetectorsStore implements IDetectorsStore {

private hideCallout = (): void => this.showCallout(undefined);

public setCalloutHandler = (calloutHandler: (callout?: ICalloutProps) => void): void => {
private showToast = (toasts?: Toast[] | undefined): void => {};

public hideToast = (removedToast: any): void => {
const toasts = this.toasts.filter((toast: Toast) => toast.id !== removedToast.id);
this.showToast(toasts);
};

public setHandlers = (
calloutHandler: (callout?: ICalloutProps) => void,
toastHandler: (toasts?: Toast[]) => void
): void => {
this.showCallout = calloutHandler;
this.showToast = toastHandler;
};
}

0 comments on commit dea7ddc

Please sign in to comment.