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

[Search Session][Management] Rename "cancel" button and delete "Reload" button #90015

Merged
merged 13 commits into from
Feb 4, 2021
1 change: 1 addition & 0 deletions src/plugins/data/server/search/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ export function createSearchRequestHandlerContext() {
updateSession: jest.fn(),
extendSession: jest.fn(),
cancelSession: jest.fn(),
deleteSession: jest.fn(),
};
}
13 changes: 11 additions & 2 deletions src/plugins/data/server/search/search_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,8 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
return strategy.extend(id, keepAlive, options, deps);
};

private cancelSession = async (deps: SearchStrategyDependencies, sessionId: string) => {
private cancelSessionSearches = async (deps: SearchStrategyDependencies, sessionId: string) => {
const searchIdMapping = await deps.searchSessionsClient.getSearchIdMapping(sessionId);
const response = await deps.searchSessionsClient.cancel(sessionId);

for (const [searchId, strategyName] of searchIdMapping.entries()) {
const searchOptions = {
Expand All @@ -319,10 +318,19 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
};
this.cancel(deps, searchId, searchOptions);
}
};

private cancelSession = async (deps: SearchStrategyDependencies, sessionId: string) => {
const response = await deps.searchSessionsClient.cancel(sessionId);
this.cancelSessionSearches(deps, sessionId);
return response;
};

private deleteSession = async (deps: SearchStrategyDependencies, sessionId: string) => {
this.cancelSessionSearches(deps, sessionId);
return deps.searchSessionsClient.delete(sessionId);
};

private extendSession = async (
deps: SearchStrategyDependencies,
sessionId: string,
Expand Down Expand Up @@ -372,6 +380,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
updateSession: searchSessionsClient.update,
extendSession: this.extendSession.bind(this, deps),
cancelSession: this.cancelSession.bind(this, deps),
deleteSession: this.deleteSession.bind(this, deps),
};
};
};
Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/server/search/session/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ export function createSearchSessionsClientMock<T = unknown>(): jest.Mocked<
update: jest.fn(),
cancel: jest.fn(),
extend: jest.fn(),
delete: jest.fn(),
};
}
3 changes: 3 additions & 0 deletions src/plugins/data/server/search/session/session_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export class SearchSessionService implements ISearchSessionService {
cancel: async () => {
throw new Error('cancel not implemented in OSS search session service');
},
delete: async () => {
throw new Error('delete not implemented in OSS search session service');
},
});
}
}
1 change: 1 addition & 0 deletions src/plugins/data/server/search/session/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface IScopedSearchSessionsClient<T = unknown> {
find: (options: Omit<SavedObjectsFindOptions, 'type'>) => Promise<SavedObjectsFindResponse<T>>;
update: (sessionId: string, attributes: Partial<T>) => Promise<SavedObjectsUpdateResponse<T>>;
cancel: (sessionId: string) => Promise<{}>;
delete: (sessionId: string) => Promise<{}>;
extend: (sessionId: string, expires: Date) => Promise<SavedObjectsUpdateResponse<T>>;
}

Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/server/search/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export interface IScopedSearchClient extends ISearchClient {
findSessions: IScopedSearchSessionsClient['find'];
updateSession: IScopedSearchSessionsClient['update'];
cancelSession: IScopedSearchSessionsClient['cancel'];
deleteSession: IScopedSearchSessionsClient['delete'];
extendSession: IScopedSearchSessionsClient['extend'];
}

Expand Down
3 changes: 2 additions & 1 deletion src/plugins/data/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,7 @@ export class SearchSessionService implements ISearchSessionService {
update: () => Promise<never>;
extend: () => Promise<never>;
cancel: () => Promise<never>;
delete: () => Promise<never>;
};
}

Expand Down Expand Up @@ -1430,7 +1431,7 @@ export function usageProvider(core: CoreSetup_2): SearchUsage;
// src/plugins/data/server/index.ts:266:1 - (ae-forgotten-export) The symbol "calcAutoIntervalLessThan" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index_patterns/index_patterns_service.ts:59:14 - (ae-forgotten-export) The symbol "IndexPatternsService" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/plugin.ts:79:74 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/search/types.ts:113:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/search/types.ts:114:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,31 @@ import { SearchSessionsMgmtAPI } from '../../lib/api';
import { TableText } from '../';
import { OnActionComplete } from './types';

