[Console] Save state of folding/unfolding of commands (#134810)

* Persist fold states and restore it back from storage

* Add tests

Co-authored-by: Muhammad Ibragimov <muhammad.ibragimov@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Muhammad Ibragimov 2022-07-07 13:49:38 +05:00 committed by GitHub
parent d32b3ace4c
commit b809237f84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 99 additions and 1 deletions

View file

@ -26,6 +26,8 @@ jest.mock('../../../../models/sense_editor', () => {
focus: () => {},
}),
on: jest.fn(),
addFoldsAtRanges: jest.fn(),
getAllFoldRanges: jest.fn(),
}),
update: jest.fn(),
commands: {

View file

@ -33,6 +33,7 @@ import { subscribeResizeChecker } from '../subscribe_console_resize_checker';
import { applyCurrentSettings } from './apply_editor_settings';
import { registerCommands } from './keyboard_shortcuts';
import type { SenseEditor } from '../../../../models/sense_editor';
import { StorageKeys } from '../../../../../services';
const { useUIAceKeyboardMode } = ace;
@ -71,6 +72,7 @@ function EditorUI({ initialTextValue, setEditorInstance }: EditorProps) {
esHostService,
http,
autocompleteInfo,
storage,
},
docLinkVersion,
} = useServicesContext();
@ -198,6 +200,26 @@ function EditorUI({ initialTextValue, setEditorInstance }: EditorProps) {
}
}
function restoreFolds() {
if (editor) {
const foldRanges = storage.get(StorageKeys.FOLDS, []);
editor.getCoreEditor().addFoldsAtRanges(foldRanges);
}
}
restoreFolds();
function saveFoldsOnChange() {
if (editor) {
editor.getCoreEditor().on('changeFold', () => {
const foldRanges = editor.getCoreEditor().getAllFoldRanges();
storage.set(StorageKeys.FOLDS, foldRanges);
});
}
}
saveFoldsOnChange();
setInputEditor(editor);
setTextArea(editorRef.current!.querySelector('textarea'));
@ -223,6 +245,7 @@ function EditorUI({ initialTextValue, setEditorInstance }: EditorProps) {
settingsService,
http,
autocompleteInfo,
storage,
]);
useEffect(() => {

View file

@ -458,4 +458,19 @@ export class LegacyCoreEditor implements CoreEditor {
mode.autoOutdent(prevLineState, session, row);
}
}
getAllFoldRanges(): Range[] {
const session = this.editor.getSession();
// @ts-ignore
// Brace does not expose type definition for session.getAllFolds, though we have access to this method provided by the underlying Ace editor.
// See https://github.com/ajaxorg/ace/blob/13dc911dbc0ea31ca343d5744b3f472767458fc3/ace.d.ts#L82
return session.getAllFolds().map((fold) => fold.range);
}
addFoldsAtRanges(foldRanges: Range[]) {
const session = this.editor.getSession();
foldRanges.forEach((range) => {
session.addFold('...', _AceRange.fromPoints(range.start, range.end));
});
}
}

View file

@ -12,6 +12,7 @@ type IStorageEngine = typeof window.localStorage;
export enum StorageKeys {
WIDTH = 'widths',
FOLDS = 'folds',
}
export class Storage {

View file

@ -17,7 +17,8 @@ export type EditorEvent =
| 'changeCursor'
| 'changeScrollTop'
| 'change'
| 'changeSelection';
| 'changeSelection'
| 'changeFold';
export type AutoCompleterFunction = (
pos: Position,
@ -277,4 +278,14 @@ export interface CoreEditor {
* Indent document within request range
*/
autoIndent(reqRange: Range): void;
/*
* Get all fold ranges in document
*/
getAllFoldRanges(): Range[];
/**
* Add folds at given ranges
*/
addFoldsAtRanges(foldRanges: Range[]): void;
}

View file

@ -154,5 +154,36 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(await PageObjects.console.hasSuccessBadge()).to.be(true);
});
});
describe('with folded/unfolded lines in request body', () => {
const enterRequestWithBody = async () => {
await PageObjects.console.enterRequest();
await PageObjects.console.pressEnter();
await PageObjects.console.enterText('{\n\t\t"_source": []');
};
it('should save the state of folding/unfolding when navigating back to Console', async () => {
await PageObjects.console.clearTextArea();
await enterRequestWithBody();
await PageObjects.console.clickFoldWidget();
await PageObjects.common.navigateToApp('home');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.common.navigateToApp('console');
expect(await PageObjects.console.hasFolds()).to.be(true);
});
it('should save the state of folding/unfolding when the page reloads', async () => {
// blocks the close help button for several seconds so just retry until we can click it.
await retry.try(async () => {
await PageObjects.console.collapseHelp();
});
await PageObjects.console.clearTextArea();
await enterRequestWithBody();
await PageObjects.console.clickFoldWidget();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
expect(await PageObjects.console.hasFolds()).to.be(true);
});
});
});
}

View file

@ -206,4 +206,19 @@ export class ConsolePageObject extends FtrService {
return false;
}
}
public async clickFoldWidget() {
const widget = await this.find.byCssSelector('.ace_fold-widget');
await widget.click();
}
public async hasFolds() {
try {
const requestEditor = await this.getRequestEditor();
const folds = await requestEditor.findAllByCssSelector('.ace_fold');
return folds.length > 0;
} catch (e) {
return false;
}
}
}