Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding MDS support for ISM Pages: Indices, Aliases, DataStreams, Templates & Component Templates #1006

Merged
merged 14 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading