Skip to content

Commit

Permalink
fix(window): unavailable localStorage and sessionStorage (#25599)
Browse files Browse the repository at this point in the history
  • Loading branch information
frassinier authored and michael-s-molina committed Oct 13, 2023
1 parent 732c5b1 commit a0b2dc4
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 80 deletions.
102 changes: 53 additions & 49 deletions superset-frontend/src/SqlLab/reducers/getInitialState.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,57 +137,61 @@ export default function getInitialState({

const queries = { ...queries_ };

/**
* If the `SQLLAB_BACKEND_PERSISTENCE` feature flag is off, or if the user
* hasn't used SQL Lab after it has been turned on, the state will be stored
* in the browser's local storage.
*/
if (
localStorage.getItem('redux') &&
JSON.parse(localStorage.getItem('redux')).sqlLab
) {
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
try {
/**
* If the `SQLLAB_BACKEND_PERSISTENCE` feature flag is off, or if the user
* hasn't used SQL Lab after it has been turned on, the state will be stored
* in the browser's local storage.
*/
if (
localStorage.getItem('redux') &&
JSON.parse(localStorage.getItem('redux')).sqlLab
) {
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));

if (sqlLab.queryEditors.length === 0) {
// migration was successful
localStorage.removeItem('redux');
} else {
unsavedQueryEditor = sqlLab.unsavedQueryEditor || {};
// add query editors and tables to state with a special flag so they can
// be migrated if the `SQLLAB_BACKEND_PERSISTENCE` feature flag is on
sqlLab.queryEditors.forEach(qe => {
queryEditors = {
...queryEditors,
[qe.id]: {
...queryEditors[qe.id],
...qe,
name: qe.title || qe.name,
...(unsavedQueryEditor.id === qe.id && unsavedQueryEditor),
inLocalStorage: true,
loaded: true,
},
};
});
const expandedTables = new Set();
tables = sqlLab.tables.reduce((merged, table) => {
const expanded = !expandedTables.has(table.queryEditorId);
if (expanded) {
expandedTables.add(table.queryEditorId);
}
return {
...merged,
[table.id]: {
...tables[table.id],
...table,
expanded,
},
};
}, tables);
Object.values(sqlLab.queries).forEach(query => {
queries[query.id] = { ...query, inLocalStorage: true };
});
tabHistory.push(...sqlLab.tabHistory);
if (sqlLab.queryEditors.length === 0) {
// migration was successful
localStorage.removeItem('redux');
} else {
unsavedQueryEditor = sqlLab.unsavedQueryEditor || {};
// add query editors and tables to state with a special flag so they can
// be migrated if the `SQLLAB_BACKEND_PERSISTENCE` feature flag is on
sqlLab.queryEditors.forEach(qe => {
queryEditors = {
...queryEditors,
[qe.id]: {
...queryEditors[qe.id],
...qe,
name: qe.title || qe.name,
...(unsavedQueryEditor.id === qe.id && unsavedQueryEditor),
inLocalStorage: true,
loaded: true,
},
};
});
const expandedTables = new Set();
tables = sqlLab.tables.reduce((merged, table) => {
const expanded = !expandedTables.has(table.queryEditorId);
if (expanded) {
expandedTables.add(table.queryEditorId);
}
return {
...merged,
[table.id]: {
...tables[table.id],
...table,
expanded,
},
};
}, tables);
Object.values(sqlLab.queries).forEach(query => {
queries[query.id] = { ...query, inLocalStorage: true };
});
tabHistory.push(...sqlLab.tabHistory);
}
}
} catch (error) {
// continue regardless of error
}

return {
Expand Down
49 changes: 30 additions & 19 deletions superset-frontend/src/SqlLab/reducers/sqlLab.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,16 @@ export default function sqlLabReducer(state = {}, action) {
return { ...state, activeSouthPaneTab: action.tabId };
},
[actions.MIGRATE_QUERY_EDITOR]() {
// remove migrated query editor from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.queryEditors = sqlLab.queryEditors.filter(
qe => qe.id !== action.oldQueryEditor.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));

try {
// remove migrated query editor from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.queryEditors = sqlLab.queryEditors.filter(
qe => qe.id !== action.oldQueryEditor.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
} catch (error) {
// continue regardless of error
}
// replace localStorage query editor with the server backed one
return addToArr(
removeFromArr(state, 'queryEditors', action.oldQueryEditor),
Expand All @@ -439,12 +442,16 @@ export default function sqlLabReducer(state = {}, action) {
);
},
[actions.MIGRATE_TABLE]() {
// remove migrated table from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tables = sqlLab.tables.filter(
table => table.id !== action.oldTable.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
try {
// remove migrated table from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tables = sqlLab.tables.filter(
table => table.id !== action.oldTable.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
} catch (error) {
// continue regardless of error
}

// replace localStorage table with the server backed one
return addToArr(
Expand All @@ -454,12 +461,16 @@ export default function sqlLabReducer(state = {}, action) {
);
},
[actions.MIGRATE_TAB_HISTORY]() {
// remove migrated tab from localStorage tabHistory
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tabHistory = sqlLab.tabHistory.filter(
tabId => tabId !== action.oldId,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
try {
// remove migrated tab from localStorage tabHistory
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tabHistory = sqlLab.tabHistory.filter(
tabId => tabId !== action.oldId,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
} catch (error) {
// continue regardless of error
}
const tabHistory = state.tabHistory.filter(
tabId => tabId !== action.oldId,
);
Expand Down
14 changes: 12 additions & 2 deletions superset-frontend/src/explore/components/DatasourcePanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,11 @@ export default function DataSourcePanel({
);

const showInfoboxCheck = () => {
if (sessionStorage.getItem('showInfobox') === 'false') return false;
try {
if (sessionStorage.getItem('showInfobox') === 'false') return false;
} catch (error) {
// continue regardless of error
}
return true;
};

Expand Down Expand Up @@ -366,7 +370,13 @@ export default function DataSourcePanel({
<StyledInfoboxWrapper>
<Alert
closable
onClose={() => sessionStorage.setItem('showInfobox', 'false')}
onClose={() => {
try {
sessionStorage.setItem('showInfobox', 'false');
} catch (error) {
// continue regardless of error
}
}}
type="info"
message=""
description={
Expand Down
19 changes: 14 additions & 5 deletions superset-frontend/src/explore/components/SaveModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,12 @@ class SaveModal extends React.Component<SaveModalProps, SaveModalState> {
async componentDidMount() {
let { dashboardId } = this.props;
if (!dashboardId) {
const lastDashboard = sessionStorage.getItem(SK_DASHBOARD_ID);
let lastDashboard = null;
try {
lastDashboard = sessionStorage.getItem(SK_DASHBOARD_ID);
} catch (error) {
// continue regardless of error
}
dashboardId = lastDashboard && parseInt(lastDashboard, 10);
}
if (dashboardId) {
Expand Down Expand Up @@ -249,10 +254,14 @@ class SaveModal extends React.Component<SaveModalProps, SaveModalState> {
);
}

if (dashboard) {
sessionStorage.setItem(SK_DASHBOARD_ID, `${dashboard.id}`);
} else {
sessionStorage.removeItem(SK_DASHBOARD_ID);
try {
if (dashboard) {
sessionStorage.setItem(SK_DASHBOARD_ID, `${dashboard.id}`);
} else {
sessionStorage.removeItem(SK_DASHBOARD_ID);
}
} catch (error) {
// continue regardless of error
}

// Go to new dashboard url
Expand Down
23 changes: 18 additions & 5 deletions superset-frontend/src/hooks/useTabId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,29 @@ export function useTabId() {
}

const updateTabId = () => {
const lastTabId = window.localStorage.getItem('last_tab_id');
let lastTabId;
try {
lastTabId = window.localStorage.getItem('last_tab_id');
} catch (error) {
// continue regardless of error
}
const newTabId = String(
lastTabId ? Number.parseInt(lastTabId, 10) + 1 : 1,
);
window.sessionStorage.setItem('tab_id', newTabId);
window.localStorage.setItem('last_tab_id', newTabId);
try {
window.sessionStorage.setItem('tab_id', newTabId);
window.localStorage.setItem('last_tab_id', newTabId);
} catch (error) {
// continue regardless of error
}
setTabId(newTabId);
};

const storedTabId = window.sessionStorage.getItem('tab_id');
let storedTabId;
try {
storedTabId = window.sessionStorage.getItem('tab_id');
} catch (error) {
// continue regardless of error
}
if (storedTabId) {
channel.postMessage({
type: 'REQUESTING_TAB_ID',
Expand Down

0 comments on commit a0b2dc4

Please sign in to comment.