Skip to content

Commit

Permalink
adding MDS support for ISM Pages: Indices, Aliases, DataStreams, Temp…
Browse files Browse the repository at this point in the history
…lates & Component Templates (#1006)

* adding MDS support for ISM Pages: Indices, Aliases, DataStreams, Templates

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* Reverting (not required) onCancel changes for forceMerge

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* force mounting IndexDetail page

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* force mounting template page

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* clearing indexdetail on datasource change

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* mounting data source menu as read only

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* integrating with readonly data source

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* re building services on page switches

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* refactoring to common hooks and MDSEnabledComponent

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* Update public/components/MDSEnabledComponent/MDSEnabledComponent.tsx

Co-authored-by: SuZhou-Joe <[email protected]>
Signed-off-by:  Ramakrishna Chilaka <[email protected]>
Signed-off-by: Ramakrishna Chilaka <[email protected]>

* refactoring code for server & appending URL with datasourceId/datasourcelabel

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* refactoring types & fixing tests

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* resolving yarn.lock conflict

Signed-off-by: Ramakrishna Chilaka <[email protected]>

* flaky test flush action aliases

Signed-off-by: Ramakrishna Chilaka <[email protected]>

---------

Signed-off-by: Ramakrishna Chilaka <[email protected]>
Signed-off-by: Ramakrishna Chilaka <[email protected]>
Co-authored-by: SuZhou-Joe <[email protected]>
  • Loading branch information
RamakrishnaChilaka and SuZhou-Joe authored Mar 26, 2024
1 parent d516380 commit b151b85
Show file tree
Hide file tree
Showing 48 changed files with 1,915 additions and 1,523 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ describe("Aliases", () => {
describe("can flush an alias", () => {
it("successfully flush an index", () => {
let sample_alias = `${SAMPLE_ALIAS_PREFIX}-${1}`;
// Sort all aliases in asc order to make it at first page
cy.contains("Alias name").click();
// Confirm we have our initial alias
cy.contains(sample_alias);
cy.get('[placeholder="Search..."]').type(`${SAMPLE_ALIAS_PREFIX}-1{enter}`);
cy.contains(`${SAMPLE_ALIAS_PREFIX}-10`);
cy.contains(`${SAMPLE_ALIAS_PREFIX}-11`);
cy.contains(`${sample_alias}`);
// index a test doc
cy.request({
method: "POST",
Expand All @@ -170,23 +170,23 @@ describe("Aliases", () => {
expect(num).to.equal(1);
});

cy.get('[data-test-subj="moreAction"]').click();
// Flush btn should be disabled if no items selected
cy.get('[data-test-subj="Flush Action"]').should("have.class", "euiContextMenuItem-isDisabled");
cy.get('[data-test-subj="moreAction"] button').click().get('[data-test-subj="Flush Action"]').should("be.disabled").end();

// Select an alias
cy.get(`[data-test-subj="checkboxSelectRow-${sample_alias}"]`).check({
force: true,
});

cy.get('[data-test-subj="moreAction"]').click();
// Flush btn should be enabled
cy.get('[data-test-subj="Flush Action"]').should("exist").should("not.have.class", "euiContextMenuItem-isDisabled").click();
cy.get(`#_selection_column_${sample_alias}-checkbox`)
.click()
.get('[data-test-subj="moreAction"] button')
.click()
.get('[data-test-subj="Flush Action"]')
.should("not.be.disabled")
.click()
.end();

// Check for flush index modal
cy.contains("Flush alias");

cy.get('[data-test-subj="flushConfirmButton"]').click();
cy.get('[data-test-subj="flushConfirmButton"]').should("not.be.disabled").click();

// Check for success toast
cy.contains(`The alias ${sample_alias} has been successfully flushed.`);
Expand Down
15 changes: 4 additions & 11 deletions opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,9 @@
"id": "indexManagementDashboards",
"version": "3.0.0.0",
"opensearchDashboardsVersion": "3.0.0",
"configPath": [
"opensearch_index_management"
],
"requiredPlugins": [
"navigation",
"opensearchDashboardsReact"
],
"optionalPlugins": [
"managementOverview"
],
"configPath": ["opensearch_index_management"],
"requiredPlugins": ["navigation", "opensearchDashboardsReact"],
"optionalPlugins": ["managementOverview", "dataSource", "dataSourceManagement"],
"server": true,
"ui": true
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@
"engines": {
"yarn": "^1.21.1"
}
}
}
54 changes: 54 additions & 0 deletions public/components/MDSEnabledComponent/MDSEnabledComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useContext, useEffect } from "react";
import { DataSourceMenuContext, DataSourceMenuProperties } from "../../services/DataSourceMenuContext";
import { useHistory } from "react-router";
import queryString from "query-string";

export default class MDSEnabledComponent<
Props extends DataSourceMenuProperties,
State extends DataSourceMenuProperties
> extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
dataSourceId: props.dataSourceId,
dataSourceLabel: props.dataSourceLabel,
multiDataSourceEnabled: props.multiDataSourceEnabled,
} as State;
}

static getDerivedStateFromProps<Props extends DataSourceMenuProperties, State extends DataSourceMenuProperties>(
nextProps: Props,
prevState: State
) {
// static members cannot reference class type parameters
if (
nextProps.multiDataSourceEnabled &&
(nextProps.dataSourceId !== prevState.dataSourceId || nextProps.dataSourceLabel !== prevState.dataSourceLabel)
) {
return {
dataSourceId: nextProps.dataSourceId,
dataSourceLabel: nextProps.dataSourceLabel,
};
}
return null;
}
}

export function useUpdateUrlWithDataSourceProperties() {
const dataSourceMenuProps = useContext(DataSourceMenuContext);
const { dataSourceId, dataSourceLabel, multiDataSourceEnabled } = dataSourceMenuProps;
const history = useHistory();
const currentSearch = history.location.search;
const currentQuery = queryString.parse(currentSearch);
useEffect(() => {
if (multiDataSourceEnabled) {
history.replace({
search: queryString.stringify({
...currentQuery,
dataSourceId,
dataSourceLabel,
}),
});
}
}, [dataSourceId, dataSourceLabel, multiDataSourceEnabled]);
}
4 changes: 4 additions & 0 deletions public/components/MDSEnabledComponent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import MDSEnabledComponent from "./MDSEnabledComponent";

export default MDSEnabledComponent;
export * from "./MDSEnabledComponent";
58 changes: 19 additions & 39 deletions public/index_management_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,40 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { CoreStart, AppMountParameters } from "opensearch-dashboards/public";
import { AppMountParameters, CoreStart } from "opensearch-dashboards/public";
import React from "react";
import ReactDOM from "react-dom";
import { HashRouter as Router, Route } from "react-router-dom";
import {
IndexService,
ManagedIndexService,
PolicyService,
RollupService,
TransformService,
NotificationService,
ServicesContext,
SnapshotManagementService,
CommonService,
} from "./services";
import { DarkModeContext } from "./components/DarkMode";
import Main from "./pages/Main";
import { CoreServicesContext } from "./components/core_services";
import "./app.scss";
import { AppPluginStartDependencies } from "./types";
import { DataSourceManagementPluginSetup } from "../../../src/plugins/data_source_management/public";

export function renderApp(coreStart: CoreStart, params: AppMountParameters, landingPage: string) {
const http = coreStart.http;

const indexService = new IndexService(http);
const managedIndexService = new ManagedIndexService(http);
const policyService = new PolicyService(http);
const rollupService = new RollupService(http);
const transformService = new TransformService(http);
const notificationService = new NotificationService(http);
const snapshotManagementService = new SnapshotManagementService(http);
const commonService = new CommonService(http);
const services = {
indexService,
managedIndexService,
policyService,
rollupService,
transformService,
notificationService,
snapshotManagementService,
commonService,
};

export function renderApp(
coreStart: CoreStart,
pluginStartDependencies: AppPluginStartDependencies,
params: AppMountParameters,
landingPage: string,
dataSourceManagement: DataSourceManagementPluginSetup
) {
const isDarkMode = coreStart.uiSettings.get("theme:darkMode") || false;

ReactDOM.render(
<Router>
<Route
render={(props) => (
<DarkModeContext.Provider value={isDarkMode}>
<ServicesContext.Provider value={services}>
<CoreServicesContext.Provider value={coreStart}>
<Main {...props} landingPage={landingPage} />
</CoreServicesContext.Provider>
</ServicesContext.Provider>
<CoreServicesContext.Provider value={coreStart}>
<Main
{...props}
landingPage={landingPage}
setActionMenu={params.setHeaderActionMenu}
multiDataSourceEnabled={!!pluginStartDependencies.dataSource}
dataSourceManagement={dataSourceManagement}
/>
</CoreServicesContext.Provider>
</DarkModeContext.Provider>
)}
/>
Expand Down
25 changes: 19 additions & 6 deletions public/pages/Aliases/containers/Aliases/Aliases.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { Component, useContext, useState } from "react";
import React, { useContext, useState } from "react";
import _, { isEqual } from "lodash";
import { RouteComponentProps } from "react-router-dom";
import queryString from "query-string";
Expand Down Expand Up @@ -36,12 +36,14 @@ import IndexControls, { SearchControlsProps } from "../../components/IndexContro
import CreateAlias from "../CreateAlias";
import AliasesActions from "../AliasActions";
import { CoreStart } from "opensearch-dashboards/public";
import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext";
import MDSEnabledComponent from "../../../../components/MDSEnabledComponent";

interface AliasesProps extends RouteComponentProps {
interface AliasesProps extends RouteComponentProps, DataSourceMenuProperties {
commonService: CommonService;
}

interface AliasesState {
interface AliasesState extends DataSourceMenuProperties {
totalAliases: number;
from: string;
size: string;
Expand Down Expand Up @@ -111,8 +113,9 @@ const defaultFilter = {
status: DEFAULT_QUERY_PARAMS.status,
};

class Aliases extends Component<AliasesProps, AliasesState> {
class Aliases extends MDSEnabledComponent<AliasesProps, AliasesState> {
static contextType = CoreServicesContext;

constructor(props: AliasesProps) {
super(props);
const {
Expand All @@ -132,6 +135,7 @@ class Aliases extends Component<AliasesProps, AliasesState> {
};
this.state = {
...defaultFilter,
...this.state,
totalAliases: 0,
from,
size,
Expand Down Expand Up @@ -164,6 +168,14 @@ class Aliases extends Component<AliasesProps, AliasesState> {
}, {} as AliasesState);
};

async componentDidUpdate(prevProps: AliasesProps, prevState: AliasesState) {
const prevQuery = this.getQueryState(prevState);
const currQuery = this.getQueryState(this.state);
if (!_.isEqual(prevQuery, currQuery)) {
await this.getAliases();
}
}

groupResponse = (array: IAlias[]) => {
const groupedMap: Record<string, IAlias & { order: number; writeIndex: string }> = {};
array.forEach((item, index) => {
Expand Down Expand Up @@ -471,7 +483,8 @@ class Aliases extends Component<AliasesProps, AliasesState> {
}
}

export default function AliasContainer(props: Omit<AliasesProps, "commonService">) {
export default function AliasContainer(props: Omit<AliasesProps, "commonService" | keyof DataSourceMenuProperties>) {
const context = useContext(ServicesContext);
return <Aliases {...props} commonService={context?.commonService as CommonService} />;
const dataSourceMenuProps = useContext(DataSourceMenuContext);
return <Aliases {...props} commonService={context?.commonService as CommonService} {...dataSourceMenuProps} />;
}
2 changes: 2 additions & 0 deletions public/pages/Aliases/utils/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ export const DEFAULT_QUERY_PARAMS = {
sortField: "alias" as keyof IAlias,
sortDirection: SortDirection.DESC,
status: "",
dataSourceId: "",
dataSourceLabel: "",
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { Component, useContext } from "react";
import { debounce, isEqual, get } from "lodash";
import React, { useContext } from "react";
import _, { debounce, isEqual, get } from "lodash";
import { Link, RouteComponentProps } from "react-router-dom";
import queryString from "query-string";
import {
Expand Down Expand Up @@ -38,8 +38,10 @@ import ComponentTemplateBadge from "../../../../components/ComponentTemplateBadg
import AssociatedTemplatesModal from "../AssociatedTemplatesModal";
import { useComponentMapTemplate } from "../../utils/hooks";
import "./index.scss";
import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext";
import MDSEnabledComponent from "../../../../components/MDSEnabledComponent";

interface ComposableTemplatesProps extends RouteComponentProps {
interface ComposableTemplatesProps extends RouteComponentProps, DataSourceMenuProperties {
commonService: CommonService;
componentMapTemplate: Record<string, string[]>;
loading: boolean;
Expand All @@ -54,13 +56,14 @@ type ComposableTemplatesState = {
selectedItems: ICatComposableTemplate[];
composableTemplates: ICatComposableTemplate[];
loading: boolean;
} & SearchControlsProps["value"];
} & SearchControlsProps["value"] &
DataSourceMenuProperties;

const defaultFilter = {
search: DEFAULT_QUERY_PARAMS.search,
};

class ComposableTemplates extends Component<ComposableTemplatesProps, ComposableTemplatesState> {
class ComposableTemplates extends MDSEnabledComponent<ComposableTemplatesProps, ComposableTemplatesState> {
static contextType = CoreServicesContext;
constructor(props: ComposableTemplatesProps) {
super(props);
Expand All @@ -79,6 +82,7 @@ class ComposableTemplates extends Component<ComposableTemplatesProps, Composable
};
this.state = {
...defaultFilter,
...this.state,
totalComposableTemplates: 0,
from,
size,
Expand All @@ -96,6 +100,14 @@ class ComposableTemplates extends Component<ComposableTemplatesProps, Composable

getComposableTemplates: () => Promise<void> | undefined;

async componentDidUpdate(prevProps: ComposableTemplatesProps, prevState: ComposableTemplatesState) {
const prevQuery = this.getQueryState(prevState);
const currQuery = this.getQueryState(this.state);
if (!_.isEqual(prevQuery, currQuery)) {
await this.getComposableTemplates();
}
}

componentDidMount() {
this.context.chrome.setBreadcrumbs([BREADCRUMBS.INDEX_MANAGEMENT, BREADCRUMBS.TEMPLATES]);
this.getComposableTemplates();
Expand Down Expand Up @@ -449,16 +461,18 @@ class ComposableTemplates extends Component<ComposableTemplatesProps, Composable
}

export default function ComposableTemplatesContainer(
props: Omit<ComposableTemplatesProps, "commonService" | "loading" | "componentMapTemplate">
props: Omit<ComposableTemplatesProps, "commonService" | "loading" | "componentMapTemplate" | keyof DataSourceMenuProperties>
) {
const context = useContext(ServicesContext);
const dataSourceMenuProps = useContext(DataSourceMenuContext);
const { componentMapTemplate, loading } = useComponentMapTemplate();
return (
<ComposableTemplates
{...props}
loading={loading}
componentMapTemplate={componentMapTemplate}
commonService={context?.commonService as CommonService}
{...dataSourceMenuProps}
/>
);
}
2 changes: 2 additions & 0 deletions public/pages/ComposableTemplates/utils/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ export const DEFAULT_QUERY_PARAMS = {
search: "",
sortField: "name" as keyof ICatComposableTemplate,
sortDirection: SortDirection.DESC,
dataSourceId: "",
dataSourceLabel: "",
};
Loading

0 comments on commit b151b85

Please sign in to comment.