Skip to content

Commit

Permalink
Merge branch 'opensearch-project:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
BigSamu authored Dec 14, 2023
2 parents cbf5689 + 3268e37 commit 0095aea
Show file tree
Hide file tree
Showing 9 changed files with 5,021 additions and 643 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Cleanup unused url ([#3847](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3847))
- [TSVB, Dashboards] Fix inconsistent dark mode code editor themes ([#4609](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4609))
- Fix `maps.proxyOpenSearchMapsServiceInMaps` config definition so it can be set ([#5170](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5170))
- [Discover] Fix inactive state on 'Discover' tab in side navigation menu ([#5432](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5432))
- [BUG] Add platform "darwin-arm64" to unit test ([#5290](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5290))
- [BUG][Dev Tool] Add dev tool documentation link to dev tool's help menu [#5166](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5166)
- Fix missing border for header navigation control on right ([#5450](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5450))
- [BUG] Fix filtering issue in data source selector ([5484](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5484))
- [BUG][Data] Support for custom filters with heterogeneous data fields ([5577](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5577))
- [BUG][Data] Fix empty suggestion history when querying in search bar [#5349](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5349)

### 🚞 Infrastructure

Expand Down Expand Up @@ -69,6 +71,8 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### 🔩 Tests

- [Home] Add more unit tests for other complications of overview ([#5418](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5418))

## [2.11.1 - 2023-11-21](https://github.com/opensearch-project/OpenSearch-Dashboards/releases/tag/2.11.1)

### 🛡 Security
Expand Down
63 changes: 63 additions & 0 deletions src/core/public/chrome/ui/header/nav_link.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { isActiveNavLink, createEuiListItem } from './nav_link';
import { ChromeNavLink } from '../../..';
import { httpServiceMock } from '../../../http/http_service.mock';

describe('isActiveNavLink', () => {
it('should return true if the appId is "discover" and linkId is "discover"', () => {
expect(isActiveNavLink('discover', 'discover')).toBe(true);
});

it('should return true if the appId is "data-explorer" and linkId is "data-explorer"', () => {
expect(isActiveNavLink('data-explorer', 'data-explorer')).toBe(true);
});

it('should return true if the appId is "data-explorer" and linkId is "discover"', () => {
expect(isActiveNavLink('data-explorer', 'discover')).toBe(true);
});

it('should return false if the appId and linkId do not match', () => {
expect(isActiveNavLink('dashboard', 'discover')).toBe(false);
});
});

const mockBasePath = httpServiceMock.createSetupContract({ basePath: '/test' }).basePath;

describe('createEuiListItem', () => {
const mockLink: Partial<ChromeNavLink> = {
href: 'test',
id: 'test',
title: 'Test App',
disabled: false,
euiIconType: 'inputOutput',
icon: 'testIcon',
tooltip: 'Test App Tooltip',
};

const mockProps = {
link: mockLink as ChromeNavLink,
appId: 'test',
basePath: mockBasePath,
dataTestSubj: 'test-subj',
onClick: jest.fn(),
navigateToApp: jest.fn(),
externalLink: false,
};

it('creates a list item with the correct properties', () => {
const listItem = createEuiListItem(mockProps);
expect(listItem).toHaveProperty('label', mockProps.link.tooltip);
expect(listItem).toHaveProperty('href', mockProps.link.href);
expect(listItem).toHaveProperty('data-test-subj', mockProps.dataTestSubj);
expect(listItem).toHaveProperty('onClick');
expect(listItem).toHaveProperty(
'isActive',
isActiveNavLink(mockProps.appId, mockProps.link.id)
);
expect(listItem).toHaveProperty('isDisabled', mockProps.link.disabled);
});
});
10 changes: 9 additions & 1 deletion src/core/public/chrome/ui/header/nav_link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ import { relativeToAbsolute } from '../../nav_links/to_nav_link';
export const isModifiedOrPrevented = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) =>
event.metaKey || event.altKey || event.ctrlKey || event.shiftKey || event.defaultPrevented;

// TODO: replace hard-coded values with a registration function, so that apps can control active nav links similar to breadcrumbs
const aliasedApps: { [key: string]: string[] } = {
discover: ['data-explorer'],
};

export const isActiveNavLink = (appId: string | undefined, linkId: string): boolean =>
!!(appId === linkId || aliasedApps[linkId]?.includes(appId || ''));

interface Props {
link: ChromeNavLink;
appId?: string;
Expand Down Expand Up @@ -82,7 +90,7 @@ export function createEuiListItem({
navigateToApp(id);
}
},
isActive: appId === id,
isActive: isActiveNavLink(appId, id),
isDisabled: disabled,
'data-test-subj': dataTestSubj,
...(basePath && {
Expand Down
41 changes: 41 additions & 0 deletions src/plugins/data/public/ui/typeahead/suggestion_component.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ const mockSuggestion: QuerySuggestion = {
type: QuerySuggestionTypes.Value,
};

const mockEmptySuggestion: QuerySuggestion = {
description: '',
end: 0,
start: 0,
text: '',
type: QuerySuggestionTypes.Value,
};

describe('SuggestionComponent', () => {
it('Should display the suggestion and use the provided ariaId', () => {
const component = shallow(
Expand Down Expand Up @@ -135,4 +143,37 @@ describe('SuggestionComponent', () => {
component.simulate('mouseenter');
expect(mockHandler).toHaveBeenCalledTimes(1);
});

it('Should return null for empty suggestion text', () => {
const component = shallow(
<SuggestionComponent
onClick={noop}
onMouseEnter={noop}
selected={false}
suggestion={mockEmptySuggestion}
innerRef={noop}
ariaId={'suggestion-empty'}
shouldDisplayDescription={true}
/>
);

expect(component.isEmptyRender()).toBeTruthy();
});

it('Should return null for suggestion text with only whitespace', () => {
const whitespaceSuggestion = { ...mockEmptySuggestion, text: ' ' };
const component = shallow(
<SuggestionComponent
onClick={noop}
onMouseEnter={noop}
selected={false}
suggestion={whitespaceSuggestion}
innerRef={noop}
ariaId={'suggestion-whitespace'}
shouldDisplayDescription={true}
/>
);

expect(component.isEmptyRender()).toBeTruthy();
});
});
7 changes: 7 additions & 0 deletions src/plugins/data/public/ui/typeahead/suggestion_component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ interface Props {
}

export function SuggestionComponent(props: Props) {
// Removing empty suggestions from the history is for maintaining a clean user experience.
// Empty suggestions, which typically result from inadvertent keystrokes or incomplete queries,
// do not provide value to the user.
if (!props.suggestion.text.trim()) {
return null;
}

return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus
<div
Expand Down
79 changes: 72 additions & 7 deletions src/plugins/data_explorer/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,76 @@
# dataExplorer
# Data Explorer

A OpenSearch Dashboards plugin
## Overview

---
Data Explorer is an integral enhancement of the OpenSearch Dashboards that seeks to consolidate various data exploration facets into a unified platform. Built to provide an efficient data exploration experience, Data Explorer merges capabilities of different applications like Discover, Visbuilder, and Event Analytics into a singular platform.

## Key Features

1. **Unified Data Exploration**: Data Explorer acts as a consolidated platform for all data exploration tasks, aiming to provide users with a seamless and efficient environment.
2. **Extensibility**: Provides an architecture that allows existing exploration apps to migrate with minimal changes.
3. **Shared Utilities**: Offers components and utilities that can be shared across different views.

## Architecture and Integration

Data Explorer, at its core, is a shell for data exploration views. Here's a breakdown of the architecture and how it manages responsibilities:

### Data Explorer Responsibilities:

1. **Data Source**: Acts as the central point for the data source being explored.
2. **View Registry**: Allows apps to register themselves as views and manages their display based on user selection.
3. **State Management**: Provides shared state management and hooks for underlying apps to register their state reducers.
4. **Shared Utilities**: Contains components and utilities that can be reused by various views.

### View Responsibilities:

1. **Metadata Storage**: Handles the logic for storing metadata and its retrieval (Saved objects).
2. **Data Fetching**: Manages the logic for fetching data from the data source.
3. **View specific state management**: Handles view-specific state management and hooks into Data Explorer's state management.
4. **Nav Options & Search/Query Bar**: Manages the navigation options, time filter, and search bar.
5. **View Specific Logic**: Contains view-specific rendering and application logic.
6. **Embeddables**: Responsible for registering their embeddables.

## Development
### Migrating Existing Applications:

Existing applications can migrate their data exploration views to Data Explorer. Such migrations involve:

1. Registering the application as a view.
2. Using Data Explorer's state management and data source.
3. Modifying routes to utilize Data Explorer's routes.
4. Adapting the UI to match Data Explorer's panel and canvas components.

#### Routing:

Existing routes for each view are expected to redirect to new routes prefixed with `/data_explorer`. E.g., existing Discover route will redirect to `/data_explorer/discover`.

### View Registry:

For an application to be registered as a view within Data Explorer, it needs to adhere to the following data model:

```ts
interface ViewDefinition<T = any> {
readonly id: string;
readonly title: string;
readonly ui?: {
defaults: DefaultViewState | (() => DefaultViewState) | (() => Promise<DefaultViewState>);
slice: Slice<T>;
};
readonly Canvas: LazyExoticComponent<(props: ViewProps) => React.ReactElement>;
readonly Panel: LazyExoticComponent<(props: ViewProps) => React.ReactElement>;
readonly Context: LazyExoticComponent<
(props: React.PropsWithChildren<ViewProps>) => React.ReactElement
>;
readonly defaultPath: string;
readonly appExtentions: {
savedObject: {
docTypes: [string];
toListItem: (obj: { id: string; title: string }) => ViewListItem;
};
};
readonly shouldShow?: (state: any) => boolean;
}
```

---

See the [OpenSearch Dashboards contributing
guide](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/main/CONTRIBUTING.md) for instructions
setting up your development environment.
Original proposal: https://github.com/opensearch-project/OpenSearch-Dashboards/issues/4165
Loading

0 comments on commit 0095aea

Please sign in to comment.