;
-
-export class I18nProvider implements angular.IServiceProvider {
- public addTranslation = i18n.addTranslation;
- public getTranslation = i18n.getTranslation;
- public setLocale = i18n.setLocale;
- public getLocale = i18n.getLocale;
- public setDefaultLocale = i18n.setDefaultLocale;
- public getDefaultLocale = i18n.getDefaultLocale;
- public setFormats = i18n.setFormats;
- public getFormats = i18n.getFormats;
- public getRegisteredLocales = i18n.getRegisteredLocales;
- public init = i18n.init;
- public load = i18n.load;
- public $get = () => i18n.translate;
-}
diff --git a/packages/osd-stylelint-config/config/global_selectors.json b/packages/osd-stylelint-config/config/global_selectors.json
index 760717c8dab5..d89561a04cbc 100644
--- a/packages/osd-stylelint-config/config/global_selectors.json
+++ b/packages/osd-stylelint-config/config/global_selectors.json
@@ -23,9 +23,7 @@
"src/plugins/vis_builder/public/application/components/searchable_dropdown.scss",
"src/plugins/vis_builder/public/application/components/side_nav.scss",
"packages/osd-ui-framework/src/components/button/button_group/_button_group.scss",
- "src/plugins/discover_legacy/public/application/components/sidebar/discover_sidebar.scss",
- "src/plugins/discover_legacy/public/application/angular/doc_table/components/table_row/_open.scss",
"src/plugins/discover/public/application/components/data_grid/data_grid_table_cell_value.scss"
]
}
-}
+}
\ No newline at end of file
diff --git a/packages/osd-ui-framework/src/components/local_nav/_local_date_picker.scss b/packages/osd-ui-framework/src/components/local_nav/_local_date_picker.scss
index 0a38a115c4a0..ec60ffb4a918 100644
--- a/packages/osd-ui-framework/src/components/local_nav/_local_date_picker.scss
+++ b/packages/osd-ui-framework/src/components/local_nav/_local_date_picker.scss
@@ -54,19 +54,6 @@
.kuiDatePickerRowCell {
padding: 0;
text-align: center;
-
- /**
- * This state class exists to support weird angular-bootstrap datepicker functionality,
- * in which you can't select a day on the "From" calendar if it falls after the selected day in
- * the "To" calendar (and vice versa, you can't select a "To" day if it is before the "From" day).
- */
- &.kuiDatePickerRowCell-isBlocked {
- cursor: not-allowed;
-
- .kuiDatePickerRowCellContent {
- pointer-events: none;
- }
- }
}
/**
diff --git a/packages/osd-ui-shared-deps/entry.js b/packages/osd-ui-shared-deps/entry.js
index 813fe512a554..8afb2b08da6c 100644
--- a/packages/osd-ui-shared-deps/entry.js
+++ b/packages/osd-ui-shared-deps/entry.js
@@ -30,16 +30,13 @@
require('./polyfills');
-// must load before angular
export const Jquery = require('jquery');
window.$ = window.jQuery = Jquery;
require('./flot_charts');
// stateful deps
export const OsdI18n = require('@osd/i18n');
-export const OsdI18nAngular = require('@osd/i18n/angular');
export const OsdI18nReact = require('@osd/i18n/react');
-export const Angular = require('angular');
export const Moment = require('moment');
export const MomentTimezone = require('moment-timezone/moment-timezone');
export const OsdMonaco = require('@osd/monaco');
diff --git a/packages/osd-ui-shared-deps/index.js b/packages/osd-ui-shared-deps/index.js
index 1ebd54a55a97..36218a28d4eb 100644
--- a/packages/osd-ui-shared-deps/index.js
+++ b/packages/osd-ui-shared-deps/index.js
@@ -40,9 +40,7 @@ exports.darkCssDistFilename = 'osd-ui-shared-deps.v7.dark.css';
exports.darkV8CssDistFilename = 'osd-ui-shared-deps.v8.dark.css';
exports.externals = {
// stateful deps
- angular: '__osdSharedDeps__.Angular',
'@osd/i18n': '__osdSharedDeps__.OsdI18n',
- '@osd/i18n/angular': '__osdSharedDeps__.OsdI18nAngular',
'@osd/i18n/react': '__osdSharedDeps__.OsdI18nReact',
jquery: '__osdSharedDeps__.Jquery',
moment: '__osdSharedDeps__.Moment',
diff --git a/packages/osd-ui-shared-deps/package.json b/packages/osd-ui-shared-deps/package.json
index fca9abd7c537..ca6028d56acc 100644
--- a/packages/osd-ui-shared-deps/package.json
+++ b/packages/osd-ui-shared-deps/package.json
@@ -16,7 +16,6 @@
"@osd/i18n": "1.0.0",
"@osd/monaco": "1.0.0",
"abortcontroller-polyfill": "^1.4.0",
- "angular": "^1.8.2",
"axios": "^0.27.2",
"compression-webpack-plugin": "npm:@amoo-miki/compression-webpack-plugin@4.0.1-rc.1",
"core-js": "^3.6.5",
@@ -52,4 +51,4 @@
"val-loader": "^2.1.2",
"webpack": "npm:@amoo-miki/webpack@4.46.0-rc.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/dev/i18n/README.md b/src/dev/i18n/README.md
index 4a9e3f45eff0..7cfb938d38ec 100644
--- a/src/dev/i18n/README.md
+++ b/src/dev/i18n/README.md
@@ -4,7 +4,7 @@
### Description
-The tool is used to extract default messages from all `*.{js, ts, jsx, tsx, html }` files in provided plugins directories to a JSON file.
+The tool is used to extract default messages from all `*.{js, ts, jsx, tsx }` files in provided plugins directories to a JSON file.
It uses Babel to parse code and build an AST for each file or a single JS expression if whole file parsing is impossible. The tool is able to validate, extract and match IDs, default messages and descriptions only if they are defined statically and together, otherwise it will fail with detailed explanation. That means one can't define ID in one place and default message in another, or use function call to dynamically create default message etc.
@@ -18,33 +18,6 @@ The `defaultMessage` must contain ICU references to all keys in the `values` and
The `description` is optional, `values` is optional too unless `defaultMessage` references to it.
-* **Angular (.html)**
-
- * **Filter**
-
- ```
- {{ ::'pluginNamespace.messageId' | i18n: {
- defaultMessage: 'Default message string literal, {key}',
- values: { key: 'value' },
- description: 'Message context or description'
- } }}
- ```
-
- * Don't break `| i18n: {` with line breaks, and don't skip whitespaces around `i18n:`.
- * `::` operator is optional. Omit it if you need data binding for the `values`.
-
- * **Directive**
-
- ```html
-
- ```
-
- * `html_` prefixes will be removed from `i18n-values` keys before validation.
* **React (.jsx, .tsx)**
diff --git a/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_1/test_file_4.html b/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_1/test_file_4.html
deleted file mode 100644
index f725fa288405..000000000000
--- a/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_1/test_file_4.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
diff --git a/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_2/test_file.html b/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_2/test_file.html
deleted file mode 100644
index c12843602b13..000000000000
--- a/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_2/test_file.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ ::'plugin_2.message-id' | i18n: { defaultMessage: 'Message text' } }}
diff --git a/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_2/test_file.jsx b/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_2/test_file.jsx
new file mode 100644
index 000000000000..b3f0c8d2b9c1
--- /dev/null
+++ b/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_2/test_file.jsx
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+i18n('plugin_2.message-id', { defaultMessage: 'Message text' });
diff --git a/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_4/test_file_4.jsx b/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_4/test_file_4.jsx
new file mode 100644
index 000000000000..5ce7b916bcd4
--- /dev/null
+++ b/src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_4/test_file_4.jsx
@@ -0,0 +1,18 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/* eslint-disable */
+class Component extends PureComponent {
+ render() {
+ return (
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/dev/i18n/__snapshots__/extract_default_translations.test.js.snap b/src/dev/i18n/__snapshots__/extract_default_translations.test.js.snap
index b19b366a8db7..cf91d6252d05 100644
--- a/src/dev/i18n/__snapshots__/extract_default_translations.test.js.snap
+++ b/src/dev/i18n/__snapshots__/extract_default_translations.test.js.snap
@@ -30,11 +30,52 @@ Array [
"message": "Message 4",
},
],
+]
+`;
+
+exports[`dev/i18n/extract_default_translations extracts messages from path to map 2`] = `
+Array [
+ Array [
+ "plugin_2.message-id",
+ Object {
+ "description": undefined,
+ "message": "Message text",
+ },
+ ],
+]
+`;
+
+exports[`dev/i18n/extract_default_translations extracts messages from path to map 3`] = `
+Array [
+ Array [
+ "plugin_3.duplicate_id",
+ Object {
+ "description": undefined,
+ "message": "Message 1",
+ },
+ ],
+]
+`;
+
+exports[`dev/i18n/extract_default_translations extracts messages from path to map 4`] = `
+Array [
Array [
- "plugin_1.id_7",
+ "plugin_3.duplicate_id",
Object {
"description": undefined,
- "message": "Message 7",
+ "message": "Message 1",
+ },
+ ],
+]
+`;
+
+exports[`dev/i18n/extract_default_translations extracts messages from path to map 5`] = `
+Array [
+ Array [
+ "plugin_4.id_1",
+ Object {
+ "description": undefined,
+ "message": "Message 4",
},
],
]
diff --git a/src/dev/i18n/extract_default_translations.test.js b/src/dev/i18n/extract_default_translations.test.js
index ea4754f3645e..c995ec562735 100644
--- a/src/dev/i18n/extract_default_translations.test.js
+++ b/src/dev/i18n/extract_default_translations.test.js
@@ -42,6 +42,7 @@ const pluginsPaths = [
path.join(fixturesPath, 'test_plugin_2'),
path.join(fixturesPath, 'test_plugin_3'),
path.join(fixturesPath, 'test_plugin_3_additional_path'),
+ path.join(fixturesPath, 'test_plugin_4'),
];
const config = {
@@ -52,17 +53,19 @@ const config = {
'src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_3',
'src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_3_additional_path',
],
+ plugin_4: ['src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_4'],
},
exclude: [],
};
describe('dev/i18n/extract_default_translations', () => {
test('extracts messages from path to map', async () => {
- const [pluginPath] = pluginsPaths;
- const resultMap = new Map();
+ for (const pluginPath of pluginsPaths) {
+ const resultMap = new Map();
- await extractMessagesFromPathToMap(pluginPath, resultMap, config, new ErrorReporter());
- expect([...resultMap].sort()).toMatchSnapshot();
+ await extractMessagesFromPathToMap(pluginPath, resultMap, config, new ErrorReporter());
+ expect([...resultMap].sort()).toMatchSnapshot();
+ }
});
test('throws on id collision', async () => {
@@ -88,11 +91,11 @@ describe('dev/i18n/extract_default_translations', () => {
const id = 'plugin_3.message-id';
const filePath1 = path.resolve(
__dirname,
- '__fixtures__/extract_default_translations/test_plugin_3/test_file.html'
+ '__fixtures__/extract_default_translations/test_plugin_3/test_file.jsx'
);
const filePath2 = path.resolve(
__dirname,
- '__fixtures__/extract_default_translations/test_plugin_3_additional_path/test_file.html'
+ '__fixtures__/extract_default_translations/test_plugin_3_additional_path/test_file.jsx'
);
expect(() => validateMessageNamespace(id, filePath1, config.paths)).not.toThrow();
expect(() => validateMessageNamespace(id, filePath2, config.paths)).not.toThrow();
@@ -103,7 +106,7 @@ describe('dev/i18n/extract_default_translations', () => {
const id = 'wrong_plugin_namespace.message-id';
const filePath = path.resolve(
__dirname,
- '__fixtures__/extract_default_translations/test_plugin_2/test_file.html'
+ '__fixtures__/extract_default_translations/test_plugin_2/test_file.jsx'
);
expect(() => validateMessageNamespace(id, filePath, config.paths, { report })).not.toThrow();
diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx
index 956bb5a7a836..dd874d3419f2 100644
--- a/src/plugins/dashboard/public/plugin.tsx
+++ b/src/plugins/dashboard/public/plugin.tsx
@@ -80,7 +80,6 @@ import {
withNotifyOnErrors,
} from '../../opensearch_dashboards_utils/public';
import {
- initAngularBootstrap,
OpenSearchDashboardsLegacySetup,
OpenSearchDashboardsLegacyStart,
} from '../../opensearch_dashboards_legacy/public';
@@ -452,9 +451,6 @@ export class DashboardPlugin
},
};
- // TODO: delete this when discover de-angular is completed
- initAngularBootstrap();
-
core.application.register(app);
urlForwarding.forwardApp(
DashboardConstants.DASHBOARDS_ID,
diff --git a/src/plugins/data/common/search/aggs/utils/prop_filter.ts b/src/plugins/data/common/search/aggs/utils/prop_filter.ts
index 341032e47bf6..2670e3d26b82 100644
--- a/src/plugins/data/common/search/aggs/utils/prop_filter.ts
+++ b/src/plugins/data/common/search/aggs/utils/prop_filter.ts
@@ -37,7 +37,7 @@ type FilterFunc = (item: T[P]) => boolean;
* - fieldType filters a list of fields by their type property
* - aggFilter filters a list of aggs by their name property
*
- * @returns the filter function which can be registered with angular
+ * @returns the filter function
*/
export function propFilter
(prop: P) {
/**
diff --git a/src/plugins/data/common/search/aggs/utils/to_angular_json.ts b/src/plugins/data/common/search/aggs/utils/to_angular_json.ts
index 0efafa7884a1..3eac6a1fcfe4 100644
--- a/src/plugins/data/common/search/aggs/utils/to_angular_json.ts
+++ b/src/plugins/data/common/search/aggs/utils/to_angular_json.ts
@@ -33,6 +33,7 @@
* https://github.com/angular/angular.js/blob/master/src/Angular.js#L1312
*
* @internal
+ * @deprecated This function will be removed in the next major version.
*/
export function toAngularJSON(obj: any, pretty?: any): string {
if (obj === undefined) return '';
diff --git a/src/plugins/data_explorer/public/components/sidebar/index.tsx b/src/plugins/data_explorer/public/components/sidebar/index.tsx
index 921e3894983b..42abed642e36 100644
--- a/src/plugins/data_explorer/public/components/sidebar/index.tsx
+++ b/src/plugins/data_explorer/public/components/sidebar/index.tsx
@@ -76,6 +76,7 @@ export const Sidebar: FC = ({ children }) => {
{
const [inspectedHit, setInspectedHit] = useState();
const rowCount = useMemo(() => (rows ? rows.length : 0), [rows]);
@@ -166,7 +172,12 @@ export const DataGridTable = ({
indexPattern,
}}
>
- <>
+
{table}
@@ -183,7 +194,7 @@ export const DataGridTable = ({
onClose={() => setInspectedHit(undefined)}
/>
)}
- >
+
);
};
diff --git a/src/plugins/discover/public/application/components/data_grid/data_grid_table_flyout.tsx b/src/plugins/discover/public/application/components/data_grid/data_grid_table_flyout.tsx
index 8cfeaf9795af..315d5ca9c006 100644
--- a/src/plugins/discover/public/application/components/data_grid/data_grid_table_flyout.tsx
+++ b/src/plugins/discover/public/application/components/data_grid/data_grid_table_flyout.tsx
@@ -13,14 +13,15 @@ import {
EuiFlexItem,
EuiTitle,
} from '@elastic/eui';
+import { FormattedMessage } from '@osd/i18n/react';
import { DocViewer } from '../doc_viewer/doc_viewer';
import { IndexPattern } from '../../../opensearch_dashboards_services';
-import { DocViewFilterFn } from '../../doc_views/doc_views_types';
+import { DocViewFilterFn, OpenSearchSearchHit } from '../../doc_views/doc_views_types';
import { DocViewerLinks } from '../doc_viewer_links/doc_viewer_links';
interface Props {
columns: string[];
- hit: any;
+ hit: OpenSearchSearchHit;
indexPattern: IndexPattern;
onAddColumn: (column: string) => void;
onClose: () => void;
@@ -40,10 +41,12 @@ export function DataGridFlyout({
// TODO: replace EuiLink with doc_view_links registry
// TODO: Also move the flyout higher in the react tree to prevent redrawing the table component and slowing down page performance
return (
-
+
- Document Details
+
+
+
diff --git a/src/plugins/discover/public/application/components/doc_viewer_links/__snapshots__/doc_viewer_links.test.tsx.snap b/src/plugins/discover/public/application/components/doc_viewer_links/__snapshots__/doc_viewer_links.test.tsx.snap
index 5da67e79a7c7..52dfa61e07f3 100644
--- a/src/plugins/discover/public/application/components/doc_viewer_links/__snapshots__/doc_viewer_links.test.tsx.snap
+++ b/src/plugins/discover/public/application/components/doc_viewer_links/__snapshots__/doc_viewer_links.test.tsx.snap
@@ -17,7 +17,7 @@ exports[`Render with 2 different links 1`] = `
key="0"
>
with 2 different links 1`] = `
key="1"
>
{
const { generateCb, href, ...props } = item;
const listItem: EuiListGroupItemProps = {
- 'data-test-subj': 'docTableRowAction',
+ 'data-test-subj': `docTableRowAction`,
...props,
href: generateCb ? generateCb(renderProps).url : href,
};
@@ -31,7 +31,7 @@ export function DocViewerLinks(renderProps: DocViewLinkRenderProps) {
href={item.href}
target="_blank"
style={{ fontWeight: 'normal' }}
- data-test-subj={item['data-test-subj']}
+ data-test-subj={`${item['data-test-subj']}-${index}`}
>
{item.label}
diff --git a/src/plugins/discover/public/application/components/sidebar/discover_field.scss b/src/plugins/discover/public/application/components/sidebar/discover_field.scss
index 8e1dd41f66ab..643f74b809c2 100644
--- a/src/plugins/discover/public/application/components/sidebar/discover_field.scss
+++ b/src/plugins/discover/public/application/components/sidebar/discover_field.scss
@@ -2,3 +2,13 @@
min-width: 260px;
max-width: 300px;
}
+
+.dscSidebarField__actionButton {
+ opacity: 0;
+ transition: opacity $ouiAnimSpeedExtraFast;
+
+ &:hover,
+ &:focus {
+ opacity: 1;
+ }
+}
diff --git a/src/plugins/discover/public/application/components/sidebar/discover_field.tsx b/src/plugins/discover/public/application/components/sidebar/discover_field.tsx
index 73dc40a262e0..a924191c88f1 100644
--- a/src/plugins/discover/public/application/components/sidebar/discover_field.tsx
+++ b/src/plugins/discover/public/application/components/sidebar/discover_field.tsx
@@ -40,7 +40,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@osd/i18n';
import { DiscoverFieldDetails } from './discover_field_details';
-import { FieldIcon, FieldButton } from '../../../../../opensearch_dashboards_react/public';
+import { FieldIcon } from '../../../../../opensearch_dashboards_react/public';
import { FieldDetails } from './types';
import { IndexPatternField, IndexPattern } from '../../../../../data/public';
import { shortenDottedString } from '../../helpers';
@@ -163,6 +163,7 @@ export const DiscoverField = ({
}}
data-test-subj={`fieldToggle-${field.name}`}
aria-label={addLabelAria}
+ className="dscSidebarField__actionButton"
/>
);
@@ -187,6 +188,7 @@ export const DiscoverField = ({
}}
data-test-subj={`fieldToggle-${field.name}`}
aria-label={removeLabelAria}
+ className="dscSidebarField__actionButton"
/>
);
@@ -219,6 +221,7 @@ export const DiscoverField = ({
onClick={() => setOpen((state) => !state)}
aria-label={infoLabelAria}
data-test-subj={`field-${field.name}-showDetails`}
+ className="dscSidebarField__actionButton"
/>
}
panelClassName="dscSidebarItem__fieldPopoverPanel"
diff --git a/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx b/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx
index 8c19d38eb20d..3a0cdd17d238 100644
--- a/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx
+++ b/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx
@@ -8,7 +8,6 @@ import React from 'react';
import { DiscoverViewServices } from '../../../build_services';
import { showOpenSearchPanel } from './show_open_search_panel';
import { SavedSearch } from '../../../saved_searches';
-import { NEW_DISCOVER_APP } from '../../../../common';
import { Adapters } from '../../../../../inspector/public';
import { TopNavMenuData } from '../../../../../navigation/public';
import { ISearchSource, unhashUrl } from '../../../opensearch_dashboards_services';
@@ -30,7 +29,6 @@ export const getTopNavLinks = (
history,
inspector,
core,
- uiSettings,
capabilities,
share,
toastNotifications,
@@ -194,7 +192,7 @@ export const getTopNavLinks = (
share?.toggleShareContextMenu({
anchorElement,
allowEmbed: false,
- allowShortUrl: capabilities.discover.createShortUrl as boolean,
+ allowShortUrl: capabilities.discover?.createShortUrl as boolean,
shareableUrl: unhashUrl(window.location.href),
objectId: savedSearch.id,
objectType: 'search',
@@ -223,27 +221,9 @@ export const getTopNavLinks = (
},
};
- const legacyDiscover: TopNavMenuData = {
- id: 'discover-new',
- label: i18n.translate('discover.localMenu.newDiscoverTitle', {
- defaultMessage: 'New Discover',
- }),
- description: i18n.translate('discover.localMenu.newDiscoverDescription', {
- defaultMessage: 'New Discover Experience',
- }),
- testId: 'discoverNewButton',
- run: async () => {
- await uiSettings.set(NEW_DISCOVER_APP, false);
- window.location.reload();
- },
- type: 'toggle' as const,
- emphasize: true,
- };
-
return [
- legacyDiscover,
newSearch,
- ...(capabilities.discover.save ? [saveSearch] : []),
+ ...(capabilities.discover?.save ? [saveSearch] : []),
openSearch,
...(share ? [shareSearch] : []), // Show share option only if share plugin is available
inspectSearch,
diff --git a/src/plugins/discover/public/application/view_components/canvas/discover_canvas.scss b/src/plugins/discover/public/application/view_components/canvas/discover_canvas.scss
new file mode 100644
index 000000000000..e1a21bcf201c
--- /dev/null
+++ b/src/plugins/discover/public/application/view_components/canvas/discover_canvas.scss
@@ -0,0 +1,5 @@
+.dscCanvas {
+ @include euiYScrollWithShadows;
+
+ height: 100%;
+}
diff --git a/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx b/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx
index 8d9966af0ec0..dcac343c4ce8 100644
--- a/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx
+++ b/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx
@@ -17,7 +17,7 @@ import {
useDispatch,
useSelector,
} from '../../utils/state_management';
-import { ResultStatus, SearchData } from '../utils/use_search';
+import { ResultStatus, SearchData, useSearch } from '../utils/use_search';
import { IndexPatternField, opensearchFilters } from '../../../../../data/public';
import { DocViewFilterFn } from '../../doc_views/doc_views_types';
import { SortOrder } from '../../../saved_searches/types';
@@ -71,6 +71,7 @@ export const DiscoverTable = ({ history }: Props) => {
);
const { rows } = fetchState || {};
+ const { savedSearch } = useSearch(services);
useEffect(() => {
const subscription = data$.subscribe((next) => {
@@ -107,6 +108,8 @@ export const DiscoverTable = ({ history }: Props) => {
rows={rows}
displayTimeColumn={displayTimeColumn}
services={services}
+ title={savedSearch?.id ? savedSearch.title : ''}
+ description={savedSearch?.id ? savedSearch.description : ''}
/>
);
};
diff --git a/src/plugins/discover/public/application/view_components/canvas/index.tsx b/src/plugins/discover/public/application/view_components/canvas/index.tsx
index b5adc9596321..3c25e5a221dc 100644
--- a/src/plugins/discover/public/application/view_components/canvas/index.tsx
+++ b/src/plugins/discover/public/application/view_components/canvas/index.tsx
@@ -4,7 +4,7 @@
*/
import React, { useEffect, useState, useRef } from 'react';
-import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiCallOut, EuiLink } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
import { TopNav } from './top_nav';
import { ViewProps } from '../../../../../data_explorer/public';
import { DiscoverTable } from './discover_table';
@@ -19,9 +19,7 @@ import { DiscoverViewServices } from '../../../build_services';
import { useOpenSearchDashboards } from '../../../../../opensearch_dashboards_react/public';
import { filterColumns } from '../utils/filter_columns';
import { DEFAULT_COLUMNS_SETTING } from '../../../../common';
-
-const KEY_SHOW_NOTICE = 'discover:deprecation-notice:show';
-
+import './discover_canvas.scss';
// eslint-disable-next-line import/no-default-export
export default function DiscoverCanvas({ setHeaderActionMenu, history }: ViewProps) {
const { data$, refetch$, indexPattern } = useDiscoverContext();
@@ -43,39 +41,6 @@ export default function DiscoverCanvas({ setHeaderActionMenu, history }: ViewPro
bucketInterval: {},
});
- const [isCallOutVisible, setIsCallOutVisible] = useState(
- localStorage.getItem(KEY_SHOW_NOTICE) !== 'false'
- );
- const closeCallOut = () => {
- localStorage.setItem(KEY_SHOW_NOTICE, 'false');
- setIsCallOutVisible(false);
- };
-
- let callOut;
-
- if (isCallOutVisible) {
- callOut = (
-
-
-
-
- To provide feedback,{' '}
-
- open an issue
-
- .
-
-
-
-
- );
- }
-
const { status } = fetchState;
useEffect(() => {
@@ -104,7 +69,7 @@ export default function DiscoverCanvas({ setHeaderActionMenu, history }: ViewPro
const timeField = indexPattern?.timeFieldName ? indexPattern.timeFieldName : undefined;
return (
-
+
}
{status === ResultStatus.READY && (
<>
- {callOut}
diff --git a/src/plugins/discover/public/application/view_components/canvas/top_nav.tsx b/src/plugins/discover/public/application/view_components/canvas/top_nav.tsx
index 7a777142d2f0..4a8ebfb1bf29 100644
--- a/src/plugins/discover/public/application/view_components/canvas/top_nav.tsx
+++ b/src/plugins/discover/public/application/view_components/canvas/top_nav.tsx
@@ -5,7 +5,7 @@
import React, { useEffect, useMemo, useState } from 'react';
import { AppMountParameters } from '../../../../../../core/public';
-import { NEW_DISCOVER_APP, PLUGIN_ID } from '../../../../common';
+import { PLUGIN_ID } from '../../../../common';
import { useOpenSearchDashboards } from '../../../../../opensearch_dashboards_react/public';
import { DiscoverViewServices } from '../../../build_services';
import { IndexPattern } from '../../../opensearch_dashboards_services';
@@ -25,12 +25,11 @@ export const TopNav = ({ opts }: TopNavProps) => {
const [indexPatterns, setIndexPatterns] = useState(undefined);
const {
- uiSettings,
navigation: {
ui: { TopNavMenu },
},
core: {
- application: { navigateToApp, getUrlForApp },
+ application: { getUrlForApp },
},
data,
chrome,
@@ -38,18 +37,6 @@ export const TopNav = ({ opts }: TopNavProps) => {
const topNavLinks = savedSearch ? getTopNavLinks(services, inspectorAdapters, savedSearch) : [];
- useEffect(() => {
- if (uiSettings.get(NEW_DISCOVER_APP) === false) {
- const path = window.location.hash;
- navigateToApp('discoverLegacy', {
- replace: true,
- path,
- });
- }
-
- return () => {};
- }, [navigateToApp, uiSettings]);
-
useEffect(() => {
let isMounted = true;
const getDefaultIndexPattern = async () => {
diff --git a/src/plugins/discover/public/application/view_components/utils/use_search.ts b/src/plugins/discover/public/application/view_components/utils/use_search.ts
index b3fbefcdfad1..6414d0328715 100644
--- a/src/plugins/discover/public/application/view_components/utils/use_search.ts
+++ b/src/plugins/discover/public/application/view_components/utils/use_search.ts
@@ -67,6 +67,7 @@ export type RefetchSubject = Subject;
* }, [data$]);
*/
export const useSearch = (services: DiscoverServices) => {
+ const initalSearchComplete = useRef(false);
const [savedSearch, setSavedSearch] = useState(undefined);
const { savedSearch: savedSearchId, sort, interval } = useSelector((state) => state.discover);
const { data, filterManager, getSavedSearchById, core, toastNotifications, store } = services;
@@ -205,6 +206,8 @@ export const useSearch = (services: DiscoverServices) => {
});
data.search.showError(error as Error);
+ } finally {
+ initalSearchComplete.current = true;
}
}, [
indexPattern,
@@ -240,18 +243,29 @@ export const useSearch = (services: DiscoverServices) => {
})();
});
- // kick off initial fetch
- refetch$.next();
+ // kick off initial refetch on page load
+ if (shouldSearchOnPageLoad() || initalSearchComplete.current === true) {
+ refetch$.next();
+ }
return () => {
subscription.unsubscribe();
};
- }, [data$, data.query.queryString, filterManager, refetch$, timefilter, fetch, core.fatalErrors]);
+ }, [
+ data$,
+ data.query.queryString,
+ filterManager,
+ refetch$,
+ timefilter,
+ fetch,
+ core.fatalErrors,
+ shouldSearchOnPageLoad,
+ ]);
// Get savedSearch if it exists
useEffect(() => {
(async () => {
- const savedSearchInstance = await getSavedSearchById(savedSearchId || '');
+ const savedSearchInstance = await getSavedSearchById(savedSearchId);
setSavedSearch(savedSearchInstance);
// sync initial app filters from savedObject to filterManager
diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts
index ebe4e80a70c5..785e72536417 100644
--- a/src/plugins/discover/public/build_services.ts
+++ b/src/plugins/discover/public/build_services.ts
@@ -78,7 +78,7 @@ export interface DiscoverServices {
urlForwarding: UrlForwardingStart;
timefilter: TimefilterContract;
toastNotifications: ToastsStart;
- getSavedSearchById: (id: string) => Promise;
+ getSavedSearchById: (id?: string) => Promise;
getSavedSearchUrlById: (id: string) => Promise;
uiSettings: IUiSettingsClient;
visualizations: VisualizationsStart;
@@ -107,7 +107,7 @@ export function buildServices(
docLinks: core.docLinks,
theme: plugins.charts.theme,
filterManager: plugins.data.query.filterManager,
- getSavedSearchById: async (id: string) => savedObjectService.get(id),
+ getSavedSearchById: async (id?: string) => savedObjectService.get(id),
getSavedSearchUrlById: async (id: string) => savedObjectService.urlFor(id),
history: getHistory,
indexPatterns: plugins.data.indexPatterns,
diff --git a/src/plugins/discover_legacy/public/application/embeddable/constants.ts b/src/plugins/discover/public/embeddable/constants.ts
similarity index 100%
rename from src/plugins/discover_legacy/public/application/embeddable/constants.ts
rename to src/plugins/discover/public/embeddable/constants.ts
diff --git a/src/plugins/discover_legacy/public/application/embeddable/index.ts b/src/plugins/discover/public/embeddable/index.ts
similarity index 100%
rename from src/plugins/discover_legacy/public/application/embeddable/index.ts
rename to src/plugins/discover/public/embeddable/index.ts
diff --git a/src/plugins/discover_legacy/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/embeddable/search_embeddable.tsx
similarity index 56%
rename from src/plugins/discover_legacy/public/application/embeddable/search_embeddable.ts
rename to src/plugins/discover/public/embeddable/search_embeddable.tsx
index 933f807f8153..6a0fd097aeef 100644
--- a/src/plugins/discover_legacy/public/application/embeddable/search_embeddable.ts
+++ b/src/plugins/discover/public/embeddable/search_embeddable.tsx
@@ -28,14 +28,14 @@
* under the License.
*/
-import './search_embeddable.scss';
-import angular from 'angular';
-import _ from 'lodash';
+import { isEqual } from 'lodash';
import * as Rx from 'rxjs';
import { Subscription } from 'rxjs';
+import React from 'react';
+import ReactDOM from 'react-dom';
import { i18n } from '@osd/i18n';
-import { UiActionsStart, APPLY_FILTER_TRIGGER } from '../../../../ui_actions/public';
-import { RequestAdapter, Adapters } from '../../../../inspector/public';
+import { UiActionsStart, APPLY_FILTER_TRIGGER } from '../../../ui_actions/public';
+import { RequestAdapter, Adapters } from '../../../inspector/public';
import {
opensearchFilters,
Filter,
@@ -44,66 +44,74 @@ import {
getTime,
Query,
IFieldType,
-} from '../../../../data/public';
-import { Container, Embeddable } from '../../../../embeddable/public';
-import * as columnActions from '../angular/doc_table/actions/columns';
-import searchTemplate from './search_template.html';
+} from '../../../data/public';
+import { Container, Embeddable } from '../../../embeddable/public';
import { ISearchEmbeddable, SearchInput, SearchOutput } from './types';
-import { SortOrder } from '../angular/doc_table/components/table_header/helpers';
-import { getSortForSearchSource } from '../angular/doc_table';
+import { getDefaultSort } from '../application/view_components/utils/get_default_sort';
+import { getSortForSearchSource } from '../application/view_components/utils/get_sort_for_search_source';
import {
getRequestInspectorStats,
getResponseInspectorStats,
getServices,
IndexPattern,
ISearchSource,
-} from '../../opensearch_dashboards_services';
+} from '../opensearch_dashboards_services';
import { SEARCH_EMBEDDABLE_TYPE } from './constants';
-import { SavedSearch } from '../..';
-import { SAMPLE_SIZE_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../common';
-
-interface SearchScope extends ng.IScope {
+import { SortOrder } from '../saved_searches/types';
+import { SavedSearch } from '../saved_searches';
+import {
+ SAMPLE_SIZE_SETTING,
+ SORT_DEFAULT_ORDER_SETTING,
+ DOC_HIDE_TIME_COLUMN_SETTING,
+} from '../../common';
+import { SearchEmbeddableComponent } from './search_embeddable_component';
+import { DiscoverServices } from '../build_services';
+import * as columnActions from '../application/utils/state_management/common';
+import { buildColumns } from '../application/utils/columns';
+
+export interface SearchProps {
columns?: string[];
description?: string;
sort?: SortOrder[];
+ onSort?: (sort: SortOrder[]) => void;
sharedItemTitle?: string;
inspectorAdapters?: Adapters;
- setSortOrder?: (sortPair: SortOrder[]) => void;
- removeColumn?: (column: string) => void;
- addColumn?: (column: string) => void;
- moveColumn?: (column: string, index: number) => void;
- filter?: (field: IFieldType, value: string[], operator: string) => void;
- hits?: any[];
+ onSetColumns?: (columns: string[]) => void;
+ onRemoveColumn?: (column: string) => void;
+ onAddColumn?: (column: string) => void;
+ onMoveColumn?: (column: string, index: number) => void;
+ onFilter?: (field: IFieldType, value: string[], operator: string) => void;
+ rows?: any[];
indexPattern?: IndexPattern;
totalHitCount?: number;
isLoading?: boolean;
+ displayTimeColumn?: boolean;
+ services: DiscoverServices;
+ title?: string;
}
interface SearchEmbeddableConfig {
- $rootScope: ng.IRootScopeService;
- $compile: ng.ICompileService;
savedSearch: SavedSearch;
editUrl: string;
editPath: string;
indexPatterns?: IndexPattern[];
editable: boolean;
filterManager: FilterManager;
+ services: DiscoverServices;
}
export class SearchEmbeddable
extends Embeddable
implements ISearchEmbeddable {
private readonly savedSearch: SavedSearch;
- private $rootScope: ng.IRootScopeService;
- private $compile: ng.ICompileService;
private inspectorAdaptors: Adapters;
- private searchScope?: SearchScope;
+ private searchProps?: SearchProps;
private panelTitle: string = '';
private filtersSearchSource?: ISearchSource;
- private searchInstance?: JQLite;
private autoRefreshFetchSubscription?: Subscription;
private subscription?: Subscription;
public readonly type = SEARCH_EMBEDDABLE_TYPE;
+ private services: DiscoverServices;
private filterManager: FilterManager;
private abortController?: AbortController;
@@ -111,16 +119,17 @@ export class SearchEmbeddable
private prevFilters?: Filter[];
private prevQuery?: Query;
+ private node?: HTMLElement;
+
constructor(
{
- $rootScope,
- $compile,
savedSearch,
editUrl,
editPath,
indexPatterns,
editable,
filterManager,
+ services,
}: SearchEmbeddableConfig,
initialInput: SearchInput,
private readonly executeTriggerActions: UiActionsStart['executeTriggerActions'],
@@ -139,14 +148,13 @@ export class SearchEmbeddable
parent
);
+ this.services = services;
this.filterManager = filterManager;
this.savedSearch = savedSearch;
- this.$rootScope = $rootScope;
- this.$compile = $compile;
this.inspectorAdaptors = {
requests: new RequestAdapter(),
};
- this.initializeSearchScope();
+ this.initializeSearchProps();
this.autoRefreshFetchSubscription = getServices()
.timefilter.getAutoRefreshFetch$()
@@ -155,8 +163,8 @@ export class SearchEmbeddable
this.subscription = Rx.merge(this.getOutput$(), this.getInput$()).subscribe(() => {
this.panelTitle = this.output.title || '';
- if (this.searchScope) {
- this.pushContainerStateParamsToScope(this.searchScope);
+ if (this.searchProps) {
+ this.pushContainerStateParamsToProps(this.searchProps);
}
});
}
@@ -173,48 +181,62 @@ export class SearchEmbeddable
*
* @param {Element} domNode
*/
- public render(domNode: HTMLElement) {
- if (!this.searchScope) {
+ public render(node: HTMLElement) {
+ if (!this.searchProps) {
throw new Error('Search scope not defined');
}
- this.searchInstance = this.$compile(searchTemplate)(this.searchScope);
- const rootNode = angular.element(domNode);
- rootNode.append(this.searchInstance);
-
- this.pushContainerStateParamsToScope(this.searchScope);
+ if (this.node) {
+ ReactDOM.unmountComponentAtNode(this.node);
+ }
+ this.node = node;
}
public destroy() {
super.destroy();
- this.savedSearch.destroy();
- if (this.searchInstance) {
- this.searchInstance.remove();
- }
- if (this.searchScope) {
- this.searchScope.$destroy();
- delete this.searchScope;
+ if (this.searchProps) {
+ delete this.searchProps;
}
if (this.subscription) {
this.subscription.unsubscribe();
}
+ if (this.node) {
+ ReactDOM.unmountComponentAtNode(this.node);
+ }
if (this.autoRefreshFetchSubscription) {
this.autoRefreshFetchSubscription.unsubscribe();
}
if (this.abortController) this.abortController.abort();
}
- private initializeSearchScope() {
- const searchScope: SearchScope = (this.searchScope = this.$rootScope.$new());
-
- searchScope.description = this.savedSearch.description;
- searchScope.inspectorAdapters = this.inspectorAdaptors;
-
+ private initializeSearchProps() {
const { searchSource } = this.savedSearch;
- const indexPattern = (searchScope.indexPattern = searchSource.getField('index'))!;
+ const indexPattern = searchSource.getField('index');
+ if (!indexPattern) {
+ return;
+ }
+
+ const sort = getDefaultSort(
+ indexPattern,
+ this.services.uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc')
+ );
+ this.savedSearch.sort = sort;
+
+ const searchProps: SearchProps = {
+ columns: this.savedSearch.columns,
+ sort: [],
+ inspectorAdapters: this.inspectorAdaptors,
+ rows: [],
+ description: this.savedSearch.description,
+ title: this.savedSearch.title,
+ services: this.services,
+ indexPattern,
+ isLoading: false,
+ displayTimeColumn: !this.services.uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false),
+ };
const timeRangeSearchSource = searchSource.create();
timeRangeSearchSource.setField('filter', () => {
- if (!this.searchScope || !this.input.timeRange) return;
+ if (!this.searchProps || !this.input.timeRange) return;
return getTime(indexPattern, this.input.timeRange);
});
@@ -223,37 +245,47 @@ export class SearchEmbeddable
searchSource.setParent(this.filtersSearchSource);
- this.pushContainerStateParamsToScope(searchScope);
-
- searchScope.setSortOrder = (sort) => {
- this.updateInput({ sort });
+ searchProps.onSort = (newSort) => {
+ this.updateInput({ sort: newSort });
};
- searchScope.addColumn = (columnName: string) => {
- if (!searchScope.columns) {
+ searchProps.onAddColumn = (columnName: string) => {
+ if (!searchProps.columns) {
return;
}
- const columns = columnActions.addColumn(searchScope.columns, columnName);
- this.updateInput({ columns });
+ const updatedColumns = buildColumns(
+ columnActions.addColumn(searchProps.columns, { column: columnName })
+ );
+ this.updateInput({ columns: updatedColumns });
};
- searchScope.removeColumn = (columnName: string) => {
- if (!searchScope.columns) {
+ searchProps.onRemoveColumn = (columnName: string) => {
+ if (!searchProps.columns) {
return;
}
- const columns = columnActions.removeColumn(searchScope.columns, columnName);
- this.updateInput({ columns });
+ const updatedColumns = columnActions.removeColumn(searchProps.columns, columnName);
+ const updatedSort =
+ searchProps.sort && searchProps.sort.length
+ ? searchProps.sort.filter((s) => s[0] !== columnName)
+ : [];
+ this.updateInput({ sort: updatedSort, columns: updatedColumns });
};
- searchScope.moveColumn = (columnName, newIndex: number) => {
- if (!searchScope.columns) {
+ searchProps.onMoveColumn = (columnName, newIndex: number) => {
+ if (!searchProps.columns) {
return;
}
- const columns = columnActions.moveColumn(searchScope.columns, columnName, newIndex);
+ const oldIndex = searchProps.columns.indexOf(columnName);
+ const updatedColumns = columnActions.reorderColumn(searchProps.columns, oldIndex, newIndex);
+ this.updateInput({ columns: updatedColumns });
+ };
+
+ searchProps.onSetColumns = (columnNames: string[]) => {
+ const columns = buildColumns(columnNames);
this.updateInput({ columns });
};
- searchScope.filter = async (field, value, operator) => {
+ searchProps.onFilter = async (field, value, operator) => {
let filters = opensearchFilters.generateFilters(
this.filterManager,
field,
@@ -271,14 +303,18 @@ export class SearchEmbeddable
filters,
});
};
+
+ this.pushContainerStateParamsToProps(searchProps);
}
public reload() {
- this.fetch();
+ if (this.searchProps) {
+ this.pushContainerStateParamsToProps(this.searchProps);
+ }
}
private fetch = async () => {
- if (!this.searchScope) return;
+ if (!this.searchProps) return;
const { searchSource } = this.savedSearch;
@@ -290,8 +326,8 @@ export class SearchEmbeddable
searchSource.setField(
'sort',
getSortForSearchSource(
- this.searchScope.sort,
- this.searchScope.indexPattern,
+ this.searchProps.sort,
+ this.searchProps.indexPattern,
getServices().uiSettings.get(SORT_DEFAULT_ORDER_SETTING)
)
);
@@ -310,6 +346,7 @@ export class SearchEmbeddable
inspectorRequest.json(body);
});
this.updateOutput({ loading: true, error: undefined });
+ this.searchProps!.isLoading = true;
try {
// Make the request
@@ -321,41 +358,53 @@ export class SearchEmbeddable
// Log response to inspector
inspectorRequest.stats(getResponseInspectorStats(resp, searchSource)).ok({ json: resp });
- // Apply the changes to the angular scope
- this.searchScope.$apply(() => {
- this.searchScope!.hits = resp.hits.hits;
- this.searchScope!.totalHitCount = resp.hits.total;
- });
+ this.searchProps!.rows = resp.hits.hits;
+ this.searchProps!.totalHitCount = resp.hits.total;
+ this.searchProps!.isLoading = false;
} catch (error) {
this.updateOutput({ loading: false, error });
+ this.searchProps!.isLoading = false;
}
};
- private pushContainerStateParamsToScope(searchScope: SearchScope) {
+ private renderComponent(node: HTMLElement, searchProps: SearchProps) {
+ if (!this.searchProps) {
+ return;
+ }
+ const props = {
+ searchProps,
+ };
+ ReactDOM.render( , node);
+ }
+
+ private async pushContainerStateParamsToProps(searchProps: SearchProps) {
const isFetchRequired =
!opensearchFilters.onlyDisabledFiltersChanged(this.input.filters, this.prevFilters) ||
- !_.isEqual(this.prevQuery, this.input.query) ||
- !_.isEqual(this.prevTimeRange, this.input.timeRange) ||
- !_.isEqual(searchScope.sort, this.input.sort || this.savedSearch.sort);
+ !isEqual(this.prevQuery, this.input.query) ||
+ !isEqual(this.prevTimeRange, this.input.timeRange) ||
+ !isEqual(searchProps.sort, this.input.sort || this.savedSearch.sort);
// If there is column or sort data on the panel, that means the original columns or sort settings have
// been overridden in a dashboard.
- searchScope.columns = this.input.columns || this.savedSearch.columns;
- searchScope.sort = this.input.sort || this.savedSearch.sort;
- searchScope.sharedItemTitle = this.panelTitle;
+ searchProps.columns = this.input.columns || this.savedSearch.columns;
+ searchProps.sort = this.input.sort || this.savedSearch.sort;
+ searchProps.sharedItemTitle = this.panelTitle;
if (isFetchRequired) {
this.filtersSearchSource!.setField('filter', this.input.filters);
this.filtersSearchSource!.setField('query', this.input.query);
-
- this.fetch();
-
this.prevFilters = this.input.filters;
this.prevQuery = this.input.query;
this.prevTimeRange = this.input.timeRange;
- } else if (this.searchScope) {
- // trigger a digest cycle to make sure non-fetch relevant changes are propagated
- this.searchScope.$applyAsync();
+ this.searchProps = searchProps;
+
+ await this.fetch();
+ } else if (this.searchProps) {
+ this.searchProps = searchProps;
+ }
+
+ if (this.node) {
+ this.renderComponent(this.node, this.searchProps!);
}
}
}
diff --git a/src/plugins/discover/public/embeddable/search_embeddable_component.tsx b/src/plugins/discover/public/embeddable/search_embeddable_component.tsx
new file mode 100644
index 000000000000..c8ae54a16429
--- /dev/null
+++ b/src/plugins/discover/public/embeddable/search_embeddable_component.tsx
@@ -0,0 +1,65 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { I18nProvider } from '@osd/i18n/react';
+import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { SearchProps } from './search_embeddable';
+import {
+ DataGridTable,
+ DataGridTableProps,
+} from '../application/components/data_grid/data_grid_table';
+import { VisualizationNoResults } from '../../../visualizations/public';
+
+interface SearchEmbeddableProps {
+ searchProps: SearchProps;
+}
+export interface DiscoverEmbeddableProps extends DataGridTableProps {
+ totalHitCount: number;
+}
+
+export const DataGridTableMemoized = React.memo((props: DataGridTableProps) => (
+
+));
+
+export function SearchEmbeddableComponent({ searchProps }: SearchEmbeddableProps) {
+ const discoverEmbeddableProps = {
+ columns: searchProps.columns,
+ indexPattern: searchProps.indexPattern,
+ onAddColumn: searchProps.onAddColumn,
+ onFilter: searchProps.onFilter,
+ onRemoveColumn: searchProps.onRemoveColumn,
+ onSort: searchProps.onSort,
+ rows: searchProps.rows,
+ onSetColumns: searchProps.onSetColumns,
+ sort: searchProps.sort,
+ displayTimeColumn: searchProps.displayTimeColumn,
+ services: searchProps.services,
+ totalHitCount: searchProps.totalHitCount,
+ title: searchProps.title,
+ description: searchProps.description,
+ } as DiscoverEmbeddableProps;
+
+ return (
+
+
+ {discoverEmbeddableProps.totalHitCount !== 0 ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+
+ );
+}
diff --git a/src/plugins/discover_legacy/public/application/embeddable/search_embeddable_factory.ts b/src/plugins/discover/public/embeddable/search_embeddable_factory.tsx
similarity index 71%
rename from src/plugins/discover_legacy/public/application/embeddable/search_embeddable_factory.ts
rename to src/plugins/discover/public/embeddable/search_embeddable_factory.tsx
index 9b8c540713ce..8d99b87fbeb2 100644
--- a/src/plugins/discover_legacy/public/application/embeddable/search_embeddable_factory.ts
+++ b/src/plugins/discover/public/embeddable/search_embeddable_factory.tsx
@@ -28,19 +28,17 @@
* under the License.
*/
-import { auto } from 'angular';
import { i18n } from '@osd/i18n';
import { UiActionsStart } from 'src/plugins/ui_actions/public';
-import { getServices } from '../../opensearch_dashboards_services';
+import { getServices } from '../opensearch_dashboards_services';
import {
EmbeddableFactoryDefinition,
Container,
ErrorEmbeddable,
-} from '../../../../embeddable/public';
-
-import { TimeRange } from '../../../../data/public';
-
-import { SearchInput, SearchOutput, SearchEmbeddable } from './types';
+} from '../../../embeddable/public';
+import { TimeRange } from '../../../data/public';
+import { SearchEmbeddable } from './search_embeddable';
+import { SearchInput, SearchOutput } from './types';
import { SEARCH_EMBEDDABLE_TYPE } from './constants';
interface StartServices {
@@ -51,8 +49,6 @@ interface StartServices {
export class SearchEmbeddableFactory
implements EmbeddableFactoryDefinition {
public readonly type = SEARCH_EMBEDDABLE_TYPE;
- private $injector: auto.IInjectorService | null;
- private getInjector: () => Promise | null;
public readonly savedObjectMetaData = {
name: i18n.translate('discover.savedSearch.savedObjectName', {
defaultMessage: 'Saved search',
@@ -61,13 +57,7 @@ export class SearchEmbeddableFactory
getIconForSavedObject: () => 'search',
};
- constructor(
- private getStartServices: () => Promise,
- getInjector: () => Promise
- ) {
- this.$injector = null;
- this.getInjector = getInjector;
- }
+ constructor(private getStartServices: () => Promise) {}
public canCreateNew() {
return false;
@@ -88,32 +78,25 @@ export class SearchEmbeddableFactory
input: Partial & { id: string; timeRange: TimeRange },
parent?: Container
): Promise => {
- if (!this.$injector) {
- this.$injector = await this.getInjector();
- }
- const $injector = this.$injector as auto.IInjectorService;
-
- const $compile = $injector.get('$compile');
- const $rootScope = $injector.get('$rootScope');
- const filterManager = getServices().filterManager;
+ const services = getServices();
+ const filterManager = services.filterManager;
+ const url = await services.getSavedSearchUrlById(savedObjectId);
+ const editUrl = services.addBasePath(`/app/data-explorer/discover${url}`);
- const url = await getServices().getSavedSearchUrlById(savedObjectId);
- const editUrl = getServices().addBasePath(`/app/discover${url}`);
try {
- const savedObject = await getServices().getSavedSearchById(savedObjectId);
+ const savedObject = await services.getSavedSearchById(savedObjectId);
const indexPattern = savedObject.searchSource.getField('index');
const { executeTriggerActions } = await this.getStartServices();
const { SearchEmbeddable: SearchEmbeddableClass } = await import('./search_embeddable');
return new SearchEmbeddableClass(
{
savedSearch: savedObject,
- $rootScope,
- $compile,
editUrl,
editPath: url,
filterManager,
- editable: getServices().capabilities.discover.save as boolean,
+ editable: services.capabilities.discover.save as boolean,
indexPatterns: indexPattern ? [indexPattern] : [],
+ services,
},
input,
executeTriggerActions,
diff --git a/src/plugins/discover_legacy/public/application/embeddable/types.ts b/src/plugins/discover/public/embeddable/types.ts
similarity index 93%
rename from src/plugins/discover_legacy/public/application/embeddable/types.ts
rename to src/plugins/discover/public/embeddable/types.ts
index 864f954588dd..24a1aac92b49 100644
--- a/src/plugins/discover_legacy/public/application/embeddable/types.ts
+++ b/src/plugins/discover/public/embeddable/types.ts
@@ -34,9 +34,9 @@ import {
EmbeddableOutput,
IEmbeddable,
} from 'src/plugins/embeddable/public';
-import { SortOrder } from '../angular/doc_table/components/table_header/helpers';
import { Filter, IIndexPattern, TimeRange, Query } from '../../../../data/public';
-import { SavedSearch } from '../..';
+import { SortOrder } from '../saved_searches/types';
+import { SavedSearch } from '../saved_searches';
export interface SearchInput extends EmbeddableInput {
timeRange: TimeRange;
diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts
index 3bc009914940..164aea1fb5bc 100644
--- a/src/plugins/discover/public/index.ts
+++ b/src/plugins/discover/public/index.ts
@@ -37,7 +37,6 @@ export function plugin(initializerContext: PluginInitializerContext) {
}
export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches';
-// TODO: Fix embeddable after removing Angular
-// export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable';
+
+export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './embeddable';
export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator';
-export { NEW_DISCOVER_APP } from '../common';
diff --git a/src/plugins/discover/public/plugin.ts b/src/plugins/discover/public/plugin.ts
index f1532b6f776b..4d28083b8892 100644
--- a/src/plugins/discover/public/plugin.ts
+++ b/src/plugins/discover/public/plugin.ts
@@ -59,8 +59,8 @@ import {
DISCOVER_APP_URL_GENERATOR,
DiscoverUrlGenerator,
} from './url_generator';
-// import { SearchEmbeddableFactory } from './application/embeddable';
-import { NEW_DISCOVER_APP, PLUGIN_ID } from '../common';
+import { SearchEmbeddableFactory } from './embeddable';
+import { PLUGIN_ID } from '../common';
import { DataExplorerPluginSetup } from '../../data_explorer/public';
import { registerFeature } from './register_feature';
import {
@@ -266,55 +266,45 @@ export class DiscoverPlugin
// This is for instances where the user navigates to the app from the application nav menu
const path = window.location.hash;
- const v2Enabled = await core.uiSettings.get(NEW_DISCOVER_APP);
-
- if (!v2Enabled) {
- navigateToApp('discoverLegacy', {
+ const newPath = migrateUrlState(path);
+ if (newPath.startsWith('#/context') || newPath.startsWith('#/doc')) {
+ const { renderDocView } = await import('./application/components/doc_views');
+ const unmount = renderDocView(params.element);
+ return () => {
+ unmount();
+ };
+ } else {
+ navigateToApp('data-explorer', {
replace: true,
- path,
+ path: `/${PLUGIN_ID}${newPath}`,
});
- } else {
- const newPath = migrateUrlState(path);
- if (newPath.startsWith('#/context') || newPath.startsWith('#/doc')) {
- const { renderDocView } = await import('./application/components/doc_views');
- const unmount = renderDocView(params.element);
- return () => {
- unmount();
- };
- } else {
- navigateToApp('data-explorer', {
- replace: true,
- path: `/${PLUGIN_ID}${newPath}`,
- });
- }
}
return () => {};
},
});
- // TODO: These routes need to be handled for Discover 2.0 to support legacy saved URLS's
- // plugins.urlForwarding.forwardApp('doc', 'discover', (path) => {
- // return `#${path}`;
- // });
- // plugins.urlForwarding.forwardApp('context', 'discover', (path) => {
- // const urlParts = path.split('/');
- // // take care of urls containing legacy url, those split in the following way
- // // ["", "context", indexPatternId, _type, id + params]
- // if (urlParts[4]) {
- // // remove _type part
- // const newPath = [...urlParts.slice(0, 3), ...urlParts.slice(4)].join('/');
- // return `#${newPath}`;
- // }
- // return `#${path}`;
- // });
- // plugins.urlForwarding.forwardApp('discover', 'discover', (path) => {
- // const [, id, tail] = /discover\/([^\?]+)(.*)/.exec(path) || [];
- // if (!id) {
- // return `#${path.replace('/discover', '') || '/'}`;
- // }
- // return `#/view/${id}${tail || ''}`;
- // });
+ plugins.urlForwarding.forwardApp('doc', 'discover', (path) => {
+ return `#${path}`;
+ });
+ plugins.urlForwarding.forwardApp('context', 'discover', (path) => {
+ const urlParts = path.split('/');
+ // take care of urls containing legacy url, those split in the following way
+ // ["", "context", indexPatternId, _type, id + params]
+ if (urlParts[4]) {
+ // remove _type part
+ const newPath = [...urlParts.slice(0, 3), ...urlParts.slice(4)].join('/');
+ return `#${newPath}`;
+ }
+ return `#${path}`;
+ });
+ plugins.urlForwarding.forwardApp('discover', 'discover', (path) => {
+ const [, id, tail] = /discover\/([^\?]+)(.*)/.exec(path) || [];
+ if (!id) {
+ return `#${path.replace('/discover', '') || '/'}`;
+ }
+ return `#/view/${id}${tail || ''}`;
+ });
if (plugins.home) {
registerFeature(plugins.home);
@@ -348,7 +338,7 @@ export class DiscoverPlugin
Context: lazy(() => import('./application/view_components/context')),
});
- // this.registerEmbeddable(core, plugins);
+ this.registerEmbeddable(core, plugins);
return {
docViews: {
@@ -394,9 +384,8 @@ export class DiscoverPlugin
}
}
- // TODO: Use this registration when legacy discover is removed
/**
- * register embeddable with a slimmer embeddable version of inner angular
+ * register embeddable
*/
private registerEmbeddable(core: CoreSetup, plugins: DiscoverSetupPlugins) {
const getStartServices = async () => {
@@ -407,8 +396,7 @@ export class DiscoverPlugin
};
};
- // TODO: Refactor to remove angular
- // const factory = new SearchEmbeddableFactory(getStartServices, this.getEmbeddableInjector);
- // plugins.embeddable.registerEmbeddableFactory(factory.type, factory);
+ const factory = new SearchEmbeddableFactory(getStartServices);
+ plugins.embeddable.registerEmbeddableFactory(factory.type, factory);
}
}
diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts
index 2b35384c2e5c..70eab306e7fb 100644
--- a/src/plugins/discover/server/ui_settings.ts
+++ b/src/plugins/discover/server/ui_settings.ts
@@ -33,7 +33,6 @@ import { schema } from '@osd/config-schema';
import { UiSettingsParams } from 'opensearch-dashboards/server';
import {
- NEW_DISCOVER_APP,
DEFAULT_COLUMNS_SETTING,
SAMPLE_SIZE_SETTING,
AGGS_TERMS_SIZE_SETTING,
@@ -48,17 +47,6 @@ import {
} from '../common';
export const uiSettings: Record = {
- [NEW_DISCOVER_APP]: {
- name: i18n.translate('discover.advancedSettings.legacyToggleTitle', {
- defaultMessage: 'Enable new discover app',
- }),
- value: true,
- description: i18n.translate('discover.advancedSettings.legacyToggleText', {
- defaultMessage: 'Disabling the new discover app will redirect to the legacy app.',
- }),
- category: ['discover'],
- schema: schema.boolean(),
- },
[DEFAULT_COLUMNS_SETTING]: {
name: i18n.translate('discover.advancedSettings.defaultColumnsTitle', {
defaultMessage: 'Default columns',
diff --git a/src/plugins/discover_legacy/README.md b/src/plugins/discover_legacy/README.md
deleted file mode 100644
index a914d651eef3..000000000000
--- a/src/plugins/discover_legacy/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Contains the Discover application and the saved search embeddable.
\ No newline at end of file
diff --git a/src/plugins/discover_legacy/common/index.ts b/src/plugins/discover_legacy/common/index.ts
deleted file mode 100644
index 371442385bbf..000000000000
--- a/src/plugins/discover_legacy/common/index.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export const DEFAULT_COLUMNS_SETTING = 'defaultColumns';
-export const SAMPLE_SIZE_SETTING = 'discover:sampleSize';
-export const AGGS_TERMS_SIZE_SETTING = 'discover:aggs:terms:size';
-export const SORT_DEFAULT_ORDER_SETTING = 'discover:sort:defaultOrder';
-export const SEARCH_ON_PAGE_LOAD_SETTING = 'discover:searchOnPageLoad';
-export const DOC_HIDE_TIME_COLUMN_SETTING = 'doc_table:hideTimeColumn';
-export const FIELDS_LIMIT_SETTING = 'fields:popularLimit';
-export const CONTEXT_DEFAULT_SIZE_SETTING = 'context:defaultSize';
-export const CONTEXT_STEP_SETTING = 'context:step';
-export const CONTEXT_TIE_BREAKER_FIELDS_SETTING = 'context:tieBreakerFields';
-export const MODIFY_COLUMNS_ON_SWITCH = 'discover:modifyColumnsOnSwitch';
diff --git a/src/plugins/discover_legacy/opensearch_dashboards.json b/src/plugins/discover_legacy/opensearch_dashboards.json
deleted file mode 100644
index 6a4259a41d75..000000000000
--- a/src/plugins/discover_legacy/opensearch_dashboards.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "id": "discoverLegacy",
- "version": "opensearchDashboards",
- "server": false,
- "ui": true,
- "requiredPlugins": [
- "charts",
- "data",
- "embeddable",
- "inspector",
- "opensearchDashboardsLegacy",
- "urlForwarding",
- "navigation",
- "uiActions",
- "visualizations"
- ],
- "optionalPlugins": [
- "home",
- "share"
- ],
- "requiredBundles": [
- "opensearchDashboardsUtils",
- "savedObjects",
- "opensearchDashboardsReact",
- "discover"
- ]
-}
\ No newline at end of file
diff --git a/src/plugins/discover_legacy/public/application/_discover.scss b/src/plugins/discover_legacy/public/application/_discover.scss
deleted file mode 100644
index f574357c5ff4..000000000000
--- a/src/plugins/discover_legacy/public/application/_discover.scss
+++ /dev/null
@@ -1,164 +0,0 @@
-.dscAppWrapper {
- display: flex;
- flex-direction: column;
- flex-grow: 1;
- overflow: hidden;
-}
-
-.dscAppContainer {
- > * {
- position: relative;
- }
-}
-
-discover-app {
- flex-grow: 1;
-}
-
-.dscHistogram {
- display: flex;
- height: 200px;
- padding: $euiSizeS;
-}
-
-// SASSTODO: replace the z-index value with a variable
-.dscWrapper {
- padding-left: $euiSizeXL;
- padding-right: $euiSizeS;
- z-index: 1;
-
- @include euiBreakpoint("xs", "s", "m") {
- padding-left: $euiSizeS;
- }
-}
-
-@include euiPanel(".dscWrapper__content");
-
-.dscWrapper__content {
- padding-top: $euiSizeXS;
- background-color: $euiColorEmptyShade;
-
- .osd-table {
- margin-bottom: 0;
- }
-}
-
-.dscTimechart {
- display: block;
- position: relative;
-
- // SASSTODO: the visualizing component should have an option or a modifier
- .series > rect {
- fill-opacity: 0.5;
- stroke-width: 1;
- }
-}
-
-.dscResultCount {
- padding-top: $euiSizeXS;
-}
-
-.dscTimechart__header {
- display: flex;
- justify-content: center;
- min-height: $euiSizeXXL;
- padding: $euiSizeXS 0;
-}
-
-.dscOverlay {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 20;
- padding-top: $euiSizeM;
- opacity: 0.75;
- text-align: center;
- background-color: transparent;
-}
-
-.dscTable {
- overflow: auto;
-
- // SASSTODO: add a monospace modifier to the doc-table component
- .osdDocTable__row {
- font-family: $euiCodeFontFamily;
- font-size: $euiFontSizeXS;
- }
-}
-
-// SASSTODO: replace the padding value with a variable
-.dscTable__footer {
- background-color: $euiColorLightShade;
- padding: 5px 10px;
- text-align: center;
-}
-
-.dscResults {
- h3 {
- margin: -20px 0 10px;
- text-align: center;
- }
-}
-
-.dscResults__interval {
- display: inline-block;
- width: auto;
-}
-
-.dscSkipButton {
- position: absolute;
- right: $euiSizeM;
- top: $euiSizeXS;
-}
-
-.dscTableFixedScroll {
- overflow-x: auto;
- padding-bottom: 0;
-
- + .dscTableFixedScroll__scroller {
- position: fixed;
- bottom: 0;
- overflow-x: auto;
- overflow-y: hidden;
- }
-}
-
-.dscCollapsibleSidebar {
- position: relative;
- z-index: $euiZLevel1;
-
- .dscCollapsibleSidebar__collapseButton {
- position: absolute;
- top: 0;
- right: -$euiSizeXL + 4;
- cursor: pointer;
- z-index: -1;
- min-height: $euiSizeM;
- min-width: $euiSizeM;
- padding: $euiSizeXS * 0.5;
- }
-
- &.closed {
- width: 0 !important;
- border-right-width: 0;
- border-left-width: 0;
-
- .dscCollapsibleSidebar__collapseButton {
- right: -$euiSizeL + 4;
- }
- }
-}
-
-@include euiBreakpoint("xs", "s", "m") {
- .dscCollapsibleSidebar {
- &.closed {
- display: none;
- }
-
- .dscCollapsibleSidebar__collapseButton {
- display: none;
- }
- }
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/_index.scss b/src/plugins/discover_legacy/public/application/angular/_index.scss
deleted file mode 100644
index acc755e4a170..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/_index.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import "directives/index";
-@import "context/index";
diff --git a/src/plugins/discover_legacy/public/application/angular/context.html b/src/plugins/discover_legacy/public/application/angular/context.html
deleted file mode 100644
index 2c8e9a2a5d6f..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/src/plugins/discover_legacy/public/application/angular/context.js b/src/plugins/discover_legacy/public/application/angular/context.js
deleted file mode 100644
index 4757102315c0..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { i18n } from '@osd/i18n';
-import { CONTEXT_DEFAULT_SIZE_SETTING } from '../../../common';
-import { getAngularModule, getServices } from '../../opensearch_dashboards_services';
-import './context_app';
-import { getState } from './context_state';
-import contextAppRouteTemplate from './context.html';
-import { getRootBreadcrumbs } from '../helpers/breadcrumbs';
-
-const k7Breadcrumbs = ($route) => {
- const { indexPattern } = $route.current.locals;
- const { id } = $route.current.params;
-
- return [
- ...getRootBreadcrumbs(),
- {
- text: i18n.translate('discover.context.breadcrumb', {
- defaultMessage: 'Context of {indexPatternTitle}#{docId}',
- values: {
- indexPatternTitle: indexPattern.title,
- docId: id,
- },
- }),
- },
- ];
-};
-
-getAngularModule().config(($routeProvider) => {
- $routeProvider.when('/context/:indexPatternId/:id*', {
- controller: ContextAppRouteController,
- k7Breadcrumbs,
- controllerAs: 'contextAppRoute',
- resolve: {
- indexPattern: ($route, Promise) => {
- const indexPattern = getServices().indexPatterns.get($route.current.params.indexPatternId);
- return Promise.props({ ip: indexPattern });
- },
- },
- template: contextAppRouteTemplate,
- });
-});
-
-function ContextAppRouteController($routeParams, $scope, $route) {
- const filterManager = getServices().filterManager;
- const indexPattern = $route.current.locals.indexPattern.ip;
- const {
- startSync: startStateSync,
- stopSync: stopStateSync,
- appState,
- getFilters,
- setFilters,
- setAppState,
- flushToUrl,
- } = getState({
- defaultStepSize: getServices().uiSettings.get(CONTEXT_DEFAULT_SIZE_SETTING),
- timeFieldName: indexPattern.timeFieldName,
- storeInSessionStorage: getServices().uiSettings.get('state:storeInSessionStorage'),
- history: getServices().history(),
- toasts: getServices().core.notifications.toasts,
- });
- this.state = { ...appState.getState() };
- this.anchorId = decodeURIComponent($routeParams.id);
- this.indexPattern = indexPattern;
- filterManager.setFilters(_.cloneDeep(getFilters()));
- startStateSync();
-
- // take care of parameter changes in UI
- $scope.$watchGroup(
- [
- 'contextAppRoute.state.columns',
- 'contextAppRoute.state.predecessorCount',
- 'contextAppRoute.state.successorCount',
- ],
- (newValues) => {
- const [columns, predecessorCount, successorCount] = newValues;
- if (Array.isArray(columns) && predecessorCount >= 0 && successorCount >= 0) {
- setAppState({ columns, predecessorCount, successorCount });
- flushToUrl(true);
- }
- }
- );
- // take care of parameter filter changes
- const filterObservable = filterManager.getUpdates$().subscribe(() => {
- setFilters(filterManager);
- $route.reload();
- });
-
- $scope.$on('$destroy', () => {
- stopStateSync();
- filterObservable.unsubscribe();
- });
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/NOTES.md b/src/plugins/discover_legacy/public/application/angular/context/NOTES.md
deleted file mode 100644
index 046e15fab327..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/NOTES.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# Discover Context App Implementation Notes
-
-The implementation of this app is intended to exhibit certain desirable
-properties by adhering to a set of *principles*. This document aims to explain
-those and the *concepts* employed to achieve that.
-
-
-## Principles
-
-**Single Source of Truth**: A good user experience depends on the UI displaying
-consistent information across the whole page. To achieve this, there should
-always be a single source of truth for the application's state. In this
-application this is the `ContextAppController::state` object.
-
-**Unidirectional Data Flow**: While a single state promotes rendering
-consistency, it does little to make the state changes easier to reason about.
-To avoid having state mutations scattered all over the code, this app
-implements a unidirectional data flow architecture. That means that the state
-is treated as immutable throughout the application except for actions, which
-may modify it to cause angular to re-render and watches to trigger.
-
-**Unit-Testability**: Creating unit tests for large parts of the UI code is
-made easy by expressing the as much of the logic as possible as
-side-effect-free functions. The only place where side-effects are allowed are
-actions. Due to the nature of AngularJS a certain amount of impure code must be
-employed in some cases, e.g. when dealing with the isolate scope bindings in
-`ContextAppController`.
-
-**Loose Coupling**: An attempt was made to couple the parts that make up this
-app as loosely as possible. This means using pure functions whenever possible
-and isolating the angular directives diligently. To that end, the app has been
-implemented as the independent `ContextApp` directive in [app.js](app.js). It
-does not access the OpenSearch Dashboards `AppState` directly but communicates only via its
-directive properties. The binding of these attributes to the state and thereby
-to the route is performed by the `CreateAppRouteController`in
-[index.js](index.js). Similarly, the `SizePicker` directive only communicates
-with its parent via the passed properties.
-
-
-## Concepts
-
-To adhere to the principles mentioned above, this app borrows some concepts
-from the redux architecture that forms a ciruclar unidirectional data flow:
-
-```
-
- |* create initial state
- v
- +->+
- | v
- | |* state
- | v
- | |* angular templates render state
- | v
- | |* angular calls actions in response to user action/system events
- | v
- | |* actions modify state
- | v
- +--+
-
-```
-
-**State**: The state is the single source of truth at
-`ContextAppController::state` and may only be modified by actions.
-
-**Action**: Actions are functions that are called in response to user or system
-actions and may modified the state the are bound to via their closure.
-
-
-## Directory Structure
-
-**index.js**: Defines the route and renders the `` directive,
-binding it to the `AppState`.
-
-**app.js**: Defines the `` directive, that is at the root of the
-application. Creates the store, reducer and bound actions/selectors.
-
-**query**: Exports the actions, reducers and selectors related to the
-query status and results.
-
-**query_parameters**: Exports the actions, reducers and selectors related to
-the parameters used to construct the query.
-
-**components/action_bar**: Defines the ``
-directive including its respective styles.
-
-
-**api/anchor.js**: Exports `fetchAnchor()` that creates and executes the
-query for the anchor document.
-
-**api/context.js**: Exports `fetchPredecessors()`, `fetchSuccessors()`, `fetchSurroundingDocs()` that
-create and execute the queries for the preceeding and succeeding documents.
-
-**api/utils**: Exports various functions used to create and transform
-queries.
diff --git a/src/plugins/discover_legacy/public/application/angular/context/_index.scss b/src/plugins/discover_legacy/public/application/angular/context/_index.scss
deleted file mode 100644
index 4ac09e25eb9c..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/_index.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-// Prefix all styles with "cxt" to avoid conflicts.
-// Examples
-// cxtChart
-// cxtChart__legend
-// cxtChart__legend--small
-// cxtChart__legend-isLoading
-
-@import "components/action_bar/index";
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/_stubs.js b/src/plugins/discover_legacy/public/application/angular/context/api/_stubs.js
deleted file mode 100644
index 99b531edfc0b..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/_stubs.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon from 'sinon';
-import moment from 'moment';
-
-export function createIndexPatternsStub() {
- return {
- get: sinon.spy((indexPatternId) =>
- Promise.resolve({
- id: indexPatternId,
- isTimeNanosBased: () => false,
- popularizeField: () => {},
- })
- ),
- };
-}
-
-/**
- * A stubbed search source with a `fetch` method that returns all of `_stubHits`.
- */
-export function createSearchSourceStub(hits, timeField) {
- const searchSourceStub = {
- _stubHits: hits,
- _stubTimeField: timeField,
- _createStubHit: (timestamp, tiebreaker = 0) => ({
- [searchSourceStub._stubTimeField]: timestamp,
- sort: [timestamp, tiebreaker],
- }),
- };
-
- searchSourceStub.setParent = sinon.spy(() => searchSourceStub);
- searchSourceStub.setField = sinon.spy(() => searchSourceStub);
-
- searchSourceStub.getField = sinon.spy((key) => {
- const previousSetCall = searchSourceStub.setField.withArgs(key).lastCall;
- return previousSetCall ? previousSetCall.args[1] : null;
- });
-
- searchSourceStub.fetch = sinon.spy(() =>
- Promise.resolve({
- hits: {
- hits: searchSourceStub._stubHits,
- total: searchSourceStub._stubHits.length,
- },
- })
- );
-
- return searchSourceStub;
-}
-
-/**
- * A stubbed search source with a `fetch` method that returns a filtered set of `_stubHits`.
- */
-export function createContextSearchSourceStub(hits, timeField = '@timestamp') {
- const searchSourceStub = createSearchSourceStub(hits, timeField);
-
- searchSourceStub.fetch = sinon.spy(() => {
- const timeField = searchSourceStub._stubTimeField;
- const lastQuery = searchSourceStub.setField.withArgs('query').lastCall.args[1];
- const timeRange = lastQuery.query.bool.must.constant_score.filter.range[timeField];
- const lastSort = searchSourceStub.setField.withArgs('sort').lastCall.args[1];
- const sortDirection = lastSort[0][timeField];
- const sortFunction =
- sortDirection === 'asc'
- ? (first, second) => first[timeField] - second[timeField]
- : (first, second) => second[timeField] - first[timeField];
- const filteredHits = searchSourceStub._stubHits
- .filter(
- (hit) =>
- moment(hit[timeField]).isSameOrAfter(timeRange.gte) &&
- moment(hit[timeField]).isSameOrBefore(timeRange.lte)
- )
- .sort(sortFunction);
-
- return Promise.resolve({
- hits: {
- hits: filteredHits,
- total: filteredHits.length,
- },
- });
- });
-
- return searchSourceStub;
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/anchor.js b/src/plugins/discover_legacy/public/application/angular/context/api/anchor.js
deleted file mode 100644
index 599379e128b0..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/anchor.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { i18n } from '@osd/i18n';
-
-export function fetchAnchorProvider(indexPatterns, searchSource) {
- return async function fetchAnchor(indexPatternId, anchorId, sort) {
- const indexPattern = await indexPatterns.get(indexPatternId);
- searchSource
- .setParent(undefined)
- .setField('index', indexPattern)
- .setField('version', true)
- .setField('size', 1)
- .setField('query', {
- query: {
- constant_score: {
- filter: {
- ids: {
- values: [anchorId],
- },
- },
- },
- },
- language: 'lucene',
- })
- .setField('sort', sort);
-
- const response = await searchSource.fetch();
-
- if (_.get(response, ['hits', 'total'], 0) < 1) {
- throw new Error(
- i18n.translate('discover.context.failedToLoadAnchorDocumentErrorDescription', {
- defaultMessage: 'Failed to load anchor document.',
- })
- );
- }
-
- return {
- ..._.get(response, ['hits', 'hits', 0]),
- $$_isAnchor: true,
- };
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/anchor.test.js b/src/plugins/discover_legacy/public/application/angular/context/api/anchor.test.js
deleted file mode 100644
index 676aabb5c3b8..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/anchor.test.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { createIndexPatternsStub, createSearchSourceStub } from './_stubs';
-
-import { fetchAnchorProvider } from './anchor';
-
-describe('context app', function () {
- describe('function fetchAnchor', function () {
- let fetchAnchor;
- let searchSourceStub;
-
- beforeEach(() => {
- searchSourceStub = createSearchSourceStub([{ _id: 'hit1' }]);
- fetchAnchor = fetchAnchorProvider(createIndexPatternsStub(), searchSourceStub);
- });
-
- it('should use the `fetch` method of the SearchSource', function () {
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(() => {
- expect(searchSourceStub.fetch.calledOnce).toBe(true);
- });
- });
-
- it('should configure the SearchSource to not inherit from the implicit root', function () {
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(() => {
- const setParentSpy = searchSourceStub.setParent;
- expect(setParentSpy.calledOnce).toBe(true);
- expect(setParentSpy.firstCall.args[0]).toBe(undefined);
- });
- });
-
- it('should set the SearchSource index pattern', function () {
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(() => {
- const setFieldSpy = searchSourceStub.setField;
- expect(setFieldSpy.firstCall.args[1].id).toEqual('INDEX_PATTERN_ID');
- });
- });
-
- it('should set the SearchSource version flag to true', function () {
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(() => {
- const setVersionSpy = searchSourceStub.setField.withArgs('version');
- expect(setVersionSpy.calledOnce).toBe(true);
- expect(setVersionSpy.firstCall.args[1]).toEqual(true);
- });
- });
-
- it('should set the SearchSource size to 1', function () {
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(() => {
- const setSizeSpy = searchSourceStub.setField.withArgs('size');
- expect(setSizeSpy.calledOnce).toBe(true);
- expect(setSizeSpy.firstCall.args[1]).toEqual(1);
- });
- });
-
- it('should set the SearchSource query to an ids query', function () {
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(() => {
- const setQuerySpy = searchSourceStub.setField.withArgs('query');
- expect(setQuerySpy.calledOnce).toBe(true);
- expect(setQuerySpy.firstCall.args[1]).toEqual({
- query: {
- constant_score: {
- filter: {
- ids: {
- values: ['id'],
- },
- },
- },
- },
- language: 'lucene',
- });
- });
- });
-
- it('should set the SearchSource sort order', function () {
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(() => {
- const setSortSpy = searchSourceStub.setField.withArgs('sort');
- expect(setSortSpy.calledOnce).toBe(true);
- expect(setSortSpy.firstCall.args[1]).toEqual([{ '@timestamp': 'desc' }, { _doc: 'desc' }]);
- });
- });
-
- it('should reject with an error when no hits were found', function () {
- searchSourceStub._stubHits = [];
-
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then(
- () => {
- expect().fail('expected the promise to be rejected');
- },
- (error) => {
- expect(error).toBeInstanceOf(Error);
- }
- );
- });
-
- it('should return the first hit after adding an anchor marker', function () {
- searchSourceStub._stubHits = [{ property1: 'value1' }, { property2: 'value2' }];
-
- return fetchAnchor('INDEX_PATTERN_ID', 'id', [
- { '@timestamp': 'desc' },
- { _doc: 'desc' },
- ]).then((anchorDocument) => {
- expect(anchorDocument).toHaveProperty('property1', 'value1');
- expect(anchorDocument).toHaveProperty('$$_isAnchor', true);
- });
- });
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/context.predecessors.test.js b/src/plugins/discover_legacy/public/application/angular/context/api/context.predecessors.test.js
deleted file mode 100644
index 52ddc2978ad8..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/context.predecessors.test.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import moment from 'moment';
-import { get, last } from 'lodash';
-import { createIndexPatternsStub, createContextSearchSourceStub } from './_stubs';
-import { fetchContextProvider } from './context';
-import { setServices } from '../../../../opensearch_dashboards_services';
-
-const MS_PER_DAY = 24 * 60 * 60 * 1000;
-const ANCHOR_TIMESTAMP = new Date(MS_PER_DAY).toJSON();
-const ANCHOR_TIMESTAMP_3 = new Date(MS_PER_DAY * 3).toJSON();
-const ANCHOR_TIMESTAMP_1000 = new Date(MS_PER_DAY * 1000).toJSON();
-const ANCHOR_TIMESTAMP_3000 = new Date(MS_PER_DAY * 3000).toJSON();
-
-describe('context app', function () {
- describe('function fetchPredecessors', function () {
- let fetchPredecessors;
- let mockSearchSource;
-
- beforeEach(() => {
- mockSearchSource = createContextSearchSourceStub([], '@timestamp', MS_PER_DAY * 8);
-
- setServices({
- data: {
- search: {
- searchSource: {
- create: jest.fn().mockImplementation(() => mockSearchSource),
- },
- },
- },
- });
-
- fetchPredecessors = (
- indexPatternId,
- timeField,
- sortDir,
- timeValIso,
- timeValNr,
- tieBreakerField,
- tieBreakerValue,
- size
- ) => {
- const anchor = {
- _source: {
- [timeField]: timeValIso,
- },
- sort: [timeValNr, tieBreakerValue],
- };
-
- return fetchContextProvider(createIndexPatternsStub()).fetchSurroundingDocs(
- 'predecessors',
- indexPatternId,
- anchor,
- timeField,
- tieBreakerField,
- sortDir,
- size,
- []
- );
- };
- });
-
- it('should perform exactly one query when enough hits are returned', function () {
- mockSearchSource._stubHits = [
- mockSearchSource._createStubHit(MS_PER_DAY * 3000 + 2),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000 + 1),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000),
- mockSearchSource._createStubHit(MS_PER_DAY * 2000),
- mockSearchSource._createStubHit(MS_PER_DAY * 1000),
- ];
-
- return fetchPredecessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3000,
- MS_PER_DAY * 3000,
- '_doc',
- 0,
- 3,
- []
- ).then((hits) => {
- expect(mockSearchSource.fetch.calledOnce).toBe(true);
- expect(hits).toEqual(mockSearchSource._stubHits.slice(0, 3));
- });
- });
-
- it('should perform multiple queries with the last being unrestricted when too few hits are returned', function () {
- mockSearchSource._stubHits = [
- mockSearchSource._createStubHit(MS_PER_DAY * 3010),
- mockSearchSource._createStubHit(MS_PER_DAY * 3002),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000),
- mockSearchSource._createStubHit(MS_PER_DAY * 2998),
- mockSearchSource._createStubHit(MS_PER_DAY * 2990),
- ];
-
- return fetchPredecessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3000,
- MS_PER_DAY * 3000,
- '_doc',
- 0,
- 6,
- []
- ).then((hits) => {
- const intervals = mockSearchSource.setField.args
- .filter(([property]) => property === 'query')
- .map(([, { query }]) =>
- get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp'])
- );
-
- expect(
- intervals.every(({ gte, lte }) => (gte && lte ? moment(gte).isBefore(lte) : true))
- ).toBe(true);
- // should have started at the given time
- expect(intervals[0].gte).toEqual(moment(MS_PER_DAY * 3000).toISOString());
- // should have ended with a half-open interval
- expect(Object.keys(last(intervals))).toEqual(['format', 'gte']);
- expect(intervals.length).toBeGreaterThan(1);
-
- expect(hits).toEqual(mockSearchSource._stubHits.slice(0, 3));
- });
- });
-
- it('should perform multiple queries until the expected hit count is returned', function () {
- mockSearchSource._stubHits = [
- mockSearchSource._createStubHit(MS_PER_DAY * 1700),
- mockSearchSource._createStubHit(MS_PER_DAY * 1200),
- mockSearchSource._createStubHit(MS_PER_DAY * 1100),
- mockSearchSource._createStubHit(MS_PER_DAY * 1000),
- ];
-
- return fetchPredecessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_1000,
- MS_PER_DAY * 1000,
- '_doc',
- 0,
- 3,
- []
- ).then((hits) => {
- const intervals = mockSearchSource.setField.args
- .filter(([property]) => property === 'query')
- .map(([, { query }]) =>
- get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp'])
- );
-
- // should have started at the given time
- expect(intervals[0].gte).toEqual(moment(MS_PER_DAY * 1000).toISOString());
- // should have stopped before reaching MS_PER_DAY * 1700
- expect(moment(last(intervals).lte).valueOf()).toBeLessThan(MS_PER_DAY * 1700);
- expect(intervals.length).toBeGreaterThan(1);
- expect(hits).toEqual(mockSearchSource._stubHits.slice(-3));
- });
- });
-
- it('should return an empty array when no hits were found', function () {
- return fetchPredecessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3,
- MS_PER_DAY * 3,
- '_doc',
- 0,
- 3,
- []
- ).then((hits) => {
- expect(hits).toEqual([]);
- });
- });
-
- it('should configure the SearchSource to not inherit from the implicit root', function () {
- return fetchPredecessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3,
- MS_PER_DAY * 3,
- '_doc',
- 0,
- 3,
- []
- ).then(() => {
- const setParentSpy = mockSearchSource.setParent;
- expect(setParentSpy.alwaysCalledWith(undefined)).toBe(true);
- expect(setParentSpy.called).toBe(true);
- });
- });
-
- it('should set the tiebreaker sort order to the opposite as the time field', function () {
- return fetchPredecessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP,
- MS_PER_DAY,
- '_doc',
- 0,
- 3,
- []
- ).then(() => {
- expect(
- mockSearchSource.setField.calledWith('sort', [{ '@timestamp': 'asc' }, { _doc: 'asc' }])
- ).toBe(true);
- });
- });
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/context.successors.test.js b/src/plugins/discover_legacy/public/application/angular/context/api/context.successors.test.js
deleted file mode 100644
index 7086495e29e0..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/context.successors.test.js
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import moment from 'moment';
-import { get, last } from 'lodash';
-
-import { createIndexPatternsStub, createContextSearchSourceStub } from './_stubs';
-import { setServices } from '../../../../opensearch_dashboards_services';
-
-import { fetchContextProvider } from './context';
-
-const MS_PER_DAY = 24 * 60 * 60 * 1000;
-const ANCHOR_TIMESTAMP = new Date(MS_PER_DAY).toJSON();
-const ANCHOR_TIMESTAMP_3 = new Date(MS_PER_DAY * 3).toJSON();
-const ANCHOR_TIMESTAMP_3000 = new Date(MS_PER_DAY * 3000).toJSON();
-
-describe('context app', function () {
- describe('function fetchSuccessors', function () {
- let fetchSuccessors;
- let mockSearchSource;
-
- beforeEach(() => {
- mockSearchSource = createContextSearchSourceStub([], '@timestamp');
-
- setServices({
- data: {
- search: {
- searchSource: {
- create: jest.fn().mockImplementation(() => mockSearchSource),
- },
- },
- },
- });
-
- fetchSuccessors = (
- indexPatternId,
- timeField,
- sortDir,
- timeValIso,
- timeValNr,
- tieBreakerField,
- tieBreakerValue,
- size
- ) => {
- const anchor = {
- _source: {
- [timeField]: timeValIso,
- },
- sort: [timeValNr, tieBreakerValue],
- };
-
- return fetchContextProvider(createIndexPatternsStub()).fetchSurroundingDocs(
- 'successors',
- indexPatternId,
- anchor,
- timeField,
- tieBreakerField,
- sortDir,
- size,
- []
- );
- };
- });
-
- it('should perform exactly one query when enough hits are returned', function () {
- mockSearchSource._stubHits = [
- mockSearchSource._createStubHit(MS_PER_DAY * 5000),
- mockSearchSource._createStubHit(MS_PER_DAY * 4000),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 1),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 2),
- ];
-
- return fetchSuccessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3000,
- MS_PER_DAY * 3000,
- '_doc',
- 0,
- 3,
- []
- ).then((hits) => {
- expect(mockSearchSource.fetch.calledOnce).toBe(true);
- expect(hits).toEqual(mockSearchSource._stubHits.slice(-3));
- });
- });
-
- it('should perform multiple queries with the last being unrestricted when too few hits are returned', function () {
- mockSearchSource._stubHits = [
- mockSearchSource._createStubHit(MS_PER_DAY * 3010),
- mockSearchSource._createStubHit(MS_PER_DAY * 3002),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000),
- mockSearchSource._createStubHit(MS_PER_DAY * 2998),
- mockSearchSource._createStubHit(MS_PER_DAY * 2990),
- ];
-
- return fetchSuccessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3000,
- MS_PER_DAY * 3000,
- '_doc',
- 0,
- 6,
- []
- ).then((hits) => {
- const intervals = mockSearchSource.setField.args
- .filter(([property]) => property === 'query')
- .map(([, { query }]) =>
- get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp'])
- );
-
- expect(
- intervals.every(({ gte, lte }) => (gte && lte ? moment(gte).isBefore(lte) : true))
- ).toBe(true);
- // should have started at the given time
- expect(intervals[0].lte).toEqual(moment(MS_PER_DAY * 3000).toISOString());
- // should have ended with a half-open interval
- expect(Object.keys(last(intervals))).toEqual(['format', 'lte']);
- expect(intervals.length).toBeGreaterThan(1);
-
- expect(hits).toEqual(mockSearchSource._stubHits.slice(-3));
- });
- });
-
- it('should perform multiple queries until the expected hit count is returned', function () {
- mockSearchSource._stubHits = [
- mockSearchSource._createStubHit(MS_PER_DAY * 3000),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 1),
- mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 2),
- mockSearchSource._createStubHit(MS_PER_DAY * 2800),
- mockSearchSource._createStubHit(MS_PER_DAY * 2200),
- mockSearchSource._createStubHit(MS_PER_DAY * 1000),
- ];
-
- return fetchSuccessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3000,
- MS_PER_DAY * 3000,
- '_doc',
- 0,
- 4,
- []
- ).then((hits) => {
- const intervals = mockSearchSource.setField.args
- .filter(([property]) => property === 'query')
- .map(([, { query }]) =>
- get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp'])
- );
-
- // should have started at the given time
- expect(intervals[0].lte).toEqual(moment(MS_PER_DAY * 3000).toISOString());
- // should have stopped before reaching MS_PER_DAY * 2200
- expect(moment(last(intervals).gte).valueOf()).toBeGreaterThan(MS_PER_DAY * 2200);
- expect(intervals.length).toBeGreaterThan(1);
-
- expect(hits).toEqual(mockSearchSource._stubHits.slice(0, 4));
- });
- });
-
- it('should return an empty array when no hits were found', function () {
- return fetchSuccessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3,
- MS_PER_DAY * 3,
- '_doc',
- 0,
- 3,
- []
- ).then((hits) => {
- expect(hits).toEqual([]);
- });
- });
-
- it('should configure the SearchSource to not inherit from the implicit root', function () {
- return fetchSuccessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP_3,
- MS_PER_DAY * 3,
- '_doc',
- 0,
- 3,
- []
- ).then(() => {
- const setParentSpy = mockSearchSource.setParent;
- expect(setParentSpy.alwaysCalledWith(undefined)).toBe(true);
- expect(setParentSpy.called).toBe(true);
- });
- });
-
- it('should set the tiebreaker sort order to the same as the time field', function () {
- return fetchSuccessors(
- 'INDEX_PATTERN_ID',
- '@timestamp',
- 'desc',
- ANCHOR_TIMESTAMP,
- MS_PER_DAY,
- '_doc',
- 0,
- 3,
- []
- ).then(() => {
- expect(
- mockSearchSource.setField.calledWith('sort', [{ '@timestamp': 'desc' }, { _doc: 'desc' }])
- ).toBe(true);
- });
- });
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/context.ts b/src/plugins/discover_legacy/public/application/angular/context/api/context.ts
deleted file mode 100644
index 046438f08339..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/context.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Filter, IndexPatternsContract, IndexPattern } from 'src/plugins/data/public';
-import { reverseSortDir, SortDirection } from './utils/sorting';
-import { extractNanos, convertIsoToMillis } from './utils/date_conversion';
-import { fetchHitsInInterval } from './utils/fetch_hits_in_interval';
-import { generateIntervals } from './utils/generate_intervals';
-import { getOpenSearchQuerySearchAfter } from './utils/get_opensearch_query_search_after';
-import { getOpenSearchQuerySort } from './utils/get_opensearch_query_sort';
-import { getServices } from '../../../../opensearch_dashboards_services';
-
-export type SurrDocType = 'successors' | 'predecessors';
-export interface OpenSearchHitRecord {
- fields: Record;
- sort: number[];
- _source: Record;
- _id: string;
-}
-export type OpenSearchHitRecordList = OpenSearchHitRecord[];
-
-const DAY_MILLIS = 24 * 60 * 60 * 1000;
-
-// look from 1 day up to 10000 days into the past and future
-const LOOKUP_OFFSETS = [0, 1, 7, 30, 365, 10000].map((days) => days * DAY_MILLIS);
-
-function fetchContextProvider(indexPatterns: IndexPatternsContract) {
- return {
- fetchSurroundingDocs,
- };
-
- /**
- * Fetch successor or predecessor documents of a given anchor document
- *
- * @param {SurrDocType} type - `successors` or `predecessors`
- * @param {string} indexPatternId
- * @param {OpenSearchHitRecord} anchor - anchor record
- * @param {string} timeField - name of the timefield, that's sorted on
- * @param {string} tieBreakerField - name of the tie breaker, the 2nd sort field
- * @param {SortDirection} sortDir - direction of sorting
- * @param {number} size - number of records to retrieve
- * @param {Filter[]} filters - to apply in the query
- * @returns {Promise}
- */
- async function fetchSurroundingDocs(
- type: SurrDocType,
- indexPatternId: string,
- anchor: OpenSearchHitRecord,
- timeField: string,
- tieBreakerField: string,
- sortDir: SortDirection,
- size: number,
- filters: Filter[]
- ) {
- if (typeof anchor !== 'object' || anchor === null || !size) {
- return [];
- }
- const indexPattern = await indexPatterns.get(indexPatternId);
- const searchSource = await createSearchSource(indexPattern, filters);
- const sortDirToApply = type === 'successors' ? sortDir : reverseSortDir(sortDir);
-
- const nanos = indexPattern.isTimeNanosBased() ? extractNanos(anchor._source[timeField]) : '';
- const timeValueMillis =
- nanos !== '' ? convertIsoToMillis(anchor._source[timeField]) : anchor.sort[0];
-
- const intervals = generateIntervals(LOOKUP_OFFSETS, timeValueMillis, type, sortDir);
- let documents: OpenSearchHitRecordList = [];
-
- for (const interval of intervals) {
- const remainingSize = size - documents.length;
-
- if (remainingSize <= 0) {
- break;
- }
-
- const searchAfter = getOpenSearchQuerySearchAfter(type, documents, timeField, anchor, nanos);
-
- const sort = getOpenSearchQuerySort(timeField, tieBreakerField, sortDirToApply);
-
- const hits = await fetchHitsInInterval(
- searchSource,
- timeField,
- sort,
- sortDirToApply,
- interval,
- searchAfter,
- remainingSize,
- nanos,
- anchor._id
- );
-
- documents =
- type === 'successors' ? [...documents, ...hits] : [...hits.slice().reverse(), ...documents];
- }
-
- return documents;
- }
-
- async function createSearchSource(indexPattern: IndexPattern, filters: Filter[]) {
- const { data } = getServices();
-
- const searchSource = await data.search.searchSource.create();
- return searchSource
- .setParent(undefined)
- .setField('index', indexPattern)
- .setField('filter', filters);
- }
-}
-
-export { fetchContextProvider };
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/date_conversion.test.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/date_conversion.test.ts
deleted file mode 100644
index fe1a18bf938f..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/date_conversion.test.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { extractNanos } from './date_conversion';
-
-describe('function extractNanos', function () {
- test('extract nanos of 2014-01-01', function () {
- expect(extractNanos('2014-01-01')).toBe('000000000');
- });
- test('extract nanos of 2014-01-01T12:12:12.234Z', function () {
- expect(extractNanos('2014-01-01T12:12:12.234Z')).toBe('234000000');
- });
- test('extract nanos of 2014-01-01T12:12:12.234123321Z', function () {
- expect(extractNanos('2014-01-01T12:12:12.234123321Z')).toBe('234123321');
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/date_conversion.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/date_conversion.ts
deleted file mode 100644
index 8f4bfb30375d..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/date_conversion.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import moment from 'moment';
-/**
- * extract nanoseconds if available in ISO timestamp
- * returns the nanos as string like this:
- * 9ns -> 000000009
- * 10000ns -> 0000010000
- * returns 000000000 for invalid timestamps or timestamps with just date
- **/
-export function extractNanos(timeFieldValue: string = ''): string {
- const fieldParts = timeFieldValue.split('.');
- const fractionSeconds = fieldParts.length === 2 ? fieldParts[1].replace('Z', '') : '';
- return fractionSeconds.length !== 9 ? fractionSeconds.padEnd(9, '0') : fractionSeconds;
-}
-
-/**
- * convert an iso formatted string to number of milliseconds since
- * 1970-01-01T00:00:00.000Z
- * @param {string} isoValue
- * @returns {number}
- */
-export function convertIsoToMillis(isoValue: string): number {
- const date = new Date(isoValue);
- return date.getTime();
-}
-/**
- * the given time value in milliseconds is converted to a ISO formatted string
- * if nanosValue is provided, the given value replaces the fractional seconds part
- * of the formated string since moment.js doesn't support formatting timestamps
- * with a higher precision then microseconds
- * The browser rounds date nanos values:
- * 2019-09-18T06:50:12.999999999 -> browser rounds to 1568789413000000000
- * 2019-09-18T06:50:59.999999999 -> browser rounds to 1568789460000000000
- * 2017-12-31T23:59:59.999999999 -> browser rounds 1514761199999999999 to 1514761200000000000
- */
-export function convertTimeValueToIso(timeValueMillis: number, nanosValue: string): string | null {
- if (!timeValueMillis) {
- return null;
- }
- const isoString = moment(timeValueMillis).toISOString();
- if (!isoString) {
- return null;
- } else if (nanosValue !== '') {
- return `${isoString.substring(0, isoString.length - 4)}${nanosValue}Z`;
- }
- return isoString;
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/fetch_hits_in_interval.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/fetch_hits_in_interval.ts
deleted file mode 100644
index 262b64ba8c15..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/fetch_hits_in_interval.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import {
- ISearchSource,
- OpenSearchQuerySortValue,
- SortDirection,
-} from '../../../../../../../data/public';
-import { convertTimeValueToIso } from './date_conversion';
-import { OpenSearchHitRecordList, OpenSearchHitRecord } from '../context';
-import { IntervalValue } from './generate_intervals';
-import { OpenSearchQuerySearchAfter } from './get_opensearch_query_search_after';
-
-interface RangeQuery {
- format: string;
- lte?: string | null;
- gte?: string | null;
-}
-
-/**
- * Fetch the hits between a given `interval` up to a maximum of `maxCount` documents.
- * The documents are sorted by `sort`
- *
- * The `searchSource` is assumed to have the appropriate index pattern
- * and filters set.
- */
-export async function fetchHitsInInterval(
- searchSource: ISearchSource,
- timeField: string,
- sort: [OpenSearchQuerySortValue, OpenSearchQuerySortValue],
- sortDir: SortDirection,
- interval: IntervalValue[],
- searchAfter: OpenSearchQuerySearchAfter,
- maxCount: number,
- nanosValue: string,
- anchorId: string
-): Promise {
- const range: RangeQuery = {
- format: 'strict_date_optional_time',
- };
- const [start, stop] = interval;
-
- if (start) {
- range[sortDir === SortDirection.asc ? 'gte' : 'lte'] = convertTimeValueToIso(start, nanosValue);
- }
-
- if (stop) {
- range[sortDir === SortDirection.asc ? 'lte' : 'gte'] = convertTimeValueToIso(stop, nanosValue);
- }
- const response = await searchSource
- .setField('size', maxCount)
- .setField('query', {
- query: {
- bool: {
- must: {
- constant_score: {
- filter: {
- range: {
- [timeField]: range,
- },
- },
- },
- },
- must_not: {
- ids: {
- values: [anchorId],
- },
- },
- },
- },
- language: 'lucene',
- })
- .setField('searchAfter', searchAfter)
- .setField('sort', sort)
- .setField('version', true)
- .fetch();
-
- // TODO: There's a difference in the definition of SearchResponse and OpenSearchHitRecord
- return ((response.hits?.hits as unknown) as OpenSearchHitRecord[]) || [];
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/generate_intervals.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/generate_intervals.ts
deleted file mode 100644
index fda2e23eb234..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/generate_intervals.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { SortDirection } from '../../../../../../../data/public';
-
-export type IntervalValue = number | null;
-
-/**
- * Generate a sequence of pairs from the iterable that looks like
- * `[[x_0, x_1], [x_1, x_2], [x_2, x_3], ..., [x_(n-1), x_n]]`.
- */
-export function* asPairs(iterable: Iterable): IterableIterator {
- let currentPair: IntervalValue[] = [];
- for (const value of iterable) {
- currentPair = [...currentPair, value].slice(-2);
- if (currentPair.length === 2) {
- yield currentPair;
- }
- }
-}
-
-/**
- * Returns a iterable containing intervals `[start,end]` for OpenSearch date range queries
- * depending on type (`successors` or `predecessors`) and sort (`asc`, `desc`) these are ascending or descending intervals.
- */
-export function generateIntervals(
- offsets: number[],
- startTime: number,
- type: string,
- sort: SortDirection
-): IterableIterator {
- const offsetSign =
- (sort === SortDirection.asc && type === 'successors') ||
- (sort === SortDirection.desc && type === 'predecessors')
- ? 1
- : -1;
- // ending with `null` opens the last interval
- return asPairs([...offsets.map((offset) => startTime + offset * offsetSign), null]);
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/get_opensearch_query_search_after.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/get_opensearch_query_search_after.ts
deleted file mode 100644
index eb6a5af565ba..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/get_opensearch_query_search_after.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { SurrDocType, OpenSearchHitRecordList, OpenSearchHitRecord } from '../context';
-
-export type OpenSearchQuerySearchAfter = [string | number, string | number];
-
-/**
- * Get the searchAfter query value for opensearch
- * When there are already documents available, which means successors or predecessors
- * were already fetched, the new searchAfter for the next fetch has to be the sort value
- * of the first (prececessor), or last (successor) of the list
- */
-export function getOpenSearchQuerySearchAfter(
- type: SurrDocType,
- documents: OpenSearchHitRecordList,
- timeFieldName: string,
- anchor: OpenSearchHitRecord,
- nanoSeconds: string
-): OpenSearchQuerySearchAfter {
- if (documents.length) {
- // already surrounding docs -> first or last record is used
- const afterTimeRecIdx = type === 'successors' && documents.length ? documents.length - 1 : 0;
- const afterTimeDoc = documents[afterTimeRecIdx];
- const afterTimeValue = nanoSeconds ? afterTimeDoc._source[timeFieldName] : afterTimeDoc.sort[0];
- return [afterTimeValue, afterTimeDoc.sort[1]];
- }
- // if data_nanos adapt timestamp value for sorting, since numeric value was rounded by browser
- // OpenSearch search_after also works when number is provided as string
- return [nanoSeconds ? anchor._source[timeFieldName] : anchor.sort[0], anchor.sort[1]];
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/get_opensearch_query_sort.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/get_opensearch_query_sort.ts
deleted file mode 100644
index 30c4888fa438..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/get_opensearch_query_sort.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import {
- OpenSearchQuerySortValue,
- SortDirection,
-} from '../../../../../opensearch_dashboards_services';
-
-/**
- * Returns `OpenSearchQuerySort` which is used to sort records in the OpenSearch query
- * https://opensearch.org/docs/latest/opensearch/ux/#sort-results
- * @param timeField
- * @param tieBreakerField
- * @param sortDir
- */
-export function getOpenSearchQuerySort(
- timeField: string,
- tieBreakerField: string,
- sortDir: SortDirection
-): [OpenSearchQuerySortValue, OpenSearchQuerySortValue] {
- return [{ [timeField]: sortDir }, { [tieBreakerField]: sortDir }];
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/sorting.test.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/sorting.test.ts
deleted file mode 100644
index 6944591d40cd..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/sorting.test.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { reverseSortDir, SortDirection } from './sorting';
-
-describe('function reverseSortDir', function () {
- test('reverse a given sort direction', function () {
- expect(reverseSortDir(SortDirection.asc)).toBe(SortDirection.desc);
- expect(reverseSortDir(SortDirection.desc)).toBe(SortDirection.asc);
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/api/utils/sorting.ts b/src/plugins/discover_legacy/public/application/angular/context/api/utils/sorting.ts
deleted file mode 100644
index 52b6df12e467..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/api/utils/sorting.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { IndexPattern } from '../../../../../opensearch_dashboards_services';
-
-export enum SortDirection {
- asc = 'asc',
- desc = 'desc',
-}
-
-/**
- * The list of field names that are allowed for sorting, but not included in
- * index pattern fields.
- */
-const META_FIELD_NAMES: string[] = ['_seq_no', '_doc', '_uid'];
-
-/**
- * Returns a field from the intersection of the set of sortable fields in the
- * given index pattern and a given set of candidate field names.
- */
-export function getFirstSortableField(indexPattern: IndexPattern, fieldNames: string[]) {
- const sortableFields = fieldNames.filter(
- (fieldName) =>
- META_FIELD_NAMES.includes(fieldName) ||
- // @ts-ignore
- (indexPattern.fields.getByName(fieldName) || { sortable: false }).sortable
- );
- return sortableFields[0];
-}
-
-/**
- * Return the reversed sort direction.
- */
-export function reverseSortDir(sortDirection: SortDirection) {
- return sortDirection === SortDirection.asc ? SortDirection.desc : SortDirection.asc;
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/_action_bar.scss b/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/_action_bar.scss
deleted file mode 100644
index da0911c3a452..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/_action_bar.scss
+++ /dev/null
@@ -1,10 +0,0 @@
-.cxtSizePicker {
- text-align: center;
- width: $euiSize * 5;
-
- &::-webkit-outer-spin-button,
- &::-webkit-inner-spin-button {
- appearance: none; // Hide increment and decrement buttons for type="number" input.
- margin: 0;
- }
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/_index.scss b/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/_index.scss
deleted file mode 100644
index 40a446220577..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/_index.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "action_bar";
diff --git a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar.test.tsx b/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar.test.tsx
deleted file mode 100644
index 2f7cc40b7d9a..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar.test.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-import { mountWithIntl } from 'test_utils/enzyme_helpers';
-import { ActionBar, ActionBarProps } from './action_bar';
-import { findTestSubject } from 'test_utils/helpers';
-import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from '../../query_parameters/constants';
-
-describe('Test Discover Context ActionBar for successor | predecessor records', () => {
- ['successors', 'predecessors'].forEach((type) => {
- const onChangeCount = jest.fn();
- const props = {
- defaultStepSize: 5,
- docCount: 20,
- docCountAvailable: 0,
- isDisabled: false,
- isLoading: false,
- onChangeCount,
- type,
- } as ActionBarProps;
- const wrapper = mountWithIntl( );
-
- const input = findTestSubject(wrapper, `${type}CountPicker`);
- const btn = findTestSubject(wrapper, `${type}LoadMoreButton`);
-
- test(`${type}: Load button click`, () => {
- btn.simulate('click');
- expect(onChangeCount).toHaveBeenCalledWith(25);
- });
-
- test(`${type}: Load button click doesnt submit when MAX_CONTEXT_SIZE was reached`, () => {
- onChangeCount.mockClear();
- input.simulate('change', { target: { valueAsNumber: MAX_CONTEXT_SIZE } });
- btn.simulate('click');
- expect(onChangeCount).toHaveBeenCalledTimes(0);
- });
-
- test(`${type}: Count input change submits on blur`, () => {
- input.simulate('change', { target: { valueAsNumber: 123 } });
- input.simulate('blur');
- expect(onChangeCount).toHaveBeenCalledWith(123);
- });
-
- test(`${type}: Count input change submits on return`, () => {
- input.simulate('change', { target: { valueAsNumber: 124 } });
- input.simulate('submit');
- expect(onChangeCount).toHaveBeenCalledWith(124);
- });
-
- test(`${type}: Count input doesnt submits values higher than MAX_CONTEXT_SIZE `, () => {
- onChangeCount.mockClear();
- input.simulate('change', { target: { valueAsNumber: MAX_CONTEXT_SIZE + 1 } });
- input.simulate('submit');
- expect(onChangeCount).toHaveBeenCalledTimes(0);
- });
-
- test(`${type}: Count input doesnt submits values lower than MIN_CONTEXT_SIZE `, () => {
- onChangeCount.mockClear();
- input.simulate('change', { target: { valueAsNumber: MIN_CONTEXT_SIZE - 1 } });
- input.simulate('submit');
- expect(onChangeCount).toHaveBeenCalledTimes(0);
- });
-
- test(`${type}: Warning about limitation of additional records`, () => {
- if (type === 'predecessors') {
- expect(findTestSubject(wrapper, 'predecessorsWarningMsg').text()).toBe(
- 'No documents newer than the anchor could be found.'
- );
- } else {
- expect(findTestSubject(wrapper, 'successorsWarningMsg').text()).toBe(
- 'No documents older than the anchor could be found.'
- );
- }
- });
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar.tsx b/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar.tsx
deleted file mode 100644
index 8a4b0b308047..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar.tsx
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React, { useState } from 'react';
-import { i18n } from '@osd/i18n';
-import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
-import {
- EuiButtonEmpty,
- EuiFieldNumber,
- EuiFlexGroup,
- EuiFlexItem,
- EuiFormRow,
- EuiSpacer,
-} from '@elastic/eui';
-import { ActionBarWarning } from './action_bar_warning';
-import { SurrDocType } from '../../api/context';
-import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from '../../query_parameters/constants';
-
-export interface ActionBarProps {
- /**
- * the number of documents fetched initially and added when the load button is clicked
- */
- defaultStepSize: number;
- /**
- * the number of docs to be displayed
- */
- docCount: number;
- /**
- * the number of documents that are available
- * display warning when it's lower than docCount
- */
- docCountAvailable: number;
- /**
- * is true while the anchor record is fetched
- */
- isDisabled: boolean;
- /**
- * is true when list entries are fetched
- */
- isLoading: boolean;
- /**
- * is triggered when the input containing count is changed
- * @param count
- */
- onChangeCount: (count: number) => void;
- /**
- * can be `predecessors` or `successors`, usage in context:
- * predecessors action bar + records (these are newer records)
- * anchor record
- * successors records + action bar (these are older records)
- */
- type: SurrDocType;
-}
-
-export function ActionBar({
- defaultStepSize,
- docCount,
- docCountAvailable,
- isDisabled,
- isLoading,
- onChangeCount,
- type,
-}: ActionBarProps) {
- const showWarning = !isDisabled && !isLoading && docCountAvailable < docCount;
- const isSuccessor = type === 'successors';
- const [newDocCount, setNewDocCount] = useState(docCount);
- const isValid = (value: number) => value >= MIN_CONTEXT_SIZE && value <= MAX_CONTEXT_SIZE;
- const onSubmit = (ev: React.FormEvent) => {
- ev.preventDefault();
- if (newDocCount !== docCount && isValid(newDocCount)) {
- onChangeCount(newDocCount);
- }
- };
-
- return (
-
-
-
- );
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar_directive.ts b/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar_directive.ts
deleted file mode 100644
index 3aa62e72353e..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar_directive.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { getAngularModule } from '../../../../../opensearch_dashboards_services';
-import { ActionBar } from './action_bar';
-
-getAngularModule().directive('contextActionBar', function (reactDirective: any) {
- return reactDirective(ActionBar);
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar_warning.tsx b/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar_warning.tsx
deleted file mode 100644
index cfdc3cc0c8cc..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/action_bar_warning.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-import { FormattedMessage } from '@osd/i18n/react';
-import { EuiCallOut } from '@elastic/eui';
-import { SurrDocType } from '../../api/context';
-
-export function ActionBarWarning({ docCount, type }: { docCount: number; type: SurrDocType }) {
- if (type === 'predecessors') {
- return (
-
- ) : (
-
- )
- }
- size="s"
- />
- );
- }
-
- return (
-
- ) : (
-
- )
- }
- size="s"
- />
- );
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/index.ts b/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/index.ts
deleted file mode 100644
index 1e3799d2121a..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/components/action_bar/index.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './action_bar_directive';
diff --git a/src/plugins/discover_legacy/public/application/angular/context/helpers/call_after_bindings_workaround.js b/src/plugins/discover_legacy/public/application/angular/context/helpers/call_after_bindings_workaround.js
deleted file mode 100644
index 455cc57b3d4d..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/helpers/call_after_bindings_workaround.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * WHAT NEEDS THIS WORKAROUND?
- * ===========================
- * Any directive that meets all of the following criteria:
- * - uses isolate scope bindings
- * - sets `bindToController: true`
- * - synchronously accesses the bound values in the controller constructor
- *
- *
- *
- * HOW DO I GET RID OF IT?
- * =======================
- * The quick band-aid solution:
- * Wrap your constructor logic so it doesn't access bound values
- * synchronously. This can have subtle bugs which is why I didn't
- * just wrap all of the offenders in $timeout() and made this
- * workaround instead.
- *
- * The more complete solution:
- * Use the new component lifecycle methods, like `$onInit()`, to access
- * bindings immediately after the constructor is called, which shouldn't
- * have any observable effect outside of the constructor.
- *
- * NOTE: `$onInit()` is not dependency injected, if you need controller specific
- * dependencies like `$scope` then you're probably using watchers and should
- * take a look at the new one-way data flow facilities available to
- * directives/components:
- *
- * https://docs.angularjs.org/guide/component#component-based-application-architecture
- *
- */
-
-export function callAfterBindingsWorkaround(constructor) {
- return function InitAfterBindingsWrapper($injector, $attrs, $element, $scope, $transclude) {
- this.$onInit = () => {
- $injector.invoke(constructor, this, {
- $attrs,
- $element,
- $scope,
- $transclude,
- });
- };
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query/actions.js b/src/plugins/discover_legacy/public/application/angular/context/query/actions.js
deleted file mode 100644
index d4b4f9ba9977..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query/actions.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { i18n } from '@osd/i18n';
-import React from 'react';
-import { getServices } from '../../../../opensearch_dashboards_services';
-
-import { fetchAnchorProvider } from '../api/anchor';
-import { fetchContextProvider } from '../api/context';
-import { getQueryParameterActions } from '../query_parameters';
-import { FAILURE_REASONS, LOADING_STATUS } from './constants';
-import { MarkdownSimple } from '../../../../../../opensearch_dashboards_react/public';
-
-export function QueryActionsProvider(Promise) {
- const { filterManager, indexPatterns, data } = getServices();
- const fetchAnchor = fetchAnchorProvider(indexPatterns, data.search.searchSource.createEmpty());
- const { fetchSurroundingDocs } = fetchContextProvider(indexPatterns);
- const { setPredecessorCount, setQueryParameters, setSuccessorCount } = getQueryParameterActions(
- filterManager,
- indexPatterns
- );
-
- const setFailedStatus = (state) => (subject, details = {}) =>
- (state.loadingStatus[subject] = {
- status: LOADING_STATUS.FAILED,
- reason: FAILURE_REASONS.UNKNOWN,
- ...details,
- });
-
- const setLoadedStatus = (state) => (subject) =>
- (state.loadingStatus[subject] = {
- status: LOADING_STATUS.LOADED,
- });
-
- const setLoadingStatus = (state) => (subject) =>
- (state.loadingStatus[subject] = {
- status: LOADING_STATUS.LOADING,
- });
-
- const fetchAnchorRow = (state) => () => {
- const {
- queryParameters: { indexPatternId, anchorId, sort, tieBreakerField },
- } = state;
-
- if (!tieBreakerField) {
- return Promise.reject(
- setFailedStatus(state)('anchor', {
- reason: FAILURE_REASONS.INVALID_TIEBREAKER,
- })
- );
- }
-
- setLoadingStatus(state)('anchor');
-
- return Promise.try(() =>
- fetchAnchor(indexPatternId, anchorId, [_.fromPairs([sort]), { [tieBreakerField]: sort[1] }])
- ).then(
- (anchorDocument) => {
- setLoadedStatus(state)('anchor');
- state.rows.anchor = anchorDocument;
- return anchorDocument;
- },
- (error) => {
- setFailedStatus(state)('anchor', { error });
- getServices().toastNotifications.addDanger({
- title: i18n.translate('discover.context.unableToLoadAnchorDocumentDescription', {
- defaultMessage: 'Unable to load the anchor document',
- }),
- text: {error.message} ,
- });
- throw error;
- }
- );
- };
-
- const fetchSurroundingRows = (type, state) => {
- const {
- queryParameters: { indexPatternId, sort, tieBreakerField },
- rows: { anchor },
- } = state;
- const filters = getServices().filterManager.getFilters();
-
- const count =
- type === 'successors'
- ? state.queryParameters.successorCount
- : state.queryParameters.predecessorCount;
-
- if (!tieBreakerField) {
- return Promise.reject(
- setFailedStatus(state)(type, {
- reason: FAILURE_REASONS.INVALID_TIEBREAKER,
- })
- );
- }
-
- setLoadingStatus(state)(type);
- const [sortField, sortDir] = sort;
-
- return Promise.try(() =>
- fetchSurroundingDocs(
- type,
- indexPatternId,
- anchor,
- sortField,
- tieBreakerField,
- sortDir,
- count,
- filters
- )
- ).then(
- (documents) => {
- setLoadedStatus(state)(type);
- state.rows[type] = documents;
- return documents;
- },
- (error) => {
- setFailedStatus(state)(type, { error });
- getServices().toastNotifications.addDanger({
- title: i18n.translate('discover.context.unableToLoadDocumentDescription', {
- defaultMessage: 'Unable to load documents',
- }),
- text: {error.message} ,
- });
- throw error;
- }
- );
- };
-
- const fetchContextRows = (state) => () =>
- Promise.all([
- fetchSurroundingRows('predecessors', state),
- fetchSurroundingRows('successors', state),
- ]);
-
- const fetchAllRows = (state) => () =>
- Promise.try(fetchAnchorRow(state)).then(fetchContextRows(state));
-
- const fetchContextRowsWithNewQueryParameters = (state) => (queryParameters) => {
- setQueryParameters(state)(queryParameters);
- return fetchContextRows(state)();
- };
-
- const fetchAllRowsWithNewQueryParameters = (state) => (queryParameters) => {
- setQueryParameters(state)(queryParameters);
- return fetchAllRows(state)();
- };
-
- const fetchGivenPredecessorRows = (state) => (count) => {
- setPredecessorCount(state)(count);
- return fetchSurroundingRows('predecessors', state);
- };
-
- const fetchGivenSuccessorRows = (state) => (count) => {
- setSuccessorCount(state)(count);
- return fetchSurroundingRows('successors', state);
- };
-
- const setAllRows = (state) => (predecessorRows, anchorRow, successorRows) =>
- (state.rows.all = [
- ...(predecessorRows || []),
- ...(anchorRow ? [anchorRow] : []),
- ...(successorRows || []),
- ]);
-
- return {
- fetchAllRows,
- fetchAllRowsWithNewQueryParameters,
- fetchAnchorRow,
- fetchContextRows,
- fetchContextRowsWithNewQueryParameters,
- fetchGivenPredecessorRows,
- fetchGivenSuccessorRows,
- setAllRows,
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query/constants.js b/src/plugins/discover_legacy/public/application/angular/context/query/constants.js
deleted file mode 100644
index 99039d463b5b..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query/constants.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export const FAILURE_REASONS = {
- UNKNOWN: 'unknown',
- INVALID_TIEBREAKER: 'invalid_tiebreaker',
-};
-
-export const LOADING_STATUS = {
- FAILED: 'failed',
- LOADED: 'loaded',
- LOADING: 'loading',
- UNINITIALIZED: 'uninitialized',
-};
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query/index.js b/src/plugins/discover_legacy/public/application/angular/context/query/index.js
deleted file mode 100644
index cbb0a7484ea7..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query/index.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { QueryActionsProvider } from './actions';
-export { FAILURE_REASONS, LOADING_STATUS } from './constants';
-export { createInitialLoadingStatusState } from './state';
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query/state.js b/src/plugins/discover_legacy/public/application/angular/context/query/state.js
deleted file mode 100644
index 7a38ea8ebe3a..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query/state.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { LOADING_STATUS } from './constants';
-
-export function createInitialLoadingStatusState() {
- return {
- anchor: LOADING_STATUS.UNINITIALIZED,
- predecessors: LOADING_STATUS.UNINITIALIZED,
- successors: LOADING_STATUS.UNINITIALIZED,
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/actions.js b/src/plugins/discover_legacy/public/application/angular/context/query_parameters/actions.js
deleted file mode 100644
index f191d7c0d5a2..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/actions.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { opensearchFilters } from '../../../../../../data/public';
-import { popularizeField } from '../../../helpers/popularize_field';
-
-import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE, QUERY_PARAMETER_KEYS } from './constants';
-
-export function getQueryParameterActions(filterManager, indexPatterns) {
- const setPredecessorCount = (state) => (predecessorCount) =>
- (state.queryParameters.predecessorCount = clamp(
- MIN_CONTEXT_SIZE,
- MAX_CONTEXT_SIZE,
- predecessorCount
- ));
-
- const setSuccessorCount = (state) => (successorCount) =>
- (state.queryParameters.successorCount = clamp(
- MIN_CONTEXT_SIZE,
- MAX_CONTEXT_SIZE,
- successorCount
- ));
-
- const setQueryParameters = (state) => (queryParameters) =>
- Object.assign(state.queryParameters, _.pick(queryParameters, QUERY_PARAMETER_KEYS));
-
- const updateFilters = () => (filters) => {
- filterManager.setFilters(filters);
- };
-
- const addFilter = (state) => async (field, values, operation) => {
- const indexPatternId = state.queryParameters.indexPatternId;
- const newFilters = opensearchFilters.generateFilters(
- filterManager,
- field,
- values,
- operation,
- indexPatternId
- );
- filterManager.addFilters(newFilters);
- if (indexPatterns) {
- const indexPattern = await indexPatterns.get(indexPatternId);
- await popularizeField(indexPattern, field.name, indexPatterns);
- }
- };
-
- return {
- addFilter,
- updateFilters,
- setPredecessorCount,
- setQueryParameters,
- setSuccessorCount,
- };
-}
-
-function clamp(minimum, maximum, value) {
- return Math.max(Math.min(maximum, value), minimum);
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/actions.test.ts b/src/plugins/discover_legacy/public/application/angular/context/query_parameters/actions.test.ts
deleted file mode 100644
index 2e3c69a32ff6..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/actions.test.ts
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// @ts-ignore
-import { getQueryParameterActions } from './actions';
-import { FilterManager } from '../../../../../../data/public';
-import { coreMock } from '../../../../../../../core/public/mocks';
-const setupMock = coreMock.createSetup();
-
-let state: {
- queryParameters: {
- defaultStepSize: number;
- indexPatternId: string;
- predecessorCount: number;
- successorCount: number;
- };
-};
-let filterManager: FilterManager;
-let filterManagerSpy: jest.SpyInstance;
-
-beforeEach(() => {
- filterManager = new FilterManager(setupMock.uiSettings);
- filterManagerSpy = jest.spyOn(filterManager, 'addFilters');
-
- state = {
- queryParameters: {
- defaultStepSize: 3,
- indexPatternId: 'INDEX_PATTERN_ID',
- predecessorCount: 10,
- successorCount: 10,
- },
- };
-});
-
-describe('context query_parameter actions', function () {
- describe('action addFilter', () => {
- it('should pass the given arguments to the filterManager', () => {
- const { addFilter } = getQueryParameterActions(filterManager);
-
- addFilter(state)('FIELD_NAME', 'FIELD_VALUE', 'FILTER_OPERATION');
-
- // get the generated filter
- const generatedFilter = filterManagerSpy.mock.calls[0][0][0];
- const queryKeys = Object.keys(generatedFilter.query.match_phrase);
- expect(filterManagerSpy.mock.calls.length).toBe(1);
- expect(queryKeys[0]).toBe('FIELD_NAME');
- expect(generatedFilter.query.match_phrase[queryKeys[0]]).toBe('FIELD_VALUE');
- });
-
- it('should pass the index pattern id to the filterManager', () => {
- const { addFilter } = getQueryParameterActions(filterManager);
- addFilter(state)('FIELD_NAME', 'FIELD_VALUE', 'FILTER_OPERATION');
- const generatedFilter = filterManagerSpy.mock.calls[0][0][0];
- expect(generatedFilter.meta.index).toBe('INDEX_PATTERN_ID');
- });
- });
- describe('action setPredecessorCount', () => {
- it('should set the predecessorCount to the given value', () => {
- const { setPredecessorCount } = getQueryParameterActions(filterManager);
- setPredecessorCount(state)(20);
- expect(state.queryParameters.predecessorCount).toBe(20);
- });
-
- it('should limit the predecessorCount to 0 as a lower bound', () => {
- const { setPredecessorCount } = getQueryParameterActions(filterManager);
- setPredecessorCount(state)(-1);
- expect(state.queryParameters.predecessorCount).toBe(0);
- });
-
- it('should limit the predecessorCount to 10000 as an upper bound', () => {
- const { setPredecessorCount } = getQueryParameterActions(filterManager);
- setPredecessorCount(state)(20000);
- expect(state.queryParameters.predecessorCount).toBe(10000);
- });
- });
- describe('action setSuccessorCount', () => {
- it('should set the successorCount to the given value', function () {
- const { setSuccessorCount } = getQueryParameterActions(filterManager);
- setSuccessorCount(state)(20);
-
- expect(state.queryParameters.successorCount).toBe(20);
- });
-
- it('should limit the successorCount to 0 as a lower bound', () => {
- const { setSuccessorCount } = getQueryParameterActions(filterManager);
- setSuccessorCount(state)(-1);
- expect(state.queryParameters.successorCount).toBe(0);
- });
-
- it('should limit the successorCount to 10000 as an upper bound', () => {
- const { setSuccessorCount } = getQueryParameterActions(filterManager);
- setSuccessorCount(state)(20000);
- expect(state.queryParameters.successorCount).toBe(10000);
- });
- });
- describe('action setQueryParameters', function () {
- const { setQueryParameters } = getQueryParameterActions(filterManager);
-
- it('should update the queryParameters with valid properties from the given object', function () {
- const newState = {
- ...state,
- queryParameters: {
- additionalParameter: 'ADDITIONAL_PARAMETER',
- },
- };
-
- const actualState = setQueryParameters(newState)({
- anchorId: 'ANCHOR_ID',
- columns: ['column'],
- defaultStepSize: 3,
- filters: ['filter'],
- indexPatternId: 'INDEX_PATTERN',
- predecessorCount: 100,
- successorCount: 100,
- sort: ['field'],
- });
-
- expect(actualState).toEqual({
- additionalParameter: 'ADDITIONAL_PARAMETER',
- anchorId: 'ANCHOR_ID',
- columns: ['column'],
- defaultStepSize: 3,
- filters: ['filter'],
- indexPatternId: 'INDEX_PATTERN',
- predecessorCount: 100,
- successorCount: 100,
- sort: ['field'],
- });
- });
-
- it('should ignore invalid properties', function () {
- const newState = { ...state };
-
- setQueryParameters(newState)({
- additionalParameter: 'ADDITIONAL_PARAMETER',
- });
-
- expect(state.queryParameters).toEqual(newState.queryParameters);
- });
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/constants.ts b/src/plugins/discover_legacy/public/application/angular/context/query_parameters/constants.ts
deleted file mode 100644
index a6dcc5653c87..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/constants.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { createInitialQueryParametersState } from './state';
-
-export const MAX_CONTEXT_SIZE = 10000; // OpenSearch's default maximum size limit
-export const MIN_CONTEXT_SIZE = 0;
-export const QUERY_PARAMETER_KEYS = Object.keys(createInitialQueryParametersState());
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/index.js b/src/plugins/discover_legacy/public/application/angular/context/query_parameters/index.js
deleted file mode 100644
index 03f172bd12cb..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/index.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { getQueryParameterActions } from './actions';
-export { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE, QUERY_PARAMETER_KEYS } from './constants';
-export { createInitialQueryParametersState } from './state';
diff --git a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/state.ts b/src/plugins/discover_legacy/public/application/angular/context/query_parameters/state.ts
deleted file mode 100644
index a9f44a0f7bef..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context/query_parameters/state.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export function createInitialQueryParametersState(
- defaultStepSize: number = 5,
- tieBreakerField: string = '_doc'
-) {
- return {
- anchorType: null,
- anchorId: null,
- columns: [],
- defaultStepSize,
- filters: [],
- indexPatternId: null,
- predecessorCount: 0,
- successorCount: 0,
- sort: [],
- tieBreakerField,
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context_app.html b/src/plugins/discover_legacy/public/application/angular/context_app.html
deleted file mode 100644
index 1d3971a41132..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context_app.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/plugins/discover_legacy/public/application/angular/context_app.js b/src/plugins/discover_legacy/public/application/angular/context_app.js
deleted file mode 100644
index fa487c726612..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context_app.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { CONTEXT_STEP_SETTING, CONTEXT_TIE_BREAKER_FIELDS_SETTING } from '../../../common';
-import { getAngularModule, getServices } from '../../opensearch_dashboards_services';
-import contextAppTemplate from './context_app.html';
-import './context/components/action_bar';
-import { getFirstSortableField } from './context/api/utils/sorting';
-import {
- createInitialQueryParametersState,
- getQueryParameterActions,
- QUERY_PARAMETER_KEYS,
-} from './context/query_parameters';
-import {
- createInitialLoadingStatusState,
- FAILURE_REASONS,
- LOADING_STATUS,
- QueryActionsProvider,
-} from './context/query';
-import { callAfterBindingsWorkaround } from './context/helpers/call_after_bindings_workaround';
-
-getAngularModule().directive('contextApp', function ContextApp() {
- return {
- bindToController: true,
- controller: callAfterBindingsWorkaround(ContextAppController),
- controllerAs: 'contextApp',
- restrict: 'E',
- scope: {
- anchorId: '=',
- columns: '=',
- indexPattern: '=',
- filters: '=',
- predecessorCount: '=',
- successorCount: '=',
- sort: '=',
- },
- template: contextAppTemplate,
- };
-});
-
-function ContextAppController($scope, Private) {
- const { filterManager, indexPatterns, uiSettings } = getServices();
- const queryParameterActions = getQueryParameterActions(filterManager, indexPatterns);
- const queryActions = Private(QueryActionsProvider);
- this.state = createInitialState(
- parseInt(uiSettings.get(CONTEXT_STEP_SETTING), 10),
- getFirstSortableField(this.indexPattern, uiSettings.get(CONTEXT_TIE_BREAKER_FIELDS_SETTING))
- );
-
- this.actions = _.mapValues(
- {
- ...queryParameterActions,
- ...queryActions,
- },
- (action) => (...args) => action(this.state)(...args)
- );
-
- this.constants = {
- FAILURE_REASONS,
- LOADING_STATUS,
- };
-
- $scope.$watchGroup(
- [
- () => this.state.rows.predecessors,
- () => this.state.rows.anchor,
- () => this.state.rows.successors,
- ],
- (newValues) => this.actions.setAllRows(...newValues)
- );
-
- /**
- * Sync properties to state
- */
- $scope.$watchCollection(
- () => ({
- ..._.pick(this, QUERY_PARAMETER_KEYS),
- indexPatternId: this.indexPattern.id,
- }),
- (newQueryParameters) => {
- const { queryParameters } = this.state;
- if (
- newQueryParameters.indexPatternId !== queryParameters.indexPatternId ||
- newQueryParameters.anchorId !== queryParameters.anchorId ||
- !_.isEqual(newQueryParameters.sort, queryParameters.sort)
- ) {
- this.actions.fetchAllRowsWithNewQueryParameters(_.cloneDeep(newQueryParameters));
- } else if (
- newQueryParameters.predecessorCount !== queryParameters.predecessorCount ||
- newQueryParameters.successorCount !== queryParameters.successorCount ||
- !_.isEqual(newQueryParameters.filters, queryParameters.filters)
- ) {
- this.actions.fetchContextRowsWithNewQueryParameters(_.cloneDeep(newQueryParameters));
- }
- }
- );
-
- /**
- * Sync state to properties
- */
- $scope.$watchCollection(
- () => ({
- predecessorCount: this.state.queryParameters.predecessorCount,
- successorCount: this.state.queryParameters.successorCount,
- }),
- (newParameters) => {
- _.assign(this, newParameters);
- }
- );
-}
-
-function createInitialState(defaultStepSize, tieBreakerField) {
- return {
- queryParameters: createInitialQueryParametersState(defaultStepSize, tieBreakerField),
- rows: {
- all: [],
- anchor: null,
- predecessors: [],
- successors: [],
- },
- loadingStatus: createInitialLoadingStatusState(),
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/context_state.test.ts b/src/plugins/discover_legacy/public/application/angular/context_state.test.ts
deleted file mode 100644
index 23d4581a158b..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context_state.test.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { getState } from './context_state';
-import { createBrowserHistory, History } from 'history';
-import { FilterManager, Filter } from '../../../../data/public';
-import { coreMock } from '../../../../../core/public/mocks';
-const setupMock = coreMock.createSetup();
-
-describe('Test Discover Context State', () => {
- let history: History;
- let state: any;
- const getCurrentUrl = () => history.createHref(history.location);
- beforeEach(async () => {
- history = createBrowserHistory();
- history.push('/');
- state = await getState({
- defaultStepSize: '4',
- timeFieldName: 'time',
- history,
- });
- state.startSync();
- });
- afterEach(() => {
- state.stopSync();
- });
- test('getState function default return', () => {
- expect(state.appState.getState()).toMatchInlineSnapshot(`
- Object {
- "columns": Array [
- "_source",
- ],
- "filters": Array [],
- "predecessorCount": 4,
- "sort": Array [
- "time",
- "desc",
- ],
- "successorCount": 4,
- }
- `);
- expect(state.globalState.getState()).toMatchInlineSnapshot(`null`);
- expect(state.startSync).toBeDefined();
- expect(state.stopSync).toBeDefined();
- expect(state.getFilters()).toStrictEqual([]);
- });
- test('getState -> setAppState syncing to url', async () => {
- state.setAppState({ predecessorCount: 10 });
- state.flushToUrl();
- expect(getCurrentUrl()).toMatchInlineSnapshot(
- `"/#?_a=(columns:!(_source),filters:!(),predecessorCount:10,sort:!(time,desc),successorCount:4)"`
- );
- });
- test('getState -> url to appState syncing', async () => {
- history.push(
- '/#?_a=(columns:!(_source),predecessorCount:1,sort:!(time,desc),successorCount:1)'
- );
- expect(state.appState.getState()).toMatchInlineSnapshot(`
- Object {
- "columns": Array [
- "_source",
- ],
- "predecessorCount": 1,
- "sort": Array [
- "time",
- "desc",
- ],
- "successorCount": 1,
- }
- `);
- });
- test('getState -> url to appState syncing with return to a url without state', async () => {
- history.push(
- '/#?_a=(columns:!(_source),predecessorCount:1,sort:!(time,desc),successorCount:1)'
- );
- expect(state.appState.getState()).toMatchInlineSnapshot(`
- Object {
- "columns": Array [
- "_source",
- ],
- "predecessorCount": 1,
- "sort": Array [
- "time",
- "desc",
- ],
- "successorCount": 1,
- }
- `);
- history.push('/');
- expect(state.appState.getState()).toMatchInlineSnapshot(`
- Object {
- "columns": Array [
- "_source",
- ],
- "predecessorCount": 1,
- "sort": Array [
- "time",
- "desc",
- ],
- "successorCount": 1,
- }
- `);
- });
-
- test('getState -> filters', async () => {
- const filterManager = new FilterManager(setupMock.uiSettings);
- const filterGlobal = {
- query: { match: { extension: { query: 'jpg', type: 'phrase' } } },
- meta: { index: 'logstash-*', negate: false, disabled: false, alias: null },
- } as Filter;
- filterManager.setGlobalFilters([filterGlobal]);
- const filterApp = {
- query: { match: { extension: { query: 'png', type: 'phrase' } } },
- meta: { index: 'logstash-*', negate: true, disabled: false, alias: null },
- } as Filter;
- filterManager.setAppFilters([filterApp]);
- state.setFilters(filterManager);
- expect(state.getFilters()).toMatchInlineSnapshot(`
- Array [
- Object {
- "$state": Object {
- "store": "globalState",
- },
- "meta": Object {
- "alias": null,
- "disabled": false,
- "index": "logstash-*",
- "key": "extension",
- "negate": false,
- "params": Object {
- "query": "jpg",
- },
- "type": "phrase",
- "value": [Function],
- },
- "query": Object {
- "match": Object {
- "extension": Object {
- "query": "jpg",
- "type": "phrase",
- },
- },
- },
- },
- Object {
- "$state": Object {
- "store": "appState",
- },
- "meta": Object {
- "alias": null,
- "disabled": false,
- "index": "logstash-*",
- "key": "extension",
- "negate": true,
- "params": Object {
- "query": "png",
- },
- "type": "phrase",
- "value": [Function],
- },
- "query": Object {
- "match": Object {
- "extension": Object {
- "query": "png",
- "type": "phrase",
- },
- },
- },
- },
- ]
- `);
- state.flushToUrl();
- expect(getCurrentUrl()).toMatchInlineSnapshot(
- `"/#?_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,index:'logstash-*',key:extension,negate:!f,params:(query:jpg),type:phrase),query:(match:(extension:(query:jpg,type:phrase))))))&_a=(columns:!(_source),filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:'logstash-*',key:extension,negate:!t,params:(query:png),type:phrase),query:(match:(extension:(query:png,type:phrase))))),predecessorCount:4,sort:!(time,desc),successorCount:4)"`
- );
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/context_state.ts b/src/plugins/discover_legacy/public/application/angular/context_state.ts
deleted file mode 100644
index 1b19b1d43e78..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/context_state.ts
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { History } from 'history';
-import { NotificationsStart } from 'opensearch-dashboards/public';
-import {
- createStateContainer,
- createOsdUrlStateStorage,
- syncStates,
- BaseStateContainer,
- withNotifyOnErrors,
-} from '../../../../opensearch_dashboards_utils/public';
-import { opensearchFilters, FilterManager, Filter, Query } from '../../../../data/public';
-
-export interface AppState {
- /**
- * Columns displayed in the table, cannot be changed by UI, just in discover's main app
- */
- columns: string[];
- /**
- * Array of filters
- */
- filters: Filter[];
- /**
- * Number of records to be fetched before anchor records (newer records)
- */
- predecessorCount: number;
- /**
- * Sorting of the records to be fetched, assumed to be a legacy parameter
- */
- sort: string[];
- /**
- * Number of records to be fetched after the anchor records (older records)
- */
- successorCount: number;
- query?: Query;
-}
-
-interface GlobalState {
- /**
- * Array of filters
- */
- filters: Filter[];
-}
-
-interface GetStateParams {
- /**
- * Number of records to be fetched when 'Load' link/button is clicked
- */
- defaultStepSize: string;
- /**
- * The timefield used for sorting
- */
- timeFieldName: string;
- /**
- * Determins the use of long vs. short/hashed urls
- */
- storeInSessionStorage?: boolean;
- /**
- * History instance to use
- */
- history: History;
-
- /**
- * Core's notifications.toasts service
- * In case it is passed in,
- * osdUrlStateStorage will use it notifying about inner errors
- */
- toasts?: NotificationsStart['toasts'];
-}
-
-interface GetStateReturn {
- /**
- * Global state, the _g part of the URL
- */
- globalState: BaseStateContainer;
- /**
- * App state, the _a part of the URL
- */
- appState: BaseStateContainer;
- /**
- * Start sync between state and URL
- */
- startSync: () => void;
- /**
- * Stop sync between state and URL
- */
- stopSync: () => void;
- /**
- * Set app state to with a partial new app state
- */
- setAppState: (newState: Partial) => void;
- /**
- * Get all filters, global and app state
- */
- getFilters: () => Filter[];
- /**
- * Set global state and app state filters by the given FilterManager instance
- * @param filterManager
- */
- setFilters: (filterManager: FilterManager) => void;
- /**
- * sync state to URL, used for testing
- */
- flushToUrl: (replace?: boolean) => void;
-}
-const GLOBAL_STATE_URL_KEY = '_g';
-const APP_STATE_URL_KEY = '_a';
-
-/**
- * Builds and returns appState and globalState containers
- * provides helper functions to start/stop syncing with URL
- */
-export function getState({
- defaultStepSize,
- timeFieldName,
- storeInSessionStorage = false,
- history,
- toasts,
-}: GetStateParams): GetStateReturn {
- const stateStorage = createOsdUrlStateStorage({
- useHash: storeInSessionStorage,
- history,
- ...(toasts && withNotifyOnErrors(toasts)),
- });
-
- const globalStateInitial = stateStorage.get(GLOBAL_STATE_URL_KEY) as GlobalState;
- const globalStateContainer = createStateContainer(globalStateInitial);
-
- const appStateFromUrl = stateStorage.get(APP_STATE_URL_KEY) as AppState;
- const appStateInitial = createInitialAppState(defaultStepSize, timeFieldName, appStateFromUrl);
- const appStateContainer = createStateContainer(appStateInitial);
-
- const { start, stop } = syncStates([
- {
- storageKey: GLOBAL_STATE_URL_KEY,
- stateContainer: {
- ...globalStateContainer,
- ...{
- set: (value: GlobalState | null) => {
- if (value) {
- globalStateContainer.set(value);
- }
- },
- },
- },
- stateStorage,
- },
- {
- storageKey: APP_STATE_URL_KEY,
- stateContainer: {
- ...appStateContainer,
- ...{
- set: (value: AppState | null) => {
- if (value) {
- appStateContainer.set(value);
- }
- },
- },
- },
- stateStorage,
- },
- ]);
-
- return {
- globalState: globalStateContainer,
- appState: appStateContainer,
- startSync: start,
- stopSync: stop,
- setAppState: (newState: Partial) => {
- const oldState = appStateContainer.getState();
- const mergedState = { ...oldState, ...newState };
-
- if (!isEqualState(oldState, mergedState)) {
- appStateContainer.set(mergedState);
- }
- },
- getFilters: () => [
- ...getFilters(globalStateContainer.getState()),
- ...getFilters(appStateContainer.getState()),
- ],
- setFilters: (filterManager: FilterManager) => {
- // global state filters
- const globalFilters = filterManager.getGlobalFilters();
- const globalFilterChanged = !isEqualFilters(
- globalFilters,
- getFilters(globalStateContainer.getState())
- );
- if (globalFilterChanged) {
- globalStateContainer.set({ filters: globalFilters });
- }
- // app state filters
- const appFilters = filterManager.getAppFilters();
- const appFilterChanged = !isEqualFilters(
- appFilters,
- getFilters(appStateContainer.getState())
- );
- if (appFilterChanged) {
- appStateContainer.set({ ...appStateContainer.getState(), ...{ filters: appFilters } });
- }
- },
- // helper function just needed for testing
- flushToUrl: (replace?: boolean) => stateStorage.flush({ replace }),
- };
-}
-
-/**
- * Helper function to compare 2 different filter states
- */
-export function isEqualFilters(filtersA: Filter[], filtersB: Filter[]) {
- if (!filtersA && !filtersB) {
- return true;
- } else if (!filtersA || !filtersB) {
- return false;
- }
- return opensearchFilters.compareFilters(
- filtersA,
- filtersB,
- opensearchFilters.COMPARE_ALL_OPTIONS
- );
-}
-
-/**
- * Helper function to compare 2 different states, is needed since comparing filters
- * works differently, doesn't work with _.isEqual
- */
-function isEqualState(stateA: AppState | GlobalState, stateB: AppState | GlobalState) {
- if (!stateA && !stateB) {
- return true;
- } else if (!stateA || !stateB) {
- return false;
- }
- const { filters: stateAFilters = [], ...stateAPartial } = stateA;
- const { filters: stateBFilters = [], ...stateBPartial } = stateB;
- return (
- _.isEqual(stateAPartial, stateBPartial) &&
- opensearchFilters.compareFilters(
- stateAFilters,
- stateBFilters,
- opensearchFilters.COMPARE_ALL_OPTIONS
- )
- );
-}
-
-/**
- * Helper function to return array of filter object of a given state
- */
-function getFilters(state: AppState | GlobalState): Filter[] {
- if (!state || !Array.isArray(state.filters)) {
- return [];
- }
- return state.filters;
-}
-
-/**
- * Helper function to return the initial app state, which is a merged object of url state and
- * default state. The default size is the default number of successor/predecessor records to fetch
- */
-function createInitialAppState(
- defaultSize: string,
- timeFieldName: string,
- urlState: AppState
-): AppState {
- const defaultState = {
- columns: ['_source'],
- filters: [],
- predecessorCount: parseInt(defaultSize, 10),
- sort: [timeFieldName, 'desc'],
- successorCount: parseInt(defaultSize, 10),
- };
- if (typeof urlState !== 'object') {
- return defaultState;
- }
-
- return {
- ...defaultState,
- ...urlState,
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/__snapshots__/no_results.test.js.snap b/src/plugins/discover_legacy/public/application/angular/directives/__snapshots__/no_results.test.js.snap
deleted file mode 100644
index f2abb590008c..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/__snapshots__/no_results.test.js.snap
+++ /dev/null
@@ -1,230 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`DiscoverNoResults props queryLanguage supports lucene and renders doc link 1`] = `
-Array [
-
,
-
-
-
-
-
-
-
-
- Refine your query
-
-
- The search bar at the top uses OpenSearch’s support for Lucene
-
- Query String syntax
-
-
- (opens in a new tab or window)
-
-
- . Here are some examples of how you can search for web server logs that have been parsed into a few fields.
-
-
-
-
-
-
-
- Find requests that contain the number 200, in any field
-
-
-
-
-
-
- 200
-
-
-
-
-
-
- Find 200 in the status field
-
-
-
-
-
-
- status:200
-
-
-
-
-
-
- Find all status codes between 400-499
-
-
-
-
-
-
- status:[400 TO 499]
-
-
-
-
-
-
- Find status codes 400-499 with the extension php
-
-
-
-
-
-
- status:[400 TO 499] AND extension:PHP
-
-
-
-
-
-
- Find status codes 400-499 with the extension php or html
-
-
-
-
-
-
- status:[400 TO 499] AND (extension:php OR extension:html)
-
-
-
-
-
-
-
,
-]
-`;
-
-exports[`DiscoverNoResults props timeFieldName renders time range feedback 1`] = `
-Array [
-
,
-
-
-
-
-
-
-
-
- Expand your time range
-
-
- One or more of the indices you’re looking at contains a date field. Your query may not match anything in the current time range, or there may not be any data at all in the currently selected time range. You can try changing the time range to one which contains data.
-
-
-
-
,
-]
-`;
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/_histogram.scss b/src/plugins/discover_legacy/public/application/angular/directives/_histogram.scss
deleted file mode 100644
index 1e625fa064e2..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/_histogram.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.dscHistogram__header--partial {
- font-weight: $euiFontWeightRegular;
- min-width: $euiSize * 12;
-}
-
-// Temporary override to inlined styles provided by ElasticCharts theming
-// Will be unnecessary when we migrate the histogram to a different rendering library:
-// https: //github.com/opensearch-project/OpenSearch-Dashboards/issues/4643
-.dscHistogram .echChartBackground {
- background-color: inherit !important;
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/_index.scss b/src/plugins/discover_legacy/public/application/angular/directives/_index.scss
deleted file mode 100644
index 01f5bbb6fd57..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/_index.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import "no_results";
-@import "histogram";
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/_no_results.scss b/src/plugins/discover_legacy/public/application/angular/directives/_no_results.scss
deleted file mode 100644
index 7ea945e820bf..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/_no_results.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.dscNoResults {
- max-width: 1000px;
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/debounce/debounce.js b/src/plugins/discover_legacy/public/application/angular/directives/debounce/debounce.js
deleted file mode 100644
index da0f4893b909..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/debounce/debounce.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-// Debounce service, angularized version of lodash debounce
-// borrowed heavily from https://github.com/shahata/angular-debounce
-
-export function createDebounceProviderTimeout($timeout) {
- return function (func, wait, options) {
- let timeout;
- let args;
- let self;
- let result;
- options = _.defaults(options || {}, {
- leading: false,
- trailing: true,
- invokeApply: true,
- });
-
- function debounce() {
- self = this;
- args = arguments;
-
- const later = function () {
- timeout = null;
- if (!options.leading || options.trailing) {
- result = func.apply(self, args);
- }
- };
-
- const callNow = options.leading && !timeout;
-
- if (timeout) {
- $timeout.cancel(timeout);
- }
- timeout = $timeout(later, wait, options.invokeApply);
-
- if (callNow) {
- result = func.apply(self, args);
- }
-
- return result;
- }
-
- debounce.cancel = function () {
- $timeout.cancel(timeout);
- timeout = null;
- };
-
- return debounce;
- };
-}
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/debounce/debounce.test.ts b/src/plugins/discover_legacy/public/application/angular/directives/debounce/debounce.test.ts
deleted file mode 100644
index 635ed560df40..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/debounce/debounce.test.ts
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon, { SinonSpy } from 'sinon';
-import angular, { auto, ITimeoutService } from 'angular';
-import 'angular-mocks';
-import 'angular-sanitize';
-import 'angular-route';
-
-// @ts-ignore
-import { createDebounceProviderTimeout } from './debounce';
-import { coreMock } from '../../../../../../../core/public/mocks';
-import { initializeInnerAngularModule } from '../../../../get_inner_angular';
-import { navigationPluginMock } from '../../../../../../navigation/public/mocks';
-import { dataPluginMock } from '../../../../../../data/public/mocks';
-import { initAngularBootstrap } from '../../../../../../opensearch_dashboards_legacy/public';
-
-describe('debounce service', function () {
- let debounce: (fn: () => void, timeout: number, options?: any) => any;
- let $timeout: ITimeoutService;
- let spy: SinonSpy;
-
- beforeEach(() => {
- spy = sinon.spy();
-
- initAngularBootstrap();
-
- initializeInnerAngularModule(
- 'app/discover',
- coreMock.createStart(),
- navigationPluginMock.createStartContract(),
- dataPluginMock.createStartContract()
- );
-
- angular.mock.module('app/discover');
-
- angular.mock.inject(($injector: auto.IInjectorService, _$timeout_: ITimeoutService) => {
- $timeout = _$timeout_;
-
- debounce = createDebounceProviderTimeout($timeout);
- });
- });
-
- it('should have a cancel method', function () {
- const bouncer = debounce(() => {}, 100);
-
- expect(bouncer).toHaveProperty('cancel');
- });
-
- describe('delayed execution', function () {
- const sandbox = sinon.createSandbox();
-
- beforeEach(() => sandbox.useFakeTimers());
- afterEach(() => sandbox.restore());
-
- it('should delay execution', function () {
- const bouncer = debounce(spy, 100);
-
- bouncer();
- sinon.assert.notCalled(spy);
- $timeout.flush();
- sinon.assert.calledOnce(spy);
-
- spy.resetHistory();
- });
-
- it('should fire on leading edge', function () {
- const bouncer = debounce(spy, 100, { leading: true });
-
- bouncer();
- sinon.assert.calledOnce(spy);
- $timeout.flush();
- sinon.assert.calledTwice(spy);
-
- spy.resetHistory();
- });
-
- it('should only fire on leading edge', function () {
- const bouncer = debounce(spy, 100, { leading: true, trailing: false });
-
- bouncer();
- sinon.assert.calledOnce(spy);
- $timeout.flush();
- sinon.assert.calledOnce(spy);
-
- spy.resetHistory();
- });
-
- it('should reset delayed execution', function () {
- const cancelSpy = sinon.spy($timeout, 'cancel');
- const bouncer = debounce(spy, 100);
-
- bouncer();
- sandbox.clock.tick(1);
-
- bouncer();
- sinon.assert.notCalled(spy);
- $timeout.flush();
- sinon.assert.calledOnce(spy);
- sinon.assert.calledOnce(cancelSpy);
-
- spy.resetHistory();
- cancelSpy.resetHistory();
- });
- });
-
- describe('cancel', function () {
- it('should cancel the $timeout', function () {
- const cancelSpy = sinon.spy($timeout, 'cancel');
- const bouncer = debounce(spy, 100);
-
- bouncer();
- bouncer.cancel();
- sinon.assert.calledOnce(cancelSpy);
- // throws if pending timeouts
- $timeout.verifyNoPendingTasks();
-
- cancelSpy.resetHistory();
- });
- });
-});
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/debounce/index.js b/src/plugins/discover_legacy/public/application/angular/directives/debounce/index.js
deleted file mode 100644
index 6acd0d680d4d..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/debounce/index.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { createDebounceProviderTimeout } from './debounce';
diff --git a/src/plugins/discover_legacy/public/application/angular/directives/fixed_scroll.js b/src/plugins/discover_legacy/public/application/angular/directives/fixed_scroll.js
deleted file mode 100644
index 6b80caaa1f71..000000000000
--- a/src/plugins/discover_legacy/public/application/angular/directives/fixed_scroll.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import $ from 'jquery';
-import _ from 'lodash';
-import { createDebounceProviderTimeout } from './debounce';
-
-const SCROLLER_HEIGHT = 20;
-
-/**
- * This directive adds a fixed horizontal scrollbar to the bottom of the window that proxies its scroll events
- * to the target element's real scrollbar. This is useful when the target element's horizontal scrollbar
- * might be waaaay down the page, like the doc table on Discover.
- */
-export function FixedScrollProvider($timeout) {
- return {
- restrict: 'A',
- link: function ($scope, $el) {
- return createFixedScroll($scope, $timeout)($el);
- },
- };
-}
-
-export function createFixedScroll($scope, $timeout) {
- const debounce = createDebounceProviderTimeout($timeout);
- return function (el) {
- const $el = typeof el.css === 'function' ? el : $(el);
- let $window = $(window);
- let $scroller = $('