From 47c41c16c9707ccb0be7659e867ee97a20bd5875 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Wed, 14 Aug 2024 14:32:03 -0400 Subject: [PATCH] chore(rca): Add notes related APIs (#190362) --- .github/CODEOWNERS | 1 + package.json | 1 + packages/kbn-investigation-shared/README.md | 3 + packages/kbn-investigation-shared/index.ts | 23 ++++++ .../kbn-investigation-shared/jest.config.js | 13 ++++ .../kbn-investigation-shared/kibana.jsonc | 5 ++ .../kbn-investigation-shared/package.json | 6 ++ .../src}/schema/create.ts | 6 +- .../src/schema/create_notes.ts | 36 ++++++++++ .../src/schema/delete.ts | 20 ++++++ .../src}/schema/find.ts | 6 +- .../src}/schema/get.ts | 6 +- .../src/schema/get_notes.ts | 23 ++++++ .../src}/schema/investigation.ts | 8 ++- .../src/schema/investigation_note.ts | 21 ++++++ .../src}/schema/origin.ts | 11 ++- .../kbn-investigation-shared/tsconfig.json | 17 +++++ tsconfig.base.json | 2 + .../investigate/common/index.ts | 8 --- .../investigate/common/types.ts | 2 +- .../public/hooks/use_investigate_widget.tsx | 8 +-- .../use_investigation/investigation_store.ts | 2 +- .../investigate/public/plugin.tsx | 4 +- .../investigate/public/types.ts | 6 +- .../investigate/tsconfig.json | 3 +- .../investigate_app/public/application.tsx | 25 +++++-- .../public/hooks/use_abort_signal.ts | 21 ------ .../hooks/use_add_investigation_note.ts | 51 ++++++++++++++ .../public/hooks/use_fetch_investigation.ts | 58 +++++++++++++++ .../hooks/use_fetch_investigation_list.ts | 2 +- .../public/hooks/use_get_alert_details.tsx | 10 +-- .../hooks/use_get_investigation_details.tsx | 10 +-- .../public/hooks/use_investigate_params.ts | 14 ---- .../public/hooks/use_investigate_router.ts | 55 --------------- .../investigation_details/index.stories.tsx | 2 +- .../investigation_details/index.tsx | 70 +++++++++---------- .../investigation_notes.tsx | 4 +- .../investigation_notes/timeline_message.tsx | 2 +- .../details/investigation_details_page.tsx | 33 ++++----- .../public/pages/details/types.ts | 10 +++ .../investigate_app/public/routes/config.tsx | 48 ++++++------- .../server/models/investigation.ts | 4 +- .../server/models/investigation_note.ts | 18 +++++ ...investigate_app_server_route_repository.ts | 63 +++++++++++++++-- .../server/services/create_investigation.ts | 6 +- .../services/create_investigation_note.ts | 33 +++++++++ .../server/services/delete_investigation.ts | 15 ++++ .../server/services/find_investigations.ts | 4 +- .../server/services/get_investigation.ts | 9 ++- .../services/get_investigation_notes.ts | 21 ++++++ .../investigate_app/tsconfig.json | 3 +- .../hooks/use_create_investigation.tsx | 6 +- .../use_fetch_investigations_by_alert.tsx | 2 +- .../observability/tsconfig.json | 1 + yarn.lock | 4 ++ 55 files changed, 587 insertions(+), 258 deletions(-) create mode 100644 packages/kbn-investigation-shared/README.md create mode 100644 packages/kbn-investigation-shared/index.ts create mode 100644 packages/kbn-investigation-shared/jest.config.js create mode 100644 packages/kbn-investigation-shared/kibana.jsonc create mode 100644 packages/kbn-investigation-shared/package.json rename {x-pack/plugins/observability_solution/investigate/common => packages/kbn-investigation-shared/src}/schema/create.ts (86%) create mode 100644 packages/kbn-investigation-shared/src/schema/create_notes.ts create mode 100644 packages/kbn-investigation-shared/src/schema/delete.ts rename {x-pack/plugins/observability_solution/investigate/common => packages/kbn-investigation-shared/src}/schema/find.ts (83%) rename {x-pack/plugins/observability_solution/investigate/common => packages/kbn-investigation-shared/src}/schema/get.ts (80%) create mode 100644 packages/kbn-investigation-shared/src/schema/get_notes.ts rename {x-pack/plugins/observability_solution/investigate/common => packages/kbn-investigation-shared/src}/schema/investigation.ts (70%) create mode 100644 packages/kbn-investigation-shared/src/schema/investigation_note.ts rename {x-pack/plugins/observability_solution/investigate/common => packages/kbn-investigation-shared/src}/schema/origin.ts (61%) create mode 100644 packages/kbn-investigation-shared/tsconfig.json delete mode 100644 x-pack/plugins/observability_solution/investigate_app/public/hooks/use_abort_signal.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/hooks/use_add_investigation_note.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation.ts delete mode 100644 x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_params.ts delete mode 100644 x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_router.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/pages/details/types.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/models/investigation_note.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/services/delete_investigation.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation_notes.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fcdfaf1fe4ef8..37941842c0fca 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -513,6 +513,7 @@ test/interactive_setup_api_integration/plugins/test_endpoints @elastic/kibana-se packages/kbn-interpreter @elastic/kibana-visualizations x-pack/plugins/observability_solution/investigate_app @elastic/obs-ux-management-team x-pack/plugins/observability_solution/investigate @elastic/obs-ux-management-team +packages/kbn-investigation-shared @elastic/obs-ux-management-team packages/kbn-io-ts-utils @elastic/obs-knowledge-team packages/kbn-ipynb @elastic/search-kibana packages/kbn-jest-serializers @elastic/kibana-operations diff --git a/package.json b/package.json index 057d064fd31e6..6a4cb58c50f57 100644 --- a/package.json +++ b/package.json @@ -556,6 +556,7 @@ "@kbn/interpreter": "link:packages/kbn-interpreter", "@kbn/investigate-app-plugin": "link:x-pack/plugins/observability_solution/investigate_app", "@kbn/investigate-plugin": "link:x-pack/plugins/observability_solution/investigate", + "@kbn/investigation-shared": "link:packages/kbn-investigation-shared", "@kbn/io-ts-utils": "link:packages/kbn-io-ts-utils", "@kbn/ipynb": "link:packages/kbn-ipynb", "@kbn/json-schemas": "link:x-pack/packages/ml/json_schemas", diff --git a/packages/kbn-investigation-shared/README.md b/packages/kbn-investigation-shared/README.md new file mode 100644 index 0000000000000..07c07fe3e7081 --- /dev/null +++ b/packages/kbn-investigation-shared/README.md @@ -0,0 +1,3 @@ +# @kbn/investigation-shared + +Empty package generated by @kbn/generate diff --git a/packages/kbn-investigation-shared/index.ts b/packages/kbn-investigation-shared/index.ts new file mode 100644 index 0000000000000..723a97d762b02 --- /dev/null +++ b/packages/kbn-investigation-shared/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export type * from './src/schema/create'; +export type * from './src/schema/create_notes'; +export type * from './src/schema/delete'; +export type * from './src/schema/find'; +export type * from './src/schema/get'; +export type * from './src/schema/get_notes'; +export type * from './src/schema/origin'; + +export * from './src/schema/create'; +export * from './src/schema/create_notes'; +export * from './src/schema/delete'; +export * from './src/schema/find'; +export * from './src/schema/get'; +export * from './src/schema/get_notes'; +export * from './src/schema/origin'; diff --git a/packages/kbn-investigation-shared/jest.config.js b/packages/kbn-investigation-shared/jest.config.js new file mode 100644 index 0000000000000..97bfdd78ff319 --- /dev/null +++ b/packages/kbn-investigation-shared/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../..', + roots: ['/packages/kbn-investigation-shared'], +}; diff --git a/packages/kbn-investigation-shared/kibana.jsonc b/packages/kbn-investigation-shared/kibana.jsonc new file mode 100644 index 0000000000000..ffc2802ff3af9 --- /dev/null +++ b/packages/kbn-investigation-shared/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/investigation-shared", + "owner": "@elastic/obs-ux-management-team" +} diff --git a/packages/kbn-investigation-shared/package.json b/packages/kbn-investigation-shared/package.json new file mode 100644 index 0000000000000..bf4a97caf483e --- /dev/null +++ b/packages/kbn-investigation-shared/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/investigation-shared", + "private": true, + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/x-pack/plugins/observability_solution/investigate/common/schema/create.ts b/packages/kbn-investigation-shared/src/schema/create.ts similarity index 86% rename from x-pack/plugins/observability_solution/investigate/common/schema/create.ts rename to packages/kbn-investigation-shared/src/schema/create.ts index f2ba04de9e88a..99073087d0b43 100644 --- a/x-pack/plugins/observability_solution/investigate/common/schema/create.ts +++ b/packages/kbn-investigation-shared/src/schema/create.ts @@ -1,9 +1,11 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ + import * as t from 'io-ts'; import { investigationResponseSchema } from './investigation'; import { alertOriginSchema, blankOriginSchema } from './origin'; diff --git a/packages/kbn-investigation-shared/src/schema/create_notes.ts b/packages/kbn-investigation-shared/src/schema/create_notes.ts new file mode 100644 index 0000000000000..a920a41108e51 --- /dev/null +++ b/packages/kbn-investigation-shared/src/schema/create_notes.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as t from 'io-ts'; +import { investigationNoteResponseSchema } from './investigation_note'; + +const createInvestigationNoteParamsSchema = t.type({ + path: t.type({ + id: t.string, + }), + body: t.type({ + content: t.string, + }), +}); + +const createInvestigationNoteResponseSchema = investigationNoteResponseSchema; + +type CreateInvestigationNoteInput = t.OutputOf< + typeof createInvestigationNoteParamsSchema.props.body +>; +type CreateInvestigationNoteParams = t.TypeOf< + typeof createInvestigationNoteParamsSchema.props.body +>; +type CreateInvestigationNoteResponse = t.OutputOf; + +export { createInvestigationNoteParamsSchema, createInvestigationNoteResponseSchema }; +export type { + CreateInvestigationNoteInput, + CreateInvestigationNoteParams, + CreateInvestigationNoteResponse, +}; diff --git a/packages/kbn-investigation-shared/src/schema/delete.ts b/packages/kbn-investigation-shared/src/schema/delete.ts new file mode 100644 index 0000000000000..de0381a6161f3 --- /dev/null +++ b/packages/kbn-investigation-shared/src/schema/delete.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as t from 'io-ts'; + +const deleteInvestigationParamsSchema = t.type({ + path: t.type({ + id: t.string, + }), +}); + +type DeleteInvestigationParams = t.TypeOf; // Parsed payload used by the backend + +export { deleteInvestigationParamsSchema }; +export type { DeleteInvestigationParams }; diff --git a/x-pack/plugins/observability_solution/investigate/common/schema/find.ts b/packages/kbn-investigation-shared/src/schema/find.ts similarity index 83% rename from x-pack/plugins/observability_solution/investigate/common/schema/find.ts rename to packages/kbn-investigation-shared/src/schema/find.ts index 4eb9d6f9bf66c..048a2f01c064a 100644 --- a/x-pack/plugins/observability_solution/investigate/common/schema/find.ts +++ b/packages/kbn-investigation-shared/src/schema/find.ts @@ -1,9 +1,11 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ + import * as t from 'io-ts'; import { investigationResponseSchema } from './investigation'; diff --git a/x-pack/plugins/observability_solution/investigate/common/schema/get.ts b/packages/kbn-investigation-shared/src/schema/get.ts similarity index 80% rename from x-pack/plugins/observability_solution/investigate/common/schema/get.ts rename to packages/kbn-investigation-shared/src/schema/get.ts index b30fb9f61cff8..6e2b7d6063ff1 100644 --- a/x-pack/plugins/observability_solution/investigate/common/schema/get.ts +++ b/packages/kbn-investigation-shared/src/schema/get.ts @@ -1,9 +1,11 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ + import * as t from 'io-ts'; import { investigationResponseSchema } from './investigation'; diff --git a/packages/kbn-investigation-shared/src/schema/get_notes.ts b/packages/kbn-investigation-shared/src/schema/get_notes.ts new file mode 100644 index 0000000000000..6162d270a3439 --- /dev/null +++ b/packages/kbn-investigation-shared/src/schema/get_notes.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as t from 'io-ts'; +import { investigationNoteResponseSchema } from './investigation_note'; + +const getInvestigationNotesParamsSchema = t.type({ + path: t.type({ + id: t.string, + }), +}); + +const getInvestigationNotesResponseSchema = t.array(investigationNoteResponseSchema); + +type GetInvestigationNotesResponse = t.OutputOf; + +export { getInvestigationNotesParamsSchema, getInvestigationNotesResponseSchema }; +export type { GetInvestigationNotesResponse }; diff --git a/x-pack/plugins/observability_solution/investigate/common/schema/investigation.ts b/packages/kbn-investigation-shared/src/schema/investigation.ts similarity index 70% rename from x-pack/plugins/observability_solution/investigate/common/schema/investigation.ts rename to packages/kbn-investigation-shared/src/schema/investigation.ts index 23247bba88ab8..d47db8283d02c 100644 --- a/x-pack/plugins/observability_solution/investigate/common/schema/investigation.ts +++ b/packages/kbn-investigation-shared/src/schema/investigation.ts @@ -1,11 +1,14 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ + import * as t from 'io-ts'; import { alertOriginSchema, blankOriginSchema } from './origin'; +import { investigationNoteResponseSchema } from './investigation_note'; const investigationResponseSchema = t.type({ id: t.string, @@ -17,6 +20,7 @@ const investigationResponseSchema = t.type({ }), origin: t.union([alertOriginSchema, blankOriginSchema]), status: t.union([t.literal('ongoing'), t.literal('closed')]), + notes: t.array(investigationNoteResponseSchema), }); type InvestigationResponse = t.OutputOf; diff --git a/packages/kbn-investigation-shared/src/schema/investigation_note.ts b/packages/kbn-investigation-shared/src/schema/investigation_note.ts new file mode 100644 index 0000000000000..f678a70cb929c --- /dev/null +++ b/packages/kbn-investigation-shared/src/schema/investigation_note.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as t from 'io-ts'; + +const investigationNoteResponseSchema = t.type({ + id: t.string, + content: t.string, + createdAt: t.number, + createdBy: t.string, +}); + +type InvestigationNoteResponse = t.OutputOf; + +export { investigationNoteResponseSchema }; +export type { InvestigationNoteResponse }; diff --git a/x-pack/plugins/observability_solution/investigate/common/schema/origin.ts b/packages/kbn-investigation-shared/src/schema/origin.ts similarity index 61% rename from x-pack/plugins/observability_solution/investigate/common/schema/origin.ts rename to packages/kbn-investigation-shared/src/schema/origin.ts index 1c00f5ad73de8..7d5c5447b633d 100644 --- a/x-pack/plugins/observability_solution/investigate/common/schema/origin.ts +++ b/packages/kbn-investigation-shared/src/schema/origin.ts @@ -1,17 +1,14 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ + import * as t from 'io-ts'; const blankOriginSchema = t.type({ type: t.literal('blank') }); const alertOriginSchema = t.type({ type: t.literal('alert'), id: t.string }); -type AlertOrigin = t.OutputOf; -type BlankOrigin = t.OutputOf; - export { alertOriginSchema, blankOriginSchema }; - -export type { AlertOrigin, BlankOrigin }; diff --git a/packages/kbn-investigation-shared/tsconfig.json b/packages/kbn-investigation-shared/tsconfig.json new file mode 100644 index 0000000000000..2f9ddddbeea23 --- /dev/null +++ b/packages/kbn-investigation-shared/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 4fb1008c3b79b..3192d741b3b1a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1020,6 +1020,8 @@ "@kbn/investigate-app-plugin/*": ["x-pack/plugins/observability_solution/investigate_app/*"], "@kbn/investigate-plugin": ["x-pack/plugins/observability_solution/investigate"], "@kbn/investigate-plugin/*": ["x-pack/plugins/observability_solution/investigate/*"], + "@kbn/investigation-shared": ["packages/kbn-investigation-shared"], + "@kbn/investigation-shared/*": ["packages/kbn-investigation-shared/*"], "@kbn/io-ts-utils": ["packages/kbn-io-ts-utils"], "@kbn/io-ts-utils/*": ["packages/kbn-io-ts-utils/*"], "@kbn/ipynb": ["packages/kbn-ipynb"], diff --git a/x-pack/plugins/observability_solution/investigate/common/index.ts b/x-pack/plugins/observability_solution/investigate/common/index.ts index 71585c294f776..7846f257f64fe 100644 --- a/x-pack/plugins/observability_solution/investigate/common/index.ts +++ b/x-pack/plugins/observability_solution/investigate/common/index.ts @@ -14,11 +14,3 @@ export type { export { mergePlainObjects } from './utils/merge_plain_objects'; export { InvestigateWidgetColumnSpan } from './types'; - -export type { CreateInvestigationInput, CreateInvestigationResponse } from './schema/create'; -export type { GetInvestigationParams } from './schema/get'; -export type { FindInvestigationsResponse } from './schema/find'; - -export { createInvestigationParamsSchema } from './schema/create'; -export { getInvestigationParamsSchema } from './schema/get'; -export { findInvestigationsParamsSchema } from './schema/find'; diff --git a/x-pack/plugins/observability_solution/investigate/common/types.ts b/x-pack/plugins/observability_solution/investigate/common/types.ts index e8a3f08cfdc2c..8fdd1968f2125 100644 --- a/x-pack/plugins/observability_solution/investigate/common/types.ts +++ b/x-pack/plugins/observability_solution/investigate/common/types.ts @@ -35,7 +35,7 @@ export interface Investigation { export interface InvestigationNote { id: string; createdAt: number; - createdBy: AuthenticatedUser; + createdBy: string; content: string; } diff --git a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigate_widget.tsx b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigate_widget.tsx index a29614f74782b..984058a1829c0 100644 --- a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigate_widget.tsx +++ b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigate_widget.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useContext, createContext } from 'react'; +import { createContext } from 'react'; import type { InvestigateWidgetCreate } from '../../common'; export interface UseInvestigateWidgetApi< @@ -17,9 +17,3 @@ export interface UseInvestigateWidgetApi< const InvestigateWidgetApiContext = createContext(undefined); export const InvestigateWidgetApiContextProvider = InvestigateWidgetApiContext.Provider; - -export function useInvestigateWidget(): UseInvestigateWidgetApi | undefined { - const context = useContext(InvestigateWidgetApiContext); - - return context; -} diff --git a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/investigation_store.ts b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/investigation_store.ts index 0b47427e16802..4c9b7ea71cffa 100644 --- a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/investigation_store.ts +++ b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/investigation_store.ts @@ -159,7 +159,7 @@ export function createInvestigationStore({ notes: prevInvestigation.notes.concat({ id: v4(), createdAt: Date.now(), - createdBy: user, + createdBy: user.username, content: note, }), }; diff --git a/x-pack/plugins/observability_solution/investigate/public/plugin.tsx b/x-pack/plugins/observability_solution/investigate/public/plugin.tsx index 6ac60dbb20751..b54454f63b455 100644 --- a/x-pack/plugins/observability_solution/investigate/public/plugin.tsx +++ b/x-pack/plugins/observability_solution/investigate/public/plugin.tsx @@ -4,10 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { CoreSetup, CoreStart, PluginInitializerContext, Plugin } from '@kbn/core/public'; +import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; import type { Logger } from '@kbn/logging'; import { useMemo } from 'react'; -import { useInvestigateWidget } from './hooks/use_investigate_widget'; import { createUseInvestigation } from './hooks/use_investigation'; import type { ConfigSchema, @@ -73,7 +72,6 @@ export class InvestigatePlugin to, }); }, - useInvestigateWidget, }; } } diff --git a/x-pack/plugins/observability_solution/investigate/public/types.ts b/x-pack/plugins/observability_solution/investigate/public/types.ts index 8951781be99f2..50da793c5b544 100644 --- a/x-pack/plugins/observability_solution/investigate/public/types.ts +++ b/x-pack/plugins/observability_solution/investigate/public/types.ts @@ -6,13 +6,12 @@ */ /* eslint-disable @typescript-eslint/no-empty-interface*/ -import type { FromSchema } from 'json-schema-to-ts'; -import type { CompatibleJSONSchema } from '@kbn/observability-ai-assistant-plugin/public'; import type { AuthenticatedUser } from '@kbn/core/public'; +import type { CompatibleJSONSchema } from '@kbn/observability-ai-assistant-plugin/public'; +import type { FromSchema } from 'json-schema-to-ts'; import type { InvestigateWidget } from '../common'; import type { GlobalWidgetParameters, InvestigateWidgetCreate } from '../common/types'; import type { UseInvestigationApi } from './hooks/use_investigation'; -import type { UseInvestigateWidgetApi } from './hooks/use_investigate_widget'; export enum ChromeOption { disabled = 'disabled', @@ -84,5 +83,4 @@ export interface InvestigatePublicStart { from: string; to: string; }) => UseInvestigationApi; - useInvestigateWidget: () => UseInvestigateWidgetApi | undefined; } diff --git a/x-pack/plugins/observability_solution/investigate/tsconfig.json b/x-pack/plugins/observability_solution/investigate/tsconfig.json index fbbd221edb33d..c0ba6efeb978a 100644 --- a/x-pack/plugins/observability_solution/investigate/tsconfig.json +++ b/x-pack/plugins/observability_solution/investigate/tsconfig.json @@ -9,8 +9,7 @@ "public/**/*", "typings/**/*", "public/**/*.json", - "server/**/*" - ], + "server/**/*", ], "kbn_references": [ "@kbn/core", "@kbn/logging", diff --git a/x-pack/plugins/observability_solution/investigate_app/public/application.tsx b/x-pack/plugins/observability_solution/investigate_app/public/application.tsx index c277f7f081368..062d3be1f444e 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/application.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/application.tsx @@ -7,14 +7,14 @@ import type { CoreStart, CoreTheme } from '@kbn/core/public'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; -import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config'; +import { Route, Router, Routes } from '@kbn/shared-ux-router'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import type { History } from 'history'; import React, { useMemo } from 'react'; import type { Observable } from 'rxjs'; import { InvestigateAppContextProvider } from './components/investigate_app_context_provider'; import { InvestigateAppKibanaContext } from './hooks/use_kibana'; -import { investigateRouter } from './routes/config'; +import { getRoutes } from './routes/config'; import { InvestigateAppServices } from './services/types'; import type { InvestigateAppStartDependencies } from './types'; @@ -46,6 +46,21 @@ function Application({ [coreStart, pluginsStart, services] ); + const App = () => { + const routes = getRoutes(); + return ( + + {Object.keys(routes).map((path) => { + const { handler, exact } = routes[path]; + const Wrapper = () => { + return handler(); + }; + return ; + })} + + ); + }; + const queryClient = new QueryClient(); return ( @@ -53,11 +68,11 @@ function Application({ - + - + - + diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_abort_signal.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_abort_signal.ts deleted file mode 100644 index cf8f4ce787042..0000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_abort_signal.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useEffect, useRef } from 'react'; - -export function useAbortSignal() { - const controllerRef = useRef(new AbortController()); - - useEffect(() => { - const controller = controllerRef.current; - return () => { - controller.abort(); - }; - }, []); - - return controllerRef.current.signal; -} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_add_investigation_note.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_add_investigation_note.ts new file mode 100644 index 0000000000000..95a470099a9d3 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_add_investigation_note.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { useMutation } from '@tanstack/react-query'; +import { + CreateInvestigationNoteInput, + CreateInvestigationNoteResponse, +} from '@kbn/investigation-shared'; +import { useKibana } from './use_kibana'; + +type ServerError = IHttpFetchError; + +export function useAddInvestigationNote() { + const { + core: { + http, + notifications: { toasts }, + }, + } = useKibana(); + + return useMutation< + CreateInvestigationNoteResponse, + ServerError, + { investigationId: string; note: CreateInvestigationNoteInput }, + { investigationId: string } + >( + ['addInvestigationNote'], + ({ investigationId, note }) => { + const body = JSON.stringify(note); + return http.post( + `/api/observability/investigations/${investigationId}/notes`, + { body, version: '2023-10-31' } + ); + }, + { + onSuccess: (response, {}) => { + // TODO: clear investigationNotes key from queryClient, and push new note to the internal store. + // console.log(response); + toasts.addSuccess('Note saved'); + }, + onError: (error, {}, context) => { + // console.log(error); + }, + } + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation.ts new file mode 100644 index 0000000000000..39f026a47af6f --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { GetInvestigationResponse } from '@kbn/investigation-shared'; +import { useQuery } from '@tanstack/react-query'; +import { investigationKeys } from './query_key_factory'; +import { useKibana } from './use_kibana'; + +export interface Params { + id: string; +} + +export interface UseFetchInvestigationResponse { + isInitialLoading: boolean; + isLoading: boolean; + isRefetching: boolean; + isSuccess: boolean; + isError: boolean; + data: GetInvestigationResponse | undefined; +} + +export function useFetchInvestigation({ id }: Params): UseFetchInvestigationResponse { + const { + core: { + http, + notifications: { toasts }, + }, + } = useKibana(); + + const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({ + queryKey: investigationKeys.fetch({ id }), + queryFn: async ({ signal }) => { + return await http.get(`/api/observability/investigations/${id}`, { + version: '2023-10-31', + signal, + }); + }, + refetchOnWindowFocus: false, + onError: (error: Error) => { + toasts.addError(error, { + title: 'Something went wrong while fetching Investigations', + }); + }, + }); + + return { + data, + isInitialLoading, + isLoading, + isRefetching, + isSuccess, + isError, + }; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts index fef9ce274d63e..db9c4264bdf3e 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts @@ -6,7 +6,7 @@ */ import { useQuery } from '@tanstack/react-query'; -import { FindInvestigationsResponse } from '@kbn/investigate-plugin/common'; +import { FindInvestigationsResponse } from '@kbn/investigation-shared'; import { investigationKeys } from './query_key_factory'; import { useKibana } from './use_kibana'; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_alert_details.tsx b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_alert_details.tsx index 5f3bc3f3c9b6a..0c0cda89d3eb8 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_alert_details.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_alert_details.tsx @@ -10,7 +10,7 @@ import { BASE_RAC_ALERTS_API_PATH, EcsFieldsResponse } from '@kbn/rule-registry- import { useKibana } from './use_kibana'; export interface AlertParams { - id: string; + id?: string; } export interface UseFetchAlertResponse { @@ -40,15 +40,7 @@ export function useFetchAlert({ id }: AlertParams): UseFetchAlertResponse { signal, }); }, - cacheTime: 0, refetchOnWindowFocus: false, - retry: (failureCount, error) => { - if (String(error) === 'Error: Forbidden') { - return false; - } - - return failureCount < 3; - }, onError: (error: Error) => { toasts.addError(error, { title: 'Something went wrong while fetching alert', diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_investigation_details.tsx b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_investigation_details.tsx index 796d8bc561575..f42a15dadbeb2 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_investigation_details.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_get_investigation_details.tsx @@ -6,7 +6,7 @@ */ import { useQuery } from '@tanstack/react-query'; -import { GetInvestigationResponse } from '@kbn/investigate-plugin/common/schema/get'; +import { GetInvestigationResponse } from '@kbn/investigation-shared'; import { investigationKeys } from './query_key_factory'; import { useKibana } from './use_kibana'; @@ -41,15 +41,7 @@ export function useFetchInvestigation({ signal, }); }, - cacheTime: 0, refetchOnWindowFocus: false, - retry: (failureCount, error) => { - if (String(error) === 'Error: Forbidden') { - return false; - } - - return failureCount < 3; - }, onError: (error: Error) => { toasts.addError(error, { title: 'Something went wrong while fetching Investigation', diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_params.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_params.ts deleted file mode 100644 index d29e06bea8b9c..0000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_params.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { type PathsOf, type TypeOf, useParams } from '@kbn/typed-react-router-config'; -import type { InvestigateRoutes } from '../routes/config'; - -export function useInvestigateParams>( - path: TPath -): TypeOf { - return useParams(path)! as TypeOf; -} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_router.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_router.ts deleted file mode 100644 index 40775d54e0605..0000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_investigate_router.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PathsOf, TypeAsArgs, TypeOf } from '@kbn/typed-react-router-config'; -import { useMemo } from 'react'; -import { InvestigateRouter, InvestigateRoutes } from '../routes/config'; -import { investigateRouter } from '../routes/config'; -import { useKibana } from './use_kibana'; - -interface StatefulInvestigateRouter extends InvestigateRouter { - push>( - path: T, - ...params: TypeAsArgs> - ): void; - replace>( - path: T, - ...params: TypeAsArgs> - ): void; -} - -export function useInvestigateRouter(): StatefulInvestigateRouter { - const { - core: { - http, - application: { navigateToApp }, - }, - } = useKibana(); - - const link = (...args: any[]) => { - // @ts-expect-error - return investigateRouter.link(...args); - }; - - return useMemo( - () => ({ - ...investigateRouter, - push: (...args) => { - const next = link(...args); - navigateToApp('investigations', { path: next, replace: false }); - }, - replace: (path, ...args) => { - const next = link(path, ...args); - navigateToApp('investigations', { path: next, replace: true }); - }, - link: (path, ...args) => { - return http.basePath.prepend('/app/investigations' + link(path, ...args)); - }, - }), - [navigateToApp, http.basePath] - ); -} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx index 276d86519dfa4..8dfb18a753ac2 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx @@ -20,7 +20,7 @@ export default meta; const defaultProps: ComponentStoryObj = { args: {}, - render: (props) => , + render: (props) => , }; export const InvestigateViewStory: ComponentStoryObj = { diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.tsx index 86a05ccdd9f34..8004e739f056f 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.tsx @@ -6,27 +6,41 @@ */ import datemath from '@elastic/datemath'; import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; -import type { InvestigateWidgetCreate } from '@kbn/investigate-plugin/public'; import { AuthenticatedUser } from '@kbn/security-plugin/common'; import { keyBy, noop } from 'lodash'; -import React, { useEffect, useMemo, useRef } from 'react'; +import React, { useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { AddObservationUI } from '../../../../components/add_observation_ui'; import { InvestigateSearchBar } from '../../../../components/investigate_search_bar'; import { InvestigateWidgetGrid } from '../../../../components/investigate_widget_grid'; +import { useAddInvestigationNote } from '../../../../hooks/use_add_investigation_note'; import { useDateRange } from '../../../../hooks/use_date_range'; +import { useFetchInvestigation } from '../../../../hooks/use_fetch_investigation'; import { useKibana } from '../../../../hooks/use_kibana'; import { InvestigationNotes } from '../investigation_notes/investigation_notes'; -function InvestigationDetailsWithUser({ user }: { user: AuthenticatedUser }) { +function InvestigationDetailsWithUser({ + user, + investigationId, +}: { + user: AuthenticatedUser; + investigationId: string; +}) { const { dependencies: { start: { investigate }, }, } = useKibana(); - const widgetDefinitions = useMemo(() => investigate.getWidgetDefinitions(), [investigate]); + const widgetDefinitions = investigate.getWidgetDefinitions(); const [range, setRange] = useDateRange(); + const { data: investigationData } = useFetchInvestigation({ id: investigationId }); + const { mutateAsync: addInvestigationNote } = useAddInvestigationNote(); + const handleAddInvestigationNote = async (note: string) => { + await addInvestigationNote({ investigationId, note: { content: note } }); + await addNote(note); + }; + const { addItem, copyItem, @@ -42,33 +56,6 @@ function InvestigationDetailsWithUser({ user }: { user: AuthenticatedUser }) { to: range.end.toISOString(), }); - const createWidget = (widgetCreate: InvestigateWidgetCreate) => { - return addItem(widgetCreate); - }; - - const createWidgetRef = useRef(createWidget); - createWidgetRef.current = createWidget; - - useEffect(() => { - if ( - renderableInvestigation?.parameters.timeRange.from && - renderableInvestigation?.parameters.timeRange.to && - range.start.toISOString() !== renderableInvestigation.parameters.timeRange.from && - range.end.toISOString() !== renderableInvestigation.parameters.timeRange.to - ) { - setRange({ - from: renderableInvestigation.parameters.timeRange.from, - to: renderableInvestigation.parameters.timeRange.to, - }); - } - }, [ - renderableInvestigation?.parameters.timeRange.from, - renderableInvestigation?.parameters.timeRange.to, - range.start, - range.end, - setRange, - ]); - const gridItems = useMemo(() => { const widgetDefinitionsByType = keyBy(widgetDefinitions, 'type'); @@ -88,7 +75,7 @@ function InvestigationDetailsWithUser({ user }: { user: AuthenticatedUser }) { }); }, [renderableInvestigation, widgetDefinitions]); - if (!investigation || !renderableInvestigation || !gridItems) { + if (!investigation || !renderableInvestigation || !gridItems || !investigationData) { return ; } @@ -135,20 +122,24 @@ function InvestigationDetailsWithUser({ user }: { user: AuthenticatedUser }) { { - return createWidgetRef.current(widget); + return addItem(widget); }} /> - + ); } -export function InvestigationDetails({}: {}) { +export function InvestigationDetails({ investigationId }: { investigationId: string }) { const { core: { security }, } = useKibana(); @@ -157,5 +148,12 @@ export function InvestigationDetails({}: {}) { return security.authc.getCurrentUser(); }, [security]); - return user.value ? : null; + if (investigationId == null) { + // TODO: return 404 page + return null; + } + + return user.value ? ( + + ) : null; } diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx index 21f5db7b768d6..09258063839e3 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx @@ -16,8 +16,8 @@ import { } from '@elastic/eui'; import { css } from '@emotion/css'; import { i18n } from '@kbn/i18n'; -import { InvestigationNote } from '@kbn/investigate-plugin/common'; import React from 'react'; +import { InvestigationNote } from '@kbn/investigate-plugin/common'; import { useTheme } from '../../../../hooks/use_theme'; import { ResizableTextInput } from './resizable_text_input'; import { TimelineMessage } from './timeline_message'; @@ -69,7 +69,7 @@ export function InvestigationNotes({ notes, addNote, deleteNote }: Props) { return ( } + icon={} note={currNote} onDelete={() => deleteNote(currNote.id)} /> diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/timeline_message.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/timeline_message.tsx index 31539050f7c52..c8e95ad70c758 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/timeline_message.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/timeline_message.tsx @@ -6,9 +6,9 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiMarkdownFormat, EuiText } from '@elastic/eui'; import { css } from '@emotion/css'; -import { InvestigationNote } from '@kbn/investigate-plugin/common'; // eslint-disable-next-line import/no-extraneous-dependencies import { format } from 'date-fns'; +import { InvestigationNote } from '@kbn/investigate-plugin/common'; import React from 'react'; import { InvestigateTextButton } from '../../../../components/investigate_text_button'; import { useTheme } from '../../../../hooks/use_theme'; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx index ed749ce925ea1..90af6b4591c69 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx @@ -7,15 +7,16 @@ import { EuiButton, EuiButtonEmpty, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React from 'react'; +import { alertOriginSchema } from '@kbn/investigation-shared'; import { ALERT_RULE_CATEGORY } from '@kbn/rule-data-utils/src/default_alerts_as_data'; -import { AlertOrigin } from '@kbn/investigate-plugin/common/schema/origin'; +import React from 'react'; +import { useParams } from 'react-router-dom'; import { paths } from '../../../common/paths'; -import { useKibana } from '../../hooks/use_kibana'; -import { useFetchInvestigation } from '../../hooks/use_get_investigation_details'; -import { useInvestigateParams } from '../../hooks/use_investigate_params'; import { useFetchAlert } from '../../hooks/use_get_alert_details'; +import { useFetchInvestigation } from '../../hooks/use_get_investigation_details'; +import { useKibana } from '../../hooks/use_kibana'; import { InvestigationDetails } from './components/investigation_details'; +import { InvestigationDetailsPathParams } from './types'; export function InvestigationDetailsPage() { const { @@ -27,9 +28,7 @@ export function InvestigationDetailsPage() { }, } = useKibana(); - const { - path: { id }, - } = useInvestigateParams('/{id}'); + const { investigationId } = useParams(); const ObservabilityPageTemplate = observabilityShared.navigation.PageTemplate; @@ -37,17 +36,15 @@ export function InvestigationDetailsPage() { data: investigationDetails, isLoading: isFetchInvestigationLoading, isError: isFetchInvestigationError, - } = useFetchInvestigation({ id }); + } = useFetchInvestigation({ id: investigationId }); - const alertId = investigationDetails ? (investigationDetails.origin as AlertOrigin).id : ''; + const alertId = alertOriginSchema.is(investigationDetails?.origin) + ? investigationDetails?.origin.id + : undefined; - const { - data: alertDetails, - isLoading: isFetchAlertLoading, - isError: isFetchAlertError, - } = useFetchAlert({ id: alertId }); + const { data: alertDetails } = useFetchAlert({ id: alertId }); - if (isFetchInvestigationLoading || isFetchAlertLoading) { + if (isFetchInvestigationLoading) { return (

{i18n.translate('xpack.investigateApp.fetchInvestigation.loadingLabel', { @@ -57,7 +54,7 @@ export function InvestigationDetailsPage() { ); } - if (isFetchInvestigationError || isFetchAlertError) { + if (isFetchInvestigationError) { return (

{i18n.translate('xpack.investigateApp.fetchInvestigation.errorLabel', { @@ -109,7 +106,7 @@ export function InvestigationDetailsPage() { ], }} > - + ); } diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/types.ts b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/types.ts new file mode 100644 index 0000000000000..1f9cb337f3d28 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/types.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface InvestigationDetailsPathParams { + investigationId: string; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/routes/config.tsx b/x-pack/plugins/observability_solution/investigate_app/public/routes/config.tsx index aaea81ec3d574..7c6d4e894a644 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/routes/config.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/routes/config.tsx @@ -4,33 +4,31 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { createRouter } from '@kbn/typed-react-router-config'; -import * as t from 'io-ts'; import React from 'react'; import { InvestigationDetailsPage } from '../pages/details/investigation_details_page'; import { InvestigationListPage } from '../pages/list/investigation_list_page'; -/** - * The array of route definitions to be used when the application - * creates the routes. - */ -const investigateRoutes = { - '/': { - element: , - }, - '/new': { - element: , - }, - '/{id}': { - element: , - params: t.type({ - path: t.type({ id: t.string }), - }), - }, +export const getRoutes = (): { + [path: string]: { + handler: () => React.ReactElement; + params: Record; + exact: boolean; + }; +} => { + return { + '/': { + handler: () => { + return ; + }, + params: {}, + exact: true, + }, + '/:investigationId': { + handler: () => { + return ; + }, + params: {}, + exact: true, + }, + }; }; - -export type InvestigateRoutes = typeof investigateRoutes; - -export const investigateRouter = createRouter(investigateRoutes); - -export type InvestigateRouter = typeof investigateRouter; diff --git a/x-pack/plugins/observability_solution/investigate_app/server/models/investigation.ts b/x-pack/plugins/observability_solution/investigate_app/server/models/investigation.ts index 041b1d217c208..9b66a71ce3a9b 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/models/investigation.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/models/investigation.ts @@ -5,8 +5,9 @@ * 2.0. */ -import { alertOriginSchema, blankOriginSchema } from '@kbn/investigate-plugin/common/schema/origin'; +import { alertOriginSchema, blankOriginSchema } from '@kbn/investigation-shared'; import * as t from 'io-ts'; +import { investigationNoteSchema } from './investigation_note'; export const investigationSchema = t.type({ id: t.string, @@ -18,6 +19,7 @@ export const investigationSchema = t.type({ }), origin: t.union([alertOriginSchema, blankOriginSchema]), status: t.union([t.literal('ongoing'), t.literal('closed')]), + notes: t.array(investigationNoteSchema), }); export type Investigation = t.TypeOf; diff --git a/x-pack/plugins/observability_solution/investigate_app/server/models/investigation_note.ts b/x-pack/plugins/observability_solution/investigate_app/server/models/investigation_note.ts new file mode 100644 index 0000000000000..d94ec1a94c108 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/models/investigation_note.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +export const investigationNoteSchema = t.type({ + id: t.string, + createdAt: t.number, + createdBy: t.string, + content: t.string, +}); + +export type InvestigationNote = t.TypeOf; +export type StoredInvestigationNote = t.OutputOf; diff --git a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts index f745b46bb54b8..65f61d7f0a814 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts @@ -5,14 +5,22 @@ * 2.0. */ -import { createInvestigationParamsSchema } from '@kbn/investigate-plugin/common'; -import { findInvestigationsParamsSchema } from '@kbn/investigate-plugin/common'; -import { getInvestigationParamsSchema } from '@kbn/investigate-plugin/common'; +import { + createInvestigationNoteParamsSchema, + createInvestigationParamsSchema, + deleteInvestigationParamsSchema, + findInvestigationsParamsSchema, + getInvestigationNotesParamsSchema, + getInvestigationParamsSchema, +} from '@kbn/investigation-shared'; import { createInvestigation } from '../services/create_investigation'; -import { investigationRepositoryFactory } from '../services/investigation_repository'; -import { createInvestigateAppServerRoute } from './create_investigate_app_server_route'; +import { createInvestigationNote } from '../services/create_investigation_note'; +import { deleteInvestigation } from '../services/delete_investigation'; import { findInvestigations } from '../services/find_investigations'; import { getInvestigation } from '../services/get_investigation'; +import { getInvestigationNotes } from '../services/get_investigation_notes'; +import { investigationRepositoryFactory } from '../services/investigation_repository'; +import { createInvestigateAppServerRoute } from './create_investigate_app_server_route'; const createInvestigationRoute = createInvestigateAppServerRoute({ endpoint: 'POST /api/observability/investigations 2023-10-31', @@ -56,11 +64,56 @@ const getInvestigationRoute = createInvestigateAppServerRoute({ }, }); +const deleteInvestigationRoute = createInvestigateAppServerRoute({ + endpoint: 'DELETE /api/observability/investigations/{id} 2023-10-31', + options: { + tags: [], + }, + params: deleteInvestigationParamsSchema, + handler: async (params) => { + const soClient = (await params.context.core).savedObjects.client; + const repository = investigationRepositoryFactory({ soClient, logger: params.logger }); + + return await deleteInvestigation(params.params.path.id, repository); + }, +}); + +const createInvestigationNoteRoute = createInvestigateAppServerRoute({ + endpoint: 'POST /api/observability/investigations/{id}/notes 2023-10-31', + options: { + tags: [], + }, + params: createInvestigationNoteParamsSchema, + handler: async (params) => { + const soClient = (await params.context.core).savedObjects.client; + const repository = investigationRepositoryFactory({ soClient, logger: params.logger }); + + return await createInvestigationNote(params.params.path.id, params.params.body, repository); + }, +}); + +const getInvestigationNotesRoute = createInvestigateAppServerRoute({ + endpoint: 'GET /api/observability/investigations/{id}/notes 2023-10-31', + options: { + tags: [], + }, + params: getInvestigationNotesParamsSchema, + handler: async (params) => { + const soClient = (await params.context.core).savedObjects.client; + const repository = investigationRepositoryFactory({ soClient, logger: params.logger }); + + return await getInvestigationNotes(params.params.path.id, repository); + }, +}); + export function getGlobalInvestigateAppServerRouteRepository() { return { ...createInvestigationRoute, ...findInvestigationsRoute, ...getInvestigationRoute, + ...deleteInvestigationRoute, + ...createInvestigationNoteRoute, + ...getInvestigationNotesRoute, }; } diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts index 52b5953fb8095..ee79ec34e1d36 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts @@ -5,10 +5,7 @@ * 2.0. */ -import { - CreateInvestigationInput, - CreateInvestigationResponse, -} from '@kbn/investigate-plugin/common'; +import { CreateInvestigationInput, CreateInvestigationResponse } from '@kbn/investigation-shared'; import { InvestigationRepository } from './investigation_repository'; enum InvestigationStatus { @@ -25,6 +22,7 @@ export async function createInvestigation( createdAt: Date.now(), createdBy: 'elastic', status: InvestigationStatus.ongoing, + notes: [], }; await repository.save(investigation); diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts new file mode 100644 index 0000000000000..57e1b3312dc45 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + CreateInvestigationNoteInput, + CreateInvestigationNoteResponse, +} from '@kbn/investigation-shared'; +import { v4 } from 'uuid'; +import { InvestigationRepository } from './investigation_repository'; + +export async function createInvestigationNote( + investigationId: string, + params: CreateInvestigationNoteInput, + repository: InvestigationRepository +): Promise { + const investigation = await repository.findById(investigationId); + + const investigationNote = { + id: v4(), + content: params.content, + createdBy: 'TODO: get user from request', + createdAt: Date.now(), + }; + investigation.notes.push(investigationNote); + + await repository.save(investigation); + + return investigationNote; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/delete_investigation.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/delete_investigation.ts new file mode 100644 index 0000000000000..f615a6fb61a33 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/delete_investigation.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { InvestigationRepository } from './investigation_repository'; + +export async function deleteInvestigation( + id: string, + repository: InvestigationRepository +): Promise { + await repository.deleteById(id); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts index 0db6f2eb587b8..a3ea2db46d357 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts @@ -5,11 +5,11 @@ * 2.0. */ -import { FindInvestigationsResponse } from '@kbn/investigate-plugin/common'; import { FindInvestigationsParams, + FindInvestigationsResponse, findInvestigationsResponseSchema, -} from '@kbn/investigate-plugin/common/schema/find'; +} from '@kbn/investigation-shared'; import { InvestigationRepository } from './investigation_repository'; export async function findInvestigations( diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation.ts index e57111af99e32..1aed642da756d 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation.ts @@ -5,8 +5,11 @@ * 2.0. */ -import { GetInvestigationParams } from '@kbn/investigate-plugin/common'; -import { GetInvestigationResponse } from '@kbn/investigate-plugin/common/schema/get'; +import { + GetInvestigationParams, + GetInvestigationResponse, + getInvestigationResponseSchema, +} from '@kbn/investigation-shared'; import { InvestigationRepository } from './investigation_repository'; export async function getInvestigation( @@ -15,5 +18,5 @@ export async function getInvestigation( ): Promise { const investigation = await repository.findById(params.id); - return investigation; + return getInvestigationResponseSchema.encode(investigation); } diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation_notes.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation_notes.ts new file mode 100644 index 0000000000000..510798e5007a5 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_investigation_notes.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + GetInvestigationNotesResponse, + getInvestigationNotesResponseSchema, +} from '@kbn/investigation-shared'; +import { InvestigationRepository } from './investigation_repository'; + +export async function getInvestigationNotes( + investigationId: string, + repository: InvestigationRepository +): Promise { + const investigation = await repository.findById(investigationId); + + return getInvestigationNotesResponseSchema.encode(investigation.notes); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json index 6647b16356984..174c81ba6f6df 100644 --- a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json @@ -21,7 +21,6 @@ "@kbn/react-kibana-context-theme", "@kbn/shared-ux-link-redirect-app", "@kbn/kibana-react-plugin", - "@kbn/typed-react-router-config", "@kbn/i18n", "@kbn/embeddable-plugin", "@kbn/observability-ai-assistant-plugin", @@ -54,5 +53,7 @@ "@kbn/core-saved-objects-server", "@kbn/rule-registry-plugin", "@kbn/rule-data-utils", + "@kbn/shared-ux-router", + "@kbn/investigation-shared", ], } diff --git a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_create_investigation.tsx b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_create_investigation.tsx index e41674b2e78be..11a797b775577 100644 --- a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_create_investigation.tsx +++ b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_create_investigation.tsx @@ -6,13 +6,13 @@ */ import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; -import { QueryKey, useMutation } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { CreateInvestigationInput, CreateInvestigationResponse, -} from '@kbn/investigate-plugin/common'; -import { FindInvestigationsResponse } from '@kbn/investigate-plugin/common'; + FindInvestigationsResponse, +} from '@kbn/investigation-shared'; +import { QueryKey, useMutation } from '@tanstack/react-query'; import { useKibana } from '../../../utils/kibana_react'; type ServerError = IHttpFetchError; diff --git a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_fetch_investigations_by_alert.tsx b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_fetch_investigations_by_alert.tsx index d9376f30d9579..67867858310f8 100644 --- a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_fetch_investigations_by_alert.tsx +++ b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_fetch_investigations_by_alert.tsx @@ -5,8 +5,8 @@ * 2.0. */ +import { FindInvestigationsResponse } from '@kbn/investigation-shared'; import { useQuery } from '@tanstack/react-query'; -import { FindInvestigationsResponse } from '@kbn/investigate-plugin/common'; import { useKibana } from '../../../utils/kibana_react'; export interface InvestigationsByAlertParams { diff --git a/x-pack/plugins/observability_solution/observability/tsconfig.json b/x-pack/plugins/observability_solution/observability/tsconfig.json index 53390c6c2d535..0a65077d42a1e 100644 --- a/x-pack/plugins/observability_solution/observability/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability/tsconfig.json @@ -111,6 +111,7 @@ "@kbn/observability-alerting-rule-utils", "@kbn/core-ui-settings-server-mocks", "@kbn/investigate-plugin", + "@kbn/investigation-shared", ], "exclude": [ "target/**/*" diff --git a/yarn.lock b/yarn.lock index 4768e377e05e0..d70da04a9070f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5320,6 +5320,10 @@ version "0.0.0" uid "" +"@kbn/investigation-shared@link:packages/kbn-investigation-shared": + version "0.0.0" + uid "" + "@kbn/io-ts-utils@link:packages/kbn-io-ts-utils": version "0.0.0" uid ""