Skip to content

Commit 8feea32

Browse files
authored
chore(compass-web): add an interface to propagate the tab closing checks for before unload interception COMPASS-8033 (#7404)
* chore(compass-web): add an interface to propagate the tab closing checks for before unload interception * chore(web): mark beforeunload callback as optional for now Otherwise it will make it a requirement to implement something on other side during the version bump and we don't want that
1 parent c0a38c0 commit 8feea32

File tree

4 files changed

+44
-20
lines changed

4 files changed

+44
-20
lines changed

packages/compass-web/src/entrypoint.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ const WithStorageProviders = createServiceProvider(
183183

184184
type CompassWorkspaceProps = Pick<
185185
React.ComponentProps<typeof WorkspacesPlugin>,
186-
'initialWorkspaceTabs' | 'onActiveWorkspaceTabChange'
186+
| 'initialWorkspaceTabs'
187+
| 'onActiveWorkspaceTabChange'
188+
| 'onBeforeUnloadCallbackRequest'
187189
> &
188190
Pick<
189191
React.ComponentProps<typeof CompassSidebarPlugin>,
@@ -226,17 +228,18 @@ export type CompassWebProps = {
226228
* `initialAutoconnectId`
227229
*/
228230
initialWorkspace?: OpenWorkspaceOptions;
231+
229232
/**
230233
* Callback prop called when current active workspace changes. Can be used to
231234
* communicate current workspace back to the parent component for example to
232235
* sync router with the current active workspace
233236
*/
234-
onActiveWorkspaceTabChange<WS extends WorkspaceTab>(
237+
onActiveWorkspaceTabChange: <WS extends WorkspaceTab>(
235238
ws: WS | null,
236239
collectionInfo: WS extends { type: 'Collection' }
237240
? CollectionTabInfo | null
238241
: never
239-
): void;
242+
) => void;
240243

241244
/**
242245
* Set of initial preferences to override default values
@@ -268,12 +271,20 @@ export type CompassWebProps = {
268271
* Callback prop called when connections fail to load
269272
*/
270273
onFailToLoadConnections: (err: Error) => void;
274+
275+
/**
276+
* Callback that will get passed another callback function that, when called,
277+
* would return back true or false depending on whether or not tabs can be
278+
* safely closed without losing any important unsaved changes
279+
*/
280+
onBeforeUnloadCallbackRequest?: (canCloseCallback: () => boolean) => void;
271281
};
272282

273283
function CompassWorkspace({
274284
initialWorkspaceTabs,
275285
onActiveWorkspaceTabChange,
276286
onOpenConnectViaModal,
287+
onBeforeUnloadCallbackRequest,
277288
}: CompassWorkspaceProps) {
278289
return (
279290
<WorkspacesProvider
@@ -306,6 +317,7 @@ function CompassWorkspace({
306317
className={connectedContainerStyles}
307318
>
308319
<WorkspacesPlugin
320+
onBeforeUnloadCallbackRequest={onBeforeUnloadCallbackRequest}
309321
initialWorkspaceTabs={initialWorkspaceTabs}
310322
openOnEmptyWorkspace={{ type: 'Welcome' }}
311323
onActiveWorkspaceTabChange={onActiveWorkspaceTabChange}
@@ -376,6 +388,7 @@ const CompassWeb = ({
376388
onTrack,
377389
onOpenConnectViaModal,
378390
onFailToLoadConnections,
391+
onBeforeUnloadCallbackRequest,
379392
}: CompassWebProps) => {
380393
const appRegistry = useRef(new AppRegistry());
381394
const logger = useCompassWebLogger({
@@ -546,6 +559,9 @@ const CompassWeb = ({
546559
onOpenConnectViaModal={
547560
onOpenConnectViaModal
548561
}
562+
onBeforeUnloadCallbackRequest={
563+
onBeforeUnloadCallbackRequest
564+
}
549565
></CompassWorkspace>
550566
</WithConnectionsStore>
551567
</FieldStorePlugin>

packages/compass-workspaces/src/components/index.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ type WorkspacesWithSidebarProps = {
2727
* @param ws current active workspace
2828
* @param collectionInfo active workspaces collection info
2929
*/
30-
onActiveWorkspaceTabChange<WS extends WorkspaceTab>(
30+
onActiveWorkspaceTabChange: <WS extends WorkspaceTab>(
3131
ws: WS | null,
3232
collectionInfo: WS extends { type: 'Collection' }
3333
? CollectionTabInfo | null
3434
: never
35-
): void;
35+
) => void;
3636
/**
3737
* Initial workspace tab to show (by default no tabs will be shown initially)
3838
*/
@@ -54,6 +54,12 @@ type WorkspacesWithSidebarProps = {
5454
* actions from service locator context
5555
*/
5656
renderModals?: () => React.ReactElement | null;
57+
/**
58+
* Callback that will get passed another callback function that, when called,
59+
* would return back true or false depending on whether or not tabs can be
60+
* safely closed without losing any important unsaved changes
61+
*/
62+
onBeforeUnloadCallbackRequest?: (canCloseCallback: () => boolean) => void;
5763
};
5864

5965
const containerLightThemeStyles = css({

packages/compass-workspaces/src/index.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import workspacesReducer, {
1616
connectionDisconnected,
1717
updateDatabaseInfo,
1818
updateCollectionInfo,
19+
beforeUnloading,
1920
} from './stores/workspaces';
2021
import Workspaces from './components';
2122
import { applyMiddleware, createStore } from 'redux';
@@ -75,7 +76,11 @@ export function configureStore(
7576
export function activateWorkspacePlugin(
7677
{
7778
initialWorkspaceTabs,
78-
}: { initialWorkspaceTabs?: OpenWorkspaceOptions[] | null },
79+
onBeforeUnloadCallbackRequest,
80+
}: {
81+
initialWorkspaceTabs?: OpenWorkspaceOptions[] | null;
82+
onBeforeUnloadCallbackRequest?: (canCloseCallback: () => boolean) => void;
83+
},
7984
{
8085
globalAppRegistry,
8186
instancesManager,
@@ -203,20 +208,9 @@ export function activateWorkspacePlugin(
203208
}
204209
});
205210

206-
// TODO(COMPASS-8033): activate this code and account for it in e2e tests and
207-
// electron environment
208-
// function onBeforeUnload(evt: BeforeUnloadEvent) {
209-
// const canUnload = store.getState().tabs.every((tab) => {
210-
// return canCloseTab(tab);
211-
// });
212-
// if (!canUnload) {
213-
// evt.preventDefault();
214-
// }
215-
// }
216-
// window.addEventListener('beforeunload', onBeforeUnload);
217-
// addCleanup(() => {
218-
// window.removeEventListener('beforeunload', onBeforeUnload);
219-
// });
211+
onBeforeUnloadCallbackRequest?.(() => {
212+
return store.dispatch(beforeUnloading());
213+
});
220214

221215
return {
222216
store,

packages/compass-workspaces/src/stores/workspaces.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,4 +1045,12 @@ export const openFallbackWorkspace = (
10451045
};
10461046
};
10471047

1048+
export const beforeUnloading = (): WorkspacesThunkAction<boolean> => {
1049+
return (_dispatch, getState) => {
1050+
return getState().tabs.every((tab) => {
1051+
return canCloseTab(tab);
1052+
});
1053+
};
1054+
};
1055+
10481056
export default reducer;

0 commit comments

Comments
 (0)