Skip to content

Commit

Permalink
[Index details page] Add a declaration file for index actions context…
Browse files Browse the repository at this point in the history
… menu and a new component for manage index button
  • Loading branch information
yuliacech committed Aug 24, 2023
1 parent 405b59d commit cfbdc05
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 116 deletions.
9 changes: 9 additions & 0 deletions x-pack/plugins/index_management/common/types/indices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ export interface Index {
hidden: boolean;
aliases: string | string[];
data_stream?: string;

// The types below are added by extension services if corresponding plugins are enabled (ILM, Rollup, CCR)
isRollupIndex?: boolean;
ilm?: {
index: string;
managed: boolean;
};
isFollowerIndex?: boolean;

// The types from here below represent information returned from the index stats API;
// treated optional as the stats API is not available on serverless
health?: HealthStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ import {
EuiButton,
} from '@elastic/eui';
import { SectionLoading } from '@kbn/es-ui-shared-plugin/public';

import { DiscoverLink } from '../../../../lib/discover_link';
import { useLoadIndex } from '../../../../services';
import { Section } from '../../home';
import { DetailsPageError } from './details_page_error';
import { IndexActionsContextMenuWithoutRedux } from '../index_actions_context_menu/index_actions_context_menu.without_redux';
import { ManageIndexButton } from './manage_index_button';

export enum IndexDetailsSection {
Overview = 'overview',
Documents = 'documents',
Expand Down Expand Up @@ -141,17 +143,20 @@ export const DetailsPage: React.FunctionComponent<
bottomBorder
rightSideItems={[
<DiscoverLink indexName={indexName} asButton={true} />,
<IndexActionsContextMenuWithoutRedux
indexNames={[indexName]}
indices={[data]}
fill={false}
<ManageIndexButton
indexName={indexName}
indexDetails={data}
reloadIndexDetails={resendRequest}
navigateToAllIndices={navigateToAllIndices}
/>,
]}
tabs={headerTabs}
/>

<EuiSpacer size="l" />
<div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
<EuiSpacer size="l" />

<div data-test-subj={`indexDetailsContent`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,104 +5,61 @@
* 2.0.
*/

import React, { FunctionComponent, useCallback, useState } from 'react';
import { HttpSetup } from '@kbn/core-http-browser';
import { EuiButtonProps } from '@elastic/eui/src/components/button/button';
import { EuiPopoverProps } from '@elastic/eui/src/components/popover/popover';
import React, { FunctionComponent, useCallback, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { HttpSetup } from '@kbn/core-http-browser';

import { Index } from '../../../../../../common';
import {
reloadIndices,
clearCacheIndices as clearCacheIndicesRequest,
closeIndices as closeIndicesRequest,
openIndices as openIndicesRequest,
deleteIndices as deleteIndicesRequest,
flushIndices as flushIndicesRequest,
forcemergeIndices as forcemergeIndicesRequest,
openIndices as openIndicesRequest,
refreshIndices as refreshIndicesRequest,
clearCacheIndices as clearCacheIndicesRequest,
unfreezeIndices as unfreezeIndicesRequest,
forcemergeIndices as forcemergeIndicesRequest,
deleteIndices as deleteIndicesRequest,
} from '../../../../services';
import { notificationService } from '../../../../services/notification';
// @ts-ignore this component needs to be refactored into TS
import { IndexActionsContextMenu } from './index_actions_context_menu';

export interface ReduxProps {
closeIndices: () => Promise<void>;
openIndices: () => Promise<void>;
flushIndices: () => Promise<void>;
refreshIndices: () => Promise<void>;
clearCacheIndices: () => Promise<void>;
unfreezeIndices: () => Promise<void>;
forcemergeIndices: (maxNumSegments: string) => Promise<void>;
deleteIndices: ({}: { indexNames: string[] }) => Promise<void>;

// following 4 actions are only added when on the list view and only 1 index is selected
showSettings: ({}: { indexNames: string[] }) => void; // opens the settings tab for the 1st index
showMapping: ({}: { indexNames: string[] }) => void; // opens the mapping tab for the 1st index
showStats: ({}: { indexNames: string[] }) => void; // opens the stats tab for the 1st index
editIndex: ({}: { indexNames: string[] }) => void; // opens the edit settings tab for the 1st index

indexStatusByName: {
[indexName: string]: Index['status'] | undefined;
};
reloadIndices: typeof reloadIndices;

// this comes from the extension service
performExtensionAction: ({}: {
requestMethod: (indexNames: string[], httpClient: HttpSetup) => Promise<void>;
indexNames: string[];
successMessage: string;
}) => Promise<void>;
}

interface Props {
// either an array of indices selected in the list view or an array of 1 index name on details panel/page
indexNames: string[];

// indicates if the context menu is on the list view (to show additional actions)
isOnListView?: boolean;
// a callback used to reset selected indices on the list view
resetSelection?: () => void;

// these props are only set on the details panel to change style
anchorPosition?: EuiPopoverProps['anchorPosition'];
iconSide?: EuiButtonProps['iconSide'];
iconType?: EuiButtonProps['iconType'];
label?: React.Component;

// a new prop to make the button secondary
fill?: boolean;
import { httpService } from '../../../../services/http';

// instead of getting indices data from the redux store, pass it as a prop
indices: Index[];

// a function to reload index details
reloadIndexDetails?: () => void;

// a function to navigate back to all indices (after index deletion)
navigateToAllIndices?: () => void;
}
import {
IndexActionsContextMenu,
IndexActionsContextMenuProps,
} from '../index_actions_context_menu/index_actions_context_menu';

const getIndexStatusByName = (
indexNames: string[],
indices: Index[]
): ReduxProps['indexStatusByName'] => {
const indexStatusByName: ReduxProps['indexStatusByName'] = {};
): IndexActionsContextMenuProps['indexStatusByName'] => {
const indexStatusByName: IndexActionsContextMenuProps['indexStatusByName'] = {};
indexNames.forEach((indexName) => {
const { status } = indices.find((index) => index.name === indexName) ?? {};
indexStatusByName[indexName] = status;
});
return indexStatusByName;
};

export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
indexNames,
indices,
interface Props {
indexName: string;
indexDetails: Index;
reloadIndexDetails: () => void;
navigateToAllIndices: () => void;
}
export const ManageIndexButton: FunctionComponent<Props> = ({
indexName,
indexDetails,
reloadIndexDetails,
navigateToAllIndices,
...rest
}) => {
const [isLoading, setIsLoading] = useState(false);

// the variables are created to write the index actions in a way to later re-use for indices list without redux
const indexNames = useMemo(() => [indexName], [indexName]);
const reloadIndices = reloadIndexDetails;
const indices = [indexDetails];
const indexStatusByName = getIndexStatusByName(indexNames, indices);

const closeIndices = useCallback(async () => {
setIsLoading(true);
try {
Expand All @@ -114,12 +71,12 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
values: { indexNames: indexNames.join(', ') },
})
);
reloadIndexDetails?.();
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
}, [reloadIndexDetails, indexNames]);
}, [reloadIndices, indexNames]);

const openIndices = useCallback(async () => {
setIsLoading(true);
Expand All @@ -132,12 +89,12 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
values: { indexNames: indexNames.join(', ') },
})
);
reloadIndexDetails?.();
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
}, [reloadIndexDetails, indexNames]);
}, [reloadIndices, indexNames]);

