;
+}
+
+export class Locator implements PersistableState
, LocatorPublic
{
+ public readonly migrations: PersistableState
['migrations'];
+
+ constructor(
+ public readonly definition: LocatorDefinition
,
+ protected readonly deps: LocatorDependencies
+ ) {
+ this.migrations = definition.migrations || {};
+ }
+
+ // PersistableState
-------------------------------------------------------
+
+ public readonly telemetry: PersistableState
['telemetry'] = (
+ state: P,
+ stats: Record
+ ): Record => {
+ return this.definition.telemetry ? this.definition.telemetry(state, stats) : stats;
+ };
+
+ public readonly inject: PersistableState['inject'] = (
+ state: P,
+ references: SavedObjectReference[]
+ ): P => {
+ return this.definition.inject ? this.definition.inject(state, references) : state;
+ };
+
+ public readonly extract: PersistableState
['extract'] = (
+ state: P
+ ): { state: P; references: SavedObjectReference[] } => {
+ return this.definition.extract ? this.definition.extract(state) : { state, references: [] };
+ };
+
+ // LocatorPublic
----------------------------------------------------------
+
+ public async getLocation(params: P): Promise {
+ return await this.definition.getLocation(params);
+ }
+
+ public async navigate(
+ params: P,
+ { replace = false }: LocatorNavigationParams = {}
+ ): Promise {
+ const location = await this.getLocation(params);
+ await this.deps.navigate(location, {
+ replace,
+ });
+ }
+}
diff --git a/src/plugins/share/common/url_service/locators/locator_client.ts b/src/plugins/share/common/url_service/locators/locator_client.ts
new file mode 100644
index 0000000000000..168cc02d03ff1
--- /dev/null
+++ b/src/plugins/share/common/url_service/locators/locator_client.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 type { SerializableState } from 'src/plugins/kibana_utils/common';
+import type { LocatorDependencies } from './locator';
+import type { LocatorDefinition, LocatorPublic, ILocatorClient } from './types';
+import { Locator } from './locator';
+
+export type LocatorClientDependencies = LocatorDependencies;
+
+export class LocatorClient implements ILocatorClient {
+ /**
+ * Collection of registered locators.
+ */
+ protected locators: Map> = new Map();
+
+ constructor(protected readonly deps: LocatorClientDependencies) {}
+
+ /**
+ * Creates and register a URL locator.
+ *
+ * @param definition A definition of URL locator.
+ * @returns A public interface of URL locator.
+ */
+ public create(definition: LocatorDefinition
): LocatorPublic
{
+ const locator = new Locator
(definition, this.deps);
+
+ this.locators.set(definition.id, locator);
+
+ return locator;
+ }
+
+ /**
+ * Returns a previously registered URL locator.
+ *
+ * @param id ID of a URL locator.
+ * @returns A public interface of a registered URL locator.
+ */
+ public get
(id: string): undefined | LocatorPublic
{
+ return this.locators.get(id);
+ }
+}
diff --git a/src/plugins/share/common/url_service/locators/types.ts b/src/plugins/share/common/url_service/locators/types.ts
new file mode 100644
index 0000000000000..d811ae0fd4aa2
--- /dev/null
+++ b/src/plugins/share/common/url_service/locators/types.ts
@@ -0,0 +1,91 @@
+/*
+ * 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 { PersistableState, SerializableState } from 'src/plugins/kibana_utils/common';
+
+/**
+ * URL locator registry.
+ */
+export interface ILocatorClient {
+ /**
+ * Create and register a new locator.
+ *
+ * @param urlGenerator Definition of the new locator.
+ */
+ create
(locatorDefinition: LocatorDefinition
): LocatorPublic
;
+
+ /**
+ * Retrieve a previously registered locator.
+ *
+ * @param id Unique ID of the locator.
+ */
+ get
(id: string): undefined | LocatorPublic
;
+}
+
+/**
+ * A convenience interface used to define and register a locator.
+ */
+export interface LocatorDefinition
+ extends Partial> {
+ /**
+ * Unique ID of the locator. Should be constant and unique across Kibana.
+ */
+ id: string;
+
+ /**
+ * Returns a deep link, including location state, which can be used for
+ * navigation in Kibana.
+ *
+ * @param params Parameters from which to generate a Kibana location.
+ */
+ getLocation(params: P): Promise;
+}
+
+/**
+ * Public interface of a registered locator.
+ */
+export interface LocatorPublic {
+ /**
+ * Returns a relative URL to the client-side redirect endpoint using this
+ * locator. (This method is necessary for compatibility with URL generators.)
+ */
+ getLocation(params: P): Promise;
+
+ /**
+ * Navigate using the `core.application.navigateToApp()` method to a Kibana
+ * location generated by this locator. This method is available only on the
+ * browser.
+ */
+ navigate(params: P, navigationParams?: LocatorNavigationParams): Promise;
+}
+
+export interface LocatorNavigationParams {
+ replace?: boolean;
+}
+
+/**
+ * This interface represents a location in Kibana to which one can navigate
+ * using the `core.application.navigateToApp()` method.
+ */
+export interface KibanaLocation {
+ /**
+ * Kibana application ID.
+ */
+ app: string;
+
+ /**
+ * A URL route within a Kibana application.
+ */
+ route: string;
+
+ /**
+ * A serializable location state object, which the app can use to determine
+ * what should be displayed on the screen.
+ */
+ state: S;
+}
diff --git a/src/plugins/share/common/url_service/url_service.ts b/src/plugins/share/common/url_service/url_service.ts
new file mode 100644
index 0000000000000..0c3a0aabb750b
--- /dev/null
+++ b/src/plugins/share/common/url_service/url_service.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 { LocatorClient, LocatorClientDependencies } from './locators';
+
+export type UrlServiceDependencies = LocatorClientDependencies;
+
+/**
+ * Common URL Service client interface for server-side and client-side.
+ */
+export class UrlService {
+ /**
+ * Client to work with locators.
+ */
+ locators: LocatorClient = new LocatorClient(this.deps);
+
+ constructor(protected readonly deps: UrlServiceDependencies) {}
+}
diff --git a/src/plugins/share/public/plugin.ts b/src/plugins/share/public/plugin.ts
index 14d74e055cbd9..eb7c46cdaef86 100644
--- a/src/plugins/share/public/plugin.ts
+++ b/src/plugins/share/public/plugin.ts
@@ -18,6 +18,7 @@ import {
UrlGeneratorsSetup,
UrlGeneratorsStart,
} from './url_generators/url_generator_service';
+import { UrlService } from '../common/url_service';
export interface ShareSetupDependencies {
securityOss?: SecurityOssPluginSetup;
@@ -27,16 +28,60 @@ export interface ShareStartDependencies {
securityOss?: SecurityOssPluginStart;
}
+/** @public */
+export type SharePluginSetup = ShareMenuRegistrySetup & {
+ /**
+ * @deprecated
+ *
+ * URL Generators are deprecated use UrlService instead.
+ */
+ urlGenerators: UrlGeneratorsSetup;
+
+ /**
+ * Utilities to work with URL locators and short URLs.
+ */
+ url: UrlService;
+};
+
+/** @public */
+export type SharePluginStart = ShareMenuManagerStart & {
+ /**
+ * @deprecated
+ *
+ * URL Generators are deprecated use UrlService instead.
+ */
+ urlGenerators: UrlGeneratorsStart;
+
+ /**
+ * Utilities to work with URL locators and short URLs.
+ */
+ url: UrlService;
+};
+
export class SharePlugin implements Plugin {
private readonly shareMenuRegistry = new ShareMenuRegistry();
private readonly shareContextMenu = new ShareMenuManager();
private readonly urlGeneratorsService = new UrlGeneratorsService();
+ private url?: UrlService;
public setup(core: CoreSetup, plugins: ShareSetupDependencies): SharePluginSetup {
core.application.register(createShortUrlRedirectApp(core, window.location));
+
+ this.url = new UrlService({
+ navigate: async (location, { replace = false } = {}) => {
+ const [start] = await core.getStartServices();
+ await start.application.navigateToApp(location.app, {
+ path: location.route,
+ state: location.state,
+ replace,
+ });
+ },
+ });
+
return {
...this.shareMenuRegistry.setup(),
urlGenerators: this.urlGeneratorsService.setup(core),
+ url: this.url,
};
}
@@ -48,16 +93,7 @@ export class SharePlugin implements Plugin {
plugins.securityOss?.anonymousAccess
),
urlGenerators: this.urlGeneratorsService.start(core),
+ url: this.url!,
};
}
}
-
-/** @public */
-export type SharePluginSetup = ShareMenuRegistrySetup & {
- urlGenerators: UrlGeneratorsSetup;
-};
-
-/** @public */
-export type SharePluginStart = ShareMenuManagerStart & {
- urlGenerators: UrlGeneratorsStart;
-};
diff --git a/src/plugins/share/public/url_generators/README.md b/src/plugins/share/public/url_generators/README.md
index 39ee5f2901e91..f948354aad959 100644
--- a/src/plugins/share/public/url_generators/README.md
+++ b/src/plugins/share/public/url_generators/README.md
@@ -1,3 +1,9 @@
+# URL Generators are deprecated
+
+__Below is documentation of URL Generators, which are now deprecated and will be removed in favor of URL locators in 7.14.__
+
+---
+
## URL Generator Services
Developers who maintain pages in Kibana that other developers may want to link to
diff --git a/src/plugins/share/public/url_generators/url_generator_service.ts b/src/plugins/share/public/url_generators/url_generator_service.ts
index 982f0692102df..5a8e7a1b5c17a 100644
--- a/src/plugins/share/public/url_generators/url_generator_service.ts
+++ b/src/plugins/share/public/url_generators/url_generator_service.ts
@@ -13,10 +13,20 @@ import { UrlGeneratorInternal } from './url_generator_internal';
import { UrlGeneratorContract } from './url_generator_contract';
export interface UrlGeneratorsStart {
+ /**
+ * @deprecated
+ *
+ * URL Generators are deprecated, use URL locators in UrlService instead.
+ */
getUrlGenerator: (urlGeneratorId: T) => UrlGeneratorContract;
}
export interface UrlGeneratorsSetup {
+ /**
+ * @deprecated
+ *
+ * URL Generators are deprecated, use URL locators in UrlService instead.
+ */
registerUrlGenerator: (
generator: UrlGeneratorsDefinition
) => UrlGeneratorContract;
diff --git a/src/plugins/share/server/plugin.ts b/src/plugins/share/server/plugin.ts
index 744a4148215c3..6e3c68935f77b 100644
--- a/src/plugins/share/server/plugin.ts
+++ b/src/plugins/share/server/plugin.ts
@@ -12,11 +12,30 @@ import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server';
import { createRoutes } from './routes/create_routes';
import { url } from './saved_objects';
import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../common/constants';
+import { UrlService } from '../common/url_service';
+
+/** @public */
+export interface SharePluginSetup {
+ url: UrlService;
+}
+
+/** @public */
+export interface SharePluginStart {
+ url: UrlService;
+}
+
+export class SharePlugin implements Plugin {
+ private url?: UrlService;
-export class SharePlugin implements Plugin {
constructor(private readonly initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup) {
+ this.url = new UrlService({
+ navigate: async () => {
+ throw new Error('Locator .navigate() does not work on server.');
+ },
+ });
+
createRoutes(core, this.initializerContext.logger.get());
core.savedObjects.registerType(url);
core.uiSettings.register({
@@ -41,10 +60,18 @@ export class SharePlugin implements Plugin {
schema: schema.boolean(),
},
});
+
+ return {
+ url: this.url,
+ };
}
public start() {
this.initializerContext.logger.get().debug('Starting plugin');
+
+ return {
+ url: this.url!,
+ };
}
public stop() {
diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json
index 1d37c25f52fd4..7b6c4ba9788f1 100644
--- a/src/plugins/telemetry/schema/oss_plugins.json
+++ b/src/plugins/telemetry/schema/oss_plugins.json
@@ -3184,6 +3184,137 @@
}
}
},
+ "integrations": {
+ "properties": {
+ "appId": {
+ "type": "keyword",
+ "_meta": {
+ "description": "The application being tracked"
+ }
+ },
+ "viewId": {
+ "type": "keyword",
+ "_meta": {
+ "description": "Always `main`"
+ }
+ },
+ "clicks_total": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the application since we started counting them"
+ }
+ },
+ "clicks_7_days": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the application over the last 7 days"
+ }
+ },
+ "clicks_30_days": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the application over the last 30 days"
+ }
+ },
+ "clicks_90_days": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the application over the last 90 days"
+ }
+ },
+ "minutes_on_screen_total": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application is active and on-screen since we started counting them."
+ }
+ },
+ "minutes_on_screen_7_days": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application is active and on-screen over the last 7 days"
+ }
+ },
+ "minutes_on_screen_30_days": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application is active and on-screen over the last 30 days"
+ }
+ },
+ "minutes_on_screen_90_days": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application is active and on-screen over the last 90 days"
+ }
+ },
+ "views": {
+ "type": "array",
+ "items": {
+ "properties": {
+ "appId": {
+ "type": "keyword",
+ "_meta": {
+ "description": "The application being tracked"
+ }
+ },
+ "viewId": {
+ "type": "keyword",
+ "_meta": {
+ "description": "The application view being tracked"
+ }
+ },
+ "clicks_total": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the application sub view since we started counting them"
+ }
+ },
+ "clicks_7_days": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the active application sub view over the last 7 days"
+ }
+ },
+ "clicks_30_days": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the active application sub view over the last 30 days"
+ }
+ },
+ "clicks_90_days": {
+ "type": "long",
+ "_meta": {
+ "description": "General number of clicks in the active application sub view over the last 90 days"
+ }
+ },
+ "minutes_on_screen_total": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application sub view is active and on-screen since we started counting them."
+ }
+ },
+ "minutes_on_screen_7_days": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application is active and on-screen active application sub view over the last 7 days"
+ }
+ },
+ "minutes_on_screen_30_days": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application is active and on-screen active application sub view over the last 30 days"
+ }
+ },
+ "minutes_on_screen_90_days": {
+ "type": "float",
+ "_meta": {
+ "description": "Minutes the application is active and on-screen active application sub view over the last 90 days"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"ingestManager": {
"properties": {
"appId": {
diff --git a/src/plugins/timelion/public/components/timelion_deprecation.tsx b/src/plugins/timelion/public/components/timelion_deprecation.tsx
index efcef88b3d0a2..117aabed6773c 100644
--- a/src/plugins/timelion/public/components/timelion_deprecation.tsx
+++ b/src/plugins/timelion/public/components/timelion_deprecation.tsx
@@ -19,7 +19,7 @@ export const TimelionDeprecation = ({ links }: DocLinksStart) => {
title={
diff --git a/src/plugins/timelion/server/deprecations.ts b/src/plugins/timelion/server/deprecations.ts
index e65d72cb460df..3c344e1d4a8d8 100644
--- a/src/plugins/timelion/server/deprecations.ts
+++ b/src/plugins/timelion/server/deprecations.ts
@@ -30,7 +30,7 @@ export const showWarningMessageIfTimelionSheetWasFound = async (
const count = await getTimelionSheetsCount(savedObjectsClient);
if (count > 0) {
logger.warn(
- 'Deprecated since 7.0, the Timelion app will be removed in the last 7.x minor version. To continue using your Timelion worksheets, migrate them to a dashboard. See https://www.elastic.co/guide/en/kibana/current/create-panels-with-timelion.html.'
+ 'Deprecated since 7.0, the Timelion app will be removed in 7.16. To continue using your Timelion worksheets, migrate them to a dashboard. See https://www.elastic.co/guide/en/kibana/current/create-panels-with-timelion.html.'
);
}
};
@@ -49,7 +49,7 @@ export async function getDeprecations({
if (count > 0) {
deprecations.push({
- message: `You have ${count} Timelion worksheets. The Timelion app will be removed in the last 7.x minor version. To continue using your Timelion worksheets, migrate them to a dashboard.`,
+ message: `You have ${count} Timelion worksheets. The Timelion app will be removed in 7.16. To continue using your Timelion worksheets, migrate them to a dashboard.`,
documentationUrl:
'https://www.elastic.co/guide/en/kibana/current/create-panels-with-timelion.html',
level: 'warning',
diff --git a/x-pack/build_chromium/README.md b/x-pack/build_chromium/README.md
index efa4d8eaa5cfc..267de376c68ff 100644
--- a/x-pack/build_chromium/README.md
+++ b/x-pack/build_chromium/README.md
@@ -1,26 +1,29 @@
# Chromium build
-We ship our own headless build of Chromium which is significantly smaller than
-the standard binaries shipped by Google. The scripts in this folder can be used
-to accept a commit hash from the Chromium repository, and initialize the build
-on Ubuntu Linux.
+We ship our own headless build of Chromium for Linux and Mac OS, using a
+version of the source that corresponds to the requirements of the Puppeteer
+node module. The scripts in this folder can be used to accept a commit hash
+from the Chromium repository, and initialize the build in a workspace.
## Why do we do this
-By default, Puppeteer will download a zip file containing the Chromium browser for any
-OS. This creates problems on Linux, because Chromium has a dependency on X11, which
-is often not installed for a server environment. We don't want to make a requirement
-for Linux that you need X11 to run Kibana. To work around this, we create our own Chromium
-build, using the
+**Linux**: By default, Puppeteer will download a zip file containing the
+Chromium browser for any OS. This creates problems on Linux, because Chromium
+has a dependency on X11, which is often not installed for a server environment.
+We don't want to make a requirement for Linux that you need X11 to run Kibana.
+To work around this, we create our own Chromium build, using the
[`headless_shell`](https://chromium.googlesource.com/chromium/src/+/5cf4b8b13ed518472038170f8de9db2f6c258fe4/headless)
-build target. There are no (trustworthy) sources of these builds available elsewhere.
-
-Fortunately, creating the custom builds is only necessary for Linux. When you have a build
-of Kibana for Linux, or if you use a Linux desktop to develop Kibana, you have a copy of
-`headless_shell` bundled inside. When you have a Windows or Mac build of Kibana, or use
-either of those for development, you have a copy of the full build of Chromium, which
-was downloaded from the main [Chromium download
-location](https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html).
+build target. There are no (trustworthy) sources of these builds available
+elsewhere.
+
+**Mac**: We do this on Mac because Elastic signs the Kibanna release artifact
+with Apple to work with Gatekeeper on Mac OS. Having our own binary of Chromium
+and bundling it with Kibana is integral to the artifact signing process.
+
+**Windows**: No custom build is necessary for Windows. We are able to use the
+full build of Chromium, downloaded from the main [Chromium download
+location](https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html),
+using the revision that corresponds with the Puppeteer dependency.
## Build Script Usage
diff --git a/x-pack/build_chromium/build.py b/x-pack/build_chromium/build.py
index 2f85e95b337d5..8f6c6c79e2d8c 100644
--- a/x-pack/build_chromium/build.py
+++ b/x-pack/build_chromium/build.py
@@ -6,7 +6,7 @@
md5_file,
)
-# This file builds Chromium headless on Linux.
+# This file builds Chromium headless on Mac and Linux.
# Verify that we have an argument, and if not print instructions
if (len(sys.argv) < 2):
@@ -68,7 +68,6 @@
print('Running install-build-deps...')
runcmd(src_path + '/build/install-build-deps.sh')
-
print('Updating all modules')
runcmd('gclient sync -D')
@@ -89,7 +88,7 @@
print('Compiling... this will take a while')
runcmd('autoninja -C out/headless headless_shell')
-# Optimize the output on Linux x64 by stripping inessentials from the binary
+# Optimize the output on Linux x64 and Mac by stripping inessentials from the binary
# ARM must be cross-compiled from Linux and can not read the ARM binary in order to strip
if platform.system() != 'Windows' and arch_name != 'arm64':
print('Optimizing headless_shell')
@@ -112,10 +111,18 @@ def archive_file(name):
archive.write(from_path, to_path)
return to_path
-# Add dependencies that must be bundled with the Chromium executable.
+# Each platform has slightly different requirements for what dependencies
+# must be bundled with the Chromium executable.
archive_file('headless_shell')
-archive_file(path.join('swiftshader', 'libEGL.so'))
-archive_file(path.join('swiftshader', 'libGLESv2.so'))
+if platform.system() == 'Linux':
+ archive_file(path.join('swiftshader', 'libEGL.so'))
+ archive_file(path.join('swiftshader', 'libGLESv2.so'))
+
+elif platform.system() == 'Darwin':
+ archive_file('headless_shell')
+ archive_file('libswiftshader_libEGL.dylib')
+ archive_file('libswiftshader_libGLESv2.dylib')
+ archive_file(path.join('Helpers', 'chrome_crashpad_handler'))
archive.close()
diff --git a/x-pack/build_chromium/darwin/args.gn b/x-pack/build_chromium/darwin/args.gn
new file mode 100644
index 0000000000000..605778a6a737c
--- /dev/null
+++ b/x-pack/build_chromium/darwin/args.gn
@@ -0,0 +1,30 @@
+# Based on //build/headless.gn
+
+# Embed resource.pak into binary to simplify deployment.
+headless_use_embedded_resources = true
+
+# In order to simplify deployment we build ICU data file
+# into binary.
+icu_use_data_file = false
+
+# Use embedded data instead external files for headless in order
+# to simplify deployment.
+v8_use_external_startup_data = false
+
+enable_nacl = false
+enable_print_preview = false
+enable_basic_printing = false
+enable_remoting = false
+use_alsa = false
+use_cups = false
+use_dbus = false
+use_gio = false
+# Please, consult @elastic/kibana-security before changing/removing this option.
+use_kerberos = false
+use_libpci = false
+use_pulseaudio = false
+use_udev = false
+
+is_debug = false
+symbol_level = 0
+is_component_build = false
diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts
index b08985e516f84..0737e0ce3f071 100644
--- a/x-pack/plugins/actions/server/lib/action_executor.ts
+++ b/x-pack/plugins/actions/server/lib/action_executor.ts
@@ -7,6 +7,7 @@
import type { PublicMethodsOf } from '@kbn/utility-types';
import { Logger, KibanaRequest } from 'src/core/server';
+import { withSpan } from '@kbn/apm-utils';
import { validateParams, validateConfig, validateSecrets } from './validate_with_schema';
import {
ActionTypeExecutorResult,
@@ -78,113 +79,136 @@ export class ActionExecutor {
);
}
- const {
- logger,
- spaces,
- getServices,
- encryptedSavedObjectsClient,
- actionTypeRegistry,
- eventLogger,
- preconfiguredActions,
- getActionsClientWithRequest,
- } = this.actionExecutorContext!;
-
- const services = getServices(request);
- const spaceId = spaces && spaces.getSpaceId(request);
- const namespace = spaceId && spaceId !== 'default' ? { namespace: spaceId } : {};
-
- const { actionTypeId, name, config, secrets } = await getActionInfo(
- await getActionsClientWithRequest(request, source),
- encryptedSavedObjectsClient,
- preconfiguredActions,
- actionId,
- namespace.namespace
- );
+ return withSpan(
+ {
+ name: `execute_action`,
+ type: 'actions',
+ labels: {
+ actionId,
+ },
+ },
+ async (span) => {
+ const {
+ logger,
+ spaces,
+ getServices,
+ encryptedSavedObjectsClient,
+ actionTypeRegistry,
+ eventLogger,
+ preconfiguredActions,
+ getActionsClientWithRequest,
+ } = this.actionExecutorContext!;
- if (!actionTypeRegistry.isActionExecutable(actionId, actionTypeId, { notifyUsage: true })) {
- actionTypeRegistry.ensureActionTypeEnabled(actionTypeId);
- }
- const actionType = actionTypeRegistry.get(actionTypeId);
-
- let validatedParams: Record;
- let validatedConfig: Record;
- let validatedSecrets: Record;
-
- try {
- validatedParams = validateParams(actionType, params);
- validatedConfig = validateConfig(actionType, config);
- validatedSecrets = validateSecrets(actionType, secrets);
- } catch (err) {
- return { status: 'error', actionId, message: err.message, retry: false };
- }
+ const services = getServices(request);
+ const spaceId = spaces && spaces.getSpaceId(request);
+ const namespace = spaceId && spaceId !== 'default' ? { namespace: spaceId } : {};
+
+ const { actionTypeId, name, config, secrets } = await getActionInfo(
+ await getActionsClientWithRequest(request, source),
+ encryptedSavedObjectsClient,
+ preconfiguredActions,
+ actionId,
+ namespace.namespace
+ );
+
+ if (span) {
+ span.name = `execute_action ${actionTypeId}`;
+ span.addLabels({
+ actionTypeId,
+ });
+ }
+
+ if (!actionTypeRegistry.isActionExecutable(actionId, actionTypeId, { notifyUsage: true })) {
+ actionTypeRegistry.ensureActionTypeEnabled(actionTypeId);
+ }
+ const actionType = actionTypeRegistry.get(actionTypeId);
+
+ let validatedParams: Record;
+ let validatedConfig: Record;
+ let validatedSecrets: Record;
+
+ try {
+ validatedParams = validateParams(actionType, params);
+ validatedConfig = validateConfig(actionType, config);
+ validatedSecrets = validateSecrets(actionType, secrets);
+ } catch (err) {
+ span?.setOutcome('failure');
+ return { status: 'error', actionId, message: err.message, retry: false };
+ }
- const actionLabel = `${actionTypeId}:${actionId}: ${name}`;
- logger.debug(`executing action ${actionLabel}`);
-
- const event: IEvent = {
- event: { action: EVENT_LOG_ACTIONS.execute },
- kibana: {
- saved_objects: [
- {
- rel: SAVED_OBJECT_REL_PRIMARY,
- type: 'action',
- id: actionId,
- ...namespace,
+ const actionLabel = `${actionTypeId}:${actionId}: ${name}`;
+ logger.debug(`executing action ${actionLabel}`);
+
+ const event: IEvent = {
+ event: { action: EVENT_LOG_ACTIONS.execute },
+ kibana: {
+ saved_objects: [
+ {
+ rel: SAVED_OBJECT_REL_PRIMARY,
+ type: 'action',
+ id: actionId,
+ type_id: actionTypeId,
+ ...namespace,
+ },
+ ],
},
- ],
- },
- };
+ };
- eventLogger.startTiming(event);
- let rawResult: ActionTypeExecutorResult;
- try {
- rawResult = await actionType.executor({
- actionId,
- services,
- params: validatedParams,
- config: validatedConfig,
- secrets: validatedSecrets,
- });
- } catch (err) {
- rawResult = {
- actionId,
- status: 'error',
- message: 'an error occurred while running the action executor',
- serviceMessage: err.message,
- retry: false,
- };
- }
- eventLogger.stopTiming(event);
+ eventLogger.startTiming(event);
+ let rawResult: ActionTypeExecutorResult;
+ try {
+ rawResult = await actionType.executor({
+ actionId,
+ services,
+ params: validatedParams,
+ config: validatedConfig,
+ secrets: validatedSecrets,
+ });
+ } catch (err) {
+ rawResult = {
+ actionId,
+ status: 'error',
+ message: 'an error occurred while running the action executor',
+ serviceMessage: err.message,
+ retry: false,
+ };
+ }
+ eventLogger.stopTiming(event);
- // allow null-ish return to indicate success
- const result = rawResult || {
- actionId,
- status: 'ok',
- };
+ // allow null-ish return to indicate success
+ const result = rawResult || {
+ actionId,
+ status: 'ok',
+ };
- event.event = event.event || {};
-
- if (result.status === 'ok') {
- event.event.outcome = 'success';
- event.message = `action executed: ${actionLabel}`;
- } else if (result.status === 'error') {
- event.event.outcome = 'failure';
- event.message = `action execution failure: ${actionLabel}`;
- event.error = event.error || {};
- event.error.message = actionErrorToMessage(result);
- logger.warn(`action execution failure: ${actionLabel}: ${event.error.message}`);
- } else {
- event.event.outcome = 'failure';
- event.message = `action execution returned unexpected result: ${actionLabel}: "${result.status}"`;
- event.error = event.error || {};
- event.error.message = 'action execution returned unexpected result';
- logger.warn(
- `action execution failure: ${actionLabel}: returned unexpected result "${result.status}"`
- );
- }
+ event.event = event.event || {};
- eventLogger.logEvent(event);
- return result;
+ if (result.status === 'ok') {
+ span?.setOutcome('success');
+ event.event.outcome = 'success';
+ event.message = `action executed: ${actionLabel}`;
+ } else if (result.status === 'error') {
+ span?.setOutcome('failure');
+ event.event.outcome = 'failure';
+ event.message = `action execution failure: ${actionLabel}`;
+ event.error = event.error || {};
+ event.error.message = actionErrorToMessage(result);
+ logger.warn(`action execution failure: ${actionLabel}: ${event.error.message}`);
+ } else {
+ span?.setOutcome('failure');
+ event.event.outcome = 'failure';
+ event.message = `action execution returned unexpected result: ${actionLabel}: "${result.status}"`;
+ event.error = event.error || {};
+ event.error.message = 'action execution returned unexpected result';
+ logger.warn(
+ `action execution failure: ${actionLabel}: returned unexpected result "${result.status}"`
+ );
+ }
+
+ eventLogger.logEvent(event);
+ return result;
+ }
+ );
}
}
diff --git a/x-pack/plugins/alerting/server/task_runner/create_execution_handler.test.ts b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.test.ts
index 78d74b78c99ba..5ab25fbfa39e7 100644
--- a/x-pack/plugins/alerting/server/task_runner/create_execution_handler.test.ts
+++ b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.test.ts
@@ -166,10 +166,12 @@ test('enqueues execution per selected action', async () => {
"id": "1",
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
Object {
"id": "1",
"type": "action",
+ "type_id": "test",
},
],
},
diff --git a/x-pack/plugins/alerting/server/task_runner/create_execution_handler.ts b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.ts
index 93cced2043d5e..ef93179bdaba1 100644
--- a/x-pack/plugins/alerting/server/task_runner/create_execution_handler.ts
+++ b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.ts
@@ -182,8 +182,14 @@ export function createExecutionHandler<
action_subgroup: actionSubgroup,
},
saved_objects: [
- { rel: SAVED_OBJECT_REL_PRIMARY, type: 'alert', id: alertId, ...namespace },
- { type: 'action', id: action.id, ...namespace },
+ {
+ rel: SAVED_OBJECT_REL_PRIMARY,
+ type: 'alert',
+ id: alertId,
+ type_id: alertType.id,
+ ...namespace,
+ },
+ { type: 'action', id: action.id, type_id: action.actionTypeId, ...namespace },
],
},
};
diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts
index 8b720203b2533..74d4bbe19b6d0 100644
--- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts
+++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts
@@ -280,6 +280,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -390,6 +391,7 @@ describe('Task Runner', () => {
namespace: undefined,
rel: 'primary',
type: 'alert',
+ type_id: 'test',
},
],
},
@@ -414,6 +416,7 @@ describe('Task Runner', () => {
namespace: undefined,
rel: 'primary',
type: 'alert',
+ type_id: 'test',
},
],
},
@@ -436,11 +439,13 @@ describe('Task Runner', () => {
namespace: undefined,
rel: 'primary',
type: 'alert',
+ type_id: 'test',
},
{
id: '1',
namespace: undefined,
type: 'action',
+ type_id: 'action',
},
],
},
@@ -463,6 +468,7 @@ describe('Task Runner', () => {
namespace: undefined,
rel: 'primary',
type: 'alert',
+ type_id: 'test',
},
],
},
@@ -542,6 +548,7 @@ describe('Task Runner', () => {
namespace: undefined,
rel: 'primary',
type: 'alert',
+ type_id: 'test',
},
],
},
@@ -565,6 +572,7 @@ describe('Task Runner', () => {
namespace: undefined,
rel: 'primary',
type: 'alert',
+ type_id: 'test',
},
],
},
@@ -586,6 +594,7 @@ describe('Task Runner', () => {
namespace: undefined,
rel: 'primary',
type: 'alert',
+ type_id: 'test',
},
],
},
@@ -724,6 +733,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -747,6 +757,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1158,6 +1169,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1183,6 +1195,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1234,11 +1247,13 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
Object {
"id": "1",
"namespace": undefined,
"type": "action",
+ "type_id": "action",
},
],
},
@@ -1262,6 +1277,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1584,6 +1600,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1609,6 +1626,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1632,6 +1650,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1842,6 +1861,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1901,6 +1921,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -1968,6 +1989,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -2035,6 +2057,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
@@ -2101,6 +2124,7 @@ describe('Task Runner', () => {
"namespace": undefined,
"rel": "primary",
"type": "alert",
+ "type_id": "test",
},
],
},
diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts
index 6e4ae1295eb33..bfb698c878124 100644
--- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts
+++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts
@@ -338,6 +338,7 @@ export class TaskRunner<
alertId,
alertLabel,
namespace,
+ ruleTypeId: alert.alertTypeId,
});
if (!muteAll) {
@@ -500,6 +501,7 @@ export class TaskRunner<
rel: SAVED_OBJECT_REL_PRIMARY,
type: 'alert',
id: alertId,
+ type_id: this.alertType.id,
namespace,
},
],
@@ -661,6 +663,7 @@ interface GenerateNewAndRecoveredInstanceEventsParams<
alertId: string;
alertLabel: string;
namespace: string | undefined;
+ ruleTypeId: string;
}
function generateNewAndRecoveredInstanceEvents<
@@ -674,6 +677,7 @@ function generateNewAndRecoveredInstanceEvents<
currentAlertInstances,
originalAlertInstances,
recoveredAlertInstances,
+ ruleTypeId,
} = params;
const originalAlertInstanceIds = Object.keys(originalAlertInstances);
const currentAlertInstanceIds = Object.keys(currentAlertInstances);
@@ -756,6 +760,7 @@ function generateNewAndRecoveredInstanceEvents<
rel: SAVED_OBJECT_REL_PRIMARY,
type: 'alert',
id: alertId,
+ type_id: ruleTypeId,
namespace,
},
],
diff --git a/x-pack/plugins/apm/public/application/index.tsx b/x-pack/plugins/apm/public/application/index.tsx
index d5d77eea8c9c0..6924a8b9161b2 100644
--- a/x-pack/plugins/apm/public/application/index.tsx
+++ b/x-pack/plugins/apm/public/application/index.tsx
@@ -10,7 +10,11 @@ import ReactDOM from 'react-dom';
import 'react-vis/dist/style.css';
import type { ObservabilityRuleTypeRegistry } from '../../../observability/public';
import { ConfigSchema } from '../';
-import { AppMountParameters, CoreStart } from '../../../../../src/core/public';
+import {
+ AppMountParameters,
+ CoreStart,
+ APP_WRAPPER_CLASS,
+} from '../../../../../src/core/public';
import { ApmPluginSetupDeps, ApmPluginStartDeps } from '../plugin';
import { createCallApmApi } from '../services/rest/createCallApmApi';
import { createStaticIndexPattern } from '../services/rest/index_pattern';
@@ -58,6 +62,9 @@ export const renderApp = ({
console.log('Error creating static index pattern', e);
});
+ // add .kbnAppWrappers class to root element
+ element.classList.add(APP_WRAPPER_CLASS);
+
ReactDOM.render(
)}
-
-
- }
- />
-
+
+ }
+ />
>
diff --git a/x-pack/plugins/apm/public/components/app/service_map/index.tsx b/x-pack/plugins/apm/public/components/app/service_map/index.tsx
index 714228d58f962..df8438c5c80a4 100644
--- a/x-pack/plugins/apm/public/components/app/service_map/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_map/index.tsx
@@ -5,7 +5,12 @@
* 2.0.
*/
-import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
+import {
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiLoadingSpinner,
+ EuiPanel,
+} from '@elastic/eui';
import React, { PropsWithChildren, ReactNode } from 'react';
import { isActivePlatinumLicense } from '../../../../common/license_check';
import { useTrackPageview } from '../../../../../observability/public';
@@ -97,6 +102,10 @@ export function ServiceMap({
const { ref, height } = useRefDimensions();
+ // Temporary hack to work around bottom padding introduced by EuiPage
+ const PADDING_BOTTOM = 24;
+ const heightWithPadding = height - PADDING_BOTTOM;
+
useTrackPageview({ app: 'apm', path: 'service_map' });
useTrackPageview({ app: 'apm', path: 'service_map', delay: 15000 });
@@ -137,20 +146,25 @@ export function ServiceMap({
return (
<>
-
-
-
+
-
- {serviceName &&
}
- {status === FETCH_STATUS.LOADING &&
}
-
-
-
+
+
+ {serviceName && }
+ {status === FETCH_STATUS.LOADING && }
+
+
+
+
>
);
}
diff --git a/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx b/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx
index 20b78b90e0378..5528bdaa40c41 100644
--- a/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx
@@ -39,13 +39,6 @@ const Truncate = euiStyled.span`
${truncate(px(unit * 12))}
`;
-const MetadataFlexGroup = euiStyled(EuiFlexGroup)`
- border-bottom: ${({ theme }) => theme.eui.euiBorderThin};
- margin-bottom: ${({ theme }) => theme.eui.paddingSizes.m};
- padding: ${({ theme }) =>
- `${theme.eui.paddingSizes.m} 0 0 ${theme.eui.paddingSizes.m}`};
-`;
-
interface ServiceNodeMetricsProps {
serviceName: string;
serviceNodeName: string;
@@ -117,55 +110,60 @@ export function ServiceNodeMetrics({
/>
) : (
-
-
-
+
+
+
+ {serviceName}
+
+ }
+ />
+
+
+
+ {host}
+
}
- )}
- title={
-
- {serviceName}
-
- }
- />
-
-
-
- {host}
-
- }
- />
-
-
-
+
+
+
+ {containerId}
+
}
- )}
- title={
-
- {containerId}
-
- }
- />
-
-
+ />
+
+
+
)}
{agentName && (
diff --git a/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx b/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx
index 69e5ea5a78ea1..1a432f90f1e3a 100644
--- a/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx
@@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import { EuiPanel, EuiToolTip } from '@elastic/eui';
+import { EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common';
@@ -142,18 +142,16 @@ function ServiceNodeOverview({ serviceName }: ServiceNodeOverviewProps) {
];
return (
-
-
-
+
);
}
diff --git a/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx b/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx
index 0938456193dc0..bf60463255d64 100644
--- a/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx
@@ -5,7 +5,6 @@
* 2.0.
*/
-import { EuiPanel } from '@elastic/eui';
import React from 'react';
import { useTrackPageview } from '../../../../../observability/public';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
@@ -51,12 +50,10 @@ export function TraceOverview() {
<>
-
-
-
+
>
);
}
diff --git a/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx b/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx
index af62f4f235af7..09c25ee4557c5 100644
--- a/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx
+++ b/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx
@@ -14,17 +14,13 @@ import { toQuery } from '../shared/Links/url_helpers';
import { ErrorGroupDetails } from '../app/ErrorGroupDetails';
import { useApmPluginContext } from '../../context/apm_plugin/use_apm_plugin_context';
import { ServiceNodeMetrics } from '../app/service_node_metrics';
-import { Settings } from '../app/Settings';
+import { SettingsTemplate } from './templates/settings_template';
import { AgentConfigurations } from '../app/Settings/AgentConfigurations';
import { AnomalyDetection } from '../app/Settings/anomaly_detection';
import { ApmIndices } from '../app/Settings/ApmIndices';
import { CustomizeUI } from '../app/Settings/CustomizeUI';
import { TraceLink } from '../app/TraceLink';
import { TransactionDetails } from '../app/transaction_details';
-import {
- CreateAgentConfigurationRouteHandler,
- EditAgentConfigurationRouteHandler,
-} from './route_handlers/agent_configuration';
import { enableServiceOverview } from '../../../common/ui_settings_keys';
import { redirectTo } from './redirect_to';
import { ApmMainTemplate } from './templates/apm_main_template';
@@ -38,6 +34,8 @@ import { ServiceOverview } from '../app/service_overview';
import { TransactionOverview } from '../app/transaction_overview';
import { ServiceInventory } from '../app/service_inventory';
import { TraceOverview } from '../app/trace_overview';
+import { useFetcher } from '../../hooks/use_fetcher';
+import { AgentConfigurationCreateEdit } from '../app/Settings/AgentConfigurations/AgentConfigurationCreateEdit';
// These component function definitions are used below with the `component`
// property of the route definitions.
@@ -222,9 +220,9 @@ function TransactionDetailsRouteView(
function SettingsAgentConfigurationRouteView() {
return (
-
+
-
+
);
}
@@ -232,9 +230,9 @@ function SettingsAgentConfigurationRouteView() {
function SettingsAnomalyDetectionRouteView() {
return (
-
+
-
+
);
}
@@ -242,9 +240,9 @@ function SettingsAnomalyDetectionRouteView() {
function SettingsApmIndicesRouteView() {
return (
-
+
-
+
);
}
@@ -252,9 +250,57 @@ function SettingsApmIndicesRouteView() {
function SettingsCustomizeUI() {
return (
-
+
-
+
+
+ );
+}
+
+export function EditAgentConfigurationRouteView(props: RouteComponentProps) {
+ const { search } = props.history.location;
+
+ // typescript complains because `pageStop` does not exist in `APMQueryParams`
+ // Going forward we should move away from globally declared query params and this is a first step
+ // @ts-expect-error
+ const { name, environment, pageStep } = toQuery(search);
+
+ const res = useFetcher(
+ (callApmApi) => {
+ return callApmApi({
+ endpoint: 'GET /api/apm/settings/agent-configuration/view',
+ params: { query: { name, environment } },
+ });
+ },
+ [name, environment]
+ );
+
+ return (
+
+
+
+
+
+ );
+}
+
+export function CreateAgentConfigurationRouteView(props: RouteComponentProps) {
+ const { search } = props.history.location;
+
+ // Ignoring here because we specifically DO NOT want to add the query params to the global route handler
+ // @ts-expect-error
+ const { pageStep } = toQuery(search);
+
+ return (
+
+
+
+
);
}
@@ -339,14 +385,14 @@ export const apmRouteConfig: APMRouteDefinition[] = [
{
exact: true,
path: '/settings/agent-configuration/create',
- component: CreateAgentConfigurationRouteHandler,
+ component: CreateAgentConfigurationRouteView,
breadcrumb: CreateAgentConfigurationTitle,
},
{
exact: true,
path: '/settings/agent-configuration/edit',
breadcrumb: EditAgentConfigurationTitle,
- component: EditAgentConfigurationRouteHandler,
+ component: EditAgentConfigurationRouteView,
},
{
exact: true,
diff --git a/x-pack/plugins/apm/public/components/routing/app_root.tsx b/x-pack/plugins/apm/public/components/routing/app_root.tsx
index 9529a67210748..2bb387ae315ff 100644
--- a/x-pack/plugins/apm/public/components/routing/app_root.tsx
+++ b/x-pack/plugins/apm/public/components/routing/app_root.tsx
@@ -11,7 +11,7 @@ import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
import React from 'react';
import { Route, Router, Switch } from 'react-router-dom';
import { DefaultTheme, ThemeProvider } from 'styled-components';
-import { euiStyled } from '../../../../../../src/plugins/kibana_react/common';
+import { APP_WRAPPER_CLASS } from '../../../../../../src/core/public';
import {
KibanaContextProvider,
RedirectAppLinks,
@@ -32,10 +32,6 @@ import { useApmPluginContext } from '../../context/apm_plugin/use_apm_plugin_con
import { AnomalyDetectionJobsContextProvider } from '../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
import { apmRouteConfig } from './apm_route_config';
-const MainContainer = euiStyled.div`
- height: 100%;
-`;
-
export function ApmAppRoot({
apmPluginContextValue,
pluginsStart,
@@ -48,7 +44,12 @@ export function ApmAppRoot({
const i18nCore = core.i18n;
return (
-
+
@@ -57,19 +58,14 @@ export function ApmAppRoot({
-
-
+
-
-
- {apmRouteConfig.map((route, i) => (
-
- ))}
-
-
+
+
+ {apmRouteConfig.map((route, i) => (
+
+ ))}
+
diff --git a/x-pack/plugins/apm/public/components/routing/route_handlers/agent_configuration.tsx b/x-pack/plugins/apm/public/components/routing/route_handlers/agent_configuration.tsx
deleted file mode 100644
index 8e0a08603bc76..0000000000000
--- a/x-pack/plugins/apm/public/components/routing/route_handlers/agent_configuration.tsx
+++ /dev/null
@@ -1,65 +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 React from 'react';
-import { RouteComponentProps } from 'react-router-dom';
-import { useFetcher } from '../../../hooks/use_fetcher';
-import { toQuery } from '../../shared/Links/url_helpers';
-import { Settings } from '../../app/Settings';
-import { AgentConfigurationCreateEdit } from '../../app/Settings/AgentConfigurations/AgentConfigurationCreateEdit';
-
-type EditAgentConfigurationRouteHandler = RouteComponentProps<{}>;
-
-export function EditAgentConfigurationRouteHandler(
- props: EditAgentConfigurationRouteHandler
-) {
- const { search } = props.history.location;
-
- // typescript complains because `pageStop` does not exist in `APMQueryParams`
- // Going forward we should move away from globally declared query params and this is a first step
- // @ts-expect-error
- const { name, environment, pageStep } = toQuery(search);
-
- const res = useFetcher(
- (callApmApi) => {
- return callApmApi({
- endpoint: 'GET /api/apm/settings/agent-configuration/view',
- params: { query: { name, environment } },
- });
- },
- [name, environment]
- );
-
- return (
-
-
-
- );
-}
-
-type CreateAgentConfigurationRouteHandlerProps = RouteComponentProps<{}>;
-
-export function CreateAgentConfigurationRouteHandler(
- props: CreateAgentConfigurationRouteHandlerProps
-) {
- const { search } = props.history.location;
-
- // Ignoring here because we specifically DO NOT want to add the query params to the global route handler
- // @ts-expect-error
- const { pageStep } = toQuery(search);
-
- return (
-
-
-
- );
-}
diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx
index 0473e88c23d12..e917350f6024b 100644
--- a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { EuiPageHeaderProps, EuiPageTemplateProps } from '@elastic/eui';
import React from 'react';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { ApmPluginStartDeps } from '../../../plugin';
@@ -21,11 +22,14 @@ import { EnvironmentFilter } from '../../shared/EnvironmentFilter';
*/
export function ApmMainTemplate({
pageTitle,
+ pageHeader,
children,
+ ...pageTemplateProps
}: {
- pageTitle: React.ReactNode;
+ pageTitle?: React.ReactNode;
+ pageHeader?: EuiPageHeaderProps;
children: React.ReactNode;
-}) {
+} & EuiPageTemplateProps) {
const { services } = useKibana();
const ObservabilityPageTemplate =
services.observability.navigation.PageTemplate;
@@ -35,7 +39,9 @@ export function ApmMainTemplate({
pageHeader={{
pageTitle,
rightSideItems: [],
+ ...pageHeader,
}}
+ {...pageTemplateProps}
>
{children}
diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx
index 526d9eb3551d0..ab53052780ea9 100644
--- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template.tsx
@@ -10,9 +10,8 @@ import { i18n } from '@kbn/i18n';
import {
EuiFlexGroup,
EuiFlexItem,
+ EuiPageHeaderProps,
EuiTitle,
- EuiTabs,
- EuiTab,
EuiBetaBadge,
} from '@elastic/eui';
import { ApmMainTemplate } from './apm_main_template';
@@ -33,12 +32,10 @@ import { useUrlParams } from '../../../context/url_params_context/use_url_params
import { Correlations } from '../../app/correlations';
import { SearchBar } from '../../shared/search_bar';
-interface Tab {
- key: TabKey;
- href: string;
- text: React.ReactNode;
+type Tab = NonNullable[0] & {
+ key: string;
hidden?: boolean;
-}
+};
type TabKey =
| 'errors'
@@ -49,60 +46,63 @@ type TabKey =
| 'profiling'
| 'transactions';
-export function ApmServiceTemplate({
+interface Props {
+ children: React.ReactNode;
+ serviceName: string;
+ selectedTab: TabKey;
+ searchBarOptions?: React.ComponentProps;
+}
+
+export function ApmServiceTemplate(props: Props) {
+ return (
+
+
+
+ );
+}
+
+function Template({
children,
serviceName,
selectedTab,
searchBarOptions,
-}: {
- children: React.ReactNode;
- serviceName: string;
- selectedTab: TabKey;
- searchBarOptions?: {
- hidden?: boolean;
- showTransactionTypeSelector?: boolean;
- showTimeComparison?: boolean;
- };
-}) {
+}: Props) {
+ const tabs = useTabs({ serviceName, selectedTab });
+
return (
-
-
-
- {serviceName}
-
+ pageHeader={{
+ tabs,
+ pageTitle: (
+
+
+
+
+
+ {serviceName}
+
+
+
+
+
+
+
-
+
- >
- }
+ ),
+ }}
>
-
-
-
-
-
-
-
-
-
+
-
-
- {children}
-
+ {children}
);
}
-function TabNavigation({
+function useTabs({
serviceName,
selectedTab,
}: {
@@ -117,7 +117,7 @@ function TabNavigation({
{
key: 'overview',
href: useServiceOverviewHref({ serviceName, transactionType }),
- text: i18n.translate('xpack.apm.serviceDetails.overviewTabLabel', {
+ label: i18n.translate('xpack.apm.serviceDetails.overviewTabLabel', {
defaultMessage: 'Overview',
}),
hidden: !core.uiSettings.get(enableServiceOverview),
@@ -129,21 +129,21 @@ function TabNavigation({
latencyAggregationType: urlParams.latencyAggregationType,
transactionType,
}),
- text: i18n.translate('xpack.apm.serviceDetails.transactionsTabLabel', {
+ label: i18n.translate('xpack.apm.serviceDetails.transactionsTabLabel', {
defaultMessage: 'Transactions',
}),
},
{
key: 'errors',
href: useErrorOverviewHref(serviceName),
- text: i18n.translate('xpack.apm.serviceDetails.errorsTabLabel', {
+ label: i18n.translate('xpack.apm.serviceDetails.errorsTabLabel', {
defaultMessage: 'Errors',
}),
},
{
key: 'nodes',
href: useServiceNodeOverviewHref(serviceName),
- text: i18n.translate('xpack.apm.serviceDetails.nodesTabLabel', {
+ label: i18n.translate('xpack.apm.serviceDetails.nodesTabLabel', {
defaultMessage: 'JVMs',
}),
hidden: !isJavaAgentName(agentName),
@@ -151,7 +151,7 @@ function TabNavigation({
{
key: 'metrics',
href: useMetricOverviewHref(serviceName),
- text: i18n.translate('xpack.apm.serviceDetails.metricsTabLabel', {
+ label: i18n.translate('xpack.apm.serviceDetails.metricsTabLabel', {
defaultMessage: 'Metrics',
}),
hidden:
@@ -160,7 +160,7 @@ function TabNavigation({
{
key: 'service-map',
href: useServiceMapHref(serviceName),
- text: i18n.translate('xpack.apm.home.serviceMapTabLabel', {
+ label: i18n.translate('xpack.apm.home.serviceMapTabLabel', {
defaultMessage: 'Service Map',
}),
},
@@ -168,7 +168,7 @@ function TabNavigation({
key: 'profiling',
href: useServiceProfilingHref({ serviceName }),
hidden: !config.profilingEnabled,
- text: (
+ label: (
{i18n.translate('xpack.apm.serviceDetails.profilingTabLabel', {
@@ -197,20 +197,11 @@ function TabNavigation({
},
];
- return (
-
- {tabs
- .filter((t) => !t.hidden)
- .map(({ href, key, text }) => (
-
- {text}
-
- ))}
-
- );
+ return tabs
+ .filter((t) => !t.hidden)
+ .map(({ href, key, label }) => ({
+ href,
+ label,
+ isSelected: key === selectedTab,
+ }));
}
diff --git a/x-pack/plugins/apm/public/components/app/Settings/Settings.test.tsx b/x-pack/plugins/apm/public/components/routing/templates/settings_template.test.tsx
similarity index 89%
rename from x-pack/plugins/apm/public/components/app/Settings/Settings.test.tsx
rename to x-pack/plugins/apm/public/components/routing/templates/settings_template.test.tsx
index 807cfd9c02654..36d54525d2537 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/Settings.test.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/settings_template.test.tsx
@@ -8,7 +8,7 @@
import { render } from '@testing-library/react';
import { MockApmPluginContextWrapper } from '../../../context/apm_plugin/mock_apm_plugin_context';
import React, { ReactNode } from 'react';
-import { Settings } from './';
+import { SettingsTemplate } from './settings_template';
import { createMemoryHistory } from 'history';
import { MemoryRouter, RouteComponentProps } from 'react-router-dom';
@@ -29,9 +29,9 @@ describe('Settings', () => {
} as unknown) as RouteComponentProps<{}>;
expect(() =>
render(
-
+
- ,
+ ,
{ wrapper: Wrapper }
)
).not.toThrowError();
diff --git a/x-pack/plugins/apm/public/components/app/Settings/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/Settings/index.tsx
rename to x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx
index b4cba2afc2550..66958c01a7fea 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/index.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx
@@ -12,7 +12,7 @@ import { useHistory } from 'react-router-dom';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { getAPMHref } from '../../shared/Links/apm/APMLink';
-export function Settings({ children }: { children: ReactNode }) {
+export function SettingsTemplate({ children }: { children: ReactNode }) {
const { core } = useApmPluginContext();
const history = useHistory();
const { basePath } = core.http;
@@ -30,7 +30,7 @@ export function Settings({ children }: { children: ReactNode }) {
}
return (
-
+
toggleOpenOnMobile()}
diff --git a/x-pack/plugins/apm/public/components/shared/search_bar.tsx b/x-pack/plugins/apm/public/components/shared/search_bar.tsx
index 17497e1fb4b30..74374e331ee8e 100644
--- a/x-pack/plugins/apm/public/components/shared/search_bar.tsx
+++ b/x-pack/plugins/apm/public/components/shared/search_bar.tsx
@@ -135,7 +135,7 @@ export function SearchBar({
-
+
>
);
}
diff --git a/x-pack/plugins/cases/README.md b/x-pack/plugins/cases/README.md
index 5cb9d82436137..a1660911567da 100644
--- a/x-pack/plugins/cases/README.md
+++ b/x-pack/plugins/cases/README.md
@@ -14,6 +14,7 @@ Case management in Kibana
## Table of Contents
- [Cases API](#cases-api)
+- [Cases Client API](#cases-client-api)
- [Cases UI](#cases-ui)
- [Case Action Type](#case-action-type) _feature in development, disabled by default_
@@ -21,6 +22,9 @@ Case management in Kibana
## Cases API
[**Explore the API docs »**](https://www.elastic.co/guide/en/security/current/cases-api-overview.html)
+## Cases Client API
+[**Cases Client API docs**][cases-client-api-docs]
+
## Cases UI
#### Embed Cases UI components in any Kibana plugin
@@ -263,4 +267,4 @@ For IBM Resilient connectors:
[all-cases-modal-img]: images/all_cases_selector_modal.png
[recent-cases-img]: images/recent_cases.png
[case-view-img]: images/case_view.png
-
+[cases-client-api-docs]: docs/cases_client/cases_client_api.md
diff --git a/x-pack/plugins/cases/common/api/cases/case.ts b/x-pack/plugins/cases/common/api/cases/case.ts
index a2bba7dba4b39..b3f7952a61ee7 100644
--- a/x-pack/plugins/cases/common/api/cases/case.ts
+++ b/x-pack/plugins/cases/common/api/cases/case.ts
@@ -31,13 +31,38 @@ const SettingsRt = rt.type({
});
const CaseBasicRt = rt.type({
+ /**
+ * The description of the case
+ */
description: rt.string,
+ /**
+ * The current status of the case (open, closed, in-progress)
+ */
status: CaseStatusRt,
+ /**
+ * The identifying strings for filter a case
+ */
tags: rt.array(rt.string),
+ /**
+ * The title of a case
+ */
title: rt.string,
+ /**
+ * The type of a case (individual or collection)
+ */
[caseTypeField]: CaseTypeRt,
+ /**
+ * The external system that the case can be synced with
+ */
connector: CaseConnectorRt,
+ /**
+ * The alert sync settings
+ */
settings: SettingsRt,
+ /**
+ * The plugin owner of the case
+ */
+ owner: rt.string,
});
const CaseExternalServiceBasicRt = rt.type({
@@ -73,11 +98,31 @@ export const CaseAttributesRt = rt.intersection([
]);
const CasePostRequestNoTypeRt = rt.type({
+ /**
+ * Description of the case
+ */
description: rt.string,
+ /**
+ * Identifiers for the case.
+ */
tags: rt.array(rt.string),
+ /**
+ * Title of the case
+ */
title: rt.string,
+ /**
+ * The external configuration for the case
+ */
connector: CaseConnectorRt,
+ /**
+ * Sync settings for alerts
+ */
settings: SettingsRt,
+ /**
+ * The owner here must match the string used when a plugin registers a feature with access to the cases plugin. The user
+ * creating this case must also be granted access to that plugin's feature.
+ */
+ owner: rt.string,
});
/**
@@ -95,23 +140,78 @@ export const CasesClientPostRequestRt = rt.type({
* has all the necessary fields. CasesClientPostRequestRt is used for validation.
*/
export const CasePostRequestRt = rt.intersection([
- rt.partial({ type: CaseTypeRt }),
+ /**
+ * The case type: an individual case (one without children) or a collection case (one with children)
+ */
+ rt.partial({ [caseTypeField]: CaseTypeRt }),
CasePostRequestNoTypeRt,
]);
export const CasesFindRequestRt = rt.partial({
+ /**
+ * Type of a case (individual, or collection)
+ */
type: CaseTypeRt,
+ /**
+ * Tags to filter by
+ */
tags: rt.union([rt.array(rt.string), rt.string]),
+ /**
+ * The status of the case (open, closed, in-progress)
+ */
status: CaseStatusRt,
+ /**
+ * The reporters to filter by
+ */
reporters: rt.union([rt.array(rt.string), rt.string]),
+ /**
+ * Operator to use for the `search` field
+ */
defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
+ /**
+ * The fields in the entity to return in the response
+ */
fields: rt.array(rt.string),
+ /**
+ * The page of objects to return
+ */
page: NumberFromString,
+ /**
+ * The number of objects to include in each page
+ */
perPage: NumberFromString,
+ /**
+ * An Elasticsearch simple_query_string
+ */
search: rt.string,
- searchFields: rt.array(rt.string),
+ /**
+ * The fields to perform the simple_query_string parsed query against
+ */
+ searchFields: rt.union([rt.array(rt.string), rt.string]),
+ /**
+ * The field to use for sorting the found objects.
+ *
+ * This only supports, `create_at`, `closed_at`, and `status`
+ */
sortField: rt.string,
+ /**
+ * The order to sort by
+ */
sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]),
+ /**
+ * The owner(s) to filter by. The user making the request must have privileges to retrieve cases of that
+ * ownership or they will be ignored. If no owner is included, then all ownership types will be included in the response
+ * that the user has access to.
+ */
+ owner: rt.union([rt.array(rt.string), rt.string]),
+});
+
+export const CasesByAlertIDRequestRt = rt.partial({
+ /**
+ * The type of cases to retrieve given an alert ID. If no owner is provided, all cases
+ * that the user has access to will be returned.
+ */
+ owner: rt.union([rt.array(rt.string), rt.string]),
});
export const CaseResponseRt = rt.intersection([
@@ -141,6 +241,9 @@ export const CasesFindResponseRt = rt.intersection([
export const CasePatchRequestRt = rt.intersection([
rt.partial(CaseBasicRt.props),
+ /**
+ * The saved object ID and version
+ */
rt.type({ id: rt.string, version: rt.string }),
]);
@@ -172,6 +275,16 @@ export const ExternalServiceResponseRt = rt.intersection([
}),
]);
+export const AllTagsFindRequestRt = rt.partial({
+ /**
+ * The owner of the cases to retrieve the tags from. If no owner is provided the tags from all cases
+ * that the user has access to will be returned.
+ */
+ owner: rt.union([rt.array(rt.string), rt.string]),
+});
+
+export const AllReportersFindRequestRt = AllTagsFindRequestRt;
+
export type CaseAttributes = rt.TypeOf;
/**
* This field differs from the CasePostRequest in that the post request's type field can be optional. This type requires
@@ -183,6 +296,7 @@ export type CasePostRequest = rt.TypeOf;
export type CaseResponse = rt.TypeOf;
export type CasesResponse = rt.TypeOf;
export type CasesFindRequest = rt.TypeOf;
+export type CasesByAlertIDRequest = rt.TypeOf;
export type CasesFindResponse = rt.TypeOf;
export type CasePatchRequest = rt.TypeOf;
export type CasesPatchRequest = rt.TypeOf;
@@ -194,3 +308,6 @@ export type ESCaseAttributes = Omit & { connector:
export type ESCasePatchRequest = Omit & {
connector?: ESCaseConnector;
};
+
+export type AllTagsFindRequest = rt.TypeOf;
+export type AllReportersFindRequest = AllTagsFindRequest;
diff --git a/x-pack/plugins/cases/common/api/cases/comment.ts b/x-pack/plugins/cases/common/api/cases/comment.ts
index 8434e419ef75a..5bc8da95639c8 100644
--- a/x-pack/plugins/cases/common/api/cases/comment.ts
+++ b/x-pack/plugins/cases/common/api/cases/comment.ts
@@ -6,6 +6,7 @@
*/
import * as rt from 'io-ts';
+import { SavedObjectFindOptionsRt } from '../saved_object';
import { UserRT } from '../user';
@@ -42,6 +43,7 @@ export const CommentAttributesBasicRt = rt.type({
]),
created_at: rt.string,
created_by: UserRT,
+ owner: rt.string,
pushed_at: rt.union([rt.string, rt.null]),
pushed_by: rt.union([UserRT, rt.null]),
updated_at: rt.union([rt.string, rt.null]),
@@ -57,6 +59,7 @@ export enum CommentType {
export const ContextTypeUserRt = rt.type({
comment: rt.string,
type: rt.literal(CommentType.user),
+ owner: rt.string,
});
/**
@@ -72,6 +75,7 @@ export const AlertCommentRequestRt = rt.type({
id: rt.union([rt.string, rt.null]),
name: rt.union([rt.string, rt.null]),
}),
+ owner: rt.string,
});
const AttributesTypeUserRt = rt.intersection([ContextTypeUserRt, CommentAttributesBasicRt]);
@@ -127,7 +131,17 @@ export const CommentsResponseRt = rt.type({
export const AllCommentsResponseRt = rt.array(CommentResponseRt);
+export const FindQueryParamsRt = rt.partial({
+ ...SavedObjectFindOptionsRt.props,
+ /**
+ * If specified the attachments found will be associated to a sub case instead of a case object
+ */
+ subCaseId: rt.string,
+});
+
+export type FindQueryParams = rt.TypeOf;
export type AttributesTypeAlerts = rt.TypeOf;
+export type AttributesTypeUser = rt.TypeOf;
export type CommentAttributes = rt.TypeOf;
export type CommentRequest = rt.TypeOf;
export type CommentResponse = rt.TypeOf;
diff --git a/x-pack/plugins/cases/common/api/cases/configure.ts b/x-pack/plugins/cases/common/api/cases/configure.ts
index b5a89efde1767..2814dd44f513f 100644
--- a/x-pack/plugins/cases/common/api/cases/configure.ts
+++ b/x-pack/plugins/cases/common/api/cases/configure.ts
@@ -9,18 +9,34 @@ import * as rt from 'io-ts';
import { UserRT } from '../user';
import { CaseConnectorRt, ConnectorMappingsRt, ESCaseConnector } from '../connectors';
+import { OmitProp } from '../runtime_types';
+import { OWNER_FIELD } from './constants';
// TODO: we will need to add this type rt.literal('close-by-third-party')
const ClosureTypeRT = rt.union([rt.literal('close-by-user'), rt.literal('close-by-pushing')]);
const CasesConfigureBasicRt = rt.type({
+ /**
+ * The external connector
+ */
connector: CaseConnectorRt,
+ /**
+ * Whether to close the case after it has been synced with the external system
+ */
closure_type: ClosureTypeRT,
+ /**
+ * The plugin owner that manages this configuration
+ */
+ owner: rt.string,
});
+const CasesConfigureBasicWithoutOwnerRt = rt.type(
+ OmitProp(CasesConfigureBasicRt.props, OWNER_FIELD)
+);
+
export const CasesConfigureRequestRt = CasesConfigureBasicRt;
export const CasesConfigurePatchRt = rt.intersection([
- rt.partial(CasesConfigureBasicRt.props),
+ rt.partial(CasesConfigureBasicWithoutOwnerRt.props),
rt.type({ version: rt.string }),
]);
@@ -38,18 +54,37 @@ export const CaseConfigureResponseRt = rt.intersection([
CaseConfigureAttributesRt,
ConnectorMappingsRt,
rt.type({
+ id: rt.string,
version: rt.string,
error: rt.union([rt.string, rt.null]),
+ owner: rt.string,
}),
]);
+export const GetConfigureFindRequestRt = rt.partial({
+ /**
+ * The configuration plugin owner to filter the search by. If this is left empty the results will include all configurations
+ * that the user has permissions to access
+ */
+ owner: rt.union([rt.array(rt.string), rt.string]),
+});
+
+export const CaseConfigureRequestParamsRt = rt.type({
+ configuration_id: rt.string,
+});
+
+export const CaseConfigurationsResponseRt = rt.array(CaseConfigureResponseRt);
+
export type ClosureType = rt.TypeOf;
export type CasesConfigure = rt.TypeOf;
export type CasesConfigureRequest = rt.TypeOf;
export type CasesConfigurePatch = rt.TypeOf;
export type CasesConfigureAttributes = rt.TypeOf;
export type CasesConfigureResponse = rt.TypeOf;
+export type CasesConfigurationsResponse = rt.TypeOf;
export type ESCasesConfigureAttributes = Omit & {
connector: ESCaseConnector;
};
+
+export type GetConfigureFindRequest = rt.TypeOf;
diff --git a/x-pack/plugins/cases/common/api/cases/constants.ts b/x-pack/plugins/cases/common/api/cases/constants.ts
new file mode 100644
index 0000000000000..92755ec633ecc
--- /dev/null
+++ b/x-pack/plugins/cases/common/api/cases/constants.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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+/**
+ * This field is used for authorization of the entities within the cases plugin. Each entity within Cases will have the owner field
+ * set to a string that represents the plugin that "owns" (i.e. the plugin that originally issued the POST request to
+ * create the entity) the entity.
+ *
+ * The Authorization class constructs a string composed of the operation being performed (createCase, getComment, etc),
+ * and the owner of the entity being acted upon or created. This string is then given to the Security plugin which
+ * checks to see if the user making the request has that particular string stored within it's privileges. If it does,
+ * then the operation succeeds, otherwise the operation fails.
+ *
+ * APIs that create/update an entity require that the owner field be passed in the body of the request.
+ * APIs that search for entities typically require that the owner be passed as a query parameter.
+ * APIs that specify an ID of an entity directly generally don't need to specify the owner field.
+ *
+ * For APIs that create/update an entity, the RBAC implementation checks to see if the user making the request has the
+ * correct privileges for performing that action (a create/update) for the specified owner.
+ * This check is done through the Security plugin's API.
+ *
+ * For APIs that search for entities, the RBAC implementation creates a filter for the saved objects query that limits
+ * the search to only owners that the user has access to. We also check that the objects returned by the saved objects
+ * API have the limited owner scope. If we find one that the user does not have permissions for, we throw a 403 error.
+ * The owner field that is passed in as a query parameter can be used to further limit the results. If a user attempts
+ * to pass an owner that they do not have access to, the owner is ignored.
+ *
+ * For APIs that retrieve/delete entities directly using their ID, the RBAC implementation requests the object first,
+ * and then checks to see if the user making the request has access to that operation and owner. If the user does, the
+ * operation continues, otherwise we throw a 403.
+ */
+export const OWNER_FIELD = 'owner';
diff --git a/x-pack/plugins/cases/common/api/cases/index.ts b/x-pack/plugins/cases/common/api/cases/index.ts
index 6e7fb818cb2b5..0f78ca9b35377 100644
--- a/x-pack/plugins/cases/common/api/cases/index.ts
+++ b/x-pack/plugins/cases/common/api/cases/index.ts
@@ -11,3 +11,4 @@ export * from './comment';
export * from './status';
export * from './user_actions';
export * from './sub_case';
+export * from './constants';
diff --git a/x-pack/plugins/cases/common/api/cases/status.ts b/x-pack/plugins/cases/common/api/cases/status.ts
index 7286e19da9159..d37e68007a21d 100644
--- a/x-pack/plugins/cases/common/api/cases/status.ts
+++ b/x-pack/plugins/cases/common/api/cases/status.ts
@@ -27,4 +27,13 @@ export const CasesStatusResponseRt = rt.type({
count_closed_cases: rt.number,
});
+export const CasesStatusRequestRt = rt.partial({
+ /**
+ * The owner of the cases to retrieve the status stats from. If no owner is provided the stats for all cases
+ * that the user has access to will be returned.
+ */
+ owner: rt.union([rt.array(rt.string), rt.string]),
+});
+
export type CasesStatusResponse = rt.TypeOf;
+export type CasesStatusRequest = rt.TypeOf;
diff --git a/x-pack/plugins/cases/common/api/cases/sub_case.ts b/x-pack/plugins/cases/common/api/cases/sub_case.ts
index c46f87c547d50..654b74276733b 100644
--- a/x-pack/plugins/cases/common/api/cases/sub_case.ts
+++ b/x-pack/plugins/cases/common/api/cases/sub_case.ts
@@ -14,6 +14,9 @@ import { CasesStatusResponseRt } from './status';
import { CaseStatusRt } from './status';
const SubCaseBasicRt = rt.type({
+ /**
+ * The status of the sub case (open, closed, in-progress)
+ */
status: CaseStatusRt,
});
@@ -26,19 +29,48 @@ export const SubCaseAttributesRt = rt.intersection([
created_by: rt.union([UserRT, rt.null]),
updated_at: rt.union([rt.string, rt.null]),
updated_by: rt.union([UserRT, rt.null]),
+ owner: rt.string,
}),
]);
export const SubCasesFindRequestRt = rt.partial({
+ /**
+ * The status of the sub case (open, closed, in-progress)
+ */
status: CaseStatusRt,
+ /**
+ * Operator to use for the `search` field
+ */
defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
+ /**
+ * The fields in the entity to return in the response
+ */
fields: rt.array(rt.string),
+ /**
+ * The page of objects to return
+ */
page: NumberFromString,
+ /**
+ * The number of objects to include in each page
+ */
perPage: NumberFromString,
+ /**
+ * An Elasticsearch simple_query_string
+ */
search: rt.string,
+ /**
+ * The fields to perform the simple_query_string parsed query against
+ */
searchFields: rt.array(rt.string),
+ /**
+ * The field to use for sorting the found objects.
+ */
sortField: rt.string,
+ /**
+ * The order to sort by
+ */
sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]),
+ owner: rt.string,
});
export const SubCaseResponseRt = rt.intersection([
@@ -78,3 +110,4 @@ export type SubCasesResponse = rt.TypeOf;
export type SubCasesFindResponse = rt.TypeOf;
export type SubCasePatchRequest = rt.TypeOf;
export type SubCasesPatchRequest = rt.TypeOf;
+export type SubCasesFindRequest = rt.TypeOf;
diff --git a/x-pack/plugins/cases/common/api/cases/user_actions.ts b/x-pack/plugins/cases/common/api/cases/user_actions.ts
index 7188ee44efa93..03912c550d77a 100644
--- a/x-pack/plugins/cases/common/api/cases/user_actions.ts
+++ b/x-pack/plugins/cases/common/api/cases/user_actions.ts
@@ -6,6 +6,7 @@
*/
import * as rt from 'io-ts';
+import { OWNER_FIELD } from './constants';
import { UserRT } from '../user';
@@ -22,6 +23,7 @@ const UserActionFieldTypeRt = rt.union([
rt.literal('status'),
rt.literal('settings'),
rt.literal('sub_case'),
+ rt.literal(OWNER_FIELD),
]);
const UserActionFieldRt = rt.array(UserActionFieldTypeRt);
const UserActionRt = rt.union([
@@ -40,6 +42,7 @@ const CaseUserActionBasicRT = rt.type({
action_by: UserRT,
new_value: rt.union([rt.string, rt.null]),
old_value: rt.union([rt.string, rt.null]),
+ owner: rt.string,
});
const CaseUserActionResponseRT = rt.intersection([
@@ -58,6 +61,7 @@ export const CaseUserActionsResponseRt = rt.array(CaseUserActionResponseRT);
export type CaseUserActionAttributes = rt.TypeOf;
export type CaseUserActionsResponse = rt.TypeOf;
+export type CaseUserActionResponse = rt.TypeOf;
export type UserAction = rt.TypeOf;
export type UserActionField = rt.TypeOf;
diff --git a/x-pack/plugins/cases/common/api/connectors/mappings.ts b/x-pack/plugins/cases/common/api/connectors/mappings.ts
index 3d2013af47688..e0fdd2d7e62dc 100644
--- a/x-pack/plugins/cases/common/api/connectors/mappings.ts
+++ b/x-pack/plugins/cases/common/api/connectors/mappings.ts
@@ -31,6 +31,7 @@ export const ConnectorMappingsAttributesRT = rt.type({
export const ConnectorMappingsRt = rt.type({
mappings: rt.array(ConnectorMappingsAttributesRT),
+ owner: rt.string,
});
export type ConnectorMappingsAttributes = rt.TypeOf;
diff --git a/x-pack/plugins/cases/common/api/helpers.ts b/x-pack/plugins/cases/common/api/helpers.ts
index 7ac686ce5c8dd..4647be5a91747 100644
--- a/x-pack/plugins/cases/common/api/helpers.ts
+++ b/x-pack/plugins/cases/common/api/helpers.ts
@@ -14,6 +14,7 @@ import {
SUB_CASES_URL,
CASE_PUSH_URL,
SUB_CASE_USER_ACTIONS_URL,
+ CASE_CONFIGURE_DETAILS_URL,
CASE_ALERTS_URL,
} from '../constants';
@@ -49,6 +50,10 @@ export const getCasePushUrl = (caseId: string, connectorId: string): string => {
return CASE_PUSH_URL.replace('{case_id}', caseId).replace('{connector_id}', connectorId);
};
+export const getCaseConfigurationDetailsUrl = (configureID: string): string => {
+ return CASE_CONFIGURE_DETAILS_URL.replace('{configuration_id}', configureID);
+};
+
export const getCasesFromAlertsUrl = (alertId: string): string => {
return CASE_ALERTS_URL.replace('{alert_id}', alertId);
};
diff --git a/x-pack/plugins/cases/common/api/runtime_types.ts b/x-pack/plugins/cases/common/api/runtime_types.ts
index f608b7effe969..361786985c6de 100644
--- a/x-pack/plugins/cases/common/api/runtime_types.ts
+++ b/x-pack/plugins/cases/common/api/runtime_types.ts
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { omit } from 'lodash';
import { either, fold } from 'fp-ts/lib/Either';
import { identity } from 'fp-ts/lib/function';
import { pipe } from 'fp-ts/lib/pipeable';
@@ -13,6 +14,9 @@ import { isObject } from 'lodash/fp';
type ErrorFactory = (message: string) => Error;
+export const OmitProp = (o: O, k: K): Omit =>
+ omit(o, k);
+
/**
* @deprecated Use packages/kbn-securitysolution-io-ts-utils/src/format_errors/index.ts
* Bug fix for the TODO is in the format_errors package
@@ -68,7 +72,9 @@ const getExcessProps = (props: rt.Props, r: Record): string[] =
return ex;
};
-export function excess>(codec: C): C {
+export function excess | rt.PartialType>(
+ codec: C
+): C {
const r = new rt.InterfaceType(
codec.name,
codec.is,
diff --git a/x-pack/plugins/cases/common/api/saved_object.ts b/x-pack/plugins/cases/common/api/saved_object.ts
index e0ae4ee82c490..2ed6ec2acdfe4 100644
--- a/x-pack/plugins/cases/common/api/saved_object.ts
+++ b/x-pack/plugins/cases/common/api/saved_object.ts
@@ -23,16 +23,49 @@ export const NumberFromString = new rt.Type(
const ReferenceRt = rt.type({ id: rt.string, type: rt.string });
export const SavedObjectFindOptionsRt = rt.partial({
+ /**
+ * The default operator to use for the simple_query_string
+ */
defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
+ /**
+ * The operator for controlling the logic of the `hasReference` field
+ */
hasReferenceOperator: rt.union([rt.literal('AND'), rt.literal('OR')]),
+ /**
+ * Filter by objects that have an association to another object
+ */
hasReference: rt.union([rt.array(ReferenceRt), ReferenceRt]),
+ /**
+ * The fields to return in the attributes key of the response
+ */
fields: rt.array(rt.string),
+ /**
+ * The filter is a KQL string with the caveat that if you filter with an attribute from your saved object type, it should look like that: savedObjectType.attributes.title: "myTitle". However, If you use a root attribute of a saved object such as updated_at, you will have to define your filter like that: savedObjectType.updated_at > 2018-12-22
+ */
filter: rt.string,
+ /**
+ * The page of objects to return
+ */
page: NumberFromString,
+ /**
+ * The number of objects to return for a page
+ */
perPage: NumberFromString,
+ /**
+ * An Elasticsearch simple_query_string query that filters the objects in the response
+ */
search: rt.string,
+ /**
+ * The fields to perform the simple_query_string parsed query against
+ */
searchFields: rt.array(rt.string),
+ /**
+ * Sorts the response. Includes "root" and "type" fields. "root" fields exist for all saved objects, such as "updated_at". "type" fields are specific to an object type, such as fields returned in the attributes key of the response. When a single type is defined in the type parameter, the "root" and "type" fields are allowed, and validity checks are made in that order. When multiple types are defined in the type parameter, only "root" fields are allowed
+ */
sortField: rt.string,
+ /**
+ * Order to sort the response
+ */
sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]),
});
diff --git a/x-pack/plugins/cases/common/constants.ts b/x-pack/plugins/cases/common/constants.ts
index 966305524c059..72c21aa12dcf2 100644
--- a/x-pack/plugins/cases/common/constants.ts
+++ b/x-pack/plugins/cases/common/constants.ts
@@ -9,6 +9,24 @@ export const DEFAULT_DATE_FORMAT_TZ = 'dateFormat:tz';
export const APP_ID = 'cases';
+export const CASE_SAVED_OBJECT = 'cases';
+export const CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT = 'cases-connector-mappings';
+export const SUB_CASE_SAVED_OBJECT = 'cases-sub-case';
+export const CASE_USER_ACTION_SAVED_OBJECT = 'cases-user-actions';
+export const CASE_COMMENT_SAVED_OBJECT = 'cases-comments';
+export const CASE_CONFIGURE_SAVED_OBJECT = 'cases-configure';
+
+/**
+ * If more values are added here please also add them here: x-pack/test/case_api_integration/common/fixtures/plugins
+ */
+export const SAVED_OBJECT_TYPES = [
+ CASE_SAVED_OBJECT,
+ CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT,
+ CASE_USER_ACTION_SAVED_OBJECT,
+ CASE_COMMENT_SAVED_OBJECT,
+ CASE_CONFIGURE_SAVED_OBJECT,
+];
+
/**
* Case routes
*/
@@ -16,6 +34,7 @@ export const APP_ID = 'cases';
export const CASES_URL = '/api/cases';
export const CASE_DETAILS_URL = `${CASES_URL}/{case_id}`;
export const CASE_CONFIGURE_URL = `${CASES_URL}/configure`;
+export const CASE_CONFIGURE_DETAILS_URL = `${CASES_URL}/configure/{configuration_id}`;
export const CASE_CONFIGURE_CONNECTORS_URL = `${CASE_CONFIGURE_URL}/connectors`;
export const SUB_CASES_PATCH_DEL_URL = `${CASES_URL}/sub_cases`;
@@ -57,7 +76,19 @@ export const SUPPORTED_CONNECTORS = [
export const MAX_ALERTS_PER_SUB_CASE = 5000;
export const MAX_GENERATED_ALERTS_PER_SUB_CASE = 50;
+/**
+ * This must be the same value that the security solution plugin uses to define the case kind when it registers the
+ * feature for the 7.13 migration only.
+ *
+ * This variable is being also used by test files and mocks.
+ */
+export const SECURITY_SOLUTION_OWNER = 'securitySolution';
+
/**
* This flag governs enabling the case as a connector feature. It is disabled by default as the feature is not complete.
*/
export const ENABLE_CASE_CONNECTOR = false;
+
+if (ENABLE_CASE_CONNECTOR) {
+ SAVED_OBJECT_TYPES.push(SUB_CASE_SAVED_OBJECT);
+}
diff --git a/x-pack/plugins/cases/common/ui/types.ts b/x-pack/plugins/cases/common/ui/types.ts
index 43e3453500b17..284f5e706292c 100644
--- a/x-pack/plugins/cases/common/ui/types.ts
+++ b/x-pack/plugins/cases/common/ui/types.ts
@@ -58,6 +58,7 @@ export interface CaseExternalService {
interface BasicCase {
id: string;
+ owner: string;
closedAt: string | null;
closedBy: ElasticUser | null;
comments: Comment[];
@@ -129,7 +130,7 @@ export interface ElasticUser {
export interface FetchCasesProps extends ApiProps {
queryParams?: QueryParams;
- filterOptions?: FilterOptions;
+ filterOptions?: FilterOptions & { owner: string[] };
}
export interface ApiProps {
diff --git a/x-pack/plugins/cases/docs/README.md b/x-pack/plugins/cases/docs/README.md
new file mode 100644
index 0000000000000..85482d98dc509
--- /dev/null
+++ b/x-pack/plugins/cases/docs/README.md
@@ -0,0 +1,37 @@
+# Cases Client API Docs
+
+This directory contains generated docs using `typedoc` for the cases client API that can be called from other server
+plugins. This README will describe how to generate a new version of these markdown docs in the event that new methods
+or parameters are added.
+
+## TypeDoc Info
+
+See more info at:
+and: for the markdown plugin
+
+## Install dependencies
+
+```bash
+yarn global add typedoc typedoc-plugin-markdown
+```
+
+## Generate the docs
+
+```bash
+cd x-pack/plugins/cases/docs
+npx typedoc --options cases_client_typedoc.json
+```
+
+After running the above commands the files in the `server` directory will be updated to match the new tsdocs.
+If additional markdown directory should be created we can create a new typedoc configuration file and adjust the `out`
+directory accordingly.
+
+## Troubleshooting
+
+If you run into tsc errors that seem unrelated to the cases plugin try executing these commands before running `typedoc`
+
+```bash
+cd
+npx yarn kbn bootstrap
+node scripts/build_ts_refs.js --clean --no-cache
+```
diff --git a/x-pack/plugins/cases/docs/cases_client/cases_client_api.md b/x-pack/plugins/cases/docs/cases_client/cases_client_api.md
new file mode 100644
index 0000000000000..d7e75af3142e6
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/cases_client_api.md
@@ -0,0 +1,22 @@
+Cases Client API Interface
+
+# Cases Client API Interface
+
+## Table of contents
+
+### Modules
+
+- [attachments/add](modules/attachments_add.md)
+- [attachments/client](modules/attachments_client.md)
+- [attachments/delete](modules/attachments_delete.md)
+- [attachments/get](modules/attachments_get.md)
+- [attachments/update](modules/attachments_update.md)
+- [cases/client](modules/cases_client.md)
+- [cases/get](modules/cases_get.md)
+- [cases/push](modules/cases_push.md)
+- [client](modules/client.md)
+- [configure/client](modules/configure_client.md)
+- [stats/client](modules/stats_client.md)
+- [sub\_cases/client](modules/sub_cases_client.md)
+- [typedoc\_interfaces](modules/typedoc_interfaces.md)
+- [user\_actions/client](modules/user_actions_client.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/classes/client.casesclient.md b/x-pack/plugins/cases/docs/cases_client/classes/client.casesclient.md
new file mode 100644
index 0000000000000..98e2f284da4a6
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/classes/client.casesclient.md
@@ -0,0 +1,178 @@
+[Cases Client API Interface](../cases_client_api.md) / [client](../modules/client.md) / CasesClient
+
+# Class: CasesClient
+
+[client](../modules/client.md).CasesClient
+
+Client wrapper that contains accessor methods for individual entities within the cases system.
+
+## Table of contents
+
+### Constructors
+
+- [constructor](client.casesclient.md#constructor)
+
+### Properties
+
+- [\_attachments](client.casesclient.md#_attachments)
+- [\_cases](client.casesclient.md#_cases)
+- [\_casesClientInternal](client.casesclient.md#_casesclientinternal)
+- [\_configure](client.casesclient.md#_configure)
+- [\_stats](client.casesclient.md#_stats)
+- [\_subCases](client.casesclient.md#_subcases)
+- [\_userActions](client.casesclient.md#_useractions)
+
+### Accessors
+
+- [attachments](client.casesclient.md#attachments)
+- [cases](client.casesclient.md#cases)
+- [configure](client.casesclient.md#configure)
+- [stats](client.casesclient.md#stats)
+- [subCases](client.casesclient.md#subcases)
+- [userActions](client.casesclient.md#useractions)
+
+## Constructors
+
+### constructor
+
+\+ **new CasesClient**(`args`: CasesClientArgs): [*CasesClient*](client.casesclient.md)
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `args` | CasesClientArgs |
+
+**Returns:** [*CasesClient*](client.casesclient.md)
+
+Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L28)
+
+## Properties
+
+### \_attachments
+
+• `Private` `Readonly` **\_attachments**: [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
+
+Defined in: [client.ts:24](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L24)
+
+___
+
+### \_cases
+
+• `Private` `Readonly` **\_cases**: [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
+
+Defined in: [client.ts:23](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L23)
+
+___
+
+### \_casesClientInternal
+
+• `Private` `Readonly` **\_casesClientInternal**: *CasesClientInternal*
+
+Defined in: [client.ts:22](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L22)
+
+___
+
+### \_configure
+
+• `Private` `Readonly` **\_configure**: [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
+
+Defined in: [client.ts:27](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L27)
+
+___
+
+### \_stats
+
+• `Private` `Readonly` **\_stats**: [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
+
+Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L28)
+
+___
+
+### \_subCases
+
+• `Private` `Readonly` **\_subCases**: [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
+
+Defined in: [client.ts:26](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L26)
+
+___
+
+### \_userActions
+
+• `Private` `Readonly` **\_userActions**: [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
+
+Defined in: [client.ts:25](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L25)
+
+## Accessors
+
+### attachments
+
+• get **attachments**(): [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
+
+Retrieves an interface for interacting with attachments (comments) entities.
+
+**Returns:** [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
+
+Defined in: [client.ts:50](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L50)
+
+___
+
+### cases
+
+• get **cases**(): [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
+
+Retrieves an interface for interacting with cases entities.
+
+**Returns:** [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
+
+Defined in: [client.ts:43](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L43)
+
+___
+
+### configure
+
+• get **configure**(): [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
+
+Retrieves an interface for interacting with the configuration of external connectors for the plugin entities.
+
+**Returns:** [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
+
+Defined in: [client.ts:76](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L76)
+
+___
+
+### stats
+
+• get **stats**(): [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
+
+Retrieves an interface for retrieving statistics related to the cases entities.
+
+**Returns:** [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
+
+Defined in: [client.ts:83](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L83)
+
+___
+
+### subCases
+
+• get **subCases**(): [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
+
+Retrieves an interface for interacting with the case as a connector entities.
+
+Currently this functionality is disabled and will throw an error if this function is called.
+
+**Returns:** [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
+
+Defined in: [client.ts:66](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L66)
+
+___
+
+### userActions
+
+• get **userActions**(): [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
+
+Retrieves an interface for interacting with the user actions associated with the plugin entities.
+
+**Returns:** [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
+
+Defined in: [client.ts:57](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/client.ts#L57)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_add.addargs.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_add.addargs.md
new file mode 100644
index 0000000000000..1bbca9167a5c2
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_add.addargs.md
@@ -0,0 +1,34 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/add](../modules/attachments_add.md) / AddArgs
+
+# Interface: AddArgs
+
+[attachments/add](../modules/attachments_add.md).AddArgs
+
+The arguments needed for creating a new attachment to a case.
+
+## Table of contents
+
+### Properties
+
+- [caseId](attachments_add.addargs.md#caseid)
+- [comment](attachments_add.addargs.md#comment)
+
+## Properties
+
+### caseId
+
+• **caseId**: *string*
+
+The case ID that this attachment will be associated with
+
+Defined in: [attachments/add.ts:308](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/add.ts#L308)
+
+___
+
+### comment
+
+• **comment**: { `comment`: *string* ; `owner`: *string* ; `type`: user } \| { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert }
+
+The attachment values.
+
+Defined in: [attachments/add.ts:312](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/add.ts#L312)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_client.attachmentssubclient.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_client.attachmentssubclient.md
new file mode 100644
index 0000000000000..e9f65bcf9915a
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_client.attachmentssubclient.md
@@ -0,0 +1,147 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/client](../modules/attachments_client.md) / AttachmentsSubClient
+
+# Interface: AttachmentsSubClient
+
+[attachments/client](../modules/attachments_client.md).AttachmentsSubClient
+
+API for interacting with the attachments to a case.
+
+## Table of contents
+
+### Methods
+
+- [add](attachments_client.attachmentssubclient.md#add)
+- [delete](attachments_client.attachmentssubclient.md#delete)
+- [deleteAll](attachments_client.attachmentssubclient.md#deleteall)
+- [find](attachments_client.attachmentssubclient.md#find)
+- [get](attachments_client.attachmentssubclient.md#get)
+- [getAll](attachments_client.attachmentssubclient.md#getall)
+- [update](attachments_client.attachmentssubclient.md#update)
+
+## Methods
+
+### add
+
+▸ **add**(`params`: [*AddArgs*](attachments_add.addargs.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Adds an attachment to a case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | [*AddArgs*](attachments_add.addargs.md) |
+
+**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Defined in: [attachments/client.ts:25](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L25)
+
+___
+
+### delete
+
+▸ **delete**(`deleteArgs`: [*DeleteArgs*](attachments_delete.deleteargs.md)): *Promise*
+
+Deletes a single attachment for a specific case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `deleteArgs` | [*DeleteArgs*](attachments_delete.deleteargs.md) |
+
+**Returns:** *Promise*
+
+Defined in: [attachments/client.ts:33](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L33)
+
+___
+
+### deleteAll
+
+▸ **deleteAll**(`deleteAllArgs`: [*DeleteAllArgs*](attachments_delete.deleteallargs.md)): *Promise*
+
+Deletes all attachments associated with a single case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `deleteAllArgs` | [*DeleteAllArgs*](attachments_delete.deleteallargs.md) |
+
+**Returns:** *Promise*
+
+Defined in: [attachments/client.ts:29](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L29)
+
+___
+
+### find
+
+▸ **find**(`findArgs`: [*FindArgs*](attachments_get.findargs.md)): *Promise*<[*ICommentsResponse*](typedoc_interfaces.icommentsresponse.md)\>
+
+Retrieves all comments matching the search criteria.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `findArgs` | [*FindArgs*](attachments_get.findargs.md) |
+
+**Returns:** *Promise*<[*ICommentsResponse*](typedoc_interfaces.icommentsresponse.md)\>
+
+Defined in: [attachments/client.ts:37](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L37)
+
+___
+
+### get
+
+▸ **get**(`getArgs`: [*GetArgs*](attachments_get.getargs.md)): *Promise*<{ `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }\>
+
+Retrieves a single attachment for a case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `getArgs` | [*GetArgs*](attachments_get.getargs.md) |
+
+**Returns:** *Promise*<{ `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }\>
+
+Defined in: [attachments/client.ts:45](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L45)
+
+___
+
+### getAll
+
+▸ **getAll**(`getAllArgs`: [*GetAllArgs*](attachments_get.getallargs.md)): *Promise*<[*IAllCommentsResponse*](typedoc_interfaces.iallcommentsresponse.md)\>
+
+Gets all attachments for a single case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `getAllArgs` | [*GetAllArgs*](attachments_get.getallargs.md) |
+
+**Returns:** *Promise*<[*IAllCommentsResponse*](typedoc_interfaces.iallcommentsresponse.md)\>
+
+Defined in: [attachments/client.ts:41](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L41)
+
+___
+
+### update
+
+▸ **update**(`updateArgs`: [*UpdateArgs*](attachments_update.updateargs.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Updates a specific attachment.
+
+The request must include all fields for the attachment. Even the fields that are not changing.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `updateArgs` | [*UpdateArgs*](attachments_update.updateargs.md) |
+
+**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Defined in: [attachments/client.ts:51](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/client.ts#L51)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_delete.deleteallargs.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_delete.deleteallargs.md
new file mode 100644
index 0000000000000..26b00ac6e037e
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_delete.deleteallargs.md
@@ -0,0 +1,34 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/delete](../modules/attachments_delete.md) / DeleteAllArgs
+
+# Interface: DeleteAllArgs
+
+[attachments/delete](../modules/attachments_delete.md).DeleteAllArgs
+
+Parameters for deleting all comments of a case or sub case.
+
+## Table of contents
+
+### Properties
+
+- [caseID](attachments_delete.deleteallargs.md#caseid)
+- [subCaseID](attachments_delete.deleteallargs.md#subcaseid)
+
+## Properties
+
+### caseID
+
+• **caseID**: *string*
+
+The case ID to delete all attachments for
+
+Defined in: [attachments/delete.ts:26](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L26)
+
+___
+
+### subCaseID
+
+• `Optional` **subCaseID**: *string*
+
+If specified the caseID will be ignored and this value will be used to find a sub case for deleting all the attachments
+
+Defined in: [attachments/delete.ts:30](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L30)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_delete.deleteargs.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_delete.deleteargs.md
new file mode 100644
index 0000000000000..f9d4038eb417a
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_delete.deleteargs.md
@@ -0,0 +1,45 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/delete](../modules/attachments_delete.md) / DeleteArgs
+
+# Interface: DeleteArgs
+
+[attachments/delete](../modules/attachments_delete.md).DeleteArgs
+
+Parameters for deleting a single attachment of a case or sub case.
+
+## Table of contents
+
+### Properties
+
+- [attachmentID](attachments_delete.deleteargs.md#attachmentid)
+- [caseID](attachments_delete.deleteargs.md#caseid)
+- [subCaseID](attachments_delete.deleteargs.md#subcaseid)
+
+## Properties
+
+### attachmentID
+
+• **attachmentID**: *string*
+
+The attachment ID to delete
+
+Defined in: [attachments/delete.ts:44](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L44)
+
+___
+
+### caseID
+
+• **caseID**: *string*
+
+The case ID to delete an attachment from
+
+Defined in: [attachments/delete.ts:40](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L40)
+
+___
+
+### subCaseID
+
+• `Optional` **subCaseID**: *string*
+
+If specified the caseID will be ignored and this value will be used to find a sub case for deleting the attachment
+
+Defined in: [attachments/delete.ts:48](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/delete.ts#L48)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.findargs.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.findargs.md
new file mode 100644
index 0000000000000..dbbac0065be85
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.findargs.md
@@ -0,0 +1,51 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/get](../modules/attachments_get.md) / FindArgs
+
+# Interface: FindArgs
+
+[attachments/get](../modules/attachments_get.md).FindArgs
+
+Parameters for finding attachments of a case
+
+## Table of contents
+
+### Properties
+
+- [caseID](attachments_get.findargs.md#caseid)
+- [queryParams](attachments_get.findargs.md#queryparams)
+
+## Properties
+
+### caseID
+
+• **caseID**: *string*
+
+The case ID for finding associated attachments
+
+Defined in: [attachments/get.ts:48](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L48)
+
+___
+
+### queryParams
+
+• `Optional` **queryParams**: *object*
+
+Optional parameters for filtering the returned attachments
+
+#### Type declaration
+
+| Name | Type |
+| :------ | :------ |
+| `defaultSearchOperator` | *undefined* \| ``"AND"`` \| ``"OR"`` |
+| `fields` | *undefined* \| *string*[] |
+| `filter` | *undefined* \| *string* |
+| `hasReference` | *undefined* \| { `id`: *string* ; `type`: *string* } \| { `id`: *string* ; `type`: *string* }[] |
+| `hasReferenceOperator` | *undefined* \| ``"AND"`` \| ``"OR"`` |
+| `page` | *undefined* \| *number* |
+| `perPage` | *undefined* \| *number* |
+| `search` | *undefined* \| *string* |
+| `searchFields` | *undefined* \| *string*[] |
+| `sortField` | *undefined* \| *string* |
+| `sortOrder` | *undefined* \| ``"desc"`` \| ``"asc"`` |
+| `subCaseId` | *undefined* \| *string* |
+
+Defined in: [attachments/get.ts:52](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L52)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.getallargs.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.getallargs.md
new file mode 100644
index 0000000000000..dbd66291e22de
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.getallargs.md
@@ -0,0 +1,45 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/get](../modules/attachments_get.md) / GetAllArgs
+
+# Interface: GetAllArgs
+
+[attachments/get](../modules/attachments_get.md).GetAllArgs
+
+Parameters for retrieving all attachments of a case
+
+## Table of contents
+
+### Properties
+
+- [caseID](attachments_get.getallargs.md#caseid)
+- [includeSubCaseComments](attachments_get.getallargs.md#includesubcasecomments)
+- [subCaseID](attachments_get.getallargs.md#subcaseid)
+
+## Properties
+
+### caseID
+
+• **caseID**: *string*
+
+The case ID to retrieve all attachments for
+
+Defined in: [attachments/get.ts:62](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L62)
+
+___
+
+### includeSubCaseComments
+
+• `Optional` **includeSubCaseComments**: *boolean*
+
+Optionally include the attachments associated with a sub case
+
+Defined in: [attachments/get.ts:66](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L66)
+
+___
+
+### subCaseID
+
+• `Optional` **subCaseID**: *string*
+
+If included the case ID will be ignored and the attachments will be retrieved from the specified ID of the sub case
+
+Defined in: [attachments/get.ts:70](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L70)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.getargs.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.getargs.md
new file mode 100644
index 0000000000000..abfd4bb5958d3
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_get.getargs.md
@@ -0,0 +1,32 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/get](../modules/attachments_get.md) / GetArgs
+
+# Interface: GetArgs
+
+[attachments/get](../modules/attachments_get.md).GetArgs
+
+## Table of contents
+
+### Properties
+
+- [attachmentID](attachments_get.getargs.md#attachmentid)
+- [caseID](attachments_get.getargs.md#caseid)
+
+## Properties
+
+### attachmentID
+
+• **attachmentID**: *string*
+
+The ID of the attachment to retrieve
+
+Defined in: [attachments/get.ts:81](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L81)
+
+___
+
+### caseID
+
+• **caseID**: *string*
+
+The ID of the case to retrieve an attachment from
+
+Defined in: [attachments/get.ts:77](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/get.ts#L77)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_update.updateargs.md b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_update.updateargs.md
new file mode 100644
index 0000000000000..b571067175f62
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/attachments_update.updateargs.md
@@ -0,0 +1,45 @@
+[Cases Client API Interface](../cases_client_api.md) / [attachments/update](../modules/attachments_update.md) / UpdateArgs
+
+# Interface: UpdateArgs
+
+[attachments/update](../modules/attachments_update.md).UpdateArgs
+
+Parameters for updating a single attachment
+
+## Table of contents
+
+### Properties
+
+- [caseID](attachments_update.updateargs.md#caseid)
+- [subCaseID](attachments_update.updateargs.md#subcaseid)
+- [updateRequest](attachments_update.updateargs.md#updaterequest)
+
+## Properties
+
+### caseID
+
+• **caseID**: *string*
+
+The ID of the case that is associated with this attachment
+
+Defined in: [attachments/update.ts:29](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/update.ts#L29)
+
+___
+
+### subCaseID
+
+• `Optional` **subCaseID**: *string*
+
+The ID of a sub case, if specified a sub case will be searched for to perform the attachment update instead of on a case
+
+Defined in: [attachments/update.ts:37](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/update.ts#L37)
+
+___
+
+### updateRequest
+
+• **updateRequest**: { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `id`: *string* ; `version`: *string* }
+
+The full attachment request with the fields updated with appropriate values
+
+Defined in: [attachments/update.ts:33](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/attachments/update.ts#L33)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/cases_client.casessubclient.md b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_client.casessubclient.md
new file mode 100644
index 0000000000000..e7d7dea34d0ad
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_client.casessubclient.md
@@ -0,0 +1,189 @@
+[Cases Client API Interface](../cases_client_api.md) / [cases/client](../modules/cases_client.md) / CasesSubClient
+
+# Interface: CasesSubClient
+
+[cases/client](../modules/cases_client.md).CasesSubClient
+
+API for interacting with the cases entities.
+
+## Table of contents
+
+### Methods
+
+- [create](cases_client.casessubclient.md#create)
+- [delete](cases_client.casessubclient.md#delete)
+- [find](cases_client.casessubclient.md#find)
+- [get](cases_client.casessubclient.md#get)
+- [getCaseIDsByAlertID](cases_client.casessubclient.md#getcaseidsbyalertid)
+- [getReporters](cases_client.casessubclient.md#getreporters)
+- [getTags](cases_client.casessubclient.md#gettags)
+- [push](cases_client.casessubclient.md#push)
+- [update](cases_client.casessubclient.md#update)
+
+## Methods
+
+### create
+
+▸ **create**(`data`: [*ICasePostRequest*](typedoc_interfaces.icasepostrequest.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Creates a case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `data` | [*ICasePostRequest*](typedoc_interfaces.icasepostrequest.md) |
+
+**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Defined in: [cases/client.ts:48](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L48)
+
+___
+
+### delete
+
+▸ **delete**(`ids`: *string*[]): *Promise*
+
+Delete a case and all its comments.
+
+**`params`** ids an array of case IDs to delete
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `ids` | *string*[] |
+
+**Returns:** *Promise*
+
+Defined in: [cases/client.ts:72](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L72)
+
+___
+
+### find
+
+▸ **find**(`params`: [*ICasesFindRequest*](typedoc_interfaces.icasesfindrequest.md)): *Promise*<[*ICasesFindResponse*](typedoc_interfaces.icasesfindresponse.md)\>
+
+Returns cases that match the search criteria.
+
+If the `owner` field is left empty then all the cases that the user has access to will be returned.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | [*ICasesFindRequest*](typedoc_interfaces.icasesfindrequest.md) |
+
+**Returns:** *Promise*<[*ICasesFindResponse*](typedoc_interfaces.icasesfindresponse.md)\>
+
+Defined in: [cases/client.ts:54](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L54)
+
+___
+
+### get
+
+▸ **get**(`params`: [*GetParams*](cases_get.getparams.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Retrieves a single case with the specified ID.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | [*GetParams*](cases_get.getparams.md) |
+
+**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Defined in: [cases/client.ts:58](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L58)
+
+___
+
+### getCaseIDsByAlertID
+
+▸ **getCaseIDsByAlertID**(`params`: [*CaseIDsByAlertIDParams*](cases_get.caseidsbyalertidparams.md)): *Promise*
+
+Retrieves the case IDs given a single alert ID
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | [*CaseIDsByAlertIDParams*](cases_get.caseidsbyalertidparams.md) |
+
+**Returns:** *Promise*
+
+Defined in: [cases/client.ts:84](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L84)
+
+___
+
+### getReporters
+
+▸ **getReporters**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*<{ `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }[]\>
+
+Retrieves all the reporters across all accessible cases.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | *object* |
+| `params.owner` | *undefined* \| *string* \| *string*[] |
+
+**Returns:** *Promise*<{ `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }[]\>
+
+Defined in: [cases/client.ts:80](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L80)
+
+___
+
+### getTags
+
+▸ **getTags**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*
+
+Retrieves all the tags across all cases the user making the request has access to.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | *object* |
+| `params.owner` | *undefined* \| *string* \| *string*[] |
+
+**Returns:** *Promise*
+
+Defined in: [cases/client.ts:76](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L76)
+
+___
+
+### push
+
+▸ **push**(`args`: [*PushParams*](cases_push.pushparams.md)): *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Pushes a specific case to an external system.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `args` | [*PushParams*](cases_push.pushparams.md) |
+
+**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
+
+Defined in: [cases/client.ts:62](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L62)
+
+___
+
+### update
+
+▸ **update**(`cases`: [*ICasesPatchRequest*](typedoc_interfaces.icasespatchrequest.md)): *Promise*<[*ICasesResponse*](typedoc_interfaces.icasesresponse.md)\>
+
+Update the specified cases with the passed in values.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `cases` | [*ICasesPatchRequest*](typedoc_interfaces.icasespatchrequest.md) |
+
+**Returns:** *Promise*<[*ICasesResponse*](typedoc_interfaces.icasesresponse.md)\>
+
+Defined in: [cases/client.ts:66](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/client.ts#L66)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/cases_get.caseidsbyalertidparams.md b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_get.caseidsbyalertidparams.md
new file mode 100644
index 0000000000000..1b8abba1a4071
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_get.caseidsbyalertidparams.md
@@ -0,0 +1,40 @@
+[Cases Client API Interface](../cases_client_api.md) / [cases/get](../modules/cases_get.md) / CaseIDsByAlertIDParams
+
+# Interface: CaseIDsByAlertIDParams
+
+[cases/get](../modules/cases_get.md).CaseIDsByAlertIDParams
+
+Parameters for finding cases IDs using an alert ID
+
+## Table of contents
+
+### Properties
+
+- [alertID](cases_get.caseidsbyalertidparams.md#alertid)
+- [options](cases_get.caseidsbyalertidparams.md#options)
+
+## Properties
+
+### alertID
+
+• **alertID**: *string*
+
+The alert ID to search for
+
+Defined in: [cases/get.ts:47](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L47)
+
+___
+
+### options
+
+• **options**: *object*
+
+The filtering options when searching for associated cases.
+
+#### Type declaration
+
+| Name | Type |
+| :------ | :------ |
+| `owner` | *undefined* \| *string* \| *string*[] |
+
+Defined in: [cases/get.ts:51](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L51)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/cases_get.getparams.md b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_get.getparams.md
new file mode 100644
index 0000000000000..8c12b5533ac18
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_get.getparams.md
@@ -0,0 +1,45 @@
+[Cases Client API Interface](../cases_client_api.md) / [cases/get](../modules/cases_get.md) / GetParams
+
+# Interface: GetParams
+
+[cases/get](../modules/cases_get.md).GetParams
+
+The parameters for retrieving a case
+
+## Table of contents
+
+### Properties
+
+- [id](cases_get.getparams.md#id)
+- [includeComments](cases_get.getparams.md#includecomments)
+- [includeSubCaseComments](cases_get.getparams.md#includesubcasecomments)
+
+## Properties
+
+### id
+
+• **id**: *string*
+
+Case ID
+
+Defined in: [cases/get.ts:122](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L122)
+
+___
+
+### includeComments
+
+• `Optional` **includeComments**: *boolean*
+
+Whether to include the attachments for a case in the response
+
+Defined in: [cases/get.ts:126](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L126)
+
+___
+
+### includeSubCaseComments
+
+• `Optional` **includeSubCaseComments**: *boolean*
+
+Whether to include the attachments for all children of a case in the response
+
+Defined in: [cases/get.ts:130](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L130)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/cases_push.pushparams.md b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_push.pushparams.md
new file mode 100644
index 0000000000000..9f1810e4f0cc2
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/cases_push.pushparams.md
@@ -0,0 +1,34 @@
+[Cases Client API Interface](../cases_client_api.md) / [cases/push](../modules/cases_push.md) / PushParams
+
+# Interface: PushParams
+
+[cases/push](../modules/cases_push.md).PushParams
+
+Parameters for pushing a case to an external system
+
+## Table of contents
+
+### Properties
+
+- [caseId](cases_push.pushparams.md#caseid)
+- [connectorId](cases_push.pushparams.md#connectorid)
+
+## Properties
+
+### caseId
+
+• **caseId**: *string*
+
+The ID of a case
+
+Defined in: [cases/push.ts:53](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/push.ts#L53)
+
+___
+
+### connectorId
+
+• **connectorId**: *string*
+
+The ID of an external system to push to
+
+Defined in: [cases/push.ts:57](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/push.ts#L57)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/configure_client.configuresubclient.md b/x-pack/plugins/cases/docs/cases_client/interfaces/configure_client.configuresubclient.md
new file mode 100644
index 0000000000000..9b3827a57a9d3
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/configure_client.configuresubclient.md
@@ -0,0 +1,84 @@
+[Cases Client API Interface](../cases_client_api.md) / [configure/client](../modules/configure_client.md) / ConfigureSubClient
+
+# Interface: ConfigureSubClient
+
+[configure/client](../modules/configure_client.md).ConfigureSubClient
+
+This is the public API for interacting with the connector configuration for cases.
+
+## Table of contents
+
+### Methods
+
+- [create](configure_client.configuresubclient.md#create)
+- [get](configure_client.configuresubclient.md#get)
+- [getConnectors](configure_client.configuresubclient.md#getconnectors)
+- [update](configure_client.configuresubclient.md#update)
+
+## Methods
+
+### create
+
+▸ **create**(`configuration`: [*ICasesConfigureRequest*](typedoc_interfaces.icasesconfigurerequest.md)): *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
+
+Creates a configuration if one does not already exist. If one exists it is deleted and a new one is created.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `configuration` | [*ICasesConfigureRequest*](typedoc_interfaces.icasesconfigurerequest.md) |
+
+**Returns:** *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
+
+Defined in: [configure/client.ts:102](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L102)
+
+___
+
+### get
+
+▸ **get**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*<{} \| [*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
+
+Retrieves the external connector configuration for a particular case owner.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | *object* |
+| `params.owner` | *undefined* \| *string* \| *string*[] |
+
+**Returns:** *Promise*<{} \| [*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
+
+Defined in: [configure/client.ts:84](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L84)
+
+___
+
+### getConnectors
+
+▸ **getConnectors**(): *Promise*
+
+Retrieves the valid external connectors supported by the cases plugin.
+
+**Returns:** *Promise*
+
+Defined in: [configure/client.ts:88](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L88)
+
+___
+
+### update
+
+▸ **update**(`configurationId`: *string*, `configurations`: [*ICasesConfigurePatch*](typedoc_interfaces.icasesconfigurepatch.md)): *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
+
+Updates a particular configuration with new values.
+
+#### Parameters
+
+| Name | Type | Description |
+| :------ | :------ | :------ |
+| `configurationId` | *string* | the ID of the configuration to update |
+| `configurations` | [*ICasesConfigurePatch*](typedoc_interfaces.icasesconfigurepatch.md) | the new configuration parameters |
+
+**Returns:** *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
+
+Defined in: [configure/client.ts:95](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/configure/client.ts#L95)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/stats_client.statssubclient.md b/x-pack/plugins/cases/docs/cases_client/interfaces/stats_client.statssubclient.md
new file mode 100644
index 0000000000000..7e01205395277
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/stats_client.statssubclient.md
@@ -0,0 +1,32 @@
+[Cases Client API Interface](../cases_client_api.md) / [stats/client](../modules/stats_client.md) / StatsSubClient
+
+# Interface: StatsSubClient
+
+[stats/client](../modules/stats_client.md).StatsSubClient
+
+Statistics API contract.
+
+## Table of contents
+
+### Methods
+
+- [getStatusTotalsByType](stats_client.statssubclient.md#getstatustotalsbytype)
+
+## Methods
+
+### getStatusTotalsByType
+
+▸ **getStatusTotalsByType**(`params`: { `owner`: *undefined* \| *string* \| *string*[] }): *Promise*<{ `count_closed_cases`: *number* ; `count_in_progress_cases`: *number* ; `count_open_cases`: *number* }\>
+
+Retrieves the total number of open, closed, and in-progress cases.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | *object* |
+| `params.owner` | *undefined* \| *string* \| *string*[] |
+
+**Returns:** *Promise*<{ `count_closed_cases`: *number* ; `count_in_progress_cases`: *number* ; `count_open_cases`: *number* }\>
+
+Defined in: [stats/client.ts:34](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/stats/client.ts#L34)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/sub_cases_client.subcasesclient.md b/x-pack/plugins/cases/docs/cases_client/interfaces/sub_cases_client.subcasesclient.md
new file mode 100644
index 0000000000000..76df26524b7b0
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/sub_cases_client.subcasesclient.md
@@ -0,0 +1,89 @@
+[Cases Client API Interface](../cases_client_api.md) / [sub_cases/client](../modules/sub_cases_client.md) / SubCasesClient
+
+# Interface: SubCasesClient
+
+[sub_cases/client](../modules/sub_cases_client.md).SubCasesClient
+
+The API routes for interacting with sub cases.
+
+## Table of contents
+
+### Methods
+
+- [delete](sub_cases_client.subcasesclient.md#delete)
+- [find](sub_cases_client.subcasesclient.md#find)
+- [get](sub_cases_client.subcasesclient.md#get)
+- [update](sub_cases_client.subcasesclient.md#update)
+
+## Methods
+
+### delete
+
+▸ **delete**(`ids`: *string*[]): *Promise*
+
+Deletes the specified entities and their attachments.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `ids` | *string*[] |
+
+**Returns:** *Promise*
+
+Defined in: [sub_cases/client.ts:60](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L60)
+
+___
+
+### find
+
+▸ **find**(`findArgs`: FindArgs): *Promise*<[*ISubCasesFindResponse*](typedoc_interfaces.isubcasesfindresponse.md)\>
+
+Retrieves the sub cases matching the search criteria.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `findArgs` | FindArgs |
+
+**Returns:** *Promise*<[*ISubCasesFindResponse*](typedoc_interfaces.isubcasesfindresponse.md)\>
+
+Defined in: [sub_cases/client.ts:64](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L64)
+
+___
+
+### get
+
+▸ **get**(`getArgs`: GetArgs): *Promise*<[*ISubCaseResponse*](typedoc_interfaces.isubcaseresponse.md)\>
+
+Retrieves a single sub case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `getArgs` | GetArgs |
+
+**Returns:** *Promise*<[*ISubCaseResponse*](typedoc_interfaces.isubcaseresponse.md)\>
+
+Defined in: [sub_cases/client.ts:68](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L68)
+
+___
+
+### update
+
+▸ **update**(`subCases`: { `subCases`: { `status`: *undefined* \| open \| *any*[*any*] \| closed } & { id: string; version: string; }[] }): *Promise*<[*ISubCasesResponse*](typedoc_interfaces.isubcasesresponse.md)\>
+
+Updates the specified sub cases to the new values included in the request.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `subCases` | *object* |
+| `subCases.subCases` | { `status`: *undefined* \| open \| *any*[*any*] \| closed } & { id: string; version: string; }[] |
+
+**Returns:** *Promise*<[*ISubCasesResponse*](typedoc_interfaces.isubcasesresponse.md)\>
+
+Defined in: [sub_cases/client.ts:72](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/sub_cases/client.ts#L72)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.iallcommentsresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.iallcommentsresponse.md
new file mode 100644
index 0000000000000..06322bb51e2ad
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.iallcommentsresponse.md
@@ -0,0 +1,11 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / IAllCommentsResponse
+
+# Interface: IAllCommentsResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).IAllCommentsResponse
+
+## Hierarchy
+
+- *AllCommentsResponse*
+
+ ↳ **IAllCommentsResponse**
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasepostrequest.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasepostrequest.md
new file mode 100644
index 0000000000000..70533a15fe616
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasepostrequest.md
@@ -0,0 +1,88 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasePostRequest
+
+# Interface: ICasePostRequest
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasePostRequest
+
+These are simply to make typedoc not attempt to expand the type aliases. If it attempts to expand them
+the docs are huge.
+
+## Hierarchy
+
+- *CasePostRequest*
+
+ ↳ **ICasePostRequest**
+
+## Table of contents
+
+### Properties
+
+- [connector](typedoc_interfaces.icasepostrequest.md#connector)
+- [description](typedoc_interfaces.icasepostrequest.md#description)
+- [owner](typedoc_interfaces.icasepostrequest.md#owner)
+- [settings](typedoc_interfaces.icasepostrequest.md#settings)
+- [tags](typedoc_interfaces.icasepostrequest.md#tags)
+- [title](typedoc_interfaces.icasepostrequest.md#title)
+- [type](typedoc_interfaces.icasepostrequest.md#type)
+
+## Properties
+
+### connector
+
+• **connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
+
+Inherited from: CasePostRequest.connector
+
+___
+
+### description
+
+• **description**: *string*
+
+Inherited from: CasePostRequest.description
+
+___
+
+### owner
+
+• **owner**: *string*
+
+Inherited from: CasePostRequest.owner
+
+___
+
+### settings
+
+• **settings**: *object*
+
+#### Type declaration
+
+| Name | Type |
+| :------ | :------ |
+| `syncAlerts` | *boolean* |
+
+Inherited from: CasePostRequest.settings
+
+___
+
+### tags
+
+• **tags**: *string*[]
+
+Inherited from: CasePostRequest.tags
+
+___
+
+### title
+
+• **title**: *string*
+
+Inherited from: CasePostRequest.title
+
+___
+
+### type
+
+• **type**: *undefined* \| collection \| individual
+
+Inherited from: CasePostRequest.type
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icaseresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icaseresponse.md
new file mode 100644
index 0000000000000..5db55e5552473
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icaseresponse.md
@@ -0,0 +1,228 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICaseResponse
+
+# Interface: ICaseResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICaseResponse
+
+## Hierarchy
+
+- *CaseResponse*
+
+ ↳ **ICaseResponse**
+
+## Table of contents
+
+### Properties
+
+- [closed\_at](typedoc_interfaces.icaseresponse.md#closed_at)
+- [closed\_by](typedoc_interfaces.icaseresponse.md#closed_by)
+- [comments](typedoc_interfaces.icaseresponse.md#comments)
+- [connector](typedoc_interfaces.icaseresponse.md#connector)
+- [created\_at](typedoc_interfaces.icaseresponse.md#created_at)
+- [created\_by](typedoc_interfaces.icaseresponse.md#created_by)
+- [description](typedoc_interfaces.icaseresponse.md#description)
+- [external\_service](typedoc_interfaces.icaseresponse.md#external_service)
+- [id](typedoc_interfaces.icaseresponse.md#id)
+- [owner](typedoc_interfaces.icaseresponse.md#owner)
+- [settings](typedoc_interfaces.icaseresponse.md#settings)
+- [status](typedoc_interfaces.icaseresponse.md#status)
+- [subCaseIds](typedoc_interfaces.icaseresponse.md#subcaseids)
+- [subCases](typedoc_interfaces.icaseresponse.md#subcases)
+- [tags](typedoc_interfaces.icaseresponse.md#tags)
+- [title](typedoc_interfaces.icaseresponse.md#title)
+- [totalAlerts](typedoc_interfaces.icaseresponse.md#totalalerts)
+- [totalComment](typedoc_interfaces.icaseresponse.md#totalcomment)
+- [type](typedoc_interfaces.icaseresponse.md#type)
+- [updated\_at](typedoc_interfaces.icaseresponse.md#updated_at)
+- [updated\_by](typedoc_interfaces.icaseresponse.md#updated_by)
+- [version](typedoc_interfaces.icaseresponse.md#version)
+
+## Properties
+
+### closed\_at
+
+• **closed\_at**: ``null`` \| *string*
+
+Inherited from: CaseResponse.closed\_at
+
+___
+
+### closed\_by
+
+• **closed\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
+
+Inherited from: CaseResponse.closed\_by
+
+___
+
+### comments
+
+• **comments**: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[]
+
+Inherited from: CaseResponse.comments
+
+___
+
+### connector
+
+• **connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
+
+Inherited from: CaseResponse.connector
+
+___
+
+### created\_at
+
+• **created\_at**: *string*
+
+Inherited from: CaseResponse.created\_at
+
+___
+
+### created\_by
+
+• **created\_by**: *object*
+
+#### Type declaration
+
+| Name | Type |
+| :------ | :------ |
+| `email` | *undefined* \| ``null`` \| *string* |
+| `full_name` | *undefined* \| ``null`` \| *string* |
+| `username` | *undefined* \| ``null`` \| *string* |
+
+Inherited from: CaseResponse.created\_by
+
+___
+
+### description
+
+• **description**: *string*
+
+Inherited from: CaseResponse.description
+
+___
+
+### external\_service
+
+• **external\_service**: ``null`` \| { `connector_id`: *string* ; `connector_name`: *string* ; `external_id`: *string* ; `external_title`: *string* ; `external_url`: *string* } & { `pushed_at`: *string* ; `pushed_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } }
+
+Inherited from: CaseResponse.external\_service
+
+___
+
+### id
+
+• **id**: *string*
+
+Inherited from: CaseResponse.id
+
+___
+
+### owner
+
+• **owner**: *string*
+
+Inherited from: CaseResponse.owner
+
+___
+
+### settings
+
+• **settings**: *object*
+
+#### Type declaration
+
+| Name | Type |
+| :------ | :------ |
+| `syncAlerts` | *boolean* |
+
+Inherited from: CaseResponse.settings
+
+___
+
+### status
+
+• **status**: CaseStatuses
+
+Inherited from: CaseResponse.status
+
+___
+
+### subCaseIds
+
+• **subCaseIds**: *undefined* \| *string*[]
+
+Inherited from: CaseResponse.subCaseIds
+
+___
+
+### subCases
+
+• **subCases**: *undefined* \| { `status`: CaseStatuses } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { `comments`: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[] }[]
+
+Inherited from: CaseResponse.subCases
+
+___
+
+### tags
+
+• **tags**: *string*[]
+
+Inherited from: CaseResponse.tags
+
+___
+
+### title
+
+• **title**: *string*
+
+Inherited from: CaseResponse.title
+
+___
+
+### totalAlerts
+
+• **totalAlerts**: *number*
+
+Inherited from: CaseResponse.totalAlerts
+
+___
+
+### totalComment
+
+• **totalComment**: *number*
+
+Inherited from: CaseResponse.totalComment
+
+___
+
+### type
+
+• **type**: CaseType
+
+Inherited from: CaseResponse.type
+
+___
+
+### updated\_at
+
+• **updated\_at**: ``null`` \| *string*
+
+Inherited from: CaseResponse.updated\_at
+
+___
+
+### updated\_by
+
+• **updated\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
+
+Inherited from: CaseResponse.updated\_by
+
+___
+
+### version
+
+• **version**: *string*
+
+Inherited from: CaseResponse.version
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigurepatch.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigurepatch.md
new file mode 100644
index 0000000000000..3854fda03fb6a
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigurepatch.md
@@ -0,0 +1,43 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesConfigurePatch
+
+# Interface: ICasesConfigurePatch
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesConfigurePatch
+
+## Hierarchy
+
+- *CasesConfigurePatch*
+
+ ↳ **ICasesConfigurePatch**
+
+## Table of contents
+
+### Properties
+
+- [closure\_type](typedoc_interfaces.icasesconfigurepatch.md#closure_type)
+- [connector](typedoc_interfaces.icasesconfigurepatch.md#connector)
+- [version](typedoc_interfaces.icasesconfigurepatch.md#version)
+
+## Properties
+
+### closure\_type
+
+• **closure\_type**: *undefined* \| ``"close-by-user"`` \| ``"close-by-pushing"``
+
+Inherited from: CasesConfigurePatch.closure\_type
+
+___
+
+### connector
+
+• **connector**: *undefined* \| { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
+
+Inherited from: CasesConfigurePatch.connector
+
+___
+
+### version
+
+• **version**: *string*
+
+Inherited from: CasesConfigurePatch.version
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigurerequest.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigurerequest.md
new file mode 100644
index 0000000000000..548e1a5c48f58
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigurerequest.md
@@ -0,0 +1,43 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesConfigureRequest
+
+# Interface: ICasesConfigureRequest
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesConfigureRequest
+
+## Hierarchy
+
+- *CasesConfigureRequest*
+
+ ↳ **ICasesConfigureRequest**
+
+## Table of contents
+
+### Properties
+
+- [closure\_type](typedoc_interfaces.icasesconfigurerequest.md#closure_type)
+- [connector](typedoc_interfaces.icasesconfigurerequest.md#connector)
+- [owner](typedoc_interfaces.icasesconfigurerequest.md#owner)
+
+## Properties
+
+### closure\_type
+
+• **closure\_type**: ``"close-by-user"`` \| ``"close-by-pushing"``
+
+Inherited from: CasesConfigureRequest.closure\_type
+
+___
+
+### connector
+
+• **connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
+
+Inherited from: CasesConfigureRequest.connector
+
+___
+
+### owner
+
+• **owner**: *string*
+
+Inherited from: CasesConfigureRequest.owner
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigureresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigureresponse.md
new file mode 100644
index 0000000000000..c493a4c6c0f0c
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesconfigureresponse.md
@@ -0,0 +1,123 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesConfigureResponse
+
+# Interface: ICasesConfigureResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesConfigureResponse
+
+## Hierarchy
+
+- *CasesConfigureResponse*
+
+ ↳ **ICasesConfigureResponse**
+
+## Table of contents
+
+### Properties
+
+- [closure\_type](typedoc_interfaces.icasesconfigureresponse.md#closure_type)
+- [connector](typedoc_interfaces.icasesconfigureresponse.md#connector)
+- [created\_at](typedoc_interfaces.icasesconfigureresponse.md#created_at)
+- [created\_by](typedoc_interfaces.icasesconfigureresponse.md#created_by)
+- [error](typedoc_interfaces.icasesconfigureresponse.md#error)
+- [id](typedoc_interfaces.icasesconfigureresponse.md#id)
+- [mappings](typedoc_interfaces.icasesconfigureresponse.md#mappings)
+- [owner](typedoc_interfaces.icasesconfigureresponse.md#owner)
+- [updated\_at](typedoc_interfaces.icasesconfigureresponse.md#updated_at)
+- [updated\_by](typedoc_interfaces.icasesconfigureresponse.md#updated_by)
+- [version](typedoc_interfaces.icasesconfigureresponse.md#version)
+
+## Properties
+
+### closure\_type
+
+• **closure\_type**: ``"close-by-user"`` \| ``"close-by-pushing"``
+
+Inherited from: CasesConfigureResponse.closure\_type
+
+___
+
+### connector
+
+• **connector**: { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none }
+
+Inherited from: CasesConfigureResponse.connector
+
+___
+
+### created\_at
+
+• **created\_at**: *string*
+
+Inherited from: CasesConfigureResponse.created\_at
+
+___
+
+### created\_by
+
+• **created\_by**: *object*
+
+#### Type declaration
+
+| Name | Type |
+| :------ | :------ |
+| `email` | *undefined* \| ``null`` \| *string* |
+| `full_name` | *undefined* \| ``null`` \| *string* |
+| `username` | *undefined* \| ``null`` \| *string* |
+
+Inherited from: CasesConfigureResponse.created\_by
+
+___
+
+### error
+
+• **error**: ``null`` \| *string*
+
+Inherited from: CasesConfigureResponse.error
+
+___
+
+### id
+
+• **id**: *string*
+
+Inherited from: CasesConfigureResponse.id
+
+___
+
+### mappings
+
+• **mappings**: { `action_type`: ``"append"`` \| ``"nothing"`` \| ``"overwrite"`` ; `source`: ``"description"`` \| ``"title"`` \| ``"comments"`` ; `target`: *string* }[]
+
+Inherited from: CasesConfigureResponse.mappings
+
+___
+
+### owner
+
+• **owner**: *string*
+
+Inherited from: CasesConfigureResponse.owner
+
+___
+
+### updated\_at
+
+• **updated\_at**: ``null`` \| *string*
+
+Inherited from: CasesConfigureResponse.updated\_at
+
+___
+
+### updated\_by
+
+• **updated\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
+
+Inherited from: CasesConfigureResponse.updated\_by
+
+___
+
+### version
+
+• **version**: *string*
+
+Inherited from: CasesConfigureResponse.version
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesfindrequest.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesfindrequest.md
new file mode 100644
index 0000000000000..cb8ec7797677f
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesfindrequest.md
@@ -0,0 +1,133 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesFindRequest
+
+# Interface: ICasesFindRequest
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesFindRequest
+
+## Hierarchy
+
+- *CasesFindRequest*
+
+ ↳ **ICasesFindRequest**
+
+## Table of contents
+
+### Properties
+
+- [defaultSearchOperator](typedoc_interfaces.icasesfindrequest.md#defaultsearchoperator)
+- [fields](typedoc_interfaces.icasesfindrequest.md#fields)
+- [owner](typedoc_interfaces.icasesfindrequest.md#owner)
+- [page](typedoc_interfaces.icasesfindrequest.md#page)
+- [perPage](typedoc_interfaces.icasesfindrequest.md#perpage)
+- [reporters](typedoc_interfaces.icasesfindrequest.md#reporters)
+- [search](typedoc_interfaces.icasesfindrequest.md#search)
+- [searchFields](typedoc_interfaces.icasesfindrequest.md#searchfields)
+- [sortField](typedoc_interfaces.icasesfindrequest.md#sortfield)
+- [sortOrder](typedoc_interfaces.icasesfindrequest.md#sortorder)
+- [status](typedoc_interfaces.icasesfindrequest.md#status)
+- [tags](typedoc_interfaces.icasesfindrequest.md#tags)
+- [type](typedoc_interfaces.icasesfindrequest.md#type)
+
+## Properties
+
+### defaultSearchOperator
+
+• **defaultSearchOperator**: *undefined* \| ``"AND"`` \| ``"OR"``
+
+Inherited from: CasesFindRequest.defaultSearchOperator
+
+___
+
+### fields
+
+• **fields**: *undefined* \| *string*[]
+
+Inherited from: CasesFindRequest.fields
+
+___
+
+### owner
+
+• **owner**: *undefined* \| *string* \| *string*[]
+
+Inherited from: CasesFindRequest.owner
+
+___
+
+### page
+
+• **page**: *undefined* \| *number*
+
+Inherited from: CasesFindRequest.page
+
+___
+
+### perPage
+
+• **perPage**: *undefined* \| *number*
+
+Inherited from: CasesFindRequest.perPage
+
+___
+
+### reporters
+
+• **reporters**: *undefined* \| *string* \| *string*[]
+
+Inherited from: CasesFindRequest.reporters
+
+___
+
+### search
+
+• **search**: *undefined* \| *string*
+
+Inherited from: CasesFindRequest.search
+
+___
+
+### searchFields
+
+• **searchFields**: *undefined* \| *string* \| *string*[]
+
+Inherited from: CasesFindRequest.searchFields
+
+___
+
+### sortField
+
+• **sortField**: *undefined* \| *string*
+
+Inherited from: CasesFindRequest.sortField
+
+___
+
+### sortOrder
+
+• **sortOrder**: *undefined* \| ``"desc"`` \| ``"asc"``
+
+Inherited from: CasesFindRequest.sortOrder
+
+___
+
+### status
+
+• **status**: *undefined* \| open \| *any*[*any*] \| closed
+
+Inherited from: CasesFindRequest.status
+
+___
+
+### tags
+
+• **tags**: *undefined* \| *string* \| *string*[]
+
+Inherited from: CasesFindRequest.tags
+
+___
+
+### type
+
+• **type**: *undefined* \| collection \| individual
+
+Inherited from: CasesFindRequest.type
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesfindresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesfindresponse.md
new file mode 100644
index 0000000000000..9be5fd5743a8e
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesfindresponse.md
@@ -0,0 +1,79 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesFindResponse
+
+# Interface: ICasesFindResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesFindResponse
+
+## Hierarchy
+
+- *CasesFindResponse*
+
+ ↳ **ICasesFindResponse**
+
+## Table of contents
+
+### Properties
+
+- [cases](typedoc_interfaces.icasesfindresponse.md#cases)
+- [count\_closed\_cases](typedoc_interfaces.icasesfindresponse.md#count_closed_cases)
+- [count\_in\_progress\_cases](typedoc_interfaces.icasesfindresponse.md#count_in_progress_cases)
+- [count\_open\_cases](typedoc_interfaces.icasesfindresponse.md#count_open_cases)
+- [page](typedoc_interfaces.icasesfindresponse.md#page)
+- [per\_page](typedoc_interfaces.icasesfindresponse.md#per_page)
+- [total](typedoc_interfaces.icasesfindresponse.md#total)
+
+## Properties
+
+### cases
+
+• **cases**: { `connector`: { id: string; name: string; } & { type: ConnectorTypes.jira; fields: { issueType: string \| null; priority: string \| null; parent: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.resilient; fields: { incidentTypes: string[] \| null; severityCode: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.serviceNowITSM; fields: { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.serviceNowSIR; fields: { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } \| null; } & { id: string; name: string; } & { type: ConnectorTypes.none; fields: null; } ; `description`: *string* ; `owner`: *string* ; `settings`: { syncAlerts: boolean; } ; `status`: CaseStatuses ; `tags`: *string*[] ; `title`: *string* ; `type`: CaseType } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `external_service`: ``null`` \| { connector\_id: string; connector\_name: string; external\_id: string; external\_title: string; external\_url: string; } & { pushed\_at: string; pushed\_by: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; }; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { `comments`: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[] ; `subCaseIds`: *undefined* \| *string*[] ; `subCases`: *undefined* \| { `status`: CaseStatuses } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { comments?: ((({ comment: string; type: CommentType.user; owner: string; } & { associationType: AssociationType; created\_at: string; created\_by: { email: string \| null \| undefined; full\_name: string \| ... 1 more ... \| undefined; username: string \| ... 1 more ... \| undefined; }; ... 4 more ...; updated\_by: { ...; } ...[] }[]
+
+Inherited from: CasesFindResponse.cases
+
+___
+
+### count\_closed\_cases
+
+• **count\_closed\_cases**: *number*
+
+Inherited from: CasesFindResponse.count\_closed\_cases
+
+___
+
+### count\_in\_progress\_cases
+
+• **count\_in\_progress\_cases**: *number*
+
+Inherited from: CasesFindResponse.count\_in\_progress\_cases
+
+___
+
+### count\_open\_cases
+
+• **count\_open\_cases**: *number*
+
+Inherited from: CasesFindResponse.count\_open\_cases
+
+___
+
+### page
+
+• **page**: *number*
+
+Inherited from: CasesFindResponse.page
+
+___
+
+### per\_page
+
+• **per\_page**: *number*
+
+Inherited from: CasesFindResponse.per\_page
+
+___
+
+### total
+
+• **total**: *number*
+
+Inherited from: CasesFindResponse.total
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasespatchrequest.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasespatchrequest.md
new file mode 100644
index 0000000000000..bfdb3b7315e55
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasespatchrequest.md
@@ -0,0 +1,25 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesPatchRequest
+
+# Interface: ICasesPatchRequest
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesPatchRequest
+
+## Hierarchy
+
+- *CasesPatchRequest*
+
+ ↳ **ICasesPatchRequest**
+
+## Table of contents
+
+### Properties
+
+- [cases](typedoc_interfaces.icasespatchrequest.md#cases)
+
+## Properties
+
+### cases
+
+• **cases**: { `connector`: *undefined* \| { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { issueType: string \| null; priority: string \| null; parent: string \| null; } ; `type`: jira } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { incidentTypes: string[] \| null; severityCode: string \| null; } ; `type`: resilient } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { impact: string \| null; severity: string \| null; urgency: string \| null; category: string \| null; subcategory: string \| null; } ; `type`: serviceNowITSM } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` \| { category: string \| null; destIp: boolean \| null; malwareHash: boolean \| null; malwareUrl: boolean \| null; priority: string \| null; sourceIp: boolean \| null; subcategory: string \| null; } ; `type`: serviceNowSIR } & { `id`: *string* ; `name`: *string* } & { `fields`: ``null`` ; `type`: none } ; `description`: *undefined* \| *string* ; `owner`: *undefined* \| *string* ; `settings`: *undefined* \| { `syncAlerts`: *boolean* } ; `status`: *undefined* \| open \| *any*[*any*] \| closed ; `tags`: *undefined* \| *string*[] ; `title`: *undefined* \| *string* ; `type`: *undefined* \| collection \| individual } & { `id`: *string* ; `version`: *string* }[]
+
+Inherited from: CasesPatchRequest.cases
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesresponse.md
new file mode 100644
index 0000000000000..2c9eed242d1fb
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icasesresponse.md
@@ -0,0 +1,11 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICasesResponse
+
+# Interface: ICasesResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICasesResponse
+
+## Hierarchy
+
+- *CasesResponse*
+
+ ↳ **ICasesResponse**
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icaseuseractionsresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icaseuseractionsresponse.md
new file mode 100644
index 0000000000000..0347711e331dc
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icaseuseractionsresponse.md
@@ -0,0 +1,11 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICaseUserActionsResponse
+
+# Interface: ICaseUserActionsResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICaseUserActionsResponse
+
+## Hierarchy
+
+- *CaseUserActionsResponse*
+
+ ↳ **ICaseUserActionsResponse**
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icommentsresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icommentsresponse.md
new file mode 100644
index 0000000000000..d34480b2c633c
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.icommentsresponse.md
@@ -0,0 +1,52 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ICommentsResponse
+
+# Interface: ICommentsResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ICommentsResponse
+
+## Hierarchy
+
+- *CommentsResponse*
+
+ ↳ **ICommentsResponse**
+
+## Table of contents
+
+### Properties
+
+- [comments](typedoc_interfaces.icommentsresponse.md#comments)
+- [page](typedoc_interfaces.icommentsresponse.md#page)
+- [per\_page](typedoc_interfaces.icommentsresponse.md#per_page)
+- [total](typedoc_interfaces.icommentsresponse.md#total)
+
+## Properties
+
+### comments
+
+• **comments**: { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[]
+
+Inherited from: CommentsResponse.comments
+
+___
+
+### page
+
+• **page**: *number*
+
+Inherited from: CommentsResponse.page
+
+___
+
+### per\_page
+
+• **per\_page**: *number*
+
+Inherited from: CommentsResponse.per\_page
+
+___
+
+### total
+
+• **total**: *number*
+
+Inherited from: CommentsResponse.total
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcaseresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcaseresponse.md
new file mode 100644
index 0000000000000..b33b280d2e753
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcaseresponse.md
@@ -0,0 +1,133 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ISubCaseResponse
+
+# Interface: ISubCaseResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ISubCaseResponse
+
+## Hierarchy
+
+- *SubCaseResponse*
+
+ ↳ **ISubCaseResponse**
+
+## Table of contents
+
+### Properties
+
+- [closed\_at](typedoc_interfaces.isubcaseresponse.md#closed_at)
+- [closed\_by](typedoc_interfaces.isubcaseresponse.md#closed_by)
+- [comments](typedoc_interfaces.isubcaseresponse.md#comments)
+- [created\_at](typedoc_interfaces.isubcaseresponse.md#created_at)
+- [created\_by](typedoc_interfaces.isubcaseresponse.md#created_by)
+- [id](typedoc_interfaces.isubcaseresponse.md#id)
+- [owner](typedoc_interfaces.isubcaseresponse.md#owner)
+- [status](typedoc_interfaces.isubcaseresponse.md#status)
+- [totalAlerts](typedoc_interfaces.isubcaseresponse.md#totalalerts)
+- [totalComment](typedoc_interfaces.isubcaseresponse.md#totalcomment)
+- [updated\_at](typedoc_interfaces.isubcaseresponse.md#updated_at)
+- [updated\_by](typedoc_interfaces.isubcaseresponse.md#updated_by)
+- [version](typedoc_interfaces.isubcaseresponse.md#version)
+
+## Properties
+
+### closed\_at
+
+• **closed\_at**: ``null`` \| *string*
+
+Inherited from: SubCaseResponse.closed\_at
+
+___
+
+### closed\_by
+
+• **closed\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
+
+Inherited from: SubCaseResponse.closed\_by
+
+___
+
+### comments
+
+• **comments**: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[]
+
+Inherited from: SubCaseResponse.comments
+
+___
+
+### created\_at
+
+• **created\_at**: *string*
+
+Inherited from: SubCaseResponse.created\_at
+
+___
+
+### created\_by
+
+• **created\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
+
+Inherited from: SubCaseResponse.created\_by
+
+___
+
+### id
+
+• **id**: *string*
+
+Inherited from: SubCaseResponse.id
+
+___
+
+### owner
+
+• **owner**: *string*
+
+Inherited from: SubCaseResponse.owner
+
+___
+
+### status
+
+• **status**: CaseStatuses
+
+Inherited from: SubCaseResponse.status
+
+___
+
+### totalAlerts
+
+• **totalAlerts**: *number*
+
+Inherited from: SubCaseResponse.totalAlerts
+
+___
+
+### totalComment
+
+• **totalComment**: *number*
+
+Inherited from: SubCaseResponse.totalComment
+
+___
+
+### updated\_at
+
+• **updated\_at**: ``null`` \| *string*
+
+Inherited from: SubCaseResponse.updated\_at
+
+___
+
+### updated\_by
+
+• **updated\_by**: ``null`` \| { `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }
+
+Inherited from: SubCaseResponse.updated\_by
+
+___
+
+### version
+
+• **version**: *string*
+
+Inherited from: SubCaseResponse.version
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcasesfindresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcasesfindresponse.md
new file mode 100644
index 0000000000000..35d63126f608a
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcasesfindresponse.md
@@ -0,0 +1,79 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ISubCasesFindResponse
+
+# Interface: ISubCasesFindResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ISubCasesFindResponse
+
+## Hierarchy
+
+- *SubCasesFindResponse*
+
+ ↳ **ISubCasesFindResponse**
+
+## Table of contents
+
+### Properties
+
+- [count\_closed\_cases](typedoc_interfaces.isubcasesfindresponse.md#count_closed_cases)
+- [count\_in\_progress\_cases](typedoc_interfaces.isubcasesfindresponse.md#count_in_progress_cases)
+- [count\_open\_cases](typedoc_interfaces.isubcasesfindresponse.md#count_open_cases)
+- [page](typedoc_interfaces.isubcasesfindresponse.md#page)
+- [per\_page](typedoc_interfaces.isubcasesfindresponse.md#per_page)
+- [subCases](typedoc_interfaces.isubcasesfindresponse.md#subcases)
+- [total](typedoc_interfaces.isubcasesfindresponse.md#total)
+
+## Properties
+
+### count\_closed\_cases
+
+• **count\_closed\_cases**: *number*
+
+Inherited from: SubCasesFindResponse.count\_closed\_cases
+
+___
+
+### count\_in\_progress\_cases
+
+• **count\_in\_progress\_cases**: *number*
+
+Inherited from: SubCasesFindResponse.count\_in\_progress\_cases
+
+___
+
+### count\_open\_cases
+
+• **count\_open\_cases**: *number*
+
+Inherited from: SubCasesFindResponse.count\_open\_cases
+
+___
+
+### page
+
+• **page**: *number*
+
+Inherited from: SubCasesFindResponse.page
+
+___
+
+### per\_page
+
+• **per\_page**: *number*
+
+Inherited from: SubCasesFindResponse.per\_page
+
+___
+
+### subCases
+
+• **subCases**: { `status`: CaseStatuses } & { `closed_at`: ``null`` \| *string* ; `closed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `created_at`: *string* ; `created_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `totalAlerts`: *number* ; `totalComment`: *number* ; `version`: *string* } & { `comments`: *undefined* \| { `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }[] }[]
+
+Inherited from: SubCasesFindResponse.subCases
+
+___
+
+### total
+
+• **total**: *number*
+
+Inherited from: SubCasesFindResponse.total
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcasesresponse.md b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcasesresponse.md
new file mode 100644
index 0000000000000..6ee45e59b53b5
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/typedoc_interfaces.isubcasesresponse.md
@@ -0,0 +1,11 @@
+[Cases Client API Interface](../cases_client_api.md) / [typedoc_interfaces](../modules/typedoc_interfaces.md) / ISubCasesResponse
+
+# Interface: ISubCasesResponse
+
+[typedoc_interfaces](../modules/typedoc_interfaces.md).ISubCasesResponse
+
+## Hierarchy
+
+- *SubCasesResponse*
+
+ ↳ **ISubCasesResponse**
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/user_actions_client.useractionget.md b/x-pack/plugins/cases/docs/cases_client/interfaces/user_actions_client.useractionget.md
new file mode 100644
index 0000000000000..2c0c084ab9b30
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/user_actions_client.useractionget.md
@@ -0,0 +1,34 @@
+[Cases Client API Interface](../cases_client_api.md) / [user_actions/client](../modules/user_actions_client.md) / UserActionGet
+
+# Interface: UserActionGet
+
+[user_actions/client](../modules/user_actions_client.md).UserActionGet
+
+Parameters for retrieving user actions for a particular case
+
+## Table of contents
+
+### Properties
+
+- [caseId](user_actions_client.useractionget.md#caseid)
+- [subCaseId](user_actions_client.useractionget.md#subcaseid)
+
+## Properties
+
+### caseId
+
+• **caseId**: *string*
+
+The ID of the case
+
+Defined in: [user_actions/client.ts:19](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/user_actions/client.ts#L19)
+
+___
+
+### subCaseId
+
+• `Optional` **subCaseId**: *string*
+
+If specified then a sub case will be used for finding all the user actions
+
+Defined in: [user_actions/client.ts:23](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/user_actions/client.ts#L23)
diff --git a/x-pack/plugins/cases/docs/cases_client/interfaces/user_actions_client.useractionssubclient.md b/x-pack/plugins/cases/docs/cases_client/interfaces/user_actions_client.useractionssubclient.md
new file mode 100644
index 0000000000000..f03667eccb858
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/interfaces/user_actions_client.useractionssubclient.md
@@ -0,0 +1,31 @@
+[Cases Client API Interface](../cases_client_api.md) / [user_actions/client](../modules/user_actions_client.md) / UserActionsSubClient
+
+# Interface: UserActionsSubClient
+
+[user_actions/client](../modules/user_actions_client.md).UserActionsSubClient
+
+API for interacting the actions performed by a user when interacting with the cases entities.
+
+## Table of contents
+
+### Methods
+
+- [getAll](user_actions_client.useractionssubclient.md#getall)
+
+## Methods
+
+### getAll
+
+▸ **getAll**(`clientArgs`: [*UserActionGet*](user_actions_client.useractionget.md)): *Promise*<[*ICaseUserActionsResponse*](typedoc_interfaces.icaseuseractionsresponse.md)\>
+
+Retrieves all user actions for a particular case.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `clientArgs` | [*UserActionGet*](user_actions_client.useractionget.md) |
+
+**Returns:** *Promise*<[*ICaseUserActionsResponse*](typedoc_interfaces.icaseuseractionsresponse.md)\>
+
+Defined in: [user_actions/client.ts:33](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/user_actions/client.ts#L33)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/attachments_add.md b/x-pack/plugins/cases/docs/cases_client/modules/attachments_add.md
new file mode 100644
index 0000000000000..d9ac6e6ce431b
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/attachments_add.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / attachments/add
+
+# Module: attachments/add
+
+## Table of contents
+
+### Interfaces
+
+- [AddArgs](../interfaces/attachments_add.addargs.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/attachments_client.md b/x-pack/plugins/cases/docs/cases_client/modules/attachments_client.md
new file mode 100644
index 0000000000000..47d96b98356e7
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/attachments_client.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / attachments/client
+
+# Module: attachments/client
+
+## Table of contents
+
+### Interfaces
+
+- [AttachmentsSubClient](../interfaces/attachments_client.attachmentssubclient.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/attachments_delete.md b/x-pack/plugins/cases/docs/cases_client/modules/attachments_delete.md
new file mode 100644
index 0000000000000..0e2cf420b6375
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/attachments_delete.md
@@ -0,0 +1,10 @@
+[Cases Client API Interface](../cases_client_api.md) / attachments/delete
+
+# Module: attachments/delete
+
+## Table of contents
+
+### Interfaces
+
+- [DeleteAllArgs](../interfaces/attachments_delete.deleteallargs.md)
+- [DeleteArgs](../interfaces/attachments_delete.deleteargs.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/attachments_get.md b/x-pack/plugins/cases/docs/cases_client/modules/attachments_get.md
new file mode 100644
index 0000000000000..99358d6683256
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/attachments_get.md
@@ -0,0 +1,11 @@
+[Cases Client API Interface](../cases_client_api.md) / attachments/get
+
+# Module: attachments/get
+
+## Table of contents
+
+### Interfaces
+
+- [FindArgs](../interfaces/attachments_get.findargs.md)
+- [GetAllArgs](../interfaces/attachments_get.getallargs.md)
+- [GetArgs](../interfaces/attachments_get.getargs.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/attachments_update.md b/x-pack/plugins/cases/docs/cases_client/modules/attachments_update.md
new file mode 100644
index 0000000000000..011fe531ede34
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/attachments_update.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / attachments/update
+
+# Module: attachments/update
+
+## Table of contents
+
+### Interfaces
+
+- [UpdateArgs](../interfaces/attachments_update.updateargs.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/cases_client.md b/x-pack/plugins/cases/docs/cases_client/modules/cases_client.md
new file mode 100644
index 0000000000000..c6e9cf17d9840
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/cases_client.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / cases/client
+
+# Module: cases/client
+
+## Table of contents
+
+### Interfaces
+
+- [CasesSubClient](../interfaces/cases_client.casessubclient.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/cases_get.md b/x-pack/plugins/cases/docs/cases_client/modules/cases_get.md
new file mode 100644
index 0000000000000..9e896881df17b
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/cases_get.md
@@ -0,0 +1,53 @@
+[Cases Client API Interface](../cases_client_api.md) / cases/get
+
+# Module: cases/get
+
+## Table of contents
+
+### Interfaces
+
+- [CaseIDsByAlertIDParams](../interfaces/cases_get.caseidsbyalertidparams.md)
+- [GetParams](../interfaces/cases_get.getparams.md)
+
+### Functions
+
+- [getReporters](cases_get.md#getreporters)
+- [getTags](cases_get.md#gettags)
+
+## Functions
+
+### getReporters
+
+▸ **getReporters**(`params`: AllReportersFindRequest, `clientArgs`: CasesClientArgs): *Promise*
+
+Retrieves the reporters from all the cases.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | AllReportersFindRequest |
+| `clientArgs` | CasesClientArgs |
+
+**Returns:** *Promise*
+
+Defined in: [cases/get.ts:279](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L279)
+
+___
+
+### getTags
+
+▸ **getTags**(`params`: AllTagsFindRequest, `clientArgs`: CasesClientArgs): *Promise*
+
+Retrieves the tags from all the cases.
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | AllTagsFindRequest |
+| `clientArgs` | CasesClientArgs |
+
+**Returns:** *Promise*
+
+Defined in: [cases/get.ts:217](https://github.com/jonathan-buttner/kibana/blob/2085a3b4480/x-pack/plugins/cases/server/client/cases/get.ts#L217)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/cases_push.md b/x-pack/plugins/cases/docs/cases_client/modules/cases_push.md
new file mode 100644
index 0000000000000..4be9df64bb420
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/cases_push.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / cases/push
+
+# Module: cases/push
+
+## Table of contents
+
+### Interfaces
+
+- [PushParams](../interfaces/cases_push.pushparams.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/client.md b/x-pack/plugins/cases/docs/cases_client/modules/client.md
new file mode 100644
index 0000000000000..7fb6b64253dd9
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/client.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / client
+
+# Module: client
+
+## Table of contents
+
+### Classes
+
+- [CasesClient](../classes/client.casesclient.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/configure_client.md b/x-pack/plugins/cases/docs/cases_client/modules/configure_client.md
new file mode 100644
index 0000000000000..7cfc43e3d0a88
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/configure_client.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / configure/client
+
+# Module: configure/client
+
+## Table of contents
+
+### Interfaces
+
+- [ConfigureSubClient](../interfaces/configure_client.configuresubclient.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/stats_client.md b/x-pack/plugins/cases/docs/cases_client/modules/stats_client.md
new file mode 100644
index 0000000000000..992a1a1ab501a
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/stats_client.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / stats/client
+
+# Module: stats/client
+
+## Table of contents
+
+### Interfaces
+
+- [StatsSubClient](../interfaces/stats_client.statssubclient.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/sub_cases_client.md b/x-pack/plugins/cases/docs/cases_client/modules/sub_cases_client.md
new file mode 100644
index 0000000000000..6bdf073566b1c
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/sub_cases_client.md
@@ -0,0 +1,9 @@
+[Cases Client API Interface](../cases_client_api.md) / sub_cases/client
+
+# Module: sub\_cases/client
+
+## Table of contents
+
+### Interfaces
+
+- [SubCasesClient](../interfaces/sub_cases_client.subcasesclient.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/typedoc_interfaces.md b/x-pack/plugins/cases/docs/cases_client/modules/typedoc_interfaces.md
new file mode 100644
index 0000000000000..4719d2a2719c0
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/typedoc_interfaces.md
@@ -0,0 +1,26 @@
+[Cases Client API Interface](../cases_client_api.md) / typedoc_interfaces
+
+# Module: typedoc\_interfaces
+
+This file defines simpler types for typedoc. This helps reduce the type alias expansion for the io-ts types because it
+can be very large. These types are equivalent to the io-ts aliases.
+
+## Table of contents
+
+### Interfaces
+
+- [IAllCommentsResponse](../interfaces/typedoc_interfaces.iallcommentsresponse.md)
+- [ICasePostRequest](../interfaces/typedoc_interfaces.icasepostrequest.md)
+- [ICaseResponse](../interfaces/typedoc_interfaces.icaseresponse.md)
+- [ICaseUserActionsResponse](../interfaces/typedoc_interfaces.icaseuseractionsresponse.md)
+- [ICasesConfigurePatch](../interfaces/typedoc_interfaces.icasesconfigurepatch.md)
+- [ICasesConfigureRequest](../interfaces/typedoc_interfaces.icasesconfigurerequest.md)
+- [ICasesConfigureResponse](../interfaces/typedoc_interfaces.icasesconfigureresponse.md)
+- [ICasesFindRequest](../interfaces/typedoc_interfaces.icasesfindrequest.md)
+- [ICasesFindResponse](../interfaces/typedoc_interfaces.icasesfindresponse.md)
+- [ICasesPatchRequest](../interfaces/typedoc_interfaces.icasespatchrequest.md)
+- [ICasesResponse](../interfaces/typedoc_interfaces.icasesresponse.md)
+- [ICommentsResponse](../interfaces/typedoc_interfaces.icommentsresponse.md)
+- [ISubCaseResponse](../interfaces/typedoc_interfaces.isubcaseresponse.md)
+- [ISubCasesFindResponse](../interfaces/typedoc_interfaces.isubcasesfindresponse.md)
+- [ISubCasesResponse](../interfaces/typedoc_interfaces.isubcasesresponse.md)
diff --git a/x-pack/plugins/cases/docs/cases_client/modules/user_actions_client.md b/x-pack/plugins/cases/docs/cases_client/modules/user_actions_client.md
new file mode 100644
index 0000000000000..b48e3faac2135
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client/modules/user_actions_client.md
@@ -0,0 +1,10 @@
+[Cases Client API Interface](../cases_client_api.md) / user_actions/client
+
+# Module: user\_actions/client
+
+## Table of contents
+
+### Interfaces
+
+- [UserActionGet](../interfaces/user_actions_client.useractionget.md)
+- [UserActionsSubClient](../interfaces/user_actions_client.useractionssubclient.md)
diff --git a/x-pack/plugins/cases/docs/cases_client_typedoc.json b/x-pack/plugins/cases/docs/cases_client_typedoc.json
new file mode 100644
index 0000000000000..5f67719b47574
--- /dev/null
+++ b/x-pack/plugins/cases/docs/cases_client_typedoc.json
@@ -0,0 +1,25 @@
+{
+ "entryPoints": [
+ "../server/client/client.ts",
+ "../server/client/typedoc_interfaces.ts",
+ "../server/client/attachments",
+ "../server/client/cases/client.ts",
+ "../server/client/cases/get.ts",
+ "../server/client/cases/push.ts",
+ "../server/client/configure/client.ts",
+ "../server/client/stats/client.ts",
+ "../server/client/sub_cases/client.ts",
+ "../server/client/user_actions/client.ts"
+ ],
+ "exclude": [
+ "**/mock.ts",
+ "../server/client/cases/+(mock.ts|utils.ts|utils.test.ts|types.ts)"
+ ],
+ "excludeExternals": true,
+ "out": "cases_client",
+ "theme": "markdown",
+ "plugin": "typedoc-plugin-markdown",
+ "entryDocument": "cases_client_api.md",
+ "readme": "none",
+ "name": "Cases Client API Interface"
+}
diff --git a/x-pack/plugins/cases/kibana.json b/x-pack/plugins/cases/kibana.json
index 4a534c29de804..c59800aaf9bcb 100644
--- a/x-pack/plugins/cases/kibana.json
+++ b/x-pack/plugins/cases/kibana.json
@@ -3,7 +3,7 @@
"id": "cases",
"kibanaVersion": "kibana",
"extraPublicDirs": ["common"],
- "requiredPlugins": ["actions", "esUiShared", "kibanaReact", "kibanaUtils", "triggersActionsUi"],
+ "requiredPlugins": ["actions", "esUiShared", "features", "kibanaReact", "kibanaUtils", "triggersActionsUi"],
"optionalPlugins": [
"spaces",
"security"
diff --git a/x-pack/plugins/cases/public/common/lib/kibana/hooks.ts b/x-pack/plugins/cases/public/common/lib/kibana/hooks.ts
index cb90568982282..5246e09f6b0f3 100644
--- a/x-pack/plugins/cases/public/common/lib/kibana/hooks.ts
+++ b/x-pack/plugins/cases/public/common/lib/kibana/hooks.ts
@@ -104,29 +104,3 @@ export const useCurrentUser = (): AuthenticatedElasticUser | null => {
}, [fetchUser]);
return user;
};
-
-export interface UseGetUserSavedObjectPermissions {
- crud: boolean;
- read: boolean;
-}
-
-export const useGetUserSavedObjectPermissions = () => {
- const [
- savedObjectsPermissions,
- setSavedObjectsPermissions,
- ] = useState(null);
- const uiCapabilities = useKibana().services.application.capabilities;
-
- useEffect(() => {
- const capabilitiesCanUserCRUD: boolean =
- typeof uiCapabilities.siem.crud === 'boolean' ? uiCapabilities.siem.crud : false;
- const capabilitiesCanUserRead: boolean =
- typeof uiCapabilities.siem.show === 'boolean' ? uiCapabilities.siem.show : false;
- setSavedObjectsPermissions({
- crud: capabilitiesCanUserCRUD,
- read: capabilitiesCanUserRead,
- });
- }, [uiCapabilities]);
-
- return savedObjectsPermissions;
-};
diff --git a/x-pack/plugins/cases/public/common/mock/test_providers.tsx b/x-pack/plugins/cases/public/common/mock/test_providers.tsx
index 94ee5dd4f2743..9a08918a483a5 100644
--- a/x-pack/plugins/cases/public/common/mock/test_providers.tsx
+++ b/x-pack/plugins/cases/public/common/mock/test_providers.tsx
@@ -10,6 +10,8 @@ import { I18nProvider } from '@kbn/i18n/react';
import React from 'react';
import { BehaviorSubject } from 'rxjs';
import { ThemeProvider } from 'styled-components';
+import { SECURITY_SOLUTION_OWNER } from '../../../common';
+import { OwnerProvider } from '../../components/owner_context';
import {
createKibanaContextProviderMock,
createStartServicesMock,
@@ -29,7 +31,9 @@ const MockKibanaContextProvider = createKibanaContextProviderMock();
const TestProvidersComponent: React.FC = ({ children }) => (
- ({ eui: euiDarkVars, darkMode: true })}>{children}
+ ({ eui: euiDarkVars, darkMode: true })}>
+ {children}
+
);
diff --git a/x-pack/plugins/cases/public/common/translations.ts b/x-pack/plugins/cases/public/common/translations.ts
index 834bd1292ccdd..85cfb60b1d6b8 100644
--- a/x-pack/plugins/cases/public/common/translations.ts
+++ b/x-pack/plugins/cases/public/common/translations.ts
@@ -7,18 +7,18 @@
import { i18n } from '@kbn/i18n';
-export const SAVED_OBJECT_NO_PERMISSIONS_TITLE = i18n.translate(
- 'xpack.cases.caseSavedObjectNoPermissionsTitle',
+export const CASES_FEATURE_NO_PERMISSIONS_TITLE = i18n.translate(
+ 'xpack.cases.caseFeatureNoPermissionsTitle',
{
defaultMessage: 'Kibana feature privileges required',
}
);
-export const SAVED_OBJECT_NO_PERMISSIONS_MSG = i18n.translate(
- 'xpack.cases.caseSavedObjectNoPermissionsMessage',
+export const CASES_FEATURE_NO_PERMISSIONS_MSG = i18n.translate(
+ 'xpack.cases.caseFeatureNoPermissionsMessage',
{
defaultMessage:
- 'To view cases, you must have privileges for the Saved Object Management feature in the Kibana space. For more information, contact your Kibana administrator.',
+ 'To view cases, you must have privileges for the Cases feature in the Kibana space. For more information, contact your Kibana administrator.',
}
);
diff --git a/x-pack/plugins/cases/public/components/add_comment/index.test.tsx b/x-pack/plugins/cases/public/components/add_comment/index.test.tsx
index d35a3dc6a7462..23a0fca48592f 100644
--- a/x-pack/plugins/cases/public/components/add_comment/index.test.tsx
+++ b/x-pack/plugins/cases/public/components/add_comment/index.test.tsx
@@ -13,7 +13,7 @@ import { noop } from 'lodash/fp';
import { TestProviders } from '../../common/mock';
import { Router, routeData, mockHistory, mockLocation } from '../__mock__/router';
-import { CommentRequest, CommentType } from '../../../common';
+import { CommentRequest, CommentType, SECURITY_SOLUTION_OWNER } from '../../../common';
import { usePostComment } from '../../containers/use_post_comment';
import { AddComment, AddCommentRefObject } from '.';
import { CasesTimelineIntegrationProvider } from '../timeline_context';
@@ -44,6 +44,7 @@ const defaultPostComment = {
const sampleData: CommentRequest = {
comment: 'what a cool comment',
type: CommentType.user,
+ owner: SECURITY_SOLUTION_OWNER,
};
describe('AddComment ', () => {
diff --git a/x-pack/plugins/cases/public/components/add_comment/index.tsx b/x-pack/plugins/cases/public/components/add_comment/index.tsx
index b4aadc85ad5a7..04104f0b9471d 100644
--- a/x-pack/plugins/cases/public/components/add_comment/index.tsx
+++ b/x-pack/plugins/cases/public/components/add_comment/index.tsx
@@ -18,6 +18,7 @@ import { Form, useForm, UseField, useFormData } from '../../common/shared_import
import * as i18n from './translations';
import { schema, AddCommentFormSchema } from './schema';
import { InsertTimeline } from '../insert_timeline';
+import { useOwnerContext } from '../owner_context/use_owner_context';
const MySpinner = styled(EuiLoadingSpinner)`
position: absolute;
top: 50%;
@@ -47,6 +48,7 @@ export const AddComment = React.memo(
{ caseId, disabled, onCommentPosted, onCommentSaving, showLoading = true, subCaseId },
ref
) => {
+ const owner = useOwnerContext();
const { isLoading, postComment } = usePostComment();
const { form } = useForm({
@@ -78,13 +80,13 @@ export const AddComment = React.memo(
}
postComment({
caseId,
- data: { ...data, type: CommentType.user },
+ data: { ...data, type: CommentType.user, owner: owner[0] },
updateCase: onCommentPosted,
subCaseId,
});
reset();
}
- }, [caseId, onCommentPosted, onCommentSaving, postComment, reset, submit, subCaseId]);
+ }, [submit, onCommentSaving, postComment, caseId, owner, onCommentPosted, subCaseId, reset]);
return (