interface CancelButtonProps {
interface DeleteButtonProps {
id: string;
name: string;
api: SearchSessionsMgmtAPI;
onActionComplete: OnActionComplete;
}

const CancelConfirm = ({
onConfirmDismiss,
const DeleteConfirm = ({
onConfirmCancel,
...props
}: CancelButtonProps & { onConfirmDismiss: () => void }) => {
}: DeleteButtonProps & { onConfirmCancel: () => void }) => {
const { id, name, api, onActionComplete } = props;
const [isLoading, setIsLoading] = useState(false);

const title = i18n.translate('xpack.data.mgmt.searchSessions.cancelModal.title', {
defaultMessage: 'Cancel search session',
defaultMessage: 'Delete search session',
});
const confirm = i18n.translate('xpack.data.mgmt.searchSessions.cancelModal.cancelButton', {
defaultMessage: 'Cancel',
const confirm = i18n.translate('xpack.data.mgmt.searchSessions.cancelModal.deleteButton', {
defaultMessage: 'Delete',
});
const cancel = i18n.translate('xpack.data.mgmt.searchSessions.cancelModal.dontCancelButton', {
defaultMessage: 'Dismiss',
const cancel = i18n.translate('xpack.data.mgmt.searchSessions.cancelModal.cancelButton', {
defaultMessage: 'Cancel',
});
const message = i18n.translate('xpack.data.mgmt.searchSessions.cancelModal.message', {
defaultMessage: `Canceling the search session \'{name}\' will expire any cached results, so that quick restore will no longer be available. You will still be able to re-run it, using the reload action.`,
defaultMessage: `Deleting the search session \'{name}\' deletes all cached results.`,
values: {
name,
},
Expand All @@ -47,7 +47,7 @@ const CancelConfirm = ({
<EuiOverlayMask>
<EuiConfirmModal
title={title}
onCancel={onConfirmDismiss}
onCancel={onConfirmCancel}
onConfirm={async () => {
setIsLoading(true);
await api.sendCancel(id);
Expand All @@ -65,26 +65,26 @@ const CancelConfirm = ({
);
};

export const CancelButton = (props: CancelButtonProps) => {
export const DeleteButton = (props: DeleteButtonProps) => {
const [showConfirm, setShowConfirm] = useState(false);

const onClick = () => {
setShowConfirm(true);
};

const onConfirmDismiss = () => {
const onConfirmCancel = () => {
setShowConfirm(false);
};

return (
<>
<TableText onClick={onClick}>
<FormattedMessage
id="xpack.data.mgmt.searchSessions.actionCancel"
defaultMessage="Cancel"
id="xpack.data.mgmt.searchSessions.actionDelete"
defaultMessage="Delete"
/>
</TableText>
{showConfirm ? <CancelConfirm {...props} onConfirmDismiss={onConfirmDismiss} /> : null}
{showConfirm ? <DeleteConfirm {...props} onConfirmCancel={onConfirmCancel} /> : null}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,22 @@ import { IClickActionDescriptor } from '../';
import extendSessionIcon from '../../icons/extend_session.svg';
import { SearchSessionsMgmtAPI } from '../../lib/api';
import { UISession } from '../../types';
import { CancelButton } from './cancel_button';
import { DeleteButton } from './delete_button';
import { ExtendButton } from './extend_button';
import { ReloadButton } from './reload_button';
import { ACTION, OnActionComplete } from './types';

export const getAction = (
api: SearchSessionsMgmtAPI,
actionType: string,
{ id, name, expires, reloadUrl }: UISession,
{ id, name, expires }: UISession,
onActionComplete: OnActionComplete
): IClickActionDescriptor | null => {
switch (actionType) {
case ACTION.CANCEL:
case ACTION.DELETE:
return {
iconType: 'crossInACircleFilled',
textColor: 'default',
label: <CancelButton api={api} id={id} name={name} onActionComplete={onActionComplete} />,
};

case ACTION.RELOAD:
return {
iconType: 'refresh',
textColor: 'default',
label: <ReloadButton api={api} reloadUrl={reloadUrl} />,
label: <DeleteButton api={api} id={id} name={name} onActionComplete={onActionComplete} />,
};

case ACTION.EXTEND:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const PopoverActionsMenu = ({ api, onActionComplete, session }: PopoverAc

// add a line above the delete action (when there are multiple)
// NOTE: Delete action MUST be the final action[] item
if (actions.length > 1 && actionType === ACTION.CANCEL) {
if (actions.length > 1 && actionType === ACTION.DELETE) {
itemSet.push({ isSeparator: true, key: 'separadorable' });
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ export type OnActionComplete = () => void;

export enum ACTION {
EXTEND = 'extend',
CANCEL = 'cancel',
RELOAD = 'reload',
DELETE = 'delete',
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ describe('Search Sessions Management API', () => {
Array [
Object {
"actions": Array [
"reload",
"extend",
"cancel",
"delete",
],
"appId": "pizza",
"created": undefined,
Expand Down Expand Up @@ -146,7 +145,7 @@ describe('Search Sessions Management API', () => {
await api.sendCancel('abc-123-cool-session-ID');

expect(mockCoreStart.notifications.toasts.addSuccess).toHaveBeenCalledWith({
title: 'The search session was canceled and expired.',
title: 'The search session was deleted.',
});
});

Expand All @@ -162,37 +161,11 @@ describe('Search Sessions Management API', () => {

expect(mockCoreStart.notifications.toasts.addError).toHaveBeenCalledWith(
new Error('implementation is so bad'),
{ title: 'Failed to cancel the search session!' }
{ title: 'Failed to delete the search session!' }
);
});
});

describe('reload', () => {
beforeEach(() => {
sessionsClient.find = jest.fn().mockImplementation(async () => {
return {
saved_objects: [
{
id: 'hello-pizza-123',
attributes: { name: 'Veggie', appId: 'pizza', status: SearchSessionStatus.COMPLETE },
},
],
} as SavedObjectsFindResponse;
});
});

test('send cancel calls the cancel endpoint with a session ID', async () => {
const api = new SearchSessionsMgmtAPI(sessionsClient, mockConfig, {
urls: mockUrls,
notifications: mockCoreStart.notifications,
application: mockCoreStart.application,
});
await api.reloadSearchSession('www.myurl.com');

expect(mockCoreStart.application.navigateToUrl).toHaveBeenCalledWith('www.myurl.com');
});
});

describe('extend', () => {
beforeEach(() => {
sessionsClient.find = jest.fn().mockImplementation(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ type UrlGeneratorsStart = SharePluginStart['urlGenerators'];

function getActions(status: SearchSessionStatus) {
const actions: ACTION[] = [];
actions.push(ACTION.RELOAD);
if (status === SearchSessionStatus.IN_PROGRESS || status === SearchSessionStatus.COMPLETE) {
actions.push(ACTION.EXTEND);
actions.push(ACTION.CANCEL);
actions.push(ACTION.DELETE);
}
return actions;
}
Expand Down Expand Up @@ -162,17 +161,17 @@ export class SearchSessionsMgmtAPI {
await this.sessionsClient.delete(id);

this.deps.notifications.toasts.addSuccess({
title: i18n.translate('xpack.data.mgmt.searchSessions.api.canceled', {
defaultMessage: 'The search session was canceled and expired.',
title: i18n.translate('xpack.data.mgmt.searchSessions.api.deleted', {
defaultMessage: 'The search session was deleted.',
}),
});
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);

this.deps.notifications.toasts.addError(err, {
title: i18n.translate('xpack.data.mgmt.searchSessions.api.cancelError', {
defaultMessage: 'Failed to cancel the search session!',
title: i18n.translate('xpack.data.mgmt.searchSessions.api.deletedError', {
defaultMessage: 'Failed to delete the search session!',
}),
});
}
Expand Down
Loading