const flushIndices = useCallback(async () => {
setIsLoading(true);
Expand All @@ -150,12 +107,12 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
values: { indexNames: indexNames.join(', ') },
})
);
reloadIndexDetails?.();
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
}, [reloadIndexDetails, indexNames]);
}, [reloadIndices, indexNames]);

const refreshIndices = useCallback(async () => {
setIsLoading(true);
Expand All @@ -168,12 +125,12 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
values: { indexNames: indexNames.join(', ') },
})
);
reloadIndexDetails?.();
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
}, [reloadIndexDetails, indexNames]);
}, [reloadIndices, indexNames]);

const clearCacheIndices = useCallback(async () => {
setIsLoading(true);
Expand All @@ -186,12 +143,12 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
values: { indexNames: indexNames.join(', ') },
})
);
reloadIndexDetails?.();
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
}, [reloadIndexDetails, indexNames]);
}, [reloadIndices, indexNames]);

const unfreezeIndices = useCallback(async () => {
setIsLoading(true);
Expand All @@ -204,12 +161,12 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
values: { indexNames: indexNames.join(', ') },
})
);
reloadIndexDetails?.();
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
}, [reloadIndexDetails, indexNames]);
}, [reloadIndices, indexNames]);

const forcemergeIndices = useCallback(
async (maxNumSegments: string) => {
Expand All @@ -226,13 +183,13 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
}
)
);
reloadIndexDetails?.();
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
},
[reloadIndexDetails, indexNames]
[reloadIndices, indexNames]
);

const deleteIndices = useCallback(async () => {
Expand All @@ -246,42 +203,50 @@ export const IndexActionsContextMenuWithoutRedux: FunctionComponent<Props> = ({
values: { indexNames: indexNames.join(', ') },
})
);
navigateToAllIndices?.();
navigateToAllIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
}, [navigateToAllIndices, indexNames]);

const props: ReduxProps = {
closeIndices,
openIndices,
flushIndices,
refreshIndices,
clearCacheIndices,
unfreezeIndices,
forcemergeIndices,
deleteIndices,

// there actions are not displayed on the index details page
showSettings: () => {},
showMapping: () => {},
showStats: () => {},
editIndex: () => {},

indexStatusByName: getIndexStatusByName(indexNames, indices),
reloadIndices: async () => {},

performExtensionAction: async () => {},
};
const performExtensionAction = useCallback(
async (
requestMethod: (indexNames: string[], http: HttpSetup) => Promise<void>,
successMessage: string
) => {
setIsLoading(true);
try {
await requestMethod(indexNames, httpService.httpClient);
setIsLoading(false);
notificationService.showSuccessToast(successMessage);
reloadIndices();
} catch (error) {
setIsLoading(false);
notificationService.showDangerToast(error.body.message);
}
},
[reloadIndices, indexNames]
);

return (
<IndexActionsContextMenu
indexNames={indexNames}
indices={indices}
indexStatusByName={indexStatusByName}
fill={false}
isLoading={isLoading}
{...props}
{...rest}
// index actions
closeIndices={closeIndices}
openIndices={openIndices}
flushIndices={flushIndices}
refreshIndices={refreshIndices}
clearCacheIndices={clearCacheIndices}
unfreezeIndices={unfreezeIndices}
forcemergeIndices={forcemergeIndices}
deleteIndices={deleteIndices}
performExtensionAction={performExtensionAction}
reloadIndices={reloadIndices}
/>
);
};
Loading

0 comments on commit cfbdc05

Please sign in to comment.