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

Adding functionality to associate existing detector with a visualization #484

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { get } from 'lodash';
import AssociatedDetectors from '../AssociatedDetectors/containers/AssociatedDetectors';
import { getEmbeddable } from '../../../../public/services';
import AddAnomalyDetector from '../CreateAnomalyDetector';
import { FLYOUT_MODES } from './constants';

const AnywhereParentFlyout = ({ startingFlyout, ...props }) => {
const embeddable = getEmbeddable().getEmbeddableFactory;
Expand All @@ -18,9 +19,9 @@ const AnywhereParentFlyout = ({ startingFlyout, ...props }) => {
const [selectedDetector, setSelectedDetector] = useState(undefined);

const AnywhereFlyout = {
create: AddAnomalyDetector,
associated: AssociatedDetectors,
existing: AddAnomalyDetector,
[FLYOUT_MODES.create]: AddAnomalyDetector,
[FLYOUT_MODES.associated]: AssociatedDetectors,
[FLYOUT_MODES.existing]: AddAnomalyDetector,
}[mode];

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

//created: Flyout for creating a new anomaly detector from a visualization
//associated: Flyout for listing all the associated detectors to the given visualization
//existing: Flyout for associating existing detectors with the current visualizations
export enum FLYOUT_MODES {
create = 'create',
associated = 'associated',
existing = 'existing',
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { DetectorListItem } from '../../../../models/interfaces';
import {
getSavedFeatureAnywhereLoader,
getNotifications,
getUISettings,
} from '../../../../services';
import {
GET_ALL_DETECTORS_QUERY_PARAMS,
Expand All @@ -39,7 +40,11 @@ import {
EmptyAssociatedDetectorMessage,
ConfirmUnlinkDetectorModal,
} from '../components';
import { ISavedAugmentVis } from '../../../../../../../src/plugins/vis_augmenter/public';
import {
ISavedAugmentVis,
SavedAugmentVisLoader,
getAugmentVisSavedObjs,
} from '../../../../../../../src/plugins/vis_augmenter/public';
import { ASSOCIATED_DETECTOR_ACTION } from '../utils/constants';

interface ConfirmModalState {
Expand Down Expand Up @@ -82,8 +87,10 @@ function AssociatedDetectors({ embeddable, closeFlyout, setMode }) {
);

// Establish savedObjectLoader for all operations on vis_augment saved objects
const savedObjectLoader: SavedObjectLoader = getSavedFeatureAnywhereLoader();
const savedObjectLoader: SavedAugmentVisLoader =
getSavedFeatureAnywhereLoader();

const uiSettings = getUISettings();
const notifications = getNotifications();

useEffect(() => {
Expand Down Expand Up @@ -127,15 +134,12 @@ function AssociatedDetectors({ embeddable, closeFlyout, setMode }) {

// Handles all changes in the assoicated detectors such as unlinking or new detectors associated
useEffect(() => {
// Gets all augmented saved objects
savedObjectLoader
.findAll()
.then((resp: any) => {
if (resp != undefined) {
const savedAugmentObjectsArr: ISavedAugmentVis[] = get(
resp,
'hits',
[]
// Gets all augmented saved objects that are associated to the given visualization
getAugmentVisSavedObjs(embeddable.vis.id, savedObjectLoader, uiSettings)
.then((savedAugmentObjectsArr: any) => {
if (savedAugmentObjectsArr != undefined) {
console.log(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this console line needed?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if not, you can remove it in the next pr

'savedAugmentObjectsArr: ' + JSON.stringify(savedAugmentObjectsArr)
);
const curSelectedDetectors = getAssociatedDetectors(
Object.values(allDetectors),
Expand All @@ -156,14 +160,8 @@ function AssociatedDetectors({ embeddable, closeFlyout, setMode }) {
// that are associated to the current visualization
const getAssociatedDetectors = (
detectors: DetectorListItem[],
savedAugmentObjects: ISavedAugmentVis[]
savedAugmentForThisVisualization: ISavedAugmentVis[]
) => {
// Filter all savedAugmentObjects that aren't linked to the specific visualization
const savedAugmentForThisVisualization: ISavedAugmentVis[] =
savedAugmentObjects.filter(
(savedObj) => get(savedObj, 'visId', '') === embeddable.vis.id
);

// Map all detector IDs for all the found augmented vis objects
const savedAugmentDetectorsSet = new Set(
savedAugmentForThisVisualization.map((savedObject) =>
Expand All @@ -180,18 +178,13 @@ function AssociatedDetectors({ embeddable, closeFlyout, setMode }) {

const onUnlinkDetector = async () => {
setIsLoadingFinalDetectors(true);
await savedObjectLoader.findAll().then(async (resp: any) => {
if (resp != undefined) {
// gets all the saved object for this visualization
const savedAugmentForThisVisualization: ISavedAugmentVis[] = get(
resp,
'hits',
[] as ISavedAugmentVis[]
).filter(
(savedObj: ISavedAugmentVis[]) =>
get(savedObj, 'visId', '') === embeddable.vis.id
);

// Gets all augmented saved objects that are associated to the given visualization
await getAugmentVisSavedObjs(
embeddable.vis.id,
savedObjectLoader,
uiSettings
).then(async (savedAugmentForThisVisualization: any) => {
if (savedAugmentForThisVisualization != undefined) {
// find saved augment object matching detector we want to unlink
// There should only be one detector and vis pairing
const savedAugmentToUnlink = savedAugmentForThisVisualization.find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
createAugmentVisSavedObject,
ISavedAugmentVis,
ISavedPluginResource,
SavedAugmentVisLoader,
VisLayerExpressionFn,
VisLayerTypes,
} from '../../../../../../src/plugins/vis_augmenter/public';
Expand Down Expand Up @@ -83,7 +84,12 @@ import {
DEFAULT_SHINGLE_SIZE,
MAX_FEATURE_NUM,
} from '../../../../public/utils/constants';
import { getNotifications, getUiActions } from '../../../../public/services';
import {
getNotifications,
getSavedFeatureAnywhereLoader,
getUISettings,
getUiActions,
} from '../../../../public/services';
import { prettifyErrorMessage } from '../../../../server/utils/helpers';
import {
ORIGIN_PLUGIN_VIS_LAYER,
Expand All @@ -93,8 +99,7 @@ import {
import { formikToDetectorName, visFeatureListToFormik } from './helpers';
import { AssociateExisting } from './AssociateExisting';
import { mountReactNode } from '../../../../../../src/core/public/utils';
import { CoreServicesContext } from '../../../../public/components/CoreServices/CoreServices';
import { CoreStart } from '../../../../../../src/core/public';
import { FLYOUT_MODES } from '../AnywhereParentFlyout/constants';

function AddAnomalyDetector({
embeddable,
Expand Down Expand Up @@ -160,6 +165,10 @@ function AddAnomalyDetector({
}
};

const uiSettings = getUISettings();
const savedObjectLoader: SavedAugmentVisLoader =
getSavedFeatureAnywhereLoader();

const getAugmentVisSavedObject = (detectorId: string) => {
const fn = {
type: VisLayerTypes.PointInTimeEvents,
Expand Down Expand Up @@ -210,11 +219,14 @@ function AddAnomalyDetector({
});

const detectorId = response.response.id;

const augmentVisSavedObjectToCreate: ISavedAugmentVis =
getAugmentVisSavedObject(detectorId);

createAugmentVisSavedObject(augmentVisSavedObjectToCreate)
createAugmentVisSavedObject(
augmentVisSavedObjectToCreate,
uiSettings,
savedObjectLoader
)
.then((savedObject: any) => {
savedObject
.save({})
Expand All @@ -230,12 +242,14 @@ function AddAnomalyDetector({
text: mountReactNode(
getEverythingSuccessfulButton(detectorId, shingleSize)
),
className: 'createdAndAssociatedSuccessToast',
toastLifeTimeMs: 3000000,
amitgalitz marked this conversation as resolved.
Show resolved Hide resolved
});
closeFlyout();
})
.catch((error) => {
console.error(
`Error associating selected detector: ${error}`
`Error associating selected detector in save process: ${error}`
);
notifications.toasts.addDanger(
prettifyErrorMessage(
Expand All @@ -248,6 +262,9 @@ function AddAnomalyDetector({
});
})
.catch((error) => {
console.error(
`Error associating selected detector in create process: ${error}`
);
notifications.toasts.addDanger(
prettifyErrorMessage(
`Error associating selected detector in create process: ${error}`
Expand Down Expand Up @@ -294,16 +311,16 @@ function AddAnomalyDetector({
initializing process takes approximately 1 minute if you have data in
each of the last {32 + shingleSize} consecutive intervals.
</p>
{alertingExists(detectorId) ? (
{alertingExists() ? (
<EuiFlexGroup>
<EuiFlexItem>
<p>Set up alerts to be notifified of any anomalies.</p>
<p>Set up alerts to be notified of any anomalies.</p>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<div>
<EuiButton onClick={() => openAlerting(detectorId)}>
Set up alerts
</EuiButton>{' '}
</EuiButton>
</div>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down Expand Up @@ -334,7 +351,11 @@ function AddAnomalyDetector({
const augmentVisSavedObjectToCreate: ISavedAugmentVis =
getAugmentVisSavedObject(detector.id);

createAugmentVisSavedObject(augmentVisSavedObjectToCreate)
createAugmentVisSavedObject(
augmentVisSavedObjectToCreate,
uiSettings,
savedObjectLoader
)
.then((savedObject: any) => {
savedObject
.save({})
Expand Down Expand Up @@ -454,14 +475,14 @@ function AddAnomalyDetector({
))}
</EuiFormFieldset>
<EuiSpacer size="m" />
{mode === 'existing' && (
{mode === FLYOUT_MODES.existing && (
<AssociateExisting
embeddableVisId={embeddable.vis.id}
selectedDetector={selectedDetector}
setSelectedDetector={setSelectedDetector}
></AssociateExisting>
)}
{mode === 'create' && (
{mode === FLYOUT_MODES.create && (
<div className="create-new">
<EuiText size="xs">
<p>
Expand Down Expand Up @@ -831,7 +852,7 @@ function AddAnomalyDetector({
<EuiButtonEmpty onClick={closeFlyout}>Cancel</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
{mode === 'existing' ? (
{mode === FLYOUT_MODES.existing ? (
<EuiButton
fill={true}
data-test-subj="adAnywhereCreateDetectorButton"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@ import {
NO_PERMISSIONS_KEY_WORD,
prettifyErrorMessage,
} from '../../../../../../server/utils/helpers';
import { SavedObjectLoader } from '../../../../../../../../src/plugins/saved_objects/public';
import { getDetectorList } from '../../../../../redux/reducers/ad';
import { getSavedFeatureAnywhereLoader } from '../../../../../services';
import { ISavedAugmentVis } from '../../../../../../../../src/plugins/vis_augmenter/public';
import {
getSavedFeatureAnywhereLoader,
getUISettings,
} from '../../../../../services';
import {
ISavedAugmentVis,
SavedAugmentVisLoader,
getAugmentVisSavedObjs,
} from '../../../../../../../../src/plugins/vis_augmenter/public';
import { stateToColorMap } from '../../../../../pages/utils/constants';
import {
BASE_DOCS_LINK,
Expand All @@ -57,6 +63,7 @@ export function AssociateExisting(
const isRequestingFromES = useSelector(
(state: AppState) => state.ad.requesting
);
const uiSettings = getUISettings();
const [isLoadingFinalDetectors, setIsLoadingFinalDetectors] =
useState<boolean>(true);
const isLoading = isRequestingFromES || isLoadingFinalDetectors;
Expand All @@ -69,7 +76,8 @@ export function AssociateExisting(
] = useState([] as DetectorListItem[]);

// Establish savedObjectLoader for all operations on vis augmented saved objects
const savedObjectLoader: SavedObjectLoader = getSavedFeatureAnywhereLoader();
const savedObjectLoader: SavedAugmentVisLoader =
getSavedFeatureAnywhereLoader();

useEffect(() => {
if (
Expand All @@ -89,14 +97,13 @@ export function AssociateExisting(

// Handle all changes in the assoicated detectors such as unlinking or new detectors associated
useEffect(() => {
// Gets all augmented saved objects
savedObjectLoader.findAll().then((resp: any) => {
if (resp != undefined) {
const savedAugmentObjectsArr: ISavedAugmentVis[] = get(
resp,
'hits',
[]
);
// Gets all augmented saved objects for the given visualization
getAugmentVisSavedObjs(
associateExistingProps.embeddableVisId,
savedObjectLoader,
uiSettings
).then((savedAugmentObjectsArr: any) => {
if (savedAugmentObjectsArr != undefined) {
const curDetectorsToDisplayOnList =
getExistingDetectorsAvailableToAssociate(
Object.values(allDetectors),
Expand All @@ -112,15 +119,8 @@ export function AssociateExisting(
// that are associated to the current visualization
const getExistingDetectorsAvailableToAssociate = (
detectors: DetectorListItem[],
savedAugmentObjects: ISavedAugmentVis[]
savedAugmentForThisVisualization: ISavedAugmentVis[]
) => {
// Filter all savedAugmentObjects that aren't linked to the specific visualization
const savedAugmentForThisVisualization: ISavedAugmentVis[] =
savedAugmentObjects.filter(
(savedObj) =>
get(savedObj, 'visId', '') === associateExistingProps.embeddableVisId
);

// Map all detector IDs for all the found augmented vis objects
const savedAugmentDetectorsSet = new Set(
savedAugmentForThisVisualization.map((savedObject) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,13 @@
height: 100%;
min-height: 40px;
}

.euiGlobalToastList {
width: 650px;
}

.createdAndAssociatedSuccessToast {
width: 550px;
position: relative;
right: 15px;
}
2 changes: 2 additions & 0 deletions public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
setOverlays,
setSavedFeatureAnywhereLoader,
setUiActions,
setUISettings,
} from './services';
import { AnomalyDetectionOpenSearchDashboardsPluginStart } from 'public';
import {
Expand Down Expand Up @@ -112,6 +113,7 @@ export class AnomalyDetectionOpenSearchDashboardsPlugin
core: CoreStart,
{ embeddable, visAugmenter, uiActions }: AnomalyDetectionStartDeps
): AnomalyDetectionOpenSearchDashboardsPluginStart {
setUISettings(core.uiSettings);
setEmbeddable(embeddable);
setOverlays(core.overlays);
setSavedFeatureAnywhereLoader(visAugmenter.savedAugmentVisLoader);
Expand Down
Loading