perf(sqllab): Rendering perf improvement using immutable state (#20877)

* perf(sqllab): Rendering perf improvement using immutable state

- keep queryEditors immutable during active state
- add unsavedQueryEditor to store all active changes
- refactor each component to subscribe the related unsaved editor state only

* revert ISaveableDatasource type cast

* missing trigger prop

* a default of an empty object and optional operator
This commit is contained in:
JUST.in DO IT
2022-08-23 08:17:19 -07:00
committed by GitHub
parent 4ca4a5c7cb
commit f77b910e2c
32 changed files with 1929 additions and 606 deletions

View File

@@ -39,23 +39,55 @@ describe('sqlLabReducer', () => {
qe = newState.queryEditors.find(e => e.id === 'abcd');
});
it('should add a query editor', () => {
expect(newState.queryEditors).toHaveLength(2);
expect(newState.queryEditors).toHaveLength(
initialState.queryEditors.length + 1,
);
});
it('should merge the current unsaved changes when adding a query editor', () => {
const expectedTitle = 'new updated title';
const updateAction = {
type: actions.QUERY_EDITOR_SET_TITLE,
queryEditor: initialState.queryEditors[0],
name: expectedTitle,
};
newState = sqlLabReducer(newState, updateAction);
const addAction = {
type: actions.ADD_QUERY_EDITOR,
queryEditor: { ...initialState.queryEditors[0], id: 'efgh' },
};
newState = sqlLabReducer(newState, addAction);
expect(newState.queryEditors[0].name).toEqual(expectedTitle);
expect(
newState.queryEditors[newState.queryEditors.length - 1].id,
).toEqual('efgh');
});
it('should remove a query editor', () => {
expect(newState.queryEditors).toHaveLength(2);
expect(newState.queryEditors).toHaveLength(
initialState.queryEditors.length + 1,
);
const action = {
type: actions.REMOVE_QUERY_EDITOR,
queryEditor: qe,
};
newState = sqlLabReducer(newState, action);
expect(newState.queryEditors).toHaveLength(1);
expect(newState.queryEditors).toHaveLength(
initialState.queryEditors.length,
);
});
it('should set q query editor active', () => {
const expectedTitle = 'new updated title';
const addQueryEditorAction = {
type: actions.ADD_QUERY_EDITOR,
queryEditor: { ...initialState.queryEditors[0], id: 'abcd' },
};
newState = sqlLabReducer(newState, addQueryEditorAction);
const updateAction = {
type: actions.QUERY_EDITOR_SET_TITLE,
queryEditor: initialState.queryEditors[1],
name: expectedTitle,
};
newState = sqlLabReducer(newState, updateAction);
const setActiveQueryEditorAction = {
type: actions.SET_ACTIVE_QUERY_EDITOR,
queryEditor: defaultQueryEditor,
@@ -64,6 +96,7 @@ describe('sqlLabReducer', () => {
expect(newState.tabHistory[newState.tabHistory.length - 1]).toBe(
defaultQueryEditor.id,
);
expect(newState.queryEditors[1].name).toEqual(expectedTitle);
});
it('should not fail while setting DB', () => {
const dbId = 9;
@@ -73,7 +106,8 @@ describe('sqlLabReducer', () => {
dbId,
};
newState = sqlLabReducer(newState, action);
expect(newState.queryEditors[1].dbId).toBe(dbId);
expect(newState.unsavedQueryEditor.dbId).toBe(dbId);
expect(newState.unsavedQueryEditor.id).toBe(qe.id);
});
it('should not fail while setting schema', () => {
const schema = 'foo';
@@ -83,7 +117,8 @@ describe('sqlLabReducer', () => {
schema,
};
newState = sqlLabReducer(newState, action);
expect(newState.queryEditors[1].schema).toBe(schema);
expect(newState.unsavedQueryEditor.schema).toBe(schema);
expect(newState.unsavedQueryEditor.id).toBe(qe.id);
});
it('should not fail while setting autorun', () => {
const action = {
@@ -91,19 +126,22 @@ describe('sqlLabReducer', () => {
queryEditor: qe,
};
newState = sqlLabReducer(newState, { ...action, autorun: false });
expect(newState.queryEditors[1].autorun).toBe(false);
expect(newState.unsavedQueryEditor.autorun).toBe(false);
expect(newState.unsavedQueryEditor.id).toBe(qe.id);
newState = sqlLabReducer(newState, { ...action, autorun: true });
expect(newState.queryEditors[1].autorun).toBe(true);
expect(newState.unsavedQueryEditor.autorun).toBe(true);
expect(newState.unsavedQueryEditor.id).toBe(qe.id);
});
it('should not fail while setting title', () => {
const title = 'Untitled Query 1';
const action = {
type: actions.QUERY_EDITOR_SET_TITLE,
queryEditor: qe,
title,
name: title,
};
newState = sqlLabReducer(newState, action);
expect(newState.queryEditors[0].name).toBe(title);
expect(newState.unsavedQueryEditor.name).toBe(title);
expect(newState.unsavedQueryEditor.id).toBe(qe.id);
});
it('should not fail while setting Sql', () => {
const sql = 'SELECT nothing from dev_null';
@@ -113,7 +151,8 @@ describe('sqlLabReducer', () => {
sql,
};
newState = sqlLabReducer(newState, action);
expect(newState.queryEditors[1].sql).toBe(sql);
expect(newState.unsavedQueryEditor.sql).toBe(sql);
expect(newState.unsavedQueryEditor.id).toBe(qe.id);
});
it('should not fail while setting queryLimit', () => {
const queryLimit = 101;
@@ -123,7 +162,8 @@ describe('sqlLabReducer', () => {
queryLimit,
};
newState = sqlLabReducer(newState, action);
expect(newState.queryEditors[1].queryLimit).toEqual(queryLimit);
expect(newState.unsavedQueryEditor.queryLimit).toBe(queryLimit);
expect(newState.unsavedQueryEditor.id).toBe(qe.id);
});
it('should set selectedText', () => {
const selectedText = 'TEST';
@@ -132,9 +172,10 @@ describe('sqlLabReducer', () => {
queryEditor: newState.queryEditors[0],
sql: selectedText,
};
expect(newState.queryEditors[0].selectedText).toBeNull();
expect(newState.queryEditors[0].selectedText).toBeFalsy();
newState = sqlLabReducer(newState, action);
expect(newState.queryEditors[0].selectedText).toBe(selectedText);
expect(newState.unsavedQueryEditor.selectedText).toBe(selectedText);
expect(newState.unsavedQueryEditor.id).toBe(newState.queryEditors[0].id);
});
});
describe('Tables', () => {